编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

取代netcat

wxchong 2024-06-13 22:31:38 开源技术 16 ℃ 0 评论
import argparse
import socket
import shlex
import subprocess
import sys
import textwrap
import threading

def execute(cmd):
    cmd=cmd.strip()
    if not cmd:
        return
    output=subprocess.check_output(shlex.split(cmd),stderr=subprocess.STDOUT)
    return output.decode()
class NetCat:
    def __init__(self,args,buffer=None):
        self.args=args
        self.buffer=buffer
        self.socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        self.socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #reuse socket if possible
    def run(self):
        if self.args.listen:
            self.listen() #listen for connections if specified in args
        else:
            self.send()
    def send(self): #send data to server if not listening
        self.socket.connect((self.args.target,self.args.port)) #connect to server
        if self.buffer: #if buffer is specified, send it
            self.socket.send(self.buffer.encode()) #send buffer to server
        try:
            while True: #keep sending data to server until connection is closed
                recv_len=1
                response=''
                while recv_len: #keep receiving data from server until connection is closed or buffer is full
                    data=self.socket.recv(4096) #receive data from server in 4096 byte chunks
                    recv_len=len(data) #get length of data received from server
                    response+=data.decode() #decode data received from server and add to response string
                    if recv_len<4096: #if less than 4096 bytes received, connection is closed or buffer is full
                        break #break out of loop and print response string to console
                    if response: #if response string is not empty, print it to console
                        print(response) #print response string to console
                        buffer=input('> ') #get input from console and store in buffer variable
                        buffer+='\n' #add newline to buffer variable to send to server as newline delimited data
                        self.socket.send(buffer.encode()) #send buffer to server as newline delimited data
        except KeyboardInterrupt: #if user presses ctrl+c, close connection to server and exit program
            print('User terminated connection') #print message to console that user terminated connection to server
            self.socket.close() #close connection to server
            sys.exit()
    def listen(self): #listen for connections from client if specified in args
        self.socket.bind((self.args.target,self.args.port)) #bind socket to specified target and port
        self.socket.listen(5) #listen for connections from client in socket with a backlog of 5 connections waiting to be accepted
        while True: #keep listening for connections from client until program is terminated or connection is closed by client or server
            client_socket, client_address=self.socket.accept() #accept connection from client and store client socket and client address in variables
            print('[*] Accepted connection from: %s:%d'% (client_address[0],client_address[1])) #print message to console that connection from client was accepted and store client address in variables
            client_thread=threading.Thread(target=self.handle_client,args=(client_socket,)) #create new thread to handle client connection and store client socket in variables
            client_thread.start() #start new thread to handle client connection and store client socket in variables
    def handle(self,client_socket): #handle client connection if specified in args and listen for connections from client if specified in args
        if self.args.execute: #if user specified command to execute in args, execute command and send output to client as newline delimited data
            output=execute(self.args.execute)
            client_socket.send(output.encode()) #send output to client as newline delimited data
        elif self.args.upload: #if user specified file to upload in args, upload file to server and send output to client as newline delimited data
            file_buffer=b'' #create buffer variable to store file data in bytes format
            while True: #keep reading file data from client until file is completely read and stored in buffer variable in bytes format
                data=client_socket.recv(1024) #read file data from client in 1024 byte chunks and store in variable in bytes format
                if data:
                    file_buffer+=data #append file data to buffer variable in bytes format if data is not empty
                else:
                    break
            with open(self.args.upload,'wb') as f: #open file specified by user in write binary mode and store in variable in bytes format
                f.write(file_buffer) #write file data to file specified by user in write binary mode and store in variable in bytes format
            message=f'Saved file {self.args.upload}' #create message to send to client as newline delimited data and store in variable in bytes format
            client_socket.send(message.encode()) #send message to client as newline delimited data and store in variable in bytes format
        elif self.args.command: #if user specified command shell in args, create command shell and send output to client as newline delimited data
            cmd_buffer=b'' #create buffer variable to store command data in bytes format
            while True: #keep reading command data from client until command is completely read and stored in buffer variable in bytes format
                try:
                    client_socket.send(b'BHP:#>') #send message to client as newline delimited data and store in variable in bytes format to indicate that server is ready to receive command data from client
                    while '\n' not in cmd_buffer.decode(): #keep reading command data from client until newline character is detected and stored in buffer variable in bytes format to indicate that command is completely read from client
                        cmd_buffer+=client_socket.recv(64) #read command data from client in 64 byte chunks and store in variable in bytes format to indicate that command is completely read from client
                    response=execute(cmd_buffer.decode()) #execute command and store output in variable in bytes format to indicate that command is completely read from client
                    if response: #if command output is not empty, send command output to client as newline delimited data and store in variable in bytes format to indicate that command output is completely read from client and ready to be sent to client
                        client_socket.send(response.encode()) #send command output to client as newline delimited data and store in variable in bytes format to indicate that command output is completely read from client and ready to be sent to client
                    cmd_buffer=b''
                except Exception as e: #if exception occurs, send exception message to client as newline delimited data and store in variable in bytes format to indicate that exception message is completely read from client and ready to be sent to client
                    print(f'server killed {e}')
                    self.socket.close()
                    sys.exit()


if __name__=="__main__":
    parser=argparse.ArgumentParser(description="BHP Net Tool",
    formatter_class=argparse.RawDescriptionHelpFormatter,
    epilog=textwrap.dedent('''Example:  
    python netcat.py -t 192.168.1.1 -p 5555 -l -c  # command shell
    python netcat.py -t 192.168.1.1 -p 5555 -l -u=mytest.txt # upload to file
    python netcat.py -t 192.168.1.1 -p 5555 -l -e="cat /etc/passwd" # execute command
    echo 'ABCDEFGH' | python netcat.py -t 192.168.1.1 -p 135 # echo local text to server port 135
    python netcat.py -t 192.168.1.1 -p 5555  # connect to server'''))
    parser.add_argument('-c','--command',action='store_true',help='command shell')
    parser.add_argument('-e','--execute',help='execute specified command')
    parser.add_argument('-l','--listen',action='store_true',help='listen mode')
    parser.add_argument('-p','--port',type=int,default=5555,help='specified port')
    parser.add_argument('-t','--target',default='192.168.1.10',help='specified IP')
    parser.add_argument('-u','--upload',help='upload file')
    args=parser.parse_args()
    if args.listen:
        buffer=''
    else:
        buffer=sys.stdin.read()
    
    nc=NetCat(args,buffer.encode())
    nc.run()

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表