passcode
{"author": ["ret2basic"]}
Challenge
Mommy told me to make a passcode based login system. My initial C code was compiled without any error! Well, there was some compiler warning, but who cares about that?
ssh passcode@pwnable.kr -p2222 (pw:guest)
Code Review
#include <stdio.h>
#include <stdlib.h>
void login(){
int passcode1;
int passcode2;
printf("enter passcode1 : ");
scanf("%d", passcode1);
fflush(stdin);
// ha! mommy told me that 32bit is vulnerable to bruteforcing :)
printf("enter passcode2 : ");
scanf("%d", passcode2);
printf("checking...\n");
if(passcode1==338150 && passcode2==13371337){
printf("Login OK!\n");
system("/bin/cat flag");
}
else{
printf("Login Failed!\n");
exit(0);
}
}
void welcome(){
char name[100];
printf("enter you name : ");
scanf("%100s", name);
printf("Welcome %s!\n", name);
}
int main(){
printf("Toddler's Secure Login System 1.0 beta.\n");
welcome();
login();
// something after login...
printf("Now I can safely trust you that you have credential :)\n");
return 0;
}Solution
There is an error in the code: instead of scanf("%d", passcode1), it should be scanf("%d", *passcode1). Because of this error, passcode1 and passcode2 are considered addresses instead of values. In fact, there are three erros in the code:
For each scanf(), we are able to write some data directly to the address of the variables name, passcode1, and passcode2. Let's read through the assembly to figure out the exact location of each variable:


The location for each variable:
The distance between name and passcode1 is 0x60, which is 96 in decimal. We are able to input at most 100 bytes for name, so it is possible to overwrite passcode1.
Note that the function fflush() is called right after scanf("%d", passcode1):
Let's see its disassembly:

This fflush() is fflush@PLT, and the first jmp instruction jumps to fflush@GOT. The idea is:
Send 96 bytes of junk data to fill the buffer.
Overwrite
password1with0x804a004, then thescanf()statement becomesscanf("%100s", 0x804a004). This would allow us to input arbitrary data to the memory location0x804a004, which isfflush@GOT.Once the
scanf()function is called, send the integer representation (because of"%100s") ofsystem("/bin/cat"). Oncefflush@PLTis called, thejmpinstruction will jump tosystem("/bin/cat")and execute it.
Essentially, this is a GOT overwrite attack. The last task is finding the address of system("/bin/cat"). Take another look at the disassembly of login():

Here 0x80485d7 is the address of system("/bin/cat"). To get its integer representation, use str(0x80485d7) in Python.
Get Flag

Exploit
Last updated