Tag: malware

Tạo Local Sinkhole với Fakenet-NG và Python Flask

Trong phân tích malware (đặc biệt là các dòng botnet), thì việc giám sát các giao tiếp của chúng với C&C Server là hết sức quan trọng. Tôi sẽ không đi quá sâu vào phần này bởi vì trên mạng đã có rất nhiều bài viết nói về vai trò của sinkhole trong việc phân tích và giám sát. Có một bài viết rất chi tiết của anh QuangNH tại đây, các bạn có thể đọc và tham khảo.

Đó là sinkhole cỡ lớn, có thể dùng mô hình này để deploy trong thực tế để monitor trên diện rộng.

Nhưng trong quá trình phân tích nhiều khi tôi gặp phải vấn đề chưa thể giải quyết ngay là máy tôi quá yếu (!), không thể chạy chung một lúc nhiều máy ảo (xin hiểu cho, tôi vốn dĩ khắc khổ và dúm dó, nhìn rất là thảm, tiền ăn không có lấy đâu ra tiền nâng cấp máy). Với 4GB Ram và một con Core i5 1.7Ghz, có lẽ tôi không nên kì vọng quá nhiều. Thành tích duy nhất của con máy này là crack được pass WPA2 của nhà hàng xóm trong vòng một đêm (tôi nghi là do yếu tố tâm linh, tôi ăn chay niệm phật nên trời phù hộ).

Nói như vậy chỉ là cái cớ, cái cách tôi sắp mô tả sau đây theo tôi nghĩ thì khá là thích hợp để thực hiện trong môi trường local (quy mô nhỏ), tiện cấu hình và chỉnh sửa trực tiếp.

Tôi sẽ sử dụng 2 thứ:

  • Fakenet-NG của team FLARE : Đây là một tool khá là hay ho, nó có 2 nhiệm vụ chính:
    • Sử dụng 1 Diverter để chuyển hướng các traffic đến địa chỉ mong muốn
    • Có sẵn các Listener trước tương ứng với từng protocol. Trong bài này tôi sử dụng DNSListener để listen và redirect từ một domain C&C về local IP của chính máy tôi đang chạy
  • Python Flask: Flask là một library, hay đúng hơn là một microframework rất phổ biến giúp xây dựng các ứng dụng web trong python. Ngoài ra nó cũng đóng vai trò như một server đơn giản. Lúc đầu tôi phân vân giữa Flask của Python và Sinatra của Ruby, nhưng cuối cùng (lại vì một lý do tâm linh nào đó) tôi chọn Flask. Cách thực hiện với Sinatra cũng không có gì khác biệt lắm.

Okay, mô hình tôi muốn xây dựng là:

  • Host sẵn một webservice bằng Flask: Rất nhẹ và nhanh, không cần yêu cầu cài đặt các ứng dụng đồ sộ như Apache, Nginx,… để host. Với webservice này ta có thể làm khá nhiều việc, từ log lại các thông tin malware gửi lên để phục vụ Reverse, ta cũng có thể thử đóng vai trò C&C server để gửi data xuống để thử control malware, qua đó hiểu hơn về cách mà malware hoạt động.
  • Sử dụng Fakenet-NG để xử lý việc phân giải DNS và redirect request về Flask webservice.

Như vậy là ta đã có một tiny sinkhole :D.

Sau đây là cách làm chi tiết:

Tải về Fakenet-NG (bản release binary hay source code tùy bạn, tôi thì dùng binary vì dạo này bắt đầu có tuổi rồi, không máu me gì nữa, cái gì đơn giản thì tôi dùng). Giải nén ra và vào trong thư mục mới giải nén, các bạn sẽ thấy có 1 folder tên là “configs”, trong này có chứa các file cấu hình để fakenet-NG sử dụng. mặc định nó sẽ sử dụng file default.ini, bạn có thể mở file này ra để thấy được các cấu hình mà fakenet-NG hỗ trợ.

Tôi thì cần tạo 1 file cấu hình mới , đơn giản hơn cấu hình mặc định để phục vụ yêu cầu của tôi, vì vậy tôi tạo một file mới với tên sinkhole.ini chẳng hạn, và nội dung của nó thì như thế này:

#############################################################
# Config for Fakenet
[FakeNet]

DivertTraffic:  Yes

#############################################################
# Config for Diverter
[Diverter]

# Dump packet to pcap
DumpPackets:            Yes
DumpPacketsFilePrefix:  sinkholes

ModifyLocalDNS:         No
StopDNSService:         Yes

RedirectAllTraffic: No
# Set listener for TCP Protocol
DefaultTCPListener: TCPListener

# Ignore some common ports to not diverting traffics
BlackListPortsTCP: 139
BlackListPortsUDP: 53, 67, 68, 137, 138, 1900, 5355

