RSS Feed

blog (Grzegorz Kuczyński)

Jak wygląda crackowanie?

Oceń wpis
Większość obecnych użytkowników Linuksa, podobnie jak ja parę lat temu, używała systemu Windows. My, Linuksiarze wiemy co najczęściej robi się na naszym ulubionym systemie. Są to głównie sieci i związane z tym rozwiązania. Nie jest też tajemnicą, że osoby używające Linuksa należą do tych, które lubią „grzebać” w komputerze. Zmierzam do zadania pytania: w takim razie, co te osoby robiły przed laty na systemie Windows?

W moim przypadku była to wielka miłość do programowania. Mimo, iż już od 4 lat tym się tak nie interesuję jak niegdyś, to postanowiłem trochę powspominać te piękne czasy i zaprezentować z nich to, co najciekawsze.

Wpis ten nie jest poradnikiem na temat łamania zabezpieczenia, choć może tak wyglądać. Jest to, mam nadzieję, niezwykle ciekawa informacja z dającym do myślenia morałem, jak łatwo oszukać komputer na swoją korzyść. Jest to również moja sentymentalna opowieść o tym, jak wiedza na temat tworzenia może zostać użyta do innych celów, takich jak łamanie programów. Jeżeli zastanawiałeś się kiedyś kim są Ci kolesie podpisujący się w notatniku i dostarczający małe pliczki o takiej samej nazwie jak aplikacja, z tym, że te dostarczone przez nich nie pytają o hasło. Od razu zaznaczam, że nie byłem żadnym crackerem, tylko interesowałem się tym z czystej ciekawości i w celu sprawdzenia swoich umiejętności. Tak więc opowiem o tym, jak to się robi oraz o tym, że nikt tak nie umie łamać programów jak sami programiści. Dlaczego? Bo nikt tak dobrze nie zna zasad działania programów, jak ich twórcy.

Moja przygoda z programowaniem zaczęła się dosyć szybko licząc od momentu posiadania pierwszego komputera. Programowaniem, a w szczególności w języku C++ zacząłem interesować się jakieś 10 lat temu. Uczyłem się z książek, bardzo grubych zresztą i nie jednej. Ta fascynacja trwała chyba jakieś 5 lat. W tym czasie poznałem bardzo wiele języków programowania i ciągle było mi mało. Po C++ przyszedł czas na Assemblera, choć dziś praktycznie nieużywany, to wydanej kasy na książkę ani poświęconego czasu nie żałuję. To była jedna z najciekawszych rzeczy jakich nauczyłem się o komputerach. Ach, to były czasy, aplikacja napisana w Assemblerze ważyła parę KB. W każdym bądź razie, po poznaniu sposobu w jaki tworzy się programy oraz jak system i procesor je wykonują, w którymś momencie mojej nauki dotarło do mnie, że wiem już tak dużo, iż mógłbym trochę namieszać w tych programach nawet nie mając ich kodu. Cracowanie nie występuje pod Linuksem bo sam możesz zmieniać kod. W Windows, nie mogłeś sprawdzić jak oni to zrobili pisząc swój program. Linux daje Ci taką możliwość, dlatego jest w pewnym sensie rajem dla programistów. Sam na niego przeszedłem między innymi z tych względów.

Kiedyś były takie programiki, które ściągało się z sieci w wersji trial. Zazwyczaj miały w menu pozycję „Pomoc” albo „About”, w której znajdowało się takie polecenie jak „Rejestracja”, gdzie należało wpisać swój klucz. Powiem szczerze, że zdarzało mi się kiedyś takie programy „rejestrować” ale to stary sposób zabezpieczeń, chyba dziś już niespotykany w nowych programach. Dlaczego to robiłem? Bo gdy przez parę lat myśli się o programowaniu to człowiek w pewnym momencie przekracza pewną granice abstrakcji i patrząc na przycisk widzi kod pod nim, patrząc na pole do wpisywania tekstu widzi kod pod nim itd. i to w dwóch językach, ludzkim - C++ i maszynowym - Assembler.

