Team : r3boot
Rank : 175/491th
처음으로 r3boot 팀과 함께 CTF를 참여했다. 하지만 Insomni'hack 도 스위스에서 CTF 본선과 컨러런스가 진행되는 규모있는 대회였고 문제도 난이도가 높아서 warmup 외에는 문제를 풀지 못했다. 하지만 종료 후 write-up을 확인해보니 앞전 Real World CTF 처럼 아예 접근이 불가능한 정도는 아니었던 것 같기에 꼼꼼히 공부를 해야겠다.
https://sekai.team/blog/insomni-hack-teaser-2022/pimpmyvariant/
주어진 사이트는 아래와 같다
뭔가 딱히 공격할 수 있는 곳이 보이지 않는 사이트였다.
robots.txt에 아래와 같은 내용이 존재한다
위 파일들에 접근해보면, flag.txt와 todo.txt에는 Try Harder와 같은 쓸데없은 내용이 적혀있다
/readme , /new, /log에 접근해야한다
우선 /readme에 접근하면
Hostname not allowed를 볼 수 있다
따라서, burp로 request header의 Host를 localhost로 변경해서 Hostname bypass 한다
/www/jwt.secret.txt 파일을 읽어야함을 알 수 있다
/new에 접근해보면 js 코드가 나온다
위 코드를 보면 /api로 접근하는 것을 알 수 있다
이때 XML request를 하면, jwt 값을 함께 response 해준다
XML request를 하고 있는데, /www/jwt.secret.txt 내용을 보기 위해 XXE를 수행한다
jwt.secret.txt:54b163783c46881f1fe7ee05f90334aa 임을 알 수 있다
생성한 jwt로 /log에 접근이 가능하다
/www/UpdateLogViewer.inc가 존재하며 이는 바로 접근하면 내용을 볼 수 있다
http://pimpmyvariant.insomnihack.ch/UpdateLogViewer.inc
<?php
class UpdateLogViewer
{
public string $packgeName;
public string $logCmdReader;
private static ?UpdateLogViewer $singleton = null;
private function __construct(string $packgeName)
{
$this->packgeName = $packgeName;
$this->logCmdReader = 'cat';
}
public static function instance() : UpdateLogViewer
{
if( !isset(self::$singleton) || self::$singleton === null ){
$c = __CLASS__;
self::$singleton = new $c("$c");
}
return self::$singleton;
}
public static function read():string
{
return system(self::logFile());
}
public static function logFile():string
{
return self::instance()->logCmdReader.' /var/log/UpdateLogViewer_'.self::instance()->packgeName.'.log';
}
public function __wakeup()// serialize
{
self::$singleton = $this;
}
};
직렬화?