The malware in this report has been blogged about before by a Russian researcher1, he referred to is as “Obscene Trojan” so that’s what I will also call it and we will go over it’s functionality in depth later in this blog but the more interesting part to me is the initial layer around the malware, it’s in Golang! This layer serves both as a wrapper layer that you would normally expect to see with crypters but also a dropper as it drops the decoded malware to detonate it instead of loading it into memory but the concept of a golang crypter is interesting nonetheless and after going through all the layers I stepped back and checked what the detection ratings were and was incredibly surprised to find that these wrapper layers took a 12 year old malware from completely detected to almost FUD.

Initial sample: 769d1396b0cef006bcaafd2de850fc97bf51fd14813948ef2bc3f8200bcb5eab

This Golang wrapper is designed to ZLIB decompress and RC4 decrypt the next file hidden inside itself.

Dumping the data blog out we can verify this manually.

>>> open ( 'test.zz' , 'wb' ) . write ( t ) >>> zobj = zlib . decompressobj () >>> t2 = zobj . decompress ( t ) >>> t2 [: 100 ] ' \x9e\xd6\x02\x1e\x19 n \xa0 ^ \xd0\x83 Ga \xcf q \xd6\x08\x94 3 \x00\x7f\xf4 n \x96\x05\xe5\xf7\x8a M8 \x17\x8a\xfb\xe3\\ ]} \x1c 5 \x07\x8d j \xce I \xd2\xae\xfa\x12\xc0\xd6\xd1\xef &N \x8c G[8L \xf3\xb9\x01\xcb d \xab\x8a\x9b\xd5 N % \x80 Q \x8f :` \xce\xc1 P \xb3\x07\xa0 + \x1c\x1e Z \x0c [;W \xbf\xb5 ` \xdb\x9f n \xf0 - \xc4 <R \xf5 ' >>> rc4 = ARC4 . new ( 'vckxjm' ) >>> t3 = rc4 . decrypt ( t2 ) >>> t3 [: 100 ] 'MZ \x90\x00\x03\x00\x04\x00\x00\x00\x00\x00\xff\xff\x00\x00\x8b\x00\x00\x00\x00\x00\x00\x00 @ \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x0e\x1f\xba\x0e\x00\xb4\t\xcd ! \xb8\x01 L \xcd !This program cannot be'

Next layer: 0015001917bc98a899536c6d72fcf0774e5b14ab66f07ccbdc4cc205d70475dd

After decoding the next exe file out we are left with another golang wrapped file that does the same thing as the previous layer but it has a differen’t RC4 key.

Next unpacked file: de2688f007dac98b579d5ed364febc8bb07bc3dc26e4b548d659ecb1974d9f46

This file appears to be a SFX RAR exe but at the end of the day it is also just another layer and is designed to drop an EXE file to disk and detonate it.

Dropped binary: afa085105a16b1284a811da11db2457778c4a267f2fa8a551dec3b8a665c11f9

This file looks like a compiled lua binary but we don’t really need to decompile it as we can see a large base64 blob inside it and a similar looking 6 byte string below it.

<snip> dIMAASIwzdmExocRQqzw0ytzQGCfKbvWFXldCcNuyFmZY0eOxzmzJtMrzn1VV6VBF8hH6CZpopOVvkCx QpeoBQy3fp/3XNCVyDc90aYiPtcwqjfbX3jSEDbspcg8AT08aUmJqm+RU53bFB8u3vL+HQzNNv17YHeX kHA5yz6ttQuwpZ0rzTHvh11DBxVFQwWLaVi1Y718ORqmrc5DcWTMCvEjagiP4qeJWUmP2N0XwQ08fXU1 buFfXfD6xBg8ugXKanSFFTsGuIJIC+QPePPjvTWoeJueb4y5IvPVJUT688HgNTo18eufF2CCyjMs/Zem Xb+7K1DeYNbF/mPbJrcqtovOdd7X4HSwcbh+0MwwWNnWak4kCT/JRumZBztD1iBMuVIJZv0V/48+rBq9 nHigHzW0fv6XFFZhzThqkHx0GEr9i/MMromlXCHSm7A= rc4_key yovzgz tmp_file getenv TEMP tmpname .exe

Base64 decoding and then RC4 decrypting this blob gives us our next binary: 1ca71bba30fb17e83fea05ef5e2d467f86bff27b6087b574fa51f94f0f725441

This binary is the unpacked trojan that a blog from 2008 calls “Obscene Trojan”[1], coincidentally it also has a compilation timestamp of 2008 so I’m unsure if it was just recently uploaded or if someone is testing the crypter layers for detection.

Has some anti debugging by using obscure opcodes that some debuggers can have problems with.

Also a VM check[3].

The malware has most of its important strings encoded using a single byte XOR.

Python > for addr in XrefsTo ( 0x40f09e , flags = 0 ): addr = addr . frm print ( hex ( addr )), addr = idc . PrevHead ( addr ) offset = GetOperandValue ( addr , 0 ) t = GetString ( offset ) t = bytearray ( t ) for i in range ( len ( t )): t [ i ] ^= 2 print ( t ) Python > 0x40f22e L advapi32 . dll 0x40f256 L kernel32 . dll 0x40f27e L GetProcAddress 0x40f2ac L GetEnvironmentVariableA 0x40f2da L WinExec 0x40f308 L CopyFileA 0x40f336 L SetFileAttributesA 0x40f364 L RegSetValueExA 0x40f392 L RegOpenKeyA 0x40f3c0 L RegCloseKey 0x40f3ee L http : // fewfwe . com / 0x40f400 L http : // fewfwe . net / 0x40f421 L cftmon . exe 0x40f442 L spools . exe 0x40f463 L ftpdll . dll 0x40f541 L Software \ Microsoft \ Windows \ CurrentVersion \ Run \ 0x40f5d8 L SYSTEM \ CurrentControlSet \ Services \ Schedule 0x40f68b L SystemDrive 0x40f8c2 L windir 0x40f8de L COMRUTERNAME 0x40f8f0 L \ system32 0x40f911 L USERPROFILE 0x40f938 L \ Local Settings \ Application Data 0x40f97f L \ drivers \ 0x40f9b7 L \ Local Settings \ Application Data \ 0x40f9ef L \ update . dat 0x40fa16 L \ drivers \ 0x40fa2d L sysproc . sys 0x40fa54 L \ mpr . dat 0x40fa7b L \ mpr2 . dat 0x40faa2 L \ mpr32 . dat 0x40fb61 L \ mpz . tmp 0x40fb88 L \ r43q34 . tmp 0x40fda5 L wininet . dll 0x40fdcb L InternetOpenA 0x40fdf7 L InternetOpenUrlA 0x40fe23 L InternetReadFile 0x410007 L Content - Type : application / x - www - form - urlencoded 0x410304 L c : \ stop

There is also an encoded file stored inside of it which was also blogged about in 2008 but was discussed as being downloaded by the previous trojan instead of being dropped directly[2]: f198e63cc1ba3153e27905881bcb8a81fa404f659b846b972b1c8f228e4185d4

The trojan sets the filename that it will have.

This DLL will hook send, WSASend, recv and WSARecv; primarily for harvesting data from traffic over ports 110, 80, 25 and 21. The harvested data is written to files while the main trojan piece will read the files and ship the data off.

Receiving function hooks:

Sending function hooks:

The receiving hook checks which port is being used before harvesting data.

The data being harvested looks like email data which will be written to one of the files.

The send hook function performs similar harvesting but it also has different code for port 21 and 80 traffic. For port 21 it will check for ‘USER’ and ‘PASS’ such as with FTP traffic.

The data will then be harvested.

The data will be written to a different file.

The send hook code will also look for ‘gzip,’ in outbound over port 80 and overwrite it, probably to prevent an Accept-Encoding header from including gzip.

As I mentioned at the beginning of the blog the most interesting aspect of this to me personally is the ability of a few simple wrappers and a golang crypter taking an old malware to almost FUD.

References: