Jump to content

newbi3

Recommended Posts

EvilPortal 3.0 is here bring bug fixes and new features! The main focus of this release was to create what I am calling "Targeted Portals" which allow you to direct clients to different portals conditionally based on SSID, MAC, Hostname, or Useragent allowing for a much wider range of attacks. This version will break the portals you have created in the past so keep that in mind when updating.

Also, THIS IS NOT A THREAD TO ASK FOR HELP ON WRITING HTML, PHP, OR JAVASCRIPT. THERE ARE OTHER PLACES TO LEARN TO PROGRAM OTHER THAN THIS THREAD.

Features

  • Targeted Portals
  • Static Portals
  • Creating/Editing/Activating/Deleting Portals
  • White listings clients by ip address
  • Dynamically adding and revoking authorized clients
  • Live Preview of your portal through the module interface

Targeted Portals

Targeted Portals allow you to direct clients to different portals conditionally based on SSID, MAC, Hostname, or Useragent allowing for a much wider range of attacks.

Creating a Targeted Portal

  1. Go to the Portal Workbench in the EvilPortal module
  2. Click the drop down menu to the left of the "Portal Name" input box and select "Targeted"
  3. Give it a name
  4. Click the create new portal button

Edit Targeting Rules

  1. Click on the name of the portal you just created in list of portals
  2. Click the "Target Rule Editor" button in the top right corner of the Work Bench
  3. You should see a modal open up titled "Editing Rules for $portalname" with MAC, SSID, HOSTNAME, and USERAGENT sections
    • These sections represent the value that you can create routing conditions for.
    • Under each section you will see a sub-section titled "Exact" and "Regex". These let you create exact rules or rules that will match a pattern.
    • It should also be noted that these conditions are evaluated as an 'or' not an 'and'. The order that they are evaluated in can be change but more on that later.
  4. Once you figure out the rule you want to create click the "Add Rule" button
  5. You'll see a row appear that says "Key Value", "Destination", and "Remove". Fill out the values for Key Value and Destination.
    • The "Key Value" represents the value that you are checking. For example if the rule is for a SSID the value might be "office-wifi".
    • The "Destination" is the file that is the landing page you are routing clients that match your rule to. If this is an office portal you might want to call it OfficePortal.php. Just remember what you called it because we will need it later. (More on creating these later)
    • The "Remove" button removes the rule
  6. Click "Save" at the bottom

Creating The Destinations

  1. Click the "New File" button in the top right of the work bench.
  2. You should see modal open up titled "Creating New FIle". For the "File Name" field type the name of the destination
    • This must be the name you typed in for the destination field when setting up the rules. In this example it was "OfficePortal.php"
  3. In the "File Contents" field you will write the code to create your portal.
    • It should be noted that you need to make a post request to /captiveportal/index.php with a redirect destination called "target" in it.
    • In my opinion it is easiest to copy the contents of "default.php" and paste it here as a starting point.
  4. Click "Save" at the bottom

Important Notes

  • If a client connects and doesn't match any of the conditions you created, they will be routed to "default.php".
  • Currently there is not an easy way to change the order the rules are evaluated in, if you want to change them you have to do it manually via ssh.
    1. ssh into your pineapple
    2. cd into where your portal is (either /root/portals/$portalname or /sd/portals/$portalname)
    3. nano $portalname.ep (replace $portalname with whatever you called your portal)
    4. Change the order of the strings in the targeted_rules->rule_order array. The items that come first are evaluated first.

Basic Portals

Basic Portals are the same oldschool portals that you have come to know in Evil Portal. These are the portals that are created by default and they work in exactly the same way as they used to.

Known Bugs

  • HTTPS traffic is not blocked for un-authorized clients (my iptables suck)

If you find a bug please create an issue for it the projects Github Repo

Change Log

Version 3.1

  • Added ability to write and view logs on a per-portal basis
  • Created method writeLog($message) that writes to the portal log file
  • Created method notify($message) that sends a notification to the web ui
  • Added ability to download files
  • Tab button in file editor will now insert four spaces
  • Revamped the file editor modal
  • Showing file sizes in the portal workbench
  • Various quality of life improvements

