Blackbox Level 4 – Sanitization Side Effects

Welcome back for another level of Blackbox from Smash The Stack.  Today we will be looking at level 4.  As always, the final password will be stripped from the page and replaced with Y’s.  If you are following along in terminal, go ahead and ssh in and let’s begin.

As usual with Blackbox, the current level’s files are in the home directory so we can check them out via ls.

level4@blackbox:~$ ls -la
total 1192
drwxr-x— 2 level4 level4 4096 Jul 9 2009 .
drwxr-xr-x 17 root root 4096 Mar 22 15:30 ..
lrwxrwxrwx 1 root root 9 Jun 17 2009 .bash_history -> /dev/null
-rw-r–r– 1 root level4 567 Dec 29 2007 .bash_profile
-rw-r–r– 1 root level4 1834 Dec 29 2007 .bashrc
-rw-r–r– 1 root level5 10 Dec 29 2007 password
-rwsr-xr-x 1 level5 level5 1189214 Jan 12 2008 shared
-rw-r–r– 1 root root 1505 Dec 29 2007 shared.cc

We see two files, the SUID executable “shared” and the provided source, “shared.cc”.  To try and understand the program, let’s go ahead and execute it:

level4@blackbox:~$ ./shared
This program allows you to read files from my shared files. See /usr/share/level5 for my shared files. Simply use the path relative to my shared files to read a file!
Example: ./shared lyrics/foreverautumn

Judging by the output, we have an idea of what the program should be doing.  In general, it will display to us the contents of a file.  However, it has to be a file located at the directory /usr/share/level5 or deeper.  Let’s check out the directory:

level4@blackbox:~$ ls /usr/share/level5
lyrics shit1 shit2 shit3 shit4 shit5
level4@blackbox:~$ ls /usr/share/level5/lyrics
foreverautumn
level4@blackbox:~$ more /usr/share/level5/shit1
shit
level4@blackbox:~$ more /usr/share/level5/lyrics/foreverautumn

LOL, I can’t find the lyrics, so google.com

Now at this point we have an idea of the directory structure and of the files.  From here, if we can move up directories using the “..” dir listing, we could potentially re-route the program to read from /home/level5/password.  Let’s see if we have full control over the relative path supplied.  When doing this, remember to try and get to a file the program would have permissions to view.

level4@blackbox:~$ ./shared lyrics/../shit1
Contents of /usr/share/level5/lyricsshit1:
Unable to open file
level4@blackbox:~$ ./shared ../level5/shit1
Contents of /usr/share/level5/level5/shit1:
Unable to open file

Well this is interesting.  From the error message, it looks like the program may be stripping “/../” out of the string we provided.  Additionally, it’s either stripping or skipping the “../” at the beginning of the string.  From here, let’s take a look at the source code file provided to see what is happening.  I’ll leave it to you to view and understand the entire file as it’s a little large to post here.  However, let’s talk about a few key points.

We see the file takes one command line argument as a string for a local path.  From here it takes the string and strips any leading / or . characters.   It next uses the strreplace function (locally defined) to strip all instances of /../ from the string.  It’s important to note this function makes one forward pass.  Afterwards, the strreplace function is used again to remove /./ from the string.  Finally, this “sanitized” string is appended to the end of the string “/usr/share/level5/” to make the string for the full path which the program will then open and write all lines of to the screen.

We will attempt to exploit the way the program sanitizes user input to create a string which points to /home/level5/password.  To do this, let’s look at how strreplace works and how it’s used in the program.  Strreplace removes instances of a string from another string and replaces it with a third string.  In this program, /../ is replaced with nothing; it is simply removed.  When doing this, strreplace keeps moving forward every time it replaces part of the original string.  Because of this, if one /../ is removed which causes another to be created in it’s place, strreplace will not see the newly created one.  Additionally, the program only calls strreplace on /../ once, not until it’s no longer there (and also not after the removal of /./ which could also have the side effect of creating /../).  So, what would one of these strings look like?  Well, like we just said, we will have /../, and when it’s removed, a new /../ needs to be created.  So assuming /../ is in the middle, let’s wrap the other around, giving us “/./.././”.  Let’s see if this works in the program (the source shows it should):

level4@blackbox:~$ ./shared lyrics/./.././shit1
Contents of /usr/share/level5/lyrics/../shit1:
shit

Aha!  We’ve done it, we’ve successfully moved up a directory.  Now let’s just reapply this idea to get to the level5 password:

level4@blackbox:~$ ./shared lyrics/./../././../././../././.././home/level5/password
Contents of /usr/share/level5/lyrics/../../../../home/level5/password:
YYYYYYYYY

There we have it, the end of level 4.  I can’t stress it enough, when a change is made to a value, the value needs to be re-verified as valid.  Simply removing a character or character string from something doesn’t make it safe.  Especially not when you only check for a character set once, and allow character removal to create the exact sets you were trying to prevent.  Test to verify and verify at the end.

This entry was posted in BlackBox, Smash The Stack, Wargames and tagged , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published.