CREATIVE CHAOS   ▋ blog

io.smashthestack.org / level01

PUBLISHED ON 28/12/2015 — EDITED ON 14/12/2023 — .SL, INFOSEC

Intro

Spomnil sem se, da sem pred leti užival v “blowfish” “wargame”-u na smashthestack.org. Nažalost takrat nisem imel dovolj znanja in vztrajnosti, da bi se kam prebil. Prevrtimo čas nekaj let naprej, nekaj stvari sem se vmes naučil in “io” bo idealen test kako daleč sem prišel. Napredek bom vmes popisoval v materinem jeziku :)

Povezava

Povezava na strežnik je klasična:

$ ssh -l level1 io.smashthestack.org -p2224

Geslo: level1

V domači mapi najdemo navodila za igro. Preberite jih.

Prvi koraki

V kolikor sledimo navodilom, naredimo tole:

    level1@io:~$ cd /levels/
    level1@io:/levels$ ./level01
    Enter the 3 digit passcode to enter: 123

Zagon “level1” programa nas vpraša za geslo, ki je v obliki treh cifer. Kombinacija “123” ni delovala, če smo pogumni lahko na roke preizkusimo še preostalih 999 možnosti. Verjetno pa to ni smisel igre…

Prefinjen pristop bi bil, da preverimo če obstaja izvorna koda programa, katere na našo žalost ni pri roki.

Naslednja stopnja je obratni inženiring.

objdump

V sklopu paketa GNU binutils najdemo med drugim objdump, ki ga lahko izkoristimo za prikaz programa v zbirnem jeziku.

    level1@io:/levels$ objdump -d level01
    
    level01:     file format elf32-i386
    
    
    Disassembly of section .text:
    
    08048080 :
     8048080:	68 28 91 04 08       	push   $0x8049128
     8048085:	e8 85 00 00 00       	call   804810f 
     804808a:	e8 10 00 00 00       	call   804809f 
     804808f:	3d 0f 01 00 00       	cmp    $0x10f,%eax
     8048094:	0f 84 42 00 00 00    	je     80480dc 
     804809a:	e8 64 00 00 00       	call   8048103 
    

Hiter pregled izpisa nam razjasni delovanje programa. Za nas zanimiva vrstica je ta, ki vsebuje ukaz cmp. cmp (compare) je ukaz za primerjavo v zbirnem jeziku, v primeru ko sta obe podani vrednosti enaki, postavi Z zastavico na 1, sicer pa na 0. Ukaz je (jump if equal), kakor neposredni prevod pove, skoči na določeno mesto v pomnilniku.

eax je en izmed registrov (ang. accumulator register) v katerega lahko shranimo vrednosti, tja shrani naš program vrednost, ki smo jo vpisali, ko je program od nas zahteval geslo. Uporablja se za dostop do vhodno/izhodnih vrat, aritmetiko, prekinitve in podobno. eax poznamo, ugotoviti moramo kaj se skriva pod vrednostjo 0x10f, to lahko izvedemo s pomočjo lupine:

    level1@io:/levels$ echo "ibase=16; 10F"| bc
    271

Privzeto objdump izpisuje ukaze zbirnika v AT&T sintaksi, ki jo prepoznamo po množici % in $ znakov, omogoča pa tudi izpis v Intel sintaksi, ki je vsaj zame berljivejša kakor AT&T. Naš primer je sicer prekratek, da bi bile razlike res opazne, vendar ga vseeno prilagam.

    level1@io:/levels$ objdump -M intel -d level01
    
    level01:     file format elf32-i386
    
    
    Disassembly of section .text:
    
    08048080 :
     8048080:	68 28 91 04 08       	push   0x8049128
     8048085:	e8 85 00 00 00       	call   804810f 
     804808a:	e8 10 00 00 00       	call   804809f 
     804808f:	3d 0f 01 00 00       	cmp    eax,0x10f
     8048094:	0f 84 42 00 00 00    	je     80480dc 
     804809a:	e8 64 00 00 00       	call   8048103 

gdb

Dodaten način za razbijanje prve stopnje je uporaba GNU razhroščevalnika (gdb, GNU debugger).

    level1@io:/levels$ gdb level01
    GNU gdb (GDB) 7.4.1-debian
    Copyright (C) 2012 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "i486-linux-gnu".
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>...
    Reading symbols from /levels/level01...(no debugging symbols found)...done.
    
    (gdb) disas main
    Dump of assembler code for function main:
       0x08048080 <+0>:    push   $0x8049128
       0x08048085 <+5>:    call   0x804810f 
       0x0804808a <+10>:    call   0x804809f 
       0x0804808f <+15>:    cmp    $0x10f,%eax
       0x08048094 <+20>:    je     0x80480dc 
       0x0804809a <+26>:    call   0x8048103 
    End of assembler dump.
    
    (gdb) p 0x10F
    $1 = 271

Intel sintakso lahko uporabljamo tudi v GNU razhroščevalniku z ukazom:

    (gdb) set dis intel

Navedeni ukaz, nam bo nastavil gdb samo za trenutno sejo, če želimo, da je Intel sintaksa privzeta pri vsakem zagonu razhroščevalnika lahko v .gdbinit dodamo vrstico “set dis intel”:

    $ echo "set dis intel" > ~/.gdbinit

Epilog

Ob pridobitvi gesla nam preostane samo še vpis v program in pridobili smo dostop do naslednje stopnje.

    level1@io:/levels$ ./level01
    Enter the 3 digit passcode to enter: 271
    Congrats you found it, now read the password for level2 from /home/level2/.pass
    sh-4.2$