首页
社区
课程
招聘
[旧帖] [原创]0day 软件漏洞分析技术 第一版 堆溢出(dword shoot)注解 0.00雪花
发表于: 2012-4-14 19:20 1347

[旧帖] [原创]0day 软件漏洞分析技术 第一版 堆溢出(dword shoot)注解 0.00雪花

2012-4-14 19:20
1347
呵呵 通宵了一晚上算是把这章看懂的 我觉得dword shoot这里可能有些人看的觉得吃力 所以贸然写一篇注解 不过鉴于水平有限 有错误请指出

虽然很多东西现在已经不实用了 原理还是相同的 没有谁可以一步登天 戒焦戒躁

感谢failwest和为软件安全做出贡献的前辈们

书上猜测卸载堆结点的代码可能是这个样子的

int remove(Listnode * node)
{
        node -> blink -> flink = node -> flink;
        node -> flink -> blank = node -> blank;
}

现在我们假设 node的结构是这样的

struct node{
        struct node         *flink;
        struct node         *blink;
        int                         data;
};

我们这里先不考虑块首和大块的数据

然后在内存地址0x44444444存在node结构

0x44444444         flink                (4byte)         0x55555555
                        blink          (4byte)         0x33333333
                        data                (4byte)

32位系统上 每个指针都有32位的大小 所以是4byte

node结构中blink被赋于0x33333333  flink被赋于0x55555555 data保存一个32位的数据

node -> blink -> flink

如果不知道->是什么意思 真的麻烦补一下C语言知识再看这本书 没有基础不可能达到巅峰

我们可以把node -> blink看成0x44444444偏移4byte位置保存的数据 我们这里保存的是0x33333333

偏移多少是当初定义数据结构时先后顺序决定的

得到0x33333333 我们把0x33333333代替node->blink->flink里面的node->blink 就成了0x33333333->flink 我们再根据数据结构的定义来算偏移 于是就得到了0x33333333+0的偏移 还是0x33333333

node->flink 一样按照上面的方法 node用0x44444444代替 根据数据结构定义 就是0x44444444偏移0byte就是要访问的地址 要访问的地址是0x44444444

所以node -> blink -> flink = node -> flink;

翻译成汇编就是        mov eax,[44444444h]
                        mov [33333333h],eax

就是这么简单的两条汇编语句-_-

node -> flink -> blink = node -> blink; 还是跟上面的方法一样

node -> flink -> blink 的 node->flink替换成0x55555555 然后0x55555555->blank 根据数据结构定义偏移4byte 就等于了0x55555559

node->blink就等于了0x44444444偏移4byte 就是0x44444448

翻译成汇编就是         mov eax,[44444448h]
                        mov [55555559h],eax

前面的内容虽说很基础 可是对理解后面的东西起到很重要的作用

现在 我们再看一下节点的数据结构

struct node{
        struct node         *flink;
        struct node         *blink;
        int                         data;
};

假设在内存是这么分布的

0x33333333         flink                (4byte)         0x44444444
                        blink         (4byte)         0x55555555
                        data                (4byte)
0x44444444         flink                (4byte)         0x55555555
                        blink         (4byte)         0x33333333
                        data                (4byte)
0x55555555         flink                (4byte)         0x33333333
                        blink                (4byte)         0x44444444
                       data                (4byte)
可能不太准确=_= 我的本意是一个双向循环链表 我数据结构老师死的早 错了勿喷

我们假设这个链表都像上面那样填写好数据了

这时候 我们修改了0x44444444处的flink和blink

将flink填为0x12345678         blink填为0x87654321

0x33333333         flink                (4byte)         0x44444444
                        blink         (4byte)         0x55555555
                        data                (4byte)
0x44444444         flink                (4byte)         0x12345678
                        blink         (4byte)         0x87654321
                        data                (4byte)
0x55555555         flink                (4byte)         0x33333333
                        blink         (4byte)         0x44444444
                        data                (4byte)

然后我们释放0x44444444处的节点

释放会调用这个方法

int remove(Listnode * node)
{
        node -> blink -> flink = node -> flink;
        node -> flink -> blank = node -> blank;
}

我们就继续用汇编来解释 按照前面我所说的话 如果我们把0x44444444当做参数传送进去
那就会是这个样子

int remove(0x44444444)
{
        0x44444444 -> blink -> flink = 0x44444444 -> flink;
        0x44444444 -> flink -> blank = 0x44444444 -> blank;
}

按照之前算便宜的方法 我们把他翻译成汇编代码

mov eax,[44444444h]
mov [87654321h],eax
mov eax,[44444448h]
mov [1234567Ch],eax

大家应该明白了点什么 这尼玛就是一个能篡改内存任意位置数据的机会啊 如果用来改保存seh函数地址的指针 或者关键变量都行

试想一下 如果我们把这个节点的flink改成程序一个关键必须执行的函数指针的内存位置 然后再把blink改成我们shellcode的地址 那就咩哈哈了

我感觉理解了这个 看这一章应该没有什么问题了 如果有什么疑问可以回帖 我再补上

感谢各位看完 本人年龄比较小 就容许叫大家一声哥哥姐姐吧 也不知道有没有姐姐。。

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 297
活跃值: (265)
能力值: ( LV4,RANK:55 )
在线值:
发帖
回帖
粉丝
2
书上这部分内容走马观花的看了下
2012-4-15 00:21
0
游客
登录 | 注册 方可回帖
返回
//