Capture the Flag – řešení flagu 9

Jako třešničku na dortu jsme si nechali řešení poslední flagu, který odolal statisícům pokusů o jeho rozluštění.

< flagy 7 – 8

Flag 9: „Zákaz vstupu se zvířaty“

Umístění flagu bylo jasné poměrně brzo. Při objevení souboru phpinfo.php jsme se dozvěděli i o existenci zvláštní složky secret-flag9-dir.

Před samotnou cestou k flagu jsme se vydali několika slepými uličkami.

WP-Scan ukázal, že je na webu plugin se zranitelností typu Local File Inclusion. Z jeho kódu však bylo patrné, že se nám příliš nehodí – soubory načítá pomocí require_once a PHP soubory vykoná a nezobrazí. Pro získání jiných citlivých informací by se však velmi hodil.

Při skenování portů se ukázalo, že je otevřený port 22 – SSH. Při pokusu, zda náhodou správce serveru nepoužil nějaké primitivní heslo, vyšlo najevo, že heslo lze velmi jednoduše odhadnout a administrátorský přístup byl náš. Alespoň zdánlivě. Brzy se ukázalo, že SSH není opravdové SSH, ale pouze jeho simulace. Tudy cesta také nevedla.

Dalším dobrým nápadem bylo využití nalezeného Admineru. Bylo možné se připojit k externímu databázovému serveru s oprávněním pro práci se soubory a díky tomu číst libovolné soubory z klienta:

LOAD DATA LOCAL INFILE "/home/flag5a6557/htdocs/www/flag.php" INTO TABLE test.a

Bohužel zatím neznáme jméno souboru, který se snažíme získat. Pokud tedy nechceme slepě zkoušet, není to pro nás vhodná cesta.

Pokusy o přihlášení do administrace přes login formulář byly také liché, ze zdrojového kódu stránky šlo zjistit, že formulář není pravý. A i kdyby pravý byl, tak WP samotný byl upraven tak, aby byl jen read-only a přihlášení by tak možné nebylo.

Přes administraci však jedna z cest vedla. Z předchozích flagů jsme totiž získali dostatek informací, abychom byli schopni vygenerovat přihlašovací cookies.

  • Hash hesla z databáze
  • Krypto klíče z wp-config.php
  • Session_token z uživatelských metadat v databázi

Za normálních okolností by potřebný session token byl k ničemu, protože se jedná o sha256 hash z více než 40 znakového náhodného řetězce, který v cookie musí být v originální podobě. U nás se však jednalo pouze o hash slova wordpress a tak ho bylo možné jednoduše zneužít.

Stačilo připravit další WP web, kterému se předhodily získané krypto klíče a založil uživatel se stejným hashem hesla (je jedno, že heslo neznáme) a nechat si vygenerovat přihlašovací cookies, které následně stačilo vložit do prohlížeče pod správným názvem obsahujícím md5 hash adresy webu:

wp_generate_auth_cookie(1,1560620800,'logged_in', 'wordpress')
wp_generate_auth_cookie(1,1560620800,'secure_auth', 'wordpress')

Díky tomu jsme se dostali do administrace, ta sice byla jen pro čtení, to však nezabránilo nahrání vlastního pluginu i když nešel aktivovat. Takto jsme na web propašovali cizí kód v podobě prohlížeče souborů.

Touto poměrně komplikovanou cestou jsme byli schopni získat přístup k poslednímu flagu.

Byla zde však i mnohem jednodušší cesta. Mohli jsme si všimnout, že je na webu nahrán Adminer ve starší verzi 4.2.3, která navíc podporuje mnoho dalších databázových systémů – včetně SQLite.

SQLite má nepříjemnou vlastnost, že při přístupu k neexistující databázi ji na disku vytvoří. Vytvořit lze pouze soubory s koncovkou .db (a několika dalšími). To nás ale příliš nezbrzdilo. Pomocí příkazu ATTACH DATABASE jsme jednoduše vytvořili novou prázdnou databázi s koncovkou .php. Pak už stačilo jen vytvořit novou tabulku a naplnit ji PHP kódem. I přes trochu binárních dat na začátku souboru se náš kód bez problémů pustil a mohli jsme tak jednoduše získat poslední flag! Stačilo už jen určit výsledek logické podmínky:

I přes to, že jsou existující soubory na serveru pouze pro čtení, šlo tímto způsobem modifikovat vzhled webu. Stačilo například vytvořit soubor home.php ve složce šablony a díky hierarchii šablony byl pak místo samotného webu zobrazen on.

Objevením posledního flagu naše CTF soutěž končí. Doufáme, že vás bavila, že  jste se třeba i něco zajímavého naučili a že se uvidíme na WordCampu.

 

Kupte si vstupenku a přijďte na WordCamp

Capture the Flag – řešení flagů 7 – 8

Flagů už moc nezbývá, pojďme se tedy podívat na další dva.

< flagy 4 – 6 > flag 9

Flag 7: „Včera, dnes a zítra“

Tyto flagy byly zaměřeny na databázi. V robots.txt jsme se dozvěděli o existenci souboru backup.sql. To však byla ošklivá nástraha a při pokusu o jeho stažení jsme získali ban. Cesta to ale nabyla úplně slepá a získali jsme nápovědu, že podobné soubory je dobré zkomprimovat – backup.sql.gz byl už na dosah.

Při prohlídce dumpu databáze jsme mohli vidět odkazy na některé již ulovené flagy, ale v tabulce ctf_options jsme nalezli i zvláštní vlastnost flag7_option a první polovinou tohoto klíče.

Někdy nás však stará hodnota nezajímá a chtěli bychom spíše přítomnost. Cílem tedy bylo zjistit jakou hodnotu má flag7_option nyní. K  tomu bylo potřeba získat přístup k živé databázi. Možností zde bylo více.

Tu první nám prozradil wp-scan, který poukázal na použití pluginu se zranitelností typu SQL injection. Po prozkoumání zranitelného kódu a několika pokusech na živém webu stačilo jen připravit dotaz, který nám hodnotu z databáze vyčetl. Drobným zádrhelem zde mohl být fakt, že plugin nahrazuje mezery za znak %, to však šlo jednoduše obejít náhradou mezer za prázdný komentář v našem payloadu.

Výsledný dotaz

K získání informací z databáze bylo samozřejmě možné použít automatizovaný nástroj SQLmap, nicméně cesta s UNION SELECT je trochu elegantnější.

Díky této zranitelnosti jsme zkompletovali sedmou sadu flagů.

Flag 8: „Heslo, heslo, heslíčko“

Při zkoumání databáze bylo možné narazit na další z flagů. Zjistili jsme, že zde existují 3 další uživatelé WordPressu – flag8a, flag8b a flag8c. Každý z nich používal jiný hash hesla – staré jednoduché MD5, aktuální PHPASS a moderní BCRYPT. Máme tedy 3 hashe a z principu pravidel naší CTF soutěže tak víme, že každý bude složen z 4 číslic. Stačilo je tedy cracknout a to nebylo vůbec složité.

V ukázce jsme na to použili nástroj John the Ripper s maskou pro 4 číslice: john --mask=?d?d?d?d --format=raw-md5 soubor-s-hashi.txt

MD5 byla prolomena ve zlomku vteřiny. PHPASS netrval o mnoho déle i když drobné zpomalení bylo znát. Na BCRYPT jsme si museli několik minut počkat.

Při použití grafické karty bychom samozřejmě měli výsledky mnohem dříve.

Prolomením všech 3 hashů jsme získali další klíč.

 

Alternativní cestou k získaní informací z databáze byl fakt, že na webu byl zapomenutý nástroj Adminer (skvělý tool, ale stejně jako PHPmyAdmin ho není rozumné nechávat přístupný). Z wp-scanu jsme dále zjistili, že je na webu přístupný swap soubor .wp-config.php.swp, který vznikl při úpravě konfiguračního souboru na produkci editorem vim. Po stažení jsme získali přístupové údaje k databázi. Skoro…

