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

Ursnif Config Extraction #13

Closed
enzok opened this issue Oct 25, 2017 · 82 comments
Closed

Ursnif Config Extraction #13

enzok opened this issue Oct 25, 2017 · 82 comments
Assignees

Comments

@enzok
Copy link
Contributor

enzok commented Oct 25, 2017

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?

@kevoreilly
Copy link
Contributor

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

@kevoreilly kevoreilly self-assigned this Oct 26, 2017
@enzok
Copy link
Contributor Author

enzok commented Oct 26, 2017

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.

rule Ursnif
{
    meta:
        author = "enzo"
        description = "Ursnif final payload"
        cape_type = "Ursnif"
    strings:
        $a1 = {48 8B C4 53 55 56 57 41 54 41 55 41 56 41 57 48 83 EC 48 48 8B 51 30 48 8B F9 48 85 D2 48 89 50 10}
        $a2 = {8B 70 EC 33 70 F8 33 70 08 33 30 83 C0 04 33 F1 81 F6 B9 79 37 9E C1 C6 0B 89 70 08 41 81 F9 84 00 00 00 72 DB}
        $b1 = "Tape Device" fullword
    condition:
        uint16(0) == 0x5A4D and (all of ($a*)) and (not $b1)
}

I think the debugger will be needed, but you can verify.

Dropper/Loader Hash

  • 2a3d5d175b57c0e1ea1a4683f7956d70091fa9fcb75b2b1b0fab4cb8424aedb0

Final Payload Hash (injected into explorer.exe in my case)

  • 965815c05bdf1672915a8420b6be86ddbc4ce1066c06f374f5ba37c31086ff84

I can share the .idb file with you if you have IDA. Let me know how you would like to collaborate.

kevoreilly added a commit that referenced this issue Oct 30, 2017
Ursnif payload extraction (thanks enzo, issue #13).
@kevoreilly
Copy link
Contributor

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?

@enzok
Copy link
Contributor Author

enzok commented Oct 30, 2017

I don't have your address.

@kevoreilly
Copy link
Contributor

It's my github username at gmail

@enzok
Copy link
Contributor Author

enzok commented Oct 31, 2017

After merging the Ursnif commits I get the following errors:

OSError: [Errno 2] No such file or directory: '/opt/cuckoo/storage/analyses/4570/files' 2017-10-30 15:31:44,538 [modules.processing.suricata] WARNING: Suricata returned a Exit Value Other than Zero 30/10/2017 -- 15:31:44 - <Error> - [ERRCODE: SC_ERR_LOGDIR_CMDLINE(117)] - The logging directory "/opt/cuckoo/storage/analyses/4570/logs" supplied at the commandline (-l /opt/cuckoo/storage/analyses/4570/logs) doesn't exist. Shutting down the engine.

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.

@kevoreilly
Copy link
Contributor

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

@enzok
Copy link
Contributor Author

enzok commented Oct 31, 2017

yes it's the new DLLs, the other commits are fine
analysis is failing, tried on 32-bit and 64-bit VMs

@kevoreilly
Copy link
Contributor

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.

@enzok
Copy link
Contributor Author

enzok commented Oct 31, 2017

I reinstalled the updated DLLs and everything seems to work now. Must have been a bad fetch or something.

@marirs
Copy link
Contributor

marirs commented Oct 31, 2017

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?

@enzok
Copy link
Contributor Author

enzok commented Oct 31, 2017

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:

2017-10-31 15:08:45,000 [root] INFO: Date set to: 10-31-17, time set to: 19:08:45 2017-10-31 15:08:45,015 [root] INFO: Analyzer:prepare: DEFAULT_DLL was None, DEFAULT_DLL_64 was None 2017-10-31 15:08:45,015 [root] INFO: Analyzer:prepare: DEFAULT_DLL set to None, DEFAULT_DLL_64 set to None 2017-10-31 15:08:45,000 [root] INFO: Date set to: 10-31-17, time set to: 19:08:45 2017-10-31 15:08:45,000 [root] INFO: Analyzer:prepare: DEFAULT_DLL was None, DEFAULT_DLL_64 was None 2017-10-31 15:08:45,000 [root] INFO: Analyzer:prepare: DEFAULT_DLL set to None, DEFAULT_DLL_64 set to None 2017-10-31 15:08:45,000 [root] DEBUG: Starting analyzer from: C:\utitlmw 2017-10-31 15:08:45,000 [root] DEBUG: Storing results at: C:\nQubPqbtQ 2017-10-31 15:08:45,015 [root] DEBUG: Pipe server name: \\.\PIPE\YdKXGF 2017-10-31 15:08:45,015 [root] INFO: Analysis package "Extraction" has been specified. 2017-10-31 15:08:45,155 [root] DEBUG: Started auxiliary module Auxfile 2017-10-31 15:08:45,155 [root] DEBUG: Started auxiliary module Browser 2017-10-31 15:08:45,155 [modules.auxiliary.digisig] DEBUG: Checking for a digitial signature. 2017-10-31 15:08:45,250 [modules.auxiliary.digisig] DEBUG: File is not signed. 2017-10-31 15:08:45,250 [modules.auxiliary.digisig] INFO: Uploading signature results to aux/DigiSig.json 2017-10-31 15:08:45,250 [root] DEBUG: Started auxiliary module DigiSig 2017-10-31 15:08:45,250 [root] DEBUG: Started auxiliary module Disguise 2017-10-31 15:08:45,265 [root] DEBUG: Started auxiliary module Human 2017-10-31 15:08:45,265 [root] DEBUG: Started auxiliary module Screenshots 2017-10-31 15:08:45,265 [root] DEBUG: Started auxiliary module Usage 2017-10-31 15:08:45,265 [root] INFO: Analyzer:run: DEFAULT_DLL set to Extraction.dll from package modules.packages.Extraction 2017-10-31 15:08:45,265 [root] INFO: Analyzer:run: DEFAULT_DLL_64 set to Extraction_x64.dll from package modules.packages.Extraction 2017-10-31 15:08:45,280 [lib.api.process] INFO: Successfully executed process from path "C:\Users\benji\AppData\Local\Temp\kronc.mdf" with arguments "" with pid 1336 2017-10-31 15:08:45,280 [lib.api.process] INFO: DLL to inject is dll\Extraction.dll 2017-10-31 15:08:45,280 [lib.api.process] DEBUG: Using QueueUserAPC injection. 2017-10-31 15:08:45,296 [lib.api.process] INFO: Injected into suspended 32-bit process with pid 1336 2017-10-31 15:08:47,296 [lib.api.process] INFO: Successfully resumed process with pid 1336 2017-10-31 15:08:47,296 [root] INFO: Added new process to list with pid: 1336 2017-10-31 15:08:47,312 [root] DEBUG: WoW64 detected: 64-bit ntdll base: 0x774f0000, KiUserExceptionDispatcher: 0x7753bc8a, NtSetContextThread: 0x7753d260, Wow64PrepareForException: 0x74f3e4a0 2017-10-31 15:08:47,312 [root] DEBUG: WoW64 workaround: KiUserExceptionDispatcher hook installed at: 0x160000 2017-10-31 15:08:47,312 [root] DEBUG: CAPE initialised (32-bit). 2017-10-31 15:08:47,328 [root] INFO: Cuckoomon successfully loaded in process with pid 1336. 2017-10-31 15:08:47,328 [root] DEBUG: NtAllocateVirtualMemory hook, BaseAddress:0x310000, RegionSize: 0x63000. 2017-10-31 15:08:47,328 [root] DEBUG: SetInitialWriteBreakpoint: AllocationBase: 0x310000, AllocationSize: 0x63000, ThreadId: 0x778 2017-10-31 15:08:47,328 [root] DEBUG: SetDebugRegister: Setting breakpoint 0 hThread=0xc4, Size=0x2, Address=0x310000 and Type=0x1. Address:0x310000, RegionSize: 0x63000. 2017-10-31 15:08:47,328 [root] DEBUG: SetInitialWriteBreakpoint: AllocationBase: 0x310000, AllocationSize: 0x63000, ThreadId: 0x778 2017-10-31 15:08:47,328 [root] DEBUG: SetDebugRegister: Setting breakpoint 0 hThread=0xc4, Size=0x2, Address=0x310000 and Type=0x1.
Log just ends here. So maybe there is still some instability here.

Here's the sample I was having issues with yesterday. Seems to process fine now.

https://www.virustotal.com/en/file/18a10852b14df97b69243b38b23a573cc89d7629115ee0fefbbd66a00078ea4f/analysis/

@kevoreilly
Copy link
Contributor

Thanks for the sample hash, let me look into it and see if i can work out what's going on.

@kevoreilly
Copy link
Contributor

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.

@kevoreilly
Copy link
Contributor

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?

@enzok
Copy link
Contributor Author

enzok commented Nov 8, 2017

Is the issue with just the 64-bit variant?

@enzok
Copy link
Contributor Author

enzok commented Nov 8, 2017

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?

@kevoreilly
Copy link
Contributor

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.

@kevoreilly
Copy link
Contributor

I just tried on an xp vm, and it doesn't get any further than explorer either...

@enzok
Copy link
Contributor Author

enzok commented Nov 8, 2017

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

@enzok
Copy link
Contributor Author

enzok commented Nov 8, 2017

sha256 not MD5...

@kevoreilly
Copy link
Contributor

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.

@enzok
Copy link
Contributor Author

enzok commented Nov 10, 2017

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.

@kevoreilly
Copy link
Contributor

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.

@enzok
Copy link
Contributor Author

enzok commented Nov 28, 2017

Any luck with this? I haven't had time to look at it too much.

@kevoreilly
Copy link
Contributor

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.

@enzok
Copy link
Contributor Author

enzok commented Nov 28, 2017

No worries. I appreciate any time you have. Thanks.

@kevoreilly
Copy link
Contributor

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

@enzok
Copy link
Contributor Author

enzok commented Jan 30, 2018

Log from the 64-bit Ursnif package. This fails with cuckoo scheduler error - Analysis failed: system restarted unexpectedly

2018-01-29 16:18:32,000 [root] INFO: Date set to: 01-29-18, time set to: 21:18:32
2018-01-29 16:18:32,046 [root] DEBUG: Starting analyzer from: C:\eykaztnkou
2018-01-29 16:18:32,046 [root] DEBUG: Storing results at: C:\ObeNIRRqXC
2018-01-29 16:18:32,046 [root] DEBUG: Pipe server name: \\.\PIPE\DTRbQsrPdF
2018-01-29 16:18:32,046 [root] INFO: Analysis package "Ursnif" has been specified.
2018-01-29 16:18:32,687 [root] DEBUG: Started auxiliary module Auxfile
2018-01-29 16:18:32,687 [root] DEBUG: Started auxiliary module Browser
2018-01-29 16:18:32,703 [modules.auxiliary.digisig] DEBUG: Checking for a digitial signature.
2018-01-29 16:18:33,328 [modules.auxiliary.digisig] DEBUG: File is not signed.
2018-01-29 16:18:33,328 [modules.auxiliary.digisig] INFO: Uploading signature results to aux/DigiSig.json
2018-01-29 16:18:33,328 [root] DEBUG: Started auxiliary module DigiSig
2018-01-29 16:18:33,328 [root] DEBUG: Started auxiliary module Disguise
2018-01-29 16:18:33,328 [root] DEBUG: Started auxiliary module Human
2018-01-29 16:18:33,342 [root] DEBUG: Started auxiliary module Screenshots
2018-01-29 16:18:33,342 [root] DEBUG: Started auxiliary module Usage
2018-01-29 16:18:33,342 [root] INFO: Analyzer: DLL set to Ursnif.dll from package modules.packages.Ursnif
2018-01-29 16:18:33,342 [root] INFO: Analyzer: DLL_64 set to Ursnif_x64.dll from package modules.packages.Ursnif
2018-01-29 16:18:33,390 [lib.api.process] INFO: Successfully executed process from path "C:\Users\barry\AppData\Local\Temp\10348995c8c513d9b92b15272d37055f9488d449f60d0dca976e041e411f55e2.exe" with arguments "" with pid 1016
2018-01-29 16:18:33,390 [lib.api.process] INFO: DLL to inject is dll\uNYDYl.dll
2018-01-29 16:18:33,390 [lib.api.process] DEBUG: Using QueueUserAPC injection.
2018-01-29 16:18:33,390 [lib.api.process] INFO: Option 'exclude-apis' with value 'NtCreateFile:NtWriteFile:NtDeleteFile:NtQueryInformationFile' sent to monitor
2018-01-29 16:18:33,390 [lib.api.process] INFO: Option 'bp0' with value '20196' sent to monitor
2018-01-29 16:18:33,390 [lib.api.process] INFO: Option 'bp1' with value '144369' sent to monitor
2018-01-29 16:18:33,467 [lib.api.process] INFO: Injected into suspended 32-bit process with pid 1016
2018-01-29 16:18:35,467 [lib.api.process] INFO: Successfully resumed process with pid 1016
2018-01-29 16:18:35,467 [root] INFO: Added new process to list with pid: 1016
2018-01-29 16:18:35,562 [root] DEBUG: CAPE debug - unrecognised key bp0.
2018-01-29 16:18:35,562 [root] DEBUG: CAPE debug - unrecognised key bp1.
2018-01-29 16:18:35,625 [root] DEBUG: WoW64 detected: 64-bit ntdll base: 0x77150000, KiUserExceptionDispatcher: 0x0, NtSetContextThread: 0x771a121a, Wow64PrepareForException: 0x0
2018-01-29 16:18:35,625 [root] DEBUG: WoW64 workaround: KiUserExceptionDispatcher hook installed at: 0x2b0000
2018-01-29 16:18:35,625 [root] DEBUG: CAPE initialised (32-bit).
2018-01-29 16:18:35,625 [root] INFO: Cuckoomon successfully loaded in process with pid 1016.
2018-01-29 16:18:40,530 [root] DEBUG: GetReturnAddress: Esp 0x0018FBB0, Ebp 0x0018FEB8.
2018-01-29 16:18:40,530 [root] DEBUG: NtOpenProcess hook: return address 0x00401879, allocation base 0x00400000.
2018-01-29 16:18:42,265 [root] DEBUG: GetReturnAddress: Esp 0x0018FB78, Ebp 0x0018FE80.
2018-01-29 16:18:42,265 [root] DEBUG: NtOpenProcess hook: return address 0x0040312B, allocation base 0x00400000.
2018-01-29 16:18:42,280 [root] INFO: Disabling sleep skipping.
2018-01-29 16:18:42,546 [root] INFO: Announced 32-bit process name: cmd.exe pid: 1840
2018-01-29 16:18:42,546 [lib.api.process] INFO: DLL to inject is dll\uNYDYl.dll
2018-01-29 16:18:42,546 [lib.api.process] DEBUG: Using QueueUserAPC injection.
2018-01-29 16:18:42,546 [lib.api.process] INFO: Option 'exclude-apis' with value 'NtCreateFile:NtWriteFile:NtDeleteFile:NtQueryInformationFile' sent to monitor
2018-01-29 16:18:42,546 [lib.api.process] INFO: Option 'bp0' with value '20196' sent to monitor
2018-01-29 16:18:42,546 [lib.api.process] INFO: Option 'bp1' with value '144369' sent to monitor
2018-01-29 16:18:42,562 [lib.api.process] INFO: Injected into suspended 32-bit process with pid 1840
2018-01-29 16:18:42,578 [root] INFO: Notified of termination of process with pid 1016.
2018-01-29 16:18:42,625 [root] INFO: Process with pid 1016 has terminated
2018-01-29 16:18:42,765 [root] DEBUG: CAPE debug - unrecognised key bp0.
2018-01-29 16:18:42,765 [root] DEBUG: CAPE debug - unrecognised key bp1.
2018-01-29 16:18:42,858 [root] INFO: Disabling sleep skipping.
2018-01-29 16:18:42,905 [root] DEBUG: WoW64 detected: 64-bit ntdll base: 0x77150000, KiUserExceptionDispatcher: 0x0, NtSetContextThread: 0x771a121a, Wow64PrepareForException: 0x0
2018-01-29 16:18:42,905 [root] DEBUG: WoW64 workaround: KiUserExceptionDispatcher hook installed at: 0x160000
2018-01-29 16:18:42,953 [root] DEBUG: CAPE initialised (32-bit).
2018-01-29 16:18:42,953 [root] INFO: Added new process to list with pid: 1840
2018-01-29 16:18:42,953 [root] INFO: Cuckoomon successfully loaded in process with pid 1840.
2018-01-29 16:18:43,078 [root] INFO: Announced 32-bit process name: cmd.exe pid: 2496
2018-01-29 16:18:43,078 [lib.api.process] INFO: DLL to inject is dll\uNYDYl.dll
2018-01-29 16:18:43,078 [lib.api.process] DEBUG: Using QueueUserAPC injection.
2018-01-29 16:18:43,125 [lib.api.process] INFO: Option 'exclude-apis' with value 'NtCreateFile:NtWriteFile:NtDeleteFile:NtQueryInformationFile' sent to monitor
2018-01-29 16:18:43,125 [lib.api.process] INFO: Option 'bp0' with value '20196' sent to monitor
2018-01-29 16:18:43,125 [lib.api.process] INFO: Option 'bp1' with value '144369' sent to monitor
2018-01-29 16:18:43,171 [lib.api.process] INFO: Injected into suspended 32-bit process with pid 2496
2018-01-29 16:18:43,280 [root] DEBUG: CAPE debug - unrecognised key bp0.
2018-01-29 16:18:43,280 [root] DEBUG: CAPE debug - unrecognised key bp1.
2018-01-29 16:18:43,296 [root] INFO: Disabling sleep skipping.
2018-01-29 16:18:43,328 [root] DEBUG: WoW64 detected: 64-bit ntdll base: 0x77150000, KiUserExceptionDispatcher: 0x0, NtSetContextThread: 0x771a121a, Wow64PrepareForException: 0x0
2018-01-29 16:18:43,328 [root] DEBUG: WoW64 workaround: KiUserExceptionDispatcher hook installed at: 0x1a0000
2018-01-29 16:18:43,328 [root] DEBUG: CAPE initialised (32-bit).
2018-01-29 16:18:43,358 [root] INFO: Added new process to list with pid: 2496
2018-01-29 16:18:43,358 [root] INFO: Cuckoomon successfully loaded in process with pid 2496.
2018-01-29 16:18:43,390 [root] INFO: Announced 32-bit process name: Authsitf.exe pid: 548
2018-01-29 16:18:43,390 [lib.api.process] INFO: DLL to inject is dll\uNYDYl.dll
2018-01-29 16:18:43,390 [lib.api.process] DEBUG: Using QueueUserAPC injection.
2018-01-29 16:18:43,405 [lib.api.process] INFO: Option 'exclude-apis' with value 'NtCreateFile:NtWriteFile:NtDeleteFile:NtQueryInformationFile' sent to monitor
2018-01-29 16:18:43,405 [lib.api.process] INFO: Option 'bp0' with value '20196' sent to monitor
2018-01-29 16:18:43,405 [lib.api.process] INFO: Option 'bp1' with value '144369' sent to monitor
2018-01-29 16:18:43,405 [lib.api.process] INFO: Injected into suspended 32-bit process with pid 548
2018-01-29 16:18:43,453 [root] DEBUG: CAPE debug - unrecognised key bp0.
2018-01-29 16:18:43,453 [root] DEBUG: CAPE debug - unrecognised key bp1.
2018-01-29 16:18:43,500 [root] INFO: Disabling sleep skipping.
2018-01-29 16:18:43,500 [root] DEBUG: WoW64 detected: 64-bit ntdll base: 0x77150000, KiUserExceptionDispatcher: 0x0, NtSetContextThread: 0x771a121a, Wow64PrepareForException: 0x0
2018-01-29 16:18:43,546 [root] DEBUG: WoW64 workaround: KiUserExceptionDispatcher hook installed at: 0x2f0000
2018-01-29 16:18:43,592 [root] DEBUG: CAPE initialised (32-bit).
2018-01-29 16:18:43,592 [root] INFO: Added new process to list with pid: 548
2018-01-29 16:18:43,592 [root] INFO: Cuckoomon successfully loaded in process with pid 548.
2018-01-29 16:18:45,905 [root] DEBUG: GetReturnAddress: Esp 0x0018FBB0, Ebp 0x0018FEB8.
2018-01-29 16:18:45,905 [root] DEBUG: NtOpenProcess hook: return address 0x00401879, allocation base 0x00400000.
2018-01-29 16:18:47,280 [root] DEBUG: GetReturnAddress: Esp 0x0018FB78, Ebp 0x0018FE80.
2018-01-29 16:18:47,296 [root] DEBUG: NtOpenProcess hook: return address 0x0040312B, allocation base 0x00400000.
2018-01-29 16:18:47,328 [root] DEBUG: GetReturnAddress: Esp 0x0018FB38, Ebp 0x0018FE40.
2018-01-29 16:18:47,328 [root] DEBUG: NtOpenProcess hook: return address 0x00401A14, allocation base 0x00400000.
2018-01-29 16:18:47,328 [root] DEBUG: GetReturnAddress: Esp 0x0018FB50, Ebp 0x0018FE58.
2018-01-29 16:18:47,342 [root] DEBUG: NtOpenProcess hook: return address 0x004046B9, allocation base 0x00400000.
2018-01-29 16:18:47,342 [root] INFO: Announced 64-bit process name: svchost.exe pid: 2392
2018-01-29 16:18:47,342 [lib.api.process] INFO: DLL to inject is dll\zCeCbj.dll
2018-01-29 16:18:47,342 [lib.api.process] DEBUG: Using QueueUserAPC injection.
2018-01-29 16:18:47,358 [lib.api.process] INFO: Option 'exclude-apis' with value 'NtCreateFile:NtWriteFile:NtDeleteFile:NtQueryInformationFile' sent to monitor
2018-01-29 16:18:47,358 [lib.api.process] INFO: Option 'bp0' with value '20196' sent to monitor
2018-01-29 16:18:47,358 [lib.api.process] INFO: Option 'bp1' with value '144369' sent to monitor
2018-01-29 16:18:47,421 [lib.api.process] INFO: Injected into suspended 64-bit process with pid 2392
2018-01-29 16:18:47,608 [root] INFO: Announced 64-bit process name: svchost.exe pid: 2392
2018-01-29 16:18:47,608 [lib.api.process] INFO: DLL to inject is dll\zCeCbj.dll
2018-01-29 16:18:47,608 [lib.api.process] DEBUG: Using QueueUserAPC injection.
2018-01-29 16:18:47,608 [lib.api.process] INFO: Option 'exclude-apis' with value 'NtCreateFile:NtWriteFile:NtDeleteFile:NtQueryInformationFile' sent to monitor
2018-01-29 16:18:47,608 [lib.api.process] INFO: Option 'bp0' with value '20196' sent to monitor
2018-01-29 16:18:47,608 [lib.api.process] INFO: Option 'bp1' with value '144369' sent to monitor
2018-01-29 16:18:47,703 [root] DEBUG: (0) bp0 set to 0x4ee4
2018-01-29 16:18:47,750 [root] DEBUG: (0) bp1 set to 0x233f1
2018-01-29 16:18:47,765 [root] INFO: Announced 64-bit process name: svchost.exe pid: 2392
2018-01-29 16:18:47,765 [root] INFO: Disabling sleep skipping.
2018-01-29 16:18:47,765 [lib.api.process] INFO: DLL to inject is dll\zCeCbj.dll
2018-01-29 16:18:47,765 [lib.api.process] DEBUG: Using QueueUserAPC injection.
2018-01-29 16:18:47,765 [lib.api.process] INFO: Option 'exclude-apis' with value 'NtCreateFile:NtWriteFile:NtDeleteFile:NtQueryInformationFile' sent to monitor
2018-01-29 16:18:47,780 [lib.api.process] INFO: Option 'bp0' with value '20196' sent to monitor
2018-01-29 16:18:47,780 [lib.api.process] INFO: Option 'bp1' with value '144369' sent to monitor
2018-01-29 16:18:47,812 [root] DEBUG: (2392) CAPE initialised: 64-bit Ursnif package. Loaded at 0x00000000734C0000
2018-01-29 16:18:47,858 [root] INFO: Added new process to list with pid: 2392
2018-01-29 16:18:47,858 [root] INFO: Cuckoomon successfully loaded in process with pid 2392.
2018-01-29 16:18:48,155 [root] INFO: Notified of termination of process with pid 548.
2018-01-29 16:18:48,155 [root] INFO: Notified of termination of process with pid 2496.
2018-01-29 16:18:48,171 [root] INFO: Notified of termination of process with pid 1840.
2018-01-29 16:18:48,203 [root] DEBUG: (2392) lstrcpynA hook: Ursnif payload marker.
2018-01-29 16:18:48,203 [root] DEBUG: (2392) GetReturnAddress: Rsp 0x00000000000AF3A0, Rip 0x00000000734C129A.
2018-01-29 16:18:48,217 [root] DEBUG: (2392) GetHookCallerBase: thread 2488 (handle 0xbc), return address 0x000000000303150B, allocation base 0x0000000003030000.
2018-01-29 16:18:48,217 [root] DEBUG: (2392) FileOffsetToVA: Virtual Address = 0x0000000003035AE4.
2018-01-29 16:18:48,233 [root] DEBUG: (2392) SetDebugRegister: Setting breakpoint 0 hThread=0xbc, Size=0x0, Address=0x0000000003035AE4 and Type=0x0.

@kevoreilly
Copy link
Contributor

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?

@enzok
Copy link
Contributor Author

enzok commented Jan 30, 2018

Sure I'm happy to test it. Thanks.

@enzok
Copy link
Contributor Author

enzok commented Jan 30, 2018

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.

@kevoreilly
Copy link
Contributor

Yeah I've only catered for 64-bit so far. I still need to extend the signature and update the DLL for 32-bit.

@enzok
Copy link
Contributor Author

enzok commented Jan 30, 2018

I used the new DLL, same error: system restarted unexpectedly.

18-01-30 14:35:59,592 [root] DEBUG: (2992) CAPE initialised: 64-bit Ursnif package. Loaded at 0x00000000751C0000
2018-01-30 14:35:59,608 [root] INFO: Added new process to list with pid: 2992
2018-01-30 14:35:59,608 [root] INFO: Cuckoomon successfully loaded in process with pid 2992.
2018-01-30 14:35:59,796 [root] INFO: Notified of termination of process with pid 1164.
2018-01-30 14:35:59,796 [root] DEBUG: (2992) lstrcpynA hook: Ursnif payload marker.
2018-01-30 14:35:59,812 [root] INFO: Notified of termination of process with pid 2604.
2018-01-30 14:35:59,812 [root] DEBUG: (2992) GetReturnAddress: Rsp 0x000000000012F420, Rip 0x00000000751C129A.
2018-01-30 14:35:59,812 [root] DEBUG: (2992) GetHookCallerBase: thread 2996 (handle 0xc0), return address 0x000000000314150B, allocation base 0x0000000003140000.
2018-01-30 14:35:59,812 [root] DEBUG: (2992) FileOffsetToVA: Virtual Address = 0x0000000003145AE4.
2018-01-30 14:35:59,842 [root] DEBUG: (2992) SetDebugRegister: Setting breakpoint 0 hThread=0xc0, Size=0x0, Address=0x0000000003145AE4 and Type=0x0.
2018-01-30 14:35:59,842 [root] DEBUG: (2992) SetDebugRegister: SetThreadContext succeeded.

@kevoreilly
Copy link
Contributor

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...

@enzok
Copy link
Contributor Author

enzok commented Jan 31, 2018

here's results from the 2nd dll you sent me
same error message

2018-01-30 19:09:43,140 [root] DEBUG: (920) CAPE initialised: 64-bit Ursnif package. Loaded at 0x0000000073570000
2018-01-30 19:09:43,171 [root] INFO: Added new process to list with pid: 920
2018-01-30 19:09:43,171 [root] INFO: Cuckoomon successfully loaded in process with pid 920.
2018-01-30 19:09:43,483 [root] DEBUG: (920) lstrcpynA hook: Ursnif payload marker.
2018-01-30 19:09:43,483 [root] INFO: Notified of termination of process with pid 1704.
2018-01-30 19:09:43,483 [root] DEBUG: (920) GetReturnAddress: Rsp 0x000000000028F600, Rip 0x000000007357129A.
2018-01-30 19:09:43,483 [root] INFO: Notified of termination of process with pid 3036.
2018-01-30 19:09:43,483 [root] DEBUG: (920) GetHookCallerBase: thread 2068 (handle 0xbc), return address 0x000000000320150B, allocation base 0x0000000003200000.
2018-01-30 19:09:43,500 [root] DEBUG: (920) FileOffsetToVA: Virtual Address = 0x0000000003205AE4.
2018-01-30 19:09:43,515 [root] DEBUG: (920) SetBreakpoint: About to call SetThreadBreakpoint for thread 2068.
2018-01-30 19:09:43,515 [root] INFO: Notified of termination of process with pid 2864.
2018-01-30 19:09:43,515 [root] DEBUG: (920) SetDebugRegister: Setting breakpoint 0 hThread=0xbc, Size=0x0, Address=0x0000000003205AE4 and Type=0x0.
2018-01-30 19:09:43,530 [root] DEBUG: (920) SetDebugRegister: SetThreadContext succeeded.```

@enzok
Copy link
Contributor Author

enzok commented Feb 1, 2018

I tried running it against a new VM build, but same result.

@kevoreilly
Copy link
Contributor

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?

@enzok
Copy link
Contributor Author

enzok commented Feb 1, 2018

KVM

@enzok
Copy link
Contributor Author

enzok commented Feb 1, 2018

Same result. Not sure if it helps but the Extraction package also terminates unexpectedly. Could it be hypervisor related?

2018-02-01 11:20:15,703 [lib.api.process] INFO: Option 'bp0' with value '20196' sent to monitor
2018-02-01 11:20:15,703 [lib.api.process] INFO: Option 'bp1' with value '144369' sent to monitor
2018-02-01 11:20:15,750 [root] DEBUG: (1712) CAPE initialised: 64-bit Ursnif package. Loaded at 0x00000000734C0000
2018-02-01 11:20:15,921 [root] INFO: Added new process to list with pid: 1712
2018-02-01 11:20:15,921 [root] INFO: Cuckoomon successfully loaded in process with pid 1712.
2018-02-01 11:20:16,171 [root] DEBUG: (1712) lstrcpynA hook: Ursnif payload marker.
2018-02-01 11:20:16,171 [root] INFO: Notified of termination of process with pid 1704.
2018-02-01 11:20:16,171 [root] DEBUG: (1712) GetReturnAddress: Rsp 0x00000000000EF500, Rip 0x00000000734C129A.
2018-02-01 11:20:16,187 [root] INFO: Notified of termination of process with pid 3036.
2018-02-01 11:20:16,187 [root] DEBUG: (1712) GetHookCallerBase: thread 1104 (handle 0xbc), return address 0x0000000001C1150B, allocation base 0x0000000001C10000.
2018-02-01 11:20:16,187 [root] DEBUG: (1712) FileOffsetToVA: Virtual Address = 0x0000000001C15AE4.
2018-02-01 11:20:16,187 [root] DEBUG: (1712) SetDebugRegister: Setting breakpoint 0 hThread=0xbc, Size=0x0, Address=0x0000000001C15AE4 and Type=0x0.
2018-02-01 11:20:16,203 [root] DEBUG: (1712) SetDebugRegister: SetThreadContext succeeded.
2018-02-01 11:20:16,203 [root] INFO: Notified of termination of process with pid 1120.```

@kevoreilly
Copy link
Contributor

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.

@enzok
Copy link
Contributor Author

enzok commented Feb 1, 2018

Two VMs both win7x64 w/SP1 - one has no additional patches, the other has most recent, same behavior from both.

2018-02-01 14:43:31,062 [lib.api.process] INFO: DLL to inject is dll\otzhHB.dll
2018-02-01 14:43:31,062 [root] DEBUG: (2516) CAPE initialised: 64-bit Ursnif package. Loaded at 0x00000000734C0000
2018-02-01 14:43:31,062 [lib.api.process] DEBUG: Using QueueUserAPC injection.
2018-02-01 14:43:31,062 [lib.api.process] INFO: Option 'exclude-apis' with value 'NtCreateFile:NtWriteFile:NtDeleteFile:NtQueryInformationFile' sent to monitor
2018-02-01 14:43:31,062 [lib.api.process] INFO: Option 'bp0' with value '20196' sent to monitor
2018-02-01 14:43:31,062 [lib.api.process] INFO: Option 'bp1' with value '144369' sent to monitor
2018-02-01 14:43:31,203 [root] INFO: Added new process to list with pid: 2516
2018-02-01 14:43:31,203 [root] INFO: Cuckoomon successfully loaded in process with pid 2516.
2018-02-01 14:43:31,390 [root] DEBUG: (2516) lstrcpynA hook: Ursnif payload marker.
2018-02-01 14:43:31,390 [root] INFO: Notified of termination of process with pid 1904.
2018-02-01 14:43:31,390 [root] DEBUG: (2516) GetReturnAddress: Rsp 0x00000000000EF0C0, Rip 0x00000000734C129A.
2018-02-01 14:43:31,390 [root] INFO: Notified of termination of process with pid 2120.
2018-02-01 14:43:31,390 [root] DEBUG: (2516) GetHookCallerBase: thread 2308 (handle 0xb8), return address 0x00000000030A150B, allocation base 0x00000000030A0000.
2018-02-01 14:43:31,405 [root] DEBUG: (2516) FileOffsetToVA: Virtual Address = 0x00000000030A5AE4.
2018-02-01 14:43:31,405 [root] DEBUG: (2516) SetBreakpoint: About to call SetThreadBreakpoint for thread 2308.
2018-02-01 14:43:31,405 [root] DEBUG: (2516) SetThreadBreakpoint: Function entry for thread 2308.
2018-02-01 14:43:31,421 [root] INFO: Notified of termination of process with pid 2544.
2018-02-01 14:43:31,421 [root] DEBUG: (2516) SetThreadBreakpoint: About to create SetBreakpointThread thread.
2018-02-01 14:43:31,421 [root] DEBUG: (2516) SetDebugRegister: Setting breakpoint 0 hThread=0xb8, Size=0x0, Address=0x00000000030A5AE4 and Type=0x0.
2018-02-01 14:43:31,421 [root] DEBUG: (2516) SetDebugRegister: SetThreadContext succeeded.```

@enzok
Copy link
Contributor Author

enzok commented Feb 1, 2018

i'm going to try moving the VM into vmware and see if it still behaves the same

@enzok
Copy link
Contributor Author

enzok commented Feb 8, 2018

haven't had much luck with vmware

@kevoreilly
Copy link
Contributor

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.

@enzok
Copy link
Contributor Author

enzok commented Feb 12, 2018

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.

@kevoreilly
Copy link
Contributor

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/
https://bugzilla.redhat.com/show_bug.cgi?id=1068627
https://patchwork.kernel.org/patch/8436261/

@enzok
Copy link
Contributor Author

enzok commented Feb 13, 2018

I Googled for this, but haven't found anything that spells out a solution.

@enzok
Copy link
Contributor Author

enzok commented Feb 23, 2018

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?

@kevoreilly
Copy link
Contributor

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?

@enzok
Copy link
Contributor Author

enzok commented Mar 5, 2018

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.

@peter9823
Copy link

Trying to get the config from this sample fails:
https://cape.contextis.com/analysis/5415/
2018-03-12 09:59:53,690 [root] DEBUG: (1632) SetInitialBreakpoint: Error - No address specified for Ursnif breakpoints.

@kevoreilly
Copy link
Contributor

Thanks for the notice - I will publish an update on this soon.

@kevoreilly
Copy link
Contributor

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
Ursnif D:\payloads\1f4ab93b10fdf93ff51200991c2a32f90861c8dd3396159d1735198306ac0cb6
0x2a1e2:$crypto64_3: 33 C6 FF C7 49 83 C2 04 33 C3 8B F1 8B CF D3 C8 89 02 48 83 C2 04 41 83 C3 FF 75 D0 45 85 C9 75 1A 41 83 E0 03
0x1f09c:$decrypt_config64: 44 8B D9 33 C0 45 33 C9 44 33 1D 65 A0 01 00 4C 8B D2 48 85 D2 74 37 4C 8D 42 10 45 3B 0A 73 2E 45 39 58 F8 75 1C 41 F6 40 FC 01 74 12

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.

@kevoreilly
Copy link
Contributor

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!

kevoreilly added a commit that referenced this issue Apr 10, 2019
 Fix syntax error is zip analysis package (thanks Sean Whalen)
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

4 participants