Missing TLS ciphers when running Burp Suite

I’ve just started testing a new product. The traffic was redirected to the transparent Burp Proxy by altering the DNS response, but the traffic wasn’t showing up in the HTTP history.

It was then I saw the “Alerts” tab was orange, and this message was showing:

The client failed to negotiate an SSL connection to blah.com:443: no cipher suites in common

This is an embedded device – they often have a much more limited set of ciphers supported. Unfortunately Burp gave no hint of which suite was being request.

Crack open Wireshark, and we see

Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA

And indeed, this wasn’t listed on the SSL ciphers in Burp.

Turns out this cipher is controlled by export restrictions and not distributed with the normal JRE.

To resolve this, firstly, make sure you have Oracle JRE installed. Follow the instructions I have posted before. 8 seems to be the best version – 9 still causes a lot of quirks. OpenJDK just doesn’t cut it with Burp unfortunately.

The google for “JCE 8” (or whichever version you have). You will get to a download for the Java Cryptography Extensions:

http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html

Download the zip, and unzip it to:

/usr/lib/jvm/java-8-oracle/jre/lib/security

Replace the 8 with your version. It will overwrite two files, back them up if you think you need to.

Restart Burp and you should now be able to intercept traffic.

Re-use of SSH keys across thousands of devices

John Matherly, of Shodan fame, posted a blog to /r/netsec (comments are relatively interesting) last week showing how he had used the Shodan Python API combined with “facets” to find the most common SSH fingerprints.

I’m a heavy user of Shodan, but largely via the web front-end. I thought I’d take this as an opportunity to get the API working. It’s very easy. All instructions are under Ubuntu 14.04, but will likely work for any Ubuntu like distro.

First make sure you have easy_install which is part of setuptools – you will likely have this already if you have built anything big in Python:

sudo apt-get install python-setuptools

Next, install the Shodan API itself:

easy_install shodan

Simple – we should be done now.

You need to sign up to Shodan and get an API key. If you use Shodan regularly, I would suggest getting a paid-for plan (it’s very good value), but a free account will have access to the API, albeit with limitations.

Let’s test it with a simple search first:

import shodan

SHODAN_API_KEY = "dontbeusingmykey"

api = shodan.Shodan(SHODAN_API_KEY)

try:
    results = api.search('port:22 country:GB')

    print 'Results found: %s' % results['total']
    for result in results['matches']:
        print 'IP: %s' % result['ip_str']
        print result['data']
        print ''
except shodan.APIError, e:
    print 'Error: %s' % e

This should throw a huge list of results back for any hosts in the UK (country code GB which I always forget) with port 22 open:

IP: 83.105.125.97
SSH-2.0-Cisco-1.25
Key type: ssh-rsa
Key: AAAAB3NzaC1yc2EAAAADAQABAAABAQCyV7QrX9EwBrRsQBeRE4gryZldmUwHSz9PCJtcaaw4y8sm
facMlgxnMNQ2KyaEpOmDVBaNgqWFD8ekalnci84G1AvZgWJ4rHIcixMouNecbbZrmdMSPxG6FSS8
paNLANBaiLuAeBI2RSk+XD4DKxKRGlJO9FG18VrKkh/t1pbV2gxW3hu9PQkirrvZkhwk9RHVW10M
8hdpXtWlM3BrR5tI/pyWk1B6/ucRR6DzQHevtDLL+BjBVwRp0gIh7t352ciCD+CwSsjCb9hZh8w/
9yp38WDcYUPT2loDFQHJxsNTxIa3PsiIJZirBrNAbDGIl7bRAXti4iWYDcqLEN1FQEZh
Fingerprint: 4c:39:7e:bc:38:b3:22:53:4a:a0:81:29:04:9c:03:35

IP: 178.62.189.135
SSH-2.0-OpenSSH_5.3
Key type: ssh-rsa
Key: AAAAB3NzaC1yc2EAAAADAQABAAABAQC/ElKK7fznlds8OTx2i9m7IOjSFaKbaSlbKpLc9lCuSkH/
YjHNwZb+vRihYULvDoTIfusCLjzOLYNp49zBplv/Jbkyy3AIUq0QzMmjZmFTuKO05BZGTTmH9jol
aFKjLliN5T//Z3q83S4p6+3xTvvpWyk6RkeisbrjxzFNdWuGdTMAN21/vgsgofi79tvjomiC7PuA
7pZn8l2hOJaG1F17NHhyURV7pgClHx+01H/ZSFXVL8MMF5mhku7Uf10JylSbAWDZntWQZx8YFW1d
ABGrdzhDmCR9OH87WCKkgY5NtcwQDp8z59LBHvu1oQp22RJDrca8+V2b5fOjbSMhColh
Fingerprint: 7d:3b:18:9d:00:54:2f:44:4e:5a:cc:07:b9:2c:1e:d3

