ctf 웹 문제를 분석하거나 풀어보면서 공부하는 스터디 글입니다.
1. ctf 문제
2021년 tetctf의 Super calc를 분석했습니다.
라업은 아래의 두 라업을 참고했습니다.
ando.gq/tetctf-super-calc-1a0dd8dc7a5b48af9c657698d1698935
github.com/hrca-writeups/CTF-Writeups/blob/master/2021/TetCTF%202021/Super%20Calc.md
2. 문제에 사용된 취약점 목록
이 문제의 취약점은 preg_match 함수로 필터링된 문자들을 어떻게 우회하는 방법입니다. 즉 LOS에서 푼 문제들처럼 필터링에 의해 단순한 공격이 막혀있고, 이 부분을 우회하여 푸는 문제입니다. 그리고 eval 함수의 취약점도 이용합니다.
eval 함수의 취약점은 아래의 링크에 eval 함수의 설명과 함께 아주 자세히 설명되어 있습니다.
velog.io/@modolee/javascript-eval-is-evil
3. 분석
<!-- Enjoy Tsu's Super Calculator <3, Not Only + - * / but also many other operators <3 <3 <3 -->
<?php
ini_set("display_errors", 0);
if(!isset($_GET["calc"]))
{
show_source(__FILE__);
}
else
{
$wl = preg_match('/^[0-9\+\-\*\/\(\)\'\.\~\^\|\&]+$/i', $_GET["calc"]);
if($wl === 0 || strlen($_GET["calc"]) > 70) {
die("Tired of calculating? Lets <a href='https://www.youtube.com/watch?v=wDe_aCyf4aE' target=_blank >relax</a> <3");
}
echo 'Result: ';
eval("echo ".eval("return ".$_GET["calc"].";").";");
}
라업에 나와있는 소스코드의 일부분입니다. wl의 값을 get방식으로 전달된 calc의 값에서 필터링된 값을 저장하는 구조입니다. 이 부분은 웹을 어느 정도 공부를 했다면 쉽게 이해가 가능할 것이라고 생각합니다. 그리고 특징은 calc의 길이가 70이하여야 한다는 점입니다.
먼저 눈에 띄는 부분은 eval함수를 사용했다는 것입니다. 이 함수는 간단히 말해서 인자로 받은 문자열을 코드로 인식해서 해당 코드를 실행시킨 결과를 출력해주는 함수입니다. 예를 들어 eval('2+2'); 일 경우 단순 출력함수 라면 화면에 2+2를 출력해야 합니다. 하지만 eval함수로 화면에 출력할 경우 2+2의 연산 결과값인 4가 화면에 출력되게 됩니다. 즉 calc에 어떤 정보를 보내는지에 따라서 결과가 달라지고 즉 이 부분이 취약점이 되어 공격에 사용될 확률이 높다는 점입니다. 다른 말로는 우리가 원하는 코드를 서버 단에서 실행할 수 있다는 말과 같기 때문에 실제로 코딩에서는 사용하면 매우 심각한 취약점을 발생하는 함수입니다.
그리고 라업을 보면서 이 문제의 핵심은 단순히 eval 함수의 취약점을 이용하는 것이 아니라 필터링된 문자들을 어떻게 우회할 것인지 였습니다. 필터링되는 문자들을 보면 싱글쿼터('), &, ^, 0~9, 사칙연산 등의 문자가 있는지 확인하고, wl의 값이 0일 경우, 즉 이 문자들이 포함되지 않는다면 바로 die를 통해 죽게 되어 있습니다. 그렇기 때문에 소스코드에 보이는 문자만 사용이 가능한 것으로 이해하면 됩니다.
분석 내용을 정리하면
1. 길이는 70자 이하여야 한다.
2. calc는 0~9, +, -, *. /, (, ), ', ., ~, ^, |, &로만 이루어져야 한다.
그리고 제가 이 문제를 직접 풀어본 것은 아니기 때문에 이 부분은 라업에 의한 내용 입니다.
3. 이 문제의 플래그는 소스 코드와 같은 디렉토리인 fl4g1sH3re.php이다. 그렇기 때문에 1=system('cat fl4g1sH3re.php'); 라는 코드를 실행하여 서버에 있는 플래그 파일을 읽어와야 한다.
3번 문제같은 경우에는 저 파일 이전에 1=system(ls); 를 통하여 쉘을 따고 현재 디렉토리에 존재하는 파일을 확인한 것 같습니다.
이렇게 분석을 마친 뒤 이제부터 해야할 점은 어떻게 허용 가능한 문자들로 system함수와 그 인자를 가지는 페이로드를 작성할 것인가 입니다.
두 라업 모두 xor연산을 이용했습니다.
예를 들어
'G' ^ '0' = 'w' (not whitelisted)
'G' ^ '1' = 'v' (not whitelisted) ...
'G' ^ '8' = 127 (not valid ASCII character)
'G' ^ '9' = '~' (whitelisted, success!)
이런 식의 연산을 통해 두 문자의 xor 연산을 통해 새로운 문자를 만들어내는 방식입니다.
여기서 a ^ b = c의 연산을 b ^ c = a의 연산으로 변환이 가능하기 때문에 위에서 만들어낸 연산인 필터링 되지 않는 ~, 9의 문자로 알파벳 G를 만들어 낼 수 있는 것입니다. 이 문제에서는 이 연산이 핵심으로 사용되었습니다.
4. 전체 익스코드 분석
chars = '0123456789+-*/().~^|&'
search = ")"
print("character ", search)
for c in chars:
x = chr(ord(c)^ord(search))
print(c, "=>" x)
익스 코든는 두 번째 라업의 익스코드가 조금 더 간단하다고 생각하여 가져왔습니다. 분석에서 설명한 내용으로 필요한 페이로드인 1=system('cat fl4g1sH3re.php'); 를 허용된 문자들로 만드는 코드입니다. 여기서 만약 70글자가 넘어갈 경우에 대해서는 첫 번째 라업에서 설명이 잘 되어 있습니다.
만약 단순히 $_GET[]을 허용 가능한 문자로 만들면 ('&'^('('^'*')).('8'^('9'^'^')).('9'^'~').('9'^'|').('~'^'*').(('('^'-')^'^').('^'^('('^'+')) 으로 90글자가 되어 70자가 넘어가버립니다. 이때, xor연산의 결합법칙을 이용해서 연산 길이를 줄인 것 같습니다. 그렇게 해서 코드를 줄이면
'(9222(('^'*^^^^-+'^'&8+)8^^'로 감소합니다. 이 방식을 이용해서 페이로드의 길이를 줄여서 사용했습니다.
이러한 방법으로 필요한 페이로드인 1=system('cat fl4g1sH3re.php'); 를 제작하여 calc의 값으로 전달하게 되면 서버 단에 저장되어 있는 플래그 파일을 읽어 올 수 있습니다.
5. 리뷰
이 문제는 어떻게 보면 그냥 필터링을 우회해서 시스템 단의 쉘을 획득하여 플래그를 읽어오는 간단한 구조의 문제처럼 보일지 모릅니다. 하지만 사용가능한 문제가 굉장히 극단적으로 제한되어 있으며, 이 문자들을 이용해 페이로드를 작성해야 하는 부분이 굉장히 흥미로웠습니다. 그리고 이 문제에서 사용한 xor 연산을 이용하여 새로운 문자를 만드는 방법도 처음 알게 되어 새로운 공격 방법을 공부할 수 있었습니다.(물론 이 부분은 eval 함수의 특징 때문에 가능한 것 같긴합니다.) 그래서 문제 구조는 단순할지 모르지만 페이로드를 만드는 과정에서 꽤나 어려움을 겪을 수 있고, 만약 저처럼 xor연산을 통해 새로운 문자를 만드는 방법을 모르고 있던 사람이 이 문제를 처음 접하게 되면 페이로드 작성 방법에 대하여 생각하다가 막힐 것이라고 생각합니다. 하지만 이 부분은 xor 연산의 활용에 대해서 알고 있는 사람이라면 쉽게 풀릴 수도 있는 문제이기 때문에 꽤 극단적인 문제라고 생각합니다. 그래서 저는 이 문제의 점수를 5.5점으로 주고 싶습니다. 왜냐하면 이 문제는 이 문제와 비슷한 문제를 풀어보지 못한 사람에게는 페이로드 작성 과정과 문제 분석 과정이 꽤나 어려운 과정이라고 생각하지만, 알고 있던 사람들에게는 굉장히 접근이 쉬운 문제라고 생각하기 때문입니다.
'웹 > CTF study & write up' 카테고리의 다른 글
ctf study #6 (0) | 2021.02.24 |
---|---|
ctf study #5 (0) | 2021.02.17 |
ctf study #4 (0) | 2021.02.15 |
ctf study #3 (0) | 2021.02.11 |
ctf sutdy #1 (0) | 2021.02.03 |