ToB企服应用市场:ToB评测及商务社交产业平台

标题: 使用Python实现简易版Netcat [打印本页]

作者: 尚未崩坏    时间: 2023-3-9 21:42
标题: 使用Python实现简易版Netcat
Netcat

Netcat是一种网络工具,也称为“nc”,可用于在计算机网络之间进行TCP/IP或UDP连接。它可以用于连接到其他计算机上的端口,发送和接收数据,扫描端口以及创建服务器等。
使用Python实现简易版

整体功能规划
  1. if __name__ == "__main__":
  2.     # argparse库是python标准库里面用来处理命令行参数的库
  3.     # 传递不同的参数,就能控制这个程序执行不同的操作
  4.     parser = argparse.ArgumentParser(       # 创建一个解析对象
  5.         description="ReverseShell",
  6.         formatter_class=argparse.RawDescriptionHelpFormatter,
  7.         # 帮助信息,程序启动的时候如果使用--help参数,就会显示这段信息
  8.         epilog=textwrap.dedent(
  9.             """
  10.                 python Simple_Netcat.py -t <IP> -p 5555 -l -c   # command shell
  11.                 python Simple_Netcat.py -t <IP> -p 5555         # connect to server
  12.                 get <file>                                      # download file
  13.                 upload <file>                                   # upload file
  14.             """
  15.         ),
  16.     )
  17.     # -c参数,打开一个交互式的命令行shell;
  18.     parser.add_argument("-c", "--command", action="store_true", help="command shell")
  19.     # -l参数,创建一个监听器
  20.     parser.add_argument("-l", "--listen", action="store_true", help="listen ")
  21.     # -p参数,指定要通信的端口
  22.     parser.add_argument("-p", "--port", type=int, default=5555, help="specified port ")
  23.     # -t参数,指定要通信的目标IP地址
  24.     parser.add_argument("-t", "--target", default="127.0.0.1", help="specified IP")
  25.     args = parser.parse_args()
  26.     nc = SimpleNetcat(args)
  27.     nc.run()
复制代码
创建NetCat类:
  1. class SimpleNetcat:
  2.     def __init__(self, args):
  3.         # 我们用main代码块传进来的命令行参数,初始化一个NetCat对象,然后创建一个socket对象
  4.         self.args = args
  5.         self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  6.         self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  7.     # 如果NetCat对象是接收方,run就执行listen函数
  8.     # 如果是发送方,run就执行send函数
  9.     def run(self):
  10.         if self.args.listen:
  11.             self.listen()
  12.         else:
  13.             # 用于启动时输出
  14.             print('Enter the first command >',end='')
  15.             self.send()
复制代码
实现listen功能:
  1. # 监听数据
  2. def listen(self):
  3.     self.socket.bind((self.args.target, self.args.port))
  4.     # listen(n)传入的值, n表示的是服务器拒绝(超过限制数量的)连接之前,操作系统可以挂起的最大连接数量。
  5.     self.socket.listen(5)
  6.     # 用一个循环监听新连接,并把已连接的socket对象传递给handle函数执行任务
  7.     while True:
  8.         # accept()等待传入连接。,返回代表连接的新套接字以及客户端的地址。
  9.         client_socket, _ = self.socket.accept()
  10.         # 给每个客户端创建一个独立的线程进行管理
  11.         client_thread = threading.Thread(target=self.handle, args=(client_socket,))
  12.         client_thread.start()
复制代码
当程序监听到指令之后,就可以执行相应的任务:
  1. # 执行传入的任务
  2. def handle(self, client_socket):
  3.     # 如果要执行命令,handle函数就会把该命令传递给execute函数
  4.     # 然后把输出结果通过socket发回去
  5.     if self.args.command:
  6.         # 创建shell,先创建一个循环,向发送方发一个提示符,
  7.         # 然后等待其发回命令。每收到一条命令,就用execute函数执行它,然后把结果发回发送方
  8.         while True:
  9.             try:
  10.                 cmd_buffer = b''
  11.                 # 循环接收发送端命令
  12.                 while '\n' not in cmd_buffer.decode():
  13.                     cmd_buffer += client_socket.recv(64)
  14.                 cmd = cmd_buffer.strip().decode()
  15.                 if cmd.startswith("get"):
  16.                     send_file(cmd, client_socket)
  17.                 elif cmd.startswith("upload"):
  18.                     get_file(cmd, client_socket)
  19.                 else:
  20.                     response = execute(cmd_buffer.decode())
  21.                     if response:
  22.                         client_socket.send(response.encode())
  23.             except Exception as e:
  24.                 print(f'Server killed {e}')
  25.                 self.socket.close()
  26.                 sys.exit()
