Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Monitoring DLL Running in Another process #168

Open
JohnPeng47 opened this issue Oct 16, 2018 · 28 comments
Open

Monitoring DLL Running in Another process #168

JohnPeng47 opened this issue Oct 16, 2018 · 28 comments

Comments

@JohnPeng47
Copy link

Is there currently functionality in CAPE to run a dll in a specific process, instead of passing it to rundll?

@kevoreilly
Copy link
Contributor

I see what you mean - yes, submit the exe and dll together in a zip, and use zip package.

@doomedraven
Copy link
Contributor

you don't need to specify file=x.exe?

@kevoreilly
Copy link
Contributor

If there is only one exe it should get picked altho I have a feeling I may have broken this with recent expansion of package to inclyde a dll (alone) in a zip. I will double check.

@JohnPeng47
Copy link
Author

so the zip package will inject the DLL into the exe file, and then capemon will be able to monitor the actions of the DLL as it executes inside the DLL?

@kevoreilly
Copy link
Contributor

No this depends on the exe either statically or dynamically importing the dll. Injection of a dll is rarely dependent on a particular target process in malware.

@kevoreilly
Copy link
Contributor

What is the specific situation? What is the nature of this combination of exe and dll?

@JohnPeng47
Copy link
Author

For instance malicious DLL's that hook browser functions that enable the malware to render anything on screen, or read the user's input. Is there any way in CAPE to monitor the process of this DLL as it's executing in the browser (ie. hooking the PR_READ and PR_WRITE functions)?

@kevoreilly
Copy link
Contributor

I think in this scenario we rely on the malware to do its own injection of the dll into the browser (requiring the 'dropper' to be submitted) and ensure the monitor dll is loaded in the browser first.

@JohnPeng47
Copy link
Author

How can I configure the monitor dll is loaded in the browser executable? Because wouldn't it default to loading inside the submitted binary (or rundll)?

@kevoreilly
Copy link
Contributor

Otherwise this could be achieved by writing a package to do it.

@kevoreilly
Copy link
Contributor

Sorry I missed your question. You don't need to configure anything to ensure the monitor is loaded into the browser, as the monitor in the process which does the injection of the malicious dll will catch the injection and ensure the monitor is loaded in the browser process first. This all happens automatically already.

The monitor in the injecting process catches the injection in hooks and uses the pipe("PROCESS:..."); call to alert the analyzer that a new process requires the monitor, and the analyzer injects the monitor before the malware has injected its dll. If you are interested you can find these calls inside the relevant hooks such as the hook for CreateRemoteThread (classic dll injection) in hook_thread.c

@JohnPeng47
Copy link
Author

From what I understand, your're saying that if the malware that's injected with the monitor creates a new process createRemoteThread, then the monitor will also be injected into this new process. I think I may have been unclear but the scenario I'm describing is if the malware overwrites the AppInit registry key, and then gets loaded into say browser.exe everytime browser.exe is executed. So the injection into the process does not happen when the malware is run, but rather, only when the process itself is run (through way of AppInit). Is there a configuration setting for CAPE to analyze this type of scenario? If not I will gladly contribute a package to implement it

1 similar comment
@JohnPeng47
Copy link
Author

From what I understand, your're saying that if the malware that's injected with the monitor creates a new process createRemoteThread, then the monitor will also be injected into this new process. I think I may have been unclear but the scenario I'm describing is if the malware overwrites the AppInit registry key, and then gets loaded into say browser.exe everytime browser.exe is executed. So the injection into the process does not happen when the malware is run, but rather, only when the process itself is run (through way of AppInit). Is there a configuration setting for CAPE to analyze this type of scenario? If not I will gladly contribute a package to implement it

@kevoreilly
Copy link
Contributor

This is indeed an interesting scenario! We can tackle it together if you like, let me give some thought about how it might work. I will need to dig into this AppInit mechanism a bit as ideally we would want to use the real Windows mechanism, but trigger it ourselves.

@kevoreilly
Copy link
Contributor

How about a package that registers the supplied DLL with AppInit then just opens the browser?

@JohnPeng47
Copy link
Author

Or we could inject it using with writeProcMemory->loadLIbrary->createRemoteThread? Whichever one is easier to implement, as long as we can get the malicious DLL loaded into the target process somehow. By the way is there a way to modify registry values from Python or does that functionality need to be implemented in native code?

@kevoreilly
Copy link
Contributor

We could, I've implemented this type of injection in Loader.c if you want to have a look. But as I said, I think if you are testing something that is normally launched via a Windows mechanism, it would be best to use this mechanism rather than another implementation that may differ. I haven't looked into how AppInit performs injection but this is key.

@kevoreilly
Copy link
Contributor

