Level 1, IO STS

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.