Non-HTTP POSTing

Zdroj: SOOM.cz [ISSN 1804-7270]
Autor: Harvie
Datum: 29.6.2007
Hodnocení/Hlasovalo: 1.65/23

V tomto článku jsem si pro vás připravil jednoduchou ukázku toho, jak může být nebezpečné, pokud váš prohlížeč umožňuje spojení na server na libovolném portu.

(aneb fake-maily prohlížečem ;))

V tomto článku jsem si pro vás připravil jednoduchou ukázku toho, jak může být nebezpečné, pokud váš prohlížeč umožňuje spojení na server na libovolném portu.

Úvod

Podstata celé napadnutelnosti prohlížeče spočívá v tom, že prakticky každý prohlížeč se umí pomocí odkazu (nebo formuláře) připojit na libovolný server, na (teoreticky) libovolný port. A odeslat službě na daném portu libovolná data (ano, pár omezení tu je). Ovšem, že pro poměrně dost protokolů nám to stačí, teď nám tedy stačí vytvořit takový formulář, který nám dovolí odeslat z klientova počítače libovolná data na požadovaný server. Před tím ale musíme vědět pár základních věcí.

Pokud tedy například máme odkaz na adresu http://localhost:25/, můžeme se připojit na server (v našem případě localhost) na portu 25 (běžně služba SMTP). Tím celá záležitost ještě vůbec nekončí. Takovýto odkaz nám sice naváže spojení a odešle GET + pár informací o požadované stránce a našem prohlížeči, s tím se ale jentak nespokojím. My tedy použijeme metodu POST, která nám umožní, spolu se správným kódováním, určit přesný obsah několika řádek v HTTP požadavku odeslaném na server.

Zmanipulovatelné služby

Tato chyba v prohlížeči nám umožní komunikovat s jinou službou (SMTP, IRC, TELNET, FTP, POP3,...), aby bylo možné na službu odeslat patřičný požadavek, je nutné aby používaný protokol splňoval několik požadavků. V první řadě by mělo jít o textově orientovaný protokol (co řádka, to příkaz), dále by měl server ignorovat neznámé příkazy (např. v našem případě HTTP Požadavek na začátku). Také je nutné, aby služba stihla vyřídit požadavek dříve, než prohlížeč s hláškou "Vypršel čas spojení." ukončí spojení. Samozřejmě musíme znát protokol dané služby (např. v našem případě jde o SMTP).

Napadnutelnost různých klientů

Pokud jde o prohlížeče (HTTP klienty), dalo by se říci, že jsem konzervativní, protože se omezuji na Firefox (+/- aktuální), IE (to co mám předinstalované - používám ho, pouze pro zajištění minimální funkčnosti mých css v IE) a PHP (zkoušel jsem funkce readfile() a include()) a uživatelům ostatních prohlížečů/klientů se tímto omlouvám (kliknutím zde otestujte svůj prohlížeč). Všechny tyto možnosti jsem vyzkoušel a test dopadl s tímto výsledkem:
- IE 6 - Plně napadnutelný
- Firefox 2 - Zabezpečený
- PHP (fopen()) - Prakticky bezpečný
Jak jsem testloval:
K testování jsem použil NetCat naslouchající na portu 26 (na 25 mi již běží virtuální SMTP server Avast!u na kontrolu odchozí pošty - v ostatních případech můžeme použít neobsazený port 25). Takže si ho můžeme spustit (nc -L -p 25), tento příkaz způsobí, že budou přijata všechna spojení na localhost:25 a na obrazovku budou vypsána přijatá data. Pokud ale bute chtít být přehnanými realisty, můžete si na svůj počítač nahodit SMTP server (pro Windows doporučuji "1st SMTP server", nebo "Mini SMTP Relay", které pro podobné účely plně postačují, v Linuxu potom šáhneme po prvním SMTPd, který najdeme na instalačce našeho distra...)

Firefox:
Pokus o napadnutí FF se základním nastavením pravděpodobně skončí podobnou hláškou:
Omezení přístupu na port
Tato adresa obsahuje číslo portu, které je obvykle používáno k jiným účelům než prohlížení webových stránek. Z bezpečnostních důvodů Firefox tento požadavek zrušil.


PHP:
Funkce FOpen() z PHP se dokáže připojit na libovolný server a odeslat mu podobná data:
GET /cokoliv HTTP/1.0
Host: localhost:25
To je pro naše účely ale prakticky nepoužitelné, pokud by nám šlo čistě pouze o otevření spojení, můžeme tedy například využít chybu RFI (nebo jinak méně nebezpečnou Remote Readfile) v napadnutelném webu.

Internet Explorer 6:
Ano, "Král mezi zneužitelnými prohlížeči, dokonalá zombie s největším počtem napadených systémů, vychytaný spambot", jedině tak bych IE označil po svém testu. K jeho bezpečnosti snad není co dodat, kromě toho, že vše, co je zmíněné níže v něm funguje naprosto bezchybně.

