You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

53 lines
1.3 KiB

// Created by Graham Northup
// https://gist.github.com/Grissess/e533a2dcc493a6ac8528c4eeeaf6755a
//
// Compile with gcc -ldl -fPIC -shared -o exploit_scanf.so exploit_scanf.c
// Run with LD_PRELOAD=./exploit_scanf.so ./guess
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <dlfcn.h>
int scanf(const char *fmt, ...) {
va_list ap;
static int (*real_vscanf)(const char *, va_list) = NULL;
int res;
int *guessptr;
int magic = 0;
if(!strcmp(fmt, "%s")) { // Assume this is our magic call
magic = 1;
va_start(ap, fmt);
guessptr = va_arg(ap, int *); // Extract &guess from main (points to the stack)
va_end(ap);
}
va_start(ap, fmt);
if(!real_vscanf) {
real_vscanf = dlsym(RTLD_NEXT, "vscanf");
}
res = real_vscanf(fmt, ap);
va_end(ap);
//Cheat code. Anything that's not a digit entered, win the game
if(magic && !isdigit(*((char *)guessptr))) {
int guess;
printf("Let's move around on the stack to find the random number you really wanted\n");
// This offset is computed by hand, it's not guaranteed to be the same on each system
guess = guessptr[-3];
printf("The gods of randomness smile on you! The answer is %d.\n", guess);
snprintf((char *)guessptr, 100, "%d", guess);
return 1;
}
return res;
}