Paweł Goleń, blog

Tytuł tego wpisu jest celowo mylący, wcale nie mam zamiaru debatować. Chcę natomiast odnieść się do tego komentarza. Adam napisał:

Nie rozumiem ludzi którzy korzystają z takich bajerów jak zapamiętywanie haseł za pośrednictwem programów czy serwerów, kiedy wystarczy sobie napisać własną funkcję i miksować 1 hasło przez url + md5, base64 itd, a na koniec np ucinać do 10 znaków i w 2ga stronę nie jest to możliwe do odtworzenia w praktyce.

Różnica między KeePass a opisanym przez Adama podejście jest taka, że hasło generowane przez KeePass jest losowe (właściwie: może być losowe, jeśli użytkownik sobie takie wygeneruje), natomiast hasło uzyskiwane w wyniku opisanej metody jest “wyprowadzane” na podstawie kilku danych wejściowych. Jeśli ktoś będzie w stanie odgadnąć “hasło główne” oraz ustalić sposób “wyliczania” hasła “docelowego”, będzie w stanie uzyskać hasło dla dowolnej strony. Mamy tutaj security through obscurity (tajny sposób “wyliczania” hasła) oraz swoisty class break. Co z tego wynika? Nic.

Czytaj dalej...

Głębokie ukrycie doczekało się wpisu na Wikipedii. I wszystko byłoby w porządku, gdyby nie ten przykład:

http://example.com/29d9283aba927109a289b03812738d89201/2873944786672/10284.pdf

Wydaje mi się, że na temat trzeba spojrzeć nieco z szerszej perspektywy. A przy okazji – moim zdaniem głębokie ukrycie nie do końca zasługuje na oddzielny wpis w Wikipedii. Na dobrą sprawę jest to pewna forma security through obscurity, która w dodatku, w pewnych przypadkach i do pewnego czasu, działa.

Czytaj dalej...