Kódování POSTu

V parametru "enctype", který se nastavuje elementu "form": enctype="multipart/form-data". Tím zajistíme, že se naše řádky pošlou tak, jak jsme je napsali, jinak by došlo k (decimálnímu urlzakódování), které by vypadalo asi takto:

Content-Length: 297
text=%0D%0AHELO%0D%0AMAIL+FROM%3A%3Cpresident@whiteh0use.com%3E%0D% 0ARCPT+TO%3A%3Cregistration@pr0nserv.com%3E%0D%0ADATA%0D%0ASubject% 3A+test+message%0D%0AFrom%3A+president@whiteh0use.com%0D%0ATo%3A+re gistration@pr0nserv.com%0D%0A%0D%0AHello%2C%0D%0AThis+is+a+test.%0D %0AGoodbye.%0D%0A.%0D%0AQUIT%0D%0A%0D%0A


My místo toho ale použijeme výše zmíněné kódování, které pošle náš text přesně tak, jak je. Kromě toho toto kódování je rychlejší (co se týče algoritmu i linky), protože si lépe poradí s binárními daty, díky tomu se používá například pro upload souborů na server.

Praxe

Celé si to ukážeme na již zmíněném protokolu SMTP. Vytvoříme si tedy jednoduchou stránku, která dokáže pomocí formuláře (naprosto bez asistence webového serveru) odeslat email.
Naše stránka může vypadat tedy například takto (použil jsem upravený příklad SMTP komunikace z Wikipedie):

Prohlížeč (klient) potom zašle na server podobná data:

Neznámé příkazy budou většinou SMTP serverů ignorovány (Zpracují se tedy pouze SMTP příkazy, nikoli HTTP). Protože příkaz QUIT donutí server ukončit spojení, řádky za ním jsou již také ignorovány.

Další náměty

Pro ty, kdo ještě pořád nepochopili, proč se mají bát: Kdo slyšel o CSRF, JavaScriptu. PHP a třeba XSS Proxy, jistě si dokáže představit, jak si na tomto například založit takřka nevystopovatelný spamovací systém (vzhledem k rozšíření IE). PHP dodává emailové adresy a adresy SMTP serverů z databáze. Javascript z nich dává dohromady požadavky a odesílá formuláře (rychlostí 1-2 emaily za sekundu na iframe). A nějaký CSRF Trik to vše ukryje do jednoho iframu, ve kterém bude například 10 dalších, které budou odesílat maily, jednou za sekundu se celý tento iframe i se všemi 10ti vnořenými refreshne metatagem, nebo javascriptem. A o možném využití AJAXu ani nemluvím. V případě, že by nešlo pouze o testování a anonymní mailování, ale vysloveně o spamování (což je v našem státě nezákonné), mohl by spam obsahovat další iframy (což nebude tak snadné) a způsobit tak vidlicovité šíření spamu (Fork Spam).

Samozřejmě by se to celé mohlo pomocí javascriptu šířit po internetu jako různí weboví wormové, nebo vyhledávat emailové adresy a volné smtp servery. ve stylu scaneru jikto.

Každý, kdo ví, jak nakonfigurovat NetCat jako backdoor, si také jistě dovede představit, jak pomocí podobné techniky ovládat celý počítač pomocí prohlížeče (ale na to máme již lepší řešení).

Tyto "triky" již raději názorně ukazovat nebudu...

Obrana

Uživatel
Pokud jsme obyčejný uživatel, musíme používat webový prohlížeč, který je pro nás po této stránce bezpečný, jako například Firefox (a doufám, že není jediný), který omezuje možnost spojení jen na porty standartně používané webservery. Samozřejmě musíme tak dávat pozor na to, jaké stránky navštěvujeme a vůbec na jaké odkazy na stránkách a v mailech klikáme.

Vývojář, Admin:
Pokud programujeme servery, nebo dokonce navrhujeme nové protokoly, je dobré mít jasno v tom, jestli je opravdu nutné ignorovat neznámé příkazy. Také můžeme nekompromisně ukončit spojení v případě, že nám klient pošle některé klíčové slovo, které se běžně vyskytuje v hlavičce HTTP požadavku (např. GET, POST,...). Další věcí je správný výběr portů, na kterých bude naše služba (podle protokolu) naslouchat, to se netýká pouze programátorů síťových aplikací, každý kdo na svůj počítač podobnou službu instaluje, může si vybrat libovolný port, měli bysme se proto mít alespoň minimálně napozoru, i když varování ze strany programu by také nebylo naškodu...

Další informace

(Doplňující, rozšiřující, nebo podobné články)

Soom:
Útoky CSRF aneb trojské koně na webu (.cCuMiNn.)
FTP Bounce --> 1. část 2. část (Genua)

Ostatní:
SP - Jikto
IANA - Port Numbers
IANA - Mime types (encoding)

Uncle Google:
XSS Proxy