Preorder drugiego tomu książki sekuraka: Wprowadzenie do bezpieczeństwa IT. -15% z kodem: sekurak-book
Case study: błąd w wyrażeniu regularnym weryfikującym nazwę domeny w Google
W dzisiejszym odcinku z serii #vulnz omówimy ciekawy błąd znaleziony przez @xdavidhu (David Schütz) w pewnym wyrażeniu regularnym, które weryfikowało poprawność nazwy domeny w wielu usługach Google.
Wszystko zaczęło się od tego, że David natrafił na stronę pod następującym adresem URL:
https://console.developers.google.com/henhouse/?pb=["hh-0","gmail",null,[],"https://developers.google.com",null,[],null,"Create API key",0,null,[],false,false,null,null,null,null,false,null,false,false,null,null,null,null,null,"Quickstart",true,"Quickstart",null,null,false]
Dalej będziemy tę stronę nazywać henhouse (jak pierwsza część ścieżki). Strona ta była umieszczona w elemencie iframe w innej domenie. Była ona wykorzystywana do tego, by ramki rodzica wysłać wiadomość przez postMessage
z tokenem OAuth. Jak widać w adresie URL, jednym z parametrów jest nazwa domeny, do której token ma zostać wysłany (w powyższym przykładzie jest to https://developers.google.com
).
Henhouse podejmował decyzję, czy chce wysłać token OAuth do tej domeny, jej nazwę z adresu URL pewnym magicznym wyrażeniem regularnym, a następnie weryfikował, czy nazwa domeny kończy się na .corp.google.com
lub .c.googlers.com
lub jest to jedna z dopuszczonych domen na białej liście. Zobaczmy to na prostych przykładach:
- W parametrze podajemy URL:
https://abc.corp.google.com/test123
. Za pomocą regeksa wyciągana jest nazwa domeny (abc.corp.google.com
), która kończy się na.corp.google.com
więc do niej zostanie wysłany token OAuth. - W parametrze podajemy URL:
https://test123.c.googlers.com.pl#magic
. Nazwa domeny wyciągnięta regeksem totest123.c.googlers.com.pl
, która nie kończy się na żadną z oczekiwanych nazw, więc do niej token OAuth nie będzie wysłany.
Wyrażenie regularne wydobywające nazwę domeny z adresu URL wyglądało dość magicznie:
^(?:([^:/?#.]+):)?(?:\/\/(?:([^/?#]*)@)?([^/#?]*?)(?::([0-9]+))?(?=[/#?]|$))?([^?#]+)?(?:\?([^#]*))?(?:#([\s\S]*))?$
Aby lepiej je zrozumieć, David posłużył się narzędziem Debuggex (choć ja sam preferuję Regexper), które pozwala na rozrysowanie wyrażenie regularne do czytelniejszej formy (patrz: rysunek 1).
Na podstawie tak rozrysowanego regeksa, David zauważył, że wynika z niego, że znakami, które kończą nazwę domeny w adresie URL są: /
, ?
oraz #
. Jest to dość naturalny wniosek , bowiem w każdym z poniższych adresów URL, nazwą domeny jest sekurak.pl
:
https://sekurak.pl/test123
https://sekurak.pl?parametr=1
https://sekurak.pl#cos-po-hashu
W tym momencie zasadne jest jednak pytanie, czy tylko te trzy znaki mogą kończyć nazwę domeny w adresie URL? David napisał prosty skrypt w JS, który ujawnił, że dla przeglądarek istnieje jeszcze jeden znak: \
.
Oznacza to, że jeśli przygotujemy adres podobny do następującego: https://zlosliwa-domena.pl\abc.corp.google.com
, to googlowy regex uzna, że jest to poddomena corp.google.com
, jednak gdy później ten sam adres URL zostanie sparsowany przez przeglądarkę, dla niej nazwa domeny to tylko zlosliwa-domena.pl
, dzięki czemu tokeny OAuth mogły wyciekać do zewnętrznych domen.
Okazało się, że David zidentyfikował błąd w popularnej bibliotece używanej przez Google, o nazwie Closure. W repozytorium można znaleźć commit, który naprawia ten błąd. Za zgłoszenie błędu, Google wypłaciło bounty w wysokości 6000 USD.
Regeksowa zagadka
Dawno temu, w starej wersji serwisu rozwal.to, przygotowałem zadanie, które też wymagało nieco zabawy z regeksami i użyciem narzedzie typu Debuggex czy Regexper. Zadanie jest nadal dostępne, więc jeśli ktoś ma ochotę przećwiczyć użycie regeksów, serdecznie zachęcam do zmierzenia się z nim.
W zadaniu należy napisać adres email, który przechodzi sprawdzanie poprawności adresu email wbudowane w PHP, ale w taki sposób by zrobić z tego SQL Injection i wyciągnąć z bazy flagę w postaci ROZWAL_...
. W PHP mail jest sprawdzany regeksem (do którego bezpośredni link tutaj), ale w jest w nim pewien błąd ;) Kluczem do rozwiązania zadania jest odkrycie tego błędu.
Link do zadania:
— Michał Bentkowski (@SecurityMB)
Kiedy rozwal.to bedzie za free?
jak się z tym odrobimy ;-) w czym covid nie pomaga.