Dziś korzystając z okazji, że na VirtualBox ma zainstalowany Windows 7 (legalny, z MSDNAA )zainstaluję co trzeba, napisze programik proszący o hasło z przyciskiem sprawdzającym poprawność kodu. Oczywiście będzie on tworzony tylko do celów prezentacyjnych, więc wiele aspektów zostanie w nim pominiętych – absolutne minimum. Wszystko po to, aby pokazać jak łatwo znając doskonale zasady działania programów komputerowych można taki program oszukać. Kiedyś stwierdziłem, że zabezpieczający takie programy oraz ten, który próbuje je łamać mają takie same możliwości, ponieważ obaj działają na tym samym gruncie. Oczywiście Ci drudzy mają trudniejsze zadanie ale i tak wygra sprytniejszy. Przykład, który zaprezentuję udowodni jak w logiczny sposób złamie program i stworze cracka zmieniając tylko jedne bajt w kodzie programu. Wiele rzeczy dla wielu może okazać się niezrozumiałych i tak powinno być
Zanim jednak wyruszymy na poszukiwania tego jednego bajta musimy go najpierw stworzyć.

Zaczynamy od ściągnięcia Borland C++ Builder 6 Personal, aby napisać taki program szybko. Znajdziemy go np. tu: http://www.softdir.pl/details.php?id=0821490141. Dlaczego wybrałem C++ Builder? Lubię go i chcę uniknąć pisania w WinAPI ale to nie oznacza, że nie trzeba go znać, wręcz przeciwnie.
Projekt programu oraz kod przedstawiam na zdjęciu.

Nazwa:  zrzut_ekranu.jpg
Wyświetleń: 5519
Rozmiar:  58.4 KB


Jak widzimy program jest bardzo prosty, posiada pole (Edit) do wpisania hasła i przycisk (Button) do sprawdzenia czy hasło jest poprawne. Kod również jest prosty. Gdy wciśniesz przycisk, program pobierze zawartość pola tekstowego i sprawdzi czy jest takie jak powinno. Ja jawnie napisałem w kodzie jaka to ma być wartość: „password” ale tak się nie robi. Nie zmienia to faktu, że przed samym porównaniem program i tak będzie musiał znać wartości, które będzie porównywał, więc i tak byśmy ją dorwali Gdy wpiszemy w pole ciąg znaków „password” pokaże się komunikat o treści „kod prawidłowy”, w przeciwnym przypadku pokaże się komunikat „zły kod”.

Ok, mamy już te cudo. Jak wpisze zły kod to zobaczę komunikat o złym kodzie.

Nazwa:  2.jpg
Wyświetleń: 5486
Rozmiar:  35.2 KB


Tylko z samej obserwacji programu można założyć jak jest stworzony. Jego kod mógłby wyglądać tak:

Kod:
if (to_co_wpisałem == to_co_powinno_być)
    // jedziesz dalej
 else
    // nigdzie nie pojedziesz
Co by się przed tą instrukcją nie działo, to program misi znać obie wartości już w tym momencie, chociażby ściągał poprawne hasło z FBI. Ale to nie wszystko, załóżmy specjalne okulary i zobaczymy jak to widzi procesor:

Kod:
cmp reg, mem
je jump_to
Co w wolnym tłumaczeniu znaczy: porównaj dwie wartości (cmp - compare), jeżeli są równe skocz w wskazane miejsce (je - jump if equal), jeżeli nie, kontynuuj wykonywanie instrukcji. To tylko przykładowy kod wzięty z głowy, ten oryginalny może wyglądać inaczej, ale zasada działania będzie taka sama. To oczywiście nie jest takie proste, trzeba jeszcze uwzględnić zmianę kodu assemblerowego po optymalizacji kompilatora. Jak mówiłem to najprostszy przykład i dosyć okrojony, bo procesor przed wykorzystaniem zmiennych musi jeszcze załadować nimi rejestry itp..

Teraz należy się zastanowić co by się stało, gdybym odwrócił logikę kodu assemblera? Aby procesor wykonywał skok tylko wtedy, gdy porównywane wartości są różne. W takim wypadku program akceptowałby wszystkie hasła oprócz prawidłowego – chyba nie będziesz miła takiego pecha, że wpiszesz prawidłowe . Czyli nasz crack będzie działał na wszystko, oprócz poprawnego hasła, ale oni – użytkownicy – tego nie wiedzą hehehe. Czasami też się robi po prostu NOP-a ale to może mieć fatalne skutki w dalszym działaniu programu.

Teraz potrzebujemy debuggera, mój ulubiony to OllyDbg, bez problemu go znajdziecie. Skoro już go mamy, to uruchamiamy w nim nasz programik.

Teraz bez porządnej wiedzy się nie obędzie. Debugger załadował program, wybieramy polecenie z obrazka.

Nazwa:  5.jpg
Wyświetleń: 5490
Rozmiar:  97.8 KB


Ważne jest, że jesteśmy w module Project1. Wyszukujemy wszystkie odwołania do innych modułów (funkcji bibliotek), z których korzysta program. W tym przypadku będzie to VLC. W innym przypadku byłoby to WinAPI i szukalibyśmy funkcji GetWindowText. My szukamy miejsca w kodzie, w którym pobierane jest to co wpisaliśmy. Była to funkcja GetTextBuf. Więc szukamy takiej i zastawiamy na nią pułapkę – breakpoint. W tym momencie znajomość funkcji, z których składa się program jest wyznacznikiem do ustalenia tego, czego szukamy. Tak naprawdę jest to o wiele bardziej skomplikowane niż przedstawiłem, zazwyczaj trzeba ustalić w czym został napisany program. Można też bazować na funkcjach systemowych, czyli WinAPI.

Nazwa:  6.jpg
Wyświetleń: 5499
Rozmiar:  102.9 KB


Wracamy do okna z kodem i uruchamiamy aplikacje. Wpisujemy w pole cokolwiek i wciskamy przycisk, debugger zatrzyma działanie programu na wywołaniu tej funkcji, teraz możemy przeanalizować kod.

Nazwa:  7.jpg
Wyświetleń: 5513
Rozmiar:  53.7 KB


Jak widzicie już w kodzie widać nasze hasło, ale zazwyczaj tak nie jest. Teraz używając klawisza F8 wykonujemy program krok po kroku ale bez wchodzenia w wywoływane funkcje, inaczej skończylibyśmy w jakiejś funkcji systemu operacyjnego, które zresztą należy dobrze znać. W przedstawionym miejscu już widzę w rejestrach procesora wartości, które za chwilę zostaną porównane (okno po prawej).

Nazwa:  8.jpg
Wyświetleń: 5480
Rozmiar:  96.7 KB


Przede mną widzę wywołanie funkcji strcmp(), której użyłem i wiem do czego używają jej inni programiści. Wiemy, że w kodzie jest ona w samym warunku if. Parę instrukcji dalej widzę jedyne wykonanie instrukcji skoku: JNE SHORT 00401BFF, a na samym dole okna widzę już wywołanie funkcji ShowMessage. Teraz wystarczy zmienić warunek.

Nazwa:  9.jpg
Wyświetleń: 5467
Rozmiar:  95.7 KB


Na krok przed samym skokiem dokonuje jego edycji, aby przetestować działanie programu przed stworzeniem cracka.

Zmieniam wartość 75 na 74 – są to wartości w systemie szesnastkowym oczywiście. Instrukcje assemblera oraz odpowiadające im kody również można znaleźć w sieci, a najlepiej na stronie Intela. Ja akurat pamiętałem na co mam zmienić.

Nazwa:  10i11.jpg
Wyświetleń: 5466
Rozmiar:  69.5 KB


W efekcie zmieniłem warunek z JNE „jeżeli nie równy” na JE „jeżeli równy”. Teraz odpalamy program dalej przyciskiem niebieskiej strzałki w pasku narzędzi lub wcisnąć F9. Powinniśmy zobaczyć pozytywne rozpatrzenie naszej sprawy .

Nazwa:  12.jpg
Wyświetleń: 5468
Rozmiar:  98.1 KB


No! Hehe

Zazwyczaj przy takich zmianach trzeba być bardzo uważnym i precyzyjnym. Ponieważ jakby nie było nasza zmiana będzie miała wpływ na późniejsze zachowanie programu i należy to umieć przewidzieć. Nie raz mi się zdarzało, że udawało mi się wyświetlić okno o udanej rejestracji ale program nadal był niezarejestrowany. Po prostu miał inne zabezpieczenia. Pamiętam taką sytuację, gdy podczas badania pewnego programu natrafiłem na wiadomość (zdjęcie) od programistów, która co tu dużo mówić dawała do zrozumienia, że oni są od Ciebie lepsi – ale wtedy to się uśmiałem hehe i odpuściłem sobie – respect.

Teraz potrzebujemy hex edytora i musimy ustalić czego należy w nim szukać. Jako edytora użyłem WinHex, również znajdziecie go bez problemu.
Teraz trzeba zinterpretować kod z debuggera. Po lewej stronie instrukcji widzimy odpowiadające im wartości heksadecymalne. Ale hola hola. Część z nich jest stała, a część zmienna – program poznaje te wartości dopiero w trakcie wykonywania. Niemniej jednak są to wartości zmienne ale o stałej wielkości. Ja to analizuje tak: instrukcje ADD, TEST i warunek JNE powinny być niezmieniane, szukam więc ciągu: 83 C4 08 85 C0

Nazwa:  13.jpg
Wyświetleń: 5452
Rozmiar:  100.9 KB


