Wednesday, May 11, 2011

Buby Script Basics Part 3


In part 2 of this series we covered the "evt_proxy_message" method. In part 3 of this series we will cover the two methods shown below which have "checks" next to them.


√ evt_http_message    
√ evt_scan_issue        
   doActiveScan        
   doPassiveScan        
   excludeFromScope
   includeInScope      
   isInScope
   issueAlert
   makeHttpRequest
   sendToIntruder
   sendToRepeater
   sendToSpider

    So let's cover each individually with brief explanation and a code example.

    You can find sample scripts for each of these under the examples directory of the buby-script repo located Here.


    EVT_HTTP_MESSAGE
    ---------------------------------


    The following code will allow you to obtain methods exposed by the message_info object (which is a class):




    The 3 separate objects that make up the param are:


    tool_name => This is a string value, it is the name of the tool for which the message originated. Examples include proxy, scanner and repeater.


    is_request => Boolean value (true/false), this returns true when it is a request and false when a response.


    message_info => This is a class. It is an instance of the IHttpRequestResponse Java class. So there are methods such as get_comment, set_comment and getUrl exposed. 


    An example of using evt_http_message can be seen here (code):






    ....and the result


    w00t!

    So what does the code actually do?

    Lines 1 and 2 - Define the method and separate param into 3 separate objects.

    Lines 3-5
    Ln 3 If the tool the message originated from was the spider and this is NOT a request proceed to Ln 4.
    Ln4 If the response status code is 200 (OK), then move to Ln 5.
    Ln 5 Puts "Yo, we received a 200 FTW!" to the console.

    Lines 6-9 Are closing statements/method and passing the param back up to the superclass method.


    You can find another example using this method in the zlib_inflate.rb script.




    EVT_SCAN_ISSUE
    ---------------------------


    The following code will allow you obtain methods exposed by the issue object (which is a class):



    Only one object is exposed, it is a class, it is called issue. Some of the methods exposed by this class are

    -issue_name
    -severity
    -confidence
    -protocol
    -host
    -url
    -port
    -issue_detail
    -issue_background
    -remediation_detail  
    -remediation_background

    The following code:




    ...produces:









































    Lets step through the code


    1.  def prnt(*objs)
    2.    strn, meth = objs  
    3.    str = ''
    4.    str << "\n#{strn}\n"
    5.    str << '=' * strn.length + "\n\n"
    6.    str << "#{meth}\n"
    7.    puts str
    8.  end


    Lines 1-2 - Defines the method (prnt) and separates objs into two objects (strn, meth).


    Lines 3-4 - This defines a string instance variable (str), and then proceeds to put the strn object onto it.

    Lines 5-7 - The length of strn gets multiplied by '=' so that we can create the following visual....

    Example:

    something
    =========

    ...then we push meth onto the string and then we "puts" or print it to the console.

    Lets step through the second method "hm_prnt".


    1.   def hm_prnt(*objs)
    2.     strn, meth = objs
    3.     str = ''
    4.     str << "\n#{strn}\n"
    5.     str << '=' * strn.length + "\n\n"
    6.     meth.each do |itm|
    7.       str << "#{itm.request_headers}\n"
    8.       str << "#{itm.request_body}\n"
    9.       str << "#{itm.response_headers}\n"
    10.     str << "#{itm.response_body}\n"
    11.    end
    12.    puts str 
    13 . end





    Lines 1-2 - Defines the method (prnt) and separates objs into two objects (strn, meth).

    Lines 3-4 - This defines a string instance variable (str), and then proceeds to put the strn object onto it. 

    Lines 6-10 - We take the meth object which is an Array, we iterate thru each item in the array, convert it to a string while calling the four methods it exposes (request_headers, request_body, response.headers, and response_body). Now these methods all belong to http_messages and itm really represents the http_messages class. So when we are iterating thru this array we are really iterating thru an array containing a bunch of http_messages classes. Hopefully that makes sense.


    Finally, we need to discuss the $burp.evt_scan_issue method.



    1.  def $burp.evt_scan_issue(issue)
    2.    meth_arry =  [
    3.      'issue_name',
    4.      'severity',
    5.      'confidence',
    6.      'protocol',
    7.      'host',
    8.      'url',
    9.      'port',
    10.     'issue_detail',
    11.     'issue_background',      
    12.     'remediation_detail',      
    13.     'remediation_background',     
    14.    ]
    15.   
    16.   meth_arry.each do |meth| 
    17.     prnt("#{meth}", "#{issue.send("#{meth}")}")
    18.   end
    19.   
    20.   hm_prnt('http_messages', issue.http_messages)
    21. 
    22. end


    Line 1 - Defines the method ($burp.evt_scan_issue) and instantiates the "issue" object.


    Lines 2-14  - Creates an Array called "meth_array" which consists of methods associated with the issue object instantiated on line 1.


    Lines 16-18 - Iterates thru the meth_arry we created on line 2 picking out each method and then sends the method name and the method itself to prnt.


    Line 20 - The http_message method attached to the issue object isn't in the meth_arry because it can't be called directly and converted to a string. This is because http_message is a an array of classes. Each class has it's own methods. So, we made a special prnt method for it called hm_prnt. 


    Well that is all for Part 3 of this series. Part 4 will cover some of the other methods listed in the first part of this post. If you have any feedback please provide it so that the series can be improved upon.

    Happy Hacking,


    ~cktricky


    cktricky

    3 comments:

    M00dy said...

    Thanks again, I'm using your advices to try to bypass some anti-CSRF mechanism (HDIV j2EE framework). Actually, in each POST request I need to send a token that looks like random_name = random_value. So with buby, I'm trying to gather this information from the response (with nokogiri HTML parser)then send it. However, it's little bit complex. Have you ever seen this kind of defensive means ?

    cktricky said...

    Ahh, so you are probably using mechanize to search the response (via xpath) or something like that for the nonce value? So like:

    res = agent.get('http://www.example.com)
    res.search(//p[@class='something']) #Then search the response

    So I'm assuming you'd like to send, based off that random key/value in the response, a request that includes it in the POST params. Or at least I think that is what you are saying. I have seen those protections and is a really good example of when to use Buby. Otherwise fuzzing becomes extremely painful and slows down the vuln discovery phase.

    cktricky said...

    ...one thing I forgot to add, you'd need to be able to re-use this token per request (re-usable). I've seen this where you can replay for a specific resource but not for another on the same site. So you could send a 100 or 300 requests using this token but only to one specific page/action on the site. Also, you'd need to be attempting to automate the process a bit otherwise per request you could send to scanner and avoid the code/buby stuff altogether (keeping things like the cookies and the token itself off limits). Hmmm, I'm thinking this would be a good topic to cover in Part 4.