Files
metasploit-gs/docs/development/developing-modules/libraries/using-reflectivedll-injection.html
T

41 lines
66 KiB
HTML
Raw Normal View History

2026-05-08 17:08:43 +00:00
<!DOCTYPE html><html lang="en-US"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=Edge"><link rel="shortcut icon" href="/assets/images/favicon.png" type="image/x-icon"><link rel="stylesheet" href="/assets/css/just-the-docs-default.css"> <script async src="https://www.googletagmanager.com/gtag/js?id=UA-4622520-7"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-4622520-7', { 'anonymize_ip': true }); </script> <script type="text/javascript" src="/assets/js/vendor/lunr.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/mermaid@10.8.0/dist/mermaid.min.js"></script> <script type="text/javascript" src="/assets/js/just-the-docs.js"></script><meta name="viewport" content="width=device-width, initial-scale=1"><title>ReflectiveDLL Injection | Metasploit Documentation Penetration Testing Software, Pen Testing Security</title><meta name="generator" content="Jekyll v4.3.4" /><meta property="og:title" content="ReflectiveDLL Injection" /><meta property="og:locale" content="en_US" /><meta name="description" content="View Metasploit Framework Documentation" /><meta property="og:description" content="View Metasploit Framework Documentation" /><link rel="canonical" href="https://rapid7.github.io/metasploit-framework/docs/development/developing-modules/libraries/using-reflectivedll-injection.html" /><meta property="og:url" content="https://rapid7.github.io/metasploit-framework/docs/development/developing-modules/libraries/using-reflectivedll-injection.html" /><meta property="og:site_name" content="Metasploit Documentation Penetration Testing Software, Pen Testing Security" /><meta property="og:type" content="website" /><meta name="twitter:card" content="summary" /><meta property="twitter:title" content="ReflectiveDLL Injection" /> <script type="application/ld+json"> {"@context":"https://schema.org","@type":"WebPage","description":"View Metasploit Framework Documentation","headline":"ReflectiveDLL Injection","publisher":{"@type":"Organization","logo":{"@type":"ImageObject","url":"https://rapid7.github.io/metasploit-framework/assets/images/favicon.png"}},"url":"https://rapid7.github.io/metasploit-framework/docs/development/developing-modules/libraries/using-reflectivedll-injection.html"}</script><body> <svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <symbol id="svg-link" viewBox="0 0 24 24"><title>Link</title><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path> </svg> </symbol> <symbol id="svg-search" viewBox="0 0 24 24"><title>Search</title><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search"> <circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line> </svg> </symbol> <symbol id="svg-menu" viewBox="0 0 24 24"><title>Menu</title><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-menu"><line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line> </svg> </symbol> <symbol id="svg-arrow-right" viewBox="0 0 24 24"><title>Expand</title><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-chevron-right"><polyline points="9 18 15 12 9 6"></polyline> </svg> </symbol> <symbol id="svg-doc" viewBox="0 0 24 24"><title>Document</title><svg xmlns
#include</span> <span class="cpf">"Exploit.h"</span><span class="cp">
#include</span> <span class="cpf">"Exploiter.h"</span><span class="cp">
</span>
<span class="k">static</span> <span class="n">VOID</span> <span class="nf">ExecutePayload</span><span class="p">(</span><span class="n">LPVOID</span> <span class="n">lpPayload</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">VOID</span><span class="p">(</span><span class="o">*</span><span class="n">lpCode</span><span class="p">)()</span> <span class="o">=</span> <span class="p">(</span><span class="n">VOID</span><span class="p">(</span><span class="o">*</span><span class="p">)())</span><span class="n">lpPayload</span><span class="p">;</span>
<span class="n">lpCode</span><span class="p">();</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">VOID</span> <span class="nf">Exploit</span><span class="p">(</span><span class="n">LPVOID</span> <span class="n">lpPayload</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">PrivEsc</span><span class="p">();</span>
<span class="n">ExecutePayload</span><span class="p">(</span><span class="n">lpPayload</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div><p>That <code class="language-plaintext highlighter-rouge">ExecutePayload</code> function is there to… well…. Execute the payload. Well talk about it later, but make sure that you have it accepting a pointer and executing it. Thatll be how we get a payload into the running thread.</p><p>All the <code class="language-plaintext highlighter-rouge">Exploit.cpp</code> needs to do is give a clear way for me to run the code I wanted to get system, then call the function responsible for starting the shellcode. In my case, all I needed to do was to somehow run <code class="language-plaintext highlighter-rouge">PrivEsc</code> and then <code class="language-plaintext highlighter-rouge">ExecutePayload(pPayload)</code>.</p><p>Sure enough, if you check out the <code class="language-plaintext highlighter-rouge">ReflectiveDll.c</code> file, you can see that it is really straightforward and should look a lot like your previous <code class="language-plaintext highlighter-rouge">DllMain</code> function, except theres a function call in <code class="language-plaintext highlighter-rouge">DLL_PROCESS_ATTACH</code>:</p><div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">"ReflectiveLoader.h"</span><span class="cp">
#include</span> <span class="cpf">"Exploit.h"</span><span class="cp">
</span>
<span class="n">BOOL</span> <span class="n">WINAPI</span> <span class="nf">DllMain</span><span class="p">(</span><span class="n">HINSTANCE</span> <span class="n">hinstDLL</span><span class="p">,</span> <span class="n">DWORD</span> <span class="n">dwReason</span><span class="p">,</span> <span class="n">LPVOID</span> <span class="n">lpReserved</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">BOOL</span> <span class="n">bReturnValue</span> <span class="o">=</span> <span class="n">TRUE</span><span class="p">;</span>
<span class="k">switch</span> <span class="p">(</span><span class="n">dwReason</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="n">DLL_QUERY_HMODULE</span><span class="p">:</span>
<span class="k">if</span> <span class="p">(</span><span class="n">lpReserved</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">)</span>
<span class="o">*</span><span class="p">(</span><span class="n">HMODULE</span> <span class="o">*</span><span class="p">)</span><span class="n">lpReserved</span> <span class="o">=</span> <span class="n">hAppInstance</span><span class="p">;</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="n">DLL_PROCESS_ATTACH</span><span class="p">:</span>
<span class="n">hAppInstance</span> <span class="o">=</span> <span class="n">hinstDLL</span><span class="p">;</span>
<span class="c1">// MessageBox(0, "In DLLMain", "Status", MB_OK);</span>
<span class="n">Exploit</span><span class="p">(</span><span class="n">lpReserved</span><span class="p">);</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="n">DLL_PROCESS_DETACH</span><span class="p">:</span>
<span class="k">case</span> <span class="n">DLL_THREAD_ATTACH</span><span class="p">:</span>
<span class="k">case</span> <span class="n">DLL_THREAD_DETACH</span><span class="p">:</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">bReturnValue</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div><p>One thing to understand- despite the feelings I had reading through the framework side, you must specify the entry point for the code you want executed in <code class="language-plaintext highlighter-rouge">DLL_PROCESS_ATTACH</code>. We are going to be (quasi) calling <code class="language-plaintext highlighter-rouge">DllMain</code>, and <code class="language-plaintext highlighter-rouge">DLL_PROCESS_ATTACH</code> will fire, thus giving us code execution in the remote process context. As you create the rest of your code, remember that <code class="language-plaintext highlighter-rouge">lpReserved</code> from <code class="language-plaintext highlighter-rouge">DllMain</code> will contain the address of your payload. Be sure that <code class="language-plaintext highlighter-rouge">lpReserve</code> has a clear path to your call of <code class="language-plaintext highlighter-rouge">ExecutePayload()</code>.</p><p>Some of the output from the framework side of the injection was confusing to me because I am used to loading DLLs explicitly and implicitly, and some of the framework methods made it sound like we were not relying on DLL_PROCESS_ATTACH. We are, but in a slightly more round-about way. That said, remember if you go back to troubleshooting just your exploit code in the <code class="language-plaintext highlighter-rouge">extern</code> function, <code class="language-plaintext highlighter-rouge">DLL_PROCESS_ATTACH</code> will still execute if you use <code class="language-plaintext highlighter-rouge">rundll32.exe</code> to call your function. Be sure to comment out your calls in <code class="language-plaintext highlighter-rouge">DLL_PROCESS_ATTACH</code> if you go back to debugging unless you want dueling exploits.</p><p>OK, so at this point, youve got a DLL with a function that does something you want, and even better, it compiles! Move that binary to the data directory corresponding to the external directory you used above. i.e. if you used <code class="language-plaintext highlighter-rouge">external/source/exploits/myfancyexploit</code>, put your binary in <code class="language-plaintext highlighter-rouge">data/exploits/myfancyexploit/</code>. If you can automate that move as a post build step, even better!</p><h3 id="now-that-we-have-the-binary-we-need-to-execute-it-on-target--enter-framework"> <a href="#now-that-we-have-the-binary-we-need-to-execute-it-on-target--enter-framework" class="anchor-heading" aria-labelledby="now-that-we-have-the-binary-we-need-to-execute-it-on-target--enter-framework"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Now that we have the binary, we need to execute it on target- Enter Framework!</h3><h2 id="step-4-adding-the-framework-module"> <a href="#step-4-adding-the-framework-module" class="anchor-heading" aria-labelledby="step-4-adding-the-framework-module"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Step 4: Adding the framework module</h2><p>Once youve got the DLL working and have it compiling with ReflectiveLoader, you have to make a framework module to use it. OJs <a href="https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/windows/local/capcom_sys_exec.rb">exploits/capcom_sys_exec</a> is a great place to start looking as an examples; it is super easy and simple to read, so lets review:</p><p>(1) Make sure you have a handle to a process. The easiest way be able to get a handle to a process is to launch your own: <code class="language-plaintext highlighter-rouge">notepad_process = client.sys.process.execute('notepad.exe', nil, {'Hidden' =&gt; true})</code></p><p>(2) We need to write to that process and launch a thread in the process, so lets get a handle to the process with ALL_ACCESS attributes: <code class="language-plaintext highlighter-rouge">process = client.sys.process.open(notepad_process.pid, PROCESS_ALL_ACCESS)</code></p><p>(3) Grab the path to your binary file: <code class="language-plaintext highlighter-rouge">library_path = ::Fi