Ustawiam kursor na bajcie o wartości 75 i zmieniam go na 74. Zapisuję zmieniony plik pod inną nazwą np. Project1_crack.exe.

Teraz możesz odpalić zmodyfikowaną aplikacje i przetestować jak działa.

Mam nadzieję, że przedstawiony przykład uświadomi dla wielu jak niebezpiecznym narzędziem może być komputer.

Submit "Jak wygląda crackowanie?" to Digg Submit "Jak wygląda crackowanie?" to del.icio.us Submit "Jak wygląda crackowanie?" to Google Submit "Jak wygląda crackowanie?" to facebook Submit "Jak wygląda crackowanie?" to wykop

Kategorie
Luźne

Ilość komentarzy

  1. Avatar AdeBe
    Bardzo fajny wpis. Podejrzewałem, że crackowanie wygląda w ten sposób, ale teraz jestem już pewien. :-)
    Ale podziw dla gości zajmujących się łamaniem prawdziwych programów: nie dość, że pewnie często można spotkać tam wyrafinowane rozwiązania, to dodatkowo stosowanie przez producentów zaciemniaczy kodu jeszcze bardziej komplikuje sprawę.
    Może napisz następną notkę o sposobach zabezpieczania programów, o ile oczywiście się na tym znasz. Już bez sposobów na łamanie :-)
  2. Avatar grzesiek
    Ja się tym interesowałem 4-5 lat temu, obecnie w ogóle programowaniem się nie interesuje przynajmniej w takim ścisłym rozumieniu.
    AdeBe - ten wpis to tylko takie wspomnienia nim zapomnę, a już bardzo dużo zapomniałem
  3. Avatar JanGustaw
    Całkiem dobry wpis, dodam że pod Linuksem też robić takie eksperymenty (fakt jest dostępny kod źródłowy, ale pobawienie się z kodem od innej strony tez jest fajne). Ale można to robić z kodem dla windows też. Wystarczy zdeasemblerować kod objdump -D, użyć jakiś hex edytor np. ghex i podłubać w kodzie asemblera...
  4. Avatar giaur
    Kolego, ty o crackowaniu niewiele wiesz Takie zabezpieczenie, jak te twoje przykladowe to nie jest zadne zabezpieczenie. Prawidłowy kod rejestracyjny jest na żywca widoczny w pliku exe - tu nie trzeba nawe nic łamać ani zmieniać. Wypadałoby też wspomnieć o takich świetnych narzędziach jak IDA Pro, czy Hiew, bez których trudno mówić o powaznym podejsciu do tematu
  5. Avatar grzesiek
    Przeczytaj sobie jeszcze raz to:
    1. O moich zabezpieczeniach:
    "...napisze programik proszący o hasło z przyciskiem sprawdzającym poprawność kodu. Oczywiście będzie on tworzony tylko do celów prezentacyjnych, więc wiele aspektów zostanie w nim pominiętych – absolutne minimum. Wszystko po to, aby pokazać jak łatwo znając doskonale zasady działania programów komputerowych można taki program oszukać."
    ...
    " Ja jawnie napisałem w kodzie jaka to ma być wartość: „password” ale tak się nie robi."
    2. Widocznym kodzie rejestracyjnym:
    "W przedstawionym miejscu już widzę w rejestrach procesora wartości, które za chwilę zostaną porównane (okno po prawej)."

    Celem tego wpisu było pokazanie jak niewiele trzeba aby zmienić logikę programu.

    Co do Twojej wypowiedzi, to bardzo mnie zastanawia w jakich programach kod rejestracyjny na stałe znajduje sie w binarce Może w jakimś CrackMe, podobnie jak w moim przykładowym programie. Zazwyczaj są to algorytmy, które potrafi generować wiele pozytywnych rozwiązań lub generowany jest po komunikacji z jakimś serwerem, a sama binarka nie uruchomi się jeżeli jej suma kontrolna została zmieniona
  6. Avatar jurenty
    Muszę przyznać, że miło to się czytało :-)
  7. Avatar kamil_j_1
    Jestem studentem informatyki. Studiuję na Wydziale Cybernetyki Wojskowej Akademii Technicznej, crackowanie programów ćwiczyliśmy na II semestrze na przedmiocie podstawy programowania niskopoziomowego. Wszystko wyglądało podobnie, tylko z użyciem innych narzędzi.
    http://infa.uber.pl/content.php?get_..._wszystkie.rar przydatne informacje na temat assemblera itp.
    Edytowany 25-12-2012 o 18:29 przez fnmirk