Heslo bohužel nebylo v souboru přítomné, protože bylo získáno pomoci proměnné prostředí „dbpass“. Proměnné prostředí lze však vyčíst z výpisu phpinfo(), který jsme již dříve objevili v souboru phpinfo.php. S těmito znalostmi tak nebyl problém získat přístup do databáze mnohem pohodlněji.

Do příště nám zbývá už jen poslední flag 9, na kterém si mnoho soutěžících vylámalo zuby.

 

 

Kupte si vstupenku a přijďte na WordCamp

Capture the Flag – řešení flagů 4 – 6

Přinášíme ukázku řešení dalších 3 flagů z naší CTF soutěže.

< flagy 0 – 3 > flagy 7 – 8

Flag 4: „Chybovat je lidské“

Při bezpečnostních testech je běžné, že se snažíme aplikaci donutit udělat nějakou chybu, aby nám prozradila nějaké informace, nebo provedla něco nečekaného.

U webových aplikací je častým prohřeškem zobrazování chybových hlášek s informacemi, které by měl znát jen administrátor.

Nejjednodušší cestou jak toto ověřit je navštívení adresy /wp-includes/rss-functions.php, čímž vyvoláme chybu 500. Podobně funguje i volání přímo šablony (např. /wp-content/themes/twentynineteen/index.php), nebo různých souborů z administrace (/wp-admin/admin-header.php). Jako odměnu za vyvolání chyby 500 získáme první flag. Pro zobrazení vlastní chyby jsme si museli pohrát s PHP funkci register-shutdown-function.

Další běžnou chybou je 404 – nenalezeno. WP nám v tomto případě vrací poměrně použitelnou stránku, což je častým problémem u jednodušších systémů. Ta je typicky renderována ze souboru 404.php v šabloně. Při infekci webu se tento soubor často zneužívá jako odložený spouštěč infekce – spuštění škodlivého kódu se odloží do vyvolání chyby 404 návštěvníkem, nebo přímo útočníkem. Na našem webu je v něm však ukryt pouze další flag.

Pokud se pokusíme provést nějakou nepovolenou akci, tak nám WordPress zobrazí chybovou hlášku pomocí funkce wp_die() a pošle stavový kód 403. Tuto chybu mimo administraci můžeme získat například přímým přístupem k souboru wp-mail.php. Pro úpravu této chybové hlášky jsme použili wp_die_handler a nechali ji prozradit další flag.

Poučení: výpisy chyb na produkčním serveru nemají co dělat.

Flag 5: „Známe své lidi“

Chyba 500 z minulé sady flagů nám prozradila i umístění aplikace na serveru. Z toho bylo možné získat jméno uživatele, pod kterým na serveru aplikace běží. Není náhoda, že jeho jméno je prvním flagem tohoto klíče. Za normálních okolností by bylo možné tuto informaci získat i z informací v zapomenutém phpinfo.php z předchozích úkolech. Tam jsme však cestu naschvál zcenzurovali 🙂

Zajímavé informace o uživatelích můžeme získat i na jiných místech. Pokud nás zajímají přímo uživatelé WordPressu, můžeme je zkusit vyčítat pomocí parametru ?author=X. Nebo je můžeme získat moderněji – použitím REST API a endpointu /wp-json/wp/v2/users. Našem webu tak nalezneme velmi zajímavého uživatele s id = 5. Pokud tedy navštívíme adresu /?author=5, adresa se magicky změní a prozradí nám login našeho uživatele, což je zároveň další flag.

Dalším typem uživatelů jsou komentující návštěvníci. V základním nastavení sbírá WordPress jejich e-maily, ze kterých následně generuje adresu pro gravatary. To je poměrně nešťastné, protože služba gravatar používá k hashování e-mailu md5 a tak není příliš složité e-maily reverzovat zpět.

