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
// Compile with gcc -ldl -fPIC -shared -o exploit_scanf.c
// Run with LD_PRELOAD=./ ./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_start(ap, fmt);
if(!real_vscanf) {
real_vscanf = dlsym(RTLD_NEXT, "vscanf");
res = real_vscanf(fmt, 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;