hasherezade / pe-sieve

Scans a given process. Recognizes and dumps a variety of potentially malicious implants (replaced/injected PEs, shellcodes, hooks, in-memory patches).
https://hshrzd.wordpress.com/pe-sieve/
BSD 2-Clause "Simplified" License
3.01k stars 421 forks source link

Mishandling of an injected .NET PE #48

Closed hodgav closed 4 years ago

hodgav commented 4 years ago

Hello, I analyzed a .NET malware. It creates a suspended process, injects a .NET PE into it and resumes execution. SHA256: e31fef0296b867dbce44c50bf2517d7d28df97698c85c0d2f51043eea7846924

When dumping with MegaDumper, a tool for dumping .NET executables, the dumped injected PE from child process seems to work fine.

When using PE-SIEVE (Version 0.2.3.1-i (x86)) I get the following error and the entry point is the wrong one - 'Wrong RVA supplied! RVA is out of image scope!'. Of course, I can't execute the dumped PE.

using PE-Bear, here is the difference in the entry point: https://ibb.co/rdKhJQP

I think it's related to the entry point calculation in .NET executables. I looked at MegaDumper's code, and found that indeed the entry point is calculated in a different way: https://github.com/CodeCracker-Tools/MegaDumper/blob/291f45bb6dd5401c5d9443cfbff0f2e60c7089f0/MegaDumper/MainForm.cs The entry point should point to a jmp to the _CorExe routine.

Apart from that, i also noticed a 1-byte difference in the .text section (compare files and see)

In the following .zip file, you will find

  1. The sample
  2. The dumped PE by PE-SIEVE
  3. PE-SIEVE log (using /imp 1)
  4. The dumped PE by MegaDumper Password: tesla Link: https://ufile.io/e3pw2gt6
hasherezade commented 4 years ago

Thank you for reporting, it will be resolved soon.

hasherezade commented 4 years ago

I checked it quickly, and it seems to be the problem related to the Entry Point only. The Entry Point in .NET binaries is overwritten on run, and PE-sieve leave it as is, while it should be recalculating it.

The other thing - one DWORD difference in the .text section:

diff

it is harmless. It just comes from the fact, that PE-sieve leaves the filled import thunk:

thunk1

while the MegaDumper clears it (sets to the value of the Original Thunk):

megadumper1

hodgav commented 4 years ago

I found using my lab 3 additional samples, each of a different malware family, that behave in the same way - injecting a .NET PE In all of them PE-sieve failed to dump a correct PE and MegaDumper's dump was OK. You can use them for additional tests on this issue. SHA256 Hashes: 47a1ddc6b39252c6541588a519753a1879b855348052382d10d5bf4c0ff09b58 916424c0d9d33236bc24139412f4fcf75668ea0648900807e513a2a46cfbc923 bb14ee4ff23e4b0cb968d5b873ba701cc16ab191f7fdd3d517d37843bef3a632

You can download them here: https://ufile.io/pnv1uzra Password: dotnet

hasherezade commented 4 years ago

Thank you. Yeah, all the .NET samples will have the same issue. I didn't have the time to work on it yet, but soon I will.

hasherezade commented 4 years ago

I still need to implement some additional checks, but for now I made a simple version and it should work (I tested it on all your samples). Please check it out and let me know. :)

Also, FYI: now I have fresh builds available from the build server on every commit to the master, so you can always get the latest version from there.

hodgav commented 4 years ago

Tested all 4 samples - all work fine with the correct entry point. Thank you! :)

hasherezade commented 4 years ago

Thank you!