Stejně, jako na mnoha dalších webech, jsme nesmazali testovací příspěvek s id = 1 – stačí navštívit /?p=1. Zde číhá drobná zrada. Pokud ve WP vypneme komentáře, tak se změna aplikuje pouze na nově přidané příspěvky – ty staré se řídí původním nastavením a je potřeba u nich komentáře povypínat ručně a na to se často zapomíná. Tento první zapomenutý příspěvek je proto často terčem různých spambotů.

Podivný komentář jste tak mohli najít i u nás:

Jméno uživatele prozrazuje, že hodnota flagu se skrývá v jeho e-mailu. Stačilo tedy získat adresu obrázku jeho gravataru, vzít si z ní md5 hash a ten zkusit prolomit. Protože to jsou jen 4 čísla, nebylo to nic těžkého a flag byl náš!

Tyto informace o uživatelích běžně získáme i z REST API (můžete si to vyzkoušet na webu WP Exposé). My jsme však aplikovali filtr, který se snaží citlivá data z REST API odstraňovat. Pokud nechcete, aby unikaly informace o e-mailech, je lepší gravatary zakázat, nebo pro ně použít jiné řešení.

Flag 6: „Důvěrné informace“

V jednom z předchozích flagů jsme zjistili, že na webu je otevřený git repozitář. Zjistili jsme také, že se zde vyskytuje soubor flag.php, ve kterém jsou určitě zajímavé informace. Bohužel se při přímém přístupu vykonal a nic zajímavého neprozradil.

Není však nic lehčího, než z git repozitáře získat zdrojové kódy a podívat se přímo do nich. Pomohli jsme si automatickým nástrojem, který prochází známé soubory ze struktury repozitáře a snaží se z nich vyparsovat jednotlivé objekty.

Po rekonstrukci repozitáře a zdrojových kódů se již stačilo jen podívat do obsahu flag.php a půlka klíče byla naše.

Při podrobnějším zkoumání změn v repozitáři bylo dále možné získat informaci, že se upravoval soubor search.php v šabloně (git whatchanged -n 1). A navíc změna není už od pohledu úplně bezpečná – není zde ošetřený uživatelský vstup, což s sebou přináší možnost XSS.

Pokud jste zkusili tento kód zneužít a dokázat existenci XSS a zavolat si nějaký pěkný javascriptový alert(), web tento pokus detekoval a místo toho zobrazil hlášku s odměnou ve formě flagu :-).

WordPress se sám o sobě snaží uživatelské vstupy dobře ošetřovat, nevhodně použitý vlastní kód však může jeho principy narušit.

Poučení: nechávat přístupný git repozitář na webu rozhodně není dobrý nápad.

Získání těchto flagů již vyžadovalo trochu úsilí a zkoušení. A příště se to nezlepší.

 

Kupte si vstupenku a přijďte na WordCamp

Capture the Flag – řešení flagů 0 – 3

V tomto souhrnu si popíšeme způsob nelezení prvních 4 flagů v naší soutěži o volné lístky na WordCamp.

> flagy 4 – 6

Flag 0: „Obrázky malé i velké“

Kdo už nějaké CTF hrál tak ví, že rozehřívací úkoly jsou často spojené s odhalením informací skrytých v různých metadatech. Náš CTF není výjimkou a tak jste mohli jednoduše najít obrázek flag-1024×413.jpg. Pak už stačilo zobrazit si jeho EXIF metadata a první flag byl váš. Pokud víte, jak WordPress s obrázky pracuje, jste se určitě brzo dostali k originálnímu obrázku v největším rozlišení a získali další flag. Poslední flag se naopak skrýval v nejmenším rozlišení  150×150 px používaném pro náhledy.

Metadata obrázků mohou mít i několik desítek kB a především u miniatur mohou zabírat více prostoru než samotná obrázková data. Na to je vhodné myslet při optimalizaci obrázků. V metadatech často naleznete informace, kdy byla fotografie pořízena, jakým fotoaparátem, případně jakým softwarem byla upravena.

Flag 1: „Moje lepší verze“

