본문 바로가기

카테고리 없음

RealWorldCTF2020 MoP2021 Write up

이번에 MoP2021 하나라도 풀어서 정말 다행이라고 생각했다. 이 문제 덕분에 중간에 12등까지 올라왔지만 끝나고보니 엄청 떨어져있었다... 그래도 빨리 풀어서 만족이라고 생각한다

 

일단 문제를 보면 php 명령어를 그대로 실행하는데 php RCE라는거를 대충 예상 할 수 있다.

팀원 분 한분이 php 버전에 맞는 UAF Exploit 을 찾아주셔서 그걸로 Reverse Shell 을 땄다.

uaf.php
0.01MB
test.py
0.00MB

이걸로 Reverse Shell 을 따게되면 이제 /readflag 를 실행시켜서 플래그를 읽어야되는데,

이게 readflag 를 보게되면 순식간에 입력을 받고 끊어버리게된다.

 

그래서 pwntools 를 이용하여 해봤는데 되지를 않았다. 아마 딜레이 때문에 그런거같은데 거기서 생각해낸게 /tmp 에 들어가서 파일을 생성한 후 그걸로 exploit을 시키는것이다.

 

예상에 맞게 tmp 에는 다른사람들이 계속 자기 파일들을 올리고 있었다. (대회 초반에는 /tmp 에 존재하는 파일들이 삭제가 늦게됬다. 이것때문에 자신의 코드가 유출이 많이 됬던거같다. 물론 중간에 패치됬다.)

 

그래서 나도 pwntools 처럼 작동할 수 있는 php 코드를 짰다. php 로 짠 이유는 shell 안에 python 이 없고 php가 존재했기 때문이다. 

<?php 
$d = array(
    0 => array("pipe", "r"),
    1 => array("pipe", "w")
);
$process = proc_open("/readflag", $d, $pipes);

echo fgets($pipes[1]);
echo fgets($pipes[1], 5);

$str1 = fgets($pipes[1]);
echo($str1);
#preg_match_all('/\(.*?\)/', $str1, $str2);
preg_match_all("/[^()]+/", $str1,$str2);
#var_dump($str2);

$str3 = $str2[0][0] + $str2[0][2] + $str2[0][4] - $str2[0][6] - $str2[0][8];

$str4 = strval($str3);
#$str4 = $str4 + "\n";
#echo $str3;
var_dump($str4);

fwrite($pipes[0], $str4."\n");

echo fgets($pipes[1]);
echo fgets($pipes[1]);
echo fgets($pipes[1]);
echo fgets($pipes[1]);


$r = proc_close($process);

16분의 1확률 이다. 원래 연산도 계속 바뀌는건데 귀찮아서 이렇게 짰다.

 

그리고 한가지 꿀팁을 주자면 bash 만을 이용해서 curl 하고 비슷한 명령어를 만들수 있는데 이걸로 외부에서 파일을 갖고와서 실행시켰다.