Smash the stack (STS) is a wargame network. We will take a look at the IO wargame.
______ _____
/\__ _\ /\ __ \ Levels are in /levels
\/_/\ \/ \ \ \/\ \ Passes are in ~/.pass
\ \ \ \ \ \ \ \ Readmes in /home/level1
\_\ \__\ \ \_\ \
/\_____\\ \_____\ Server admin: bla (bla@smashthestack.org)
\/_____/ \/_____/
1. No DoS, local or otherwise
2. Do not try to connect to remote systems from this box
3. Quotas, watch resources usage, max 2 connections per IP
(30 levels)
Logging in to the server level01@io.smashthestack.org
with password level1
.
level1@io:/levels$ ./level01
You need to supply a password.
Usage: ./level01 [password]
Hmm.. I wonder what the password is?
level1@io:/levels$ ./level01 password
Fail.
Dang. Okay. Since we have no clue what the password is, lets take a look inside the binary.
level1@io:/levels$ gdb -q level01
Reading symbols from /levels/level01...(no debugging symbols found)...done.
(gdb) disassemble main
Dump of assembler code for function main:
0x08048596 <+0>: push %ebp
0x08048597 <+1>: mov %esp,%ebp
0x08048599 <+3>: sub $0x18,%esp
0x0804859c <+6>: and $0xfffffff0,%esp
0x0804859f <+9>: mov $0x0,%eax
0x080485a4 <+14>: sub %eax,%esp
0x080485a6 <+16>: cmpl $0x2,0x8(%ebp)
0x080485aa <+20>: je 0x80485ca <main+52>
0x080485ac <+22>: mov 0xc(%ebp),%eax
0x080485af <+25>: mov (%eax),%eax
0x080485b1 <+27>: mov %eax,0x4(%esp)
0x080485b5 <+31>: movl $0x8048760,(%esp)
0x080485bc <+38>: call 0x80483b8 <printf@plt>
0x080485c1 <+43>: movl $0x0,-0x4(%ebp)
0x080485c8 <+50>: jmp 0x8048618 <main+130>
0x080485ca <+52>: call 0x804852d <pass>
0x080485cf <+57>: movl $0x64,0x8(%esp)
0x080485d7 <+65>: mov 0xc(%ebp),%eax
0x080485da <+68>: add $0x4,%eax
0x080485dd <+71>: mov (%eax),%eax
0x080485df <+73>: mov %eax,0x4(%esp)
0x080485e3 <+77>: movl $0x80491a0,(%esp)
0x080485ea <+84>: call 0x80483a8 <mbstowcs@plt>
0x080485ef <+89>: movl $0x8049140,0x4(%esp)
0x080485f7 <+97>: movl $0x80491a0,(%esp)
0x080485fe <+104>: call 0x80483d8 <wcscmp@plt>
0x08048603 <+109>: test %eax,%eax
0x08048605 <+111>: jne 0x804860c <main+118>
0x08048607 <+113>: call 0x80484b4 <win>
0x0804860c <+118>: movl $0x8048795,(%esp)
0x08048613 <+125>: call 0x80483e8 <puts@plt>
0x08048618 <+130>: mov -0x4(%ebp),%eax
0x0804861b <+133>: leave
0x0804861c <+134>: ret
End of assembler dump.
disassemble main
disassembles the main function of this binary. Note: disas main
also works. Taking a look at the assembly, we notice a suspicious function call 0x080485ca <+52>: call 0x804852d <pass>
.
(gdb) disas pass
Dump of assembler code for function pass:
0x0804852d <+0>: push %ebp
0x0804852e <+1>: mov %esp,%ebp
0x08048530 <+3>: sub $0x4,%esp
0x08048533 <+6>: movl $0x8049140,-0x4(%ebp)
0x0804853a <+13>: movl $0x53,0x8049140
0x08048544 <+23>: movl $0x65,0x8049144
0x0804854e <+33>: movl $0x63,0x8049148
0x08048558 <+43>: movl $0x72,0x804914c
0x08048562 <+53>: movl $0x65,0x8049150
0x0804856c <+63>: movl $0x74,0x8049154
0x08048576 <+73>: movl $0x50,0x8049158
0x08048580 <+83>: movl $0x57,0x804915c
0x0804858a <+93>: movl $0x0,0x8049160
0x08048594 <+103>: leave
0x08048595 <+104>: ret
End of assembler dump.
(gdb)
Converting the hexadecimal values into ASCII, we find out that 0x53 = 'S'
, 0x65 = 'e'
, 0x63 = 'c'
, 0x72 = 'r'
, 0x65 = 'e'
, 0x74 = 't'
, 0x50 = 'P'
and 0x57 = 'W'
. Concat the strings and you’ll get 'SecretPW'
level1@io:/levels$ ./level01 SecretPW
Win!
You will find the ssh password for level2 in /home/level2/.pass
sh-4.2$
The level01
binary has spawned a shell with access to the file /home/level2/.pass
. Open it and you’ll find the password to level 2. Save it somewhere to keep it for future access.
–
Here is another way that we can find out the elusive password.
Instead of using a debugger gdb
, we can use static analysis tools like objdump
to analyse our binary.
level1@io:/levels$ objdump -d level01
level01: file format elf32-i386
...
...
080484b4 <win>:
80484b4: 55 push %ebp
80484b5: 89 e5 mov %esp,%ebp
80484b7: 56 push %esi
80484b8: 53 push %ebx
80484b9: 83 ec 20 sub $0x20,%esp
80484bc: c7 45 e8 00 87 04 08 movl $0x8048700,-0x18(%ebp)
80484c3: c7 45 ec 08 87 04 08 movl $0x8048708,-0x14(%ebp)
80484ca: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp)
80484d1: c7 04 24 0b 87 04 08 movl $0x804870b,(%esp)
80484d8: e8 0b ff ff ff call 80483e8 <puts@plt>
80484dd: c7 04 24 20 87 04 08 movl $0x8048720,(%esp)
80484e4: e8 ff fe ff ff call 80483e8 <puts@plt>
80484e9: e8 0a ff ff ff call 80483f8 <geteuid@plt>
80484ee: 89 c6 mov %eax,%esi
80484f0: e8 03 ff ff ff call 80483f8 <geteuid@plt>
80484f5: 89 c3 mov %eax,%ebx
80484f7: e8 fc fe ff ff call 80483f8 <geteuid@plt>
80484fc: 89 74 24 08 mov %esi,0x8(%esp)
8048500: 89 5c 24 04 mov %ebx,0x4(%esp)
8048504: 89 04 24 mov %eax,(%esp)
8048507: e8 8c fe ff ff call 8048398 <setresuid@plt>
804850c: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp)
8048513: 00
8048514: 8d 45 e8 lea -0x18(%ebp),%eax
8048517: 89 44 24 04 mov %eax,0x4(%esp)
804851b: 8b 45 e8 mov -0x18(%ebp),%eax
804851e: 89 04 24 mov %eax,(%esp)
8048521: e8 a2 fe ff ff call 80483c8 <execve@plt>
8048526: 83 c4 20 add $0x20,%esp
8048529: 5b pop %ebx
804852a: 5e pop %esi
804852b: 5d pop %ebp
804852c: c3 ret
0804852d <pass>:
804852d: 55 push %ebp
804852e: 89 e5 mov %esp,%ebp
8048530: 83 ec 04 sub $0x4,%esp
8048533: c7 45 fc 40 91 04 08 movl $0x8049140,-0x4(%ebp)
804853a: c7 05 40 91 04 08 53 movl $0x53,0x8049140
8048541: 00 00 00
8048544: c7 05 44 91 04 08 65 movl $0x65,0x8049144
804854b: 00 00 00
804854e: c7 05 48 91 04 08 63 movl $0x63,0x8049148
8048555: 00 00 00
8048558: c7 05 4c 91 04 08 72 movl $0x72,0x804914c
804855f: 00 00 00
8048562: c7 05 50 91 04 08 65 movl $0x65,0x8049150
8048569: 00 00 00
804856c: c7 05 54 91 04 08 74 movl $0x74,0x8049154
8048573: 00 00 00
8048576: c7 05 58 91 04 08 50 movl $0x50,0x8049158
804857d: 00 00 00
8048580: c7 05 5c 91 04 08 57 movl $0x57,0x804915c
8048587: 00 00 00
804858a: c7 05 60 91 04 08 00 movl $0x0,0x8049160
8048591: 00 00 00
8048594: c9 leave
8048595: c3 ret
08048596 <main>:
8048596: 55 push %ebp
8048597: 89 e5 mov %esp,%ebp
8048599: 83 ec 18 sub $0x18,%esp
804859c: 83 e4 f0 and $0xfffffff0,%esp
804859f: b8 00 00 00 00 mov $0x0,%eax
80485a4: 29 c4 sub %eax,%esp
80485a6: 83 7d 08 02 cmpl $0x2,0x8(%ebp)
80485aa: 74 1e je 80485ca <main+0x34>
80485ac: 8b 45 0c mov 0xc(%ebp),%eax
80485af: 8b 00 mov (%eax),%eax
80485b1: 89 44 24 04 mov %eax,0x4(%esp)
80485b5: c7 04 24 60 87 04 08 movl $0x8048760,(%esp)
80485bc: e8 f7 fd ff ff call 80483b8 <printf@plt>
80485c1: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp)
80485c8: eb 4e jmp 8048618 <main+0x82>
80485ca: e8 5e ff ff ff call 804852d <pass>
80485cf: c7 44 24 08 64 00 00 movl $0x64,0x8(%esp)
80485d6: 00
80485d7: 8b 45 0c mov 0xc(%ebp),%eax
80485da: 83 c0 04 add $0x4,%eax
80485dd: 8b 00 mov (%eax),%eax
80485df: 89 44 24 04 mov %eax,0x4(%esp)
80485e3: c7 04 24 a0 91 04 08 movl $0x80491a0,(%esp)
80485ea: e8 b9 fd ff ff call 80483a8 <mbstowcs@plt>
80485ef: c7 44 24 04 40 91 04 movl $0x8049140,0x4(%esp)
80485f6: 08
80485f7: c7 04 24 a0 91 04 08 movl $0x80491a0,(%esp)
80485fe: e8 d5 fd ff ff call 80483d8 <wcscmp@plt>
8048603: 85 c0 test %eax,%eax
8048605: 75 05 jne 804860c <main+0x76>
8048607: e8 a8 fe ff ff call 80484b4 <win>
804860c: c7 04 24 95 87 04 08 movl $0x8048795,(%esp)
8048613: e8 d0 fd ff ff call 80483e8 <puts@plt>
8048618: 8b 45 fc mov -0x4(%ebp),%eax
804861b: c9 leave
804861c: c3 ret
804861d: 90 nop
804861e: 90 nop
804861f: 90 nop
In the pass
function, the string is laid out here.
804853a: c7 05 40 91 04 08 53 movl $0x53,0x8049140
8048541: 00 00 00
8048544: c7 05 44 91 04 08 65 movl $0x65,0x8049144
804854b: 00 00 00
804854e: c7 05 48 91 04 08 63 movl $0x63,0x8049148
8048555: 00 00 00
8048558: c7 05 4c 91 04 08 72 movl $0x72,0x804914c
804855f: 00 00 00
8048562: c7 05 50 91 04 08 65 movl $0x65,0x8049150
8048569: 00 00 00
804856c: c7 05 54 91 04 08 74 movl $0x74,0x8049154
8048573: 00 00 00
8048576: c7 05 58 91 04 08 50 movl $0x50,0x8049158
804857d: 00 00 00
8048580: c7 05 5c 91 04 08 57 movl $0x57,0x804915c
8048587: 00 00 00
804858a: c7 05 60 91 04 08 00 movl $0x0,0x8049160
8048591: 00 00 00
Similar to the first step, decode the hexadecimal into ASCII and you’ll find the password.
–
Yet another method of finding the password.
I have saved the easiest for last. The commands are pretty straight forward.
level1@io:/levels$ strings level01
/lib/ld-linux.so.2
__gmon_start__
libc.so.6
_IO_stdin_used
puts
mbstowcs
printf
wcscmp
setresuid
execve
geteuid
__libc_start_main
GLIBC_2.0
PTRh
[^]
[^_]
/bin/sh
Win!
You will find the ssh password for level2 in /home/level2/.pass
You need to supply a password.
Usage: %s [password]
Fail.
level1@io:/levels$ strings -el level01
SecretPW
The fist time we ran strings
, it looked for the normal encoded strings and returned with the result. The second time, we ran strings
with the -el
flag, where -e
represents encoding and l
represents 16-bit little endian. As we saw earlier, our password is a wide character string and thus strings -el
will reveal it.
Published on 13 Mar 2013 by Stanley Tan