Version 3.0

  • Created targeted portals which allow routing clients to different portals based on SSID, MAC, Hostname, or Useragent.
  • Created easy to use interface for setting up targeting rules
  • Added doc strings to all methods in module.php and functions in module.js
  • Made it easy to get the SSID of a client in your portal
  • Added ability to create and move portals on and to the SD card
  • Made IP address in the Authorized and White Listed clients lists clickable
  • Fixed redirection issues
  • Other QOL improvements.

Version 2.1

  • Removed un-needed verbosity
  • Made tab key indent in the editor instead of change elements
  • Added confirmation dialogue box when deleting a portal
  • Created auto-start feature
  • Various other quality of life updates

Version 2.0

  • Captive Portal is now purely iptables (because F*** NoDogSplash)

Version 1.0

  • Install/Remove NoDogSplash
  • Start/Stop NoDogSplash
  • Enable/Disable NoDogSplash
  • Create/Edit/Delete/Active Portals
  • Live Preview portals
  • All panels collapse for a better mobile experience

Just one more time for the people in the back; THIS IS NOT A THREAD TO ASK FOR HELP ON WRITING HTML, PHP, OR JAVASCRIPT. THERE ARE OTHER PLACES TO LEARN TO PROGRAM OTHER THAN THIS THREAD.

Screen Shot 2018-06-28 at 10.16.11 PM.png

Screen Shot 2018-06-28 at 10.20.47 PM.png

Screen Shot 2018-07-21 at 8.05.04 PM.png

Screen Shot 2018-07-21 at 8.05.32 PM.png

Link to comment
Share on other sites

  • Replies 263
  • Created
  • Last Reply

Hi all,

The new Evil Portal looks Promising.

Unfortunately my old captive portals won't work because it's no longer using nodogsplash.

However, for what I understand, it's a step in the right direction. Looking forward to learning how to use it.

Can someone tell me where the captive portal's images and html files are stored?

Thanks.

Link to comment
Share on other sites

The new EP looks great and I like that you've implemented some structure to portals and an API. I've come across a couple issues, some I consider to be real issues and others are just things that would be nice to have.

Real Issues

1. There is no redirect to the requested site once the client has been authorized. I followed the data flow and it appears the following files are accessed in order (index.php -> /www/captiveportal/index.php -> API.php -> Portal.php) and within Portal.php the methods handleAuthorization() and getResponse() are called. The problem is your redirect() method is never called in Portal.php. I tried adding it to handleAuthorization() but it appears the header does not get set because I still don't get redirected. I also tried adding it to MyPortal.php and removed the parent::showSuccess(); call.

Edit: I see now that redirect() is called in the authorizeClient() method but it still does not work.

2. When creating a new portal, if the name contains spaces then none of the portal files are created. A check should be in place to either work with spaces or explicitly deny the user from entering them.

3. When directories are added to portal directories (i.e. images/, resources/) they don't appear in the web interface. This could mislead users into thinking their directories do not exist.

Nice to have

1. It would be nice if tab characters could be inserted into the portal editor. I hate having to beat my space bar senseless to format my code. Tab support can easily be added with the following code:

$(document).delegate('#textbox', 'keydown', function(e) {
  var keyCode = e.keyCode || e.which;

  if (keyCode == 9) {
    e.preventDefault();
    var start = $(this).get(0).selectionStart;
    var end = $(this).get(0).selectionEnd;

    // set textarea value to: text before caret + tab + text after caret
    $(this).val($(this).val().substring(0, start)
                + "\t"
                + $(this).val().substring(end));

    // put caret at right position again
    $(this).get(0).selectionStart =
    $(this).get(0).selectionEnd = start + 1;
  }
});

2. You've already mentioned it before but blocking/redirecting HTTPS requests is really important. Pretty much every site that anyone will visit nowadays implements HTTPS so even if they connect to the Pineapple they will most likely not ever see the captive portal. Kinda feels useless without this functionality but I'm sure you're working on it already.

3. Not really a problem but I find that there are too many messages popping up under Evil Portal Messages. For example, I don't think it's necessary to post a message every time I edit a file. Maybe no one else see's this as a problem but I don't like clicking Clear All every minute. Just a thought.

The final thing I noticed that doesn't fall under either category above is an infinite chain of symlinks in /www/captiveportal/api. It doesn't seem to hurt anything but I thought you'd might like to know for a future update.

