whitehat contest 2023에서 출제된 웹 Vanitas에서 나온 취약점을 알아봅시다.
파일을 읽어와 계정 정보를 가져오는 CVE-2018-13379 부분만 직접 구현 비슷하게 했습니다.
문제에서는 웹서버 파일이 ELF로 되어있지만 간단하게 exe 파일로 만들었습니다.
문제 코드
문제는 아래와 같이 구성되어 있습니다.
unpatch.exe
html - en.html, ko.html
flag - flag.txt
nopatch.exe의 코드는 아래와 같습니다.
lang 파일을 입력받아 .html을 붙여 파일이 있으면 내용을 알려주고, 없으면 에러를 출력합니다.
html 코드는 단순히 <h1>를 보여주는 파일입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
FILE* file;
char filepath[100];
char line[100];
char lang[100];
printf("파일 이름을 입력하세요: ");
scanf("%s", lang);
if (snprintf(filepath, 0x30, "./html/%s.html", lang) <= 0) {
printf("입력 오류\n");
return 1;
}
printf("filepath : %s\n",filename);
file = fopen(filepath, "r");
if (file == NULL) {
printf("파일을 열 수 없습니다.\n");
return 1;
}
printf("파일 내용:\n");
while (fgets(line, sizeof(line), file) != NULL) {
printf("%s", line);
}
fclose(file);
return 0;
}
1
2
3
4
5
6
7
8
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1>Hi lang is english</h1>
</body>
</html>
1
2
3
4
5
6
7
8
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1>Hi lang is korea</h1>
</body>
</html>
snprintf
snprintf의 원형은 아래와 같습니다.
1
2
int snprintf(char *buffer, size_t n, const char *format-string,
argument-list);
exploit
1
snprintf(filepath, 0x30, "./html/%s.html", lang)
en을 입력시 en.html 파일을 확인할 수 있습니다.
../flag.txt를 입력시 flag.txt.html
으로 입력되어 파일을 읽어올 수 없습니다.
sprintf의 size (0x30 -1) 47만큼 읽어옵니다.
따라서 뒤의 .html을 truncate를 할 수 있어 flag.txt를 읽어올 수 있습니다.
////////////////////////../flag/flag.txt
을 입력하면 -> ./html/////////////////////////../flag/flag.txt.html
이 되지만
뒤에 5자리가 짤려 .html
이 truncate가 됩니다.
후기
못풀었던 문제의 코드 취약한 부분을 직접 구현해보면서 다시 풀어보니 아쉽다….
문제 풀때에는 생각도 못했다….
열심히 해서 다음 CTF에선 꼭 풀어보자….