复制代码
实现execute函数
  1. # execute函数用于接受一条命令并执行,然后将结果作为一段字符串返回
  2. def execute(cmd):
  3.     if cmd.startswith('cd '):
  4.         # 切换目录
  5.         os.chdir(cmd[3:].strip())
  6.         return os.getcwd() + '>'
  7.     else:
  8.         cmd = cmd.strip()
  9.         if not cmd:
  10.             return
  11.         # subprocess库提供了一组强大的进程创建接口,可以通过多种方式调用其他程序。
  12.         # check_output函数会在本机运行一条命令,并返回该命令的输出
  13.         output = subprocess.check_output(shlex.split(cmd), stderr=subprocess.STDOUT)
  14.         return output.decode() + os.getcwd() + '>'
复制代码
实现send函数
  1. def send(self):
  2.     # 连接到target:port
  3.     self.socket.connect((self.args.target, self.args.port))
  4.     # 创建个try/catch块,这样就能直接用Ctrl+C组合键手动关闭连接
  5.     try:
  6.         # 创建一个大循环,接收target返回的数据
  7.         while True:
  8.             # 等待用户输入新的内容,再把新的内容发给target
  9.             buffer = input() + '\n'
  10.             self.socket.send(buffer.encode())
  11.             if buffer.startswith("get"):
  12.                 get_file(buffer, self.socket)
  13.             elif buffer.startswith("upload"):
  14.                 send_file(buffer, self.socket)
  15.             else:
  16.                 recv_len = 4096
  17.                 response = ''
  18.                 # 读取socket本轮返回的数据,如果socket里的数据目前已经读到头,就退出小循环
  19.                 while recv_len:
  20.                     data = self.socket.recv(4096)
  21.                     recv_len = len(data)
  22.                     response += data.decode('utf-8', errors='ignore')
  23.                     if recv_len < 4096:
  24.                         break
  25.                 # 检查刚才有没有实际读出什么东西来,如果读出了什么,就输出到屏幕上
  26.                 if response:
  27.                     print(response, end='')
  28.     except KeyboardInterrupt:
  29.         print("User Terminated.")
  30.         self.socket.close()
  31.         sys.exit()
复制代码
实现文件上传功能
  1. def send_file(cmd, client_socket):
  2.     filename = cmd.split()[1]
  3.     if os.path.isfile(filename):  # 判断文件是否存在
  4.         size = os.path.getsize(filename)  # 获取文件大小
  5.         client_socket.send(str(size).encode() + b'\n')  # 发送数据长度
  6.         with open(filename, "rb") as f:
  7.             client_socket.send(f.read())
  8.     else:
  9.         client_socket.send("File Not Exist".encode())
复制代码
实现文件下载功能
  1. def get_file(buffer, socket):
  2.     cmd, filename = buffer.split(" ")
  3.     filename = filename.replace("\n", "")
  4.     file_size = int(socket.recv(64).decode().strip('\n'))
  5.     print("File Size:%s" % (file_size))
  6.     with open(filename, "wb") as f:
  7.         received_size = 0
  8.         while received_size < file_size:
  9.             size = min(4096, file_size - received_size)
  10.             data = socket.recv(size)
  11.             f.write(data)
  12.             received_size += len(data)
  13.             print("Download: {:.2f}%".format(received_size / file_size * 100))
  14.     print("File '{}' downloaded successfully.".format(filename))
  15.     print('Enter Command >', end="")
复制代码
整体代码

Github
代码测试

shell:


上传文件:


下载文件:



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4