#############################################################
# Config for Listener
# Divert HTTP traffic to local ip
[TCPListener]

Enabled:            True
Port:               80
Protocol:           TCP

# Divert DNS Query to local ip
# So whenever malware queries for malicious domain, fakenet-ng will leads it to our sinkhole
[DNS Server]

Enabled:     True
Port:        53
Protocol:    UDP
Listener:    DNSListener
# Change IP to sinkhole host IP
DNSResponse: 192.168.63.128
NXDomains:   0

Cấu hình này là cấu hình đơn giản nhất, có nghĩa là nó sẽ thực hiện:

  • Redirect toàn bộ traffic TCP trên port 80 về local IP. Bạn có thể thay đổi port tùy ý
  • Phân giải DNS về local IP, bật cái này để có thể track được domain C&C của malware

Ok, save lại và sau đó chạy fakenet-NG với lệnh:

fakenet32(64).exe -c configs\sinkhole.ini

Nó sẽ hiển thị ra như thế này, thông báo rằng 2 port 80 và 53 đã được monitor:

  ______      _  ________ _   _ ______ _______     _   _  _____
 |  ____/\   | |/ /  ____| \ | |  ____|__   __|   | \ | |/ ____|
 | |__ /  \  | ' /| |__  |  \| | |__     | |______|  \| | |  __
 |  __/ /\ \ |  < |  __| | . ` |  __|    | |______| . ` | | |_ |
 | | / ____ \| . \| |____| |\  | |____   | |      | |\  | |__| |
 |_|/_/    \_\_|\_\______|_| \_|______|  |_|.     |_|.\_|\_____|

                         Version  1.0
  _____________________________________________________________
                         Developed by
                      Peter Kacherginsky
       FLARE (FireEye Labs Advanced Reverse Engineering)
  _____________________________________________________________

08/26/17 10:50:09 PM [           FakeNet] Loaded configuration file: configs\sin
khole.ini
08/26/17 10:50:09 PM [          Diverter] Capturing traffic to sinkholes_2017082
6_225009.pcap
08/26/17 10:50:09 PM [           FakeNet] Anonymous TCPListener listener on TCP
port 80...
08/26/17 10:50:09 PM [        DNS Server] Starting...
08/26/17 10:50:09 PM [          Diverter] Starting...
08/26/17 10:50:09 PM [          Diverter] Successfully disabled the service Dnsc
ache.
08/26/17 10:50:10 PM [          Diverter] Successfully stopped the service Dnsca
che.
08/26/17 10:50:10 PM [          Diverter] Diverting ports:
08/26/17 10:50:10 PM [          Diverter] TCP: 80
08/26/17 10:50:10 PM [          Diverter] UDP: 53
08/26/17 10:50:10 PM [          Diverter] Failed to flush DNS cache. (DnsFlushRe
solverCache)
08/26/17 10:50:10 PM [          Diverter] Flushed DNS cache. (ipconfig)

Bây giờ ta tạo một web service nhỏ làm nhiệm vụ nhận request gửi lên, ghi vào log và trả về một đoạn data đơn gian. Code Python:

from flask import Flask, request
import socket
import logging

def getlocalIP():
    return socket.gethostbyname(socket.gethostname())

app = Flask(__name__)

@app.route("/", methods=["POST", "GET"])
def postIndex():
    remote_ip = request.remote_addr
    # Write a log entry
    app.logger.debug("%s -> %s" % (remote_ip, request.__dict__) )
    # Return a simple message to client
    return "Yay! You\'re visiting my tiny sinkhole. I saw that you\'re at %s " % remote_ip

if __name__ == "__main__":
    ip = getlocalIP()
    PORT = 80
    formatter = logging.Formatter("[%(asctime)s] - %(message)s")
    #Log to file
    fileHandler = logging.FileHandler("client.log")
    fileHandler.setLevel(logging.DEBUG)
    fileHandler.setFormatter(formatter)
    app.logger.addHandler(fileHandler)
    #Log to console output
    streamHandler = logging.StreamHandler()
    streamHandler.setLevel(logging.DEBUG)
    streamHandler.setFormatter(formatter)
    app.logger.addHandler(streamHandler)
    # Run in local address with predefined port
    app.run(debug=True, host=ip, port=PORT, threaded=True)

Lưu lại với tên bất kì, vd httpListener.py. Sau đó ta cài Flask bằng pip:

pip install flask

mở cmd, chuyển đến thư mục chứa code vừa tạo và dùng lệnh:

python httpListener.py

Sẽ có hiện thông báo webserver đang chạy trên port 80.

Sử dụng Google Chrome để truy cập vào một website bất kì, ta sẽ thấy hiển thị:

Trong log của fakenet-NG có ghi nhận:

08/26/17 10:50:28 PM [        DNS Server] Received A request for domain 'evil-ur
l.com'.
08/26/17 10:50:28 PM [        DNS Server] Responding with '192.168.63.128'
08/26/17 10:50:28 PM [          Diverter] Modifying outbound external TCP reques
t packet:
08/26/17 10:50:28 PM [          Diverter]   from: 192.168.63.128:49417 -> 192.16
8.63.128:80
08/26/17 10:50:28 PM [          Diverter]   to:   192.168.63.128:49417 -> 192.16
8.63.128:80
08/26/17 10:50:28 PM [          Diverter]   pid:  2184 name: chrome.exe
08/26/17 10:50:28 PM [          Diverter] Modifying outbound external TCP reques
t packet:
08/26/17 10:50:28 PM [          Diverter]   from: 192.168.63.128:49418 -> 192.16
8.63.128:80
08/26/17 10:50:28 PM [          Diverter]   to:   192.168.63.128:49418 -> 192.16
8.63.128:80
08/26/17 10:50:28 PM [          Diverter]   pid:  2184 name: chrome.exe

Trong cửa sổ chạy cmd của flask thì hiện thế này:

Và chúng ta có 1 file log với nội dung như sau:

Như vậy toàn bộ request đến evil-url.com đã được chuyển hướng sang localIP của tôi, từ đây có thể monitor được các hành vi của malware một cách dễ dàng.
Và chúng ta có cả file pcap để thực hiện phân tích gói tin (nếu cần):

Mission accomplished!
Bằng cách này tôi có thể chạy một tiny sinkhole và monitor trên một máy ảo với chỉ 1GB RAM, đồng thời chạy luôn debugger trên máy đó để trace trực tiếp và thay đổi trực tiếp cấu hình sinkhole mỗi khi cần thiết.

Happy Reversing and Best Regards,

Levis

Advertisements

Deobfuscating Javascript Malware

Hello,

I just received a javascript sample, from one of my friends. He said that this sample was sent by an malicious email address. and seem that the bad actors are trying to trick people to click on the file.

THen i quickly open up the file in a text editor, and relized that the file is strongly obfuscated, that can not be read normally. So, to figure out what exactly behind it, i have to deobfuscate javascript. Then the journey begins.

The code: http://pastebin.com/uk0vk3VT ( i can’t post the code here because it’s too long
Meh, >5000 lines of code, and mostly are seem nonsense. But, i noticed on the top of the code:


function f(s) {return eval(s);};

It uses eval() to execute a variable s. And at the very last of the file, i saw:

if (c["length"] >= 12) f(c);

It calls f with c as the input. And from the line 5664 to 5670, i got:

b = aj85dZA;
b = b"join";
b = b"split";
b = b"join";
b = b"split";
c = b"reverse";
c = c"join";

It takes all the data of the huge chunk above and do some tasks. I’m to lazy in this phase to rewrite the code, so i use Chrome, with a little trick, change:

function f(s) {return eval(s);};

to
function f(s) {return document.write(s);};
So when we execute the code, it will prints out the value of s, rather than execute it. So we can get another piece of code for the next phase. Fire up Chrome -> F12 -> Paste the modified code -> Enter, and:

js_decoded_phase1
Pretty easy, eh? Phase 1 completed. But still, the code is obfuscated. We got more, but seem to be really ugly since it is unstructured. I use Jsbeautifier to clean up and restructure it, for a better view. In a second, we have:

Full code is at: http://pastebin.com/p332nWSa (sorry, because i don’t want to make this post to be very long)

From there, why can’t i use Chrome to evaluate the code? Simply i don’t have any idea about the code, so better not run it, because it’s too complicated to set a breakpoint or trace down. So, what did i do?

In the very beginning of the code, i see a lot of variables which are strings. Seem that they’re originally a word, but now that word is splitted into pieces, each one is stored in a dedicated variable, and the variable’s name is randomized. So, i started to think that, i need to reformat all the name of those variables.

The scheme is simple, rename the variable name, according to its value. Just need a text editor, anyone that can perform search and replace, and replace them all in whole document. In this case, i choose sublime, and it consumes a lot of time to finish the task, because i have to do a lot of steps with mouse, not the hotkey. I believe that some other editors that can do better.

Start the boring task
Start the boring task

After a while, 20-30 mins, maybe, i replace all the name of variables which store readable strings. Phew, i can believe that i have done a most-boring-task-ever. Then i quickly scroll down in the file, i got a diamond:

Voila
Voila

So, what can you see in there? Yeah, i think that you saw some interesting things here. We have some sensitive data hare. I did the magic with just “Search and Replace”. Now the next job is combine them together and make it rocks. Delete the plus (“+”) sign, or better rewrite the code based on what you actually saw, now everything is clearly, even a kid can do that, like a tetris game.

