Tweets by @buherablog
profile for buherator at IT Security Stack Exchange, Q&A for IT security professionals

A BitBetyár Blog

Túljártál a nagyokosok eszén? Küldd be a mutatványodat! (e-mail a buherator gmailkomra jöhet)

Full-Disclosure / Névjegy / Coming out


Promó

H.A.C.K.

Címkék

0day (110) adobe (87) adobe reader (21) anonymous (26) apple (60) az olvasó ír (49) blackhat (20) botnet (22) bug (200) buherablog (44) buhera sörözés (39) bukta (49) deface (38) dns (22) dos (29) esemény (82) facebook (26) firefox (64) flash (33) gondolat (31) google (59) google chrome (36) hacktivity (37) hírek (117) incidens (224) internet explorer (88) iphone (35) java (50) jog (22) kína (21) kriptográfia (68) kultúra (21) linux (24) malware (43) microsoft (142) móka (48) mozilla (23) office (26) oracle (40) os x (43) patch (197) php (20) politika (31) privacy (58) programozás (22) safari (34) sql injection (62) windows (85) xss (77) Címkefelhő

Licensz

Creative Commons Licenc

Defcon XIX CTF - Retro Revisited 300

2011.06.22. 12:00 | buherator | 3 komment

Depth jóvoltából itt van az idei Defcon CTF selejtező RR300-as pályájának megoldása és egy kis ráhangolás Hacktivity-re :)

+++

Az RR200 feladatot megoldva fellelkesülve mentem neki a következő feladványnak:

root@BackTrack4:/home/retro300# file /root/defcon/rr3001d8bcd25d1849ac5a
/root/defcon/rr3001d8bcd25d1849ac5a.tar: POSIX tar archive (GNU)

Jól látszik,hogy egy tömörített fájl az alábbi tartalommal:

root@BackTrack4:/home/retro300# file retro300 
retro300: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.32, dynamically linked (uses shared libs), stripped

Tartalmazott egy adatbázis fájlt is a csomagolt archívum:

root@BackTrack4:/home/retro300# file auth.db 
auth.db: SQLite 3.x database

Egyszerűen meg lehet szerezni a fontosabb információkat a fájlból:

root@BackTrack4:/home/retro300# strings auth.db 

SQLite format 3
tableusersusers
CREATE TABLE users (id INTEGER PRIMARY KEY, user TEXT, pin TEXT)
jeff1315
jupi1234
mars3473
merc2345
vulcan2945
joe8305
bob8367
dave3245
aaron7345

A binárist elindítva látható, hogy ismét egy hálózati kiszolgáló programmal szembesülünk:

root@BackTrack4:~# netstat -an | grep LISTEN

tcp        0      0 0.0.0.0:5500            0.0.0.0:*               LISTEN     // itt fut a jószág

A bináris vizsgálatához a legkézenfekvőbb megoldás az ltrace parancs. Mivel az előző feladatnál bemutatott fork() megoldást alkalmazza, így az alábbi scriptet használjuk ismét:

root@BackTrack4:/home/retro300# PID=`ps a | grep retro | grep -v grep | tail -1 | awk '{print $1}'` ; ltrace -p $PID

--- SIGSTOP (Stopped (signal)) ---

--- SIGSTOP (Stopped (signal)) ---

read(4, "a", 1)                                                                  = 1

read(4, "n", 1)                                                                  = 1

read(4, "i", 1)                                                                  = 1

read(4, "t", 1)                                                                  = 1

read(4, "t", 1)                                                                  = 1

read(4, "v", 1)                                                                  = 1

read(4, "a", 1)                                                                  = 1

read(4, "l", 1)                                                                  = 1

read(4, "a", 1)                                                                  = 1

read(4, "k", 1)                                                                  = 1

read(4, "i", 1)                                                                  = 1

read(4, "?", 1)                                                                  = 1

read(4, "\r", 1)                                                                 = 1

read(4, "\n", 1)                                                                 = 1

strcmp("vanittvalaki?\r", "letmeinpls")                                          = 1

