diff --git a/.gitbook/assets/image (570).png b/.gitbook/assets/image (570).png new file mode 100644 index 000000000..b040d642c Binary files /dev/null and b/.gitbook/assets/image (570).png differ diff --git a/.gitbook/assets/image (579).png b/.gitbook/assets/image (579).png new file mode 100644 index 000000000..e51830670 Binary files /dev/null and b/.gitbook/assets/image (579).png differ diff --git a/SUMMARY.md b/SUMMARY.md index af4d80ede..5564a8471 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -491,9 +491,9 @@ ## Reversing +* [Reversing Tools & Basic Methods](reversing/reversing-tools-basic-methods/README.md) + * [Blobrunner](reversing/reversing-tools-basic-methods/blobrunner.md) * [Common API used in Malware](reversing/common-api-used-in-malware.md) -* [Reversing Tools](reversing/reversing-tools/README.md) - * [Blobrunner](reversing/reversing-tools/blobrunner.md) * [Cryptographic/Compression Algorithms](reversing/cryptographic-algorithms/README.md) * [Unpacking binaries](reversing/cryptographic-algorithms/unpacking-binaries.md) * [Word Macros](reversing/word-macros.md) diff --git a/mobile-apps-pentesting/android-app-pentesting/README.md b/mobile-apps-pentesting/android-app-pentesting/README.md index 99d7d3bab..e4d64c0fc 100644 --- a/mobile-apps-pentesting/android-app-pentesting/README.md +++ b/mobile-apps-pentesting/android-app-pentesting/README.md @@ -175,7 +175,7 @@ Then, decompress all the DLsL using [**xamarin-decompress**](https://github.com/ python3 xamarin-decompress.py -o /path/to/decompressed/apk ``` - and finally you can use [**these recommended tools**](../../reversing/reversing-tools/#net-decompiler) to **read C\# code** from the DLLs. + and finally you can use [**these recommended tools**](../../reversing/reversing-tools-basic-methods/#net-decompiler) to **read C\# code** from the DLLs. ### Other interesting functions diff --git a/reversing/reversing-tools-basic-methods/README.md b/reversing/reversing-tools-basic-methods/README.md new file mode 100644 index 000000000..bf9c75dfb --- /dev/null +++ b/reversing/reversing-tools-basic-methods/README.md @@ -0,0 +1,338 @@ +# Reversing Tools & Basic Methods + +## Wasm decompiler / Wat compiler + +Online: + +* Use [https://webassembly.github.io/wabt/demo/wasm2wat/index.html](https://webassembly.github.io/wabt/demo/wasm2wat/index.html) to **decompile** from wasm \(binary\) to wat \(clear text\) +* Use [https://webassembly.github.io/wabt/demo/wat2wasm/](https://webassembly.github.io/wabt/demo/wat2wasm/) to **compile** from wat to wasm +* you can also try to use [https://wwwg.github.io/web-wasmdec/](https://wwwg.github.io/web-wasmdec/) to decompile + +Software: + +* [https://www.pnfsoftware.com/jeb/demo](https://www.pnfsoftware.com/jeb/demo) +* [https://github.com/wwwg/wasmdec](https://github.com/wwwg/wasmdec) + +## .Net decompiler + +[https://github.com/icsharpcode/ILSpy](https://github.com/icsharpcode/ILSpy) +[ILSpy plugin for Visual Studio Code](https://github.com/icsharpcode/ilspy-vscode): You can have it in any OS \(you can install it directly from VSCode, no need to download the git. Click on **Extensions** and **search ILSpy**\). +If you need to **decompile**, **modify** and **recompile** again you can use: [**https://github.com/0xd4d/dnSpy/releases**](https://github.com/0xd4d/dnSpy/releases) \(**Right Click -> Modify Method** to change something inside a function\). +You cloud also try [https://www.jetbrains.com/es-es/decompiler/](https://www.jetbrains.com/es-es/decompiler/) + +### DNSpy Logging + +In order to make **DNSpy log some information in a file**, you could use this .Net lines: + +```bash +using System.IO; +path = "C:\\inetpub\\temp\\MyTest2.txt"; +File.AppendAllText(path, "Password: " + password + "\n"); +``` + +### DNSpy Debugging + +In order to debug code using DNSpy you need to: + +First, change the **Assembly attributes** related to **debugging**: + +![](../../.gitbook/assets/image%20%287%29.png) + +From: + +```aspnet +[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] +``` + +To: + +```text +[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | +DebuggableAttribute.DebuggingModes.DisableOptimizations | +DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | +DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] +``` + +And click on **compile**: + +![](../../.gitbook/assets/image%20%28314%29%20%281%29.png) + +Then save the new file on _**File >> Save module...**_: + +![](../../.gitbook/assets/image%20%28261%29.png) + +This is necessary because if you don't do this, at **runtime** several **optimisations** will be applied to the code and it could be possible that while debugging a **break-point is never hit** or some **variables don't exist**. + +Then, if your .Net application is being **run** by **IIS** you can **restart** it with: + +```text +iisreset /noforce +``` + +Then, in order to start debugging you should close all the opened files and inside the **Debug Tab** select **Attach to Process...**: + +![](../../.gitbook/assets/image%20%28166%29.png) + +Then select **w3wp.exe** to attach to the **IIS server** and click **attach**: + +![](../../.gitbook/assets/image%20%28274%29.png) + +Now that we are debugging the process, it's time to stop it and load all the modules. First click on _Debug >> Break All_ and then click on _**Debug >> Windows >> Modules**_: + +![](../../.gitbook/assets/image%20%28210%29.png) + +![](../../.gitbook/assets/image%20%28341%29.png) + +Click any module on **Modules** and selec**t Open All Modules**: + +![](../../.gitbook/assets/image%20%28216%29.png) + +Right click any module in **Assembly Explorer** and click **Sort Assemblies**: + +![](../../.gitbook/assets/image%20%28130%29.png) + +## Java decompiler + +[https://github.com/skylot/jadx](https://github.com/skylot/jadx) +[https://github.com/java-decompiler/jd-gui/releases](https://github.com/java-decompiler/jd-gui/releases) + +## Debugging DLLs + +### Using IDA + +* **Load rundll32** \(64bits in C:\Windows\System32\rundll32.exe and 32 bits in C:\Windows\SysWOW64\rundll32.exe\) +* Select **Windbg** debugger +* Select "**Suspend on library load/unload**" + +![](../../.gitbook/assets/image%20%2869%29.png) + +* Configure the **parameters** of the execution putting the **path to the DLL** and the function that you want to call: + +![](../../.gitbook/assets/image%20%28325%29.png) + +Then, when you start debugging **the execution will be stopped when each DLL is loaded**, then, when rundll32 load your DLL the execution will be stopped. + +But, how can you get to the code of the DLL that was lodaded? Using this method, I don't know how. + +### Using x64dbg/x32dbg + +* **Load rundll32** \(64bits in C:\Windows\System32\rundll32.exe and 32 bits in C:\Windows\SysWOW64\rundll32.exe\) +* **Change the Command Line** \( _File --> Change Command Line_ \) and set the path of the dll and the function that you want to call, for example: "C:\Windows\SysWOW64\rundll32.exe" "Z:\shared\Cybercamp\rev2\\14.ridii\_2.dll",DLLMain +* Change _Options --> Settings_ and select "**DLL Entry**". +* Then **start the execution**, the debugger will stop at each dll main, at some point you will **stop in the dll Entry of your dll**. From there, just search for the points where you want to put a breakpoint. + +Notice that when the execution is stopped by any reason in win64dbg you can see **in which code you are** looking in the **top of the win64dbg window**: + +![](../../.gitbook/assets/image%20%28181%29.png) + +Then, looking to this ca see when the execution was stopped in the dll you want to debug. + +## ARM & MIPS + +{% embed url="https://github.com/nongiach/arm\_now" %} + +## Shellcodes + +### Debugging a shellcode with blobrunner + +[**Blobrunner**](https://github.com/OALabs/BlobRunner) will **allocate** the **shellcode** inside a space of memory, will **indicate** you the **memory address** were the shellcode was allocated and will **stop** the execution. +Then, you need to **attach a debugger** \(Ida or x64dbg\) to the process and put a **breakpoint the indicated memory address** and **resume** the execution. This way you will be debugging the shellcode. + +The releases github page contains zips containing the compiled releases: [https://github.com/OALabs/BlobRunner/releases/tag/v0.0.5](https://github.com/OALabs/BlobRunner/releases/tag/v0.0.5) +You can find a slightly modified version of Blobrunner in the following link. In order to compile it just **create a C/C++ project in Visual Studio Code, copy and paste the code and build it**. + +{% page-ref page="blobrunner.md" %} + +### Debugging a shellcode with jmp2it + +\*\*\*\*[**jmp2it** ](https://github.com/adamkramer/jmp2it/releases/tag/v1.4)is very similar to blobrunner. It will **allocate** the **shellcode** inside a space of memory, and start an **eternal loop**. You then need to **attach the debugger** to the process, **play start wait 2-5 secs and press stop** and you will find yourself inside the **eternal loop**. Jump to the next instruction of the eternal loop as it will be a call to the shellcode, and finally you will find yourself executing the shellcode. + +![](../../.gitbook/assets/image%20%28403%29.png) + +You can download a compiled version of [jmp2it inside the releases page](https://github.com/adamkramer/jmp2it/releases/). + +### Debugging shellcode using Cutter + +\*\*\*\*[**Cutter**](https://github.com/rizinorg/cutter/releases/tag/v1.12.0) is the GUI of radare. Using cutter you can emulate the shellcode and inspect it dynamically. + +Note that Cutter allows you to "Open File" and "Open Shellcode". In my case when I opened the shellcode as a file it decompiled it correctly, but when I opened it as a shellcode it didn't: + +![](../../.gitbook/assets/image%20%28254%29.png) + +In order to start the emulation in the place you want to, set a bp there and apparently cutter will automatically start the emulation from there: + +![](../../.gitbook/assets/image%20%28402%29.png) + +![](../../.gitbook/assets/image%20%28343%29.png) + +You can see the stack for example inside a hex dump: + +![](../../.gitbook/assets/image%20%28404%29.png) + +### Deobfuscating shellcode and getting executed functions + +You should try ****[**scdbg**](http://sandsprite.com/blogs/index.php?uid=7&pid=152). +It will tell you things like **which functions** is the shellcode using and if the shellcode is **decoding** itself in memory. + +```bash +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 also counts with a graphical launcher where you can select the options you want and execute the shellcode + +![](../../.gitbook/assets/image%20%28401%29.png) + +The **Create Dump** option will dump the final shellcode if any change is done to the shellcode dynamically in memory \(useful to download the decoded shellcode\). The **start offset** can be useful to start the shellcode at a specific offset. The **Debug Shell** option is useful to debug the shellcode using the scDbg terminal \(however I find any of the options explained before better for this matter as you will be able to use Ida or x64dbg\). + +### Disassembling using CyberChef + +Upload you shellcode file as input and use the following receipt to decompile it: [https://gchq.github.io/CyberChef/\#recipe=To\_Hex\('Space',0\)Disassemble\_x86\('32','Full%20x86%20architecture',16,0,true,true\)](https://gchq.github.io/CyberChef/#recipe=To_Hex%28'Space',0%29Disassemble_x86%28'32','Full%20x86%20architecture',16,0,true,true%29) + +## [Movfuscator](https://github.com/xoreaxeaxeax/movfuscator) + +This obfuscator **modify all the instructions for `mov`**\(yeah, really cool\). It also uses interruptions to change executions flows. For more information about how does it works: + +* [https://www.youtube.com/watch?v=2VF\_wPkiBJY](https://www.youtube.com/watch?v=2VF_wPkiBJY) +* [https://github.com/xoreaxeaxeax/movfuscator/blob/master/slides/domas\_2015\_the\_movfuscator.pdf](https://github.com/xoreaxeaxeax/movfuscator/blob/master/slides/domas_2015_the_movfuscator.pdf) + +If you are lucky [demovfuscator ](https://github.com/kirschju/demovfuscator)will deofuscate the binary. It has several dependencies + +```text +apt-get install libcapstone-dev +apt-get install libz3-dev +``` + +And [install keystone](https://github.com/keystone-engine/keystone/blob/master/docs/COMPILE-NIX.md) \(`apt-get install cmake; mkdir build; cd build; ../make-share.sh; make install`\) + +If you are playing a **CTF, this workaround to find the flag** could be very useful: [https://dustri.org/b/defeating-the-recons-movfuscator-crackme.html](https://dustri.org/b/defeating-the-recons-movfuscator-crackme.html) + +## Delphi + +For Delphi compiled binaries you can use [https://github.com/crypto2011/IDR](https://github.com/crypto2011/IDR) + +## GBA - Game Body Advance + +If you get the **binary** of a GBA game you can use different tools to **emulate** and **debug** it: + +* \*\*\*\*[**no$gba**](https://problemkaputt.de/gba.htm) \(_Download the debug version_\) - Contains a debugger with interface +* \*\*\*\*[**mgba** ](https://mgba.io/)- Contains a CLI debugger +* \*\*\*\*[**gba-ghidra-loader**](https://github.com/pudii/gba-ghidra-loader) ****- Ghidra plugin +* [**GhidraGBA**](https://github.com/SiD3W4y/GhidraGBA) ****- Ghidra plugin + +In [**no$gba**](https://problemkaputt.de/gba.htm), in _**Options --> Emulation Setup --> Controls**_ ****you can see how to press the Game Boy Advance **buttons** + +![](../../.gitbook/assets/image%20%28579%29.png) + +When pressed, each **key has a value** to identify it: + +```text +A = 1 +B = 2 +SELECT = 4 +START = 8 +RIGHT = 16 +LEFT = 32 +UP = 64 +DOWN = 128 +R = 256 +L = 256 +``` + +So, in this kind of programs, the an interesting part will be **how the program treats the user input**. In the address **0x4000130** you will find the commonly found function: **KEYINPUT.** + +![](../../.gitbook/assets/image%20%28570%29.png) + +In the previous image you can find that the function is called from **FUN\_080015a8** \(addresses: _0x080015fa_ and _0x080017ac_\). + +In that function, after some init operations \(without any importance\): + +```c +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; +``` + + It's found this code: + +```c + 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) { +``` + +The last if is checking **`uVar4`** is in the **last Keys** and not is the current key, also called letting go off a button \(current key is stored in **`uVar1`**\). + +```c + 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; +``` + +In the previous code you can see that we are comparing **uVar1** \(the place where the **value of the pressed button** is\) with some values: + +* First, it's compared with the **value 4** \(**SELECT** button\): In the challenge this button clears the screen +* Then, it's comparing it with the **value 8** \(**START** button\): In the challenge this checks is the code is valid to get the flag. + * In this case the var **`DAT_030000d8`** is compared with 0xf3 and if the value is the same some code is executed. +* In any other cases, some cont \(`DAT_030000d4`\) is checked. It's a cont because it's adding 1 right after entering in the code. **I**f less than 8 something that involves **adding** values to **`DAT_030000d8`** is done \(basically it's adding the values of the keys pressed in this variable as long as the cont is less than 8\). + +So, in this challenge, knowing the values of the buttons, you needed to **press a combination with a length smaller than 8 that the resulting addition is 0xf3.** + +**Reference for this tutorial:** [**https://exp.codes/Nostalgia/**](https://exp.codes/Nostalgia/)\*\*\*\* + +## Game Boy + +{% embed url="https://www.youtube.com/watch?v=VVbRe7wr3G4" %} + +## Courses + +* [https://github.com/0xZ0F/Z0FCourse\_ReverseEngineering](https://github.com/0xZ0F/Z0FCourse_ReverseEngineering) +* [https://github.com/malrev/ABD](https://github.com/malrev/ABD) \(Binary deobfuscation\) + diff --git a/reversing/reversing-tools-basic-methods/blobrunner.md b/reversing/reversing-tools-basic-methods/blobrunner.md new file mode 100644 index 000000000..cf87a649b --- /dev/null +++ b/reversing/reversing-tools-basic-methods/blobrunner.md @@ -0,0 +1,209 @@ +# Blobrunner + +The only modified line from the [original code](https://github.com/OALabs/BlobRunner) is the line 10. +In order to compile it just **create a C/C++ project in Visual Studio Code, copy and paste the code and build it**. + +```c +#include +#include +#include + +#ifdef _WIN64 +#include +#endif + +// Define bool +#pragma warning(disable:4996) +#define true 1 +#define false 0 + +const char* _version = "0.0.5"; + +const char* _banner = " __________.__ ___. __________\n" +" \\______ \\ | ____\\_ |__\\______ \\__ __ ____ ____ ___________ \n" +" | | _/ | / _ \\| __ \\| _/ | \\/ \\ / \\_/ __ \\_ __ \\ \n" +" | | \\ |_( <_> ) \\_\\ \\ | \\ | / | \\ | \\ ___/| | \\/ \n" +" |______ /____/\\____/|___ /____|_ /____/|___| /___| /\\___ >__| \n" +" \\/ \\/ \\/ \\/ \\/ \\/ \n\n" +" %s \n\n"; + + +void banner() { + system("cls"); + printf(_banner, _version); + return; +} + +LPVOID process_file(char* inputfile_name, bool jit, int offset, bool debug) { + LPVOID lpvBase; + FILE* file; + unsigned long fileLen; + char* buffer; + DWORD dummy; + + file = fopen(inputfile_name, "rb"); + + if (!file) { + printf(" [!] Error: Unable to open %s\n", inputfile_name); + + return (LPVOID)NULL; + } + + printf(" [*] Reading file...\n"); + fseek(file, 0, SEEK_END); + fileLen = ftell(file); //Get Length + + printf(" [*] File Size: 0x%04x\n", fileLen); + fseek(file, 0, SEEK_SET); //Reset + + fileLen += 1; + + buffer = (char*)malloc(fileLen); //Create Buffer + fread(buffer, fileLen, 1, file); + fclose(file); + + printf(" [*] Allocating Memory..."); + + lpvBase = VirtualAlloc(NULL, fileLen, 0x3000, 0x40); + + printf(".Allocated!\n"); + printf(" [*] |-Base: 0x%08x\n", (int)(size_t)lpvBase); + printf(" [*] Copying input data...\n"); + + CopyMemory(lpvBase, buffer, fileLen); + return lpvBase; +} + +void execute(LPVOID base, int offset, bool nopause, bool jit, bool debug) +{ + LPVOID shell_entry; + +#ifdef _WIN64 + DWORD thread_id; + HANDLE thread_handle; + const char msg[] = " [*] Navigate to the Thread Entry and set a breakpoint. Then press any key to resume the thread.\n"; +#else + const char msg[] = " [*] Navigate to the EP and set a breakpoint. Then press any key to jump to the shellcode.\n"; +#endif + + shell_entry = (LPVOID)((UINT_PTR)base + offset); + +#ifdef _WIN64 + + printf(" [*] Creating Suspended Thread...\n"); + thread_handle = CreateThread( + NULL, // Attributes + 0, // Stack size (Default) + shell_entry, // Thread EP + NULL, // Arguments + 0x4, // Create Suspended + &thread_id); // Thread identifier + + if (thread_handle == NULL) { + printf(" [!] Error Creating thread..."); + return; + } + printf(" [*] Created Thread: [%d]\n", thread_id); + printf(" [*] Thread Entry: 0x%016x\n", (int)(size_t)shell_entry); + +#endif + + if (nopause == false) { + printf("%s", msg); + getchar(); + } + else + { + if (jit == true) { + // Force an exception by making the first byte not executable. + // This will cause + DWORD oldp; + + printf(" [*] Removing EXECUTE access to trigger exception...\n"); + + VirtualProtect(shell_entry, 1 , PAGE_READWRITE, &oldp); + } + } + +#ifdef _WIN64 + printf(" [*] Resuming Thread..\n"); + ResumeThread(thread_handle); +#else + printf(" [*] Entry: 0x%08x\n", (int)(size_t)shell_entry); + printf(" [*] Jumping to shellcode\n"); + __asm jmp shell_entry; +#endif +} + +void print_help() { + printf(" [!] Error: No file!\n\n"); + printf(" Required args: \n\n"); + printf(" Optional Args:\n"); + printf(" --offset The offset to jump into.\n"); + printf(" --nopause Don't pause before jumping to shellcode. Danger!!! \n"); + printf(" --jit Forces an exception by removing the EXECUTE permission from the alloacted memory.\n"); + printf(" --debug Verbose logging.\n"); + printf(" --version Print version and exit.\n\n"); +} + +int main(int argc, char* argv[]) +{ + LPVOID base; + int i; + int offset = 0; + bool nopause = false; + bool debug = false; + bool jit = false; + char* nptr; + + banner(); + + if (argc < 2) { + print_help(); + return -1; + } + + printf(" [*] Using file: %s \n", argv[1]); + + for (i = 2; i < argc; i++) { + if (strcmp(argv[i], "--offset") == 0) { + printf(" [*] Parsing offset...\n"); + i = i + 1; + if (strncmp(argv[i], "0x", 2) == 0) { + offset = strtol(argv[i], &nptr, 16); + } + else { + offset = strtol(argv[i], &nptr, 10); + } + } + else if (strcmp(argv[i], "--nopause") == 0) { + nopause = true; + } + else if (strcmp(argv[i], "--jit") == 0) { + jit = true; + nopause = true; + } + else if (strcmp(argv[i], "--debug") == 0) { + debug = true; + } + else if (strcmp(argv[i], "--version") == 0) { + printf("Version: %s", _version); + } + else { + printf("[!] Warning: Unknown arg: %s\n", argv[i]); + } + } + + base = process_file(argv[1], jit, offset, debug); + if (base == NULL) { + printf(" [!] Exiting..."); + return -1; + } + printf(" [*] Using offset: 0x%08x\n", offset); + execute(base, offset, nopause, jit, debug); + printf("Pausing - Press any key to quit.\n"); + getchar(); + return 0; +} +``` +