Now this is interesting and useful, but Shodan has a very neat bit of functionality called “facets”. The simplest way of explaining these is that it allows me to group the results and show you the top by count.

For example, we could find the top ports open across the UK:

import shodan

SHODAN_API_KEY = "jesustakethewheel"

api = shodan.Shodan(SHODAN_API_KEY)

try:

    results = api.count('country:GB', facets=[('port', 10)])

    for facet in results['facets']['port']:
        print '%s -- %s' % (facet['value'], facet['count'])

except shodan.APIError, e:
    print 'Error: %s' % e

Which gives us the following results:

7547 -- 2519825
80 -- 1816315
443 -- 1051424
22 -- 506137
5060 -- 499811
1723 -- 423132
25 -- 382716
8080 -- 351585
500 -- 242772
21 -- 241357

As expected, we have the common ports of 80 (http), 443 (https), 22 (ssh), 25 (SMTP), 8080 (http or http proxy), and 21 (telnet). What’s the top port 7547 though?

This is TR-069 or CWMP (CPE WAN management protocol), a http based protocol that allows the remote management of customer premises equipment i.e. lets your ISP remotely control your router. It’s open on a worryingly large number of routers and suffers from a number of vulnerabilities, most notably the “Misfortune Cookie“.

Anyway, facets also let us group by more esoteric fields, such as the SSH fingerprint presented each time you try to connect via SSH. This is the focus of John’s blog post.

import shodan

SHODAN_API_KEY = "hesapiratehesaftermybooty"

api = shodan.Shodan(SHODAN_API_KEY)

try:

    results = api.count('port:22 country:GB', facets=[('ssh.fingerprint', 10)])

    for facet in results['facets']['ssh.fingerprint']:
        print '%s -- %s' % (facet['value'], facet['count'])

except shodan.APIError, e:
    print 'Error: %s' % e

I’ve restricted this to the UK – I know the lay of the land better, and dealing with any issues found is a little easier both from a communication and legal standpoint.

The results are as follows:

7c:a8:25:21:13:a2:eb:00:a6:c1:76:ca:6b:48:6e:bf -- 11758
a8:99:c2:92:08:fb:5e:de:4b:96:14:de:61:df:ad:6d -- 7990
03:56:e6:52:ee:d2:da:f0:73:b5:df:3d:09:08:54:b7 -- 2239
b4:af:64:0c:9a:ed:ed:4d:b1:c0:12:5d:c9:e4:c8:f0 -- 1217
eb:65:52:6e:40:28:af:a6:36:5b:b3:b4:0c:5d:32:3d -- 1091
39:aa:e4:e9:a2:e7:c1:04:9d:00:9f:b6:99:d5:9c:bd -- 880
57:94:42:63:a1:91:0b:58:a6:33:cb:db:fe:b5:83:38 -- 782
34:47:0f:e9:1a:c2:eb:56:eb:cc:58:59:3a:02:80:b6 -- 630
14:96:82:72:6f:bc:a5:14:53:1c:72:71:0d:8b:cb:c2 -- 598
f9:76:13:e7:86:11:8b:64:0f:e0:39:ea:e9:14:a7:18 -- 471

Those top three are very, very common! How has this happened?

Let’s plug the top one back into Shodan via the web front-end:

Shodan results

What can we tell from those organisations and hostnames? These are all devices on consumer broadband connections. Routers, NAS, other devices with SSH open.

So what is the issue here? Why are these duplicate SSH fingerprints an issue?

The SSH fingerprint is a hash of the public key used by the router for SSH communication. It provides a human-readable way of checking that you are connecting to the host you are expecting to connect to. If it has a different public key, you should nearly always get a different fingerprint.

SSH keys should be unique per device. The first time they boot, they should use a source of entropy to generate unique keys. The reason so many devices have the same keys is that the keys are stored in firmware and are not changed.

Having the same fingerprint means it is no longer possible for you to authenticate the device you are connecting to. Is it your router, or another person with the same router? Who knows!

It also, worryingly, means that there is a private key that could be used to impersonate and possibly even access these devices. This key may be stored in the firmware of these devices and recovered. This has happened in the real-world.

It is worthwhile noting, that even with the public/private keypair, you still need to MITM a SSH conversation to be able to decrypt it. SSH uses Diffie-Hellmann key exchange to ensure Perfect Forward Secrecy. The session keys are forgotten and the conversation can never be decrypted.

But above all, the biggest question is why is SSH open on so many broadband connections? Routers shouldn’t have SSH open like this. If they are NAS or similar behind the router and using UPnP to forward ports, why are routers still allowing this? If SSH is open by default, it would suggest that there is at least one account that can login by default. If the SSH keys are the same across all devices, how are we to know that the login credentials differ from device to device?