Pokazanie przykładów niewłaściwego encodingu mamy za sobą (patrz: #1, #2, #3, #4 i #5). Na koniec przykład: http://bootcamp.threats.pl/lesson09b/, w którym encoding jest realizowany za pośrednictwem ESAPI (konkretnie owasp-esapi-php, jest to jeszcze wersja nieprodukcyjna). Dane wpisane przez użytkownika wypisywane są w trzech miejscach, w których encodowane są przy pomocy funkcji:

Funkcja doStuff obecnie coś robi, konkretnie wypisuje wartość otrzymanego parametru w drugim textarea. Zrobiłem to po to, by każdy mógł się przekonać, że te dziwne znaczki, które generuje ESAPI to rzeczywiście to, co zostało oryginalnie przekazane. A te dziwne znaczki wyglądają tak:

Dla encodeForJavaScript w kontekście atrybutu HTML:

demo 1

Dla encodeForJavaScript i encodeForHTMLAttribute w kontekście atrybutu HTML:

demo 2

Jeszcze raz dla encodeForJavaScript , tym razem w kontekście skryptu:

Mam nadzieję, że ten przykład wystarczająco dobrze pokazuje, że:

  • encoding może być prosty, wystarczy wywołać odpowiednią dla kontekstu funkcję,
  • encoding może być skuteczny (ktoś potrafi obejść encoding implementowany przez ESAPI i wykorzystany w tym przykładzie?),
  • mimo encodingu wszystko może nadal działać,

I tym optymistycznym akcentem kończę ten temat. Przynajmniej na jakiś czas.

Oryginał tego wpisu dostępny jest pod adresem Encoding: ESAPI

Autor: Paweł Goleń

Pora na zakończenie tematu przykładu z niewłaściwym encodingiem (patrz: #1, #2, #3 i #4). Ponownie, by nie przeciągać, dla tradycyjnego zestawu znaków testowych otrzymujemy:

Czy można tu coś zepsuć?

Czytaj dalej...

Tego odcinka mogłoby właściwie nie być. W tym przypadku sytuacja jest praktycznie taka sama, jak w poprzednim przykładzie. Dobrze to widać poniżej:

?@[\]^_{|}~')">demo 3</a><br /> <a href="#" onclick="javascript:doStuff('!\"#$%25&\'()*+,-.\/:;<=>?@[\\]^_{|}~')“>demo 4

Jedyna różnica pojawia się przy znaku /, który w drugim przypadku zyskuje postać \/. Czy ma to jakieś znaczenie w tym konkretnym kontekście? Może w pewnym, niewielkim stopniu ma, ale przed XSS nie chroni, przykład:

“><foo bar=”

Różnica w stosunku do poprzedniego przykładu sprowadza się do tego, że w tym przypadku nie jestem w stanie uzyskać tagu:

ponieważ funkcja escapowania znaków spowoduje jego przekształcenie do postaci:

<\/script>

Użycie String.fromCharCode natomiast obchodzi drobną niedogodność związaną z brakiem znaków ', “ oraz / dostępnych w “czystej” postaci. Jak widać całkiem dobrze można sobie poradzić bez nich.

Oryginał tego wpisu dostępny jest pod adresem Niewłaściwy encoding #4

Autor: Paweł Goleń

Raz, dwa, trzy (to teraz). To make long story short:

?@[\]^_`{|}~')“>demo 3

Co jest tu nie tak? Cóż, przykładowy payload, czyli:

'+alert(/xss/)+'

w tym przypadku nie zadziała, będzie rezultat w kodzie strony będzie wyglądał tak:

demo 3

Jak widać znak ' jest wypisywany jako \', co jest właściwym sposobem escapingu tego znaku. Podobnie zresztą jak \\\\” jest właściwym sposobem escapingu znaku “, uwaga, w JavaScript. Problem tylko w tym, że nie jesteśmy (wyłącznie) w kontekście JavaScript, ale również w kontekście atrybutu HTML. A skoro tak, to:

“><foo bar=”

da w rezultacie:

demo 3

Zagmatwane? Przeglądarka zobaczy to tak (IE i Firefox):

Poprzednio okazało się, że encoding HTML w kontekście atrybutu HTML, który zawiera JavaScript, nie jest zbyt skuteczny. Tak samo encoding właściwy dla JavaScript stosowany w przypadku JavaScript, który zawarty jest w atrybucie HTML, nie jest wystarczający. Zupełnie inaczej sytuacja wyglądałaby, gdyby złożyć ze sobą te dwa sposoby kodowania znaków. Najpierw dane wstawiane do kontekstu JavaScript zabezpieczyć w sposób właściwy dla JavaScript właśnie, a potem, skoro trafiają do atrybutu HTML, całość zakodować w sposób właściwy dla tego kontekstu. Wyglądałoby to mniej więcej tak:

demo 3

Jak zobaczy to przeglądarka – do sprawdzenia we własnym zakresie :)

Oryginał tego wpisu dostępny jest pod adresem Niewłaściwy encoding #3

Autor: Paweł Goleń

Po pierwszym przykładzie niewłaściwego encodingu, pora na drugi. Dla analogicznego jak w pierwszym przypadku zestawu znaków:

!“#$%25&'()*+,–./:;<=>?@[]^_`{|}~

na wyjściu otrzymuje się:

demo 2

Jak łatwo zauważyć, jedyną różnicą w stosunku do poprzedniego przypadku jest dodatkowe kodowanie znaku “. Dobrze to widać, jeśli oba przypadki zestawi się ze sobą:

demo 1
demo 2

Można się domyślić, że problemu z XSS w tym kontekście ta zmiana raczej nie rozwiązuje.

Czytaj dalej...

Pierwsze wyjaśnienie odnośnie ćwiczeń z nieprawidłowego encodingu. Na pierwszy ogień pójdzie pierwsze miejsce, w którym wprowadzone dane są wypisywane. Jako string testowy wykorzystam następujący zestaw znaków:

!“#$%25&'()*+,–./:;<=>?@[]^_`{|}~

Na wyjściu natomiast dostaje się coś takiego:

demo 1

Jak widać, specjalnie traktowane są tylko nieliczne znaki, które są przekształcane w następujący sposób:

& –> & < –> < > –> >

Byłoby to zabezpieczenie wystarczające, gdyby dane te były wypisywane w kontekście HTML. Problem w tym, że nie są. Są wypisywane w kontekście atrybutu HTML, który, tak się dodatkowo składa, zawiera kod JavaScript.

Czytaj dalej...

Pod adresem http://bootcamp.threats.pl/lesson09a/ znajduje się prosty przykład “aplikacji”, która nie do końca poprawnie stosuje encoding danych wyjściowych. Przekazane dane są wypisywane w kilku miejscach, w różnym kontekście z wykorzystaniem różnego encodingu. Każdy z zastosowanych sposobów encodingu danych pozwala na XSS (na różne sposoby), choć nie w każdym(?) kontekście.

To tak w nawiązaniu do tego, że właściwy encoding jest trudny. W przeciwieństwie do encodingu, ten przykład trudny specjalnie nie jest. Miłej zabawy!

P.S. W zasadzie można się zastanawiać, czy i w którym przypadku stosowany jest encoding, a w którym escaping.

Oryginał tego wpisu dostępny jest pod adresem Ćwiczenia z niewłaściwego encodingu

Autor: Paweł Goleń

Gmail zaczął witać swoich użytkowników w następujący sposób:

O tym, że warto mieć unikalne hasła w różnych serwisach mówi się zwykle wówczas, gdy pojawia się jakaś informacja o możliwym wycieku danych użytkowników (w szczególności haseł lub stosunkowo łatwych do złamania hashy) z jakiegoś bardziej lub mniej popularnego serwisu. Zastanawiam się jakie są efekty takich dyskusji i jaki będzie efekt informacji wyświetlanej w Gmailu.

Ja tylko po raz kolejny podpowiem, że do przechowywania haseł i do generowania unikalnych haseł do różnych serwisów można wykorzystać na przykład KeePass. O tym, jak z niego korzystam pisałem tutaj: Jak korzystam z KeePass.

Oryginał tego wpisu dostępny jest pod adresem A czy Ty już zmieniłeś swoje hasło?

Autor: Paweł Goleń