13:49
23/9/2013

Jest możliwe odczytanie wystąpienia zdarzenia “zawinięcia” tekstu umieszczonego wewnątrz tagu iframe i na tej podstawie wywnioskowanie, z jakich słów tekst się składa. Atak na pewno nie jest szybkim i łatwym sposobem na wykradanie treści z iframe’ów, ale ciekawie obrazuje ataki typu side-channel.

Jak wykryć zawinięcie tekstu w iframe?

Na swojej stronie atakujący, w ramce (iframe), osadzić może dowolną zawartość pochodzącą z innej domeny (o ile domena ta pozwala na “ramkowanie”, czyli nie ma ustawionego nagłówka X-Frame-Options zabezpieczającego przed clickjackingiem).

Jeśli atakujący osadzi w ramce taką stronę, na której ofiara ma konto, ofiara zobaczy w ramce tę stronę wyświetloną w swoim kontekście (dobrym przykładem są np. strony profilowe, bo każdemu z nas wyświetlają się one inaczej — zawierają nasze dane, por. https://www.google.com/settings/account).

Atakujący z poziomu swojej strony co prawda nie jest w stanie odczytać tekstu z iframe’a (nie pozwala na to Same Origin Policy). Może on jednak wykryć, że tekst w iframe został zawinięty do następnej linii. Jak? Otóż atakujący może zmniejszać/zwiększać wysokość i szerokość ramki, a także wykrywać obecność pasków przesuwania oraz — przekierować kolejnego iframe’a wewnątrz osadzanego przez nas iframe’a na inną domenę (w szczególności tę, którą sami kontrolujemy).

Wizualizacja zawijanego tekstu i rozmiaru iframe'a

Wizualizacja zawijanego tekstu i rozmiaru iframe’a

To, że tekst się zawinął można wykryć poprzez:

  • Wykrycie obecności pasków przewijania poprzez przypisanie im własnego stylu CSS. Kiedy zmniejszymy okno iframe’a tak, że tekst się “zawinie”, pojawi się pasek, co wykryjemy poprzez request przeglądarki sięgający po tło paska, zdefiniowane w CSS, a wskazujące na naszą domenę.
  • Jeśli zagnieżdżana przez nas strona ma sama w sobie zagnieżdżonego iframe’a, to zawinięcie odczytamy poprzez odczytanie pozycji iframe’a zagnieżdzonego w zagnieżdżanym iframe. Działa na przeglądarkach opartych na silnikach Trindent poprzez dostęp do window.screenTop a w Gecko do window.mozInnerScreenY po uprzednim przekierowaniu zagnieżdżonego iframe’a na swoją domenę.

Przykłady implementacji można przetestować na stronie Eduardo Veli, który jest pomysłodawcą tego ataku.

Sama wiedza, że tekst się “zawinął” jednak nie wystarczy — spróbujmy zatem domyślić się jak wyglądał zawinięty tekst.

Co zwiera zawinięty tekst?

Aby zmierzyć ile pikseli zajmuje na ekranie “zawinięte” słowo, należy ustawić szerokość poprzez width: na 999999 px, a wysokość na “smallest-without-scrollbar”, a następnie powoli zmniejszać szerokość do momentu pojawienia się scrollbara. Po pojawieniu się scrollbara należy zwiększyć wysokość (aby znów zniknął).

Korzystając z tego, że wiemy w jakim fontem wypisany jest ramkowany tekst, oraz ile pikseli ma każda litera, możemy

  • a. sporządzić słownik w postaci (słowo, długość). Następnie “zawijane” słowa weryfikujemy pod kątem słownika. To prawda, że czasem mogą wyjść duplikaty, ale mając kilka propozycji słów, na każdej pozycji, można generować różne zdania i weryfikować, czy “mają one sens”.
  • b. odczytać jakie potencjalnie litery (ich szerokości) sumują się do szerokości “zawiniętego” słowa. Nie znamy kolejności liter, ale możemy permutować ich zbiór i sprawdzać pod katem poprawności (“czy istnieje takie słowo?”).

Teraz najważniejsze pytanie — czy znacie jakieś ciekawe strony, które da się “zramkować”, a które mogą zwierać interesujące dane w przewidywalnym miejscu w tekście?

Ochrona przed “wykradaniem” tekstu z ramki

Nie ma dobrego rozwiązania tego problemu. Atak utrudnia jednak zarówno X-Frame-Options, jak i zdefiniowana na sztywno szerokość tekstu w CSS (brak tzw. “overflowa”) — niestety nie na każdej stronie zastosowanie tych rozwiązań będzie możliwe…

Gdybyś chciał poznać inne ciekawe ataki na webaplikacje, zapraszamy na nasze szkolenia z Ataku i Ochrony Webaplikacji — na najbliższy termin w Warszawie zostało ostatnie wolne miejsce, ale otworzyliśmy już kolejny termin w Krakowie, 24-25 października, gdzie jest jeszcze kilka wolnych miejsc…

Zaawansowanym programistom HTML5 polecamy nasze warsztaty z HTML5 Hackingu — najbliższy termin to 17-18 października, w Krakowie.


Dowiedz się, jak zabezpieczyć swoje dane i pieniądze przed cyberprzestępcami. Wpadnij na nasz kultowy ~3 godzinny wykład pt. "Jak nie dać się zhackować?" i poznaj kilkadziesiąt praktycznych i przede wszystkim prostych do zastosowania porad, które skutecznie podniosą Twoje bezpieczeństwo i pomogą ochronić przed atakami Twoich najbliższych. Uczestnicy tego wykładu oceniają go na: 9,34/10!

Na ten wykład powinien przyjść każdy, kto korzysta z internetu na smartfonie lub komputerze, prywatnie albo służbowo. Wykład prowadzimy prostym językiem, wiec zrozumie go każdy, także osoby spoza branży IT. Dlatego na wykład możesz spokojnie przyjść ze swoimi rodzicami lub mniej technicznymih znajomych. W najbliższych tygodniach będziemy w poniższych miastach:

Zobacz pełen opis wykładu klikając tutaj lub kup bilet na wykład klikając tu.

23 komentarzy

Dodaj komentarz
  1. Już widzę to morze spanikowanych web-designerów, którzy na wieść o tym ataku pozmieniaja wszystkie fonty na monospace ;)

    Internecie! drżyj. :P

    • Nie muszą zmieniać wszystkich, wystarczą te newralgiczne dane.

  2. Niezły hardcore. Coś w stylu: Jeśli wepchniesz w rurę wydechową samochodu drut, to odpowiednio manewrując możesz wykręcić świecę a to już tylko krok do otwarcia maski :)

    • Dokładnie. Już widzę te ramki fruwajace w te i we te po to
      żeby… Przeczytać twitta :-). Interesujące rzeczy i tak nie
      powinny być widoczne bez interakcji i właśnie kwestia interakcji
      jest ważniejsza w wypadku dostępu do ramek. Chyba trochę redakcja
      przesadziła tym razem. Poza tym wystarczy, że jeden blok na stronie
      ma stałą szerokość (a zwykle któryś ma) i cały misterny plan…
      ;-)

    • @Nux To ze ty nie jestes w stanie wyobrazic sobie usecase
      dla tego ataku nie czyni go mniej groznym. Atak mozna ukryc przed
      ofiara, korzystajac z tego samego triku jak przy clickjackingu, css
      visibility lub opacity.

  3. “Działa na przeglądarkach opartych na silnikach Trindent…”
    Trident chyba powinno być ;)

    A sama metoda ciekawa, chociaż mocno czasochłonna i nie koniecznie mogąca dać dobre rezultaty. Dalej możemy wyciągnąć tylko sensowne słowa – haseł generowanych losowo nie wyciągniemy (a jeśli już, to tylko kombinacje znaków o ustalonej szerokości).

    Taka sztuka dla sztuki, jak podsłuchiwanie drukarek igłowych ;) Fajne, ale mało praktyczne

  4. Kiedyś to było hackowanie ! Wpisywało się hasło dupa i połowa serwisów stała otworem :)

  5. Wszystko pisać czcionką Courier New! :)

  6. Wspomniałem kiedys na jednym z for o tym ataku aczkolwiek z tego wzgledu ze jest czasochlonny wylali mi kubeł zimnej wody :)))

    • To jest swiezy atak, podaj linka do tego forum.

  7. > Zaawansowanym programistom HTML5 polecamy nasze warsztaty z HTML5 Hackingu

    > programistom HTML5

    O_O

    • Wygrałeś.

    • http://helion.pl/ksiazki/html5-programowanie-aplikacji-zachary-kessin,htm5pa.htm

      mało wiesz o html5 i mocy jaka posiada z rozwinięciami typu node.js ;)

    • node.js jako rozszerzenie HTML5. I ty innym opowiadasz, że mało wiedzą. Wyborne :D

    • HTML5 to nazwa szerszej technologii zawierającej w sobie CSS i JS, nazywanej czasem DHTML. Jak zwał, tak zwał, wiadomo (albo przynajmniej powinno być wiadomo) o co chodzi. O frontend, ale dlatego warto napisać HTML w znaczeniu ogólnym, bo nie frontend typu WinForms czy GTK, i nie sam JavaScript – bo JavaScript może napędzać różne frontendy, np XUL. Najlepszym narzędziem dla programisty HTML5 będzie JetBrains WebStorm, bo najlepiej obsługuje intergrację i refactoring frontentów używających HTML/CSS/JS.

      Dziś praktycznie nie ma gołego HTML-a nigdzie. A HTML w wersji 5 to dzisiejszy standard, dlatego nie mówimy o prehistorii. HTML bez skryptów to szablon, a nie kompletny produkt.

  8. Jest jeszcze jedna zmienna w tym wszystkim – margines. Co z tego, że tekst się mieści na np. 50px, jak niewiadomo ile jest marginesem,

    • ale to iframowanie nie leci na randomowe strony i randomowe
      textbloki tylko na wybrane przez ciebie więc jesteś w stanie
      sprawdzić ile ma margines na stronie np fejsbuka zanim
      zaimplementujesz zaimplementujesz na stronie

  9. “[…] jak rzekła młodziutka Cerro do króla Vridanka na ich pierwszej schadzce: <>”
    A. Sapkowski, “Pani Jeziora”

    • “[…] jak rzekła młodziutka Cerro do króla Vridanka na ich pierwszej schadzce: ”
      A. Sapkowski, “Pani Jeziora”

  10. Niebrzydka rzecz, ale czy ma jakieś zastosowanie praktyczne?

    PS. Co to za patent z ukrywaniem tekstu zawartego między znakami mniejszości/większości?

  11. paranoja

  12. Niechce mi się sprawdzać ale wydaje mi się że z poziomu css
    możemy dla elementów w iframe nadać własne atrybuty CSS i np tym
    sposobem ustalić spreparowaną czcionkę która ma dla każdej litery
    inną szerokość tak aby jak najbardziej zmniejszyć ilość wystąpienia
    duplikatów lub kilka różnych czcionek (+ kilka wywołań iframe)
    wycelowanych w konkretne litery tak aby z szerokości można było
    ustalić ile liter np R jest w danym słowie )

  13. a czy nie lepiej byłoby, żeby zrobić w screenshot co jakiś czas? jedynie haseł się tym nie przechwyci

Odpowiadasz na komentarz mnmnc

Kliknij tu, aby anulować

Zamieszczając komentarz akceptujesz regulamin dodawania komentarzy. Przez moderację nie przejdą: wycieczki osobiste, komentarze nie na temat, wulgaryzmy.

RSS dla komentarzy: