

2021 LINE CTF에 출제됐었던 문제다.
난이도는 9레벨, 풀이 인원은 총 3명으로 난이도가 매우 높다..
그래도 눈에 보였으니 한번 풀어보고 싶어졌다.

분석 가능한 파일은 이렇게 존재한다.
data.db에는 아무런 내용이 없고, client와 firewall.sqlext 바이너리를 분석하는 문제 같다.

RELRO를 제외한 모든 보안이 다 걸려있다고 볼 수 있다.
바로 IDA로 분석 이어가보겠다.

이게 도대체 무슨 끔찍한 오버뷰야…
main() 함수부터 살펴보겠다.

__int64 __fastcall main(int a1, char **a2, char **a3)
{
char v4; // [rsp+3h] [rbp-13Dh]
int v5; // [rsp+4h] [rbp-13Ch] BYREF
int v6; // [rsp+8h] [rbp-138h] BYREF
int i; // [rsp+Ch] [rbp-134h]
int v8; // [rsp+10h] [rbp-130h]
int v9; // [rsp+14h] [rbp-12Ch]
__int64 v10; // [rsp+18h] [rbp-128h] BYREF
const char *v11; // [rsp+20h] [rbp-120h] BYREF
void *buf; // [rsp+28h] [rbp-118h]
char s[264]; // [rsp+30h] [rbp-110h] BYREF
unsigned __int64 v14; // [rsp+138h] [rbp-8h]
v14 = __readfsqword(0x28u);
signal(14, handler);
alarm(0x1Eu);
v11 = 0;
v4 = 1;
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
if ( (unsigned int)sqlite3_open("data.db", &v10) )
{
puts("Cannot open database...");
exit(0);
}
v8 = sqlite3_load_extension(v10, "./firewall.sqlext", 0, &v11);
if ( v8 )
{
printf("SQL Error: %s\\n", v11);
sqlite3_free(v11);
exit(0);
}
buf = malloc(0x68u);
while ( v4 )
{
puts("\\n[ Menu ]");
puts("1. show version");
puts("2. run query");
puts("3. show blocked query");
puts("4. remove blocked query");
puts("5. exit");
printf("> ");
__isoc99_scanf("%d", &v5);
switch ( v5 )
{
case 1:
strcpy(s, "select sqlite_version();");
v8 = sqlite3_exec(v10, s, sub_D10, 0, &v11);
if ( v8 )
goto LABEL_21;
break;
case 2:
printf("query> ");
v9 = read(0, buf, 0x60u);
*((_BYTE *)buf + v9) = 0;
for ( i = 0; i <= 95; ++i )
{
if ( *((_BYTE *)buf + i) == 34 )
{
puts("double quotes is not allow.");
exit(0);
}
}
sprintf(s, "select block(\\"%s\\");", (const char *)buf);
v8 = sqlite3_exec(v10, s, sub_D10, 0, &v11);
if ( v8 )
goto LABEL_21;
printf("query didn't blocked...\\n[+] now execute it: %s\\n", (const char *)buf);
v8 = sqlite3_exec(v10, buf, sub_D10, 0, &v11);
if ( v8 )
goto LABEL_21;
break;
case 3:
printf("query index> ");
__isoc99_scanf("%d", &v6);
sprintf(s, "select block_log(%d);", v6);
v8 = sqlite3_exec(v10, s, sub_D10, 0, &v11);
if ( v8 )
goto LABEL_21;
break;
case 4:
v8 = sqlite3_exec(v10, "select block_remove();", sub_D10, 0, &v11);
if ( v8 )
{
LABEL_21:
printf("SQL Error: %s\\n", v11);
sqlite3_free(v11);
}
break;
case 5:
v4 = 0;
break;
default:
continue;
}
}
sqlite3_close(v10);
free(buf);
return 0;
}