25.02.2009

Использование *nix procfs при проведении LFI

Файловая система /proc - это механизм ядра *nix-систем, представляющий собой виртуальную файловую систему расположенную в памяти. Обращаясь к ее файлам можно работать с внутренними структурами ядра, получать полезную информацию о процессах и изменять установки ядра "на лету". Не так давно в паблике появилась интересная информация о том, как можно использовать файлы unix'овой файловой системы /proc для получения шелла на атакуемом сайте при наличии LFI. Стоит отметить, что это актуально прежде всего для Linux-систем, так как уже долгое время в BSD-системах procfs по-умолчанию не используется из соображений безопасности.

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

Если у нас есть права на чтение файлов расположенных в /proc, то мы можем воспользоваться этим для проведения атаки. Прежде всего следует определить, каким образом выполняется PHP скрипт: через CGI или в mod_php. Для этого, например, можно обратиться файлу /proc/self/status, содержащем детальную информацию о статусе текущего процесса.

Если PHP-скрипты выполняется на сервере как CGI-приложения, то наиболее простой метод - использовать файл /proc/self/environ, который содержит переменные окружения процесса. Данный способ был описан в статье G-Brain'a LOCAL FILE INCLUSIONS.

Допустим, имеется уязвимый код:

<?php
// ...
include('include/' . $_GET['file']);
// ...
?>

PoC:
GET /index.php?file=../../../../../../../../../proc/self/environ HTTP/1.1
Host: www.site.com
Accept: <?php echo `ls -la`; ?>
Я предпочел бы помещать php-код в заголовок Accept вместо User-Agent, как предлагается в статье G-Brain'a, т.к. Accept, в отличие от User-Agent'а, не логируется веб-сервером.

Но гораздо чаще мы все же имеем дело с mod_php. Здесь использование /proc может также сильно упростить задачу. Есть статья, от USH team LFI2RCE (Local File Inclusion to Remote Code Execution) advanced exploitation: /proc shortcuts, в которой описывается способ доступа к лог-файлам используя возможности /proc.

Через /proc мы можем получить доступ к файловым дескрипторам процесса и прочитать различные файлы логов:
/proc/self/fd/x
где x - число от 0 до n, которое стоит поперебирать, чтоб найти подходящий файл для внедрения кода шелла.

В случаях, когда мы имеем только вывод содержимого, без исполнения кода, возможность чтения файлов из /proc также может быть весьма полезна, так как оттуда можно получить множество информации о системе.

Полезная документация по /proc