Unpacking NSIS-based Crypter – part 2

After publishing my short tutorial about unpacking NSIS-based crypter I got one more sample from a reader who complained that my method doesn’t work – so I decided to take a look inside. Of course cybercriminals continuously work on improving their tools, so I would not be surprised if they completely replaced the algorithm by something new. However, as we will see, in this case they added just some tiny tricks to mislead.

Before reading this article please refer to the first part for more background information.

Sample:

b9b3a9fac262f36df864fbef767f8ad2 – original sample

Used scripts:

Steps

  1. Decompress

Again we will start from decompressing the original sample. This is the content in the directory of our interest:

folder1.png

2. Find the DLL

The only DLL in this folder is named AnimGif.dll (it’s original name is ContinueAcrefoot.dll). It exports one function: __CPPdebugHook – and we can suspect that  this is the function will be used for extracting the payload:

exported_func.png

Let’s search inside the names of files that are going to be decrypted and loaded:

refered_namesOk, we got some names:

  • “Akmryote.vbkOEvgOYj”
  • “WNshery.jEcychvgOlR”

and the possible key for decrypting the payload:

“SNowcapLithoLabyrinthPerquisiteArroyo”

3. Find the referenced files in the same directory where the DLL is.

File “Akmryote.vbkOEvgOYj” does not exist, but we can suspect that it means the file “Akmryote.vbk”.

file1.png

What about about “WNshery.jEcychvgOlR”? Nothing like this exists in the unpacked directory… We can guess that the file has been renamed. We can go by the hard way and analyze the (obfuscated) unpacking function – or use the shortcut to figure out which of the dropped files is our payload.

We can start by taking a fast look on every file and eliminating those that are for sure not the payload, i.e. images, files containing text etc. We are left with some suspects – and using bytes visualization we can find out more about them.

burks.eey:

enc_burks.eey.png

burks.ujg:

enc_burks.ujg

and the already mentioned file “Akmryote.vbk” looks like this:

enc_Akaryote.vbk

Visual patterns in burks.eey suggests, that it has some padding in between – that is common in PE files – so it will be the first suspect of being the payload.

Files burks.eey and burks.ujg have not only similar names, but also similar sizes, that looks a bit suspicious.

64661 burks.eey
64267 burks.ujg

My guess is that it can be a payload divided into two parts, that is merged and saved under the referenced name, and then unpacked.

Akmryote.vbk  is too small to be the payload and visual patterns suggests that it have different content at the beginning – probably this is the element with functions that are going to be loaded (that part starts from text that is followed by code).

4. Try to crack the payload

Let’s try to crack burks.eey using the known algorithm (nsisdec.py, mode 2) and the found key: “SNowcapLithoLabyrinthPerquisiteArroyo” :

./nsisdec.py –file burks.eey –key “SNowcapLithoLabyrinthPerquisiteArroyo” –mode 2 > out.bin

No luck. The output is nothing like the beginning of the PE file.

./nsisdec.py –file burks.ujg –key “SNowcapLithoLabyrinthPerquisiteArroyo” –mode 2 > out.bin

Now it looks much better – we can see patterns suggesting that it is really a PE file, and the used algorithm is valid:

00000000  61 7a b0 00 03 00 00 00  04 00 00 00 ff ff 00 00  |az..............|
00000010  b8 00 00 00 00 00 00 00  40 00 00 00 00 00 00 00  |........@.......|
00000020  00 00 00 00 00 00 20 20  00 00 00 00 00 00 00 00  |......  ........|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 e8 00 00 00  |................|
00000040  0e 1f ba 0e 00 b4 09 cd  21 b8 01 6c ed 21 54 68  |........!..l.!Th|
00000050  69 73 20 70 72 6f 67 72  61 6d 20 63 61 6e 6e 6f  |is program canno|
00000060  74 20 62 65 20 72 75 6e  20 69 6e 20 44 4f 53 20  |t be run in DOS |
00000070  4d 4f 64 65 2e 0d 0d 0a  24 00 00 00 00 00 00 00  |MOde....$.......|
00000080  ce b7 f2 b5 8a d6 9c e6  8a d6 9c e6 8a d6 9c e6  |................|
00000090  49 d9 93 e6 89 f6 bc e6  49 d9 c3 e6 8b d6 9c e6  |I.......I.......|
000000a0  49 d9 c1 e6 88 d6 9c e6  83 ae 1f e6 89 d6 9c e6  |I...............|
000000b0  83 ae 0f e6 a9 d6 9c e6  8a d6 bd c6 05 d7 9c e6  |................|
000000c0  91 4b 33 e6 de d6 9c e6  91 4b 01 e6 8b d6 9c e6  |.K3......K......|
000000d0  52 69 63 68 8a d6 9c e6  00 00 00 00 00 00 00 20  |Rich........... |
000000e0  20 00 00 00 00 00 00 00  50 45 00 00 4c 01 04 00  | .......PE..L...|

Yet, it is not perfect… The first character of the header is always modified, so we not need to bother about it for now. But in the further part we see some invalid characters, i. e. the second character is small ‘z’ instead of capital ‘Z’ – similarly in the word “Mode” we should not have the capital ‘O’. My guess is that the second character of the key needs a tiny modification:

“SNowcapLithoLabyrinthPerquisiteArroyo” should be: “SnowcapLithoLabyrinthPerquisiteArroyo”

Let’s try!

./nsisdec.py --file burks.ujg --key "SnowcapLithoLabyrinthPerquisiteArroyo" --mode 2 > out.bin

