Friday, July 11, 2014

Basic Dynamic Analysis: Sandbox

Dynamic analysis là bất cứ quá trình phân tích nào được thực hiện sau khi thực thi malware. Dynamic analysis techniques là bước thứ hai trong quá trình phân tích malware. Dynamic analysis thường được thực hiện sau basic static analysis đã được thực hiện xong, có hay không obfuscation, packing hoặc là việc phân tích đã tận dụng hết các kĩ thuật phân tích tĩnh chưa. Nó có thể yêu cầu monitering malware khi nó runs hoặc là kiểm tra hệ thống sau khi malware đã được thực thi.

Không giống như static analysis, dynamic analysis giúp bạn quan sát được các chức năng thực sự của malware, bởi vì, cho ví dụ, sự tồn tại của một action string trong một binary không có nghĩa là action sẽ thực sự được thực thi. Dynamic analysis còn là một cách hiệu quả để nhận dạng những chức năng mà malware thực hiện. Cho ví dụ, nếu malware của bạn là một keylogger, dynamic analysis có thể cho phép bạn tìm được vị trí của keylogger's log file trên hệ thống, phát hiện ra những kiểu records nó giữ, giải mã được nơi nó gửi thông tin của nó, và còn nhiều thứ khác. Những kiểu thông tin như vầy có thể rất khó có được khi ta chỉ sử dụng basic static techniques.

Mặc dù dynamic analysis techniques là cực kì mạnh mẽ, chúng chỉ nên được thực hiện sau khi basic static analysis đã được hoàn thành, bởi vì dynamic analysis có thể đặt mạng và hệ thống của bạn vào mối nguy hiểm. Dynamic techniques cũng có những giới hạn của chúng, bởi vì không phải tất cả code paths có thể thực thi khi một mảnh malware được run. Cho ví dụ, trong trường hợp command-line malware mà yêu cầu arguments, mỗi argument có thể thực thi các chức năng khác nhau của chương trình, và nếu không biết về options bạn không thể nào phân tích động tất cả các chức năng của chương trình. Bạn có thể cần sử dụng advanced dynamic hoặc static techniques để tìm ra cách làm cho malware thực thi tất cả các chức năng của nó. Bài viết này mô tả basic dynamic analysis techniques.

Sandboxes: The Quick-and-Dirty Approach

Một vài sản phầm phần mềm "tất cả trong một" có thể được sử dụng để thực hiện basic dynamic analysis, và phổ biến nhất là sử dụng sandbox. sandbox là một cơ chế bảo vệ (security mechanism) dành cho việc running các chương trình không đáng tin mà không phải lo sợ nó ảnh hưởng đến các hệ thống thực. Sandboxes bao gồm các môi trường được ảo hóa mà thường mô phỏng các dịch vụ mạng theo một vài kiểu mẫu nào đó để đảm bảo rằng phần mềm  hoặc là malware được tested sẽ hoạt động bình thường.

Using a Malware Sandbox

Nhiều malware sandboxes - như là Norman SandBox, GFI Sandbox, Anubis, Joe Sandbox, ThreatExpert, BitBlaze, và Comodo Instant Malware Analysis - sẽ phân tích malware miễn phí. Hiện tại, Norman Sandbox và GFI Sandbox (ban đầu có tên là CWSandbox) là 2 sandboxes phổ biến nhất.

Các sandboxes  cung cấp output dễ hiểu và là thích hợp cho bước phân loại ban đầu, miễn là bạn submit malware của mình lên sandbox websites. Mặc dù sandboxes được tự động, bạn có thể chọn để không phải submit malware chứa thông tin về công ty lên public website.

Hầu hết sandboxes làm việc tương tự như nhau, vì vậy tôi sẽ thảo luận về một sandbox, GFI sandbox. Figure 4-1 hiển thị bảng nội dung của một PDF report được sinh ra bởi việc running một file thông qua GFI Sandbox's automated analysis. Malware report bao gồm nhiều chi tiết khác nhau về malware, như là hành vi mạng nó thực hiện, file nó tạo ra, kết quả sinh ra thông qua việc scan với VirusTotal,...
 Reports được sinh bởi GFI sandbox khác nhau trong số lượng sections chúng chứa, dựa trên những gì analysis tìm được. GFI sandbox report 6 sections trong Figure 4-1, như sau:


  • Analysis Summary liệt kê static analysis information và một toàn cảnh ở mức cao của các kết quả phân tích động. 
  • File Activity section liệt kê các files được mở, được tạo, hoặc bị xóa cho mỗi process bị tác động bởi malware. 
  • Created Mutexes section liệt kê mutexes tạo bởi malware. 
  • Registry Activity section liệt kê các thay đổi đến registry.
  • Network Activity section bao gồm network activity được sinh ra bởi malware, bao gồm cả việc thiết lập một listening port hoặc thực hiện một DNS request. 
  • VirusTotal Results section liệt kê các kết quả của VirusTotal scan đối với malware.
Sandbox Drawbacks

Malware sandboxes thường có một vài nhược điểm chính. Cho ví dụ, sandbox đơn giản chỉ run executable, mà không có command-line options. Nếu malware executable yêu cầu command-line options, nó sẽ không thực thi bất cứ code nào và nó chỉ run khi cung cấp một option. Ngoài ra, nếu subject malware của bạn đang chờ cho command-and-control packet được trả về trước khi launching một backdoor, backdoor sẽ không được lanched trong sandbox. 

Sandbox có thể không record được tất cả events, bởi vì cả bạn lẫn sandbox không thể chờ đợi trong một thời gian đủ dài. Cho ví dụ, nếu malware được thiết lập để sleep trong vòng một ngày trước khi thực hiện các hành vi nguy hiểm, bạn có thể lỡ mất sự kiện đó. (Hầu hết sandboxes hook Sleep function và thiết lập nó ngủ chỉ trong một thời gian ngắn, nhưng để ngủ thì đâu phải chỉ có một cách này, và sandboxes không thể theo kịp tất cả những cách thức trên.)

Các khuyết điểm tiềm ẩn khác bao gồm:
  • Malware thường phát hiện khi nó đang đực running trong một máy ảo, và nếu một máy ảo bị phát hiện, malware có thể dùng việc running hoặc trở mặt cư xử khác đi. Không phải tất cả sandboxes đều giải quyết được vấn đề này. 
  • Một vài malware yêu cầu sự hiện diện của registry keys nhất định hoặc files trên hệ thống mà những thứ này có thể không được tìm thấy trong sandbox. Nhiều cái còn yêu cầu chứa dữ liệu hợp lệ, ví dụ như commands hoặc encrytion keys. 
  • Nếu malware là một DLL, một lượng nhất định exported functions sẽ không được invoked một cách thích hợp, bởi vì một DLL sẽ không run dễ dàng như là một excutable. 
  • Sandbox environment OS có thể không đúng với malware. Cho ví dụ, malware có thể crash Windows XP nhưng sẽ run mà không hề gì trong Windows 7.
  • Một sandbox không thể nói cho bạn những gì malware làm. Nó có thể report các chức năng cơ bản, nhưng không thể nói cho bạn nếu malware là một custom Security Account Manager (SAM) hash dump utility hoặc một encryted keylogging backdoor. 

Xây dựng lab phục vụ cho phân tích động malware

Malware labs có thể cực kì đơn giản hoặc rất phức tạp. Tất cả phụ thuộc vào resources hiện có của bạn (ví dụ như hardware, networking equipment, Windows licences, và những thứ khác), phụ thuộc vào bao nhiêu công việc phân tích bạn muốn tự động hóa, bao nhiêu options bạn muốn có. Bài viết này chỉ cho bạn cách set up một lab nhỏ bao gồm các mục tiêu ảo (virtual targets) và các mục tiêu vật lý (physical targets) sử dụng Internet thực hoặc mô phỏng. Hình phía dưới shows một ví dụ của môi trường lab.
Mô hình lab trên gồm các thành phần sau:

  • Physical targets: Đây là các máy tính xài hệ điều hành Windows, chúng sẽ đảm nhiệm việc thực thi malware. Đừng lo lắng về việc lây nhiễm malware lên các máy vật lý. Bạn có thể ngăn chặn không cho chúng lây malware lây nhiễm với Deep Freeze , hoặc bạn cũng có thể re-image chúng một cách nhanh chóng qua các giải pháp nhưTruman và FOG. Khi FOG  d được thảo luận trong Recipe 7-8, những physical targets được coi như là FOG clients. Dĩ nhiên, các máy tính thật không phải là một yêu cầu, nhưng thật là tốt khi ta có chúng trong trường hợp ta cần phân tích VM-aware malware. 
  • Virtual targets: Đây là các máy ảo chạy Windows bạn cũng sẽ thực thi malware trên các máy này. Mỗi khi bạn xong việc, bạn có thể phục hồi chúng về trạng thái trước khi bị lây nhiễm. Chúng tôi khuyến nghị bạn nên có ít nhất một hoặc hai VMs running các phiên bản khác nhau của Windows. Trong bài viết này, khi nhắc đến virtual targets tôi còn sử dụng hai thuật ngữ là virtual machine guests và VMs. 
  • Controller: Đây là một máy tính vật lý chạy Linux. Nó runs imaging software để điều khiển physical targets, các phần mềm máy ảo (như là VMware hoặc VirtualBox) để điều khiển virtual targets, và các chương trình để điều khiển, log, hoặc mô phỏng truy cập mạng. Xuyên suốt bài viết này, tôi nhắc tới controller như là FOG server và virtual machine host, phụ thuộc vào vai trò của nó trong vấn đề ta thảo luận. 
Thông thường chúng ta chỉ xài một laptop, nhưng với những yêu cầu phía trên đòi hỏi ta phải có 2 máy thật (Physical targets và Controller). Bạn có thể tạo một lab dựa trên một máy tính duy nhất. Tôi khuyến cáo bạn nên sử dụng Linux như là hệ điều hành của controller, nhưng nó không phải là yêu cầu, chỉ là lựa chọn của bạn mà thôi. Bạn cũng có thể tạo một portable, personal lab trên các máy tính chạy Windows hoặc Mac OS X. Tuy nhiên, bởi vì chúng ta không thể cung cấp instructions trên mọi cấu hình có thể, tôi sẽ sử dụng setup trong Figure 7-1 như là một mô hình chung trong bài viết này và tôi sẽ chỉ ra những chỗ bạn cần điều chỉnh nếu lab của bạn khác với cách thức chung.

Mạng trong mô hình này được chứa trong một LAN duy nhất bởi vì đó là những gì người ta sử dụng nhiều nhất. Mặc dù không được chỉ ra trong Figure 7-1, tôi đang giả định rằng firewall có một địa chỉ IP bên ngoài để giao tiếp với Internet. Nêu bạn có quyền truy nhập đến một mạng lớn hơn hoặc bạn có nhiều địa chỉ external IP lấy từ ISP của bạn, khi đó bạn có thể gắn cho mỗi target những IP để nó có thể được route.

