当前位置: 首页 > Python, 代码艺术, 安全工具 > 正文

简单NetCat的实现

在之前的博文《NC入门笔记》 中简单介绍了NC的四种常见的使用技巧。在本篇博文中将用python实现NC几个常用的功能。基本实现很简单,就是建立TCP socket连接进行通信,关于python的socket编程可以看我之前的文章:《python网络编程基础》。在命令执行这块就是使用subprocess(subprocess 模块允许你大量产生新的进程,然后连接到它们的输入/输出/错误管道,并获取它们的返回码)。它会创建子进程并在子进程中执行命令,和c中的fork出一个子进程,然后在子进程中运行exec执行另外一个进程类似。由于采用python单文件语编写,因此可以跨平台使用(在Windows下可以使用py2exe等打包程exe独立运行)。

首先,导入需要的python模块,并定义一些必要的全局变量:

import sys
import socket
import getopt
import threading
import subprocess

listen = False
command = False
upload = False
execute = ""
target = ""
upload_dest = ""
port = 0

编写主函数部分:使用getopt解析参数,这里的NC实现的基本的功能:1)文字交互; 2)远程shell连接; 3)文件上传。并根据参数选择执行server_loop()部分,还是发送数据部分的client_sender()函数:

def main():
    global listen
    global port
    global execute
    global command
    global upload_dest
    global target

    if not len(sys.argv[1:]):
        usage()

    # read the commandline options
    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 opt,arg in opts:
        if opt in ("-h", "--help"):
            usage()
        elif opt in ("-l", "--listen"):
            listen = True
        elif opt in ("-e", "--execute"):
            execute = arg
        elif opt in ("-c", "--command"):
            command = True
        elif opt in ("-u", "--upload"):
            upload_dest = arg
        elif opt in ("-t", "--target"):
            target = arg
        elif opt in ("-p", "--port"):
            port = int(arg)
        else:
            assert False, "unhandled Option"
    
    # connection remote server
    #if not listen and len(target)

    # read the buffer from the commandline
    if not listen and len(target) and port > 0:
        # send CTRL-D in order not be block
        buffer = sys.stdin.read()
        client_sender(buffer)

    # upload things, execute commands,and drop a shell back
    if listen:
        server_loop()

接下来就是server_loop()部分,还是发送数据部分的client_sender()函数:

def server_loop():
    global target

    # listen all interfaces if no target is defined
    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()

        # spin off a thread to handle our new client
        client_thread = threading.Thread(target=client_handler,args=(client_socket,))
        client_thread.start()

server_loop()部分建立TCP socket循环监听本地端口接收TCP连接并创建一个新的线程处理函数client_handler()。其线程处理函数如下:

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

    # check for upload
    if len(upload_dest):
        # read in all of the bytes and write to our destination
        file_buffer  = ""

        # keep reading data until none is available

        while True:
            data = client_socket.recv(1024)
            if not data:
                break
            else:
                file_buffer += data

        # now we take these bytes and try to write them out
        try:
            file_desc = open("upload_dest","wb")
            file_desc.write(file_buffer)
            file_desc.close()

            # acknowledge that we wrote the file out
            client_socket.send("Successfully saved file to %s\r\n % uplaod_dest")
        except:
            client_socket.send("Failed to save file to %s\r\n" % upload_dest)

    # check for command execution
    if len(execute):
        # run the command
        output = run_command(execute)
        
        client_socket.send(output)

    # now we go into another loop if a command shell was requested
    if command:
        while True:
            # show a simple prompt
            client_socket.send("CMD:#> ")
            # now we receive until we see a linefeed (enter key)
            cmd_buffer = ""
            while "\n" not in cmd_buffer:
                cmd_buffer += client_socket.recv(1024)

            # send back the command output
            response = run_command(cmd_buffer)

            # send back the response
            client_socket.send(response)

在不使用-l参数时,就是像远程服务端发送数据,基本就是socket数据发送,详见下面代码:

def client_sender(buffer):
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.setblocking(0)
    #client.settimeout(5)

    try:
        client.connect((target, port))

        if len(buffer):
            client.send(buffer)
        
        while True:

            # now wait for data back
            recv_len = 1
            response = ""

            while recv_len:
                data = client.recv(4096)
                recv_len = len(data)
                response = data

                if recv_len < 4096:
                    break

            print response,

            # wait for more input
            buffer = raw_input("")
            buffer += "\n"

            client.send(buffer)

    except:
        print "[*] Exception! Exiting"
        client.close()

至此,一个基本的NC的简单框架算是基本完成了。当然还有其他一些简单的函数部分,这里就不一一说明,完整的代码见GitHub:

https://github.com/Lingerhk/py_script/blob/master/simple_netcat.py

 



这篇博文由 s0nnet 于2015年12月08日发表在 Python, 代码艺术, 安全工具 分类下, 欢迎你在下面发表评论
如无特别说明,独木の白帆发表的文章均为原创,欢迎大家转载,转载请注明: 简单NetCat的实现 | 独木の白帆
关键字: ,

简单NetCat的实现:目前有2 条留言

  1. Wow, fantastic blog layout! How long have you been blogging for?
    you made blogging look easy. The overall look of
    your website is magnificent, as well as the content!

    2017-10-21 上午8:07 [回复]
    • s0nnet:

      haha,thanks for coming!

      2017-11-17 下午10:29 [回复]

发表评论

快捷键:Ctrl+Enter