Yes, now it looks fine:

00000000  61 5a 90 00 03 00 00 00  04 00 00 00 ff ff 00 00  |aZ..............|
00000010  b8 00 00 00 00 00 00 00  40 00 00 00 00 00 00 00  |........@.......|
00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 e8 00 00 00  |................|
00000040  0e 1f ba 0e 00 b4 09 cd  21 b8 01 4c cd 21 54 68  |........!..L.!Th|
00000050  69 73 20 70 72 6f 67 72  61 6d 20 63 61 6e 6e 6f  |is program canno|
00000060  74 20 62 65 20 72 75 6e  20 69 6e 20 44 4f 53 20  |t be run in DOS |
00000070  6d 6f 64 65 2e 0d 0d 0a  24 00 00 00 00 00 00 00  |mode....$.......|
00000080  ce b7 f2 b5 8a d6 9c e6  8a d6 9c e6 8a d6 9c e6  |................|
00000090  49 d9 93 e6 89 d6 9c e6  49 d9 c3 e6 8b d6 9c e6  |I.......I.......|
000000a0  49 d9 c1 e6 88 d6 9c e6  83 ae 1f e6 89 d6 9c e6  |I...............|
000000b0  83 ae 0f e6 a9 d6 9c e6  8a d6 9d e6 05 d7 9c e6  |................|
000000c0  91 4b 33 e6 de d6 9c e6  91 4b 01 e6 8b d6 9c e6  |.K3......K......|
000000d0  52 69 63 68 8a d6 9c e6  00 00 00 00 00 00 00 00  |Rich............|
000000e0  00 00 00 00 00 00 00 00  50 45 00 00 4c 01 04 00  |........PE..L...|

Let’s substitute the first character to make the valid header and preview the PE file:

preview

Headers looks good,  but the file is truncated. So, the file burks.ujg contains the first part of the payload – and burks.eey most probably contains the second part. Before the decoding, we should make a merge of both parts in a proper order. Then, we can execute the same script on the merged content:

./nsisdec.py --file merged.bin --key "SnowcapLithoLabyrinthPerquisiteArroyo" --mode 2 > out.bin

Just the first character to modify (‘a’ -> ‘M’) and we can view it again:
payload

Now the payload is complete and valid! Again it is Cerber ransomware – md5=ee927a4cdc1c82f3e9cde4298ea83211 (see also the extracted configuration file [here])

Ending note

The main task is done, but just to be precise let’s take a look at the remaining file: “Akmryote.vbk” and see if it’s structure/method of packing changed. We will use nsisdec.py in mode 1. Casual key for those files is their name (often truncated to some random length).

./nsisdec.py --file Akaryote.vbk --key "Akaryote.vbk" --mode 1 > out.bin

Output:

00000000  43 72 65 61 47 77 5e 47  61 2c 52 7a 79 41 0a 4e  |CreaGw^Ga,RzyA.N|
00000010  47 47 60 58 6f 3f 61 60  6f 77 4f 66 60 77 6d 41  |GG`Xo?a`owOf`wmA|
00000020  67 20 59 03 5c 69 72 74  46 73 62 74 62 23 58 6a  |g Y.\irtFsbtb#Xj|
00000030  4f 78 0a 56 5a 60 7a 40  6f 23 76 65 66 6f 63 0a  |Ox.VZ`z@o#vefoc.|

Beginning (first 4 characters) looks fine, but then the content started to be invalid. For sure key must be truncated (keylen <= 4). After few attempts we can see that the valid length is 3.

./nsisdec.py --file Akaryote.vbk --key "Akaryote.vbk" --mode 1 --maxkey 3 > out.bin
00000000  43 72 65 61 74 65 50 72  6f 63 65 73 73 41 0a 4e  |CreateProcessA.N|
00000010  74 55 6e 6d 61 70 56 69  65 77 4f 66 53 65 63 74  |tUnmapViewOfSect|
00000020  69 6f 6e 0a 56 69 72 74  75 61 6c 41 6c 6c 6f 63  |ion.VirtualAlloc|
00000030  45 78 0a 56 69 72 74 75  61 6c 41 6c 6c 6f 63 0a  |Ex.VirtualAlloc.|
00000040  57 72 69 74 65 50 72 6f  63 65 73 73 4d 65 6d 6f  |WriteProcessMemo|
00000050  72 79 0a 47 65 74 54 68  72 65 61 64 43 6f 6e 74  |ry.GetThreadCont|
00000060  65 78 74 0a 53 65 74 54  68 72 65 61 64 43 6f 6e  |ext.SetThreadCon|

Conclusion

There are various mutation of this packing technique – but many of them follow the same general idea. Sometimes we need to fiddle around a bit to find out the familiar patterns.

 

About hasherezade

Programmer and researcher, interested in InfoSec.
This entry was posted in Malware, Tutorial. Bookmark the permalink.

2 Responses to Unpacking NSIS-based Crypter – part 2

  1. Alexander.K.Polyakov says:

    Here’s another one: http://www.broadanalysis.com/2016/07/11/neutrino-exploit-kit-via-eitest-sends-hancitor-and-downloads-unidentified-malware/ (MD5: c07cf898aff9d0f08af63ce4a919f302)

    Encrypted file: Pickaninny.s

    The key is in Moldwarp.BML, but the first 0x11e bytes need to be dropped.

  2. Thad Drug says:

    7-zip 16.04 on Windows 8 64bit says: Can not open file as archive

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s