hacktricks/reversing/reversing-tools-basic-methods
2024-04-07 00:09:03 +00:00
..
angr Translated ['README.md', 'binary-exploitation/arbitrary-write-2-exec/REA 2024-04-07 00:09:03 +00:00
blobrunner.md Translated to Polish 2024-02-11 01:46:25 +00:00
cheat-engine.md Translated ['README.md', 'binary-exploitation/arbitrary-write-2-exec/REA 2024-04-07 00:09:03 +00:00
README.md Translated ['README.md', 'binary-exploitation/arbitrary-write-2-exec/REA 2024-04-07 00:09:03 +00:00
satisfiability-modulo-theories-smt-z3.md Translated to Polish 2024-02-11 01:46:25 +00:00

Narzędzia do Odwracania Inżynieryjnego i Podstawowe Metody

Zacznij od zera i stań się ekspertem od hakowania AWS dzięki htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks:

Try Hard Security Group

{% embed url="https://discord.gg/tryhardsecurity" %}


Narzędzia do Odwracania Inżynieryjnego oparte na ImGui

Oprogramowanie:

Dekompilator Wasm / Kompilator Wat

Online:

Oprogramowanie:

Dekompilator .NET

dotPeek

dotPeek to dekompilator, który dekompiluje i analizuje wiele formatów, w tym biblioteki (.dll), pliki metadanych systemu Windows (.winmd) i pliki wykonywalne (.exe). Po dekompilacji zestawu można go zapisać jako projekt Visual Studio (.csproj).

Zaletą jest to, że jeśli utracony kod źródłowy wymaga przywrócenia z archiwalnego zestawu, ta czynność może zaoszczędzić czas. Ponadto dotPeek zapewnia wygodną nawigację po zdekompilowanym kodzie, co czyni go jednym z doskonałych narzędzi do analizy algorytmów Xamarin.

.NET Reflector

Z kompleksowym modelem dodatków i interfejsem API rozszerzającym narzędzie, .NET Reflector oszczędza czas i upraszcza rozwój. Przejrzyjmy mnogość usług inżynierii wstecznej, które oferuje to narzędzie:

  • Zapewnia wgląd w sposób przepływu danych przez bibliotekę lub komponent
  • Zapewnia wgląd w implementację i użycie języków i frameworków .NET
  • Znajduje funkcjonalności nieudokumentowane i nieujawnione, aby uzyskać więcej z używanych interfejsów API i technologii.
  • Znajduje zależności i różne zestawy
  • Namierza dokładne miejsce błędów w twoim kodzie, komponentach innych firm i bibliotekach.
  • Debuguje źródło całego kodu .NET, z którym pracujesz.

ILSpy & dnSpy

Wtyczka ILSpy dla Visual Studio Code: Możesz ją mieć w dowolnym systemie operacyjnym (możesz zainstalować ją bezpośrednio z VSCode, nie trzeba pobierać z git. Kliknij Extensions i szukaj ILSpy).
Jeśli musisz dekompilować, modyfikować i ponownie kompilować, możesz użyć dnSpy lub aktywnie rozwijanej gałęzi, dnSpyEx. (Kliknij prawym przyciskiem myszy -> Modify Method aby zmienić coś wewnątrz funkcji).

Logowanie DNSpy

Aby sprawić, że DNSpy zaloguje pewne informacje do pliku, możesz użyć tego fragmentu:

using System.IO;
path = "C:\\inetpub\\temp\\MyTest2.txt";
File.AppendAllText(path, "Password: " + password + "\n");

Debugowanie w DNSpy

Aby debugować kod za pomocą DNSpy, musisz:

Po pierwsze, zmień Atrybuty zestawu związane z debugowaniem:

[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]

Do:

[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default |
DebuggableAttribute.DebuggingModes.DisableOptimizations |
DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints |
DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]

I kliknij skompiluj:

Następnie zapisz nowy plik za pomocą Plik >> Zapisz moduł...:

Jest to konieczne, ponieważ jeśli tego nie zrobisz, podczas uruchamiania kodu zostanie zastosowanych kilka optymalizacji i może się zdarzyć, że podczas debugowania punkt przerwania nie zostanie osiągnięty lub niektóre zmienne nie istnieją.

Następnie, jeśli twoja aplikacja .NET jest uruchamiana przez IIS, możesz ją ponownie uruchomić za pomocą:

iisreset /noforce

Następnie, aby rozpocząć debugowanie, należy zamknąć wszystkie otwarte pliki i w zakładce Debug wybrać opcję Attach to Process...:

Następnie wybierz w3wp.exe, aby dołączyć do serwera IIS i kliknij attach:

Teraz, gdy debugujemy proces, nadszedł czas, aby go zatrzymać i załadować wszystkie moduły. Najpierw kliknij Debug >> Break All, a następnie kliknij Debug >> Windows >> Modules:

Kliknij dowolny moduł w Modules i wybierz Open All Modules:

Kliknij prawym przyciskiem myszy dowolny moduł w Assembly Explorer i wybierz Sort Assemblies:

Dekompilator Java

https://github.com/skylot/jadx
https://github.com/java-decompiler/jd-gui/releases

Debugowanie plików DLL

Korzystanie z IDA

  • Załaduj rundll32 (64 bity w C:\Windows\System32\rundll32.exe i 32 bity w C:\Windows\SysWOW64\rundll32.exe)
  • Wybierz debugger Windbg
  • Wybierz "Suspend on library load/unload"

  • Skonfiguruj parametry wykonania, podając ścieżkę do pliku DLL i funkcję, którą chcesz wywołać:

Następnie, gdy rozpoczniesz debugowanie, wykonanie zostanie zatrzymane po załadowaniu każdego DLL, a gdy rundll32 załaduje twoje DLL, wykonanie zostanie zatrzymane.

Ale jak uzyskać dostęp do kodu DLL, który został załadowany? Korzystając z tej metody, nie wiem jak.

Korzystanie z x64dbg/x32dbg

  • Załaduj rundll32 (64 bity w C:\Windows\System32\rundll32.exe i 32 bity w C:\Windows\SysWOW64\rundll32.exe)
  • Zmień linię poleceń ( File --> Change Command Line ) i ustaw ścieżkę do pliku DLL oraz funkcję, którą chcesz wywołać, na przykład: "C:\Windows\SysWOW64\rundll32.exe" "Z:\shared\Cybercamp\rev2\\14.ridii_2.dll",DLLMain
  • Zmień Options --> Settings i wybierz "DLL Entry".
  • Następnie rozpocznij wykonanie, debugger zatrzyma się przy każdym głównym elemencie DLL, w pewnym momencie zatrzymasz się w wejściu DLL twojego DLL. Następnie wyszukaj miejsca, w których chcesz ustawić punkt przerwania.

Zauważ, że gdy wykonanie zostanie zatrzymane z jakiegokolwiek powodu w win64dbg, możesz zobaczyć w jakim kodzie się znajdujesz patrząc na górę okna win64dbg:

Następnie, patrząc na to, możesz zobaczyć, kiedy wykonanie zostało zatrzymane w DLL, które chcesz debugować.

Aplikacje GUI / Gry wideo

Cheat Engine to przydatny program do znajdowania ważnych wartości zapisanych w pamięci działającej gry i ich zmiany. Więcej informacji znajdziesz w:

{% content-ref url="cheat-engine.md" %} cheat-engine.md {% endcontent-ref %}

ARM & MIPS

{% embed url="https://github.com/nongiach/arm_now" %}

Shellkody

Debugowanie shellkodu za pomocą blobrunner

Blobrunner przydzieli shellkod w przestrzeni pamięci, wskaże adres pamięci, w którym shellkod został przydzielony, a następnie zatrzyma wykonanie.
Następnie musisz dołączyć debugger (Ida lub x64dbg) do procesu i ustawić punkt przerwania na wskazanym adresie pamięci, a następnie wznów wykonanie. W ten sposób będziesz debugować shellkod.

Na stronie wydań na GitHubie znajdziesz archiwa zip zawierające skompilowane wersje: https://github.com/OALabs/BlobRunner/releases/tag/v0.0.5
Możesz znaleźć nieco zmodyfikowaną wersję Blobrunner pod następującym linkiem. Aby ją skompilować, wystarczy utworzyć projekt C/C++ w Visual Studio Code, skopiować i wkleić kod oraz go skompilować.

{% content-ref url="blobrunner.md" %} blobrunner.md {% endcontent-ref %}

Debugowanie shellkodu za pomocą jmp2it

jmp2it jest bardzo podobny do blobrunner. Przydzieli shellkod w przestrzeni pamięci i rozpocznie wieczną pętlę. Następnie musisz dołączyć debugger do procesu, rozpocząć działanie, poczekać 2-5 sekund i nacisnąć stop, a znajdziesz się w wiecznej pętli. Przejdź do następnej instrukcji wiecznej pętli, ponieważ będzie to wywołanie shellkodu, a ostatecznie będziesz wykonywać shellkod.

Możesz pobrać skompilowaną wersję jmp2it ze strony wydań.

Debugowanie shellkodu za pomocą Cutter

Cutter to GUI radare. Za pomocą Cuttera możesz emulować shellkod i dynamicznie go analizować.

Zauważ, że Cutter pozwala na "Otwarcie pliku" i "Otwarcie shellkodu". W moim przypadku, gdy otworzyłem shellkod jako plik, został poprawnie zdekompilowany, ale gdy otworzyłem go jako shellkod, nie:

Aby rozpocząć emulację w wybranym miejscu, ustaw tam punkt przerwania, a Cutter automatycznie rozpocznie emulację od tego miejsca:

Możesz zobaczyć stos na przykład w postaci wydruku szesnastkowego:

Rozszyfrowywanie shellkodu i uzyskiwanie funkcji wykonywanych

Spróbuj scdbg.
Pokaże ci, które funkcje używa shellkod i czy shellkod jest dekodowany w pamięci.

scdbg.exe -f shellcode # Get info
scdbg.exe -f shellcode -r #show analysis report at end of run
scdbg.exe -f shellcode -i -r #enable interactive hooks (file and network) and show analysis report at end of run
scdbg.exe -f shellcode -d #Dump decoded shellcode
scdbg.exe -f shellcode /findsc #Find offset where starts
scdbg.exe -f shellcode /foff 0x0000004D #Start the executing in that offset

scDbg posiada również graficzny uruchamiacz, w którym możesz wybrać opcje, których chcesz użyć i wykonać shellcode

Opcja Create Dump spowoduje zrzucenie ostatecznego shellcode, jeśli jakakolwiek zmiana zostanie dokonana dynamicznie w pamięci shellcode (przydatne do pobrania zdekodowanego shellcode). Start offset może być przydatny do uruchomienia shellcode w określonym przesunięciu. Opcja Debug Shell jest przydatna do debugowania shellcode za pomocą terminala scDbg (jednak uważam, że każda z opcji wyjaśnionych wcześniej jest lepsza w tej kwestii, ponieważ będziesz mógł użyć Ida lub x64dbg).

Rozkładanie na części za pomocą CyberChef

Prześlij plik shellcode jako dane wejściowe i użyj następującego przepisu, aby go zdekompilować: https://gchq.github.io/CyberChef/#recipe=To_Hex('Space',0)Disassemble_x86('32','Full%20x86%20architecture',16,0,true,true)

Movfuscator

Ten obfuskator modyfikuje wszystkie instrukcje dla mov (tak, naprawdę fajne). Wykorzystuje również przerwania do zmiany przepływów wykonań. Aby uzyskać więcej informacji na temat jego działania:

Jeśli masz szczęście, demovfuscator zdeobfuskuje plik binarny. Ma kilka zależności

apt-get install libcapstone-dev
apt-get install libz3-dev

I zainstaluj keystone (apt-get install cmake; mkdir build; cd build; ../make-share.sh; make install)

Jeśli bierzesz udział w CTF, ta metoda znajdowania flagi może być bardzo przydatna: https://dustri.org/b/defeating-the-recons-movfuscator-crackme.html

Rust

Aby znaleźć punkt wejścia, wyszukaj funkcje za pomocą ::main jak w:

W tym przypadku plik binarny nazywał się authenticator, więc jest dość oczywiste, że to jest interesująca funkcja główna.
Mając nazwę funkcji, które są wywoływane, wyszukaj je w Internecie, aby dowiedzieć się o ich wejściach i wyjściach.

Delphi

Dla skompilowanych binariów Delphi można użyć https://github.com/crypto2011/IDR

Jeśli musisz zreversować binarny plik Delphi, sugeruję użycie wtyczki IDA https://github.com/Coldzer0/IDA-For-Delphi

Wystarczy nacisnąć ATL+f7 (importuj wtyczkę python w IDA) i wybierz wtyczkę python.

Ta wtyczka uruchomi binarny plik i dynamicznie rozwiąże nazwy funkcji na początku debugowania. Po rozpoczęciu debugowania ponownie naciśnij przycisk Start (zielony lub f9), a przerwa zostanie osiągnięta na początku rzeczywistego kodu.

Jest to również bardzo interesujące, ponieważ jeśli naciśniesz przycisk w aplikacji graficznej, debugger zatrzyma się w funkcji wykonywanej przez ten przycisk.

Golang

Jeśli musisz zreversować binarny plik Golang, sugeruję użycie wtyczki IDA https://github.com/sibears/IDAGolangHelper

Wystarczy nacisnąć ATL+f7 (importuj wtyczkę python w IDA) i wybierz wtyczkę python.

To rozwiąże nazwy funkcji.

Skompilowany Python

Na tej stronie znajdziesz, jak uzyskać kod pythona z binarnego pliku skompilowanego w formacie ELF/EXE:

{% content-ref url="../../generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/.pyc.md" %} .pyc.md {% endcontent-ref %}

GBA - Game Body Advance

Jeśli masz binarny plik gry GBA, możesz użyć różnych narzędzi do emulacji i debugowania:

W no$gba, w Opcje --> Konfiguracja Emulacji --> Kontrole** ** możesz zobaczyć, jak nacisnąć przyciski Game Boy Advance

Naciśnięcie każdego przycisku ma wartość identyfikacyjną:

A = 1
B = 2
SELECT = 4
START = 8
RIGHT = 16
LEFT = 32
UP = 64
DOWN = 128
R = 256
L = 256

Więc w tego rodzaju programie interesującą częścią będzie sposób, w jaki program traktuje dane wejściowe użytkownika. W adresie 0x4000130 znajdziesz często spotykaną funkcję: KEYINPUT.

Na poprzednim obrazku możesz zobaczyć, że funkcja jest wywoływana z FUN_080015a8 (adresy: 0x080015fa i 0x080017ac).

W tej funkcji, po pewnych operacjach inicjalizacyjnych (bez znaczenia):

void FUN_080015a8(void)

{
ushort uVar1;
undefined4 uVar2;
undefined4 uVar3;
ushort uVar4;
int iVar5;
ushort *puVar6;
undefined *local_2c;

DISPCNT = 0x1140;
FUN_08000a74();
FUN_08000ce4(1);
DISPCNT = 0x404;
FUN_08000dd0(&DAT_02009584,0x6000000,&DAT_030000dc);
FUN_08000354(&DAT_030000dc,0x3c);
uVar4 = DAT_030004d8;

Znaleziono ten kod:

do {
DAT_030004da = uVar4; //This is the last key pressed
DAT_030004d8 = KEYINPUT | 0xfc00;
puVar6 = &DAT_0200b03c;
uVar4 = DAT_030004d8;
do {
uVar2 = DAT_030004dc;
uVar1 = *puVar6;
if ((uVar1 & DAT_030004da & ~uVar4) != 0) {

Ostatnie if sprawdza, czy uVar4 znajduje się w ostatnich kluczach i nie jest to bieżący klucz, zwany również puśczeniem przycisku (bieżący klucz jest przechowywany w uVar1).

if (uVar1 == 4) {
DAT_030000d4 = 0;
uVar3 = FUN_08001c24(DAT_030004dc);
FUN_08001868(uVar2,0,uVar3);
DAT_05000000 = 0x1483;
FUN_08001844(&DAT_0200ba18);
FUN_08001844(&DAT_0200ba20,&DAT_0200ba40);
DAT_030000d8 = 0;
uVar4 = DAT_030004d8;
}
else {
if (uVar1 == 8) {
if (DAT_030000d8 == 0xf3) {
DISPCNT = 0x404;
FUN_08000dd0(&DAT_02008aac,0x6000000,&DAT_030000dc);
FUN_08000354(&DAT_030000dc,0x3c);
uVar4 = DAT_030004d8;
}
}
else {
if (DAT_030000d4 < 8) {
DAT_030000d4 = DAT_030000d4 + 1;
FUN_08000864();
if (uVar1 == 0x10) {
DAT_030000d8 = DAT_030000d8 + 0x3a;

W poprzednim kodzie można zobaczyć, że porównujemy uVar1 (miejsce, gdzie znajduje się wartość naciśniętego przycisku) z pewnymi wartościami:

  • Po pierwsze, porównujemy go z wartością 4 (przycisk SELECT): W wyzwaniu ten przycisk czyści ekran.
  • Następnie porównujemy go z wartością 8 (przycisk START): W wyzwaniu sprawdzane jest, czy kod jest poprawny, aby uzyskać flagę.
  • W tym przypadku zmienna DAT_030000d8 jest porównywana z 0xf3, a jeśli wartość jest taka sama, wykonywany jest pewien kod.
  • W pozostałych przypadkach sprawdzane jest cont (DAT_030000d4). Jest to cont, ponieważ dodaje 1 zaraz po wpisaniu kodu.
    Jeśli jest mniejszy niż 8, coś związanego z dodawaniem wartości do DAT_030000d8 jest wykonywane (w zasadzie dodawane są wartości naciśniętych klawiszy do tej zmiennej, dopóki cont jest mniejszy niż 8).

Więc w tym wyzwaniu, znając wartości przycisków, musisz nacisnąć kombinację o długości mniejszej niż 8, aby wynikowe dodawanie było równe 0xf3.

Odnośnik do tego samouczka: https://exp.codes/Nostalgia/

Game Boy

{% embed url="https://www.youtube.com/watch?v=VVbRe7wr3G4" %}

Kursy

Try Hard Security Group

{% embed url="https://discord.gg/tryhardsecurity" %}

Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks: