Summary

We observed a threat actor leveraging GitHub repositories to execute Braodo Stealer a Sophisticated Python based Stealer. The Author hosted all the necessary python packages to run the stealer within the GitHub repository. The infection layers included a Byte Order Marker (BOM), a type of obfuscator designed to make the victim believe it is a Chinese file. The BOM then renders the content in Chinese. Even Google translates the content into what appears to be a legitimate file containing seemingly random statements. The main difference we can see here is the Version 2.0 employs AES encryption followed by BOM & pyobfuscate obfuscation method which makes the Researchers difficult to Analyze further

Infection Chain

Fig 1: Infection Killchain

Technical Analysis

GitHub Repository serving malicious files

As our automated threat Intelligence platform continuously crawls the internet, including GitHub Repositories, some of our entries show us suspicious files such as bat, python packages. These were present in a repository that belonged to the same GitHub User. This prompted us to dive into the repository and conduct an Investigation, which led to the discovery of the Braodo stealer being served from GitHub containing multi-stage obfuscation methods.

Fig 2: GitHub Page Inspection

Obfuscated Batch script

The initial Bat script contains Chinese strings that can be translated to normal English statements without any errors. This leads the victim to run the file without hesitation. But investigating further reveals that it employs a BOM (Byte Order Marker) obfuscation technique, which deceives text editors and other command-line tools to interpret the script as UTF-8. This tactic makes the script appear to be gibberish or some random statements in Chinese, effectively making it harder to analyse further.

Fig 3: Obfuscated Batch Script (BOM)

The system interprets the commands as gibberish as threat actor embedded “FF FE” in the beginning of the file, The above decoded content has been revealed by removing the bytes of “FF FE” from the beginning

Code

if content.startswith(b'\xff\xfe'):
    content = content[2:]

Python script (Obfuscated)

Lib\prt.py contains obfuscated code that employs the popular obfuscation method pyobfuscate, which is available in open source. In addition to AES encryption, the decryption key was revealed within the obfuscated code itself. We used a de-obfuscation tool shared by pyobfuscate.com/pyd by ‘pyobfuscate‘ and tweaked it slightly to print to the console. This revealed the AES encryption in place for hardcoded encrypted values from pyc and pye with the key IlllIllllllllIlIllIIlIIIllIlIIlIlII. We spent some time to extract the script manually and executed it by feeding the required fields. The final payload of the Braodo stealer was decrypted.

Fig 4: De-Obfuscation of Python Snippet

Code for Deobfuscation

import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning) 

class compile:
    def __init__(self):
        try:
            __import__('builtins').? = __import__('builtins').exec.?[0]
        except:
            __import__('builtins').? = __import__('builtins').exec

        for ? in dir(__import__('builtins').compile):
            try:
                __import__('builtins').?("self.{0} = __import__('builtins').compile.{0}".format(str(?)), {'self': self})
            except AttributeError:
                pass
        self.? = [vars(__import__('builtins')).copy()['compile'], 0]
        self.__dir__ = self.?[0].__dir__
        try:
            del __import__('builtins').?
        except:
            pass
        return None
    
    def __repr__(self):
        return str(self.?[0])

    def __call__(self, *args, **kwargs):
        #print(eval(__import__('ast').unparse(args[0])[4:]))
        print(__import__('ast').unparse(args[0]))
        exit(0)

    @property
    def __dict__(self):
        return self.?[0].__dict__
    @property
    def __class__(self):
        return self.?[0].__class__

compile = compile()
__import__('builtins').compile = compile

file = open(input(">> input file path: "), 'rb').read()
print('>> source code: ')
exec(file)

Braodo Layer decoder

from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from Crypto.Protocol.KDF import PBKDF2
from Crypto.Util.Padding import unpad
import hashlib
from base64 import b85decode as b85

#Key
httpspyobfuscatecom = "KEY"
#Main Braodo script
pyc = """Obfuscated Code"""
pye = """Obfuscated Code"""

try:
    def d(b, p):
        c = b85(b.encode('utf-8'))
        r = AES.new(PBKDF2(p, c[:16], dkLen=32, count=1000000), AES.MODE_GCM, nonce=c[16:32])
        return r.decrypt_and_verify(c[48:], c[32:48]).decode('utf-8')
    fo = open("braodo.py", "w", encoding="utf-8")
    fo.write(d(pyc + pye, httpspyobfuscatecom))
    #print(d(pyc + pye, httpspyobfuscatecom))