exit(0 <unfinished ...>

+++ exited (status 0) +++

Természetesen egy másik konzolon hozzá csatlakozunk a szolgáltatáshoz:

Computer:~ depth$ telnet 192.168.1.102 5500

Trying 192.168.1.102...

Connected to 192.168.1.102.

Escape character is '^]'.

vanittvalaki?

Connection closed by foreign host.

Amint látható a beírt karaktersorozatunkat hasonlítja össze a 'letmeinpls' szöveggel, amennyiben egyezik mehet tovább a feladvány megoldása felé a vándor egyébként kimarad egy dobásból.

 Megismételve a vizsgálatot érdekes látvány tárul a szemünk elé (részlet az ltrace kimenetéből):

strcmp("letmeinpls", "letmeinpls")                                               = 0

ptrace(0, 0, 1, 0, 0xbf926640)                                                   = -1  // ez itt a szivattyú!

exit(1 <unfinished ...>

+++ exited (status 1) +++

Szóval, a bináris meghívja a ptrace függvényt, amely segítségével az összes debugger alkalmazást ledobja magáról (mivel ha érzékeli, hogy valaki ptrace megoldással próbálja vizsgálni, megszakítja a további működést).

Nem nagy probléma több megoldás is létezik a tovább menetelésre:

  • átírjuk a binárist (béna, mi van ha crc checksum vagy egyéb védelem van? Defcon selejtezőn nem lehet tudni...)
  • alkalmazzuk az LD_PRELOAD technikát amely segítvégével szépen eltéríthetük a ptrace függvényt. 

A következő fájlt kell megalkotni: 

#include <stdio.h>
#include <string.h> 

long ptrace(char request, int pid, void *addr, void *data){
return 0;
}

Látható,hogy lényeges funkciót nem végez viszont az én szempontomból igen, mivel mindig nullával tér vissza és ezáltal a program úgy érzékeli minden ok, senki nem próbál debuggolni.

Lefordítjuk:

root@BackTrack4:/home/retro300#  gcc -fPIC -c ld.c -o ld.o

root@BackTrack4:/home/retro300#  gcc -shared -o ld.so ld.o


Bínárist a következő módon kell indítani,hogy a változás életbe lépjen:

root@BackTrack4:/home/retro300# LD_PRELOAD=/home/retro300/ld.so ./retro300

Ismételt támadási kísérlet után látható,hogy sikerrel jártunk:

Computer:~ depth$ nc -v  192.168.1.102 5500

Connection to 192.168.1.102 5500 port [tcp/fcp-addr-srvr1] succeeded!

letmeinpls

                                           _____ ______ _____ _     _ 

               __    ____       __        / ____|  ____/ ____(_)   | |

          ____/ /___/ / /____  / /__     | (___ | |__ | |     _  __| |

         / __  / __  / __/ _ \/ //_/      \___ \|  __|| |    | |/ _` |

        / /_/ / /_/ / /_/  __/ ,<         ____) | |___| |____| | (_| |

        \__,_/\__,_/\__/\___/_/|_|       |_____/|______\_____|_|\__,_|    (beta)

 

     ( cause everyone is looking for a new provider right?!)

 

Username:jupi

Passcode:1234

Bad Username or Pin

 

Itt lehet próbálkozni az auth.db-ben szereplő információkkal ahogy látjuk, sikertelenül.

Az ltrace kimenetén sem látunk olyan információt amivel okosabbak lennénk:

strcmp("letmeinpls", "letmeinpls")                                               = 0

ptrace(0, 0, 1, 0, 0xbfe6b360)                                                   = 0

strlen("                                "...)                                    = 499

send(4, 0xbfe6b13c, 499, 0, 0xbfe6b118)                                          = 499

strlen("Username:")                                                              = 9

send(4, 0x804a795, 9, 0, 0x6f797265)                                             = 9

read(4, "j", 1)                                                                  = 1

read(4, "u", 1)                                                                  = 1

read(4, "p", 1)                                                                  = 1

read(4, "i", 1)                                                                  = 1

read(4, "\n", 1)                                                                 = 1

strdup("jupi")                                                                   = 0x8908878

strlen("Passcode:")                                                              = 9

send(4, 0x804a895, 9, 0, 0xb7ec23c0)                                             = 9

read(4, "1", 1)                                                                  = 1

read(4, "2", 1)                                                                  = 1

read(4, "3", 1)                                                                  = 1

read(4, "4", 1)                                                                  = 1

read(4, "\n", 1)                                                                 = 1

strlen("Bad Username or Pin\n")                                                  = 20

send(4, 0x804a89f, 20, 0, 0xbfe6b33b)                                            = 20

free(0x8908878)                                                                  = <void>

close(4)                                                                         = 0

exit(1 <unfinished ...>

+++ exited (status 1) +++

Ezen a ponton jött ez a várva várt lehetőség és beizzíthatjuk kedvenc debuggerünket majd a jelszó bekérés funkcióra vagy környékére töréspontot tenni és közelebbről megvizsgálni mi is történik:

(gdb) set disassembly-flavor intel

Az alábbi információkat találtam meg a jegyzeteimben:

  • 0x8049de7 (username beolvasás utáni RET)
  • 0x8049e73 (username és pin beolvasás utáni RET)

Az alábbi kódrészlet árulkodik egy kis turpisságról (egy strlen() után):

MOV DWORD PTR [EBP-24], EAX

CMP DWORD PTR [EBP-24], 14

JZ 0x08049EAC

Ha a PIN-ként beadott érték hossza nem 14 akkor automatikusan kiléptet a program. Próbáljunk meg 14-et beadni és nézzük meg mi történik. A következő a felállás:

  1. szerver LD_PRELOAD techikával indítva.
  2. Gyermek folyamatra ltrace segítségével rácsatlakozunk.
  3. egy másik terminálon beküldjük a megfelelő adatokat.

Kapcsolódási kísérlet a szoftverhez:

Computer:~ depth$ nc -v  192.168.1.102 5500

Connection to 192.168.1.102 5500 port [tcp/fcp-addr-srvr1] succeeded!

letmeinpls

                                           _____ ______ _____ _     _ 

               __    ____       __        / ____|  ____/ ____(_)   | |

          ____/ /___/ / /____  / /__     | (___ | |__ | |     _  __| |

         / __  / __  / __/ _ \/ //_/      \___ \|  __|| |    | |/ _` |

        / /_/ / /_/ / /_/  __/ ,<         ____) | |___| |____| | (_| |

        \__,_/\__,_/\__/\___/_/|_|       |_____/|______\_____|_|\__,_|    (beta)

 

 

    ( cause everyone is looking for a new provider right?!)

 

Username:jupi

Passcode:12341234567890

Bad Username or Passcode

Nézzük meg mit sikerült megfogni, ltrace kimenete elég sokmindent elárul:

--- SIGSTOP (Stopped (signal)) ---

--- SIGSTOP (Stopped (signal)) ---

read(4, "e", 1)                                                                  = 1

read(4, "t", 1)                                                                  = 1

read(4, "m", 1)                                                                  = 1

read(4, "e", 1)                                                                  = 1

read(4, "i", 1)                                                                  = 1

read(4, "n", 1)                                                                  = 1

read(4, "p", 1)                                                                  = 1

read(4, "l", 1)                                                                  = 1

read(4, "s", 1)                                                                  = 1

read(4, "\n", 1)                                                                 = 1

strcmp("letmeinpls", "letmeinpls")                                               = 0

ptrace(0, 0, 1, 0, 0xbfe6b360)                                                   = 0

strlen("                                "...)                                    = 499

send(4, 0xbfe6b13c, 499, 0, 0xbfe6b118)                                          = 499

strlen("Username:")                                                              = 9

send(4, 0x804a795, 9, 0, 0x6f797265)                                             = 9

read(4, "j", 1)                                                                  = 1

read(4, "u", 1)                                                                  = 1

read(4, "p", 1)                                                                  = 1

read(4, "i", 1)                                                                  = 1

read(4, "\n", 1)                                                                 = 1

strdup("jupi")                                                                   = 0x8908878

strlen("Passcode:")                                                              = 9

send(4, 0x804a895, 9, 0, 0xb7ec23c0)                                             = 9

read(4, "1", 1)                                                                  = 1

read(4, "2", 1)                                                                  = 1

read(4, "3", 1)                                                                  = 1

read(4, "4", 1)                                                                  = 1

read(4, "1", 1)                                                                  = 1

read(4, "2", 1)                                                                  = 1

read(4, "3", 1)                                                                  = 1

read(4, "4", 1)                                                                  = 1

read(4, "5", 1)                                                                  = 1

read(4, "6", 1)                                                                  = 1

read(4, "7", 1)                                                                  = 1

read(4, "8", 1)                                                                  = 1

read(4, "9", 1)                                                                  = 1

read(4, "0", 1)                                                                  = 1

read(4, "\n", 1)                                                                 = 1

strncpy(0xbfe6b46f, "1234", 4)                                                   = 0xbfe6b46f

sqlite3_open(0x804a7d2, 0xbfe6b334, 2, 5, 0xb7e9daf3)                            = 0

sprintf("select id,pin from users where u"..., "select id,pin from users where u"...) = 42

sqlite3_exec(0x8908ad0, 0xbfe6b2e4, 0x80497f5, 0, 0xbfe6b2e0 <unfinished ...>

strncpy(0xbfe6b238, "8", 20)                                                     = 0xbfe6b238

strncpy(0x804bbbb, "1234", 4)                                                    = 0x804bbbb

atoi(0xbfe6b238, 0x890bb38, 4, 1, 0xb7f34ff4)                                    = 8

<... sqlite3_exec resumed> )                                                     = 0

sqlite3_close(0x8908ad0, 0xbfe6b30e, 0x80497f5, 0, 0xbfe6b2e0)                   = 0

strlen("1234")                                                                   = 4

strdup("1234")                                                                   = 0x89098c8

memcpy(0x804bbbb, "    ", 5)                                                     = 0x804bbbb

strncmp("1234", "1234", 4)                                                       = 0

strncpy(0xbfe6b464, "1234567890", 10)                                            = 0xbfe6b464

printf("sending %s out of buf: %s\n", "1234567890", "12341234567890")            = 46

time(NULL)                                                                       = 1308660361

htonl(0x33d655e0, 0xb7ec0ff4, 0, 0, 0x655eb348)                                  = 0xe055d633

sprintf("1253239787", "%0.10u", 1253239787)                                      = 10

strncmp("1253239787", "1234567890", 10)                                          = 1 // Itt a lényeg, itt történik az összehasonlítás a beküldött PIN változó 10 karakteres részével (PASSCODE)

strlen("Bad Username or Passcode\n")                                             = 25

send(4, 0x804a8cf, 25, 0, 0xb7ec5910)                                            = 25

free(0x8908878)                                                                  = <void>

free(0x89098c8)                                                                  = <void>

close(4)                                                                         = 0

exit(1 <unfinished ...>

+++ exited (status 1) +++

 

Újra próbálkozva és a fenti kódot megadva a szerver meghatározott ideig (kb 10perc) beengedi a felhasználót: 

Computer:~ depth$ nc -v  192.168.1.102 5500

Connection to 192.168.1.102 5500 port [tcp/fcp-addr-srvr1] succeeded!

letmeinpls

                                           _____ ______ _____ _     _ 
               __    ____       __        / ____|  ____/ ____(_)   | |
          ____/ /___/ / /____  / /__     | (___ | |__ | |     _  __| |
         / __  / __  / __/ _ \/ //_/      \___ \|  __|| |    | |/ _` |
        / /_/ / /_/ / /_/  __/ ,<         ____) | |___| |____| | (_| |
        \__,_/\__,_/\__/\___/_/|_|       |_____/|______\_____|_|\__,_|    (beta)

    ( cause everyone is looking for a new provider right?!)

Username:jupi
Passcode:12341253239787 //PIN+PASSCODE

   DDTEK VPN console         

    Choose an option:        

       1:  change pin        
       2:  re-sync sec token 
       3:  add user          
       4:  change username   
       5:  exit 

Egyik menüpont sem működik, viszont a 8-as gombot megnyomva megjelenik a szükséges kulcs és pár másodperccel később +300 pont az eredménykijelzőn.

(Én bruteforcoltam kézzel, de további debuggolás is segít ;) - de ilyenkor alap,hogy végignyomkodod 0-9-ig :) )

Remélem érthető volt a leírás, triviális dolgokba próbáltam nem belemenni és csak a lényegre koncentrálni. Tévutakat nem mutattam be pl: SQL injection és egyebek még a debuggolás megkezdése előtt :)

Tanulni lehet belőle az tuti! A lényeg, hogy sokat tanultunk és reszkessetek Hacktivity CTF-en mert izgalmas feladványokat találtunk ki :)

Címkék: esemény verseny defcon ctf az olvasó ír

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

zota 2011.06.22. 14:06:03

Jo tutorial, kossz.

NamelessOne 2011.06.22. 14:13:37

Én úgy érzem, hogy aki írta ezt a bejegyzést nem ember.

Tyra3l 2011.06.23. 20:27:11

koszi az irast, egy kerdes: a grepelos awk-s megoldas helyett nem lett volna elegendo a -f kapcsolo hasznalata, hogy a (l)trace utanamenjen a forkolt processznek?

Tyrael
süti beállítások módosítása