Link to comment
Share on other sites

Real Issues

1. There is no redirect to the requested site once the client has been authorized. I followed the data flow and it appears the following files are accessed in order (index.php -> /www/captiveportal/index.php -> API.php -> Portal.php) and within Portal.php the methods handleAuthorization() and getResponse() are called. The problem is your redirect() method is never called in Portal.php. I tried adding it to handleAuthorization() but it appears the header does not get set because I still don't get redirected. I also tried adding it to MyPortal.php and removed the parent::showSuccess(); call.

Edit: I see now that redirect() is called in the authorizeClient() method but it still does not work.

2. You've already mentioned it before but blocking/redirecting HTTPS requests is really important. Pretty much every site that anyone will visit nowadays implements HTTPS so even if they connect to the Pineapple they will most likely not ever see the captive portal. Kinda feels useless without this functionality but I'm sure you're working on it already.

3. Not really a problem but I find that there are too many messages popping up under Evil Portal Messages. For example, I don't think it's necessary to post a message every time I edit a file. Maybe no one else see's this as a problem but I don't like clicking Clear All every minute. Just a thought.

+1

the HTTPS problem hasn't been much of an issue for me as iPhones are usually what I am after and they request captive.apple.com (plain http). Other devices however never show the portal. The redirect has also been problematic for me.

Loving the work so far!

Link to comment
Share on other sites

I've come across another problem, not sure if others have experienced this. Once a client is authorized, if they try to go to the site they originally tried to access when the portal was displayed it continues to display the portal. Once I navigate away to another site using HTTP (getting harder to find these days) then everything works. For example:

Client attempts to access http://stackoverflow.com/
Captive portal is displayed
Client is authorized (but not redirected)
Client attempts to access http://stackoverflow.com/again and the captive portal is displayed once again even though they received the message stating they were authorized and their IP appears in the Authorized Clients list.
Client attempts to browse to http://www.puffycode.com/and all is well.

Edit:

One final thing. Can we get an option to store portals on the SD card on the NANO? Otherwise we're going to run out of storage space real quick.

Link to comment
Share on other sites

Hey newbi3,

unfortunately I can't use EP.

My problem is that after clicking on "Evil Portal" in the Modules dropdown Evil Portal shows up shortly (<1 second) and then a random other module is shown.

This behavior only occurs on EP.

Any Idea what might cause it? Did anybody else get this behavior?

I start thinking my Nano has some other defect?!? :wacko:

Link to comment
Share on other sites

Great job on this Newbi3! Def looks promising so far.

Anyone figure out a good way to Autostart EP on reboot yet? If not I'll be looking into a way when I get some more time and will post here unless Newbi3 is already building it in.

Link to comment
Share on other sites

Thanks for the feedback. Here are answers to your questions.

I've come across another problem, not sure if others have experienced this. Once a client is authorized, if they try to go to the site they originally tried to access when the portal was displayed it continues to display the portal. Once I navigate away to another site using HTTP (getting harder to find these days) then everything works. For example:

Client attempts to access http://stackoverflow.com/
Captive portal is displayed
Client is authorized (but not redirected)
Client attempts to access http://stackoverflow.com/again and the captive portal is displayed once again even though they received the message stating they were authorized and their IP appears in the Authorized Clients list.
Client attempts to browse to http://www.puffycode.com/and all is well.

Edit:

One final thing. Can we get an option to store portals on the SD card on the NANO? Otherwise we're going to run out of storage space real quick.

It sounds like there is something caching, try doing a hard refresh? And yes storing portals on SD cards is coming in a future release. I had to get v2 out before pentest with hak5 so it was just a bare minimum release.

Hey newbi3,

unfortunately I can't use EP.

My problem is that after clicking on "Evil Portal" in the Modules dropdown Evil Portal shows up shortly (<1 second) and then a random other module is shown.

This behavior only occurs on EP.

Any Idea what might cause it? Did anybody else get this behavior?

I start thinking my Nano has some other defect?!? :wacko:

Try uninstalling the other modules that you have installed. Is this happening on the nano or tetra?

Great job on this Newbi3! Def looks promising so far.