Trước khi bắt đầu với việc setting up một lab , luôn nhớ trong đầu rằng việc setting up một môi trường an toàn là rất quan trọng, nếu bạn không muốn compromise hệ thống host và controller của bạn. Virtual machines chia sẻ rất nhiều resources với host computer và một cách nhanh chóng có thể trở thành một nguy cơ an ninh nếu bạn cấp phép cho chúng. Dưới đây là một vài điểm giúp bạn ngăn chặn malware "chạy thoát" khỏi môi trường bị cô lập đến nơi mà chúng bị hạn chế:

  • Đảm bảo rằng phần mềm máy ảo bạn đang sử dụng đã được cập nhật. Các lỗ hổng trong máy ảo có thể dẫn đến việc lây nhiểm malware lên host của bạn.
  • Cấu hình firewall trên host của bạn để drop incoming packets đến từ targets. 
  • Nếu bạn không muốn cho malicious code mà bạn run trong target có thể đi vào Internet, chắc chắn rằng bạn đã disable virtual network card, sử dụng host-only networking configuration, hoặc chứa traffic với simulation scripts (sẽ thấy trong Recipe 7-3)
  • Disable shared folders giữa host và target hoặc làm cho chúng read-only.
  • Ngăn chặn target truy nhập tới bất cứ shared devices hoặc removable media nào, ví dụ USB drives được cắm vào host của bạn. 
  • Đừng tùy chỉnh (customize) target system của bạn với bất cứ thông tin nào, nếu bị leaked bởi một trojan, các thông tin này có thể được sử dụng để nhận dạng bạn. 
Bạn cần có kiến thức về TCP/IP, Linux system administration, và Windows system administration. Bạn cần biết sử dụng máy ảo như VMware hoặc Virtual Box. Bạn cần phải quen thuộc với forensic tools, cũng như là khả năng tùy chỉnh Perl và Python scripts để phù hợp với nhu cầu của bạn. 

Networking

Cấu hình mạng hợp lý trong môi trường lab của bạn là một bước quan trọng cho việc capturing và phân tích traffic mà malware sinh ra. Việc giải quyết thách thức này yêu cầu sự hiểu biết về các network settings khác nhau mà hầu hết các sản phẩm máy ảo cung cấp. 
Tham khảo Table 7-1, đây là một bảng tổng kết về các chế độ mạng: host-only, NAT/shared, và bridged. 

Ba modes được định nghĩa như sau:
  • Host-only mode: Mode này tạo ra một private LAN được chia sẻ giữa host và VMs của nó. VMs không thể giao tiếp với các hệ thống bên ngoài- những hệ thống mà có thể tốt hoặc xấu, dựa trên mục đích của bạn. Đó là rất tệ nếu bạn muốn cho phép malware liên hệ (contact) với các sites thực tế trên Internet, bởi vì nó sẽ không hoạt động, nhưng một điều tốt đó là nếu bạn muốn chứa traffic trong môi trường sandbox của cá nhân bạn . 
  • NAT/Shared mode: VMs contact với máy khác trong LAN hoặc Internet, nhưng các kết nối thường có địa chỉ IP nguồn là địa chỉ IP của host. Các máy khác khổng thể khởi tạo các kết nối đến ngược trở lại VMs nếu không có cấu hình port-forwarding trên máy host. 
  • Bridge mode: VMs chia sẻ physcal Ethernet adaptor của host, nhưng chúng các địa chỉ IPv MAC của riêng chúng. VMs xuất hiện trong cùng local subnet với host. Đó là cấu hình duy nhất cho phép các máy khác tạo ra các kết nối gửi đến VMs. Nó còn là mode duy nhất cho phép các máy bên ngoài, như là router hoặc firewall, để phân biệt giữa traffic sinh ra bởi host và traffic sinh ra bởi một VM trên host. 
Chúng tôi khuyến nghị sử dụng bridged mode cho các VMs của bạn và gán cho chúng các địa chỉ IP vì vậy bạn mới có thể xác định được VM nào chịu trách nhiệm cho traffic mà bạn capture. Dĩ nhiên, nếu bạn chỉ có một VM và không có nhu cầu cho incoming connections đến VM của bạn, khi đó NAT/Shared mode sẽ thích hợp. 

RECIPE 7-1: ROUTING TCP/IP CONNECTIONS IN YOUR LAB

Trên máy của bạn, đối với controller trong sơ đồ ở đầu bài, sử dụng ifconfig để xác định địa chỉ IP của nó. Sau đó sử dụng ipconfig trên Windows targets của bạn để làm điều tương tự. Kiểm tra tất cả các máy nằm chung một subnet và đảm bảo rằng bạn có thể ping controller từ Windows targets. Để thuận tiện cho việc tham khảo, Table 7-2 cung cấp các giá trị có liên quan lấy từ lab của tôi, những thứ này sẽ còn liên quan trong các phần sau. 

Note: Nếu bạn bị hạn chế về mặt hardware, bạn có thể sử dụng máy ảo Linux như là controller. Trong trường hợp đó, bạn sẽ cần tối thiểu 2 VMs - một để running Windows (the target) và cái kia để running Linux (the controller).

Thế nào, bây giờ bạn đã kiểm tra được tính liên thông của mạng giữa controller và targets của bạn, bạn sẽ cần tạo ra một vài thay đổi để tất cả traffic sinh ra bởi programs trên target "đổ" vào controller. Chúng ta sẽ thảo luận một vài cách thức để thực hiện điều đó, vì vậy bạn có thể đánh giá được những điểm mạnh và điểm yếu, nhưng tôi thực sự khuyên bạn nên sử dụng chỉ một cách thức đó là kĩ thuật IP routing. 

Redirecting DNS

Nếu bạn đã biết DNS hostname của server(s) được liện hệ với malware, bạn có thể modify hosts file để điều hướng các kết nối đến controller's IP. Hosts file được đặt trong thư mục%SYSTEMROOT%\config\drivers\etc và nó được định dạng như sau:

# redirect DNS to the controller’s IP
172.16.176.130 commandserver.com

Entry phía trước forces processes trên target machine để kết nối với địa chỉ IP của controller sau khi resolving commandserver.com với DNS. Nếu bạn có một process trên controller của bạn lằng nghe incoming connections, bạn có thể log traffic và nhìn xem malware có thể làm gì khi kết nối thành công đến server thực sự commandserver.com.

Có một vài điểm yếu với phương thức này. Thứ nhất, bạn sẽ không thường xuyên "chắc ăn" biết được hostname mà một sample contact đến, và giả sử nếu bạn biết được đi nữa, thêm các entries đến host files mỗi lần phải thực hiện một cách thủ công và tẻ nhạt. Thứ hai, nếu malware resolves domains sử dụng DNS_QUERY_NO_HOSTS_FILE flag trong DnsQuery, khi đó nó sẽ bypass your hosts file entries.

Một lựa chọn khác là bạn có thể tạo một DNS server cho chính mình và cấu hình nó để trả về IP của controller cho một vài hoặc tất cả hostnames mà target cố gắng để resolve. Sử dụng kĩ thuật này, bạn không phải edit thủ công hosts file, nhưng malware vẫn có thể bypass setup của bạn thông qua việc không thực hiện DNS lookups và contacting với một hệ thống bằng IP của nó. Malware có thể lờ đi DNS settings trên target machine của bạn và resolve hostnames sử dụng một public DNS server thay thế (cho ví dụ, Google's open DNS).

Redirecting IP with Routing

Nếu bạn thay đổi thiết lập mạng trên target của mình, trỏ gateway của nó vào controller của bạn, sau đó tất cả traffic sẽ hit controller của bạn mặc kệ malware contacts với một hệ thống bởi DNS name hoặc IP. Nếu bạn có một quyết định quan trọng cần phải quyết - Bạn có muốn log hay là forward packets đến real servers trên Internet hay là bạn muốn redirect packets đến một hệ thống giả hoặc các dịch vụ mô phỏng ?

Nếu bạn forward packets đến real servers, bạn có thể biết được chính xác hơn những cư sử của malware trong tự nhiên, nhưng có một mối lo ngại đó là bạn có thể làm lộ IP của bạn với bad guys. Nếu bạn sử dụng một bộ phần mềm mô phỏng, bạn có thể tạo hoàn toàn một sandnet chứa chính nó, nhưng bạn sẽ không thực sự quan sát được malware trong môi trường tự nhiên.

Để route tất cả target machine's traffic thông qua controller, làm theo các bước sau:

  1. Trên controller chạy Linux, enable IP forwarding trong kernel bằng việc thực hiện command sau như root:
          $ sudo su
          # echo 1 > /proc/sys/net/ipv4/ip_forward
    2.    Trên controller, đảm bảo rằng iptables default firewall policy cho phép forwarding packets,           như sau
          $sudo iptables - P FORWARD ACCEPT
    3. Quay lại target, cấu hình mạng cho nó sao cho default gateway trỏ đến controller. Bạn có thể 
          thực hiện điều này thông qua 2 cách. Cách thứ nhất yêu cầu gõ command sau trong cmd.exe
          C:\> route change 0.0.0.0 mask 0.0.0.0 172.16.176.130

         Bạn cũng thể sử dụng GUI, như trong Figure 7-2. 


 Với thiết lập như trên, bạn có thể tự tin để capture, redirect, hoặc interact với bất cứ traffic được sinh bởi Windows target machine. Sở dĩ tôi nói từ "tự tin" một cách công bằng bởi vì mặc dù chúng ta không bao giờ có thể nhìn thấy nó trong tự nhiên, malware có thể reconfigure default gateway trên target machine và gửi traffic xung quan controller. Khả năng để làm điều đó phụ thuộc vào nơi đặt controller của bạn. Malware còn cần phải biết IP của next-hop router mà nhận hoặc và forwards traffic; tuy nhiên, có rất nhiều thứ bạn có thể học được từ một trace route đơn giản. 

Recipe 7-2: CAPTURING AND ANALYZING NETWORK TRAFFIC

Tất cả traffic gửi từ / đến targets của bạn đổ xuống controller, bạn đã có thể khởi động tiện ích capture trên controller và nhìn packets trong thời gian thực. 

NOTE: 
Bên cạnh phương thức capturing packets, bạn có thể sử dụng một vài kĩ thuật khác:
  • Kết nối machines trên mạng của bạn đến một old hub nếu bạn có một cái, và sử dụng dụng một mode sniffer.
  • Plug sniffer của bạn vào trong một switch hoặc router để cho phép port mirroring.
  • Kết nối target machines đến controller của bạn thông qua crossover cable. 

Using WireShark's GUI 

WireShark là một công cụ phân tích giao thức mạng trên Windows, Linux, MAC OS X, trên các OS khác. Bên cạnh việc capturing packets, WireShark có thể thực hiện việc kiểm tra "sâu" hàng trăm giao thức, và xuất ra kết quả là pcap file, CSV, hoặc XML. Nó còn có khả năng filter mạnh mẽ. Nếu WireShark chưa được cài đặt trên controller của bạn, bạn có thể tải nó bằng cách running command sau:

  $ sudo apt-get install wireshark

Figure 7-3 shows WireShark's GUI. Bạn sẽ chú ý đến source address của DNS queries là 172.16.176.138 - target VM. DNS server hồi đáp lại queries là 172.16.176.2, trên mỗi cấu hình trong bước phía trước. Bạn có thể nhìn thấy được target resolved hostnames trong wikipedia.orgvà google.com domains để giao tiếp với những servers này thông qua HTTP.

Using tshark

Nếu bạn thích các công cụ sử dụng command-line hơn (được khuyến khích cho việc phân tích tự động), bạn có thể sử dụng tshark , là một non-GUI version của Wireshark. Bạn có thể cài đặt nó như sau:

 $ sudo apt-get install tshark

Command sau đây shows cách để capture packets trên eth0 interface, tự động thoát ra sau 60 giây, và lưu packets vào output.pcap

 $ sudo tshark -i eth0 -a duration:60 -w output.pcap

Để đọc packets sử dụng cùng cách thức phân tích như GUI version của Wireshark, bạn có thể làm như sau:

 $ tshark -r output.pcap -V

Using tcpdump

tcpdump không bao gồm các phân tích giao thức mở rộng như Wireshark và tshark, nhưng nó cung cấp khả năng capture đáng tin và mạnh mẽ và các khả năng đọc trở lại. Nếu bạn cần cài đặt nó, sử dụng command sau:

 $ sudo apt-get install tcpdump

Command sau shows cách để capture packets trên eth0 interface đã được đánh đánh địa chỉ đến hoặc từ 172.16.172.138, và lưu tất cả bytes trong packet (thông qua việc thiết lập snaplen đến 0) trong output.pcap:

 $ tcpdump -i eth0 -s 0 -w output.pcap host 172.16.172.138

Từ khóa host là một trong nhiều BPF-style filters mà giúp cho bạn điều khiển chính xác những packets nào được lưu trong file của mình. Để có nhiều thông tin về BPF-style filters, gõ man tcpdump

Nếu bạn pass -r flag đến tcpdump, nó sẽ phân tích file packet capture được lưu.

 $ tcpdump -r output.pcap

Chúng tôi khuyến cáo bạn có thể pass -n flag để ngăn cho tcpdump khỏi thực hiện DNS lookups, những gì có thể tốn thời gian. Dĩ nhiên, nếu bạn muốn nhìn thấy DNS names thay cho IP addresses, đừng sử dụng -n flag.

Using snort IDS

Bạn có thể cài đặt Snort IDS lên controller của mình để cảnh báo bất cứ traffic đáng nghi nào gửi đến hoặc là gửi từ target machines trong khi malware đang running. Snort sẽ cho bạn một gợi ý tốt về các kiểu cảnh báo bạn sẽ nhìn thấy nếu một malware hay malware tương tự tồn tại trên mạng công ty. Commands sau tạo một simple Snort setup với Emerging Threats signatures trên controller của bạn:

 $ sudo apt-get install snort
 $ sudo wget -P /etc/snort/rules http://www.emergingthreats.net/rules/emerging-all.rules
 $ sudo echo 'include $RULE_PATH/emerging-all.rules' >> /etc/snort/snort.conf
 $ sudo /etc/init.d/snort start

Nếu bạn muốn kiểm tra xem mọi thứ thực hiện có thành công không hoặc nhìn xem command-line parameters startup script gửi đến Snort, khi đó bạn có thể view nó như sau:
 $ cat /proc/'pidof snort'/cmdline
/usr/sbin/snort –m 027 –D –d –l /var/log/snort –u snort –g snort –c \
/etc/snort/snort.conf –S HOME_NET=[172.16.176.0/24] –i eth0

http://iamtoet.blogspot.com/

Debugging

Debugger là một phần mềm hoặc phần cứng được sử dụng để kiểm tra và việc thực thi của một chương trình khác. Debuggers giúp sức trong quá trình phát triển phần mềm, bời vì các chương trình thường xuyên có những lỗi khi chúng được viết lần đầu tiên. Như khi bạn phát triển, bạn cung cấp input cho chương trình và nhìn vào output, nhưng bạn không thể biết được làm thế nào chương trình sinh ra kết quả như vậy. Debuggers cho bạn những cái nhìn sâu hơn về những gì chương trình làm khi nó đang thực thi. Debuggers được thiết kế để cho phép developers có thể đo lường (measure) và điều khiển (control) trạng thái bên trong và thực thi của một chương trình.

Debuggers cung cấp thông tin về một chương trình mà ta có thể rất khó hoặc là không thể khi sử dụng disassembler. Disassemblers cung cấp một snapshot về chương trình trước khi thực thi câu lệnh đầu tiên. Debuggers cung cấp một cái nhìn "động" về một chương trình như là nó run. Một ví dụ nhé, debuggers có thể show các giá trị memory addresses như chúng thay đổi xuyên suốt quá trình thực thi của một chương trình.

Khả năng đo lường và điều khiển thực thi của một chương trình cung cấp những hiểu biết quan trọng trong suốt quá trình phân tích malware. Debuggers cho phép bạn nhìn thấy mọi memory location, register, và argument đến mọi function. Debuggers còn giúp bạn thay đổi bất cứ thứ gì về thực thi chương trình vào bất cứ lúc nào. Cho ví dụ, bạn có thể thay đổi giá trị của một biến vào bất cứ thời điểm nào - tất cả những thứ bạn cần đó là thông tin đầy đủ về biến đó, bao gồm cả location của nó.

Source-Level và Assembly-Level Debuggers

Hầu hết software developers đều quen thuộc với source-level debuggers, những gì cho phép một programmer debug trong khi coding. Kiểu debugger này được tích hợp sẵn trong integrated development environments (IDEs). Source-level debuggers cho phép bạn đặt breakpoints, việc đặt breakpoints làm dừng thực thi chương trình  trên các dòng của source code, để kiểm tra trạng thái của các biến phía bên trong và đi qua (step through) thực thi của chương trình mỗi lần một dòng.

Assembly-level debuggers, thỉnh thoảng được gọi là low-level debuggers, hoạt động trên assembly code thay vì source code. Cũng như với source-code debuggers, bạn có thể sử dụng assembly-level debugger để step through một chương trình mỗi lệnh tại mỗi thời điểm, đặt breakpoints để dùng lại tại các dòng assembly code xác định, và phân tích memory locations.

Malware analysts thường sử dụng assembly-level debuggers bởi vì họ thường không có sẵn source code của một chương trình.

Kernel và User-Mode Debugging

Chúng ta gặp nhiều thách thức hơn khi debug kernel-mode code so với debug user-mode code bởi vì bạn phải cần tới 2 systems khác nhau cho kernel-mode. Trong user-mode, debugger đang running trên cùng một system với code được debugged. Khi debugging trong user mode, bạn đang debugging một single executable, những gì được tách rời với executables khác bởi hệ điều hành.

Kernel debugging được thực hiện trên 2 systems bởi vì chỉ có duy nhất một kernel; nếu kernel nằm tại một breakpoint, không có một ứng dụng nào có running trên system. Một system runs code được debugged, và system còn lại runs debugger. Ngoài ra, OS phải được cấu hình để cho phép kernel debugging, và bạn phải kết nối 2 machines.

Có 2 gói phần mềm dành cho user-mode debugging và kernel debugging. WinDbg là một công cụ phổ biến hỗ trợ cho kernel debugging. OllyDbg là một công cụ nổi tiếng  khác dành cho malware analysts . WinDbg cũng hỗ trợ user-mode debugging tốt, và IDA Pro có một built-in debugger, nhưng nó không cung cấp các tính năng hoặc dễ dàng sử dụng như OllyDbg.

Sử dụng Debugger

Có 2 cách debug một chương trình. Cách thứ nhất là start chương trình với debugger. Khi bạn start chương trình và nó được nạp vào trong bộ nhớ, nó dừng running trước thực thi của entry point của nó. Tại entry point, bạn có thể hoàn toàn điều khiển chương trình.

Bạn có thể gắn (attach) một debugger đến một chương trình khi nó đã running. tất cả threads của chương trình được paused, và bạn có thể debug nó. Đó là một cách tiếp cận tốt khi bạn muốn debug một chương trình sau khi nó đã running hoặc nếu bạn muốn debug một process bị ảnh hưởng bởi malware.

Single-Stepping 

Thứ đơn giản nhất có thể làm với một debugger là single-step qua một chương trình, điều đó có nghĩa là bạn run một lệnh và trả quyền điều khiển cho debugger. Single-stepping cho phép bạn nhìn thấy mọi thứ đang diễn ra bên trong một chương trình.

Bạn có thể single-step qua toàn bộ chương trình, nhưng bạn không nên làm như vậy khi gặp các chương trình phức tập bởi vì nó sẽ tiêu tốn một lượng thời gian khá lớn. Single-stepping là một công cụ tốt cho việc hiểu các chi tiết của một section code, nhưng bạn phải lựa chọn những code nào muốn phân tích. Tập trung vào bức tranh lớn, toàn cảnh hoặc là bạn sẽ bị lạc trong các tiểu tiết.

Ví dụ, disassembly trong Example 9-1 shows cách bạn có thể sử dụng một debugger để giúp bạn hiểu về một section code.

Example 9-1. Stepping through code
mov edi, DWORD_00406904
mov ecx, 0x0d
LOC_040106B2
xor [edi], 0x9C
inc edi
loopw LOC_040106B2
...
DWORD:00406904:       F8FDF3D0 (1)

Đoạn code sau có thể hiểu là truy nhập vào dữ liệu và sửa đổi nó trong một loop. Dữ liệu được hiểu thị tại cuối của (1) không phải là dạng ASCII text hay là bất cứ giá trị có thể nhận dạng nào, nhưng bạn có thể sử dụng một debugger để step through loop này để làm lộ ra đoạn code này đang làm gì.

Nếu bạn single-step qua loop này với hoặc WinDbg hoặc OllyDbg, bạn có thể nhìn thấy dữ liệu bị sửa đổi. Cho ví dụ, trong Example 9-2, bạn nhìn thấy 13 bytes được sửa đổi bởi hàm này thay đổi mỗi lần qua loop.

Example 9-2. Single-stepping through a section of code to see how it changes memory
D0F3FDF8 D0F5FEEE FDEEE5DD 9C (.............)
4CF3FDF8 D0F5FEEE FDEEE5DD 9C (L............)
4C6FFDF8 D0F5FEEE FDEEE5DD 9C (Lo...........)
4C6F61F8 D0F5FEEE FDEEE5DD 9C (Loa..........)
. . . SNIP . . .
4C6F6164 4C696272 61727941 00 (LoadLibraryA.)

Với một debugger được gắn vào, rõ ràng thấy rằng hàm này đang sử dụng single-byte XOR function để decode string LoadLibrary. Có thể khó khăn để nhận dạng string này chỉ với phân tích tĩnh.

Stepping-Over và Stepping-Into

Khi single-stepping qua code, debuggers dùng lại sau mọi lệnh. Tuy nhiên, khi bạn quan tâm đến những gì chương trình đang làm, bạn có thể không cần lo lắng về chức năng của mỗi call. Cho ví dụ, nếu chương trình của bạn calls LoadLibrary , bạn có thể không muốn step through mọi lệnh của LoadLibrary function.

Để điều khiển các lệnh mà bạn nhìn thấy trong debugger của bạn, bạn thể step-over hoặc là step-into các lệnh. Khi bạn step-over call instructions, bạn bỏ quả chúng. Cho ví dụ, nếu bạn step-over một call, lệnh tiếp theo bạn sẽ nhìn thấy trong debugger của bạn sẽ là lệnh đằng sau function call trả về. Mặt khác, bạn step-into một call instruction, lệnh tiếp theo bạn sẽ nhìn thấy trong debugger là lệnh đầu tiên của hàm được gọi.

Stepping-over cho phép bạn giảm một số lượng đáng kể các lệnh bạn cần phân tích, nhưng nó cũng tiềm tàng việc bạn có thể missing các chức năng quan trọng của chương trình phân tích nếu bạn step-over wrong functions. Thêm vào đó là một số lượng function calls không bao giờ return, và nếu chương trình của bạn gọi một function mà không bao giờ returns và bạn step-over nó, debugger sẽ không bao giờ giành lại được điều khiển. Khi điều đó xảy ra, khởi động lại chương trình và step đến cùng vị trí đó, nhưng lúc này, step-into funtion.

Pausing Excution với Breakpoints

Breakpoints được sử dụng để pause excution và cho phép bạn kiểm tra trạng thái của một chương trình. Khi một chương trình bị paused tại một breakpoint, nó được nhắc tới như làbroken . Breakpoints là cần thiết bởi vì bạn không thể access registers hoặc memory addresses trong khi một chương trình đang running, bởi vì các giá trị đó đang được thay đổi.

Example 9-3 demo nơi mà breakpoint trở nên hữu ích. Trong ví dụ này, có một lời gọi đến EAX. Trong khi disassembler không thể nói cho bạn biết function nào được gọi, bạn có thể set một breakpoint trên lệnh đó để tìm hiểu. Khi chương trình đụng phải breakpoint, nó sẽ bị dừng lại, và debugger sẽ show cho bạn giá trị của EAX, những gì là destination của hàm được gọi.

Example 9-3. Call to EAX
00401008 mov ecx, [ebp+arg_0]
0040100B mov eax, [edx]
0040100D call eax

Một ví dụ khác là trong Example 9-4 show điểm bắt đầu của một hàm với một lời gọi tớiCreateFile để mở một handle đến file. Trong assembly, rất khó khăn để xác định được tên của file, mặc dù một phần của tên được pass như là một parameter đến hàm. Để tìm file trong disassembly, bạn có thể sử dụng IDA Pro để search tất cả các lần mà hàm này được gọi để nhìn xem những arguments nào được gửi vào, nhưng nhiều giá trị cũng có thể được passed như là parameters hoặc đến từ các function calls khác. Có thể rất khó khăn để xác định filename. Sử dụng một debugger làm cho công việc trở nên rất dễ dàng.

Example 9-4. Using a debugger to determine a filename
0040100B xor eax, esp
0040100D mov [esp+0D0h+var_4], eax
00401014 mov eax, edx
00401016 mov [esp+0D0h+NumberOfBytesWritten], 0
0040101D add eax, 0FFFFFFFEh
00401020 mov cx, [eax+2]
00401024 add eax, 2
00401027 test cx, cx
0040102A jnz short loc_401020
0040102C mov ecx, dword ptr ds:a_txt ; ".txt"
00401032 push 0 ; hTemplateFile
00401034 push 0 ; dwFlagsAndAttributes
00401036 push 2 ; dwCreationDisposition
00401038 mov [eax], ecx
0040103A mov ecx, dword ptr ds:a_txt+4
00401040 push 0 ; lpSecurityAttributes
00401042 push 0 ; dwShareMode
00401044 mov [eax+4], ecx
00401047 mov cx, word ptr ds:a_txt+8
0040104E push 0 ; dwDesiredAccess
00401050 push edx ; lpFileName
00401051 mov [eax+8], cx
00401055 (1) call CreateFileW ; CreateFileW(x,x,x,x,x,x,x)

Chúng ta set một breakpoint trên một lời gọi đến CreateFileW tại (1), và sau đó nhìn vào các giá trị trên stack khi breakpoint được kích hoạt.

Bây giờ hãy tưởng tượng bạn có một mảnh malware và một packet capture. Trong packet capture, chúng ta nhìn thấy encrypted data. Chúng ta có thể tìm thấy lời gọi để gửi đi và chúng ta có thể khai phá ra encryption code, nhưng rất khó khăn để decrypt các dữ liệu đó, bởi vì bạn không biết encrytion routine hoặc key. May mắn thay, bạn có thể sử dụng một debugger để đơn giản hóa công việc bởi vì encryption routines thường là các hàm rời rạc mà chuyển dữ liệu.

Nếu bạn có thể tìm thấy encrytion routine được gọi, chúng ta có thể set một breakpoint trước khi dữ liệu đó được encrypted và nhìn xem dữ liệu được gửi.

Bạn có thể sử dụng một vài kiểu breakpoints, bao gồm software execution, hardware execution, và conditional breakpoints. Mặc dù tất cả breakpoints đều phục vụ chung một mục đích, phụ thuộc vào tình hình, một số breakpoints sẽ không làm việc được trong khi số khác làm việc được. Nào hãy cùng xét từng breakpoint một

Software Execution Breakpoints

Cho đến bây giờ, chúng ta đang nói về software execution breakpoints , những gì làm cho một chương trình dừng lại khi một lệnh được thực thi. Khi bạn set một breakpoint mà không có bất cứ options nào, hầu hết debbuggers phổ biến sẽ set software execution breakpoint bởi mặc định.

debugger implement một software breakpoint thông qua việc overwriting byte đầu tiên của một lệnh với OxCC, lệnh tương ứng với INT 3, breakpoint interrupt được thiết kế cho việc sử dụng với debuggers. Khi lệnh OxCC được thực thi, OS sinh ra một ngoại lệ và chuyển quyền điều khiển đến debugger.

http://iamtoet.blogspot.com/

Reverse " Hello World " program

Như bài viết trước mình đã giới thiệu cơ bản về RE. Vậy để RE chúng ta cần những gì ? Câu trả lời là kiến thức về lập trình. Ngôn ngữ lập trình yêu cầu là C/C++ và Assembly. Trong loạt tut về OllyDbg mình thấy tổng hợp những kiến thức cơ bản cần thiết để có thể reverse, các bạn nên đọc đến tut số 8 để có kiến thức về assembly. Bài viết này giả sử như bạn đã có những kiến thức đó rồi.

Bài viết này mình chỉ dụng Microsoft Studio Visual C++ 2010 làm công cụ. Nào hãy cùng bắt đầu với một chương trình đơn giản: Hello World program.

#include <stdio.h>
int main()
{
printf("hello, world");
return 0;
};

Mình compile nó trong MSVC 2010: cl 1.cpp /Fa1.asm
(/Fa option có nghĩa là sinh ra assembly listing file)

CONST SEGMENT
$SG3830 DB ’hello, world’, 00H
CONST ENDS
PUBLIC _main
EXTRN _printf:PROC
; Function compile flags: /Odtp
_TEXT SEGMENT
_main PROC
push ebp
mov ebp, esp
push OFFSET $SG3830
call _printf
add esp, 4
xor eax, eax
pop ebp
ret 0
_main ENDP
_TEXT ENDS

Note: Đoạn code trên đã được tinh giản đi những thông tin không cần thiết để phù hợp với kích thước bài viết.

Trong trường hợp này chúng ta có 2 phân đoạn (segment) : CONST (dành cho dữ liệu) và _TEXT(dành cho code). Chuỗi (string) "hello, world " trong C/C++ có kiểu  const char*, tuy nhiên nó không có một danh định riêng. 
Vì compiler cần làm việc với string này, vì vậy nó định nghĩa một cái tên nội bộ (internal name) cho string cần thao tác trong trường hợp này đó là $SG3830, các bạn không cần phải lo lắng về cái tên này. 

Như các bạn có thể nhìn thấy string được kết thúc bởi zero byte - đó là quy định chuẩn cho strings của C/C++.
Trong code segment _TEXT chỉ xuất hiện một hàm đó là _main.
Hàm _main bắt đầu với code mào đầu (prologue code) và kết thúc với code kết thúc (epilogue code), giống như bất cứ hàm nào khác. Tôi sẽ nói về phần mào đầu và kết thúc ở phía dưới, hiện tại chúng ta cứ chấp nhận như vậy đã. 

Sau phần mở đầu chúng ta có thể nhìn thấy lời gọi printf(): CALL _printf. (Nếu tới đây bạn thấy khó hiểu thì hãy quay lại loạt tut, tại tut7 có giới thiệu lệnh CALL)
Trước khi thực hiện lời gọi, địa chỉ của string (hay là một con trỏ tới nó) chứa lời chào mừng của chúng ta được đặt vào trong stack với sự giúp đỡ của lệnh PUSH (kiến thức về lệnh PUSH cũng như stack có tại tut4).

Khi hàm printf() trả luồng điều khiển về hàm main(), địa chỉ string (hay là một con trỏ đến nó) vẫn còn nằm trên stack. 
Bởi vì chúng ta không cần nó (địa chỉ string ) nữa, nên chúng ta chỉnh sửa lại con trỏ ngăn xếp(ESP) để điều chỉnh lại đỉnh ngăn xếp. 
ADD ESP, 4 nghĩa là cộng 4 vào thanh ghi ESP.

Tại sao lại là 4? bởi vì nó là 32-bit code, chúng ta cần chính xác 4 bytes để biểu diễn địa chỉ để đưa vào stack. Nó là 8 bytes trong x64-code. 
"ADD ESP, 4" là tương đương với "POP register" nhưng không sử dụng bất cứ thanh ghi nào. 

Intel C++ compiler sử dụng POP ECX bởi vì opcode của lệnh này là ngắn hơn ADD ESP, x (1 so với 3), cái này có thể dễ dàng của tra bằng cách search opcode trên internent hoặc có thể load trực tiếp vào OllyDbg để thấy được opcode của chúng. 

Sau printf() call, trong code C/C++ ban đầu là return 0 - trả về zero như là kết quả của hàmmain().

Lệnh biểu diễn return 0 trong assemby đó là XOR EAX, EAX

XOR thường được sử dụng bởi compiler thay thế cho lệnh MOV EAX, 0 bởi vì opcode cua nó ngắng hơn (2 so với 5)

Môt vài compilers sử dụng lệnh SUB EAX, EAX, có nghĩa là trừ giá trị của EAX cho EAX, trong bất cứ trường hợp nào thì kết quả cũng là 0. 
Lệnh cuối cùng là lệnh RET trả luồng điều khiển về hàm gọi trong trường hợp này là main(). 

Phần mào đầu và kết thúc

Mào đầu của một hàm (function prologue) là các lệnh nằm ở phần bắt đầu của hàm. Nó thường giống như sau:

push ebp
mov ebp, esp
sub esp, X

Những lệnh trên làm gì? Chúng lưu giá trị của thanh ghi EBP, set EBP đến ESP và sau đó cấp phát không gian trong stack cho các biến cục bộ.

Giá trị EBP được cố định đến một khoảng thực thi của hàm và nó được sử dụng cho việc truy nhập đến các biến cục bộ và arguments. Bạn cũng có thể sử dụng ESP, nhưng nó thay đổi liên tục và không thích hợp. 

Phần kết hàm giải phóng không gian đã được cấp phát trong stack, trả lại giá trị EBP vể trạng thái ban đầu  và trả luồng điều khiển về hàm gọi: 
mov esp, ebp
pop ebp
ret 0

http://iamtoet.blogspot.com/