Při zkoumání zdrojového kódu stránky jste určitě velmi rychle nalezli meta tag „generator“, který většinou ukazuje verzi WP. Na našem testovacím webu prozradil část flagu 1. Původní číslo verze zde bylo přepsáno filtrem the_generator. Tato sada flagů se zaměřovala právě na prozrazení verze WP a pro získání flagů tak bylo třeba navštívit i další místa, kde je verze vypisována.

Readme.html již pro tento účel nějakou dobu použít nelze (i když alespoň prozradí, že se jedná o vcelku novou řadu WP).

Verze se často vyskytuje ve feedech. Po navštívení RSS feedu třeba na /feed jsme tak ihned získali další flag. Reálná verze zde byla nahrazena pomocí předefinování globální proměnné $wp_version. Tento flag tak bylo možné vyčíst i na /wp-links-opml.php.

Méně známým místem, kde lze vyčíst verzi WP, jsou soubory /wp-admin/install.php nebo /wp-admin/upgrade.php. Zde je v query parametrech statických souborů zobrazována nijak nefiltrovaná hodnota ze souboru version.php. To je důvod, proč tuto hodnotu nemohou modifikovat ani bezpečnostní pluginy.

Tím jsme získali poslední část klíče.

Přestože doporučení na skrytí verze WP často naleznete mezi tipy pro zvýšení bezpečnosti WordPress, má tato akce na bezpečnost minimální vliv. Jak můžeme vidět, tak lze verzi vyčíst mnoha způsoby a útočící boti rovnou zkouší známé exploity, aniž by web nějak zkoumali. Podrobnější informace o skrývání verzí.

Flag 2: „Pohozené soubory“

Ať už jste web zkoumali ručně, nebo jste web oskenovali nástroji, jako je například WP-SCAN, tak jste určitě odhalili některé soubory, které na produkční web určitě nepatří.

Bylo tak možné nalézt například /wp-content/debug.log, do kterého si můžete nechat logovat chyby, místo toho, abyste je zobrazovali návštěvníkům. Určitě není moudré tento soubor mít přístupný, protože z něj lze vyčíst mnoho informací a především to, co na vašem webu špatně funguje. V našem debug logu jste však nalezli „jen“ flag.

Mezi další nešvary patří soubor s výpisem funkce phpinfo(). V něm lze najít užitečné informace o konfiguraci webu, cestách na serveru a proměnné prostředí – informace, které se útočníkovi mohou hodit při dalších typech útoků.

U nás jste tak mohli nalézt phpinfo.php (zde byla malá zrada, protože tento soubor nám naschvál vrací stavový kód 404 a tím ho jednodušší automatizované scany přehlédnou).

Pokud pro vývoj používáte verzovací nástroj GIT, tak se může stát, že nedopatřením na serveru necháte přístupný celý repozitář. To se bohužel stalo i nám a tak jste z /.git/index mohli jednoduše zjistit přítomnost textového souboru s flagem v názvu v kořenové složce webu.

Více o problému s otevřenými .git repozitáři.

Flag 3: „Jen tak si listuji“

V předchozím klíči jsme našli flag v názvu textového souboru. Na webu jich bylo však několik dalších. Ty jste mohli nalézt díky povoleným výpisům adresářů, což je opět funkce, která by neměla být na produkci povolná. Tento problém vám samozřejmě nahlásí i wp-scan.

Stačilo se tedy podívat na 3 místa, kde WP soubory vypíše, protože ve složce standardně nemá žádný index.html/php:

  • /wp-content/uploads
  • /wp-includes/
  • /wp-content/language

Povolený výpis adresářů může být kritickým problémem například v kombinaci se zálohovacím pluginem, který zálohy ukládá do složky uploads a nemá výpisy pohlídané.

Přišlo vám řešení jednoduché? Příště se podíváme na dalších pár flagů, které již mohou být složitější.

Kupte si vstupenku a přijďte na WordCamp

WordCamp Praha 23 .2. 2019 is over. Check out the next edition!