Anyone figure out a good way to Autostart EP on reboot yet? If not I'll be looking into a way when I get some more time and will post here unless Newbi3 is already building it in.

Autostart is coming in a future release:)

Hi all,
The new Evil Portal looks Promising.
Unfortunately my old captive portals won't work because it's no longer using nodogsplash.
However, for what I understand, it's a step in the right direction. Looking forward to learning how to use it.

Can someone tell me where the captive portal's images and html files are stored?
Thanks.

All of the files for the portals are stored in /root/portals/{portalName}

The new EP looks great and I like that you've implemented some structure to portals and an API. I've come across a couple issues, some I consider to be real issues and others are just things that would be nice to have.

Real Issues

1. There is no redirect to the requested site once the client has been authorized. I followed the data flow and it appears the following files are accessed in order (index.php -> /www/captiveportal/index.php -> API.php -> Portal.php) and within Portal.php the methods handleAuthorization() and getResponse() are called. The problem is your redirect() method is never called in Portal.php. I tried adding it to handleAuthorization() but it appears the header does not get set because I still don't get redirected. I also tried adding it to MyPortal.php and removed the parent::showSuccess(); call.

Edit: I see now that redirect() is called in the authorizeClient() method but it still does not work.

2. When creating a new portal, if the name contains spaces then none of the portal files are created. A check should be in place to either work with spaces or explicitly deny the user from entering them.

3. When directories are added to portal directories (i.e. images/, resources/) they don't appear in the web interface. This could mislead users into thinking their directories do not exist.

Nice to have

1. It would be nice if tab characters could be inserted into the portal editor. I hate having to beat my space bar senseless to format my code. Tab support can easily be added with the following code:

$(document).delegate('#textbox', 'keydown', function(e) {
  var keyCode = e.keyCode || e.which;

  if (keyCode == 9) {
    e.preventDefault();
    var start = $(this).get(0).selectionStart;
    var end = $(this).get(0).selectionEnd;

    // set textarea value to: text before caret + tab + text after caret
    $(this).val($(this).val().substring(0, start)
                + "\t"
                + $(this).val().substring(end));

    // put caret at right position again
    $(this).get(0).selectionStart =
    $(this).get(0).selectionEnd = start + 1;
  }
});

2. You've already mentioned it before but blocking/redirecting HTTPS requests is really important. Pretty much every site that anyone will visit nowadays implements HTTPS so even if they connect to the Pineapple they will most likely not ever see the captive portal. Kinda feels useless without this functionality but I'm sure you're working on it already.

3. Not really a problem but I find that there are too many messages popping up under Evil Portal Messages. For example, I don't think it's necessary to post a message every time I edit a file. Maybe no one else see's this as a problem but I don't like clicking Clear All every minute. Just a thought.

The final thing I noticed that doesn't fall under either category above is an infinite chain of symlinks in /www/captiveportal/api. It doesn't seem to hurt anything but I thought you'd might like to know for a future update.

1. I'll look into that.. What device are you seeing this happen on?

2. Yep I know about this - it will be fixed in the next release

3. This will also be fixed in the next release

nice-to-have-1: Alright I'll include that in a future release

nice-to-have-2: I know this is a big thing, i wasn't going to release without it working but didn't have the time to fix it

nice-to-have-3: Sure I can remove some of the verbosity

Link to comment
Share on other sites

Newbi3,

Awesome job, one thing i have also notice as well as the above. even after adding to the whitelist (and auto added to authorized) you are still directed through the portal and must authorize for internet use.

also

seems to still block some ports after going through which for capturing is not a problem but in the long term may raise some eyebrows. i.e. some irc ports , some ssh "sometimes" , again seemed to only notice this when i forgot i was still connected. so i'm not sure which others since those were my issue ones that i noticed by accident. ;-) (could be part of the same problem also, just thought i'd add)

other than that, love it.....

OutLaW

Link to comment
Share on other sites

I think it's happening on both for me but for sure on the TETRA. I'd have to try again on the NANO to verify.

I'm sorry I meant what OS is the client device running

Link to comment
Share on other sites

