取代netcat

简介

NetCat是一个非常简单的Unix工具,可以读、写TCP或UDP网络连接(network
connection)。它被设计成一个可靠的后端(back-end) 工具,能被其它的程序
程序或脚本直接地或容易地驱动。同时,它又是一个功能丰富的网络调试和开
发工具,因为它可以建立你可能用到的几乎任何类型的连接,以及一些非常有
意思的内建功能。NetCat,它的实际可运行的名字叫nc,应该早很就被提供,
就象另一个没有公开但是标准的Unix工具。

nc命令的使用

实现代码

#!/usr/bin/env python
# coding:utf-8

import sys
import socket
import getopt
import threading
import subprocess
import time

# 定义全局变量
listen = False
command = False
upload = False
execute = ""
target = ""
upload_destination = ""
port = 0
DEBUG = False

# 使用说明


def usage():
    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 command shell"
    print "-u --upload=destination - upon receiving connection upload a file and write to " \
          "[destinaiton]"
    print
    print
    print "Examples:"
    print "netcat.py -t 192.168.1.1 -p 5555 -l -c"
    print "netcat.py -t 192.168.1.1 -p 5555 -l -u c:\\target.exe"
    print "netcat.py -t 192.168.1.1 -p 5555 -l -e \"cat /etc/passwd\""
    print "echo 'ABCDEFGHI'| ./netcat.py -t 192.168.1.11 -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", "target", "port", "command", "upload"])
    except getopt.GetoptError, 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", "--command"):
            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:
        # 标准输入流可以重定向
        buffer = sys.stdin.read()
        client_sendaller(buffer)

    elif listen:
        # 开始监听
        server_loop()

# 客户端收发数据


def client_sendaller(buffer):
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    
    try:
        client.connect((target, port))
        if len(buffer):
            client.sendall(buffer)
            time.sleep(1)
            client.sendall("EOF")

        while True:

            respose = ""

            # 接收数据
            while True:
                data = client.recv(4096)
                respose += data
                # 用长度来判断接收结束
                if len(data) < 4096:
                    break
            print respose,

            # 发送新的数据
            buffer = raw_input("")
            buffer += "\n"
            client.sendall(buffer)

    except socket.error, err:
        print err
    finally:
        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.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server.bind((target, port))

    server.listen(5)

    while True:
        client_socket, addr = server.accept()
        if DEBUG:
            print "%s:%d" % addr
        # 创建新线程
        client_thread = threading.Thread(
            target=client_hanlder, args=(client_socket,))
        client_thread.start()
        if DEBUG:
            print client_thread.getName()

# 服务器线程


def client_hanlder(client_socket):
    global upload
    global execute
    global command

    # 如果要上传文件
    if len(upload_destination):
        file_buffer = ""

        while True:
            data = client_socket.recv(1024)
            # 文件结束
            if data == "EOF":
                break
            file_buffer += data
        # 写入数据
        try:
            file_descriptor = open(upload_destination, "wb")
            file_descriptor.write(file_buffer)
            file_descriptor.close()

            client_socket.sendall(
                "Successfully saved file to %s\r\n" % upload_destination)
        except:
            client_socket.sendall(
                "Failed to saved file to %s\r\n" % upload_destination)

    # 如果要执行命令
    if len(execute):
        output = run_command(execute)
        client_socket.sendall(output)

    # 如果需要命令行shell
    if command:
        while True:
            client_socket.sendall("#")
            cmd_buffer = ""
            while "\n" not in cmd_buffer:
                cmd_buffer += client_socket.recv(2048)

            # 执行命令
            response = run_command(cmd_buffer)
            client_socket.sendall(response)


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


if __name__ == '__main__':
    main()

测试运行

服务器端

./netcat.py -l -p 8080 -c

客户端

./netcat.py -t 127.0.0.1 -p 8080
CTRL-D
ls - l

访问服务器

echo -ne 'GET / HTTP/1.1\r\nHost:www.baidu.com\r\n\r\n' | ./netcat.py -t www.baidu.com -p 80

也可以使用重定向符上传文件
不过没有对大文件优化

你可能感兴趣的:(取代netcat)