하.. 진짜 단순한 바이너리라도 분석을 제대로 안하면 어떤 꼴이 나는지 볼 수 있었던 문제인데..
일단 바이너리를 보자.
void __fastcall __noreturn main(__int64 a1, char **a2, char **a3)
{
__int64 v3; // rax
unsigned int v4; // [rsp+Ch] [rbp-4h]
initialize();
printf("Name:", a2);
read_Str((__int64)&name, 0x20u);
v4 = 0;
while ( 1 )
{
while ( 1 )
{
menu();
v3 = read_int();
if ( v3 != 2 )
break;
if ( v4 <= 7 )
{
free(ptr);
++v4;
}
}
if ( v3 > 2 )
{
if ( v3 == 3 )
{
print_name();
}
else
{
if ( v3 == 4 )
exit(0);
LABEL_14:
puts("Invalid choice");
}
}
else
{
if ( v3 != 1 )
goto LABEL_14;
alloc();
}
}
}
너무 단순하다. alloc은 0xff미만 사이즈를 입력받아서 그만큼 할당 해주고 전역변수에 저장한다.
int sub_400B14()
{
unsigned __int64 v0; // rax
int size; // [rsp+8h] [rbp-8h]
printf("Size:");
v0 = read_int();
size = v0;
if ( v0 <= 0xFF )
{
ptr = malloc(v0);
printf("Data:");
read_Str((__int64)ptr, size - 0x10);
LODWORD(v0) = puts("Done !");
}
return v0;
}
내가 놓쳤던 부분은 free된 횟수 체크하는 부분을 놓쳤다.. 7개 이상 free했는데 unsorted bin에 안들어가서 진짜.. free함수 분석하고 있었는데 그냥 로컬에서 디버깅해보고나서 알았다;;
leak만 하면 끝나는 문제이다. 왜냐면 tcache double free가 되기 때문이다. 우리에게는 name이라는 전역변수를 출력할 수 있는 기능이 있기 때문에 내 원래 계획은 unsorted bin attack으로 name에 main arena를 적어주려고 했는데, 이 방법이 안되기 때문에 name에 fake chunk를(0x410이상의) 만들어서 free 해주고 leak을 한뒤 free hook에 one gadget 을 덮었다.
쉬운문제라서 자세한 설명은 없다.
'전공쪽 > pwnable.tw' 카테고리의 다른 글
[pwnable.tw] starbound (0) | 2020.12.31 |
---|---|
[pwnable.tw] death note (0) | 2020.12.29 |
[pwnable.tw] Re-alloc (0) | 2020.12.24 |
[pwnable.tw] apple store (0) | 2020.12.24 |
[pwanble.tw] breakout (0) | 2020.12.22 |