As a total new to the Pineapple in general where is the best place to learn how to utilize Evil Portal and PortalAuth -- I see lots of info in the MKV but not sure if thats going to be helpful with using the modules that are specific for the Nano? Is there any guide for the modules specifically for the Nano or should I read and watch the info for the MKV to brush up on how to make portals?

Link to comment
Share on other sites

Evil Portal has changed significantly but Portal Auth hasn't. You can use the MKV video for Portal Auth and it should all still be relevant except for a couple features that haven't been updated yet. The current version of Portal Auth implements the Evil Portal API when cloning a portal and sets everything up automagically. Other than that, if you want to build your own from scratch you need to learn about HTML, JavaScript, and PHP. Cloning a portal and looking at the code could really help you understand how all of it fits together.

Link to comment
Share on other sites

I hacked the following together to autostart EP until newbi3 builds in that feature. Not a complete solution by any means but the steps below got me running.

Steps:

root into Pineapple

cd /pineapple/modules/EvilPortal/executable

chmod +x executable

ln -s executable start_evilportal

(you can now start EvilPortal by CLI "./executable start" to make autostart on boot I did the following)

cd /etc/init.d

nano evilportal

#!/bin/sh /etc/rc.common
#EvilPortal init.d script.

START=99z

start() {
        /pineapple/modules/EvilPortal/executable/executable start
}

chmod +x evilportal

/etc/init.d/evilportal enable

cd /etc/rc.d

ls (should now be a file called S99zevilportal. If it's there you are good to go)

reboot pineapple - EP should autostart on boot :)

Hope this helps someone out.

Hey newbi3 - Any idea on when the https issues might be fixed?

Link to comment
Share on other sites

Thanks for the feedback. Here are answers to your questions.

Try uninstalling the other modules that you have installed. Is this happening on the nano or tetra?

Hey newbi3,

just found out:

EP is not being shown as my error.php (@ /www/) contains a "<body onload="goBack()">". The goback is called from index.php => redirect.php => error.php.

Is there any solution to that except renaming error.php?

Link to comment
Share on other sites

I have a PARTIAL solution to the HTTPS problem. I'm not sure if a fully functional solution can be found strictly with iptables and you should understand why by the end of this post.

I decided to try and redirect all HTTPS requests to nginx on the Pineapple instead of just blocking them or redirecting them to 80. I also tried redirecting all 443 requests to 80 but the only way to make it work is to use the return directive in nginx.conf to point those requests back to 172.16.42.1. The problem with that approach is it still requires an SSL handshake which will raise alarms in the browser about improperly configured certificates at the least and HSTS issues at the worst. The problem with my current method is that HSTS alarms will still be raised when the user tries to visit sites that have already been visited using HTTPS. However, requests over 443 will no longer just pass through the Pineapple, nor will they be dropped.

Step 1:

Create a key pair for the portal using Papers. If you don't know how to use Papers you can check out my demo video here. For this demo we'll call our keys portal.

Step 2:

Configure nginx.conf:

SSH into the Pineapple and copy the keys to /etc/nginx/ssl/

cp /pineapple/modules/Papers/includes/ssl/portal.* /etc/nginx/ssl/

Then edit the nginx.conf file by issuing the following command

nano /etc/nginx/nginx.conf

Find the opening server block and add the following line just under the listen 80; directive.

listen 443 ssl;

Add the ssl_certificate and ssl_protocol directives:

ssl_certificate /etc/nginx/ssl/portal.cer;
ssl_certificate_key /etc/nginx/ssl/portal.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

Press Ctrl+O and hit Enter to save the file. Then Ctrl+X to exit the nano editor. Next, issue the following command to reload the nginx configuration:

/etc/init.d/nginx reload

Here is the full server block from my configuration:

        server {
                listen  80;             # Port, make sure it is not in conflict with another http daemon.
                listen 443 ssl;
                server_name  www;       # Change this, reference -> http://nginx.org/en/docs/http/server_names.html
                error_page 404 =200 /index.php;
                error_log /dev/null;
                access_log /dev/null;
                fastcgi_connect_timeout 300;
                fastcgi_send_timeout 300;
                fastcgi_read_timeout 300;
                fastcgi_buffer_size 32k;
                fastcgi_buffers 4 32k;
                fastcgi_busy_buffers_size 32k;
                fastcgi_temp_file_write_size 32k;
                client_body_timeout 10;
                client_header_timeout 10;
                send_timeout 60;                # 60 sec should be enough, if experiencing alof of timeouts, increase this.
                output_buffers 1 32k;
                postpone_output 1460;

                root   /www/;           # Your document root, where all public material is.
                ssl_certificate /etc/nginx/ssl/portal.cer;
                ssl_certificate_key /etc/nginx/ssl/portal.pem;
                ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

                location ~ \.php$ {
                        fastcgi_index  index.php;
                        include        fastcgi_params;
                        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;

                        if (-f $request_filename) {
                                # Only throw it at PHP-FPM if the file exists (prevents some PHP exploits)
                                fastcgi_pass    unix:/var/run/php5-fpm.sock;     # The upstream determined above
                        }
                }
                error_page 404 =200 /index.php;
        }

Step 3:

Configure iptables (netfilter)

I ended up changing the API script in the Evil Portal module so I can just click the Start and Stop button without having to also enter these iptables commands every time. Here is what I did.

cd /pineapple/modules/EvilPortal/api/
nano module.php

Scroll down to the startCaptivePortal() function and add the following lines of code in the //Configure other rules section.

exec("iptables -t nat -A PREROUTING -s 172.16.42.0/24 -p tcp --dport 443 -j DNAT --to-destination 172.16.42.1:443");
exec("iptables -A INPUT -p tcp --dport 443 -j ACCEPT");

I also commented out the rule to drop all 443 requests.

The whole function should look like this:

    public function startCaptivePortal()
    {

        // Delete client tracking file if it exists
        if (file_exists($this->CLIENTS_FILE)) {
            unlink($this->CLIENTS_FILE);
        }

        // Enable forwarding. It should already be enabled on the pineapple but do it anyways just to be safe
        exec("echo 1 > /proc/sys/net/ipv4/ip_forward");
        exec("ln -s /pineapple/modules/EvilPortal/includes/api /www/captiveportal");

        // Insert allowed clients into tracking file
        $allowedClients = file_get_contents($this->ALLOWED_FILE);
        file_put_contents($this->CLIENTS_FILE, $allowedClients);

        // Configure other rules
        exec("iptables -t nat -A PREROUTING -s 172.16.42.0/24 -p tcp --dport 80 -j DNAT --to-destination 172.16.42.1:80");
        exec("iptables -t nat -A PREROUTING -s 172.16.42.0/24 -p tcp --dport 443 -j DNAT --to-destination 172.16.42.1:443");
        exec("iptables -A INPUT -p tcp --dport 53 -j ACCEPT");
        exec("iptables -A INPUT -p tcp --dport 443 -j ACCEPT");

        // Add rule for each allowed client
        $lines = file($this->CLIENTS_FILE);
        foreach ($lines as $client) {
            $this->authorizeClient($client);
            //exec("iptables -t nat -I PREROUTING -s {$client} -j ACCEPT");
        }

        // Drop everything else
        //exec("iptables -I INPUT -p tcp --dport 443 -j DROP");

        return $this->checkCaptivePortalRunning();

    }

Then scroll down to the stopCaptivePortal() function and add the following lines of code:

exec("iptables -t nat -D PREROUTING -s 172.16.42.0/24 -p tcp --dport 443 -j DNAT --to-destination 172.16.42.1:443");
exec("iptables -D INPUT -p tcp --dport 443 -j ACCEPT");

The whole function should look like this:

    public function stopCaptivePortal()
    {
        if (file_exists($this->CLIENTS_FILE)) {
            $lines = file($this->CLIENTS_FILE);
            foreach ($lines as $client) {
                $this->revokeClient($client);
                //exec("iptables -t nat -D PREROUTING -s {$client} -j ACCEPT");
            }
            unlink($this->CLIENTS_FILE);
        }

        exec("iptables -t nat -D PREROUTING -s 172.16.42.0/24 -p tcp --dport 80 -j DNAT --to-destination 172.16.42.1:80");
        exec("iptables -t nat -D PREROUTING -s 172.16.42.0/24 -p tcp --dport 443 -j DNAT --to-destination 172.16.42.1:443");
        exec("iptables -D INPUT -p tcp --dport 53 -j ACCEPT");
        exec("iptables -D INPUT -p tcp --dport 443 -j ACCEPT");
        exec("iptables -D INPUT -j DROP");

        return $this->checkCaptivePortalRunning();

    }

Press Ctrl+o and Enter to save then Ctrl+x to exit nano. Now you should be able to start and stop Evil Portal from your browser and these rules will be added/removed each time. As I said at the beginning this is just a partial solution and will still be stopped by HSTS but it is much better than having all 443 requests go straight out to the internet in my opinion.

Edit:

I've noticed that the HSTS issues arise in Firefox but not Chrome (both updated on OS X El Capitan). However, on my Android phone (running Lollipop 5.0.1) Chrome blocks the connection due to HSTS.

Link to comment
Share on other sites

I have a PARTIAL solution to the HTTPS problem. I'm not sure if a fully functional solution can be found strictly with iptables and you should understand why by the end of this post.

I decided to try and redirect all HTTPS requests to nginx on the Pineapple instead of just blocking them or redirecting them to 80. I also tried redirecting all 443 requests to 80 but the only way to make it work is to use the return directive in nginx.conf to point those requests back to 172.16.42.1. The problem with that approach is it still requires an SSL handshake which will raise alarms in the browser about improperly configured certificates at the least and HSTS issues at the worst. The problem with my current method is that HSTS alarms will still be raised when the user tries to visit sites that have already been visited using HTTPS. However, requests over 443 will no longer just pass through the Pineapple, nor will they be dropped.

Step 1:

Create a key pair for the portal using Papers. If you don't know how to use Papers you can check out my demo video here. For this demo we'll call our keys portal.

Step 2:

Configure nginx.conf:

SSH into the Pineapple and copy the keys to /etc/nginx/ssl/

cp /pineapple/modules/Papers/includes/ssl/portal.* /etc/nginx/ssl/

Then edit the nginx.conf file by issuing the following command

nano /etc/nginx/nginx.conf

Find the opening server block and add the following line just under the listen 80; directive.

listen 443 ssl;

Add the ssl_certificate and ssl_protocol directives:

ssl_certificate /etc/nginx/ssl/portal.cer;
ssl_certificate_key /etc/nginx/ssl/portal.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

Press Ctrl+O and hit Enter to save the file. Then Ctrl+X to exit the nano editor. Next, issue the following command to reload the nginx configuration:

/etc/init.d/nginx reload

Here is the full server block from my configuration:

        server {
                listen  80;             # Port, make sure it is not in conflict with another http daemon.
                listen 443 ssl;
                server_name  www;       # Change this, reference -> http://nginx.org/en/docs/http/server_names.html
                error_page 404 =200 /index.php;
                error_log /dev/null;
                access_log /dev/null;
                fastcgi_connect_timeout 300;
                fastcgi_send_timeout 300;
                fastcgi_read_timeout 300;
                fastcgi_buffer_size 32k;
                fastcgi_buffers 4 32k;
                fastcgi_busy_buffers_size 32k;
                fastcgi_temp_file_write_size 32k;
                client_body_timeout 10;
                client_header_timeout 10;
                send_timeout 60;                # 60 sec should be enough, if experiencing alof of timeouts, increase this.
                output_buffers 1 32k;
                postpone_output 1460;

                root   /www/;           # Your document root, where all public material is.
                ssl_certificate /etc/nginx/ssl/portal.cer;
                ssl_certificate_key /etc/nginx/ssl/portal.pem;
                ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

                location ~ \.php$ {
                        fastcgi_index  index.php;
                        include        fastcgi_params;
                        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;

                        if (-f $request_filename) {
                                # Only throw it at PHP-FPM if the file exists (prevents some PHP exploits)
                                fastcgi_pass    unix:/var/run/php5-fpm.sock;     # The upstream determined above
                        }
                }
                error_page 404 =200 /index.php;
        }

Step 3:

Configure iptables (netfilter)

I ended up changing the API script in the Evil Portal module so I can just click the Start and Stop button without having to also enter these iptables commands every time. Here is what I did.

cd /pineapple/modules/EvilPortal/api/
nano module.php

Scroll down to the startCaptivePortal() function and add the following lines of code in the //Configure other rules section.

