最近在看 Python黑帽子–黑客与渗透测试编程之道 这本书 发现这本书的代码实现都是使用python2 的于是我就想使用python3来实现 缓慢更新中
python2版本 有一个博主写的特别好 这是链接 http://blog.csdn.net/u012763794/article/details/50612756 部分注释我使用的这位博主的 而且这位博主的注释写的比我好 我的注释写的很少
这位博主也也不错 他对代码的每一个模块做了解释 http://blog.csdn.net/SKI_12/article/details/71152826
发现了一位用python3来实现的博主
https://my.oschina.net/oby/blog/804064#comment-list
TCP客户端
代码
import socket
target_host = "www.baidu.com"
target_port = 80
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect((target_host,target_port))
aaa = "GET / HTTP/1.1\r\nHost:baidu.com\r\n\r\n"
client.send(str.encode(aaa)) #这里只需要注意 send在python3中 接收的是 bytes 只需要做一个转换就好
response = client.recv(4096)
print (bytes.decode(response))
UDP客户端
代码
import socket
target_host = '127.0.0.1'
terget_post = 12138
client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
client.sendto(str.encode('sdsdsdsdsdsd'),(target_host,terget_post)) #和tcp一样在这里做一个转换
data, addr = client.recvfrom(4096)
print (data)
使用nc验证 这里我就不贴验证的图了
TCP服务端
代码
import socket
import threading
bing_ip = '0.0.0.0'
bing_port = 12138
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((bing_ip,bing_port))
server.listen(5) #最大连接数
print ("[*] listen on %s:%d" % (bing_ip,bing_port))
def handle_client(client_socket): #客户端处理进程
request = client_socket.recv(1024)
print ("[*] Received: %s" % request) #接受类型并打印
client_socket.send(str.encode('ACK!'))
client_socket.close()
while True:
client,addr = server.accept()
print ("[*] Accepted connection from: %s:%d" % (addr[0],addr[1]))
client_handler = threading.Thread(target=handle_client,args=(client,))
client_handler.start()
这里的验证可以使用之前的tcp客户段来验证
取代netcat
这个简直了 由于python3 区分了str 和 bytes 所以有很多坑
这个我改了两个版本 一个是只能在linux上可以正常使用的版本 一个是兼容windows和linux的版本
兼容版 我引入了一个新的第三方库 chardet 来判断 字符编码
先贴linux版本
import sys
import socket
import getopt
import threading
import subprocess
listen = False
command = False
upload = False
execute = ""
target = ""
upload_destination = ""
port = ""
def run_command(command): #命令执行模块
command = command.rstrip()
try:
print (command)
output = subprocess.check_output(command, stderr = subprocess.STDOUT, shell = True )
except:
output = "Failed to execute command. \r\n"
return output #返回执行的结果
def client_handler(client_socket):# 上传 命令执行相关功能
global upload
global execute
global command
if len(upload_destination):
file_buffer = ""
while True:
data = client_socket.recv(1024)
if not data:
break
else:
file_buffer += data
try:
file_descriptor = open(upload_destination,"wb")
file_descriptor.write(file_buffer)
file_descriptor.close()
client_socket.send(str.encode("Successfully saved file to %s\r\n" % upload_destination))
except:
client_socket.send(str.encode("Failed to save file to %s\r\n" % upload_destination))
if len(execute):
output = run_command(execute)
client_socket.send(str.encode(output))
if command:
while True:
client_socket.send(str.encode("" ))
cmd_buffer = ""
cmd_buffer = str.encode(cmd_buffer)
while "\n" not in bytes.decode(cmd_buffer):
cmd_buffer += client_socket.recv(1024)
response = run_command(cmd_buffer)
print (response)
client_socket.send(response)
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 client_sender(buffer): #返回信息模块
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
client.connect((target,port))
if len(buffer):
client.send(str.encode(buffer))
while True:
recv_len = 1
response = ""
while recv_len:
data = client.recv(4096) #这时 data 为 bytes类型
data = bytes.decode(data) #这里需要转换为str 不然下面的 response += data 没法执行
recv_len = len(data)
response += data
if recv_len < 4096:
break
print (response)
buffer = input("")
buffer += "\n"
client.send(str.encode(buffer))
except Exception as e:
print (e)
print ("[*] Exception! Exiting.")
client.close()
def usage():
print ("BHP Net Tool")
print ()
print ("Usage:netcat.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 connection")
print ("-c --command - initialize a commandshell")
print ("-u --upload=destination - upon receiving connection upload a file and write to [destination]")
print ()
print ()
print ("Examples: ")
print ("netcat.py -t 192.168.0.1 -p 5555 -l -c")
print ("netcat.py -t 192.168.0.1 -p 5555 -l -u=c:\\target.exe" )
print ("netcat.py -t 192.168.0.1 -p 5555 -l -e=\"cat /etc/passwd")
print ("echo 'ABCDEFGHI' | python ./netcat.py -t 192.168.11.12 -p 135")
sys.exit(0)
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","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","--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 Optin"
if not listen and len(target) and port > 0:
buffer = sys.stdin.read()
client_sender(buffer)
if listen:
server_loop()
main()
linux版本和兼容版我的区别 我会在代码中注明 兼容版没有注释
代码
import sys
import socket
import getopt
import threading
import subprocess
from chardet import detect
listen = False
command = False
upload = False
execute = ""
target = ""
upload_destination = ""
port = ""
def run_command(command):
command = command.rstrip()
try:
command = bytes.decode(command)
print (command)
output = subprocess.check_output(command, stderr = subprocess.STDOUT, shell = True )
except Exception as b:
print (b)
output = "Failed to execute command. \r\n"
return output
def client_handler(client_socket):
global upload
global execute
global command
if len(upload_destination):
file_buffer = ""
while True:
data = client_socket.recv(1024)
if not data:
break
else:
file_buffer += data
try:
file_descriptor = open(upload_destination,"wb")
file_descriptor.write(file_buffer)
file_descriptor.close()
client_socket.send(str.encode("Successfully saved file to %s\r\n" % upload_destination))
except:
client_socket.send(str.encode("Failed to save file to %s\r\n" % upload_destination))
if len(execute):
output = run_command(execute)
client_socket.send(str.encode(output))
if command:
while True:
client_socket.send(str.encode("" ))
cmd_buffer = ""
cmd_buffer = str.encode(cmd_buffer)
while "\n" not in bytes.decode(cmd_buffer):
cmd_buffer += client_socket.recv(4096)
response = run_command(cmd_buffer)
bytestype = detect(response)
if bytestype["encoding"] == "GB2312": #我在这里加了一个字符编码判断当编码为 gbk时 先解码 因为py3 默认是utf-8
response = response.decode('gbk')
response = str.encode(response)
client_socket.send(response)
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 client_sender(buffer):
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
client.connect((target,port))
if len(buffer):
client.send(str.encode(buffer))
while True:
recv_len = 1
response = ""
while recv_len:
data = client.recv(4096)
recv_len = len(data)
data = bytes.decode(data)
response += data
if recv_len < 4096:
break
print (response)
buffer = input("")
buffer += "\n"
client.send(str.encode(buffer))
except Exception as e:
print (e)
print ("[*] Exception! Exiting.")
client.close()
def usage():
print ("BHP Net Tool")
print ()
print ("Usage:netcat.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 connection")
print ("-c --command - initialize a commandshell")
print ("-u --upload=destination - upon receiving connection upload a file and write to [destination]")
print ()
print ()
print ("Examples: ")
print ("netcat.py -t 192.168.0.1 -p 5555 -l -c")
print ("netcat.py -t 192.168.0.1 -p 5555 -l -u=c:\\target.exe" )
print ("netcat.py -t 192.168.0.1 -p 5555 -l -e=\"cat /etc/passwd")
print ("echo 'ABCDEFGHI' | python ./netcat.py -t 192.168.11.12 -p 135")
sys.exit(0)
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","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","--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 Optin"
if not listen and len(target) and port > 0:
buffer = sys.stdin.read()
client_sender(buffer)
if listen:
server_loop()
main()
usage()函数用于参数的说明帮助、当用户输入错误的参数时会输出相应的提示;
client_sender()函数用于与目标主机建立连接并交互数据直到没有更多的数据发送回来,然后等待用户下一步的输入并继续发送和接收数据,直到用户结束脚本运行;
server_loop()函数用于建立监听端口并实现多线程处理新的客户端;
run_command()函数用于执行命令,其中subprocess库提供多种与客户端程序交互的方法;
client_handler()函数用于实现文件上传、命令执行和与shell相关的功能,其中wb标识确保是以二进制的格式写入文件、从而确保上传和写入的二进制文件能够成功执行;
主函数main()中是先读取所有的命令行选项从而设置相应的变量,然后从标准输入中读取数据并通过网络发送数据,若需要交互式地发送数据需要发送CTRL-D以避免从标准输入中读取数据,若检测到listen参数为True则调用server_loop()函数准备处理下一步命令。
TCP代理
import sys
import socket
import threading
import binascii
def server_loop(local_host,local_port,remote_host,remote_port,receive_first):
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try :
server.bind((local_host,local_port))
except :
print ("[!!] Failed to listen on %s:%d"%(local_host,local_port))
print ("[!!] Check for other listening sockets or correct permissions.")
sys.exit(0)
print ("[*] Listening on %s:%d"%(local_host,local_port))
server.listen(5) #创建线程
while True:
client_socket, addr = server.accept()
#打印出本地连接信息
print ("[==>] Received incoming connection from %s:%d" % (addr[0],addr[1]))
#开启一个线程与远程主机通信
proxy_thread = threading.Thread(target=proxy_handler,args=(client_socket,remote_host,remote_port,receive_first))
proxy_thread.start()
def main():
if len(sys.argv[1:])!= 5:
print ("Usage: ./proxy.py [localhost] [localport] [remotehost] [remoteport] [receive_first]")
print ("Example: ./proxy.py 127.0.0.1 9000 10.12.132.1 9000 True")
sys.exit(0)
#本地监听
local_host = sys.argv[1]
local_port = int(sys.argv[2])
#远程监听
remote_host = sys.argv[3]
remote_port = int(sys.argv[4])
#告诉代理在发送给远程主机之前连接和接受数据
receive_first = 'True' #sys.argv[5]
if "True" in receive_first:
receive_first = True
else:
receive_first = False
#现在设置好我们监听socket
server_loop(local_host,local_port,remote_host,remote_port,receive_first)
def proxy_handler(client_socket,remote_host,remote_port,receive_first):
#连接远程主机
remote_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
remote_socket.connect((remote_host,remote_port))
#如果必要从远程主机接收数据
if receive_first:
remote_buffer = receive_from(remote_socket)
hexdump(remote_buffer)
#发送给我们的响应处理
remote_buffer = response_handler(remote_buffer)
if len(remote_buffer):
print ("[<==] sending %d bytes to localhost." % len(remote_buffer))
client_socket.send(str.encode(remote_buffer))
#现在我们从本地循环读取数据,发送个远程主机和本地主机
while True:
#从本地读取数据
local_buffer = receive_from(client_socket)
if len(local_buffer):
print ("[==>] Received %d bytes from localhost." % len(local_buffer))
hexdump(local_buffer)
#发送给我们的本地请求
local_buffer = request_handler(local_buffer)
#向远程主机发送数据
remote_socket.send(local_buffer)
print ("[==>] Sent to remote.")
#接收相应数据
remote_buffer = receive_from(remote_socket)
if len(remote_buffer):
print ("[<==] Received %d byte from remote." % len(remote_buffer))
hexdump(remote_buffer)
remote_buffer = response_handler(remote_buffer)
client_socket.send(remote_buffer)
print ("[<==] Sent localhost")
#如两边都没有数据 关闭连接
if not len(local_buffer) or not len(remote_buffer):
client_socket.close()
remote_socket.close()
print ("[*] No more data. Closing connections")
break
#十六进制导出函数
def hexdump(src, length=16):
result = []
# Python 3 renamed the unicode type to str, the old str type has been replaced by bytes
digits = 4 if isinstance(src, str) else 2
# xrange() was renamed to range() in Python 3.
for i in range(0, len(src), length):
s = src[i:i+length]
hexa = ' '.join(["%0*X" % (digits, (x))for x in s])
text = ''.join([chr(x) if 0x20 <= x < 0x7F else '.'for x in s])
result.append( "%04X %-*s %s" % (i, length*(digits + 1), hexa, text) )
print ('\n'.join(result))
def receive_from(connection):
buffer = ""
#超时时间
connection.settimeout(2)
try:
# 持续从缓存中读取数据直到没有数据或者超时
while True:
data = connection.recv(4096)
if not data:
break
data = bytes.decode(data)
buffer += data
buffer = str.encode(buffer)
except :
pass
return buffer
#对目标是远程主机的请求进行修改
def request_handler(buffer):
#数据包修改
return buffer
#对目标是本地主机的响应进行修改
def response_handler(buffer):
#数据包修改
return buffer
main()
这个花费时间最多的是 hexdump 模块 。。。。最后写完了发现我写的好繁琐 就直接使用这位博主的代码
https://my.oschina.net/oby/blog/804064#comment-list
待续。。。。。