Casual McDonald's Employee Scriptorium
BlogMemesGitHubAbout
  • root@JesusCries
  • ⛩️Red Teaming
    • Methodology
    • Red Team Infrastructure
    • Initial Access
    • Reconnaissance
    • Lateral Movement
    • Post-Exploitation
      • Credentials Dumping
    • Persistence
    • Evasion
      • Memory Scanner
      • Antimalware Scan Interface (AMSI)
      • Event Tracing for Windows (ETW)
      • Attack Surface Reduction (ASR)
      • Microsoft Windows Defender Application Control (WDAC)
      • EDR Evasion
    • Offensive Development
      • Process Injection & Shellcode Loader
      • Portable Executable (PE) Loader
      • User Defined Reflective Loader
      • Beacon Object Files
    • Command & Control (C2)
      • Cobalt Strike
      • Havoc
      • Mythic
      • Sliver
    • Miscellaneous
      • Interesting Read
      • Certification Reviews
        • Certified Red Team Lead (CRTL)
  • 🧊Active Directory & Pentest
    • Check List
  • 🚩CTF Writeups
    • Reverse Engineering
      • Wargames.MY 2024: World 3
      • Wargames.MY 2023: Defeat the boss!
      • ACS 2023: Licrackense Pt I
      • ACS 2023: babyrev
      • ACS 2023: expr
      • ACS 2023: rustarm
      • ACS 2023: Maze
      • SiberSiaga 2023: Obstacles
      • SiberSiaga 2023: Packed
      • SiberSiaga 2023: Malbot
      • SiberSiaga 2023: Vacine
      • ABOH 2023: MetalPipe
      • ABOH 2023: Grape
      • iCTF 2023: RemoteC4
    • Binary Exploitation
      • HTB Cyber Apocalypse 2024: SoundOfSilence
      • LACTF 2024: pizza
      • ACS 2023: Licrackense Pt II
      • ACS 2023: Shellcoding Test
      • ACS 2023: Coding Test
      • ACS 2023: register
      • Wargames.MY 2023: Pak Mat Burger
      • SiberSiaga 2023: Password Generator
      • NahamCON CTF 2023: nahmnahmnahm
      • NahamCON CTF 2023: Weird Cookie
      • TJCTF 2023: shelly
      • TJCTF 2023: formatter
      • ångstromCTF 2023: gaga2
      • ångstromCTF 2023: leek
      • Space Heroes 2023: Rope Dancer
      • corCTF 2022: babypwn
      • corCTF 2021: Cshell
      • HTB Cyber Apocalypse 2023: Void
      • HTB Cyber Santa CTF 2021: minimelfistic
      • HTB Challenge: pwnshop
  • 🤡Clown Chronicles
    • About Me
    • Blogs
      • How to Win A CTF by Overcomplicating Things
      • Exploring Dynamic Invocation for Process Injection in C# and Rust
    • Projects
    • Memes
    • Others
Powered by GitBook
On this page
  • TL;DR
  • Initial Analysis
  • Manual Unpacking
  1. CTF Writeups
  2. Reverse Engineering

SiberSiaga 2023: Packed

