Masarykova Univerzita Fakulta informatiky
Penetrační testování v prostředí KYPO Diplomová práce
Roman Koníček
Brno, Jaro 2016
Místo tohoto listu vložte kopie oficiálního podepsaného zadání práce a prohlášení autora školního díla.
Prohlášení Prohlašuji, že tato diplomová práce je mým původním autorským dílem, které jsem vypracoval samostatně. Všechny zdroje, prameny a literaturu, které jsem při vypracování používal nebo z nich čerpal, v práci řádně cituji s uvedením úplného odkazu na příslušný zdroj.
Roman Koníček
Vedoucí práce: RNDr. Martin Vizváry i
Poděkování Rád bych poděkoval vedoucímu své práce RNDr. Martinu Vizvárymu za vedení této práce. Velmi si cením jeho vstřícnosti a cenných rad, které mi během konzultací uděloval. ii
Shrnutí Cílem diplomové práce je vytvořit vhodné prostředí pro provádění penetračního testování webových aplikací v prostředí Kybernetického polygonu – KYPO. Teoretická část práce je věnována otázkám penetračního testování webových aplikací a výběru vhodného nástroje. V další části, práce seznámí čtenáře s možnostmi tunelování provozu mezi cílem penetračního testu a prostředím KYPO pro bezpečné provedení penetračního testu. Součástí práce budou nástroje pro automatizované spouštění testů z prostředí KYPO, navázání bezpečného spojení s cílem testu a výsledná zpráva z penetračního testu provedeného na platformu Kentico. Test bude sloužit k ověření funkčnosti implementace řešení.
iii
Klíčová slova Kybernetický polygon, KYPO, virtuální stroj, bezpečnostní scénář, skener webových zranitelností, Arachni, penetrační testování, webová aplikace, Kentico, SSH, Socks, VPN, Ncat
iv
Obsah 1 2
3
4
5
Úvod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Penetrační testování webových aplikací . . . . . . . . . . . . 2.1 Vymezení pojmu penetrační testování webových aplikací . . 2.2 Platforma sloužící k penetračnímu testování webových aplikací 2.3 Posouzení vybraných skenerů webových zranitelností . . . . 2.3.1 Definování požadavků . . . . . . . . . . . . . . . 2.3.2 Zvolení nástrojů pro posuzování . . . . . . . . . 2.3.3 Ověření funkcí a porovnání . . . . . . . . . . . . 2.3.4 Otestování nástroje v praxi . . . . . . . . . . . . 2.3.5 Arachni skener . . . . . . . . . . . . . . . . . . . Paralelní testování různých systémů s využitím výpočetních zdrojů prostředí KYPO . . . . . . . . . . . . . . . . . . 3.1 Seznámení s prostředím KYPO . . . . . . . . . . . . . . . . 3.2 Definování bezpečnostního scénáře . . . . . . . . . . . . . . 3.2.1 Popis scénáře . . . . . . . . . . . . . . . . . . . . 3.2.2 Logická topologie . . . . . . . . . . . . . . . . . . 3.2.3 Specifikace použitých uzlů . . . . . . . . . . . . 3.2.4 Síťová topologie . . . . . . . . . . . . . . . . . . . 3.2.5 Realizace scénáře . . . . . . . . . . . . . . . . . . 3.3 Příprava Kybernetického polygonu . . . . . . . . . . . . . . 3.3.1 Datový model . . . . . . . . . . . . . . . . . . . . 3.3.2 Konfigurace strojů . . . . . . . . . . . . . . . . . 3.3.3 Konfigurační soubor . . . . . . . . . . . . . . . . Vytvoření bezpečného kanálu pro propojení virtuálního prostředí KYPO a testovaného subjektu . . . . . . . . . . . 4.1 SSH tunel . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2 SOCKS tunel . . . . . . . . . . . . . . . . . . . . . . . . . 4.3 Ncat HTTP Proxy . . . . . . . . . . . . . . . . . . . . . . 4.4 VPN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Penetrační testování platformy Kentico . . . . . . . . . . . . 5.1 Zajištění bezpečného produktu ve firmě Kentico . . . . . . . 5.1.1 Moduly pro prohlížeč Firefox . . . . . . . . . . . 5.1.2 Moduly pro nástroj Fiddler . . . . . . . . . . . . 5.1.3 Nástroje pro statickou analýzu kódu . . . . . . . 5.1.4 Webové skenery . . . . . . . . . . . . . . . . . . .
1 2 3 3 5 5 7 9 10 11 13 13 14 14 16 17 17 18 21 21 21 24 25 27 29 31 33 36 37 37 38 38 39 v
6 A B C D
5.2 Výsledky provedeného testování s využitím Arachni skeneru Závěr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Soubor pentester_machine_config.sh . . . . . . . . . . . . . Soubor penetration_test.py . . . . . . . . . . . . . . . . . . . Výsledná zpráva skeneru Arachni . . . . . . . . . . . . . . . Seznam elektronických příloh . . . . . . . . . . . . . . . . .
40 41 46 47 75 81
vi
1 Úvod Zabezpečení webových aplikací by mělo být druhou přirozeností vývojáře. Důraz kladený na bezpečné webové aplikace nabývá čím dál více na důležitosti. Jakmile zpřístupníme webovou aplikaci pro širokou veřejnost, můžeme si být téměř jisti, že se dřív nebo později objeví zlomyslný uživatel, který se pokusít zneužít chyby v našem systému. Prvním krokem, jak dosáhnout bezpečné webové aplikace, je vytvořit zásady bezpečného programování tak, abychom v první řadě zabránili vzniku těchto chyb. Nicméně ani striktní dodržování těchto pravidel ještě nezaručuje, že jsme vyvinuli bezpečný produkt, proto je důležité, abychom si zpětně ověřili, že je náš produkt bezpečný. V kontextu webových aplikací můžeme k tomuto účelu využít tzv. skenery webových zranitelností, které automatizovaným způsobem prověří naši aplikaci z hlediska bezpečnosti. Cílem diplomové práce je vytvořit vhodné prostředí pro provádění penetračního testování webových aplikací v prostředí Kybernetického polygonu. Samotné penetrační testování webové aplikace je poměrně náročné co se týče využitých zdrojů a potřebného času k jeho přípravě a realizaci. Hlavní motivací této práce bylo poskytnout řešení, které omezí potřebné zdroje uživatelů na nezbytné minimum. Vzniká tak řešení, kdy nám pro provedení penetračního testu stačí vyplnit na straně uživatele pouze několik vstupních hodnot a o zbytek práce se postará Kybernetický polygon. Druhá kapitola se věnuje skenerům webových zranitelností. Je zde vysvětleno co jsou skenery webových zranitelností, jakým způsobem fungují a jaké jsou požadavky při výběru správného nástroje. Ve třetí kapitole se seznámíme s projektem Kybernetického polygonu. V této části se budeme věnovat definici bezpečnostního scénáře, který bude sloužit jako vodítko k provedení penetračního testu. Dále se zaměříme na samotnou přípravu KYPO tak, abychom mohli realizovat bezpečnostní scénář. Obsah čtvrté kapitoly se zaměřuje na analýzu možností tunelování provozu mezi cílem penetračního testu a prostředím KYPO pro bezpečné provedení penetračního testu. V páté kapitole si přiblížíme platformu Kentico, na které provedeme penetrační test. Tento test bude sloužit k ověření funkčnosti implementace řešení.
1
2 Penetrační testování webových aplikací Penetrační testování může být definováno jako oprávněný pokus nalézt a úspěšně využít počítačový systém, jehož ultimátním účelem je poskytnout větší bezpečnost právě testovanému systému. Tento proces typicky zahrnuje hledání zranitelností, spolu s poskytnutím ověření konceptu, tzv. „proof of concept“, dané zranitelnosti [1]. Provedení penetračních testů by si mělo zachovat určitou formální úroveň. Existují standardy, které definují jednotlivé fáze penetračního testování. V těchto standardech je také řešena návaznost a propojení těchto fází. Standardní model pro penetrační testování zahrnuje tyto fáze [2]: ∙
Předběžná interakce (Pre-engagement Interactions)
∙
Shromažďování informací (Intelligence Gathering)
∙
Modelování hrozeb (Threat Modeling)
∙
Analýza zranitelností (Vulnerability Analysis)
∙
Využití zranitelností (Exploitation)
∙
Následné využití zranitelností (Post Exploitation)
∙
Vypracování zprávy (Reporting)
V současné době existuje velké množství nástrojů, které má penetrační tester k dispozici. Nicméně široká škála možností, která se tak nabízí, může paradoxně penetračnímu testerovi práci zkomplikovat. Konkrétněji se jedná o nutnost nalezení a následnou instalaci jednotlivých nástrojů. Tyto aktivity mohou trvat netriviální množství času, proto existují linuxové distribuce, které jsou speciálně vytvořeny za účelem penetračního testování. Typickými zástupci v této kategorii jsou Kali1 či Backtrack2 . Další možností, jak ušetřit čas a předejít opakované konfiguraci stroje pro penetrační testování, je připravit si tento s předstihem. Díky tomu můžeme testování provádět bez iniciální 1. 2.
http://www.kali.org http://www.backtrack-linux.org
2
2. Penetrační testování webových aplikací konfigurace. Nicméně i v tomto případě pro nás nemusí být jednoduché testovat více webových aplikací souběžně, neboť konfigurace kopií původní stroje vyžaduje další časovou investici.
2.1
Vymezení pojmu penetrační testování webových aplikací
Webové servery jsou jedním z nejčastějcích terčů útočníků, v penetračním testování mluvíme o vektoru útoku (attack vector). Vektor útoku lze definovat jako způsob nebo prostředek, pomocí kterého může útočník získat přístup k systému a následně provádět škodlivý kód [3]. Hlavním důvodem nárustu těchto útoků je fakt, že valná většina současných zařízení komunikuje prostřednictvím Internetu. Mezi typické zástupce těchto zařízení patří mobilní telefony, tablety, ale také kávovary, pračky, lampy a mnohé jiné. Jedná se o tzv. Internet věcí (Internet of Things). Za samozřejmost lze považovat skutečnost, že téměř každá firma vlastní webové stránky. Ze statistiky společnosti WhiteHat [4] vyplývá, že 86 % webových aplikací, které byly pokryty v provedeném testu, obsahuje nejméně jednu vážnou bezpečnostní zranitelnost. Z toho vyplývá, že většina webových aplikací na Internetu obsahuje při nejmenším jednu vážnou zranitelnost. Dalším faktem je to, že většina těchto využitých zranitelností byla již odhalena a je veřejně přístupná. Tyto informace jsou publikovány v podobě CVE3 . Z tohoto důvodu by měl každý penetrační tester porozumět alespoň základům hackingu webových aplikací.
2.2
Platforma sloužící k penetračnímu testování webových aplikací
Existují frameworky, které slouží k provádění penetračních testů webových aplikací. Tyto frameworky představují standardizovaný přístup k jednotlivým cílům útoku. Ačkoliv existuje velké množství nástrojů s tímto zaměřením, můžeme naznačit hlavní principy, které jsou pro ně společné [1]: 3.
https://cve.mitre.org
3
2. Penetrační testování webových aplikací ∙
Schopnost zachytávat požadavky. Tato funkcionalita umožňuje měnit hodnoty parametrů předtím, než je zpracuje webová aplikace.
∙
Schopnost nalézt veškeré webové stránky, adresáře a další soubory, které tvoří webovou aplikaci.
∙
Schopnost analyzovat a prozkoumat odpověď webové aplikace, zda obsahuje zranitelnosti.
Vzhledem k tomu, že penetrační testování jako celek je velmi obsáhlé, bude se tato práce věnovat pouze fázi, kdy dochází ke sběru informací (information gathering). K tomuto účelu nám poslouží automatizovaný nástroj. Tyto nástroje jsou typicky známé pod označením skener webových zranitelností, případně v anglickém jazyce „web vulnerability scanner“ (v této práci budeme pro označení těchto nástrojů využívat zkratku „WVS“, případně pouze označení skener). Proces shromažďování informací zahrnuje aktivní analýzu webové aplikace za účelem objevení slabých míst, technických vad či zranitelností. Všechny bezpečnostní problémy, které budou nalezeny během testování, budou nahlášeny správci systému, případně zadavateli testu. Spolu s doručením seznamu zranitelností budou doručeny i posouzení dopadu, doporučení na minimalizování rizika, případně technické řešení. Skenery webových zranitelností jsou automatizované nástroje, které skenují webovou aplikaci za účelem objevení zranitelností, jako jsou například XSS (Cross-site scripting)4 , SQL injection5 nebo „directory traversal“6 . V současné době je na trhu k dispozici velké množství těchto nástrojů, ať už se jedná o komerční či open source řešení. Důležité je vždy pamatovat na to, že každý nástroj má své silné a slabé stránky.
4. 5. 6.
https://www.owasp.org/index.php/XSS https://www.owasp.org/index.php/SQL_Injection https://www.owasp.org/index.php/Path_Traversal
4
2. Penetrační testování webových aplikací
2.3
Posouzení vybraných skenerů webových zranitelností
Není jednoduché vybrat ten nejlepší skener webových zranitelností. Co je dobré pro jednoho, nevyhovuje druhému a naopak. Webové aplikace se od sebe liší v mnoha aspektech, a to je hlavní důvod, proč je tak obtížné vybrat ten nejlepší nástroj. Představme si následující příklad, mějme skener, který má lepší výsledky při skenování webových aplikací, které byly vyvinuty v PHP, jiné skenery mohou doručovat lepší výsledky, pokud je aplikace napsaná v jazyce ASP.NET či Java. Nicméně, není to jenom o webových aplikacích a technologiích, které byly použity k výstavbě těchto stránek, musíme vzít v potaz také o uživatele těchto nástrojů, jejichž potřeby se mohou lišit. Posuzování skenerů se typicky skládá z následujících akcí: ∙
Definovat požadavky
∙
Zvolit si nástroje, které budou součástí posuzování
∙
Ověřit si dostupné funkce a porovnat s ostatními nástroji
∙
Otestovat nástroj v praxi
Každá z těchto akcí bude detailněji probrána v následujících podkapitolách. 2.3.1 Definování požadavků Když mluvíme o posuzování jednotlivých skenerů, nejprve se musíme rozhodnout, které parametry budeme brát v úvahu během výběru. Mezi parametry, které jsou důležité pro tuto práci, patří univerzálnost skeneru, detekce zranitelností, přesnost, přizpůsobivost skeneru, autentizace a další požadavky, které uvedeme dále. Univerzálnost skeneru Pod pojmem univerzálnost skeneru si můžeme představit následující požadavky. Skener je schopný prozkoumávat všechny objekty webové 5
2. Penetrační testování webových aplikací stránky a její vstupy. Skener musí podporovat všechny typy protokolů, které využívá webová aplikace. Skener musí být schopný provést syntaktickou analýzu webové stránky a zároveň rozumět HTML obsahu na stránce. Detekce zranitelností Zde nás především zajímá, kolik zranitelností skener objevil. Dále musí být skener schopný detekovat zranitelnosti relevantní pro technologie, které fakticky používáme. Přesnost Vysoký počet detekovaných zranitelností, které skener odhalil, není ještě zárukou kvality. Musíme se přesvědčit, že moduly pro detekci zranitelností jsou tak přesné, jak je to jen možné. Konkrétně, zde si klademe otázku: „Jaký je počet false-positive položek?“. Přizpůsobivost skeneru Některé webové aplikace mohou implementovat bezpečnostní mechanismy, které mají za úkol bránit útokům, jako jsou Clickjacking7 , CSRF8 apod. Tyto mechanismy mohou drasticky snižovat efektivitu skeneru, zejména, pokud tvůrce skeneru tyto mechanismy nebral při jeho vývoji v potaz. Mezi běžné bariéry patří požadavky v HTTP hlavičkách, AntiCSRF tokeny nebo CAPTCHA. Ve výsledku, pokud skener prozkoumává aplikaci s bariérami, které nemůže ošetřit, to zabrání prozkoumání a detekování zranitelností ve vstupních bodech, které jsou ovlivněny těmito bariérami. Autentizace V případě, že určité sekce webové aplikace vyžadují autentizaci, je důležité tento fakt promítnout do požadavků. Skener musí podporovat autentizační metodu, která je v aplikaci implementována. 7. 8.
https://www.owasp.org/index.php/Clickjacking https://www.owasp.org/index.php/CSRF
6
2. Penetrační testování webových aplikací Další požadavky V této sekci je uveden seznam doplňujících požadavků. Jak jsem zmínil v úvodu této práce, výběr a stanovení priorit požadavků se může lišit scénář od scénaře. Z tohoto důvodu je zde uveden tento výčet spíše pro úplnost: ∙
Paralelnost (možnost spouštět více skenování souběžně)
∙
Automatizace (může být skenování spuštěno z příkazové řádky nebo pomocí dávkových souborů?)
∙
Stabilita
∙
Uživatelské rozhraní
∙
Aktualizace produktu
∙
Výsledná zpráva (jakým způsobem lze prohlížet výsledky skenování?)
∙
Možnost vytvářet znovupoužitelné konfigurační šablony
∙
Možnost zobrazit stav běžícího skenování v reálném čase
∙
Možnost zastavit a znovu spustit skenování
∙
Konfigurace „web crawleru“ (počáteční URL, dodatečné jméno počítače – hostname, trénování web crawleru)
Ve zkratce, skenery webových zranitelností se používají pro zvýšení efektivity a ušetření času a zejména pro zajištění, že identifikujeme co možná nejvíce technických webových zranitelnosti. Jakmile je definice požadavků hotová, můžeme přejít k další části. 2.3.2 Zvolení nástrojů pro posuzování Mezi testované nástroje jsem vybral pouze zástupce ze strany open source. Z velkého množství řešení jsem vybral následující kandidáty, které se mi jevily vhodné pro tuto práci: 7
2. Penetrační testování webových aplikací ∙
N-Stalker 2012 Free Edition - skener vznikl v roce 2000 a je průběžně aktualizován. Je poskytován v několika edicích a to včetně „Free“ edice, která je zdarma. N-Stalker využívá při skenování databázi „N-Stealth Web Attack Signature Database“, která je jednou z největších databází sloužící k hledání zranitelností, nicméně ve verzi zdarma je dostupná pouze omezená verze. Další nevýhodou verze zdarma je fakt, že podporuje skenování maximálně 100 stránek v cílové aplikaci. N-Stalker také prohledává balíčky třetích stran jako jsou WordPress, Joomla nebo Drupal. Skener vyžaduje operační systém Windows [5].
∙
Scrawlr - za tímto skenerem stojí uskupení HP Web Security Research Group. Poslední verze byla vydána v roce 2008. Skener je k dispozici pod licencí „CC BY-NC-SA“. Scrawlr oproti N-Stalkeru zvládne prohledat až 1500 stránek. Na druhou stranu nepodporuje aplikace, které vyžadují autentizaci a netestuje SQL injection v POST parametrech. Skener beží na operačních systémech Windows [6].
∙
SkipFish - mezi hlavní autory skeneru patří Michal Zalewski, Niels Heinen a Sebastian Roschke. Poslední aktualizace skeneru proběhla v roce 2012. Skener je poskytovaný pod licencí „Apache-2.0“. SkipFish je napsaný v jazyce C a optimalizovaný pro práci s HTTP protokolem. SkipFish provádí kontrolu běžných webových zranitelností. Je důležité také zmínit omezení tohoto skeneru, a to je chybějící podpora HTTP proxy. Pro spuštění skeneru je vyžadován operační systém Linux [7].
∙
Vega - byl vyvinutý společností Subgraph sídlící v Montrealu, poskytovaní pod licencí „Eclipse Public License 1.0“. Poslední aktualizace proběhla v roce 2015. Skener je napsaný v jazyce Java a běží na operačních systémech Linux, OS X a Windows [8].
∙
W3AF - skener W3AF vytvořil Andres Riancho. Nejnovější verze vyšla v roce 2016. Jedná se o open source řešení šířené pod licencí „GPLv2.0“. Tento skener je vytvořený kompletně v jazyce Python. Skener můžeme spustit na operačních systémech 8
2. Penetrační testování webových aplikací Linux, BSD či OS X. Operační systém Windows není oficiálně podporovaný [9]. ∙
Arachni - autorem skeneru Arachni je Tasos „Zapotek“ Laskos. Skener je k dispozici pod licencí „Arachni Public Source License v1.0“. Nejnovější verze skeneru vyšla v roce 2016. Skener Arachni byl vytvořený na frameworku Ruby. Podporované operační systémy jsou Linux a Windows [10].
∙
Wapiti - skener vyvinutý Nicolasem Surribasem. Poslední aktualizace skeneru proběhla v roce 2013 a je šířený pod licencí „GNU GPL“. Skener disponuje standardní funkcionalitou, ale narozdíl od jiných nástrojů nedisponuje grafickým uživatelským rozhraním. Skener podporuje operační systémy Linux, Windows a OS X [11].
∙
WebScarab - tento nástroj vytvořil Rogan Dawes. Poslední aktualizace WebScarab skeneru proběhla v roce 2014. Spadá pod licenci „GNU GPL“. Jedná se o modulární řešení napsané v jazyce Java. Skener disponuje velkým množstvím modulů. Instalací těchto modulů si můžeme řešení přizpůsobit plně našim potřebám. Podporovány jsou operační systémy Windows a Linux [12].
∙
ZAP - jedná se v podstatě o nástupce skeneru WebScarab. Poslední verze byla vydána v roce 2015. Skener je k dispozici zdarma pod licencí „Apache-2.0“. Výhodou ZAP skeneru je aktivní zapojení komunity, která se stará o jeho vývoj. ZAP dostupný napříč mnoha platformami, a to včetně Raspberry Pi [13].
2.3.3 Ověření funkcí a porovnání Pro ověření funkcí skenerů a jejich porovnání jsem využil SECTOOL Market9 . Na webové stránce zmíněné společnosti jsou provedeny testy všech výše uvedených skenerů. Pro zjednodušení přikládám pouze tabulku celkových výsledků [14]: 9.
http://www.sectoolmarket.com
9
2. Penetrační testování webových aplikací Přesnost (%) Skener Netsparker Comm. N-Stalker 2012 Free Scrawlr SkipFish Vega W3AF Arachni Wapiti WebScarab ZAP
False positive (%)
SQLi
RXSS LFI
RFI
SQLi RXSS LFI
RFI
72.0
78.7
x
x
30.0
0.0
x
x
x
95.4
x
x
x
0.0
x
x
13.2 76.4 100.0 35.2 100.0 100.0 x 100.0
x 93.9 100.0 37.8 90.9 66.6 12.1 100.0
x 82.3 94.1 57.4 100.0 51.4 x 75.0
x 31.4 100.0 16.6 100.0 51.4 x 100.0
0.0 0.0 20.0 30.0 0.0 20.0 x 30.0
x 0.0 0.0 0.0 0.0 42.8 42.8 0.0
x 25.0 62.5 12.5 0.0 12.5 x 0.0
x 16.6 0.0 16.6 0.0 0.0 x 16.6
Tabulka 2.1: Souhrn vlastností webových skenerů SQLi - Error Based SQL Injection RXSS - Reflected Cross Site Scripting LFI - Path Traversal & Local File Inclusion RFI - Remote File Inclusion 2.3.4 Otestování nástroje v praxi Provedení průzkumu či hledání informací o skenerech na oficiálních stránkách a v dokumentaci je jedno hledisko. Nicméně, nemůžeme se v tomto případě spoléhat pouze na statistiku, nejlepším způsobem, jak zjistit, který skener odpovídá našim potřebám, je vyzkoušet si ho. Pro tyto případy lze využít designované zkušební prostředí jako je například WAVSEP10 . Jedná se o platformu, která poskytuje modelové případy, na kterých si lze ověřit, jaké bariéry může skener překonat a jaké zranitelnosti detekuje. Po této fázi bychom měli mít dostatek informací, na jejímž základě jsme schopni vybrat nejvhodnější skener. Jakmile si otestujeme webové skenery v praxi a máme k dispozici výsledky skenování, začneme porovnávat nálezy těchto skenerů. Typicky hledáme odpovědi na následující otázky. 10. https://www.code.google.com/p/wavsep
10
2. Penetrační testování webových aplikací ∙
Který webový skener detekoval nejvíce zranitelností?
∙
Který webový skener nahlásil nejméně false positive položek?
∙
Jsou zde nějaké zranitelnosti, které skener nedokázal detekovat (false negatives)?
Nalezením vhodného poměru mezi body, které jsem zmínil výše, bychom měli najít ideálního kandidáta. 2.3.5 Arachni skener Jak je patrné z tabulky v kapitole 2.3.3., nejlepších výsledků dosahuje skener Arachni. V porovnání s ostatními má Arachni nejvyšší přesnost, nejnižší počet false positive hlášení a disponuje bohatou funkcionalitou. Na základě těchto výsledků, byl Arachni skener zvolen jako nejvhodnější kandidát pro tuto práci. Přehled vlastností Arachni je open source projekt, který původně začal jako vzdělávací cvičení. Kladl si za cíl provést bezpečnostní testy vůči webovým aplikacím a identifikovat rizika. V současnosti je využití Arachni považováno za spolehlivý způsob, jak provést penetrační testování. Arachni je plně automatizovaný systém, po spuštění skenovacího procesu není potřebná již další aktivita ze strany uživatele. Jakmile je sken dokončený, vytvoří se zpráva obsahující informace o rizicích. Co se týká výkonu, Arachni používá asynchronní HTTP požadavky, které zaručují maximální využití šířky pásma. Framework může být obohacen o nespočet nových komponent, jako jsou moduly, pluginy či uživatelská rozhraní [10]. Instalace Instalace Arachni je snadná a spočívá ve dvou krocích. Prvním krokem je stáhnout instalační balíček z oficiálních stránek Arachni11 . Druhým krokem je extrahování instalačního balíčku do zvolené lokality. 11. http://www.arachni-scanner.com
11
2. Penetrační testování webových aplikací Praktická ukázka Po provedení instalace můžeme spustit následující příkaz, který zobrazí dostupné volby [15]: $ arachni -h
Samotné spuštění procesu skenování probíhá příkazem: $ arachni http://testsite.com
Výše zmíněný příkaz načte všechny moduly a započne skenování oproti doméně http://testsite.com. Výsledky auditu budou uloženy do souboru s názvem testsite.com.afr. Soubor typu Arachni Framework Report (.afr) lze transformovat také do jiných formatů, například HTML: $ arachni --repload=test.com.afr --report=html:outfile=my_report.html
V případě, že si nepřejeme testovat webovou aplikaci vůči všem dostupným modulům, které nám Arachni nabízí, můžeme si zvolit pouze konkrétní moduly, které budou součástí auditu, v příkladu níže spouštíme pouze moduly testující XSS zranitelnost: $ arachni http://example.net –mods=xss_*
12
3 Paralelní testování různých systémů s využitím výpočetních zdrojů prostředí KYPO Provedení penetračního testování webové aplikace představuje pro webový server velkou zátěž. Během testu na server přichází tisíce požadavků, které generuje skener webových zranitelností. Pokud se rozhodneme provést takové testování, je nutné vzít tento fakt v úvahu a zajistit si dostatečné výpočetní zdroje. V této práci budu využívat prostředí Kybernetického polygonu (KYPO), které mi takové výpočetní zdroje zajistí. Mít k dispozici potřebné zdroje je nezbytnou podmínkou pro provedení testování, avšak neméně důležitou součástí je optimalizace těchto zdrojů. Konkrétně to znamená, že stroje existují v KYPO pouze po dobu provádění penetračního testování. V okamžiku, kdy daný stroj dokončí svou úlohu budou tyto zdroje opět uvolněny a k dispozici pro další testování.
3.1
Seznámení s prostředím KYPO
Kybernetický polygon má za cíl vytvořit prostředí pro vývoj a výzkum metod na ochranu proti kybernetickým útokům. Tohoto cíle bude dosaženo pomocí provádění komplexních kybernetických útoků proti reálné síťové a IT infrastruktuře, která bude umístěna ve virtualizovaném prostředí cloudu. Provedené útoky pak bude možné analyzovat a vyhodnocovat v jejich průběhu i po jejich ukončení. Prostředí bude dále sloužit pro vývoj nových bezpečnostních nástrojů a pro školení členů bezpečnostních týmů [16]. Prostředí KYPO poskytuje tři základní možnosti využití [17]: ∙
Bezpečnostní školení a cvičení
∙
Výzkum ochrany proti kybernetickým útokům
∙
Forenzní analýza a síťové simulace
Tato práce bude zkoumat čtvrtou možnost využití prostředí KYPO, a to konkrétně předání výpočetního výkonu. Nyní, když jsme definovali účel KYPO a jeho využití, můžeme přejít k detailnějšímu popisu 13
3. Paralelní testování různých systémů v prostředí KYPO principů, na kterých je KYPO založeno. Fungování Kybernetického polygonu můžeme shrnout do následujících případů užití [16]: ∙
Vytvoření bezpečnostního scénáře
∙
Příprava Kybernetického polygonu
∙
Realizace bezpečnostního scénáře
∙
Online monitorování a vizualizace
∙
Offline monitorování a vizualizace
Výše uvedené případy užití budou rozebrány detailněji v následujících podkapitolách, s výjimkou monitorování a vizualizace. Uživatel nebude mít k dispozici přehled o aktuálním dění v polygonu či statistických údajích. Po skončení experimentu bude uživateli předložena výsledná zpráva o nalezených zranitelnostech.
3.2
Definování bezpečnostního scénáře
Nezbytnou součástí KYPO je bezpečnostní scénář. Scénář obsahuje popis, technickou specifikaci a průběh scénaře. Popis scénáře slouží k přípravě infrastruktury Kybernetického polygonu a realizaci daného úkolu. Bezpečnostní scénář musí jasně definovat akce a komponenty, aby se zamezilo nejasnostem při jeho implementaci. Scénář se skládá ze dvou částí, první části porozumí běžný uživatel, druhá část je určená ke strojovému zpracování. 3.2.1 Popis scénáře Hlavním cílem scénáře je přiblížit použití skeneru webových zranitelností v prostředí kybernetického polygonu. Za modelového uživatele je v tomto případě považován penetrační tester. Uživatel je součástí bezpečnostního týmu, kdy část jeho agendy spočívá v provádění penetračních testů webových aplikací. Úkolem uživatele je provést audit webových aplikací a zjistit tak, jestli jsou spolehlivé a bezpečné. Scénář se zaměřuje na provedení skenu webové aplikace a identifikování bezpečnostních děr. V daném scénáři si penetrační tester na 14
3. Paralelní testování různých systémů v prostředí KYPO počátku zvolí jednu nebo více webových aplikací, které mají být otestovány, dále zvolí rozsah prováděných testů, a v poslední řadě zvolí variantu, pomocí které bude vytvořený tunel. Tunel zajišťuje přenos informací mezi Kybernetickým polygonem a privátní sítí testovaného subjektu. Pokud se rozhodneme využít Kybernetický polygon k provádění penetračního testování webových aplikací, pak je vhodné si uvědomit, že existují dvě varianty tohoto přístupu. První variantou je nasazení webové aplikace v Kybernetickém polygonu, to znamená, že tuto aplikaci lze spustit jako virtuální stroj přímo v prostředí KYPO. V tomto případě máme tedy oba stroje, jak stroj provádějící penetrační testování, tak testovaný subjekt v KYPO. Tato varianta má tu výhodu, že testování probíhá v izolovaném prostředí Kybernetického polygonu, další výhodou je relativně snadné použití, protože využíváme pouze dva stroje. Oproti tomu existuje druhá varianta, kdy webová aplikace, kterou máme otestovat běží mimo prostředí Kybernetického polygonu. V tomto případě využíváme tzv. pivot server (více v kapitole 4.). Tato varianta je vhodná například pro projekty, které obsahují citlivé informace. Mohou existovat případy, kdy je pro klienta nepřijatelné poskytnout webovou aplikaci třetí straně. Pak je tedy nutné přistupovat k webové aplikaci skrze pivot server. V této práci jsou výše zmíněné varinty zkombinovány. Konkrétně to znamená, že webová aplikace a stroj provádějící penetrační test jsou spuštěny přímo v Kybernetickém polygonu, nicméně přístup k webové aplikaci je možný pouze prostřednictvím pivot serveru, který je simulován v síti kybernetického polygonu. Jak je patrné z obrázku 3.1 penetrační tester se připojí pomocí SSH protokolu k virtuálnímu stroji SMN (Scenario Management Node). SMN umožňuje přístup do Kybernetického polygonu. Po přistoupení k uzlu SMN se dle požadavků penetračního testra vytvoří jedna či více instancí virtuálních strojů Arachni, které budou provádět skenování. Obrázek 3.2 popisuje scénář, kdy se v Kybernetickém polygonu vytvořily dvě instance virtuálního stroje s Arachni, pomocí kterého bude probíhat souběžné testování webové aplikace, která běží na webovém serveru v síti společnosti A, a zárověn bude probíhat skenování webové aplikace v síti společnosti B. Požadavky vytvořené strojem 15
3. Paralelní testování různých systémů v prostředí KYPO
Obrázek 3.1: Přehled bezpečnostního scénáře
Arachni budou přenášeny prostřednictvím tunelu na tzv. pivot server, který bude umístěn v privátní síti testovaného subjektu. Po ukončení testu se uživateli zpřístupní zpráva o výsledku provedení skenování.
3.2.2 Logická topologie Scénář obsahuje síť, ze které se provádí penetrační testování a korporátní síť, kde se nachází webový server. Na tomto serveru běží webová aplikace, která bude předmětem penetračního testu. Toto prostředí má za úkol simulovat reálné prostředí Internetu. 16
3. Paralelní testování různých systémů v prostředí KYPO
Obrázek 3.2: Paralelní testování v KYPO 3.2.3 Specifikace použitých uzlů Uzel představuje jeden konkrétní kus hardware definovaný ve scénáři. ∙
Arachni - uzel typu Arachni využívá operační systém Linux, konkrétně se jedná o distribuci Debian. Běží zde také skener webových zranitelností Arachni.
∙
Pivot server - jedná se o server používající operační systém Linux (Debian). Účel tohoto uzlu je zpřístupnění korporátní sítě tak, aby bylo možné provést penetrační test z uzlu Arachni.
∙
Webový server - uzel typu webový server. Na tomto uzlu je nainstalovaný operační systém Windows Server 2012 R2 spolu s webovým serverem IIS. Uzel obsahuje také webovou aplikaci, která využívá Kentico platformu (více v kapitole 5). Tato webová aplikace bude podrobena penetračnímu testu.
3.2.4 Síťová topologie Pro simulaci reálného prostředí Internetu byla vytvořena infrastruktura, která se skládá z částí zobrazených na obrázku 3.3: 17
3. Paralelní testování různých systémů v prostředí KYPO
Obrázek 3.3: Síťová topologie bezpečnostního scénáře ∙
Síť penetračního testera - obsahuje stroj se skenerem webových zranitelností Arachni.
∙
Korporátní síť - obsahuje pivot server a webový server, na kterém běží webová aplikace.
3.2.5 Realizace scénáře Před spuštěním samotného skriptu se musíme rozhodnout, v jakém rozsahu chceme provádět penetrační testování. K testování můžeme využít jeden, více nebo všechny moduly, které jsou určeny k hledání 18
3. Paralelní testování různých systémů v prostředí KYPO zranitelností. K ulehčení takového rozhodnutí bude dodán seznam všech dostupných modulů společně se skriptem k penetračnímu testování. Tento skript je napsaný v jazyce Python. Kompletní zdrojový kód skriptu se nachází v příloze B, dále je také dostupný elektronicky v GitHub repositáři.1 Zde je třeba zmínit, že existuje odlehčená verze původního penetračního skriptu. V této verzi nebereme v úvahu pivot server a skener Arachni tak komunikuje napřímo s webovou aplikací. Tato verze je dostupná pouze jako elektronická příloha. Při spuštění skriptu musíme zadat následující parametry příkazu: ∙
-n, kde udáváme, kolik webových aplikací budeme testovat
∙
-s, název sandboxu v kybernetickém polygonu
∙
-u, emailová adresa uživatele
∙
-m, jedná se o moduly, pomocí kterých určujeme rozsah penetračního testu. Tento parametr je nepovinný, pokud nebude uveden, pak se provede testování v plném rozsahu
Dalším krokem je definování parametrů jednotlivých webových aplikací, které budeme testovat. Mezi tyto parametry patří: ∙
url adresa webové aplikace
∙
metoda, pomocí které vytvoříme tunel
∙
adresa pivot serveru
∙
přístupové údaje k pivot serveru (jméno a heslo)
∙
adresa webového serveru
Interakce s uživatelem končí v momentě, kdy zadá validní údaje. V této chvíli od uživatele neočekáváme další vstupy a řízení předáme skriptu. Dále následuje zajištění přístupu k sandboxu, který se nachází v Kybernetickém polygonu. Pokud sandbox existuje, tak ho využijeme. V opačeném případě je třeba tento sandbox nejprve vytvořit pomocí příkazu: 1.
https://github.com/damolh/Master_KYPO
19
3. Paralelní testování různých systémů v prostředí KYPO http://kypo.ics.muni.cz:5000/scenario/sandbox/load/ konicek-vizvary/konicek-vizvary.json
Poté je nutné vygenerovat odpovídající množství strojů Arachni, které budou provádět penetrační testování. V případě, že testujeme pouze jednu webovou aplikaci a momentálně není aktivní žádný stroj Arachni, pak využijeme stroj, který je definovaný v konfiguračním souboru (více v kapitole 3.3.3), v opačném případě vygenerujeme odpovídající počet těch strojů. K tomu využijeme následující příkaz: http://kypo.ics.muni.cz:5000/scenario/konicek-vizvary/ host/copy/arachni/arachni_new/10.10.10.2
Samotné připojení do KYPO je realizováno pomocí SSH. Jakmile se skript připojí k SMN, je nutné provést příkazy uvedené níže, které umožní přístup do sítě penetračního testera a korporátní sítě: # route netmask # route netmask
add –net 10.10.20.0 gw 172.16.1.3 255.255.255.0 add –net 10.10.10.0 gw 172.16.1.2 255.255.255.0
Aby bylo možné realizovat testování, je nutné vytvořit aktivní připojení mezi strojem uživatele a strojem Arachni. Toto spojení je realizováno pomocí SSH, kde počet vytvořených aktivních spojení odpovídá počtu webových aplikací, které se mají testovat. Nyní máme k dispozici seznam aktivních připojení a můžeme přejít k samotnému testování. Před spuštěním testu je nutné ještě zkontrolovat typ tunelu. Podle zvoleného typu tunelu je nutné provést dodatečné akce: ∙
ncat - v tomto případě je nezbytné vytvořit další připojení na pivot server a spustit příkaz ncat (viz. kapitola 4.1.3)
∙
socks - pokud zvolime tento typ tunelu, je nezbytné na stroji Arachni upravit soubor proxychains.conf (viz. kapitola 4.1.2)
V této fázi probíhá samotné testování. Testování probíhá asynchronně. To tedy znamená, že pokud testujeme více webových aplikací, pak jsou tyto testy na sobě nezávislé a mohou probíhat paralelně. 20
3. Paralelní testování různých systémů v prostředí KYPO Po dokončení testu se uživateli odešle emailová zpráva na jeho adresu s informací, že daný test proběhl. Dále se uživateli na jeho počítač uloží výsledná zpráva, která obsahuje ucelené informace o výsledku testu. Před samotným ukončením skriptu následuje ještě fáze úklidu. To znamená, že Arachni stroj, který právě dokončil testování, bude smazán. Momentálně taková funkce není v Kybernetickém polygonu dostupná, proto probíhá mazání strojů Arachni pouze na úrovni databáze. V případě, že neexistuje v sandboxu žádný stroj Arachni, který by prováděl aktivní testování, pak se smaže celý sandbox. Celý postup ilustruje diagram na obrázku 3.4.
3.3
Příprava Kybernetického polygonu
Před samotnou realizací bezpečnostního scénáře v kybernetickém polygonu je nutné KYPO nejprve nakonfigurovat. V kontextu této práce můžeme rozdělit konfiguraci na tři fáze. První fází je vytvoření datového modelu. Druhá fáze zahrnuje konfiguraci strojů. Třetí fáze spočívá ve vytvoření konfiguračního souboru na jehož základě se vytvoří sandbox v KYPO. 3.3.1 Datový model Datový model popisuje způsob, jakým se ukládají data během provádění bezpečnostního scénáře. Skript, který slouží k provádění penetračního testování, pracuje se svou vlastní databází. V této databázi uchováváme informace o uživateli, který test inicioval, webové aplikaci, kterou budeme testovat, pivot serveru, stroji Arachni, který bude testování výkonávat, a také zde nalezneme informace o webovém serveru. Na obrázku 3.5 je zobrazen datový model v podobě zjednodušeného entitně-relačního diagramu. 3.3.2 Konfigurace strojů Dalším krokem, který následuje po vytvoření datového modelu je příprava strojů, které budeme využívat. Tuto přípravu můžeme rozdělit na dvě části, a to přípravu virtuálních strojů a přípravu stroje, na kterém budeme spouštět testovací skript. 21
3. Paralelní testování různých systémů v prostředí KYPO
Obrázek 3.4: Průběh scénáře
22
3. Paralelní testování různých systémů v prostředí KYPO
Obrázek 3.5: Databázová struktura Konfigurace virtuálních strojů V této části využíváme virtuální prostředí, ve kterém provedeme potřebnou konfiguraci stroje, a poté tento obraz hrajeme do úložiště Kybernetického polygonu. Pro účel tohoto scénáře bylo nezbytné provést konfiguraci tří strojů. ∙
stroj Arachni - jak bylo zmíněno dříve, tento stroj obsahuje operační systém Debian. Dále je potřeba, aby stroj obsahoval SSH klienta a SSH server. Podle technik, které se rozhodneme využít pro vytvoření tunelů, je nutné doinstalovat nástroje Proxy chains, ncat a VPN klienta. V poslední řadě je nezbytné provést samotnou instalaci Arachni skeneru
∙
pivot server - tento stroj opět obsahuje operační systém Debian. Abychom byli schopní pokrýt veškeré možnosti pro vytvoření tunelu, je nutné mít na stroji nainstalované tyto nástroje: SSH server, VPN server, nca
∙
webový server - pokud chceme Kentico zprovoznit na webo23
3. Paralelní testování různých systémů v prostředí KYPO vém serveru, je nutné splnit požadavky na instalaci 2 Konfigurace stroje penetračního testera Penetrační tester, který bude provádět testování podle zmiňovaného bezpečnostního scénáře, bude mít k dispozici tři soubory. První soubor check_list.txt bude obsahovat seznam veškerých modulů, které Arachni podporuje. Druhý soubor penetration_test.py bude obsahovat samotný skript, který bude provádět penetrační testování. Třetí soubor pentester_machine_config.sh slouží k tomu, aby penetrační tester mohl tento skript bez problémů spustit. V podstatě se jedná o skript, který doinstaluje potřebné nástroje na stroj penetračního testera. Obsah souboru nalezneme v příloze A. 3.3.3 Konfigurační soubor Jak bylo řečeno v kapitole 3.2, bezpečnostní scénář se skládá ze dvou částí. První část, které rozumí uživatel, jsme probrali v kapitole 3.2.1. Druhou část představuje strojově čitelný text sloužící k automatizovanému vytváření sandboxů. „Pro vytváření a ukládaní strukturovaného popisu sandboxu byl zvolen otevřený standard JSON3 . Jde o datový formát pro ukládání a přenos dat nezávislý na zvolené počítačové platformě nebo použitém programovacím jazyku. Data jsou uloženy pomocí dvojice klíč-hodnota. Hodnota může být číslo, řetězec, logická hodnota (true/false), pole, objekt nebo prázdná hodnota (null). Použití pole zaručí, že bude dodrženo pořadí zpracování jednotlivých elementů.“ [18] Ukázkový konfigurační soubor, který je využíván v této práci, nalezneme jako elektronickou přílohu.
2. 3.
https://docs.kentico.com/display/K9/Server+and+hosting+requirements JSON – JavaScript Object Notation. http://www.json.org
24
4 Vytvoření bezpečného kanálu pro propojení virtuálního prostředí KYPO a testovaného subjektu Penetrační testování již ze své podstaty je velmi náročné na výkon systému a dokáže spotřebovat nezanedbatelné množství zdrojů testovaného subjektu, vždyť i v případě menší webové aplikace musí skener webových zranitelností vygenerovat více než tisíc požadavků, které musí webový server obsloužit. Pokud přihlédneme k těmto faktům a povaze penetračního testování, tak typicky penetrační testování nebudeme provádět v produkčním prostředí za běžného provozu, toto platí zejména pro vysoce dostupné systémy. Abychom se vyhnuli možnému přerušení běhu webové aplikace či urychlili testování, tak využíváme separované prostředí, které je identické oproti produkčnímu prostředí. Tímto docílíme toho, že nenarušíme provoz webové aplikace, ale zároveň otestujeme stejnou aplikaci, která běží v produkčním prostředí. Separovaná verze webové aplikace není typicky dostupná veřejně z Internetu. Proto, abychom mohli takovou aplikaci otestovat, musíme nejprve získat přístup do korporátní sítě. Mezi běžné způsoby, jak tohoto docílit, patří technika „bílé listiny“ (whitelist). Jedná se v podstatě o seznam aplikací, které mají povolený přístup do dané sítě. Kdykoliv se aplikace pokusí přistoupit k takové síti, tak se nejprve ověří, zda se nachází na bílé listině, pokud ne, pak se přístup zamítne. V případě penetračního testování uvedeme v této listině stroj, který má testování provádět, poté je mu umožněn přístup. Dalším způsobem, jak přistupovat k privátní korporátní síti je tzv. pivotovací technika. Pod pojmem pivoting se v oblasti počítačové bezpečnosti obecně rozumí akce, během které penetrační tester využije jednoho kompromitovaného systému za účelem získání přístupu k dalším systémům v architektuře klienta [19]. Technice pivotingu se budeme věnovat i v této práci. V porovnání s výše zmíněnou variantou se nám pivotovací technika může zdát zajímavější z několika důvodů. Technika „whitelist“ nám může působit problémy v případě, kdy používáme dynamicky generované IP ad25
4. Vytvoření bezpečného kanálu resy. Pokud bychom přidali určitou IP adresu na bílou listinu, a poté by se IP adresa stroje změnila, pak by tento stroj už nemohl přistoupit do korporátní sítě. To může být problém například i pokud bychom měli dvě firemní pobočky, v České republice a Spojených státech amerických. Může nastat scénář, kdy bude přístup udělen stroji v České republice, ale my budeme potřebovat přístup k privátní síti z americké pobočky, pak by to nebylo možné, protože přístup byl udělen pouze stroji, který se nachází v České republice. Pokud využijeme techniku pivoting, pak nás tento problém netrápí, jelikož na IP adrese stroje, který provádí testování, vůbec nezáleží. Dalším důvodem pro zvážení použití pivot serveru je fakt, že pokud využíváme techniku „whitelist“, pak veškerý provoz mezi testovacím strojem a webovou aplikací probíhá standardně nešifrovanou komunikací. V případě pivotingu můžeme vytvořit bezpečný tunel mezi testovacím strojem a pivot serverem pomocí technologií SSH či VPN a zabezpečit tak tímto způsobem jejich komunikaci. Technika pivotingu by měla patřit do běžného arzenálu penetračního testera. Jakmile penetrační tester získá přístup k hostiteli, může se pustit do pátrání po užitečných informacích. Penetrační tester může být schopen přemostit spojení a tímto způsobem se dostat do jiných systémů, které pro útočící systém nejsou přímo přístupné. Jedním z důvodů, proč útočící systém nemůže zaútočit přímo na takový systém, může být striktně nastavená politika, kdy firewall takovou komunikaci zachytí a nepropustí dále do korporátní sítě. Jak bylo zmíněno na počátku kapitoly, v této práci bude technika pivotingu využitá odlišným způsobem. Nebude zde probíhat fáze útočení na systém za účelem jeho zkompromitování. Klient, který si sjednal penetrační testování webové aplikace, bude srozumněný s tím, že se mezi Kybernetickým polygonem a pivot serverem v korporátní síti vytvoří tunel, pomocí kterého bude proveden penetrační test. V případě, že se penetrační tester rozhodne využít techniku pivotingu, musí ověřit, že nástroje sloužící pro penetrační testování fungují korektně i v případě, kdy komunikace putuje skrze tunel. Z tohoto důvodu je vhodné si nejprve stanovit očekávaný výsledek. Ve scenáři, který popisuje tato práce, je ověření funkčnosti skeneru webových zranitelností triviální. Webový server si ukládá přístupové logy, to tedy znamená, že po spuštění skeneru stačí tyto logy projít a ověřit, že IP adresa v zaznamenaných požadavcích je IP adresa pivot serveru 26
4. Vytvoření bezpečného kanálu a nikoliv stroje Arachni. Existují různé způsoby, kterými lze pivotovací techniku realizovat. Pivotovací nástroje, kterým se budeme věnovat v této práci, jsou: SSH tunel, SOCKS tunel, Ncat HTTP Proxy a Virtual Private Network (VPN). Každá z těchto technologií bude probrána v následujících podkapitolách.
4.1
SSH tunel
Pokud mluvíme o SSH tunelu, tak je na místě nejprve definovat pojem přesměrování portů. Přesměrování portů, z anglického „port forwarding“, chápeme jako proces zachytávání datového provozu, který je určený pro určitou kombinaci IP adresy a portu a následné přesměrování takového provozu na odlišnou IP adresu či port. Program, který běží na cílovém hostiteli, většinou obstarává přesměrování. Není ovšem výjimkou, kdy za tímto účelem využíváme mezilehlé hardwarové komponenty jako jsou router, proxy server nebo firewall [20]. Přesměrování portů, také známé jako tunelovaní (SSH Local Port Forwarding), je způsob, jakým lze přesměrovat jinak nezabezpečený TCP provoz skrze SSH. Takto lze například zabezpečit POP3, SMTP nebo HTTP spojení, které by jinak bylo nezabezpečené [21]. Tato technika může být využita k vytvoření spojení mezi penetračním testerem a pivot serverem. Princip fungování spočívá v tom, že se vytvoří SSH spojení mezi SSH klientem a SSH serverem. SSH klient naslouchá na místním portu, který je specifikován při vytváření spojení. Jakmile je spojení navázáno, tak jakékoliv spojení, které povede na tento port, bude posláno skrze bezpečný SSH tunel na předem definovaného hostitele. Abychom mohli takové spojení vytvořit, je třeba spustit příkaz s následující syntaxí [22]: $ ssh -L local_port:destination_server:destination_port username@pivot_server
Nejprve tedy musíme definovat název příkazu, který chceme použít, zde ssh. Kde -L nám říká, že se jedná o místní přesměrování portů, local_port je port naslouchající na stroji, který bude iniciovat penetrační testování, destination_server je cílová IP adresa nebo název 27
4. Vytvoření bezpečného kanálu hostitele (v tomto případě webová aplikace), destination_port je port, který naslouchá na cílovém hostiteli, username je uživatelské jméno, pomocí kterého se připojíme k pivot serveru, a pivot_server je IP adresa nebo název hostitele, který bude sloužit jako pivot.
Obrázek 4.1: SSH tunel (místní přesměrování portů) Pokud budeme uvažovat výhody tohoto přístupu, tak zde lze uvést šifrování, kdy nezabezpečený provoz prochází skrze šifrovaný kanál, a lze tak bezpečně komunikovat mezi serverem a klientem. Další výhodou z pohledu bezpečnosti je podpora autentizace. Autentizace může probíhat dvěma způsoby. První způsob je použití kombinace uživatelského jména a hesla. Hlavní výhodou použití uživatelského jména a hesla je snadnost použití, není vyžadována dodatečná konfigurace a kdokoli může vkládat přístupové údaje. To znamená, že tento způsob otevírá dveře útočníkům, kteří zkoušejí hesla uživatelů hádat, případně automatizovaným botům. Další nevýhodou je fakt, že uživatel si musí heslo pamatovat a vkládat jej při každém přístupu k serveru. Výše zmíněné nevýhody se pokouší eliminovat druhý způsob autentizace, a to použití systému klíčů. Uživatel vytvoří dvojici veřejných a privátních klíčů, nainstaluje veřejný klíč do jeho účtu, který se nachází na cílovém serveru. Přístup je serverem udělen, když se prokáže, že SSH klient, který se pokouší o autentizaci, vlastní privátní klíč. V tomto případě privátní klíč necestuje spolu s jinými požadavky na server, a tudíž nehrozí, že by potenciální útočník mohl tento privátní klíč jakkoliv odchytit a narušit tak jeho integritu. Přístup veřejného a privátního klíče je využíván také v této práci. 28
4. Vytvoření bezpečného kanálu Naopak za nevýhodu, či spíše nutný předpoklad, lze považovat to, že SSH server musíme nejprve na pivot server nainstalovat. Bez tohoto kroku nelze tuto metodu použít. Použití Arachni s místním přesměrováním portů Abychom mohli využívat Arachni skener a místní přesměrování portů, tak je nezbytné Arachni nakonfigurovat a sdělit mu, že pro veškerou komunikaci bude využívat HTTP proxy. K tomuto účelu slouží příkaz –http-proxy [15], který nastaví proxy server pro daného klienta. Ukázkový příklad použití s Arachni bude vypadat tedy následovně. Nejdříve vytvoříme SSH tunel: $ ssh -L 80:10.10.10.4:80
[email protected]
Po vytvoření tunelu spustíme Arachni skener: $ ./arachni http://10.10.10.4/web --http-proxy 127.0.0.1:80
4.2
SOCKS tunel
SOCKS tunel je v podstatě jinou variantou SSH tunelu, která byla zmíněna v předchozích odstavcích. Tato technika opět využívá příkaz ssh, ovšem s tím rozdílem, že tentokrát využíváme dynamické přesměrování portů. Dynamické přesměrování portů, přetvoří SSH klienta na SOCKS proxy server. SOCKS je méně známý protokol, ale často implementovaný protokol v programech, které vyžadují, aby internetové spojení putovalo skrze proxy server. Každý program, který chce využít proxy server, musí být nakonfigurován a překonfigurován po tom, co takový proxy server přestaneme využívat [22]. To tedy znamená, že SSH tunel je velmi podobný SOCKS tunelu, s tím rozdílem, že v tomto případě na straně klienta očekáváme SOCKS proxy. Dalším rozdílem mezi místním a dynamickým přesměrováním portů je fakt, že při místním přesměrování portů přesměrujeme všechna spojení do předem stanovené destinace. Když se poté připojíme k místnímu portu, pak putuje veškerý provoz přímo na vzdáleného hostilele, který je specifikovaný v přepínači -L. 29
4. Vytvoření bezpečného kanálu V případě dynamického přesměrování portů je cílová destinace dynamická. To konkrétně znamená, že po připojení k místnímu portu musíme ještě používat SOCKS proxy protokol, pomocí kterého určíme vzdáleného hostitele, ke kterému se chceme připojit. Z tohoto faktu plyne ten důsledek, že pokud chceme využívat tento přístup, tak nejprve musíme znát hostitele, na kterého chceme provoz přesměrovat. Pokud mluvíme o praktickém použití SOCKS tunelu, tak i v tomto případě, stejně jako v předchozím, vytvoříme bezpečný kanál mezi SSH klientem a SSH serverem. Cokoliv, co pošleme na místní port, se přesměruje skrze tento bezpečný kanál. Abychom tuto techniku mohli využít, tak jako první musíme zajistit dynamické přesměrování portu. Syntaxe příkazu je následující [23]: $ ssh -D local_address:local_port –N username@pivot_server
Opět nejprve uvedeme název příkazu, který chceme použít: ssh. Kde parametr -D říká, že se jedná o dynamické přesměrování portů, local_address je adresa místního stroje, local_port je místní port, který naslouchá komunikaci, parametr -N indikuje, aby se neprováděl vzdálený příkaz, username je uživatelské jméno na pivot serveru, a pivot_server je IP adresa nebo název hostitele, který bude sloužit jako pivot.
Obrázek 4.2: SOCKS proxy (dynamické přesměrování portů) Dalším krokem je konfigurace SOCKS proxy na straně SSH klienta. Ke konfiguraci SOCKS proxy využíváme nástroj, který se nazývá ProxyChains [24]. 30
4. Vytvoření bezpečného kanálu Aby SOCKS tunel fungoval správně, musíme přidat do konfiguračního souboru proxychains.conf řádek, který definuje port a vzdáleného hostitele, ke kterému se chceme připojit. Řádek přidáme na konec souboru ve formátu: socks5
address port
Použití Arachni s dynamickým přesměrováním portů Prvním krokem je konfigurace nástroje ProxyChains. Konfiguraci provedeme modifikací souboru proxychains.conf, který se v distribuci Debian nachází v /etc/proxychains.conf. Na konec souboru je nutné přidat: socks5
127.0.0.1 9150
Po provedení konfigurace ProxyChains můžeme vytvořit SOCKS tunel pomocí: $ ssh -D 127.0.0.1:9150 -N
[email protected]
Posledním krokem je spuštění samotného Arachni skeneru tímto příkazem: $ ./arachni http://10.10.20.14/web --http-proxy socks5://127.0.0.1:9150
4.3
Ncat HTTP Proxy
Ncat je síťový nástroj, který prostřednictvím příkazového řádku čte nebo zapisuje data v síti. Ncat pro komunikaci využívá protokoly TCP a UDP. Nástroj Ncat byl vyvinutý projektem Nmap a jedná se o přetvořený a vylepšený nástroj Netcat [25]. Ncat lze spustit v jednom ze dvou režimů. V prvním režimu Ncat zahajuje spojení a posílá data službě, která naslouchá síťovému provozu a přijímá data, která generuje Ncat. Ve druhém režimu se naopak Ncat nachází ve stavu, kdy on sám naslouchá síťovému provozu a čeká na příchozí spojení. Tento režim bude využitý při implementaci Ncat HTTP Proxy tunelu. Ncat může vytvořit tunel dvěma způsoby, pomocí SOCKS 4 nebo HTTP Proxy. V této práci jsem pro implementaci tunelu zvolil HTTP 31
4. Vytvoření bezpečného kanálu
Obrázek 4.3: Ncat HTTP Proxy Proxy. Ačkoliv se tyto dva způsoby mohou zdát podobné, rozdíl je značný. SOCKS server je server pro všeobecné použití, který navazuje TCP spojení s jiným serverem jménem klienta. Poté směřuje veškerý provoz, tam i zpět, mezi klientem a serverem. Toto funguje pro všechny síťové protokoly nezávisle na portu. SOCKS server žádným způsobem neinterpretuje síťový provoz mezi klientem a serverem. SOCKS 5 přidává podporu UDP protokolu a zlepšuje bezpečnost. HTTP Proxy se využívá k podobným účelům jako SOCKS server. Ovšem narozdíl od SOCKS serveru, HTTP proxy rozumí a interpretuje síťový provoz, který putuje mezi klientem a serverem. Tento fakt má za následek to, že HTTP Proxy může být využito pouze k manipulaci s HTTP provozem. Důsledek toho, že HTTP Proxy je omezeno pouze na HTTP provoz, je to, že s tímto provozem lze zacházet efektivněji. Například HTTP Proxy může rozpoznat často se opakující požadavky a ukládat do paměti odpovědi, a tím pádem zlepšit celkovou výkonnost [26]. Ncat je víceúčelový nástroj, který lze využít i k jiným účelům než směrování síťového provozu. Pomocí Ncat nástroje můžeme například odesílat emailové zprávy nebo můžeme proměnit Ncat na jednoduchý webový server. Použití Arachni s Ncat HTTP Proxy Nejprve je na pivot serveru nutné spustit nástroj Ncat v režimu, kdy naslouchá příchozímu spojení. Toto zajistíme provedením následují32
4. Vytvoření bezpečného kanálu cího příkazu [27]: $ ncat --listen --proxy-type http 10.10.20.7 8080
Tímto způsobem jsme si připravili pivot server, který bude nyní zachytávat veškerou příchozí HTTP komunikaci na portu 8080. Dalším krokem je již pouze spuštění Arachni skeneru, kde udáme, že generované požadavky budou proudit skrze port 8080: $ ./arachni http://10.10.20.14/web --http-proxy 10.10.20.7:8080
4.4
VPN
VPN (Virtual Private Network) představuje soukromou síť, která je vybudována nad veřejnou infrastrukturou. Bezpečnostní mechanismy, jako například šifrování, dovolují VPN uživatelům bezpečně přistupovat k síti z různých lokací prostřednictvím veřejné telekomunikační sítě, nejčastěji Internet [28].
Obrázek 4.4: VPN Mluvíme-li o VPN, pak je nutné si uvědomit, že se jedná o přístup klient a server. Na jedné straně máme VPN klienta, který autentizuje uživatele a šifruje data. Na druhé straně je zde VPN server využívající techniku zvanou tunelování, pomocí této techniky jsme schopni vytvořit bezpečnou komunikaci nad nezabezpečeným médiem. Ukázkovým příkladem využití VPN je poskytnutí vzdáleného 33
4. Vytvoření bezpečného kanálu přístupu studentům k univerzitním zdrojům. VPN server vytvoří tunel mezi počítačem studenta a univerzitní sítí. Jakmile je spojení navázáno, počítač studenta dostane IP adresu z rozsahu univerzitní sítě a bude se tvářit jako její součást, což mu umožní přístup k jinak omezeným zdrojům. Nyní, když jsme definovali technologie SSH a VPN, můžeme detailněji probrat jejich společné resp. rozdílné znaky. SSH i VPN jsou způsoby, kterými můžeme zabezpečit komunikaci. Klíčovou odlišností těchto technologií je fakt, že SSH je specifické pro danou aplikaci, zatímco VPN šifruje veškerý provoz. Pokud například nakonfigurujeme SSH a budeme ho používat k prohlížení webových stránek, pak šifrujeme pouze komunikaci webového prohlížeče, pokud bychom potřebovali šifrovat jiný komunikační kanál, pak bychom museli SSH nakonfigurat odděleně. Na druhou stranu, pokud využíváme VPN, pak po příhlášení VPN klienta k VPN serveru je šifrovaná veškerá komunikace bez ohledu na to, jestli využíváme webový prohlížeč, Skype či email [29]. Odvětví VPN je narozdíl od SSH výrazně fragmentované co se týče standardů. V této práci budeme využívat protokol OpenVPN1 . Použití Arachni s OpenVPN Pokud se rozhodneme použít Arachni spolu s OpenVPN, je třeba nejprve nainstalovat OpenVPN na pivot server pomocí příkazu # apt-get install openvpn a poté nakonfigurovat pivot server jako VPN server. Účelem této práce není popsat detailní kroky této konfigurace, proto budeme předpokládat, že konfigurace pivot serveru proběhla v pořádku. Tímto je konfigurace pivot serveru dokončena a můžeme přejít ke konfiguraci stroje Arachni. Také na tomto stroji je nezbytné nainstalovat balík OpenVPN. Po instalaci tohoto balíku dodáme Arachni stroji ještě konfigurační soubor, který slouží k navázání spojení s VPN serverem, tento soubor vznikne během konfigurace VPN serveru. Konfigurační soubor umístíme do /etc/openvpn/. Tímto je konfigurace hotová. Spuštění OpenVPN tunelu provedeme následujícím příkazem: # sudo openvpn --config /etc/openvpn/pivotserver.ovpn
1.
https://www.openvpn.net/
34
4. Vytvoření bezpečného kanálu Stroj, který slouží jako VPN server, musí být přístupný vnějšímu světu, toto je nutná podmínka pro správné fungování technologie VPN. Abychom se vyvarovali nechtěnému provozu, který by byl způsobený tím, že by VPN server byl veřejně přístupný, tak reálné testování probíhá v izolovaném prostředí kybernetického polygonu. To znamená, že tato metoda nebude dostupná k provedení penetračního testu. Nicméně tato varianta je stále relevantní, protože jakmile pivot serveru přidělíme veřejnou IP adresu, bude VPN tunel plně funkční.
35
5 Penetrační testování platformy Kentico Kentico založil v roce 2004 Petr Palas, který byl v té době studentem Masarykovy univerzity. Společnost Kentico sídlí v Brně, nicméně další pobočky existují například ve Spojených státech či Austrálii. Kentico má v současné době více než 200 zaměstnanců. Platforma Kentico slouží jako redakční a správcovský systém, pomocí kterého lze vytvářet statické webové stránky, internetové obchody či komplexní webové aplikace. Kentico představuje integrované marketingové řešení, které lze rozdělit do následujících modulů [30]: ∙
Systém pro správu obsahu
∙
Online marketing
∙
Internetový obchod
∙
Online komunity
∙
Intranetová řešení
∙
Platforma
Kentico je vysoce flexibilní systém, to konkrétně znamená, že pokud uživateli nedostačuje vestavěná funkcionalita, může si Kentico rozšířit a modifikovat prostřednictvích nově vytvářených modulů nebo pomocí vlastního kódu. Platforma Kentico je vystavěna na technologiích ASP.NET a Microsoft SQL server. Proto je nutné se před samotnou instalací přesvědčit, že server splňuje následující požadavky [31]: ∙
Operační systém Windows 7 nebo novější
∙
Microsoft .NET Framework 4.5 nebo novější
∙
Microsoft Internet Information Services 7.5 nebo novější
∙
Microsfot SQL server 2008 R2 nebo novější
∙
„Full trust“ oprávnění pro aplikaci ASP.NET
∙
Alespoň 1 GB paměti a nejméně 100 MB pro instalaci databáze 36
5. Penetrační testování platformy Kentico
5.1
Zajištění bezpečného produktu ve firmě Kentico
K zajištění bezpečnosti platformy Kentico přispívá několik aktivit. Do těchto aktivit spadá například pravidelná kontrola kódu nebo provádění skenu webových aplikací. Bezpečnostní kontrola platformy se provádí těmito způsoby: ∙
Automaticky (za tímto účelem se používá skener webových zranitelností)
∙
Manuálně (tuto kontrolu provádí bezpečnostní tým)
Nezávisle na tom, jestli se kontrola provádí automaticky nebo manuálně, tak se testují zranitelnosti jako jsou XSS, SQL injection, Crosssite request forgery apod. Kentico používá k provádění bezpečnostní kontroly několik nástrojů, které lze rozčlenit do následujících kategorií: ∙
Moduly pro prohlížeč Firefox
∙
Moduly pro nástroj Fiddler
∙
Nástroje pro statickou analýzu kódu
∙
Webové skenery
5.1.1 Moduly pro prohlížeč Firefox Webový prohlížeč Firefox disponuje několika moduly, které jsou užitečné při hledání zranitelností v produktu. Mezi hlavní výhody těchto modulů patří snadná instalace a také fakt, že jsou zdarma k dispozici. Mezi nejpoužívanější moduly patří: ∙
Web developer toolbar - modul se skládá z nástrojů pro inspekci stránek, spouštění libovolného javascriptového kódu a prohlížení HTTP požadavků či jiných zpráv. Mezi nejužitečnější vlastnosti patří možnost potlačení určitého chování na stránce (např. vypnutí cachování, javascriptu), dále lze manipulovat s cookies na stránce (vypnutí, mazání či přidání cookies), v neposlední řadě je možné ovlivňovat chování formuláře na stránce. 37
5. Penetrační testování platformy Kentico ∙
Tamper data - Tamper data modul poskytuje možnost prohlížet, zaznamenávat či modifikovat odchozí HTTP požadavky. Nejsilnější vlastnostní tohoto nástroje je právě zmíněná modifikace HTTP požadavků, ta umožňuje upravit parametry požadavku před samotným odesláním žádosti o jeho zpracování.
∙
Firebug - umožňuje upravovat rozličné detaily webových stránek. Typicky se používá k inspekci elementů na stránce, také je možné měnit atributy těchto elementů. Dále je možné zobrazit jednotlivé požadavky a odpovědi na tyto požadavky.
∙
RightClickXSS - pomocí tohoto modulu je možné testovat, zda se na stránce nachází XSS zranitelnost. Za použití tohoto modulu lze vkládat XSS kódy do textových polí formuláře na stránce. Tímto způsobem můžeme otestovat, jestli je vstup náchylný na XSS zranitelnost.
5.1.2 Moduly pro nástroj Fiddler Fiddler je nástroj, který má funkci webového proxy serveru a lze jej využívat například k ladění webových aplikací, performačním testům a své nezastupitelné místo má také v oblasti bezpečnosti. Fiddler se používá k testování bezpečnosti webových aplikací. S jeho pomocí je možné dešifrovat HTTPS provoz, zobrazit a modifikovat požadavky pomocí techniky „man-in-the-middle“ [32]. ∙
Watcher - cílem modulu Watcher je asistovat penetračním testerům při hledání zranitelností webové aplikace. Tento modul analyzuje běžné chování uživatele na stránce a na jeho základě vytváří zprávy, které se týkají bezpečnosti dané webové aplikace (např. nastavení cookies či SSL).
∙
Ammonite - pomocí Ammonite modulu je možné provést sken webové aplikace a hledat běžné webové zranitelnosti jako jsou XSS, SQL injection, apod.
5.1.3 Nástroje pro statickou analýzu kódu Princip statické analýzy kódu spočívá v analyzování kódu, ovšem bez toho, abychom takový kód vůbec prováděli. Typicky se využívá k hle38
5. Penetrační testování platformy Kentico dání chyb v produktu nebo k zajištění souladu s pravidly pro psaní kódu. ∙
FxCop - tento nástroj provádí statickou analýzu kódu, který je napsaný v .NET. Disponuje více než stovkou různých pravidel, prostřednictvím kterých lze provádět různé typy analýzy.
∙
Code.It.Right - Code.It.Right kombinuje statickou analýzu kódu s automatickým refactoringem pro Microsoft Visual Studio.
5.1.4 Webové skenery V současné době se ve společnosti Kentico využívá webový skener Acunetix v jeho placené verzi. Celý proces testování pomocí skeneru Acunetix lze shrnout do následujících fází: ∙
Modifikace knihoven ve zdrojovém kódu
∙
Instalace Kentico
∙
Spuštění skeneru Acunetix
Před samotným začátkem skenování je tedy nejprve nutné upravit knihovny zdrojového kódu tak, aby skener měl k těmto knihovnám přístup a mohl je podrobit testování. Dalším krokem je spuštění skriptu napsaného v Power Shell, tento skript se stará o instalaci Kentico do virtuálního prostředí společnosti Acunetix. Jakmile je tento skript dokončený, zašle se bezpečnostnímu týmu notifikace, zda instalace proběhla úspěšně či nikoliv. Další den je naplánované spuštění webového skeneru Acunetix. Tato prodleva mezi instalací Kentico a spuštění skeneru slouží jako pojistka pro případ, že by se instalace do virtuálního prostředí nezdařila a zbyl tak čas na její nápravu. Webový skener testuje pouze jedinou webovou aplikaci, paralelně neprobíhá více testů zároveň. Testování pomocí Acunetix skeneru se spouští každou středu ráno a dokončení testu trvá několik dní. Jakmile skener dokončí svou práci, vygeneruje závěrečnou zprávu a výsledky uloží do databáze. Bezpečnostní tým v Kentico obdrží notifikaci o ukončení činnosti skeneru. 39
5. Penetrační testování platformy Kentico
5.2
Výsledky provedeného testování s využitím Arachni skeneru
Jak jsme dříve uvedli, ukázkové penetrační testování je provedeno na webovém serveru, který obsahuje webovou aplikaci, jenž běží na platformě Kentico. Tento test má za cíl ověřit funkčnost navrženého řešení. Penetrační skript byl spuštěný s následujícími parametry: $ python penetration_test.py -n 1 -s konicek-vizvary -u
[email protected] -m xss
V tomto ukázkovém příkladu se Arachni skener zaměřuje pouze na zranitelnost XSS. Po spuštění výše uvedeného příkazu bylo nutné zadat následující parametry: ∙
URL webové aplikace: http://kypotesting.com
∙
Způsob tunelování: ssh
∙
Pivot server: 10.10.20.7
∙
Pivot uživatel: pivotserver
∙
Pivot heslo: pivot
∙
Webový server: 10.10.20.14
Jakmile skener dokončí testování webové aplikace odešle zprávu o této skutečnosti na adresu
[email protected]. Dále vytvoří na disku uživatele, který spustil penetrační testování, soubor, jenž obsahuje informace o průběhu testování a nalezených zranitelnostech. V příloze C se nachází ukázka výsledné zprávy, kterou vygeneroval skener Arachni.
40
6 Závěr Cílem této diplomové práce bylo vytvoření vhodného prostředí pro provádění penetračního testování webových aplikací v prostředí Kybernetického polygonu. Praktickým výstupem této práce je skript napsaný v jazyce Python, který slouží pro provádění penetračního testování webových aplikací. Pomocí vyvinutého skriptu můžeme penetrační testování provádět efektivněji. Pomineme-li fakt, že je třeba nakonfigurovat pivot server, tak před započetím testování od uživatele vyžadujeme pouze několik vstupních hodnot. Také jsme optimalizovali využití zdrojů, neboť množství webových požadavků, které generuje skener webových zranitelností jsme přenesli od uživatele do Kybernetického polygonu. Nejprve jsme se věnovali pojmu skener webových zranitelností a představili jsme způsob, jakým tyto nástroje můžeme využít k ověření bezpečnoti webové aplikace. Dále jsme si představili prostředí Kybernetického polygonu, ve kterém jsme prováděli samotné penetrační testování. Abychom mohli realizovat penetrační testování dle definovaného bezpečnostního scénáře, bylo nutné vytvořit a nakonfigurovat jednotlivé stroje, a to konkrétně pivot server, stroj Arachni a webový server. V další části jsme prodiskutovali jednotlivé nástroje, které můžeme využít k vytvoření tunelu mezi strojem Arachni a pivot serverem. Prakticky jsme ověřili, že k vytvoření tunelu mezi těmito stroji můžeme využít jak nástroj SSH, tak nástroj Ncat. Co se týče možnosti využití VPN k vytvoření tunelu, tuto možnost jsme prodiskutovali pouze teoreticky, neboť penetrační testování probíhalo v izolovaném prostředí bez přístupu k Internetu. V závěrečné části této práce jsme si představili platformu Kentico, na které jsme provedli ukázkový penetrační test a jeho výsledky stručně prezentovali. Co se týče dalšího možného vývoje, pak by bylo vhodné zvážit přesunutí samotného skriptu do prostředí Kybernetického polygonu tak, aby uživatel neměl přístup k jeho zdrojovému kódu. Interakce uživatele by pak byla zajištěna uživatelským formulářem, který by byl vytvořen jako další prvek Liferay portálu, na kterém je KYPO nasazen. Tímto způsobem bychom uživatele odstínili od samotného skriptu a dopřáli mu přívětivější uživatelský zážitek, neboť by pracoval s grafickým formulářem. 41
Bibliografie 1. ENGEBRETSON, Patrick. The Basics of Hacking and Penetration Testing: Ethical Hacking and Penetration Testing Made Easy. 2. vyd. Waltham: Elsevier, 2013. 204 s. ISBN 978-0-12-411644-3. 2. High Level Organization of the Standard [online]. 2014 [cit. 2016-04-20]. Dostupný z WWW: ⟨http://www.pentest- standard.org/index. php/Main_Page⟩. 3. The OWASP Foundation: Input Validation Vulnerabilities, Encoded Attack Vectors and Mitigations [online]. 2008 [cit. 2016-04-20]. Dostupný z WWW: ⟨https : / / www . owasp . org / images / 6 / 6c / Encoded _ Attacks_Threats_Countermeasures_9_30_08.pdf⟩. 4. WhiteHat Security: WhiteHat Security 2015 Website Security Statistics Report Reveals the Need to Identify Security Metrics Most Important for Vulnerability Remediation [online]. 2015 [cit. 2016-04-20]. Dostupný z WWW: ⟨https : / / www . owasp . org / images / 6 / 6c / Encoded _ Attacks _ Threats_Countermeasures_9_30_08.pdf⟩. 5. N-Stalker: Free Edition X [online]. 2016 [cit. 2016-04-20]. Dostupný z WWW: ⟨http://www.nstalker.com/products/editions/free/⟩. 6. Hewlett Packard Enterprise: Finding SQL Injection with Scrawlr [online]. 2015 [cit. 2016-04-21]. Dostupný z WWW: ⟨http://community.hpe. com / t5 / Protect - Your - Assets / Finding - SQL - Injection - with Scrawlr/ba-p/2408262#.Vxe1_0dDzfZ⟩. 7. Kali Tools: Skipfish [online]. 2014 [cit. 2016-04-21]. Dostupný z WWW: ⟨https://code.google.com/archive/p/skipfish/⟩. 8. Subgraph: Vega Vulnerability Scanner [online]. 2014 [cit. 2016-04-21]. Dostupný z WWW: ⟨https://subgraph.com/vega/⟩. 9. w3af [online]. 2013 [cit. 2016-04-21]. Dostupný z WWW: ⟨http : / / w3af.org/⟩.
42
BIBLIOGRAFIE 10. Arachni: Web Application Security Scanner Framework [online]. 2016 [cit. 2016-04-21]. Dostupný z WWW: ⟨http : / / www . arachni - scanner . com/⟩. 11. Wapiti: The web-application vulnerability scanner [online]. 2014 [cit. 201604-21]. Dostupný z WWW: ⟨http://wapiti.sourceforge.net/⟩. 12. OWASP: WebScarab Project [online]. 2011 [cit. 2016-04-21]. Dostupný z WWW: ⟨https://www.owasp.org/index.php/Category:OWASP_ WebScarab_Project⟩. 13. OWASP: Zed Attack Proxy Project [online]. 2016 [cit. 2016-04-21]. Dostupný z WWW: ⟨https://www.owasp.org/index.php/OWASP_Zed_ Attack_Proxy_Project#tab=Features⟩. 14. SECTOOL Market: Price and Feature Comparison of Web Application Scanners [online]. 2014 [cit. 2016-04-21]. Dostupný z WWW: ⟨http : / / sectoolmarket . com / price - and - feature - comparison - of - web application-scanners-opensource-list.html⟩. 15. GitHub: Arachni command line user interface [online]. 2016 [cit. 2016-0421]. Dostupný z WWW: ⟨https://github.com/Arachni/arachni/ wiki/Command-line-user-interface⟩. 16. ČELEDA, Pavel et al. Projekt KYPO – VG20132015103: Analýza a návrh architektury. Technická zpráva. Ústav výpočetní techniky. Masarykova univerzita. 2013. 17. Ústavu výpočetní techniky MU: KYPO případy užití [online]. 2015 [cit. 2016-01-20]. Dostupný z WWW: ⟨http://www.kypo.cz/pripadyuziti⟩. 18. VELAN, Petr; JIRSÍK, Tomáš; VIZVARY, Martin; ČEGAN, Jakub; PROCHÁZKA, Michal; OŠLEJŠEK, Radek; EICHLER, Zdenek. Projekt KYPO – VG20132015103: Návrh a vývoj prototypu Kybernetického polygonu – etapa II. Technická zpráva. Ústav výpočetní techniky. Masarykova univerzita. 2014.
43
BIBLIOGRAFIE 19. Post Exploitation [online]. 2014 [cit. 2016-03-18]. Dostupný z WWW: ⟨http://www.pentest-standard.org/index.php/Post_Exploitation⟩. 20. What is Port Forwarding? [online]. 2016 [cit. 2016-03-18]. Dostupný z WWW: ⟨http://whatismyipaddress.com/port-forwarding⟩. 21. Debian Admin: Howto use SSH local and remote port forwarding [online]. 2015 [cit. 2016-01-20]. Dostupný z WWW: ⟨http://www.debianadmin. com/howto-use-ssh-local-and-remote-port-forwarding.html⟩. 22. Ubuntu: SSH/OpenSSH/PortForwarding [online]. 2013 [cit. 2016-03-01]. Dostupný z WWW: ⟨https://help.ubuntu.com/community/SSH/ OpenSSH/PortForwarding⟩. 23. Ubuntu manuals [online]. 2010 [cit. 2016-03-01]. Dostupný z WWW: ⟨http://manpages.ubuntu.com/manpages/xenial/en/man1/ssh.1. html⟩. 24. ProxyChains HowTo [online]. [cit. 2016-03-12]. Dostupný z WWW: ⟨http: //proxychains.sourceforge.net/howto.html⟩. 25. Ncat: Ncat for the 21st Century [online]. [cit. 2016-03-12]. Dostupný z WWW: ⟨https://nmap.org/ncat/⟩. 26. jGuru: What is the difference between a SOCKS proxy and an HTTP proxy? [online]. 2012 [cit. 2016-03-01]. Dostupný z WWW: ⟨http : / / www . jguru.com/faq/view.jsp?EID=227532⟩. 27. Ncat: Ncat Reference Guide [online]. [cit. 2016-03-12]. Dostupný z WWW: ⟨https://nmap.org/book/ncat-man.html⟩. 28. techopedia: Virtual Private Network (VPN) [online]. 2016 [cit. 2016-0501]. Dostupný z WWW: ⟨https://www.techopedia.com/definition/ 4806/virtual-private-network-vpn⟩. 29. Quora: Great Firewall of China (GFW): What is the difference between SSH and VPN? [online]. 2011 [cit. 2016-05-10]. Dostupný z WWW: ⟨https: //www.quora.com/Great-Firewall-of-China-GFW-What-is-thedifference-between-SSH-and-VPN⟩. 44
BIBLIOGRAFIE 30. Kentico: All Features [online]. 2016 [cit. 2016-03-01]. Dostupný z WWW: ⟨http://www.kentico.com/product/all-features⟩. 31. Kentico 9 Documentation: Server and hosting requirements [online]. 2016 [cit. 2016-03-01]. Dostupný z WWW: ⟨https://docs.kentico.com/ display/K9/Server+and+hosting+requirements⟩. 32. Fiddler: Key Features [online]. 2016 [cit. 2016-03-20]. Dostupný z WWW: ⟨http://www.telerik.com/fiddler⟩.
45
A Soubor pentester_machine_config.sh #!/bin/bash apt-get install python-setuptools build-essential python-dev libffi-dev libpq-dev libxml2-dev libxslt1-dev easy_install pip pip install pexpect --upgrade paramiko requests SQLAlchemy psycopg2
46
B Soubor penetration_test.py import paramiko import getopt import sys import json import requests from sqlalchemy import create_engine, MetaData, Table from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker import random import getpass import pickle import time import re import datetime import smtplib import Queue import threading # SQL Alchemy mapping Base = declarative_base() engine = create_engine(’’,echo=False) metadata = MetaData(bind=engine) session = sessionmaker() session.configure(bind=engine) s = session() ### Section with class definition and their managers ###
# testing subject class class TestingSubject(Base): __table__ = Table(’testing_subject’, metadata, autoload=True, schema="pentest") def __init__(self, web_application, pivot_server, pentester, tunneling_method): self.tunnel_method = tunneling_method
47
B. Soubor penetration_test.py self.pentester_id = pentester self.pivot_server_id = pivot_server self.web_application_id = web_application
# TestingSubject manager class class TestingSubjectManager: def __init__(self, s): self.s = s def create_testing_subject(self, testing_subject): self.s.add(testing_subject) self.s.commit() def delete_testing_subject(self, testing_subject): self.s.delete(testing_subject) self.s.commit() self.s.flush()
# web server class class WebServer(Base): __table__ = Table(’web_server’, metadata, autoload=True, schema="pentest") def __init__(self, hostname): self.hostname = hostname
# WebServer manager class class WebServerManager: def __init__(self, s): self.s = s def create_web_server(self, web_server): self.s.add(web_server) self.s.commit() def delete_web_server(self, web_server): query = s.query(WebApplication.id)\
48
B. Soubor penetration_test.py .filter(WebApplication.web_server_id == web_server.id) web_application_id = query.scalar() if not web_application_id: self.s.delete(web_server) self.s.commit() self.s.flush() print "[+] Web server ’" + web_server.hostname + \ "’ was deleted [+]" else: print "[!] Web server ’" + web_server.hostname + \ "’ was not deleted. Other application is" \ " being tested [!]" def get_web_server_byid(self, web_server_id): web_server = self.s.query(WebServer)\ .filter_by(id=web_server_id).first() return web_server def get_web_server_byhostname(self, hostname): web_server = self.s.query(WebServer)\ .filter_by(hostname=hostname).first() return web_server
# web application class class WebApplication(Base): __table__ = Table(’web_application’, metadata, autoload=True, schema="pentest") def __init__(self, url, web_server): self.url = url self.web_server_id = web_server
# WebApplication manager class class WebApplicationManager: def __init__(self, s): self.s = s def create_web_application(self, web_application):
49
B. Soubor penetration_test.py self.s.add(web_application) self.s.commit() def delete_web_application(self, web_application): self.s.delete(web_application) self.s.commit() self.s.flush() def get_web_application_byid(self, web_application_id): web_application = self.s.query(WebApplication)\ .filter_by(id=web_application_id).first() return web_application
# Sandbox class class Sandbox: def __init__(self, name): self.name = name
# Sandbox manager class class SandboxManager: def create_sandbox(self, sandbox_name): rest_url = "http://kypo.ics.muni.cz:5000/sce" \ "nario/sandbox/load/"\ + sandbox_name + "/konicek-vizvary.json" response = requests.get(rest_url) if response.ok: jData = json.loads(response.content) print jData else: print "[-] Sandbox ’" + sandbox_name + \ "’ cannot be created [-]" response.raise_for_status() sys.exit(1) def delete_sandbox(self, sandbox_name): rest_url = "http://kypo.ics.muni.cz:5000/sce" \ "nario/sandbox/delete/"\ + sandbox_name
50
B. Soubor penetration_test.py response = requests.get(rest_url) if response.ok: print "[+] Sandbox ’" + sandbox_name + \ "’ successfully deleted [+]" jData = json.loads(response.content) print jData else: print "[-] Sandbox ’" + sandbox_name + \ "’ cannot be deleted [-]" response.raise_for_status() sys.exit(1) def get_sandbox_ip(self, sandbox_name): rest_url = "http://kypo.ics.muni.cz:5000/scenario/sa" \ "ndbox/ip/" + sandbox_name response = requests.get(rest_url) if response.ok: jData = json.loads(response.content) sandbox_ip = jData["ip"] return sandbox_ip
# Pentester class class Pentester(Base): __table__ = Table(’pentest_user’, metadata, autoload=True, schema="pentest") def __init__(self, email): self.email = email
# Pentester manager class class PentesterManager: def __init__(self, s): self.s = s def create_pentester(self, pentester): s.add(pentester) s.commit()
51
B. Soubor penetration_test.py def get_pentester_byemail(self, pentester_email): pentester = self.s.query(Pentester)\ .filter_by(email=pentester_email).first() return pentester
# Arachni host class class ArachniHost(Base): __table__ = Table(’arachni_host’, metadata, autoload=True, schema="pentest") def __init__(self, hostname, username, password, name): self.hostname = hostname self.username = username self.password = password self.name = name
# ArachniHost manager class class ArachniHostManager: def __init__(self, s): self.s = s def create_arachni_host(self, arachni_host, sandbox_name): if arachni_host.hostname == "10.10.10.4": s.add(arachni_host) s.commit() else: rest_url ="http://kypo.ics.muni.cz:5000/scenario/"+\ sandbox_name + "/host/copy/arachni/" + \ arachni_host.name + "/" + \ arachni_host.hostname response = requests.get(rest_url) if response.ok: jData = json.loads(response.content) print jData print "[+] Arachni host ’"+ArachniHost.hostname \ + "’ was created [+]" self.s.add(arachni_host)
52
B. Soubor penetration_test.py self.s.commit() else: print "[-] Arachni host ’"+ArachniHost.hostname \ + "’ cannot be created [-]" response.raise_for_status() sys.exit(1) def get_arachni_host_byhostname(self, hostname): arachni_host = self.s.query(ArachniHost)\ .filter_by(hostname=hostname).first() return arachni_host def get_arachni_host_username(self, username): arachni_host = self.s.query(ArachniHost)\ .filter_by(username=username).first() return arachni_host def delete_arachni_host(self, arachni_host): # delete function is not actually implemented in KYPO, # so the code removes only database records self.s.delete(arachni_host) self.s.commit()
# Pivot class class PivotServer(Base): __table__ = Table(’pivot_server’, metadata, autoload=True, schema="pentest") def __init__(self, hostname, username, password): self.hostname = hostname self.username = username self.password = password
# PivotServer manager class class PivotServerManager: def __init__(self, s): self.s = s
53
B. Soubor penetration_test.py def create_pivot_server(self, pivot_server): s.add(pivot_server) s.commit() def get_pivot_server_byhostname(self, hostname): pivot_server = self.s.query(PivotServer)\ .filter_by(hostname=hostname).first() return pivot_server def get_pivot_byid(self, pivot_id): pivot_server = self.s.query(PivotServer)\ .filter_by(id=pivot_id).first() return pivot_server def delete_pivot_byid(self, pivot_id): query = s.query(TestingSubject)\ .filter(TestingSubject.pivot_server_id == pivot_id) testing_subject_id = query.scalar() pivot_server = self.get_pivot_byid(pivot_id) if not testing_subject_id: self.s.delete(pivot_server) self.s.commit() print "[+] Pivot server ’" + pivot_server.hostname \ + "’ was deleted [+]" else: print "[!] Pivot server ’" + pivot_server.hostname \ + "’ was not deleted. " \ "Other application is being tested [!]"
# SMTPServer class class SMTPServer: def __init__(self, smtp_server, smtp_login, smtp_password, smtp_user): self.smtp_server = smtp_server self.smtp_login = smtp_login self.smtp_password = smtp_password self.smtp_user = smtp_user
54
B. Soubor penetration_test.py ### Initialization of managers ### testing_subject_manager = TestingSubjectManager(s) arachni_host_manager = ArachniHostManager(s) pivot_server_manager = PivotServerManager(s) web_application_manager = WebApplicationManager(s) web_server_manager = WebServerManager(s) sandbox_manager = SandboxManager()
### Section related to connection establishment def establish_smn_connection(smn_host, port, smn_username, smn_password): print "[*] Trying to establish connection to " + \ smn_host + " [*]" # establish connection to KYPO (SMN) try: smn_client = paramiko.SSHClient() smn_client.set_missing_host_key_policy( paramiko.AutoAddPolicy()) smn_client.connect(smn_host, port=port, username=smn_username, password=smn_password) print "[+] Connection to "+smn_host+" established [+]" smn_client.exec_command("route add -net 10.10.20.0 gw " "172.16.1.3 netmask 255.255.255.0") smn_client.exec_command("route add -net 10.10.10.0 gw " "172.16.1.2 netmask 255.255.255.0") except paramiko.AuthenticationException: print "[-] Authentication failed when connecting to "+\ smn_host + " [-]" sys.exit(1) return smn_client
def establish_arachni_connection(smn_client, smn_host, arachni_host, port):
55
B. Soubor penetration_test.py counter = 0 while True: print "[*] Trying to establish connection to " + \ arachni_host.hostname + " [*]" if counter >= 1: time.sleep(15) elif counter > 15: print "[!] Authentication failed when connecting" \ " to " + arachni_host.hostname + " [!]" sys.exit(1) try: transport = smn_client.get_transport() destination_addr = (arachni_host.hostname, port) local_addr = (smn_host, port) channel = transport.\ open_channel("direct-tcpip", destination_addr, local_addr) except Exception: counter += 1 continue break # establish connection to Arachni host try: arachni_client = paramiko.SSHClient() arachni_client.set_missing_host_key_policy( paramiko.AutoAddPolicy()) arachni_client.connect(arachni_host.hostname, port=port, username=arachni_host.username, password=arachni_host.password, sock=channel) print "[+] Connection to " + arachni_host.hostname + \ " established [+]" except paramiko.AuthenticationException: print "[!] Authentication failed when connecting to "+\ arachni_host.hostname + " [!]" sys.exit(1) return arachni_client
56
B. Soubor penetration_test.py def establish_pivot_connection(smn_client, smn_host, pivot_server, port): counter = 0 while True: print "[*] Trying to establish connection to " + \ pivot_server.hostname + " [*]" if counter >= 1: time.sleep(15) elif counter > 15: print "[!] Authentication failed when connecting " \ "to " + pivot_server.hostname + " [!]" sys.exit(1) try: transport = smn_client.get_transport() destination_addr = (pivot_server.hostname, port) local_addr = (smn_host, port) channel = transport.\ open_channel("direct-tcpip", destination_addr, local_addr) except Exception: counter += 1 continue break # establish connection to pivot host try: pivot_client = paramiko.SSHClient() pivot_client.set_missing_host_key_policy( paramiko.AutoAddPolicy()) pivot_client.connect(pivot_server.hostname, port=port, username=pivot_server.username, password=pivot_server.password, sock=channel) print "[+] Connection to " + pivot_server.hostname + \ " established [+]" except paramiko.AuthenticationException: print "[!] Authentication failed when connecting to "+\ pivot_server.hostname + " [!]"
57
B. Soubor penetration_test.py sys.exit(1) return pivot_client
### Section where is the actual penetration test performed def perform_test(arachni_client, testing_subject, smn_client, smn_host, port, smtp_server, pentester, modules, q): # prepare command to feed scanner arachni_command = ’’ checks = "" if modules != "": checks = "--checks=" + modules # get pivot server specific for penetration test pivot_server = pivot_server_manager.\ get_pivot_byid(testing_subject.pivot_server_id) # establish connection to pivot server pivot_client = establish_pivot_connection(smn_client, smn_host, pivot_server, port) # get web application specific for penetration test web_application = web_application_manager\ .get_web_application_byid(testing_subject .web_application_id) # get web server specific for penetration test web_server = web_server_manager\ .get_web_server_byid(web_application.web_server_id) # get item from queue q.get() print "[*] Penetration testing is in progress [*]"
58
B. Soubor penetration_test.py print "[*] Pivot server hostname being used is ’" + \ pivot_server.hostname + "’ [*]" print "[*] Web server hostname being used is ’" + \ web_server.hostname + "’ [*]" print "[*] Web application URL being scanned is ’" + \ web_application.url + "’ [*]" print "[*] Tunneling method was set to ’" + \ testing_subject.tunnel_method + "’ [*]" if checks == "": print "[*] No modules specified. " \ "All checks were loaded [*]" else: print "[*] The following checks were loaded: " + \ modules + " [*]" # vpn technique if testing_subject.tunnel_method == ’vpn’: print "[!] Invalid tunneling method [!]" sys.exit(1) # socks technique elif testing_subject.tunnel_method == ’socks’: arachni_client.exec_command("echo ’socks5 " "127.0.0.1:9150’ >> " "/etc/proxychains.conf") arachni_client.exec_command(’ssh -fN -o ’ ’StrictHostKeyChecking=no ’ ’-D 127.0.0.1:9150 ’ + pivot_server.username + ’@’+pivot_server.hostname) arachni_command = ’Scanner/arachni-1.4-0.5.10/’ \ ’bin/arachni ’+ checks + ’ ’ + \ web_application.url + ’ --http’ \ ’-proxy socks5://127.0.0.1:9150’ # ncat technique elif testing_subject.tunnel_method == ’ncat’: pivot_client.exec_command("ncat --listen --proxy-type " "http " + pivot_server .hostname + " 8080 &")
59
B. Soubor penetration_test.py arachni_command = ’Scanner/arachni-1.4-0.5.10/bin/’ \ ’arachni ’ + checks + ’ ’ + \ web_application.url+’ --http-proxy ’\ + pivot_server.hostname+ ’:8080’ # ssh technique elif testing_subject.tunnel_method == ’ssh’: arachni_client.exec_command(’ssh -fN ’ ’-o StrictHostKeyChecking=no’ ’ -L 8080:’+ web_server.hostname +’:80 ’ + pivot_server.username + ’@’ + pivot_server.hostname) arachni_command = ’Scanner/arachni-1.4-0.5.10/’ \ ’bin/arachni ’+ checks + ’ ’ + \ web_application.url + \ ’ --http-proxy 127.0.0.1:8080’ else: print "[x] Invalid tunneling method [x]" sys.exit(1) current_time = datetime.datetime.now().isoformat() log_text_file = "arachni_log_" + \ web_application.url[7:] + "_" + \ current_time + ".log" report_text_file = "arachni_report_" + \ web_application.url[7:] + "_" + \ current_time + ".txt" # read arachni output stdin, stdout, stderr= arachni_client.\ exec_command(arachni_command) # store the arachni output to the log file net_dump = stdout.readlines() pickle.dump(net_dump, open(log_text_file, ’wb’)) # generate txt report
60
B. Soubor penetration_test.py arachni_client.exec_command("Scanner/arachni-1.4-0.5.10/bin/" "arachni_reporter " "/home/pentester/*.afr " "--reporter=txt:outfile=" "/home/pentester/final_report.txt") time.sleep(2) stdin, stdout, stderr = arachni_client.\ exec_command(’cat /home/pentester/final_report.txt’) # store the arachni report to the report file net_dump2 = stdout.readlines() pickle.dump(net_dump2, open(report_text_file, ’wb’)) print "[*] Penetration test for ’" + \ web_application.url + "’ has completed [*]" # remove the finished objects testing_subject_manager\ .delete_testing_subject(testing_subject) web_application_manager\ .delete_web_application(web_application) web_server_manager.delete_web_server(web_server) pivot_server_manager.\ delete_pivot_byid(testing_subject.pivot_server_id) # send notification to the user that test is completed send_notification(smtp_server.smtp_server, smtp_server.smtp_user, smtp_server.smtp_password, smtp_server.smtp_user, pentester.email) rows = s.query(TestingSubject)\ .filter(TestingSubject.pentester_id == pentester.id)\ .count() if rows == 1: print "[*] Penetration testing still in progress. " \ "1 web application remains [*]" elif rows > 1: print "[*] Penetration testing still in progress. " \ + str(rows) + " web applications remain [*]"
61
B. Soubor penetration_test.py # mark item in queue as done q.task_done()
### Section with general methods ###
# method which prints instructions def help(): print "Usage: penetration_test.py -n
-s " \ "<SANDBOX_NAME> -u -m " print " -n specify the number " \ "of websites for penetration test" print " -s specify the sandbox name" print " -u specify the user email" print " -m specify the checks " \ "(separated by commas without spaces, " \ "if not specified " \ "all checks are used)" print " -h output help information" print print "[*] are status messages." print "[+] are success messages." print "[!] are warning messages." print "[-] are error messages." print print "Examples: " print "penetration_test.py -n 2 -s sandbox_name " \ "-u [email protected] -m xss" print "Web application url: http://kypotesting.com" print "Tunneling method: ssh" print "Pivot server: 10.10.20.7" print "Pivot user: pivotserver" print "Pivot password: pivot" print "Web server: 10.10.20.14" print print "Web application url: http://10.10.20.14" print "Tunneling method: ncat" print "Pivot server: 10.10.20.7"
62
B. Soubor penetration_test.py print "Pivot user: pivotserver" print "Pivot password: pivot" print "Web server: 10.10.20.14"
# method which checks if the variable is int def int_try_parse(value): try: int(value) return True except ValueError: return False
# verify that pivot has a valid format def validate_pivot(pivot_server): error_message = "" if not pivot_server.hostname: error_message += "\n[!] Pivot hostname is empty [!]" if not pivot_server.username: error_message += "\n[!] Pivot username is empty [!]" if not pivot_server.password: error_message += "\n[!] Pivot password is empty [!]" if error_message == "": return True else: print error_message return False
# verify that testing_subject has a valid format def validate_testing_subject(testing_subject): error_message = "" if testing_subject.tunnel_method != "ncat" and \ testing_subject.tunnel_method != "ssh" and \ testing_subject.tunnel_method != "socks" \ and testing_subject.tunnel_method != "vpn": print testing_subject.tunnel_method error_message += "\n[!] Invalid tunnel method [!]"
63
B. Soubor penetration_test.py if error_message == "": return True else: print error_message print "\n" return False
# verify that web application has a valid format def validate_web_application(web_application): error_message = "" if web_application.url[:7] != "http://" or \ not web_application.url: error_message += "\n[!] Web application URL is not " \ "starting with ’http://’ [!]" if error_message == "": return True else: print error_message print "\n" return False
# verify that web server has a valid format def validate_web_server(web_server): error_message = "" if not web_server.hostname: error_message += "\n[!] Web server is empty [!]" if error_message == "": return True else: print error_message print "\n" return False
# verify that user eamil has a valid format: def validate_user_email(user_email):
64
B. Soubor penetration_test.py if not re.match( r"^[A-Za-z0-9\.\+_-]+@[A-Za-z0-9\._-]+\.[a-zA-Z]*$", user_email): return False return True
# method which creates a specified number of websites def generate_testing_subjects(number_of_websites,pentester_id): isValid = False testing_subjects = [None] testing_subject_counter = 0 while testing_subject_counter < int(number_of_websites) \ and isValid is False: print print "Data for web application %s" % \ (testing_subject_counter + 1) print "--------------------------" website_url = raw_input("Web application url: ")\ .strip(’\n’) tunneling_method = raw_input("Tunneling method: ")\ .strip(’\n’) pivot_server = raw_input("Pivot server: ").strip(’\n’) pivot_username = raw_input("Pivot user: ").strip(’\n’) pivot_password = getpass.getpass("Pivot password: ")\ .strip(’\n’) web_server = raw_input("Web server: ").strip(’\n’) web_server_complete = WebServer(web_server) pivot_complete = PivotServer(pivot_server, pivot_username, pivot_password) pivot_server_db = pivot_server_manager\ .get_pivot_server_byhostname(pivot_server) if pivot_server_db: pivot_server_id = pivot_server_db.id else: pivot_server_manager\
65
B. Soubor penetration_test.py .create_pivot_server(pivot_complete) pivot_server_id = pivot_complete.id web_server_db = web_server_manager\ .get_web_server_byhostname(web_server) if web_server_db: web_server_id = web_server_db.id else: web_server_manager\ .create_web_server(web_server_complete) web_server_id = web_server_complete.id # initialize the objects based on the user input web_application_complete = WebApplication(website_url, web_server_id) web_application_manager\ .create_web_application(web_application_complete) testing_subject = \ TestingSubject(web_application_complete.id, pivot_server_id, pentester_id, tunneling_method) # validate user input and create objects if they # pass validation if validate_web_server(web_server_complete) and \ validate_web_application(web_application) \ and validate_testing_subject(testing_subject) \ and validate_pivot(pivot_complete): testing_subject_manager.\ create_testing_subject(testing_subject) testing_subjects.append(testing_subject) testing_subject_counter += 1 # remove the first empty object testing_subjects.remove(None) return testing_subjects
66
B. Soubor penetration_test.py # method which creates a specified number of arachni hosts def generate_arachni_hosts(number_of_hosts, sandbox_name): arachni_hosts = [None] # get arachni host which is defined in # configuration file default_arachni_host = arachni_host_manager\ .get_arachni_host_byhostname("10.10.10.4") # if one arachni is needed, it is taken just from # configuration file if (not default_arachni_host) and \ (int(number_of_hosts) == 1): default_arachni_host = ArachniHost(’10.10.10.4’, ’pentester’, ’pentest’, ’arachni’) arachni_host_manager\ .create_arachni_host(default_arachni_host,sandbox_name) arachni_hosts.append(default_arachni_host) arachni_hosts.remove(None) return arachni_hosts # if more than one arachni is needed use the one in # configuration file and generate the rest of them elif (not default_arachni_host) and \ (int(number_of_hosts) > 1): default_arachni_host = ArachniHost(’10.10.10.4’, ’pentester’, ’pentest’, ’arachni’) arachni_host_manager\ .create_arachni_host(default_arachni_host, sandbox_name) arachni_hosts.append(default_arachni_host) hostname = ’’ for x in range(0, (int(number_of_hosts)-1)): arachni_exitst = True while(arachni_exitst): # generate random IP addresses
67
B. Soubor penetration_test.py host_ip = random.SystemRandom().randint(0,255) hostname = "10.10.10.%d" % host_ip test_arachni = arachni_host_manager\ .get_arachni_host_byhostname(hostname) if not test_arachni: arachni_exitst = False name = default_arachni_host.name + "%d" % host_ip arachni_host = ArachniHost(hostname, default_arachni_host.username, default_arachni_host.password, name) arachni_host_manager\ .create_arachni_host(arachni_host, sandbox_name) arachni_hosts.append(arachni_host) # do not use arachni from configuration file and generate # all of them else: for x in range(0, int(number_of_hosts)): arachni_exitst = True while (arachni_exitst): # generate random IP addresses host_ip = random.SystemRandom().randint(0, 255) hostname = "10.10.10.%d" % host_ip test_arachni = arachni_host_manager\ .get_arachni_host_byhostname(hostname) if not test_arachni: arachni_exitst = False name = default_arachni_host.name + "%d" % host_ip arachni_host = ArachniHost(hostname, default_arachni_host.username, default_arachni_host.password, name) arachni_host_manager.create_arachni_host(arachni_host, sandbox_name) arachni_hosts.append(arachni_host)
68
B. Soubor penetration_test.py # remove the first empty object arachni_hosts.remove(None) return arachni_hosts
# method which sends notification to user # that the test is completed def send_notification(smtp_server, smtp_username, smtp_password, from_address, to_address): message = "\r\n".join([ "From: " + smtp_username, "To: " + to_address, "Subject: KYPO: Penetration test for completed", "", "Penetration test for your application has completed." ]) try: server_ssl = smtplib.SMTP_SSL(smtp_server, 465) server_ssl.ehlo() server_ssl.login(smtp_username, smtp_password) server_ssl.sendmail(from_address, to_address, message) server_ssl.close() print "[*] Email successfully sent to " + \ to_address + " [*]" except: print "[!] Failed to send email to " + \ to_address + " [!]"
# main method def main(): # check the correct number of parameters if len(sys.argv[1:]) <= 1 : help() sys.exit(1) # definition of basic variables smn_username = ’’
69
B. Soubor penetration_test.py smn_password = ’’ port = 22 number_of_websites = ’’ sandbox_name = ’’ user_email = ’’ modules = ’’ smtp_server = SMTPServer("smtp.gmail.com", "[email protected]", "", "[email protected]") # parse command line options try: options = getopt.getopt(sys.argv[1:],"n:h:s:u:m:", ["number_of_websites", "help_manual", "sandbox_name", "user_email", "modules"])[0] except getopt.GetoptError as err: print str(err) help() sys.exit(1) try: verify_options = [None] verify_options.append(options[1][0]) verify_options.append(options[1][0]) verify_options.append(options[2][0]) if ’-n’ not in verify_options and ’-u’ not \ in verify_options \ and ’-s’ not in verify_options: help() sys.exit(1) except: help() sys.exit(1) # initialize arguments for option in options: if option[0] in ’-h’: help()
70
B. Soubor penetration_test.py sys.exit(1) elif option[0] in ’-u’: user_email = option[1] if not validate_user_email(user_email): print "[-] User email has invalid format! " \ "The general" \ " format should be used: " \ "[email protected] [-]" print "\n" help() sys.exit(1) elif option[0] in ’-m’: modules = option[1] elif option[0] in ’-n’: number_of_websites = option[1] if not int_try_parse(number_of_websites): print "[!] Number cannot be parsed [!]" print "\n" help() sys.exit(1) if (int(number_of_websites) < 1) or \ (int(number_of_websites) > 99): print "[!] Incorrect number range! Insert " \ "number 1-99 [!]\n" help() sys.exit(1) elif option[0] in ’-s’: sandbox_name = option[1] else: print "[!] The option does not exist [!]" print "\n" help() sys.exit(1) print "[*] Initialization of subjects to test [*]" # check if user already exists if not create a new user pentester_manager = PentesterManager(s) pentester = pentester_manager\ .get_pentester_byemail(user_email)
71
B. Soubor penetration_test.py if not pentester: pentester = Pentester(user_email) pentester_manager.create_pentester(pentester) #pentester_id = pentester.id # generate websites which should be tested testing_subjects = \ generate_testing_subjects(number_of_websites, pentester.id) # clear terminal window sys.stderr.write("\x1b[2J\x1b[H") # check if sandbox already exists if not create a new sandbox if not sandbox_manager.get_sandbox_ip(sandbox_name): print "[*] Sandbox is being initiliazed [*]" sandbox_manager.create_sandbox(sandbox_name) print "[+] Sandbox initialization is complete [+]" else: print "[*] Sandbox is already initialized [*]" # get IP adress of SMN host smn_host = sandbox_manager.get_sandbox_ip(sandbox_name) print "[*] Arachni hosts are being prepared [*]" # generate arachni hosts arachni_hosts = generate_arachni_hosts(number_of_websites, sandbox_name) # establish connection to SMN smn_client = establish_smn_connection(smn_host, port, smn_username, smn_password) # create empty list for arachni connections arachni_clients = [None] # setup queue for multi threaded operations q = Queue.Queue()
72
B. Soubor penetration_test.py # establish connection to all arachni hosts for x in range(0, len(arachni_hosts)): arachni_client = establish_arachni_connection(smn_client, smn_host, arachni_hosts[x], port) arachni_clients.append(arachni_client) # insert arachni client to the queue q.put(arachni_client) # remove redundant None option arachni_clients.remove(None) # perform penetration test for x in range (0, len(arachni_clients)): # establish multiple threads t = threading.Thread(target=perform_test, args=(arachni_clients[x], testing_subjects[x], smn_client, smn_host, port, smtp_server, pentester, modules, q,)) t.daemon = True t.start() # wait until all theads complete their job q.join() # delete arachni hosts for x in range(0, len(arachni_hosts)): arachni_host_manager.delete_arachni_host(arachni_hosts[x]) # check if there is active arachni host, # if not delete sandbox if not arachni_host_manager\ .get_arachni_host_username("pentester"):
73
B. Soubor penetration_test.py sandbox_manager.delete_sandbox(sandbox_name) print "[+] Sandbox was deleted [+]" else: print "[!] Sandbox cannot be deleted. Active " \ "Arachni hosts found [!]"
if __name__ == ’__main__’: main()
74
C Výsledná zpráva skeneru Arachni (lp0 V\u000a p1 aV\u000a p2 aV======================================================= p3 aV\u000a p4 aV\u000a p5 aV[+] Web Application Security Report - Arachni Framework\u000a p6 aV\u000a p7 aV[~] Report generated on: 2016-05-25 02:05:17 -0400\u000a p8 aV[~] Report false positives at: http://github.com/Arachni/arachni/issues\u000a p9 aV\u000a p10 aV[+] System settings:\u000a p11 aV[~] ---------------\u000a p12 aV[~] Version: 1.4\u000a p13 aV[~] Audit started on: 2016-05-25 01:56:26 -0400\u000a p14 aV[~] Audit finished on: 2016-05-25 02:05:14 -0400\u000a p15 aV[~] Runtime: 00:08:48\u000a p16 aV\u000a
75
C. Výsledná zpráva skeneru Arachni p17 aV[~] URL: http://kypotesting.com/\u000a p18 aV[~] User agent: Arachni/v1.4\u000a p19 aV\u000a p20 aV[*] Audited elements: \u000a p21 aV[~] * Links\u000a p22 aV[~] * Forms\u000a p23 aV[~] * Cookies\u000a p24 aV[~] * XMLs\u000a p25 aV[~] * JSONs\u000a p26 aV[~] * UI inputs\u000a p27 aV[~] * UI forms\u000a p28 aV\u000a p29 aV[*] Checks: xss\u000a p30 aV\u000a p31 aV[~] ===========================\u000a p32 aV\u000a p33 aV[+] 0 issues were detected.\u000a p34 aV\u000a p35 aV\u000a p36 aV[+] Plugin data:\u000a
76
C. Výsledná zpráva skeneru Arachni p37 aV[~] ---------------\u000a p38 aV\u000a p39 aV\u000a p40 aV[*] Health map\u000a p41 aV[~] ~~~~~~~~~~~~~~\u000a p42 aV[~] Description: Generates a simple list of safe/unsafe URLs.\u000a p43 aV\u000a p44 aV[~] Legend:\u000a p45 aV[+] No issues\u000a p46 aV[-] Has issues\u000a p47 aV\u000a p48 aV[+] http://kypotesting.com/\u000a p49 aV[+] http://kypotesting.com/About-Me.aspx\u000a p50 aV[+] http://kypotesting.com/Admin/\u000a p51 aV[+] http://kypotesting.com/CMSPages/Dialogs/ CaptchaImage.aspx\u000a p52 aV[+] http://kypotesting.com/CMSPages/GetResource.ashx\u000a p53 aV[+] http://kypotesting.com/Forums.aspx\u000a p54 aV[+] http://kypotesting.com/My-Blog.aspx\u000a p55 aV[+] http://kypotesting.com/My-Blog/July-2008.aspx\u000a
77
C. Výsledná zpráva skeneru Arachni p56 aV[+] http://kypotesting.com/My-Blog/July-2008/Paris, -France.aspx\u000a p57 aV[+] http://kypotesting.com/My-Blog/June-2008.aspx\u000a p58 aV[+] http://kypotesting.com/My-Blog/June-2008/Graz, -Austria.aspx\u000a p59 aV[+] http://kypotesting.com/My-Blog/June-2008/Ljubljana, -Slovenia.aspx\u000a p60 aV[+] http://kypotesting.com/My-Blog/June-2008/Madrid, -Spain.aspx\u000a p61 aV[+] http://kypotesting.com/My-Blog/June-2008/Montpellier, -France.aspx\u000a p62 aV[+] http://kypotesting.com/My-Blog/June-2008/Trieste, -Italy.aspx\u000a p63 aV[+] http://kypotesting.com/My-Blog/June-2008/Vienna, -Austria.aspx\u000a p64 aV[+] http://kypotesting.com/Photo-Gallery.aspx\u000a p65 aV[+] http://kypotesting.com/ScriptResource.axd\u000a p66 aV[+] http://kypotesting.com/Special-pages/ Logon-page.aspx\u000a p67 aV[+] http://kypotesting.com/Special-pages/My-account/ My-profile.aspx\u000a p68 aV[+] http://kypotesting.com/Special-pages/Search.aspx\u000a p69 aV[+] http://kypotesting.com/favicon.ico\u000a p70 aV[+] http://kypotesting.com/getattachment /04da942a-c89d-4bc4-ba32-7db2b1201e44
78
C. Výsledná zpráva skeneru Arachni /Sweet-Home-Arizona.aspx\u000a p71 aV[+] http://kypotesting.com/getattachment /151be78a-661f-42b3-9e81-7fc3ac874fba/Berlin,-Germany.aspx\u000a p72 aV[+] http://kypotesting.com/getattachment /1c53d7a7-28ca-43da-8a2e-f8e89a12a932/European-Trip.aspx\u000a p73 aV[+] http://kypotesting.com/getattachment /2aa6156d-b4c9-41e1-a299-fef4533375f9/Budapest,-Hungary.aspx\u000a p74 aV[+] http://kypotesting.com/getattachment /3fcdba38-4e6a-4cf1-822d-0c6860388f7f/Madrid,-Spain.aspx\u000a p75 aV[+] http://kypotesting.com/getattachment /44959c64-f09a-481c-943c-313914b270a4/Trieste,-Italy.aspx\u000a p76 aV[+] http://kypotesting.com/getattachment /5b91adf6-195a-46c8-a297-42334a2b1487/Montpellier, -France.aspx\u000a p77 aV[+] http://kypotesting.com/getattachment /663dfed9-ff80-46a1-9f07-c676ed9359c9/Graz,-Austria.aspx\u000a p78 aV[+] http://kypotesting.com/getattachment /78711f7c-8f69-431a-aec6-ea5320140222/Vienna,-Austria.aspx\u000a p79 aV[+] http://kypotesting.com/getattachment /9f87727b-74ae-4f98-ae0c-8dd54d8d767a/Ljubljana, -Slovenia.aspx\u000a p80 aV[+] http://kypotesting.com/getattachment /a89c1087-25da-4a10-b466-e0e5bfac6460/Paris,-France.aspx\u000a p81 aV[+] http://kypotesting.com/getattachment /c2f3dc49-18df-4b10-809c-95847d36ae21/Prague, -Czech-Republic.aspx\u000a p82 aV[+] http://kypotesting.com/getattachment /d40164b0-7839-4839-bee1-7667e50b2e4b/prague.aspx\u000a
79
C. Výsledná zpráva skeneru Arachni p83 aV\u000a p84 aV[~] Total: 35\u000a p85 aV[+] Without issues: 35\u000a p86 aV[-] With issues: 0 ( 0% )\u000a p87 a.
80
D Seznam elektronických příloh Archivní balíček elektronicke_prilohy.zip je umístěný v archivu závěrečné práce v IS MU a obsahuje následující elektronické přílohy: ∙
arachni_report.txt - výsledná zpráva skeneru Arachni
∙
check_list.txt - přehled dostupných zranitelností pro otestování
∙
penetration_test.py - skript pro penetrační testování
∙
penetration_test_version2.py - skript pro penetrační testování, verze bez pivot serveru
∙
penetration_machine_config.sh - konfigurační soubor pro stroj penetračního testera
∙
sandbox_configuration.json - konfigurační soubor pro vytvoření sandboxu v KYPO
∙
sandbox_configuration_version2.json - konfigurační soubor pro vytvoření sandboxu v KYPO, verze bez pivot servervu
81