Quick and easy fake WiFi access point in Kali

I’m working on a project at the moment that requires me to observe traffic from an iOS/Android app to various external IPs.

The easiest way to do this is to setup a fake WiFi access point and use Wireshark to sniff the traffic. This is very easy in Kali Linux.

1. Connect the Kali box to the Internet

On my machine, this is as simple as connecting to my WiFi network “DoingAJob5G” using the built-in wireless card on my x220. I use the GUI provided with Kali.

Using ifconfig I can see that this adapter is called wlan0.

You could use wired Ethernet, then in all likelihood this will be eth0 instead.

2. Connect an external WiFi adapter that is supported by hostapd

I’m using a USB TP-LINK TL-WN722N which is using an Atheros AR9271 chipset. These are cheap (£8-£10), powerful and reliable.

I suspect many USB WiFi adapters are compatible with hostapd, unfortunately I can’t see a clear source documenting which ones.

Check it works by connecting to any network using Kali’s GUI. This will save you hassle later if there are any driver or hardware issues.

3. Bring up the new wireless interface.

Use ifconfig -a to see the new wireless interface name:

wlan3     Link encap:Ethernet  HWaddr c0:4a:00:1e:64:fd  
          BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

Bring this up as the gateway for your new wireless network. I am using 10.0.0.1/24 simply to avoid any chance of confusion with my internal NATed 192.168.0.1/24 network.

root@kali:~# ifconfig wlan3 10.0.0.1/24 up
root@kali:~# ifconfig wlan3
wlan3     Link encap:Ethernet  HWaddr c0:4a:00:1e:64:fd  
          inet addr:10.0.0.1  Bcast:10.0.0.255  Mask:255.255.255.0
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

4. Configure and run DHCP and DNS services

DHCP assigns IP addresses when clients connect, and DNS provides resolution of names to IPs.

Most wireless clients expect DHCP by default, so it is convenient to run a DHCP server. You can manually set IP addresses, but it’s really easier to do DHCP.

Running our own DNS server means that we can easily intercept and alter DNS queries, which can assist in setting up man-in-the-middle attacks.

A piece of software called dnsmasq does both DHCP and DNS and is very simple to setup.

First, install dnsmasq:

apt-get install dnsmasq

Next, create a config file dnsmasq.conf as follows:

interface=wlan3
dhcp-range=10.0.0.10,10.0.0.250,12h
dhcp-option=3,10.0.0.1
dhcp-option=6,10.0.0.1
server=8.8.8.8
log-queries
log-dhcp

This is about as simple as it gets. Only listen on wlan3, our additional wireless adapter. Hand out DHCP addresses from 10.0.0.10-10.0.0.250. DHCP option 3 is the gateway, DHCP option 6 is the DNS server – both of these should be set to our wlan3 IP of 10.0.0.1. server specifies upstream DNS servers that will handle most DNS queries – I have provided Google’s DNS server of 8.8.8.8. Finally, log DNS queries and DHCP requests – this just makes it easier to check everything is working.

We also want to create a file fakehosts.conf to allow us to spoof certain DNS requests:

10.0.0.9 neohub.co.uk

This will cause the dnsmasq DNS server to respond with 10.0.0.9 to any request for neohub.co.uk.

We then need to bring dnsmasq up. I want it to run with output to stderr, so this is done as follows:

dnsmasq -C dnsmasq.conf -H fakehosts.conf -d

5. Configure and run hostapd

Next, we need to get our wireless adapter to run as a access point.

hostapd allows us to do this.

Install hostapd:

apt-get install hostapd

Create a config file hostapd.conf:

interface=wlan3
driver=nl80211
ssid=Kali-MITM
channel=1

Again – really simple. Use our additional wireless adapter wlan3 with the nl80211 drivers (which seem to cover pretty much all modern adapters than can be APs), set the SSID to Kali-MITM and set the channel to 1. There is no encryption etc. but I really don’t need or want it for sniffing traffic.

Then start hostapd:

root@kali:~# hostapd ./hostapd.conf 
Configuration file: ./hostapd.conf
Failed to update rate sets in kernel module
Using interface wlan3 with hwaddr c0:4a:00:1e:64:fd and ssid 'Kali-MITM'

6. Setup routing for the access point

You want a very simple setup at the moment – act as a basic NAT gateway between wlan3 and wlan0.

Without going into any detail, the following commands will set this up:

sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -P FORWARD ACCEPT
sudo iptables --table nat -A POSTROUTING -o wlan0 -j MASQUERADE

At this stage, you should now be able to connect to Kali-MITM, get an IP address, and start using the Internet.