The binary looks so messy. Get me the flag. Please :(

PreviousSiberSiaga 2023: ObstaclesNextSiberSiaga 2023: Malbot

Last updated 1 year ago

TL;DR

Manually unpack the executable via debugging using dnSpy's Module Breakpoints feature.

Initial Analysis

Analyzing the executable file via Detect It Easy shows a .NET executable that is heavily obfuscated using 3 different packers.

We can attempt to unpack the executable iteratively via de4dot:

 ┌──(kali💀JesusCries)-[~/…/CTF/SiberSiaga2023 (Finals)/Rev/Packed]
 └─$ de4dot finaldotnet.exe -p cr      
 de4dot v3.1.41592.3405 Copyright (C) 2011-2015 de4dot@gmail.com
 Latest version and source code: https://github.com/0xd4d/de4dot
 Detected Confuser v1.9 (r76186+) (/home/kali/Desktop/CTF/SiberSiaga2023 (Finals)/Rev/Packed/finaldotnet.exe)
 Cleaning /home/kali/Desktop/CTF/SiberSiaga2023 (Finals)/Rev/Packed/finaldotnet.exe
 Renaming all obfuscated symbols
 Saving /home/kali/Desktop/CTF/SiberSiaga2023 (Finals)/Rev/Packed/finaldotnet-cleaned.exe
 ​
 ┌──(kali💀JesusCries)-[~/…/CTF/SiberSiaga2023 (Finals)/Rev/Packed]
 └─$ de4dot finaldotnet-cleaned.exe -p df 
 de4dot v3.1.41592.3405 Copyright (C) 2011-2015 de4dot@gmail.com
 Latest version and source code: https://github.com/0xd4d/de4dot
 Detected Dotfuscator (/home/kali/Desktop/CTF/SiberSiaga2023 (Finals)/Rev/Packed/finaldotnet-cleaned.exe)
 Cleaning /home/kali/Desktop/CTF/SiberSiaga2023 (Finals)/Rev/Packed/finaldotnet-cleaned.exe
 Renaming all obfuscated symbols
 Saving /home/kali/Desktop/CTF/SiberSiaga2023 (Finals)/Rev/Packed/finaldotnet-cleaned-cleaned.exe                                                                                                                         
 
 ┌──(kali💀JesusCries)-[~/…/CTF/SiberSiaga2023 (Finals)/Rev/Packed]
 └─$ de4dot finaldotnet-cleaned-cleaned.exe -p go 
 de4dot v3.1.41592.3405 Copyright (C) 2011-2015 de4dot@gmail.com
 Latest version and source code: https://github.com/0xd4d/de4dot
 Detected Goliath.NET (/home/kali/Desktop/CTF/SiberSiaga2023 (Finals)/Rev/Packed/finaldotnet-cleaned-cleaned.exe)
 Cleaning /home/kali/Desktop/CTF/SiberSiaga2023 (Finals)/Rev/Packed/finaldotnet-cleaned-cleaned.exe
 Renaming all obfuscated symbols
 Saving /home/kali/Desktop/CTF/SiberSiaga2023 (Finals)/Rev/Packed/finaldotnet-cleaned-cleaned-cleaned.exe

Verify this against Detect It Easy shows that the executable is now fully unpacked.

However, this results in no avail. As verified in dnSpy, the decompiled code remains obfuscated despite de4dot claiming to have successfully unpack it. This is likely due to the use of a custom/unknown packer.

Manual Unpacking

We can expect this challenge to be solved with a similar approach as Vacine - that is: by debugging the executable until we reach the real entry point of the program.

By default, all assemblies in .NET (regardless of it's .EXE or .DLL extension) will be loaded directly into memory, which makes the debugging of external assemblies practically impossible.

To fix this, go to Debug -> Windows -> Module Breakpoints and change the name field to an asterisk wildcard *:

Start debugging the program by hitting Continue - F5 with the default configurations, and notice how dnSpy places a breakpoint on the first ever module loaded mscorlib.dll:

As mscorlib.dll is a common dependency of .NET applications for bootstrapping the Common Language Runtime (CLR) environment, this isn't something of our interest. For the same reason, we will also skip through all subsequent assemblies that looks benign with Continue - F5:

  1. finaldotnet.exe (The application itself)

  2. Microsoft.VisualBasic.dll, System.Core.dll, System.dll

A while later, we notice that Sevenziplib is loaded. This suggests that the executable is utilizing some kind of compression to obfuscate the application.

Regardless of that, Continue - F5 one step further shows that finaldotnet (without the .EXE extension) is now loaded. This breakpoint also corresponds to the function RuntimeAssembly.nLoadImage(rawAssembly), which confirms that finaldotnet.exe is loading finaldotnet - like an inception.

To verify what comes before the loading of finaldotnet, hit Step Out - Shift + F11. This brings us to the Assembly.Load(sLcn.Ptpi(array)) function, which sounded like the Caller of our previous function:

  • Caller: Assembly.Load(sLcn.Ptpi(array)) <- High Level Function

  • Callee: RuntimeAssembly.nLoadImage(rawAssembly) <- Low Level Function

Step Out - Shift + F11 again leads us to Assembly assembly = sLcn.lFRS(). Taking a wild guess, this line of code is most probably referencing the actual assembly that will be loaded, which in this case points tofinaldotnet.

To sum up, the reason for Stepping Out twice, is because there are 3 layers of Abstraction implemented. Therefore, we need to go back 2 levels to reach the top-most level Caller.

A few lines below (Line 99) the current statement (Line 42), indicates the the entry point entryPoint.Invoke(null, parameters) of our unpacked executable. Place a breakpoint on it.

Afterwards, hit Continue - F5 until the program execution stops at the entry point.

After stopping at the entry point, hit Step Over - F10 to start exploring the unpacked executable.

Recall that we configured dnSpy to set a breakpoint every time an external assembly is loaded. As we are now in the bootstrapping stage of the unpacked executable, it makes sense for it to be loading a tons of dependencies it requires. This also means that we have a long way to go (Step Over - F10 x28 times) until we will see some sensible lines of code.

Continue to Step Over - F10 repeatedly until the current statement reaches Line 36. This will allow a bunch of string variables to be initialized and populated.

BEFORE:

AFTER:

At this point onwards, when trying to run the executable normally, it will go to sleep indefinitely thanks to the code in Line 37. To bypass the sleep function, as well as other insignificant comparison statements marked under the giant cross mark, we need to Set Next Statement - CTRL + SHIFT + F10 on Line 66.

Line 66 onwards is our point of interest because it seems to be comparing our user input to a base64-decoded string. With that said, this is most probably a flag-checker function.

 using (uNPH.NvYX())
 {
     string jzvx = text6;
     string s = text7;
     byte[] wTdt = Convert.FromBase64String(s);
     byte[] bytes = uNPH.GBrL(wTdt, jzvx);
     string @string = Encoding.UTF8.GetString(bytes);
     Console.Write(value2);
     string a = Console.ReadLine();
     if (a == @string)
     {
         Console.WriteLine(value3);
         Console.WriteLine(value4);
     }
     else
     {
         Console.WriteLine(value5);
     }
 }

By the looks of it, the decrypted flag will be stored in variable @string. Hence, we can place a breakpoint on the comparison statement, and try to read the value of variable @string:

Finally, keep on Stepping Over - F10 from Line 66 until Line 73 for the values to be populated.

Flag: sibersiaga{2d50972fcecd376129545507f1062089}

🚩