It may, for example, be that the Windows loader loads the AppInit DLLs as part of its startup routine, which is what the malware developers may depend upon to do their hooking. If we inject using a remote thread, this will come much later in the process life and may be too late to work with the hooking mechanism, thus the sample won't behave properly.

@JohnPeng47
Copy link
Author

Ah yes good point. And I think the AppInit DLL's gets loaded by user32.dll when that gets loaded into a process

@JohnPeng47
Copy link
Author

JohnPeng47 commented Nov 2, 2018

Should this be implemented as an auxiliary module since it needs to run before the analyzer executes the targeted binary?

@kevoreilly
Copy link
Contributor

I haven't had time to look into this mechanism myself, but if this mechanism causes a dll to be loaded into all processes, then if set up accordingly in advance, it should be loaded in an IE process that is launched by the 'ie' package. So I would start with this simple test. Set the AppInit mechanism up, snapshot the state, then use that snapshot as the beginning of a typical run with IE, and see if the analysis catches the loading of the AppInit dll.

If it does, then the challenge would shift to making a package which first created the relevant AppInit registry key, then subsequently launches the process. This shouldn't be so hard. If the loading of the dll is missed (or doesn't occur) then we'll need to work out why not, there are things we can try in that eventuality too.

@kevoreilly
Copy link
Contributor

Did you have any luck getting the AppInit registry key set? Let me know if you need any help integrating this into a package.

@JohnPeng47
Copy link
Author

JohnPeng47 commented Dec 4, 2018 via email

@JohnPeng47
Copy link
Author

JohnPeng47 commented Dec 4, 2018 via email

@kevoreilly
Copy link
Contributor

One thing I've learned over the years is that it's wise to break things down into pieces, so let's get this AppInit package done first before tackling this other idea.

Another classic gem of wisdom is many hands make light work! So if you are happy to show me what you've done so far, perhaps with a smattering of relevant malware samples, perhaps I can help drive it to completion...!

@JohnPeng47
Copy link
Author

JohnPeng47 commented Dec 5, 2018

Ah yes u are right sometimes I get a little too ahead of myself. Below code shud load VIRUS.EXE into every process that also loads user32, by way of LoadAppInitDLL, test on Win7 v6.2:

from  _winreg import *

dllpath = "C:\\Users\\IEUser\\Documents\\test_dll\\msgbox.dll"
keyVal = r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows
try:
	print "hello"
	key = OpenKey(HKEY_LOCAL_MACHINE, keyVal, 0, KEY_ALL_ACCESS)
except:
	print "creating key"
	key = CreateKey(HKEY_LOCAL_MACHINE, keyVal)

SetValueEx(key, "LoadAppInit_DLLs", 1, REG_DWORD, 0)
SetValueEx(key, "RequireSignedAppInit_DLLs", 1, REG_DWORD, 1)
SetValueEx(key, "AppInit_DLLs", 1, REG_SZ, dllpath)

print QueryValueEx(key, u'AppInit_DLLs') 
CloseKey(key)

After running the above, the process to be injected will be provided by the user as a parameter, and the package will hook/start that process. Then once analysis is complete, find a way to filter out the results by only looking for calls made by the DLL. And then stopping the analysis after the DLL has finished executing (not sure best way to do this). What do you think?

@kevoreilly
Copy link
Contributor

Thanks - do you have a sample I can test this with?

@JohnPeng47
Copy link
Author

JohnPeng47 commented Dec 6, 2018

Yep I have a small DLL that pops a text box in DLLMain. https://drive.google.com/file/d/1I_tMZb22xbPMj4v5DNP5EZowWoQylXs4/view?usp=sharing

So just download the DLL, and change the dllpath variable in the script to point to the downloaded file. Run the script, and then afterwards, any program you open (ie. calculator, browser, etc.) should pop a text box. Note: I actually posted the wrong version of the script it shud be as follows:


from  _winreg import *

dllpath = "C:\\Users\\IEUser\\Documents\\test_dll\\msgbox.dll"
keyVal = r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows
try:
	print "hello"
	key = OpenKey(HKEY_LOCAL_MACHINE, keyVal, 0, KEY_ALL_ACCESS)
except:
	print "creating key"
	key = CreateKey(HKEY_LOCAL_MACHINE, keyVal)

SetValueEx(key, "LoadAppInit_DLLs", 1, REG_DWORD, 1)
SetValueEx(key, "RequireSignedAppInit_DLLs", 1, REG_DWORD, 0)
SetValueEx(key, "AppInit_DLLs", 1, REG_SZ, dllpath)

print QueryValueEx(key, u'AppInit_DLLs') 
CloseKey(key)

enzok pushed a commit to enzok/CAPE that referenced this issue Oct 7, 2019
Fix office template for BinGraph graphs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants