Где уязвимость в этом php-коде?

#php #security

#php #Безопасность

Вопрос:

Я решаю проблемы codeshell.kr

   <?php 
    include("./config.php"); 

    $foo = $_GET['______foo_adm1nkyj______']; 
    $check = urldecode($_SERVER['QUERY_STRING']); 

    if(preg_match("/_| /i", $check)) 
    { 
        die("no hack ~_~"); 
    } 
    if($foo == "adm1nkyj") 
    { 
        echo $flag; 
    } 

    echo "<br/>"; 
    highlight_file(__FILE__); 
  ?>
  

Что я должен сделать, чтобы получить $flag ?
И в чем уязвимость этих кодов? Это в $_GET ? или preg_match() ? Я не могу найти его, несмотря на поиск в Google.

Комментарии:

1. Проблема в том, что preg_match() проверит _ exists из URL (строка ?______foo_ad1nkyj____=someValue и запустите die() метод .. вы пробовали заменить _ на альтернативный код для него? Это не совсем сайт для этого вопроса, это не программируемый вопрос, поэтому я голосую против.

Ответ №1:

Решение заключается в следующем:

 http://123.111.158.161/codeshell/prob2/?......foo.adm1nkyj......=adm1nkyj
  

Это работает, потому что PHP заменяет точки и пробелы символами подчеркивания в ключах массивов данных запроса ( $_GET , $_POST , $_REQUEST , $_COOKIE ).

Из PHP docs:

Примечание: точки и пробелы в именах переменных преобразуются в символы подчеркивания. Например <input name="a.b" /> , становится $_REQUEST["a_b"] .

Вероятно, это пережиток времен, когда глобальные регистры еще существовали.

Ответ №2:

Проблема на самом деле довольно проста, если вы знаете об одной вещи: php заменяет точки в именах GET переменных подчеркиванием.

Скрипт проверяет, есть ли символ подчеркивания в переменной GET, и если да, то умирает. Таким образом, он не может достичь точки, где он проверяет значения GET переменных. Но если вы замените подчеркивания точками, это пройдет.

Просто вызовите этот URL:

 123.111.158.161/codeshell/prob2/?......foo.adm1nkyj......=adm1nkyj