exec("iptables -t nat -A PREROUTING -s 172.16.42.0/24 -p tcp --dport 443 -j DNAT --to-destination 172.16.42.1:443");
exec("iptables -A INPUT -p tcp --dport 443 -j ACCEPT");

I also commented out the rule to drop all 443 requests.

The whole function should look like this:

    public function startCaptivePortal()
    {

        // Delete client tracking file if it exists
        if (file_exists($this->CLIENTS_FILE)) {
            unlink($this->CLIENTS_FILE);
        }

        // Enable forwarding. It should already be enabled on the pineapple but do it anyways just to be safe
        exec("echo 1 > /proc/sys/net/ipv4/ip_forward");
        exec("ln -s /pineapple/modules/EvilPortal/includes/api /www/captiveportal");

        // Insert allowed clients into tracking file
        $allowedClients = file_get_contents($this->ALLOWED_FILE);
        file_put_contents($this->CLIENTS_FILE, $allowedClients);

        // Configure other rules
        exec("iptables -t nat -A PREROUTING -s 172.16.42.0/24 -p tcp --dport 80 -j DNAT --to-destination 172.16.42.1:80");
        exec("iptables -t nat -A PREROUTING -s 172.16.42.0/24 -p tcp --dport 443 -j DNAT --to-destination 172.16.42.1:443");
        exec("iptables -A INPUT -p tcp --dport 53 -j ACCEPT");
        exec("iptables -A INPUT -p tcp --dport 443 -j ACCEPT");

        // Add rule for each allowed client
        $lines = file($this->CLIENTS_FILE);
        foreach ($lines as $client) {
            $this->authorizeClient($client);
            //exec("iptables -t nat -I PREROUTING -s {$client} -j ACCEPT");
        }

        // Drop everything else
        //exec("iptables -I INPUT -p tcp --dport 443 -j DROP");

        return $this->checkCaptivePortalRunning();

    }

Then scroll down to the stopCaptivePortal() function and add the following lines of code:

exec("iptables -t nat -D PREROUTING -s 172.16.42.0/24 -p tcp --dport 443 -j DNAT --to-destination 172.16.42.1:443");
exec("iptables -D INPUT -p tcp --dport 443 -j ACCEPT");

The whole function should look like this:

    public function stopCaptivePortal()
    {
        if (file_exists($this->CLIENTS_FILE)) {
            $lines = file($this->CLIENTS_FILE);
            foreach ($lines as $client) {
                $this->revokeClient($client);
                //exec("iptables -t nat -D PREROUTING -s {$client} -j ACCEPT");
            }
            unlink($this->CLIENTS_FILE);
        }

        exec("iptables -t nat -D PREROUTING -s 172.16.42.0/24 -p tcp --dport 80 -j DNAT --to-destination 172.16.42.1:80");
        exec("iptables -t nat -D PREROUTING -s 172.16.42.0/24 -p tcp --dport 443 -j DNAT --to-destination 172.16.42.1:443");
        exec("iptables -D INPUT -p tcp --dport 53 -j ACCEPT");
        exec("iptables -D INPUT -p tcp --dport 443 -j ACCEPT");
        exec("iptables -D INPUT -j DROP");

        return $this->checkCaptivePortalRunning();

    }

Press Ctrl+o and Enter to save then Ctrl+x to exit nano. Now you should be able to start and stop Evil Portal from your browser and these rules will be added/removed each time. As I said at the beginning this is just a partial solution and will still be stopped by HSTS but it is much better than having all 443 requests go straight out to the internet in my opinion.

Edit:

I've noticed that the HSTS issues arise in Firefox but not Chrome (both updated on OS X El Capitan). However, on my Android phone (running Lollipop 5.0.1) Chrome blocks the connection due to HSTS.

Looks good, definitely a good start. I'm not sure there is going to be a good way to get around HSTS.

Link to comment
Share on other sites

Looks good, definitely a good start. I'm not sure there is going to be a good way to get around HSTS.

Yeah...I've been playing around with this a little today to try and find a better way but so far no such luck. I wish there was a way to redirect 443 traffic to 80 at the network layer so we wouldn't need to establish certificates. That would defeat our HSTS issues. So far any attempt of that using iptables hasn't worked since the target's browser flat out rejects it.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...