python版netcat

从《python黑帽子》上学来的,不过简化了它的功能,只保留了shell。其实就是个正向shell。

实现过程

程序分为两部分,client和server。
clinet的功能是:

  1. 连接服务端

  2. 发送命令

  3. 接收命令执行结果

对应的函数为client_sender()

server的功能是:

  1. 建立监听-->server_loop()

  2. 接收命令-->client_handler()

  3. 执行命令-->run_command()

  4. 发送执行结果-->client_handler()

2到4步形成一个循环。

代码

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

import sys
import socket
import threading
import subprocess
import argparse

listen = False
target = ""
port = 0

def usage():
    parse = argparse.ArgumentParser(description="usage:")
    parse.add_argument("-t", "--target", action="store", default="", help="target host")
    parse.add_argument("-p", "--port", action="store", default="", help="the target port")
    parse.add_argument("-l", "--listen", action="store", default="", help="listen on [host]:[port]")
    args = parse.parse_args()
    return args

# 客户端函数
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 "\n[*]Exception! Exiting.\n"
    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:
        clien_socket, addr = server.accept()
        print "[*]Connected to %s:%s\n" % (addr[0], addr[1])
        clien_thread = threading.Thread(target=client_handler, args=(clien_socket,))
        clien_thread.start()

def run_command(command):  # 服务端
    command = command.rstrip()
    try:
        output = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True)
    except:
        output = "Faild to execute command.\r\n"
    return output

# 执行命令,返回执行结果
def client_handler(client_socket):
    while True:
        client_socket.send("<shell:#>")
        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 target

    args = usage()
    if len(args.listen):
        listen = True
    if len(args.target):
        target = args.target
    if len(args.port):
        port = int(args.port)

    if not listen and len(target) and port > 0:  # 不监听,只发送数据
        # 输入数据
        buffer = sys.stdin.read()
        # 发送数据
        client_sender(buffer)
    if listen:  # 监听
        server_loop()
if __name__ == "__main__":
    main()

ps: 只能在Linux下使用,客户端连接时以ctrl+d结束输入而非回车。

标签: none

添加新评论