The obfuscation scheme is:

  • Split sensitive strings into pieces, and then obfuscate the name.
  • Use many junk code to make it harder to read. You can read the code that it makes some function that only return the input “as it”.
  • Use Object[“MethodName”]() instead of the traditional object.methodName(). So it’s really hard to keep up with.

Next to it, i got:

Maliciouse URLs
Maliciouse URLs

Now we have the malicious URLs. There are 3, from the first time i saw them, they’re still active, but in this time, they removed the file from the server (just 3 days ago). Anybody interested, just do a whois.

List of malicious URLS:

http://sirimba.com.br/qiovtl
http://zakagimebel.ru/krcsvf
http://repair-service.london/uywgi7v

 

The fully cleaned the code i posted to gist. I built it truely from the obfuscated code. Now it’s fully readable. Mission accomplished. Nothing special, just “Search and replace”, and then tidy up the code.

From the code, I can know that it create some WScript objects, connects to the server and download file to %TEMP%, with the name 0ttyR4ET9BxiI.exe. This file is encrypted, the decryption code is right below of the main function. I decrypted it and uploaded to virustotal, in Jul 12, only 17 AV Detected, but to Jul 13, the number is 31 (link). It’s a ransomware (a new variant?). I want to post about analysis result here, but, seem to be enough, maybe in the next post, we will dissect it and make the fun.

Any request for the decrypted malware, feel free to mail me (Posting it right here is not a good idea).

Enjoy and stay safe,

Regards,
Levis

 

Unpacking Malware with dnSpy

Lần đầu làm chuyện ấy…

À ý tôi là làm video thuyết minh tiếng Việt, nên rất là run và có chút bẽn lẽn. Trước đây tôi làm tiếng Anh thì quen hơn nhiều, chứ còn tiếng Việt thì rất hay nói lỗi bởi vì có mấy thuật ngữ tôi không bao giờ dịch sang tiếng Việt, cũng không biết giải thích theo nghĩa tiếng Việt như thế nào nữa, cho nên rất là bối rối, mong các bạn bỏ quá cho.  Xin hay ủng hộ tôi, chỉ cần một comment “hjhj d0 ng0’k” hoặc “bố em hút rất nhiều thuốc” thôi là đã thấy yêu thương vô hạn lắm rồi. Cảm ơn

Ở trong video này chúng ta sẽ cùng sử dụng dnSpy để unpack 1 dạng unknown packer được sử dụng bởi 1 mẫu malware giả mạo Steam Client, mà một người bạn gửi cho tôi. Đây (có lẽ) là phần 1, nếu có thời gian tôi sẽ tiếp tục phân tích tiếp, và tất nhiên sẽ cố gắng làm full hd không che như thế này.

Note: Dạo gần đây tôi phát hiện khá nhiều mẫu, sử dụng .NET để làm wrapper để vượt mặt các Antivirus, vì việc detect mấy kiểu file .NET tôi có cảm giác như các hãng AV đang làm khá mơ hồ, đơn cử như trong mẫu này, file unpack ra mới chỉ có 8 AV phát hiện ra dưới dạng tên chung chung kiểu MSIL/Injector, hay Trojan.Gen,… Link scan trên virustotal có tại đây.

Thực sự rất đáng báo động, vì bây giờ đa pần các thế hệ windows mới (7,8/8.1,10) có sắn .NET đi kèm, vậy nên cái risk khá là cao. Khi mà phần lớn các AV đều chưa nhận diện tốt các loại malware thế này. .NET Wrapper có thể làm nhiệm vụ anti-AV hoặc detect xem có đang bị analysis hay không, sau đó mới drop các “em bé” thứ thiệt xuống (điển hình là trong vụ malware skype vừa qua, tôi có những mẫu đầu tiên và đã phân tích hoàn chỉnh chúng hồi đầu tháng 5, là những mẫu wrapper sử dụng Confuser/ConfuserEx). Thực sự rất là quan ngại sâu sắc lắm

Các yêu cầu về mẫu malware, xin vui lòng liên hệ qua email.

Enjoy and stay safe,

Levis

[Show up] WhiteHat Grand Prix 2014 Final RE400 Challenge

Xin chào các bạn

Đây là 1 video show up tiếp theo, cũng là để kết thúc cho việc writeup GrandPrix.

Bài RE400 này cũng là trích xuất từ 1 loại malware .NET, 1 dạng dropper khá thông dụng, cho nên bên cạnh việc tìm flag, tôi đã cố gắng phân tích nhiều hơn để có thể chia sẻ với các bạn về phương pháp decrypt code, chắc chắn sẽ hữu dụng trong việc phân tích các loại malware .NET sau này.

Tôi đã từng gặp 1 số loại malware sử dụng phương pháp decrypt và drop/execute tương tự (điển hình là con malware được embed trong IDM Silent mà tôi đã có 1 bài phân tích ở ĐÂY).

Thể loại malware .NET càng ngày càng trở nên phổ biên hơn bởi vì chúng được build rất nhanh chóng và dễ dàng, lại được .NET Framework hỗ trợ quá mạnh về mặt tính năng, nên có thể nói là kẻ xấu chỉ cần nghĩ ra ý tưởng, sau đó click, click trong VS và .NET Framework sẽ hoàn thành nốt những gì chúng muốn.

Nếu nói rằng .NET malware không mạnh và nguy hiểm bằng các loại malware native khác, thì cũng không sai, nhưng cũng không hoàn toàn đúng. Cryptographic Locker là 1 loại ransomware tương tự như CryptoLocker, và nó được viết bằng Visual Basic .NET.

Vậy nên, bên cạnh việc tìm flag, hãy chú ý vào phương pháp thực hiện. FIle RE400 và code decrypt các bạn có thể down ở ĐÂY. Và dưới đây là video:

Enjoy and best Regards,

Levis

Malware analyzing – Hello world with IDM Silent Plus Malwares

These days i joined a small campain which its main goal is to find and clear out the malware embeded inside a Cracked IDM package released by some VNese guys with name “IDM Silent Plus vx.xx”. This is very interesting because it’s my first time dealing with malware analysis. Still not completed yet, but i create this note to show my result.

 

 

At the first time, a RCE Guru (TQN) warned that the malicious application is located in folder %windir%\System32\Microsoft .NET Framework v4.5.1\Application.exe. This folder is set to Hidden and System attribute, so we could remove these attribute to get the file. When i tried to extract the idm package which contains this file, in a xpsp3 vm, i could not grab it (later i discovered that it had some anti-VM code, so the file actually won’t run). So i asked some other guy who are also analyzing it, to give me that file, to start. After a while, they gave me an archive which has Application.exe inside. And then i start analyzing.

 

 

i Scanned it using some scanner, this file is written in dotNET (vb.net, i assume that) and was protected by DeepSea Obfuscator. So i quickly threw it into de4dot to have a clean file, which is easier to read the code. After de4dot finished its job, i got a cleaned file, and then i opened this file in .NET Reflector (because it’s .NET). The first thing i did is take a look at the entrypoint of that file:

 

in this picture, it’s trying to invoke some method in GClass7, the name of that method was changed by the obfuscator. It’s not a big deal, just follow the call:

 

Here you can see that there is a string, a warning message if debugger is detected. And we have an ‘if’ statement block above. Another call? yeah, it’s another call. Keep following the code inside that call. And what we got is a bunch of code, and these code are used for anti-debugging, you can see that they invoke some winapi like isDebuggerPresent, CheckRemoteDebuggerPresent, EnumWindows. These tricks are very very useless with a .NET Application,lol. so nothing interesting here, just come back to the code at its entrypoint.We have another one call to GClass0.u(). Follow it and we see some code. Seem that this malware is trying to create some threads and execute them. And the thread proc is GClass0.c(). One more time, follow the call.

 

The picture shows the code in GClass0.c(). The one interesting line at the bottom of the method body. It calls a method: Class1.p(). What does Class1.p() actually do? Follow it, again. but we got nothing. The body of p is blank. Don’t give up, we should analyze Class1. So i browse all the method inside Class1, and get a good news in constructor method .cctor():

static Class1()

{

p = (b) Delegate.CreateDelegate(typeof(b), Class4.O, "doua");

}

 

 

So p is a delegate of a method called “doua”, and the method is located in Class4.O(). but in Class4.O(), we see nothing. And again, take a look at .cctor() method of Class4:

static Class4()

{

O = ((Class3.D) Delegate.CreateDelegate(typeof(Class3.D), typeof(Assembly).GetMethod("Load", new Type[] { typeof(byte[]) })))(Class0.L()).GetType("simplu.una");

}

The code is a bit complicated, so i will describe what it does here:- Malware will try to use Assembly.Load() to load a data stream defined by Class0.L() with name “simplu.una”.- After assembly is loaded, it creates a delegate to invoke a method with name “doua” in that assembly.

 

 

So, how we can take that assembly out to browse code of doua()? Follow Class0.L(). and you will see a extreme long string with the common schema. It’s a base64 encoded string! So we need to decode it to see the real data. Because the string is very long, so i copied to a file, named file.txt (http://pastebin.com/16iBzrtu), and made a small python script to decode and save to file:

 

 

Python code:

 


import base64

f = open("file.txt", "r")

string = f.read()

f.close()

f2 = open("newdll.dll", "wb")

f2.write(base64.b64decode(string))

f.close()

 

 

Save code and run, we got a new file named newdll.dll, and it’s the assembly which we’re looking for. This one is coded in .NET with no obfuscation, so we can easily browse the code when drop into .NET Reflector. After load that file in .NET Reflector, i start searching for method named “doua”. And it’s in a class named “una”. in doua(), you will see a lot of code, and some anti-VM and anti-sandboxies code, if detected, the malware would not run:

 

 

But those code is not as important as this one:


int timestamp = GetTimestamp();

Pack pack = new Pack();

byte[] data = ReadManagedResource(timestamp.ToString(CultureInfo.InvariantCulture));

object[] objArray = pack.Deserialize(Decrypt(data, timestamp.ToString(CultureInfo.InvariantCulture)));

FileData = (byte[]) objArray[0];

int num2 = (int) objArray[1];

int num3 = num2 * 5;

bool flag3 = (bool) objArray[2 + num3];

bool flag4 = (bool) objArray[3 + num3];

byte num4 = (byte) objArray[4 + num3];

bool flag5 = (bool) objArray[5 + num3];

string caption = objArray[6 + num3].ToString();

string text = objArray[7 + num3].ToString();

bool flag6 = (bool) objArray[8 + num3];

bool flag7 = (bool) objArray[9 + num3];

bool flag8 = (bool) objArray[10 + num3];

bool flag9 = (bool) objArray[11 + num3];

string uriString = (string) objArray[12 + num3];

string pass = (string) objArray[13 + num3];

bool flag10 = (bool) objArray[14 + num3];

bool flag11 = (bool) objArray[15 + num3];

int num5 = (int) objArray[0x10 + num3];

bool flag12 = (bool) objArray[0x11 + num3];

injectionPath = string.Empty;

Seem that it trying to get Resource in the file and decrypt the data, resource name is defined by Timestamp.ToString(CultureInfo.InvariantCulture). The GetTimeStamp() method is a type of checksum function which reads the value of specified memory address of program at runtime. But in .NET, it’s a bit harder to debug, so we can not get the value directly. So what will we do now?
Remember that doua() is used via a delegate of Application.exe. So it will takes resource of Application.exe instead of simplu.dll( the dll contains doua()) (although, the resource of simplu.dll also very supicious, i will talk later). The name is a constant and not changed in runtime, so maybe the name of resource in Application.exe is the value of timestamp. Browse the resource section of Application.exe, inside Reflector. There is only one resource with name 1406429313. So what i’ve thought above seem to be correct. let’s view the resource, we only see a very big (and complicated) data.

 

So this must be encrypted data, we have to find a way to decrypt it. go back to doua() and keep focus on the code i posted before (i copied it here to get a better look)

 


int timestamp = GetTimestamp();

Pack pack = new Pack();

byte[] data = ReadManagedResource(timestamp.ToString(CultureInfo.InvariantCulture));

object[] objArray = pack.Deserialize(Decrypt(data, timestamp.ToString(CultureInfo.InvariantCulture)));

FileData = (byte[]) objArray[0];

int num2 = (int) objArray[1];

int num3 = num2 * 5;

bool flag3 = (bool) objArray[2 + num3];

bool flag4 = (bool) objArray[3 + num3];

byte num4 = (byte) objArray[4 + num3];

bool flag5 = (bool) objArray[5 + num3];

string caption = objArray[6 + num3].ToString();

string text = objArray[7 + num3].ToString();

bool flag6 = (bool) objArray[8 + num3];

bool flag7 = (bool) objArray[9 + num3];

bool flag8 = (bool) objArray[10 + num3];

bool flag9 = (bool) objArray[11 + num3];

string uriString = (string) objArray[12 + num3];

string pass = (string) objArray[13 + num3];

bool flag10 = (bool) objArray[14 + num3];

bool flag11 = (bool) objArray[15 + num3];

int num5 = (int) objArray[0x10 + num3];

bool flag12 = (bool) objArray[0x11 + num3];

injectionPath = string.Empty;</blockquote>

 

These code:


Pack pack = new Pack();

byte[] data = ReadManagedResource(timestamp.ToString(CultureInfo.InvariantCulture));

object[] objArray = pack.Deserialize(Decrypt(data, timestamp.ToString(CultureInfo.InvariantCulture)));

 

 

The malware created a new object using class Pack. this object will be used to deserializethe decrypted data into an object array. I will re-build this class with my code to make it do the right job for me. Then the malware will read and take resource (encrypted data) out, then save it to a byte array. Call the Decrypt() method with 2 parameters: encrypted data and Timestamp (must be a key string for decryption method). we have value of timestamp – 1406429313, so the key is also “1406429313”. After decryption done, all the data will be splitted into array of object using method Deserialize() in class Pack.These code:

 

FileData = (byte[]) objArray[0];</pre>

int num2 = (int) objArray[1];

int num3 = num2 * 5;

bool flag3 = (bool) objArray[2 + num3];

bool flag4 = (bool) objArray[3 + num3];

byte num4 = (byte) objArray[4 + num3];

bool flag5 = (bool) objArray[5 + num3];

string caption = objArray[6 + num3].ToString();

string text = objArray[7 + num3].ToString();

bool flag6 = (bool) objArray[8 + num3];

bool flag7 = (bool) objArray[9 + num3];

bool flag8 = (bool) objArray[10 + num3];

bool flag9 = (bool) objArray[11 + num3];

string uriString = (string) objArray[12 + num3];

string pass = (string) objArray[13 + num3];

bool flag10 = (bool) objArray[14 + num3];

bool flag11 = (bool) objArray[15 + num3];

int num5 = (int) objArray[0x10 + num3];

bool flag12 = (bool) objArray[0x11 + num3];

injectionPath = string.Empty;
 

 

The decrypted data stored in object array before now will be assigned to each separate variables and will be used to control the malware activities. you will see that in code of doua() it will use these variable to define where to drop malware, which to drop, and how to execute newly dropped file. So we have to get all the value of these variables, to define what will actually do. And a small notice with the variable named “fileData”, it should be another malware which will be dropped onto the computer, with specified path. So, i will create a small decryptor in C# to make them automatically. Our decryptor will decrypts the resource and extracts the fileData, also shows the value of all variables.But before we get started with coding, there is one more thing to determine, that is the algorithm used to decrypt. Pretty simple, follow the call to Decrypt() to view code, and we know it’s DES.

 

 

now the time to build a decryptor. I ripped almost the code from this malware, and it’s pretty easy to understand. the code i pasted it here: http://pastebin.com/RhB9YPJ0

/*
 * Created by SharpDevelop.
 * User: Levis
 * Date: 13/08/14
 * Time: 8:21 AM
 * 
 * For further information or any question, contact me: levintaeyeon@live.com or Skype: levintaeyeon
 * My personal Blog: http://www.ltops9.wordpress.com
 ^ Team REPT Official Website: http://www.team-rept.com 
 */
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Security.Cryptography;

namespace get_decrypted_flag
{
    class Program
    {
        public static void Main(string[] args)
        {
            string Magic_value = "1406429313";
            Pack pack = new Pack();
            byte[] inputfile = File.ReadAllBytes(Magic_value);
            object[] objArray =pack.Deserialize(Decrypt(inputfile,Magic_value));
            byte[] FileData = (byte[]) objArray[0];
            int num2 = (int) objArray[1];
            int num3 = num2 * 5;
            bool flag3 = (bool) objArray[2 + num3];
            bool flag4 = (bool) objArray[3 + num3];
            byte num4 = (byte) objArray[4 + num3];
            bool flag5 = (bool) objArray[5 + num3];
            string caption = objArray[6 + num3].ToString();
            string text = objArray[7 + num3].ToString();
            bool flag6 = (bool) objArray[8 + num3];
            bool flag7 = (bool) objArray[9 + num3];
            bool flag8 = (bool) objArray[10 + num3];
            bool flag9 = (bool) objArray[11 + num3];
            string uriString = (string) objArray[12 + num3];
            string pass = (string) objArray[13 + num3];
            bool flag10 = (bool) objArray[14 + num3];
            bool flag11 = (bool) objArray[15 + num3];
            int num5 = (int) objArray[0x10 + num3];
            bool flag12 = (bool) objArray[0x11 + num3];
            File.WriteAllBytes("Decrypted-malware.bin",FileData);
            Console.WriteLine("num2: " +num2.ToString());
            Console.WriteLine("num3: " +num3.ToString());
            Console.WriteLine("flag3: " +flag3.ToString());
            Console.WriteLine("flag4: " + flag4.ToString());
            Console.WriteLine("num4: " +num4.ToString());
            Console.WriteLine("flag5: " +flag5.ToString());
            Console.WriteLine("Flag6: " +flag6.ToString());
            Console.WriteLine("flag7: " +flag7.ToString());
            Console.WriteLine("flag8: " +flag8.ToString());
            Console.WriteLine("flag9: " +flag9.ToString());
            Console.WriteLine("flag10: "+flag10.ToString());
            Console.WriteLine("flag11: "+flag11.ToString());
            Console.WriteLine("flag12: "+flag12.ToString());
            Console.WriteLine("num5: " +num5.ToString());
            Console.WriteLine("uriString: "+uriString);
            Console.WriteLine("Pass: "+pass);
            Console.WriteLine("Caption: "+caption);
            Console.WriteLine("Text: " +text);
            Console.ReadKey(true);
        }
        private static byte[] Decrypt(byte[] data, string pass)
        {
            byte[] src = new MD5CryptoServiceProvider().ComputeHash(Encoding.UTF8.GetBytes(pass));
            byte[] dst = new byte[8];
            Buffer.BlockCopy(src, 0, dst, 0, dst.Length);
            DESCryptoServiceProvider provider2 = new DESCryptoServiceProvider {
                Key = dst,
                IV = dst,
                Mode = CipherMode.CBC
            };
            return provider2.CreateDecryptor().TransformFinalBlock(data, 0, data.Length);
        }

    }
    
    
    public class Pack
    {
        public Pack()
        {
            Dictionary<Type, byte> dictionary = new Dictionary<Type, byte>();
            dictionary.Add(typeof(bool), 0);
            dictionary.Add(typeof(byte), 1);
            dictionary.Add(typeof(byte[]), 2);
            dictionary.Add(typeof(char), 3);
            dictionary.Add(typeof(char[]), 4);
            dictionary.Add(typeof(decimal), 5);
            dictionary.Add(typeof(double), 6);
            dictionary.Add(typeof(int), 7);
            dictionary.Add(typeof(long), 8);
            dictionary.Add(typeof(sbyte), 9);
            dictionary.Add(typeof(short), 10);
            dictionary.Add(typeof(float), 11);
            dictionary.Add(typeof(string), 12);
            dictionary.Add(typeof(uint), 13);
            dictionary.Add(typeof(ulong), 14);
            dictionary.Add(typeof(ushort), 15);
            dictionary.Add(typeof(DateTime), 0x10);
        }
        public object[] Deserialize(byte[] data)
        {
            MemoryStream input = new MemoryStream(data);
            BinaryReader reader = new BinaryReader(input, Encoding.UTF8);
            List<object> list = new List<object>();
            byte num = reader.ReadByte();
            for (int i = 0; i <= (num - 1); i++)
            {
                switch (reader.ReadByte())
                {
                    case 0:
                        list.Add(reader.ReadBoolean());
                        break;
        
                    case 1:
                        list.Add(reader.ReadByte());
                        break;
        
                    case 2:
                        list.Add(reader.ReadBytes(reader.ReadInt32()));
                        break;
        
                    case 3:
                        list.Add(reader.ReadChar());
                        break;
        
                    case 4:
                        list.Add(reader.ReadString().ToCharArray());
                        break;
        
                    case 5:
                        list.Add(reader.ReadDecimal());
                        break;
        
                    case 6:
                        list.Add(reader.ReadDouble());
                        break;
        
                    case 7:
                        list.Add(reader.ReadInt32());
                        break;
        
                    case 8:
                        list.Add(reader.ReadInt64());
                        break;
        
                    case 9:
                        list.Add(reader.ReadSByte());
                        break;
        
                    case 10:
                        list.Add(reader.ReadInt16());
                        break;
        
                    case 11:
                        list.Add(reader.ReadSingle());
                        break;
        
                    case 12:
                        list.Add(reader.ReadString());
                        break;
        
                    case 13:
                        list.Add(reader.ReadUInt32());
                        break;
        
                    case 14:
                        list.Add(reader.ReadUInt64());
                        break;
        
                    case 15:
                        list.Add(reader.ReadUInt16());
                        break;
        
                    case 0x10:
                        list.Add(DateTime.FromBinary(reader.ReadInt64()));
                        break;
                }
            }
            reader.Close();
            return list.ToArray();
        }


    }
}

 

After compiling code, then we have to extract the resource of Application.exe in Reflector and save with its name (1406429313). Copy that file to the same folder with our decryptor and run the decryptor, we will get a dumped file and all the value of variables will be shown in the console screen, like this:

 

 

We’re doing well. But right now i don’t have idea to dealing with the Decrypted-malware.bin (originally named hi.exe) which is just dumped by decryptor (another obfuscated .NET baby). Also take a look at resource section of the simplu.dll (which contains the doua() method), you will see another .NET file (named newfile.dll, no obfuscated). That’s all i’ve got so far, and i’m still analyzing that 2 files. I think this enough to stop this note. New information maybe added in another post, in future.

Here you can download the entire project which i did (malware sample + some extracted malware + decryptor source + IDM setup package):

CRITICAL CAUTION: BECAUSE THIS IS MALWARE ANALYSIS, SO YOU MUST HAVE BASIC KNOWLEDGE BEFORE DOWNLOAD THESE FILES AND USE THEM IN YOUR OWN RISK!!! I WILL NOT TAKE ANY RESPONSIBILITIES IF YOUR COMPUTER WAS INFECTED.

DOWNLOAD LINK (PASSWORD: silentisfake)

 

Regards,

Levis