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.