草庐IT

Python实现简易版Netcat

顾北清 2023-03-28 原文

Netcat

Netcat是一种网络工具,也称为“nc”,可用于在计算机网络之间进行TCP/IP或UDP连接。它可以用于连接到其他计算机上的端口,发送和接收数据,扫描端口以及创建服务器等。

使用Python实现简易版

整体功能规划

if __name__ == "__main__":
    # argparse库是python标准库里面用来处理命令行参数的库
    # 传递不同的参数,就能控制这个程序执行不同的操作
    parser = argparse.ArgumentParser(       # 创建一个解析对象
        description="ReverseShell",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        # 帮助信息,程序启动的时候如果使用--help参数,就会显示这段信息
        epilog=textwrap.dedent(
            """
                python Simple_Netcat.py -t <IP> -p 5555 -l -c   # command shell
                python Simple_Netcat.py -t <IP> -p 5555         # connect to server
                get <file>                                      # download file
                upload <file>                                   # upload file
            """
        ),
    )

    # -c参数,打开一个交互式的命令行shell;
    parser.add_argument("-c", "--command", action="store_true", help="command shell")
    # -l参数,创建一个监听器
    parser.add_argument("-l", "--listen", action="store_true", help="listen ")
    # -p参数,指定要通信的端口
    parser.add_argument("-p", "--port", type=int, default=5555, help="specified port ")
    # -t参数,指定要通信的目标IP地址
    parser.add_argument("-t", "--target", default="127.0.0.1", help="specified IP")

    args = parser.parse_args()

    nc = SimpleNetcat(args)
    nc.run()

创建NetCat类:

class SimpleNetcat:
    def __init__(self, args):
        # 我们用main代码块传进来的命令行参数,初始化一个NetCat对象,然后创建一个socket对象
        self.args = args
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    # 如果NetCat对象是接收方,run就执行listen函数
    # 如果是发送方,run就执行send函数
    def run(self):
        if self.args.listen:
            self.listen()
        else:
            # 用于启动时输出
            print('Enter the first command >',end='')
            self.send()

实现listen功能:

# 监听数据
def listen(self):
    self.socket.bind((self.args.target, self.args.port))
    # listen(n)传入的值, n表示的是服务器拒绝(超过限制数量的)连接之前,操作系统可以挂起的最大连接数量。
    self.socket.listen(5)

    # 用一个循环监听新连接,并把已连接的socket对象传递给handle函数执行任务
    while True:
        # accept()等待传入连接。,返回代表连接的新套接字以及客户端的地址。
        client_socket, _ = self.socket.accept()
        # 给每个客户端创建一个独立的线程进行管理
        client_thread = threading.Thread(target=self.handle, args=(client_socket,))
        client_thread.start()

当程序监听到指令之后,就可以执行相应的任务:

# 执行传入的任务
def handle(self, client_socket):
    # 如果要执行命令,handle函数就会把该命令传递给execute函数
    # 然后把输出结果通过socket发回去
    if self.args.command:
        # 创建shell,先创建一个循环,向发送方发一个提示符,
        # 然后等待其发回命令。每收到一条命令,就用execute函数执行它,然后把结果发回发送方
        while True:
            try:
                cmd_buffer = b''
                # 循环接收发送端命令
                while '\n' not in cmd_buffer.decode():
                    cmd_buffer += client_socket.recv(64)
                cmd = cmd_buffer.strip().decode()
                if cmd.startswith("get"):
                    send_file(cmd, client_socket)
                elif cmd.startswith("upload"):
                    get_file(cmd, client_socket)
                else:
                    response = execute(cmd_buffer.decode())
                    if response:
                        client_socket.send(response.encode())
            except Exception as e:
                print(f'Server killed {e}')
                self.socket.close()
                sys.exit()

实现execute函数

# execute函数用于接受一条命令并执行,然后将结果作为一段字符串返回
def execute(cmd):
    if cmd.startswith('cd '):
        # 切换目录
        os.chdir(cmd[3:].strip())
        return os.getcwd() + '>'
    else:
        cmd = cmd.strip()
        if not cmd:
            return
        # subprocess库提供了一组强大的进程创建接口,可以通过多种方式调用其他程序。
        # check_output函数会在本机运行一条命令,并返回该命令的输出
        output = subprocess.check_output(shlex.split(cmd), stderr=subprocess.STDOUT)
        return output.decode() + os.getcwd() + '>'

实现send函数

def send(self):
    # 连接到target:port
    self.socket.connect((self.args.target, self.args.port))
    # 创建个try/catch块,这样就能直接用Ctrl+C组合键手动关闭连接
    try:
        # 创建一个大循环,接收target返回的数据
        while True:
            # 等待用户输入新的内容,再把新的内容发给target
            buffer = input() + '\n'
            self.socket.send(buffer.encode())
            if buffer.startswith("get"):
                get_file(buffer, self.socket)
            elif buffer.startswith("upload"):
                send_file(buffer, self.socket)
            else:
                recv_len = 4096
                response = ''
                # 读取socket本轮返回的数据,如果socket里的数据目前已经读到头,就退出小循环
                while recv_len:
                    data = self.socket.recv(4096)
                    recv_len = len(data)
                    response += data.decode('utf-8', errors='ignore')
                    if recv_len < 4096:
                        break
                # 检查刚才有没有实际读出什么东西来,如果读出了什么,就输出到屏幕上
                if response:
                    print(response, end='')
    except KeyboardInterrupt:
        print("User Terminated.")
        self.socket.close()
        sys.exit()

实现文件上传功能

def send_file(cmd, client_socket):
    filename = cmd.split()[1]
    if os.path.isfile(filename):  # 判断文件是否存在
        size = os.path.getsize(filename)  # 获取文件大小
        client_socket.send(str(size).encode() + b'\n')  # 发送数据长度

        with open(filename, "rb") as f:
            client_socket.send(f.read())
    else:
        client_socket.send("File Not Exist".encode())

实现文件下载功能

def get_file(buffer, socket):
    cmd, filename = buffer.split(" ")
    filename = filename.replace("\n", "")
    file_size = int(socket.recv(64).decode().strip('\n'))
    print("File Size:%s" % (file_size))

    with open(filename, "wb") as f:
        received_size = 0
        while received_size < file_size:
            size = min(4096, file_size - received_size)
            data = socket.recv(size)
            f.write(data)
            received_size += len(data)
            print("Download: {:.2f}%".format(received_size / file_size * 100))
    print("File '{}' downloaded successfully.".format(filename))
    print('Enter Command >', end="")

整体代码

完整代码可以参考我的Github仓库:Github

代码测试

shell:

上传文件:

下载文件:

有关Python实现简易版Netcat的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  3. Python 相当于 Perl/Ruby ||= - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。

  4. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  5. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  6. python - 如何读取 MIDI 文件、更改其乐器并将其写回? - 2

    我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的

  7. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  8. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

  9. MIMO-OFDM无线通信技术及MATLAB实现(1)无线信道:传播和衰落 - 2

     MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO

  10. python ffmpeg 使用 pyav 转换 一组图像 到 视频 - 2

    2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p

随机推荐