-
Notifications
You must be signed in to change notification settings - Fork 155
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
Ursnif Config Extraction #13
Comments
Hi enzo, this sounds good. Could you share some hashes with me and I'll have a look. Are you using the existing yara sig or a new updated one? If the config data & key are easily had from API hooks we can make a package to capture them quite easily. If they use internal code then we will use the debugger. Please share with me your analysis so far and we can collaborate on the package? Kev |
This is the Ursnif rule I'm using. We are interested in the code when it's injected into explorer.exe which I've only matched with CAPE Extraction. There are additional strings that would be good to match on, but they are in the .bss section which is decrypted during execution.
I think the debugger will be needed, but you can verify. Dropper/Loader Hash
Final Payload Hash (injected into explorer.exe in my case)
I can share the .idb file with you if you have IDA. Let me know how you would like to collaborate. |
Ursnif payload extraction (thanks enzo, issue #13).
Thanks for the hashes and the sig - this sample has been really useful as it has helped me find a couple of issues with the Injection package which should of course have been able to dump the payloads injected into explorer. I've fixed the package now and pushed the updates, as well as updating the signature to detect both the 32-bit and 64-bit DLLs which are injected into explorer. You can see the results on the public instance: https://cape.contextis.com/analysis/3060. So next let's look at the config - sharing the .idb file sounds good to me. You could email it to me if it's not too big - do you have my address? |
I don't have your address. |
It's my github username at gmail |
After merging the Ursnif commits I get the following errors:
I think the tasks are just timing out and shutting down without any reporting. This then leads to processing errors obviously. I reverted and everything went back to normal. Also, I'm sending you the idb. Cheers and thanks. |
Oh dear that isn't good. Is it the commit with the new Injection DLLs? Perhaps they are causing analysis to fail. Do you think you could run a test to see if this is the case? Thanks for the idb - I'm looking into it now. Cheers |
yes it's the new DLLs, the other commits are fine |
Hmm weird - would you mind checking to see if there is anything obvious in the analysis log? Is it just the Injection package? I can't reproduce this unfortunately. |
I reinstalled the updated DLLs and everything seems to work now. Must have been a bad fetch or something. |
I still have the problem, not sure if its bad fetch - how did you reinstall the dlls? what was the method? you still made a fetch right? |
yes I did a fetch and merge, verified that the md5s matched when I pushed to my server. Now it seems to work. However, I did have one failure during extraction:
Here's the sample I was having issues with yesterday. Seems to process fine now. |
Thanks for the sample hash, let me look into it and see if i can work out what's going on. |
I now suspect the problem may have been due to bugs introduced into the processing module. I've tried to clean up the code in this and submitCAPE reporting module as suggested by marirs, hopefully the most recent push will clear up the problems. Please let me know how you go, thanks. |
Hi enzo, just to give you an update - I have looked at your IDB (thanks for that) and I think you are right about using the debugger. The other alternative which I looked at was to do the decryption and parsing of the BSS section in a config parsing script in the processing phase. It looked like the main decryption algorithm was quite simple and straightforward to reimplement in Python. But there are a couple of functions, quite a few inputs (like operations on the version strings in the binary) so in the end this looks more complicated than just sticking a breakpoint on the decryption function and dumping its output and key. So I have been looking at creating a debugger package. Since fixing the Injection package it looks like there is a 32 and 64-bit version of the final payload so we'll need to cover both. But the problem I've hit is that I'm finding the behaviour of the sample tricky to reproduce. On one of my systems (64-bit) explorer spawns a final process wmpnscfg.exe which it hollows with the payload. But on other of my systems this doesn't happen. I suspect it's something to do with the state of the vm, I noticed it looking at Firefox's prefs.js which was missing on one system. I've set Firefox up properly now but still I can't get that final process to spawn. Any ideas on what it needs to get there? |
Is the issue with just the 64-bit variant? |
On my VMs (Win 7 SP1 64-bit) an svchost.exe process injects into explorer.exe (this would be the equivalent CAPE process dump that I used for the 32-bit binary that I analyzed.) Are you saying that explorer.exe goes one step further with wmpnscfg.exe? |
Yeah exactly - explorer goes one further and spawns a new process. I suspect that it's in this final process that it goes down the route of decryptinh the .bss and doing its comms via the flag it checks for in DllMain - I haven't checked this for sure though. If the .bss is decrypted any time prior to this then we don't need it, but I think it's likely to only execute that path (and thus trip the breakpoint) in the final process. |
I just tried on an xp vm, and it doesn't get any further than explorer either... |
Is it possible that the final process doesn't trigger until it properly communicates with it's C2? Although, I have samples where comms are occurring from explorer.exe (32-bit); it would have had to have decoded the .bss section to do so. MD5: a3b82142eebd5d3650563b05ebb1be1ac546436d166f1a70b65c56011db5ffc7 |
sha256 not MD5... |
You're right if the comms is happening then it must be decoded - unfortunately I haven't had any do comms - it's probably quite particular about the setup. Let me have a go at setting up the breakpoint and we'll see if we can get it to hit. |
I added a text file to the dropbox share. It contains analysis notes from a sample I reversed back in 2015. I don't have the .idb file unfortunately. Something to note. There is a compressed(maybe encrypted) config data block with initial values. Finding this would be ideal as it contains the serpent encryption key for comms along with other info. I know I pulled it from memory, but don't remember what code generated it. I don't know if the mechanism has changed in newer versions. I haven't had a chance to compare the notes to see if they still apply fully to newer samples. It shouldn't be too different, so hopefully something in the notes helps. |
Thanks - I'll have a look at this and hopefully spend a bit more time analysing some samples to get to the bottom of it. |
Any luck with this? I haven't had time to look at it too much. |
Hi enzo, I'm sorry I've been slack on this, I've been caught up in some other work. I'll get back on the case and do some tests to see whether I can catch the .bss decryption with a breakpoint. |
No worries. I appreciate any time you have. Thanks. |
Hi enzo - good news. I've created a debugger package for Ursnif, the first challenge was as discussed previously, that most of the time the samples don't seem to get to the final process, and I discovered that unfortunately this means the .bss section isn't decrypted. So I decided to manipulate the execution flow in the debugger to force it to decrypt this section by manipulating a test it performs just prior to decrypting. This works nicely and allows the module to dumped with the .bss section decrypted, ready for config parsing. I haven't quite completed all the bits yet, I've only just got it working for 64-bit, but I'll try and wrap up the package and push it tomorrow all being well. In the meantime if you want to have a look at an example, check the payload in the following job on the public instance: https://cape.contextis.com/analysis/3432 The .bss is in the clear - next step, parsing the config! Cheers |
Log from the 64-bit Ursnif package. This fails with cuckoo scheduler error - Analysis failed: system restarted unexpectedly
|
Ok that makes it clear - thanks for the extra detail. Definitely the 64-bit DLL then, as you say the setting of the first breakpoint seems to be triggering it. But I am still perplexed as to why it would cause a full system reboot! I've tested this package on a few systems,, I'll see if I can come up with a new build to try and find out a bit more... Shall I email you the new build? |
Sure I'm happy to test it. Thanks. |
32-bit samples aren't hitting on the decrypt, crypto, or parse_config yara rules. 64-bit samples appear to be fine. That could explain the not getting submitted to ursnif package. |
Yeah I've only catered for 64-bit so far. I still need to extend the signature and update the DLL for 32-bit. |
I used the new DLL, same error: system restarted unexpectedly.
|
Hmm well we got a bit more information - the next line should be: SetThreadBreakpoint: Set bp 0 thread id 1992 type 0 at address 0x0000000003425AE4, size 0 with Callback 0x73b63970 So if you are happy to test another iteration (and maybe more) we can zero in on where the problem must lie if I keep adding debug output lines until we find the exact place... |
here's results from the 2nd dll you sent me
|
I tried running it against a new VM build, but same result. |
Thanks for testing that - it's beginning to look like the crash is occurring in or around the 'SetThreadBreakpoint' function. I've just created (and sent) another build with even more debug statements around the suspected code, if you wouldn't mind giving it a run that would be really helpful. Also, out of interest, what hypervisor do you use in your setup? |
KVM |
Same result. Not sure if it helps but the Extraction package also terminates unexpectedly. Could it be hypervisor related?
|
It's a tricky one - I guess we can't yet rule out it being the hypervisor. I've not seen this issue on either VMware ESX or Workstation... Another potential might be the OS or patch level - is it running on Windows 7 x64? Let me know if you patch the VMs (all mine are SP1 but no more). In your previous log there is one of the extra lines I added: SetBreakpoint: About to call SetThreadBreakpoint for thread 2068. This is missing from the most recent one which is another mystery. I've just compiled yet another with a line at the beginning of the SetThreadBreakpoint function so we should see that appear before the SetDebugRegister call. Let me know if you get any more output from this one. |
Two VMs both win7x64 w/SP1 - one has no additional patches, the other has most recent, same behavior from both.
|
i'm going to try moving the VM into vmware and see if it still behaves the same |
haven't had much luck with vmware |
Hi enzo, I've just pushed an update to the Ursnif package which should now cover both 32-bit and 64-bit systems, as well as working on some recent samples. I have added to the Yara sig, but it's starting to look pretty bloated and unwieldy so I'd like to remove most of it leaving only the 'crypto' and 'parse_config' bits for each platform. Can you let me know if you have any samples that these bits won't detect as I don't want to break older detection. As far as your crashes/restarts are concerned, it might be worth testing the new package on your system (particularly if you have a 32-bit vm), although I guess it's likely to have the same problem as before. Did you manage to test on VMware? I'm very curious to know if this is a problem with KVM specifically. One other thing it might be worth trying is to test another package which relies on the debugger to see if it's this that causes the restarts. A Sedreco sample such as e1259372d15bb5001be18f03dddbdc117710d7a64829dad3a95829413783f0d7 should test an older version of the debugger on 64-bit. Let me know how you go. |
I get the same error with the Sedreco sample, and the new Ursnif32/64 DLLs. Looks like it may be KVM specific. I have to build a new VM from scratch to test VMware as converting to vmdk didn't get me far. As to the yara rules, the simpler the better. I would have to rerun my samples against the Cape injection files to see if they still work after being pared down. |
I found some bits on the web suggesting that KVM doesn't allow for use of the debug registers in the guest and takes a vmexit if they're touched. There's also a couple of patches to allow for their use or prevent the restarts but they're from a few years ago so there may be more up-to-date info. https://patchwork.kernel.org/patch/4717311/ |
I Googled for this, but haven't found anything that spells out a solution. |
I'm considering migrating my VMs to ESX, but the cuckoo conf says it isn't possible to create memory dumps with ESX. Can you verify this? |
I think this must be 'whole system' memory dumps taken by the hypervisor. I haven't ever used this functionality myself but would be surprised if it can't be done with VMware as I've heard of .vmem files from snapshots being used - in forensics for example. I'm not sure how though. But the process memory dumps taken within the guest work fine in case this is what you meant? |
I was referring to system dumps for Volatility analysis. I've taken a poll and most of are willing to lose that capability to have fully working CAPE. As soon as I get some time I'll be migrating our VMs to ESX. You're right about the .vmem file, just have to take a snapshot of the running VM and copy it over. Shouldn't be too difficult to accomplish. Maybe I'll take a stab at that down the road. Thanks. |
Trying to get the config from this sample fails: |
Thanks for the notice - I will publish an update on this soon. |
I have just published an update to the Ursnif package to handle this and other recent variants. Here is the sample you mention: https://cape.contextis.com/analysis/6177 Please note that in order to achieve extraction of config and payload, breakpoint addresses need to be supplied to the Ursnif package. This is done automatically in CAPE when the payload is extracted by the Injection package, so in order for complete automation be sure to submit with either the Injection package or no package (auto). To submit directly with the Ursnif package, you may use the Ursnif Yara signature to find the addresses of the two required breakpoints - for example: D:>yara -s D:\CAPE\cape\data\yara\CAPE\Ursnif.yar D:\payloads\1f4ab93b10fdf93ff51200991c2a32f90861c8dd3396159d1735198306ac0cb6 You would then convert these addresses to decimal and add the following line to the options: bp0=127132,bp1=172514 Note that the config breakpoint must be bp0, and payload bp1, not the other way around! Let me know if you have any problems. |
I'm glad to say this is now done and dusted - the latest samples at the time of writing are working (e.g. https://cape.contextis.com/analysis/6654) so I can finally close this issue! |
Fix syntax error is zip analysis package (thanks Sean Whalen)
Requesting config extraction for Ursnif. I am able to get the final Ursnif payload that's injected into Explorer.exe using CAPE extraction and a yara rule. I've done some RE and have the functions that build the comms strings prior to encryption. At this point, I'd like to dump the data along with the encryption key. Would this require a capemon dll to hook these functions? Thoughts?
The text was updated successfully, but these errors were encountered: