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

Leave a kudo...