336 0x600
localhost [127.0.0.1] 80 (www) open
reader@hacking:~/booksrc $ fg
nc -l -p 31337
whoami
root
The connection used by this exploit creates the following log file entries
on the server machine.
08/02/2007 13:37:36> Starting up..
08/02/2007 13:37:44> From 127.0.0.1:32828 "GET / HTTP/1.1" 200 OK
Even though the logged IP address cannot be changed using this method,
the request itself appears valid, so it won’t attract too much attention.
0x650 Overlooking the Obvious
In a real-world scenario, the other obvious sign of intrusion is even more
apparent than log files. However, when testing, this is something that is easily
overlooked. If log files seem like the most obvious sign of intrusion to you,
then you are forgetting about the loss of service. When the tinyweb daemon
is exploited, the process is tricked into providing a remote root shell, but it
no longer processes web requests. In a real-world scenario, this exploit would
be detected almost immediately when someone tries to access the website.
A skilled hacker can not only crack open a program to exploit it, he can
also put the program back together again and keep it running. The program
continues to process requests and it seems like nothing happened.
0x651 One Step at a Time
Complex exploits are difficult because so many different things can go wrong,
with no indication of the root cause. Since it can take hours just to track down
where the error occurred, it’s usually better to break a complex exploit down
into smaller parts. The end goal is a piece of shellcode that will spawn a shell
yet keep the tinyweb server running. The shell is interactive, which causes
some complications, so let’s deal with that later. For now, the first step should
be figuring out how to put the tinyweb daemon back together after exploit-
ing it. Let’s begin by writing a piece of shellcode that does something to prove
it ran and then puts the tinyweb daemon back together so it can process fur-
ther web requests.
Since the tinyweb daemon redirects standard out to /dev/null, writing
to standard out isn’t a reliable marker for shellcode. One simple way to prove
the shellcode ran is to create a file. This can be done by making a call to open(),
and then close(). Of course, the open() call will need the appropriate flags to
create a file. We could look through the include files to figure out what O_CREAT
and all the other necessary defines actually are and do all the bitwise math
for the arguments, but that’s sort of a pain in the ass. If you recall, we’ve done
something like this already—the notetaker program makes a call to open()
which will create a file if it didn’t exist. The strace program can be used on