except:
    def a(i):
        return unpad(AES.new(hashlib.sha256(str(list(pyobfuscate)[0][0] + list(pyobfuscate)[1][0][:-1]).encode()).digest()[:24], AES.MODE_CBC, i[:AES.block_size]).decrypt(i[AES.block_size:]), AES.block_size).decode()
    print(a(pyobfuscate[1][2]))

Braodo Stealer (Python)

The de-obfuscated Python code, which is the core payload of Braodo stealer, reveals that it also drops a web browser extension. This extension is later used to collect cookie information and post it to the URL chinaischo.in/upload.php, allowing the collected cookies to be handled separately.

Fig 5: Extension downloaded & Steals

Exfiltration

Below are the details it looks for and sent to Telegram bot by encrypting all the information into Base64.

  • Computer Name
  • IP Information (using ipinfo.io)
  • Browsers User data (Typical path: browser_name\User Data\\)
  • Facebook session & Other Facebook details
  • Credit card details (All payment methods)
  • logins.json & hostname
  • Passwords (SELECT a11, a102 FROM nssPrivate WHERE a102 = ?;)
  • Login Data (SELECT action_url, username_value, password_value FROM logins from login_db)
  • Cookies (in the name of edge_Cookies_Fb_*, chrome_Cookies_Fb_*, brave_Cookies_Fb_*, Cookies_Fb_* from extension) cookies.zip/background.js
  • Exfiltrate information from Cookies (SELECT host_key, name, path, encrypted_value, expires_utc, is_secure, is_httponly FROM cookies)

List of Browsers it looks for,

Chromium Thorium 7Star Cent Browser
Iridium Vivaldi Coowon Epic Privacy Browser
Catalina Liebao QIP Comodo Dragon
Orbitum Sputnik Brave Browser Slimjet
Yandex Sogou Discord Speed360

All these information was archived and sent to Telegram Bot and will be deleted from the victim machine immediately.

Fig 6: Data Exfiltration

Fig 7: Facebook cookie and other information

The archive will get deleted once the zipped file sent to Telegram Bot contains all the exfiltrated information.

Fig 8: Data sent to Telegram Bot & Deleted

Indicator of Compromise (IOCs)

# Type/ Filename IOCs
1 zip 801016eff72de82ecbb575793c45a9f0c9c830d0afc3282b31e55fa5f7736242
2 Stage #1 BAT 54cac2be9f051e300436c8cec8c6186182e551e50a95d77822f96869a37e6408
3 Stage #1 BAT cf138624ea870a821742b55d764da16a720ae9c0ace7cc00bc5ae85e66563d46
4 Python ea68356bf6e9c23ebe0ebf05a39f8bc5b8c27a9515c45aae0769e6905373e0df
5 Python (AES decrypted layer) 5335158b14e4e5e980d397f6ca0ae5b7c8b4790da9e4d3d245f3e70674c87bc3
6 Python (Braodo) 6403092566f0ce88db552cd8fd5931c06eb8d173c09dd88a5b7d98734a9add3e
7 Python (Braodo) ecd08093eae07e239b70d3d00b90c139173e548c3ec6e39462e93f4aef101de9
8 Zip 8d9f58762885b3befce4d0bf7103f9c3d2f3b0ed45cc4e500fe78614e60aef64
9 Zip 5256649361bd2f5be074f5fccfd937e89b4ee946b3aafb0cc5fb146b2a4a63c4
10 Zip 7ba5790ff595c852fa45c02fcf40f8118c6584e7382e2bed1357e9efedcb2866

GitHub Pages

  • github[.]com/bvit17
  • github[.]com/KevinDark5
  • github[.]com/abarekl1
  • github[.]com/eed8989
  • github[.]com/eggege342358

Telegram BOTS

  • 7686322208:AAEqS0m2oyvfjVi6gZg3MeY_KouflxGZcok
  • 7520995374:AAHV5sS_YzF3rpMs6aKTnl2ErTX0DxANoqw

Domain & C2C

  • chinaischo.in/upload.php
  • nonever.net/uploads

img
Gurumoorthi

Rust Engineer ||

Comments

Your E-mail address not be published

    You be the first comment

Leave a Reply