[CTF Series #11] C# P/Invoke + Reflective load

GhouLSec
5 min readNov 6, 2021

This is one of the binary that I had created for this year University CTF competition. This challenge is inspired by some red teaming C# script and malware (e.g. Agent Tesla)

Challenge name: ParentSharp

General binary description: Little obfuscated C# Binary with reflective load and P/Invoke methods with annoying runtime byte modification via Virtual Protect. Also, there is no crpyto library used in the challenge🙃

It can be solved in very easy way by dynamically analyzing it 😶 GG …

This post will explain the tricks that I had implemented in this challenge 😂.

General Binary Overview

Class Structure
Entry point

[Walkthrough]

Normal string decryption by RC4

RC4 Function: KJASD.cHalala
RC4 encoded data: Variable dada*
RC4 Key: Variable pwx

@string = kernel32.dll                                         string2 = CreateFileA
string3 = .\MessageFromAuthor.txt string4 = Baby Shark dodododo Baby Sharp dudududu

Reflective Loaded function

All the reflective loaded function can be found in Native class.

CreateFileA

LoadLibary(“Kernel32.dll”);
GetProcAddress(“CreateFileA”, “Kernel32.dll”);
CreateFileA(…);

Program.ascasc/CreateFileA will create a new file named MessageFromAuthor.txt in its executed path.

WriteFile

csaasczxc = GetProcAddress(“WriteFile”, “Kernel32.dll”);
WriteFile(…);

csaasczxc/WriteFile function will write string Baby Shark dodododo Baby Sharp dudududu into ./MessageFromAuthor.txt

Custom Base64 encoded blob

A custom base64 decoder with custom key generator.

👇
👇
👇
👇
Key Generator

bsd() is b64 input cleanup.
gdgdgd() is b64 decoder function.
c2sb() custom key generated.

Number to Ascii:
65–90 = A-Z
97–122 = a-z
48–57 = 0–9
43 = +
47 = /
Reverse string:
array[array.Length - l - 1]
Final key produced:
/+9876543210zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA

Test it against the encoded blob and apparently it is a MZ binary file.

The decrypted blob will be load via Assembly.Load function with the namespace Baby_Sharp and class name shark_call.

You may refer to my previous blog here on how to extract external loaded module during runtime.

shark_call has two method called which are:

dudu()

** I’m just too lazy to remove the part “No author, instant win” string and fixing the easy win method, so it will lead to a quick win if the participant delete the .\MessageAuthor.txtin between the program execution and continue to run it later 😢

Sharp()

rktrkt() in modify flag bytes during runtime via VirtualProtect in cmr()

Original key = 0x1f, 0xf9, 0x23, 0x62, 0x64, 0x13, 0x4e, 0x54, 0x87, 0x66, 0xdd, 0xba, 0x23, 0x95, 0xc5, 0x4f, 0xf2

Key after runtime = 0x1f, 0xf9, 0x2d, 0x67, 0x6c, 0x2b, 0x5e, 0x64, 0x87, 0x62, 0xdd, 0xba, 0x23, 0x95, 0xc5, 0x4f, 0xf2

cHalala() as mentioned above, it is RC4 that will decrypt the flag blob shark_call.dada with key md5(tkrtkr(Program.bsbsbs)

Program.bsbsbs after tkrtkr: 0x3a, 0xbe, 0x5a, 0xf4, 0xbe, 0x3a

👇
👇

Let’s try to RC4 the encrypted flag blob with the md5 key!

やった!FlaggagaGettttoo

Thoughts:

You may also see such technique used in malicious Powershell command.For example, utilization of C# “Assembly Load” module in PS script [System.Reflection.Assembly]::Load

By using the such technique, the threat actor can achieve “living off the land” attack without dropping any payload in the system drive which might detect by the AV static scanner. 😈

Besides that, some malware is using Javascript to compile C# code in runtime and executed them afterwards. 😮

Interesting read — Utilizing Syscalls in C#:

References:

--

--