Making of: Javascript botnet
Jeśli ktoś czytał mój wczorajszy post to pewnie się nieco zdziwił. Ponieważ podstawowy cel – przedstawienie mojego gadżetu w formie gadżetu na blog został osiągnięty, dziś mogę co nieco o nim powiedzieć.
Czy wiecie z jaką prędkością przeciętny komputer (Tu: Intel Atom 1,6 ghz HT) może testować hashe md5? Około 5 milionów na sekundę (program: BarsWF-sse2). Dla porównania, mój prywatny łamacz osiąga prędkość ok. 1 tysiąca na sekundę.
Jaki tu sens? Gdzie tkwi haczyk? Po co mi taki cracker?
Oto odpowiedź: mój cracker napisany jest w JavaScript. Tak właśnie, nie inaczej. Jednak tym, co go odróżnia od innych jest to, że może działać na wielu komputerach jednocześnie, których właściciele nawet o tym nie wiedzą. Wystarczy że ktoś wejdzie na stronę która ma odpowiednią wstawkę (js lub iframe), a którą dodałem choćby przez odpowiedni XSS – jego komputer zacznie szukać kolizji w zadanych hashach md5. Nawet nie będzie o tym wiedział. Strona może wyglądać całkiem zwyczajnie, a mimo to służy mi :)
Program napisałem w taki sposób, by zminimalizować ponowne liczenie tego samego. Jeśli dowolny klient przemieli cały zakres znaków dla danej długości, wszystkie inne również przejdą do następnej. Serwer z grubsza dzieli zakres testów na taką ilość, ile mamy znaków w zadanym charsecie, następnie losowo daje do testów jeden z nich. Oczywiście nie daje ot tak – daje przy tym zapisaną pozycję, więc nic nie jest liczone ponownie – każdy klient zaczyna tam, gdzie inny skończył.
Cały skrypt jeszcze czeka wiele usprawnień i modernizacji, głównie by zoptymalizować cały kod. Choć już teraz nie jest źle, zastosowałem tam kilka ciekawych sztuczek – osobne wątki generują zestawy plain:hash, osobne testują czy następuje kolizja. Chyba że akurat jest nadmiar/niedosyt dostępnych zestawów – wtedy są generowane w locie lub testowane w locie. Dodatkowo bez większych problemów mogę dostosować kod do łamania innego typu szyfrowania – w praktyce polega to na znalezieniu/napisaniu algorytmu szyfrowania.
Jeśli doczytałeś aż tutaj, a nie blokujesz skryptów/iframe, to prawdopodobnie przetestowałeś dla mnie kilka-kilkanaście-kilkadziesiąt tysięcy kluczy – być może nawet znalazłeś kolizję! Jesteś pewnie dumny :)
Jeśli ktoś wstawi na swoją stronę – czy to samodzielnie, czy z moją pomocą – odpowiedni kod, zmusi wszystkich swoich odwiedzających do pracy ;) oto dist-cracker idealny ;)
post mortem: Mogłem to oczywiście napisac w formie apletu java czy też w technologii flash, zapewne byłoby to znacznie szybsze. Jednak nie każdy ma w/w składniki w swojej przeglądarce. Coś za coś.
Jakbyś jeszcze płacił za dodawanie tego na swoje strony…
Po co płacić skoro można kraść? Nie rozumiem…
;-) pr0n…
Okej, a co jeśli komuś się to nie spodoba i np. zanieczyści Ci bazę ? Oczywiście możesz sprawdzać czy ktoś tego nie robi ale wtedy cała idea traci sens ;)
Cóż, jest tu pewien problem, bo jednego z ataków nie da się powstrzymać (nie da się odróżnić od tego co klient może zwrócić serwerowi). Jednak najgorsze (fałszywe wyniki, wywalanie bzdur do bazy) jest niemożliwe.
Ciągle nad tym pracuję, na razie to taka wersja beta – w wersji finalnej kod będzie zaszyfrowany odpowiednio (ba! potrafię stworzyć polimorficzny js, jak w wirusach, przy każdym odczytaniu jest inaczej :)) a i może wymyślę jak to zabezpieczyć.
ale to strata mocy rzędu 5 tys. razy czyli potrzebujesz ponad 5 tys. osób na stronie i to cały czas żeby miało to jakiś sens
jeżeli stworzy się odpowiednio dużą sieć, to te 5k osób nie były by aż tak dużym problemem, a gdyby taki js odpowiednio zareklamować, to nie sądzę, by był to większy problem
Czekałem, aż napiszesz co ten pasek robi i muszę powiedzieć, że mnie zaskoczyłeś:).
Jeśli chcesz z tego korzystać, a nie napisałeś tylko po to, żeby sprawdzić czy można, warto było by zrobić jakiś prosty serwis/ mailing/ cokolwiek, co zachęci większą ilość osób do wstawienia skryptu.
Może zrób różne animowane gify i daj trzynastolatkom na blogaski;).
Do publicons.pl możnaby dodać ;) Albo wyobrazić sobie że na gmailu jest (choć kto wie co tam w js mają:P) Jak dla mnie świetne, gratulacje. Jeden z postów, który mną głęboko wstrząsnął.
Trochę słychać, że wiatraczek w laptopie zwiększa obroty.
/edit: Chyba pora zainwestować w NoScript
@kosa: O, o „różnych” animowanych gifach nie pomyślałem, na początku myślałem by były tylko paski ładowania. Sam nie wiem czemu :)
I właśnie zamierzam to przerobić na taki blogaskowy widget … ba, może nawet dodawać jakąś funkcjonalność, typu licznik odwiedzin, latające za kursorem kotki itd – czemu nie :)
Poza tym… w całej idei chodzi o to, że łamanie trwa zawsze, absolutnie zawsze jest ktoś kto kontynuuje proces. Nie musi być specjalnie szybko – byle było trwałe i ciągłe. Bo do prostych hashy to ja i tak użyję barswf.
Jednak niejaki rozie (który mnie w trakcie pisania programu opierdzielił ze 150 razy że źle robię ;)) mi przypomniał jak jeszcze to można poprawić – muszę jeszcze trochę pomyśleć, a łamanie będzie jeszcze szybsze. Stay tuned ;-)
(at): miło mi :)
http://flame.nomicon.pl/md5.js ;)
Najs.
o ile uda ci się zmniejszyć ten współczynnik z 5 tys. o rząd wielkości w dół to już naprawdę zacznie mieć sens,
pozostaje jeszcze strona celowości zastosowania czegoś takiego…
To akurat nie moje, choć zastanawiam się czy nie da rady odrobinkę to zoptymalizować..
Od tego samego pana można sobie ukraść podobny skrypt dla sha-1 i md4, jakby ktoś potrzebował :-)
http://pajhome.org.uk/crypt/
O, to już rozumiem, dlaczego tak mi tamta strona przywieszała komputer.
No właśnie. Ja tam nic nie zauważyłem, chociaż byłem przekonany, że skrypt robi coś więcej. Ale może warto by spowolnić skrypt, żeby dzieciaki nic nie wiedziały?
Nie wiedziałem, o co chodzi, dopóki wiatrak w laptopie mi nie zaczął kręcić jak szalony. Teraz zużycie procesora mam na poziomie 50%.
Kilka zmian nastąpiło, można prosić o test? ;)
Powinno być kilka razy szybsze (!) z racji całkiem nowego modelu przechowywania hashy do testów. Zamiast przy każdym porównaniu robić iteracje po wszystkich hashach zapisanych, sprawdza czy istnieje tabela[hash] :)
Poza tym zmniejszyłem ilość wątków z 5/5 na 2/2 (generowanie/porównywanie).
Ameryki nie odkryłeś i osobiście zastanawiam się nad sensownością takiego przedsięwzięcia. Jedyne to botnety oparte o JavaScript mogłyby robić to rozwiązywać problemy obliczeniowe — tak jak w Twoim kodzie łamać MD5 — i nic więcej. Nie wykorzystasz ich do rozsyłania spamu ani ataków typu DDoS.
Tymczasem jeśli chodzi o obliczenia to strata na warstwie wykonywania kodu JavaScript jest przeogromny — tysiąc haseł na sekunde to tyle co nic (siedmioliterowych haseł skladających się z samych małych liter jest osiem miliardó) i o wiele wygodniej i bezpieczniej kupić sobie jakiś mocny komputer (albo PS3 i korzystać z GPU), niż starać się o złapanie milionów ofiar.
Co więcej JavaScript nie jest językiem wielowątkowym zatem kod wykonywany na procesorze 4 rdzeniowym będzie wykrzystywał 25% mocy obliczeniowej.
Należy również zwrócić uwagę, że taki serwer, z którego kod JavaScript jest ściągany jest łatwiej namierzyć, niż inne botnety.
Zużycie C2D 2.7 na poziomie 20%. Niby niezauważalne, ale jak ktoś ma conky’ego albo te mierniki z Visty to może zwrócić uwagę. Ja bym jeszcze spowolnił. Siła botnetu tkwi w ilości i tym, że nie zostanie zauważony IMO.
kosa: Hm, się zrobi.
mina86: Akurat do ddosów można wykorzystać bez większych problemów :P js który tworzy kilka iframe które non stop się odświeżają na celu. Jasne że badziewne, ale przy odpowiedniej ilości działa (jak ten ddos redwatcha przy pomocy wget). Wiem że narzut jest ogromny – w pierwszych zdaniach to napisałem. Siła tego systemu to cierpliwość i nieco losowości – jak dopiszę pewien ważny dodatek, to tylko dodatkowo go usprawni (nie będzie kolejno próbowało 1,2,3,4… znaków, ale gdy nie ma slotów, będzie próbowało od razu następną długość. Przy odpowiedniej ilości klientów daje to np. długości 5-20 robione jednocześnie, zaczynając losowo od dowolnego znaku (charsety są „przekręcone” o pewną wartość – tyle ich jest, ile znaków w charsecie; oczywiście każdy osobno trzyma gdzie później kontynuować).
Ofiar? No bez przesady, dziewictwa nie tracą jak ich komputer przemieli trochę hashy. W dodatku… to tylko funkcja na mojej stronie :> co w tym złego? Serwerów może też być dowolnie wiele, tylko każdy serwer by później wysyłał i odbierał dane z innego (a ten innego i innego).
Czemu taki projekt? Because I can.
Akurat przy proporcji 5 mln na Atomie i 1k na pojedynczym kliencie zabawa (poza PoC i podejściem akademickim) nie ma sensu. Jeśli różnica w wydajności byłaby dziesięcio- czy nawet stukrotna, to owszem, miałoby to sens (zakładając, że umiesz rozdzielać na $bignum klientów i faktycznie podłączonych jest non-stop min. tych kilkuset userów). W tym przypadku – niespecjalnie, szczególnie, że czas działania jest ograniczony do przebywania na danej stronie.
Co do samej idei – botnety tego typu nie są niczym nowym. I jak najbardziej da się je wykorzystać do wysyłania spamu (tu mina86 nie ma racji). Od tego, że każdy może być samodzielnym crawlerem przeszukującym zadane strony w poszukiwaniu maili zaczynając (tylko po co?), po samą wysyłkę (get spakowana treść, get spakowane adresy, rozpakuj, wyślij z IP ofiary – tu zyskiem jest zwiększenie ilości IP).
Ale z uwagi na to, że są one trywialne do wykrycia i zablokowania – czy jest sens?
Chętnie bym zobaczył skrypt JS, który mógłby wysyłać spam — skrypty nie są wszak w stanie nawiązać połączeń SMTP przez co trudno mi sobie wyobrazić jak list byłby wysłany. Co prawda można się starać szukać dziurawych stron z formularzami kontaktowymi, ale na takowych często i tak wykorzystuje się metodę POST, a skrypt JS nie ma uprawnień, aby łączyć się z innymi serwerami, niż ten, na którym znajduje się strona. Tak sam, zastanawia mnie idea zbierania adresów email skoro skrypt mógłby zbierać adresy jedynie z domeny, na której został umieszczony.
mina86: hold on, mam chyba pomysł pewien, co do wysyłania POST na dowolną stronę z dowolnej domeny :>
Ale ze mnie debil. Godzine próbowałem ominąć zabezpieczenia przeglądarki by stworzyć iframe na zdalny serwer i dokleić tam skrypt który za pomocą ajax wysyła wartość POST...
A wystarczy przecież dynamicznie stworzyć iframe + form z odpowiednim action, method i target. I dynamicznie walnąć submit().
Adresy email można zbierać tak samo – doklejamy na jakąś stronę iframe z odpowiednim kodem (lub np. popunder który to robi) który to kod:
a) wyszukuje w google np. for internetowych
b) wchodzi na te fora, na listę użytkowników i sprawdza czy dostępne są adresy email
c) zapisuje je i co jakiś czas wysyła na zdalny serwer (np. powyższą metodą).
I jesteś pewny, że skrypt będzie mógł sobie chodzić po drzewie DOM strony w innej domenie? Bo mnie się wydaje, że nie.
Hmm, racja. Muszę to jeszcze przemyśleć :P
Anyway: Od zera napisałem nowy serwer, przerobiłem nieco klienta – zapraszam do testów, teraz powinno byc znacznie efektywniejsze (nie tyle szybsze: po prostu serwer lepiej zarządza klientami).
na /hashc.txt mozna patrzec co juz sie znalazło.