Skip to content

Instantly share code, notes, and snippets.

@zimnyaa
Created July 28, 2023 13:02
Show Gist options
  • Save zimnyaa/c5a06a774255ca087d1453c681a671aa to your computer and use it in GitHub Desktop.
Save zimnyaa/c5a06a774255ca087d1453c681a671aa to your computer and use it in GitHub Desktop.
A patch for NiCOFF to load the BOF in a memory region of a trusted DLL.
diff --git a/Main.nim b/Main.nim
index ef19f4c..c133586 100644
--- a/Main.nim
+++ b/Main.nim
@@ -128,7 +128,7 @@ proc ApplyGeneralRelocations(patchAddress:uint64,sectionStartAddress:uint64,give
echo "[!] No code for type: ",givenType
var allocatedMemory:LPVOID = nil
-
+var caveLibH: HANDLE
proc RunCOFF(functionName:string,fileBuffer:seq[byte],argumentBuffer:seq[byte]):bool =
var fileHeader:ptr FileHeader = cast[ptr FileHeader](unsafeAddr(fileBuffer[0]))
var totalSize:uint64 = 0
@@ -172,7 +172,38 @@ proc RunCOFF(functionName:string,fileBuffer:seq[byte],argumentBuffer:seq[byte]):
echo "[!] Text section is not found!"
return false
# We need to store external function addresses too
- allocatedMemory = VirtualAlloc(NULL, cast[UINT32](totalSize+GetNumberOfExternalFunctions(fileBuffer,textSectionHeader)), MEM_COMMIT or MEM_RESERVE or MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE)
+ #allocatedMemory = VirtualAlloc(NULL, cast[UINT32](totalSize+GetNumberOfExternalFunctions(fileBuffer,textSectionHeader)), MEM_COMMIT or MEM_RESERVE or MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE)
+
+ echo "need size:", totalSize+GetNumberOfExternalFunctions(fileBuffer,textSectionHeader)
+ # FORK STARTS HERE
+ var mbi: MEMORY_BASIC_INFORMATION
+ var offset: LPVOID
+ var process: HANDLE = GetCurrentProcess()
+ var pages = newSeq[int](0)
+
+ # enumerating current RWX regions
+ while VirtualQueryEx(process, offset, addr(mbi), sizeof(mbi)) != 0:
+ offset = cast[LPVOID](cast[DWORD_PTR](mbi.BaseAddress) + mbi.RegionSize)
+ if mbi.AllocationProtect == PAGE_EXECUTE_READWRITE and mbi.State == MEM_COMMIT and mbi.Type == MEM_PRIVATE:
+ if cast[int](mbi.BaseAddress) notin pages:
+ pages.add(cast[int](mbi.BaseAddress))
+ echo " ! old RWX: 0x", toHex(cast[int](mbi.BaseAddress)), " | size: ", mbi.RegionSize
+ # adding a new one
+ caveLibH = LoadLibraryA("C:\\Windows\\System32\\mfcm120.dll")
+
+
+ # finding it again
+ offset = NULL
+ var oldprotect: DWORD
+ while VirtualQueryEx(process, offset, addr(mbi), sizeof(mbi)) != 0:
+ offset = cast[LPVOID](cast[DWORD_PTR](mbi.BaseAddress) + mbi.RegionSize)
+ if mbi.AllocationProtect == PAGE_EXECUTE_READWRITE and mbi.State == MEM_COMMIT and mbi.Type == MEM_PRIVATE:
+ if cast[int](mbi.BaseAddress) notin pages:
+ echo " ! RWX: 0x", toHex(cast[int](mbi.BaseAddress)), " | size: ", mbi.RegionSize
+ allocatedMemory = mbi.BaseAddress
+ echo "will load to 0x", toHex(cast[int](allocatedMemory))
+
+ # FORK ENDS HERE
if(allocatedMemory == NULL):
echo "[!] Failed for memory allocation!"
return false
@@ -261,15 +292,16 @@ when isMainModule:
# Run COFF file
if(not RunCOFF(paramStr(2),fileBuffer,argumentBuffer)):
echo "[!] Error on executing file!"
- VirtualFree(allocatedMemory, 0, MEM_RELEASE)
+ #VirtualFree(allocatedMemory, 0, MEM_RELEASE)
+ FreeLibrary(caveLibH)
quit(0)
echo "[+] COFF File is Executed!"
var outData:ptr char = BeaconGetOutputData(NULL);
if(outData != NULL):
echo "[+] Output Below:\n\n"
echo $outData
- VirtualFree(allocatedMemory, 0, MEM_RELEASE)
-
+ # VirtualFree(allocatedMemory, 0, MEM_RELEASE)
+ FreeLibrary(caveLibH)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment