ctf 웹 문제를 분석하거나 풀어보면서 공부하는 스터디 글입니다.\
1. CTF 문제
2020 justCTF의 Baby CSP입니다. 이 문제를 선택해서 공부한 이유는 앞의 Build a Better Panel문제를 분석하면서 공부하다가 CSP가 어떻게 쓰이는지를 알게 됐고, 조금 난이도가 쉬운 문제를 공부하면서 확실하게 개념을 짚고 넘어가고 싶어서 선택했습니다.
참고한 라업은 아래와 같습니다.
hackmd.io/@terjanq/justCTF2020-writeups#Baby-CSP-web-6-solves-406-points
2. 취약점 목록
1. Reflected XSS
2. CSP bypass
3. PHP Warnings
3. 분석
소스 코드
<?php
require_once("secrets.php");
$nonce = random_bytes(8);
if(isset($_GET['flag'])){
if(isAdmin()){
header('X-Content-Type-Options: nosniff');
header('X-Frame-Options: DENY');
header('Content-type: text/html; charset=UTF-8');
echo $flag;
die();
}
else{
echo "You are not an admin!";
die();
}
}
for($i=0; $i<10; $i++){
if(isset($_GET['alg'])){
$_nonce = hash($_GET['alg'], $nonce);
if($_nonce){
$nonce = $_nonce;
continue;
}
}
$nonce = md5($nonce);
}
if(isset($_GET['user']) && strlen($_GET['user']) <= 23) {
header("content-security-policy: default-src 'none'; style-src 'nonce-$nonce'; script-src 'nonce-$nonce'");
echo <<<EOT
<script nonce='$nonce'>
setInterval(
()=>user.style.color=Math.random()<0.3?'red':'black'
,100);
</script>
<center><h1> Hello <span id='user'>{$_GET['user']}</span>!!</h1>
<p>Click <a href="?flag">here</a> to get a flag!</p>
EOT;
}else{
show_source(__FILE__);
}
// Found a bug? We want to hear from you! /bugbounty.php
// Check /Dockerfile
docker file
FROM php:7.4-apache
COPY src-docker/ /var/www/html/
RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"
EXPOSE 80
1. Reflected XSS
공격자가 악성 스크립트가 있는 URL을 클라이언트에게 보내고, 그 URL을 눌렀을 때 해당 URL에 맞는 응답을 웹 서버에서 보내주는 방식의 XSS공격입니다. 기본적인 XSS공격에 대한 내용은 다루지 않겠습니다.(구글링해보시면 많은 자료들이 나올겁니다.) 이 공격에서는 주로 get방식으로 데이터를 전달할 때 사용됩니다. 왜냐하면 get방식이 사용될 때 공격자가 원하는 악성 스크립트 등을 서버 측에 전달하기가 쉽기 때문입니다. 전체적인 구조는 아래와 같습니다.
위의 페이지가 문제의 페이지입니다. 문제를 보면 get방식으로 user의 값을 전달받는 것으로 보이며 Reflected XSS 공격이 가능한 페이지라고 합니다.(제가 직접 문제를 풀어보지 못하기 때문에 라업에 의존한 분석임을 밝힙니다.) 그리고 소스코드를 보면 user의 길이느 23으로 제한되어 있는 것을 알 수 있습니다.
if(isset($_GET['user']) && strlen($_GET['user']) <= 23)
그리고 한 가지 더 주목해야 할 점은 CSP가 걸려있는 것을 코드에서 확인이 가능합니다.
header("content-security-policy: default-src 'none'; style-src 'nonce-$nonce'; script-src 'nonce-$nonce'");
이 부분이 CSP가 설정되어 있는 것을 보여주는 코드입니다.
그리고 아래의 링크를 참고하면 23길이보다 작은 xss 공격 코드를 참고하여 공부할 수 있습니다.
이 문제의 라업에서는 <svg/onload=eval(name> 을 사용했습니다. 하지만 이 코드를 사용하려고 하면
위 화면처럼 CSP에 의해서 오류 메시지가 발생하면서 공격이 막히게 됩니다. 그렇다면 CSP가 무엇인지 이를 어떻게 우회했는지 살펴보겠습니다.
2. CSP bypass
CSP는 저번 ctf분석에서도 소개했듯이 보안 규정과 비슷한 역할을 합니다. 주목적은 1번 취약점인 XSS공격을 막기 위해서 사용됩니다. 즉 CSP를 설정해놓은 규정에 맞는(유효한) 페이지만 화면에 보여주고, 만약 CSP의 조건에 맞지 않을 경우 위처럼 경고를 출력해주면서 공격자가 시도하는 화면 등을 띄워주지 않습니다. 그렇다면 이 정책을 어떻게 우회하는지 살펴보겠습니다.
이 문제에서 사용한 우회 방법은 php에서 echo등의 함수를 이용하여 출력할 때 버퍼링을 하는 과정을 악용한 것입니다. 이 우회 기법을 사용하기 위해서는 php의 버퍼링 사이즈가 4096바이트임을 알고 있어야 한다고 합니다. 그리고 소스코드를 보면 header함수를 통해 csp가 작동(?)하는 것을 볼 수 있는데, 여기서 header함수는 버퍼링의 대상이고, 버퍼링이 되어야만 함수가 정상적으로 실행됩니다. 하지만 버퍼링크기를 더미 값으로 채운 뒤 함수를 실행하면 header함수의 내용이 실행이 되지 않습니다. 이 부분에서 3번째 취약점인 PHP Warnings을 이용합니다.
3. PHP Warnings
이 문제에서 alg인자 값을 조정하면 아래와 같은 오류를 화면에 출력하게 됩니다. 이 오류는 개발자 모드에서 php가 실행되기 때문입니다.
여기서 주목할점은 alg 인자를 조작하면 '화면'에 에레 메시지들이 출력된다는 점입니다.
그렇다면 다시 CSP를 우회하는 부분으로 넘어가겠습니다. 앞서 설명했듯이 header함수의 내용(CSP)가 실행되기 위해서는 header함수 실행 전 '화면'에 값이 출력되어서는 안 된다고 설명했습니다. 하지만 페이지의 php오류를 이용하면 화면에 에러 메시지를 다수 출력하게 되고, 에러 메시지로 php 버퍼링 사이즈를 덮을 수 있다면 CSP 우회가 가능해지게 됩니다. 그리고 여기서 alg인자를 조절하여 에러메시지의 크기를 조절할 수 있기 때문에 이를 이용할 수 있습니다.
4. 전체 익스코드 분석
<script>
name="fetch('?flag').then(e=>e.text()).then(alert)"
location = 'https://baby-csp.web.jctf.pro/?user=%3Csvg%20onload=eval(name)%3E&alg='+'a'.repeat('292');
</script>
분석 내용에서 설명한 부분을 XSS코드로 만든 페이로드입니다. user에서는 설명한 XSS 코드를 넣어주었고, alg인자로는 a를 큰 수로 반복하여 에레 메시지를 충분히 많이 띄워주게 설정해 둡니다. 그리고 조금 이해하고 넘어가야할 부분은 name에 들어가는 정보입니다.
이 부분을 조금 구글링해보니 fetch api를 사용한 것으로 보입니다. 이는 웹 서버에서 리소스를 획득하는 것 같습니다. 그래서 간단하게 나마 해석을 해보면 flag의 내용을 가져와서 text형태로 저장하거나 alert한다라고 이해를 했습니다. 그래서 아마 이 스크립트를 넣어주면 flag내용을 text형태로 가져와서 alert로 띄워주지 않을까 추측이 됩니다.
5. 리뷰
이 문제의 라업을 보고 공부하면서 CSP가 무엇인지 어떤 기능을 하는지 확실하게 짚고 넘어갈 수 있는 좋은 응용 문제였다고 생각합니다. 다른 라업에서 공부했을 때와 동아리 수업을 들었을 때 CSP의 개념만 어렴풋이 알고 넘어갔는데, 이 문제를 공부하면서 어떤 기능을 하는지와 어떤 목적을 가지고 사용되는지는 확실하게 이해하고 넘어간 것 같습니다. 그리고 앞서 공부했던 우회방법과는 또다른 우회방법을 접할 수 있어 좋았습니다. 새로운 개념을 익히고 공부할 수 있는 문제라고 생각하여 5점정도를 주었습니다.
'웹 > CTF study & write up' 카테고리의 다른 글
ctf study #7 (0) | 2021.02.24 |
---|---|
ctf study #6 (0) | 2021.02.24 |
ctf study #4 (0) | 2021.02.15 |
ctf study #3 (0) | 2021.02.11 |
ctf sutdy #2 (0) | 2021.02.09 |