Align quote usage

This commit is contained in:
adfoster-r7
2022-01-07 17:44:26 +00:00
parent 9af9b4277d
commit af888f1af0
9 changed files with 44 additions and 44 deletions
+14 -14
View File
@@ -2,18 +2,18 @@
## Using the ReflectiveDll loader in a metasploit module.
First, lets be clear. I have used this exactly once, but there exists little in the way of guidance on how ReflectiveDll injection works in Framework, so I figure poor guidance is better than none. I am in part hoping that someone who knows how it works will come along and correct this, ala Cunninghams Law.
First, let's be clear. I have used this exactly once, but there exists little in the way of guidance on how ReflectiveDll injection works in Framework, so I figure poor guidance is better than none. I am in part hoping that someone who knows how it works will come along and correct this, ala Cunningham's Law.
This documentation assumes that you have some familiarity with DLLs already.
### Step 1 - Make your DLL
Use Visual studio 2013 and make a standard, empty DLL. Do not attempt to add the reflective DLL stuff yet.
When you make the DLL, make sure that you have at least three files: A header file with the function declarations, a c(pp) file with the functions that do the exploit, and a DllMain file with the `DllMain` function. I find that testing the DLL outside the reflective loader helps tremendously, so in the header file, I declare my working function as an `extern`, C-style function:
When you make the DLL, make sure that you have at least three files: A header file with the function declarations, a c(pp) file with the functions that 'do' the exploit, and a DllMain file with the `DllMain` function. I find that testing the DLL outside the reflective loader helps tremendously, so in the header file, I declare my working function as an `extern`, C-style function:
`extern "C" __declspec (dllexport) void PrivEsc(void);`
I think using C as the language over cpp would make life marginally easier, as you can combine the source code into one project. Using cpp meant I needed to have separate projects, or at least using my limited compiler knowledge thats how I got it to work. I noticed OJ was able to extend his c project ([exploits/capcom_sys_exec](https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/windows/local/capcom_sys_exec.rb)) to include the reflectiveloader, but I could not seem to do the same for my cpp project.
I think using C as the language over cpp would make life marginally easier, as you can combine the source code into one project. Using cpp meant I needed to have separate projects, or at least using my limited compiler knowledge that's how I got it to work. I noticed OJ was able to extend his c project ([exploits/capcom_sys_exec](https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/windows/local/capcom_sys_exec.rb)) to include the reflectiveloader, but I could not seem to do the same for my cpp project.
Store your project in `external/source/exploits/<identifier>/<projectname>`. Thats not written in stone. The project I just finished had both DLL and EXE, so I have `external/source/exploits/<identifier>/dll` and `external/source/exploits/<identifier>/exe`. Just don't be a jerk and do something hard to follow. Your requirements may differ, and we're not super particular as long as it makes sense. I suggest the identifier to make life easier, then a project name because youll be bringing the reflective loader project into the identifier folder, and at least I like to have some separation between the two.
Store your project in `external/source/exploits/<identifier>/<projectname>`. That's not written in stone. The project I just finished had both DLL and EXE, so I have `external/source/exploits/<identifier>/dll` and `external/source/exploits/<identifier>/exe`. Just don't be a jerk and do something hard to follow. Your requirements may differ, and we're not super particular as long as it makes sense. I suggest the identifier to make life easier, then a project name because you'll be bringing the reflective loader project into the identifier folder, and at least I like to have some separation between the two.
### Step 2 Write the DLL using an extern, C-linkage entry point to make testing easier
@@ -86,12 +86,12 @@ One thing to understand- despite the feelings I had reading through the framewor
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 `extern` function, `DLL_PROCESS_ATTACH` will still execute if you use `rundll32.exe` to call your function. Be sure to comment out your calls in `DLL_PROCESS_ATTACH` if you go back to debugging unless you want dueling exploits.
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 `external/source/exploits/myfancyexploit`, put your binary in `data/exploits/myfancyexploit/`. If you can automate that move as a post build step, even better!
OK, so at this point, you've 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 `external/source/exploits/myfancyexploit`, put your binary in `data/exploits/myfancyexploit/`. If you can automate that move as a post build step, even better!
### Now that we have the binary, we need to execute it on target- Enter Framework!
## Step 4: Adding the framework module
Once youve got the DLL working and have it compiling with ReflectiveLoader, you have to make a framework module to use it. OJs [exploits/capcom_sys_exec](https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/windows/local/capcom_sys_exec.rb) is a great place to start looking as an examples; it is super easy and simple to read, so let's review:
Once you've got the DLL working and have it compiling with ReflectiveLoader, you have to make a framework module to use it. OJ's [exploits/capcom_sys_exec](https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/windows/local/capcom_sys_exec.rb) is a great place to start looking as an examples; it is super easy and simple to read, so let's review:
(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:
`notepad_process = client.sys.process.execute('notepad.exe', nil, {'Hidden' => true})`
@@ -104,32 +104,32 @@ Once youve got the DLL working and have it compiling with ReflectiveLoader, y
Replace the directory and file names with the ones to your binary.
(3.5) OJ went ahead and expanded the path; likely this is because hes used filepath hijacking in the past:
(3.5) OJ went ahead and expanded the path; likely this is because he's used filepath hijacking in the past:
`library_path = ::File.expand_path(library_path)`
(4) Now, heres where things get fun- inject your DLL directly into the memory of notepad:
(4) Now, here's where things get fun- inject your DLL directly into the memory of notepad:
`exploit_mem, offset = inject_dll_into_process(process, library_path)`
That function allocates memory in the process and loads up the DLL. There is a second method that allows you to upload DLL data, so you could create a payload using a template and load that without the dll touching the local or remote disk, but I have not had cause to use it.
Unfortunately, this is where my grasp of things gets tenuous because it departs from my experience of traditional DLL loading with LoadLibrary and GetProcAddress. We copied the DLL into the remote process memory, but we have not “loaded” it, so DLL_PROCESS_ATTACH is not executed. Thats a good thing, as we have not yet provided the payload!
Unfortunately, this is where my grasp of things gets tenuous because it departs from my experience of traditional DLL loading with LoadLibrary and GetProcAddress. We copied the DLL into the remote process memory, but we have not “loaded” it, so DLL_PROCESS_ATTACH is not executed. That's a good thing, as we have not yet provided the payload!
I square this by basically treating it like process hollowing, but on a thread-level. Watching OJs ReflectiveDll injection video might help: <https://www.youtube.com/watch?v=ZKznMBWUQ_c>
I square this by basically treating it like process hollowing, but on a thread-level. Watching OJ's ReflectiveDll injection video might help: <https://www.youtube.com/watch?v=ZKznMBWUQ_c>
You may want to watch it daily for a month or so.
Regardless, now we have a process with our exploit DLL mapped into its memory, but not doing anything. Now we need to get the payload into the process too, so we can get exploit and payload execution. Getting the payload in there is honestly not much different that getting the DLL data in there.
(5) Just allocate some RWX memory and copy the shellcode over. Theres a method for that:
(5) Just allocate some RWX memory and copy the shellcode over. There's a method for that:
`payload_mem = inject_into_process(process, payload.encoded)`
To be clear, Thats the first time you should have dealt with the payload, because while it is annoying how much goes on in the background in Framework, when you know it is happening, Framework is awesome!
To be clear, That's the first time you should have dealt with the payload, because while it is annoying how much goes on in the background in Framework, when you know it is happening, Framework is awesome!
Now, if youve been paying attention to the return values from the above methods, we have three important values: (1) `exploit_mem` that has the address of the DLL loaded into memory, (2) `offset` that (I think) contains the offset to the `DllMain` function inside the DLL loaded into memory, and (3) `payload_mem`, that contains the address of your payload.
Now, if you've been paying attention to the return values from the above methods, we have three important values: (1) `exploit_mem` that has the address of the DLL loaded into memory, (2) `offset` that (I think) contains the offset to the `DllMain` function inside the DLL loaded into memory, and (3) `payload_mem`, that contains the address of your payload.
(6) Now, With those three values, and our code stored in the process's memory, things make a lot more sense. We just need to create a thread in the process and point it to the `DllMain` function with the address of our payload as the `lpReserve` parameter.
`process.thread.create(exploit_mem + offset, payload_mem)`
(6) What Im Still unclear about:
(6) What I'm Still unclear about:
(6.1) How do we get the offset value? If we check out `inject_dll_into_process`, it shows that it is searching the pe for `ReflectiveLoader` and that's not a string I can find as an entry point. I do not understand why that gives us the offset to what I believe to be DllMain when it appears to be searching to ReflectiveLoader...?
(6.2) There are a few ways to use `ReflectiveDllLoader`, and I wish I could read more on using it as an import like OJ does in that `capcom_sys_exec`.