diff --git a/README.md b/README.md
index 70689c2..faebf98 100644
--- a/README.md
+++ b/README.md
@@ -6,16 +6,15 @@ The module automates PMKID attack
**Device:** Tetra
+[![Demo video](https://i.ibb.co/wMf1BGg/PMKIDAttack-You-Tube.png)](https://youtu.be/AU2kAd3PUz8)
+
**Official topics for discussions:**
```
https://codeby.net/threads/6-wifi-pineapple-pmkidattack.66709
https://forums.hak5.org/topic/45365-module-pmkidattack/
```
-[![Watch the video](https://i.ibb.co/wMf1BGg/PMKIDAttack-You-Tube.png)](https://youtu.be/AU2kAd3PUz8)
-
-**Install module:**
-
+**Module installation:**
```
opkg update && opkg install git git-http
cd /pineapple/modules/
diff --git a/api/module.php b/api/module.php
index ac2e134..9bc7eb4 100644
--- a/api/module.php
+++ b/api/module.php
@@ -9,15 +9,16 @@
class PMKIDAttack extends Module
{
const PATH_MODULE = '/pineapple/modules/PMKIDAttack';
+ const PATH_LOG_FILE = '/var/log/pmkidattack.log';
public function route()
{
switch ($this->request->action) {
- case 'isConnected':
- $this->isConnected();
+ case 'clearLog':
+ $this->clearLog();
break;
- case 'getInfo':
- $this->getInfo();
+ case 'getLog':
+ $this->getLog();
break;
case 'getDependenciesStatus':
$this->getDependenciesStatus();
@@ -55,18 +56,33 @@ public function route()
}
}
- public function isConnected()
+ protected function clearLog()
{
- $connected = @fsockopen("google.com", 80);
+ if (!file_exists(self::PATH_LOG_FILE)) {
+ touch(self::PATH_LOG_FILE);
+ }
- if ($connected) {
- $this->response = array('success' => true);
- } else {
- $this->response = array('success' => false);
+ exec('rm ' . self::PATH_LOG_FILE);
+ touch(self::PATH_LOG_FILE);
+ }
+
+ protected function getLog()
+ {
+ if (!file_exists(self::PATH_LOG_FILE)) {
+ touch(self::PATH_LOG_FILE);
}
+
+ $file = file_get_contents(self::PATH_LOG_FILE);
+
+ $this->response = array("pmkidlog" => $file);
+ }
+
+ protected function formatLog($massage)
+ {
+ return '[' . date("Y-m-d H:i:s") . '] ' . $massage . PHP_EOL;
}
- private function getDependenciesStatus()
+ protected function getDependenciesStatus()
{
if (!file_exists('/tmp/PMKIDAttack.progress')) {
if ($this->checkDependency()) {
@@ -93,7 +109,7 @@ protected function checkDependency()
return ((trim(exec("which hcxdumptool")) == '' ? false : true) && $this->uciGet("pmkidattack.module.installed"));
}
- private function managerDependencies()
+ protected function managerDependencies()
{
if (!$this->checkDependency()) {
$this->execBackground(self::PATH_MODULE . "/scripts/dependencies.sh install");
@@ -104,26 +120,31 @@ private function managerDependencies()
}
}
- private function statusDependencies()
+ protected function statusDependencies()
{
- if (!file_exists('/tmp/HandshakeCrack.progress')) {
+ if (!file_exists('/tmp/PMKIDAttack.progress')) {
$this->response = array('success' => true);
} else {
$this->response = array('success' => false);
}
}
- private function startAttack()
+ protected function startAttack()
{
$this->uciSet('pmkidattack.attack.bssid', $this->request->bssid);
$this->uciSet('pmkidattack.attack.run', '1');
exec("echo " . $this->getFormatBSSID() . " > " . self::PATH_MODULE . "/filter.txt");
exec(self::PATH_MODULE . "/scripts/PMKIDAttack.sh start " . $this->getFormatBSSID());
+
+ $massageLog = 'Start attack ' . $this->request->bssid;
+
+ file_put_contents(self::PATH_LOG_FILE, $this->formatLog($massageLog), FILE_APPEND);
+
$this->response = array('success' => true);
}
- private function stopAttack()
+ protected function stopAttack()
{
$this->uciSet('pmkidattack.attack.run', '0');
@@ -136,20 +157,27 @@ private function stopAttack()
exec("rm -rf /tmp/" . $this->getFormatBSSID() . '.pcapng');
exec("rm -rf " . self::PATH_MODULE . "/log/output.txt");
+ $massageLog = 'Stop attack ' . $this->getBSSID();
+
+ file_put_contents(self::PATH_LOG_FILE, $this->formatLog($massageLog), FILE_APPEND);
+
$this->response = array('success' => true);
}
- private function catchPMKID()
+ protected function catchPMKID()
{
if ($this->checkPMKID()) {
+ $massageLog = 'PMKID ' . $this->getBSSID() . ' intercepted!';
+
+ file_put_contents(self::PATH_LOG_FILE, $this->formatLog($massageLog), FILE_APPEND);
$this->response = array('success' => true);
} else {
$this->response = array('success' => false);
}
}
- private function getFormatBSSID()
+ protected function getFormatBSSID()
{
$bssid = $this->uciGet('pmkidattack.attack.bssid');
$bssidFormat = str_replace(':', '', $bssid);
@@ -157,7 +185,12 @@ private function getFormatBSSID()
return $bssidFormat;
}
- private function checkPMKID()
+ protected function getBSSID()
+ {
+ return $this->uciGet('pmkidattack.attack.bssid');
+ }
+
+ protected function checkPMKID()
{
$searchLine = 'PMKIDs';
@@ -168,7 +201,7 @@ private function checkPMKID()
return strpos($file, $searchLine) !== false;
}
- private function getPMKIDFiles()
+ protected function getPMKIDFiles()
{
$pmkids = [];
exec("find -L " . self::PATH_MODULE . "/pcapng/ -type f -name \"*.**pcapng\" 2>&1", $files);
@@ -187,7 +220,7 @@ private function getPMKIDFiles()
$this->response = array("pmkids" => $pmkids);
}
- private function downloadPMKID()
+ protected function downloadPMKID()
{
$fileName = basename($this->request->file, '.pcapng');
@@ -200,12 +233,12 @@ private function downloadPMKID()
$this->response = array("download" => $this->downloadFile("/tmp/". $fileName .".tar.gz"));
}
- private function deletePMKID()
+ protected function deletePMKID()
{
exec("rm -rf " . $this->request->file);
}
- private function getOutput()
+ protected function getOutput()
{
if (!empty($this->request->pathPMKID)) {
exec('hcxpcaptool -z /tmp/pmkid.txt ' . $this->request->pathPMKID . ' &> ' . self::PATH_MODULE . '/log/output2.txt');
@@ -218,7 +251,7 @@ private function getOutput()
$this->response = array("output" => $output);
}
- private function getStatusAttack()
+ protected function getStatusAttack()
{
if ($this->uciGet('pmkidattack.attack.run') == '1') {
$this->response = array('success' => true);
@@ -226,4 +259,4 @@ private function getStatusAttack()
$this->response = array('success' => false);
}
}
-}
\ No newline at end of file
+}
diff --git a/js/module.js b/js/module.js
index e014302..3795f01 100644
--- a/js/module.js
+++ b/js/module.js
@@ -1,44 +1,24 @@
-registerController('PMKIDAttack_IsConnected', ['$api', '$scope', '$rootScope', '$interval', function ($api, $scope, $rootScope, $interval) {
- $rootScope.isConnected = false;
- $rootScope.noDependencies = false;
- $rootScope.running = false;
- $rootScope.accessPoints = [];
- $rootScope.unassociatedClients = [];
- $rootScope.outOfRangeClients = [];
- $rootScope.captureRunning = false;
+registerController('PMKIDAttack_Log', ['$api', '$scope', '$rootScope', '$interval', function ($api, $scope, $rootScope, $interval) {
+ $scope.wipe = "Clear";
+ $scope.clear = "Clear";
+ $scope.pmkidlog = '';
- var isConnected = function () {
+ $scope.clearLog = (function () {
$api.request({
module: "PMKIDAttack",
- action: "isConnected"
- }, function (response) {
- if (!response.success) {
- $rootScope.isConnected = true;
- } else {
- $rootScope.isConnected = false;
- }
- });
- };
-
- $api.request({
- module: "PMKIDAttack",
- action: "getDependenciesStatus"
- }, function (response) {
- if (response.install == 'Install') {
- $rootScope.noDependencies = true;
- isConnected();
- }
-
- console.log(response.install);
+ action: "clearLog"
+ }, function (response) { })
});
- var interval = $interval(function () {
- if (!$rootScope.isConnected) {
- $interval.cancel(interval);
- } else {
- isConnected();
- }
- }, 5000);
+ $interval(function () {
+ $api.request({
+ module: "PMKIDAttack",
+ action: "getLog"
+ }, function (response) {
+ $scope.pmkidlog = response.pmkidlog;
+ })
+ }, 2000);
+
}]);
registerController('PMKIDAttack_Dependencies', ['$api', '$scope', '$rootScope', '$interval', function ($api, $scope, $rootScope, $interval) {
@@ -46,12 +26,12 @@ registerController('PMKIDAttack_Dependencies', ['$api', '$scope', '$rootScope',
$scope.installLabel = "default";
$scope.processing = false;
$rootScope.handshakeInfo = false;
+ $rootScope.noDependencies = false;
+ $rootScope.running = false;
+ $rootScope.captureRunning = false;
- $rootScope.status = {
+ $scope.status = {
installed: false,
- generated: false,
- refreshOutput: false,
- refreshKnownHosts: false
};
$scope.refreshStatus = (function () {
@@ -66,6 +46,8 @@ registerController('PMKIDAttack_Dependencies', ['$api', '$scope', '$rootScope',
if ($scope.processing) {
$scope.statusDependencies();
+ } else {
+ $rootScope.noDependencies = response.installed;
}
})
});
@@ -105,11 +87,23 @@ registerController('PMKIDAttack_Dependencies', ['$api', '$scope', '$rootScope',
});
});
+ $api.request({
+ module: "PMKIDAttack",
+ action: "getDependenciesStatus"
+ }, function (response) {
+ if (response.install === 'Install') {
+ $rootScope.noDependencies = true;
+ }
+ });
+
$scope.refreshStatus();
}]);
registerController('PMKIDAttack_ScanSettings', ['$api', '$scope', '$rootScope', '$interval', '$timeout', '$cookies', function ($api, $scope, $rootScope, $interval, $timeout, $cookies) {
$rootScope.pmkids = [];
+ $rootScope.accessPoints = [];
+ $rootScope.unassociatedClients = [];
+ $rootScope.outOfRangeClients = [];
$scope.scans = [];
$scope.selectedScan = "";
$scope.loadedScan = null;
@@ -503,45 +497,32 @@ registerController('PMKIDAttack_ScanResults', ['$api', '$scope', '$interval', '$
$scope.orderByName = 'ssid';
$rootScope.mac = '';
- $api.request({
- action: "getStatusAttack",
- module: "PMKIDAttack"
- }, function (response) {
- if (response.success) {
- $rootScope.captureRunning = true;
- if (!$rootScope.intervalCheckHash) {
- $rootScope.intervalCheckHash = $interval(function () {
- if ($rootScope.captureRunning) {
- $rootScope.catchPMKID();
- $rootScope.viewLog();
- }
- }, 3000);
- }
+ $scope.checkPMKID = (function() {
+ $rootScope.captureRunning = true;
+ if (!$rootScope.intervalCheckHash) {
+ $rootScope.intervalCheckHash = $interval(function () {
+ if ($rootScope.captureRunning) {
+ $scope.catchPMKID();
+ $rootScope.viewLog();
+ } else {
+ $rootScope.stopAttack();
+ }
+ }, 2000);
}
});
- $scope.startAttack = function (bssid) {
+ $scope.startAttack = (function (bssid) {
$rootScope.mac = bssid;
$api.request({
action: 'startAttack',
module: 'PMKIDAttack',
bssid: bssid
}, function (response) {
- $rootScope.captureRunning = true;
- if (!$rootScope.intervalCheckHash) {
- $rootScope.intervalCheckHash = $interval(function () {
- if ($rootScope.captureRunning) {
- $rootScope.catchPMKID();
- $rootScope.viewLog();
- } else {
- $rootScope.stopAttack();
- }
- }, 2000);
- }
+ $scope.checkPMKID();
});
- };
+ });
- $rootScope.catchPMKID = function () {
+ $scope.catchPMKID = (function () {
$api.request({
action: 'catchPMKID',
module: 'PMKIDAttack'
@@ -550,5 +531,15 @@ registerController('PMKIDAttack_ScanResults', ['$api', '$scope', '$interval', '$
$rootScope.captureRunning = false;
}
});
- }
-}]);
\ No newline at end of file
+ });
+
+ $api.request({
+ action: "getStatusAttack",
+ module: "PMKIDAttack"
+ }, function (response) {
+ if (response.success) {
+ $scope.checkPMKID();
+ }
+ });
+}]);
+
diff --git a/module.html b/module.html
index c50543d..0ae1f5e 100644
--- a/module.html
+++ b/module.html
@@ -1,244 +1,265 @@
-
-
- Internet connection required for this module to work!
-
-
-
-
-
-
Controls
-
-
-
-
- Dependencies |
-
-
- |
-
-
-
+
+
+
-
-
-
-
-
Captured WPA PMKID
-
-
-
-
-
-
- Name |
- View Log |
- Download |
- Delete |
-
-
-
-
- {{ pmkid.name }} |
-
-
- |
-
-
- |
-
-
- |
-
-
-
-
-
- No PMKID results.
-
-
+
+
+
+ Dependencies |
+
+
+ |
+
+
+
+
-
-
-
-
Scan Settings
-
-
-
-
-
-
-
-
-
-
{{ percent | roundCeil }}%
-
-
{{ error }}
-
-
-
-
-
+
+
-
-
-
-
-
- Scan Results
-
-
-
-
+
+
+
- SSID |
- MAC |
- Security |
- WPS |
- Channel |
- Signal |
- Last Seen |
- |
+ Name |
+ View Log |
+ Download |
+ Delete |
-
-
- Hidden
- {{ accessPoint.ssid }}
- |
+
+ {{ pmkid.name }} |
-
+
|
- {{ accessPoint.encryption }}
+
|
- {{ (accessPoint.wps == 1) ? "Yes" : "No" }} |
- {{ (accessPoint.channel == 0) ? "Wi-Fi Direct" : accessPoint.channel }} |
- {{ accessPoint.power }} |
- {{ accessPoint.lastSeen | timesincedate }} |
- |
-
- No scan results.
+
+ No PMKID results.
-
-
+
+
+
+
+
+
+
+
Scan Settings
+
+
+
+
+
+
+
+
+
+
{{ percent | roundCeil }}%
+
+
{{ error }}
+
+
+
+
+
+
+
+
+
+
+
+ Scan Results
+
+
+
+
+
+
+ SSID |
+ MAC |
+ Security |
+ WPS |
+ Channel |
+ Signal |
+ Last Seen |
+ |
+
+
+
+
+
+ Hidden
+ {{ accessPoint.ssid }}
+ |
+
+
+ |
+
+ {{ accessPoint.encryption }}
+ |
+ {{ (accessPoint.wps == 1) ? "Yes" : "No" }} |
+ {{ (accessPoint.channel == 0) ? "Wi-Fi Direct" : accessPoint.channel }} |
+ {{ accessPoint.power }} |
+ {{ accessPoint.lastSeen | timesincedate }} |
+
+ Attack
+
+ |
+
+
+
+
+
+ No scan results.
+
+
+
+
-
+
+
+
+
+
+ Log
+ {{clear}}
+
+
+
+
+
+
No log entries found yet.
+
{{pmkidlog}}
+
+
+
+
+
+
+
@@ -249,4 +270,4 @@
View Log
-
\ No newline at end of file
+
diff --git a/module.info b/module.info
index 7743ea2..20b1bbd 100644
--- a/module.info
+++ b/module.info
@@ -5,5 +5,5 @@
"tetra"
],
"title": "PMKIDAttack",
- "version": "1.0"
-}
\ No newline at end of file
+ "version": "1.1"
+}
diff --git a/scripts/dependencies.sh b/scripts/dependencies.sh
index f279e84..b586d0d 100644
--- a/scripts/dependencies.sh
+++ b/scripts/dependencies.sh
@@ -1,27 +1,79 @@
#!/bin/sh
-[[ -f /tmp/PMKIDAttack.progress ]] && {
- exit 0
-}
+export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/sd/lib:/sd/usr/lib
+export PATH=$PATH:/sd/usr/bin:/sd/usr/sbin
+
+TIMESTAMP=`date "+[%Y-%m-%d %H:%M:%S]"`
+LOGFILE="/var/log/pmkidattack.log"
+
+if [[ "$1" == "" ]]; then
+ echo "$TIMESTAMP Argument to script missing! Run with \"dependencies.sh [install|remove]\"" >> $LOGFILE
+ exit 1
+fi
+
+echo "$TIMESTAMP Starting dependencies script with argument:" $1 >> $LOGFILE
touch /tmp/PMKIDAttack.progress
if [[ "$1" = "install" ]]; then
- opkg update
- wget -qO- https://raw.githubusercontent.com/n3d-b0y/hcxtools-hcxdumptool-openwrt/master/INSTALL.sh | bash -s -- -v -v
- touch /etc/config/pmkidattack
- echo "config pmkidattack 'settings'" > /etc/config/pmkidattack
- echo "config pmkidattack 'module'" >> /etc/config/pmkidattack
- echo "config pmkidattack 'attack'" >> /etc/config/pmkidattack
+ echo "$TIMESTAMP Updating opkg" >> $LOGFILE
+
+ if [[ -e /sd ]]; then
+ echo "$TIMESTAMP Installing on sd" >> $LOGFILE
+
+ opkg --dest sd install /pineapple/modules/PMKIDAttack/scripts/ipk/hcxtools_5.1.3-1_ar71xx.ipk >> $LOGFILE
+
+ if [[ $? -ne 0 ]]; then
+ echo "$TIMESTAMP ERROR: opkg --dest sd install hcxtools_5.1.3-1_ar71xx.ipk failed" >> $LOGFILE
+ exit 1
+ fi
+
+ opkg --dest sd install /pineapple/modules/PMKIDAttack/scripts/ipk/hcxdumptool_5.1.3-1_ar71xx.ipk >> $LOGFILE
+
+ if [[ $? -ne 0 ]]; then
+ echo "$TIMESTAMP ERROR: opkg --dest sd install hcxdumptool_5.1.3-1_ar71xx.ipk failed" >> $LOGFILE
+ exit 1
+ fi
+ else
+ echo "$TIMESTAMP Installing on disk" >> $LOGFILE
+
+ opkg install /pineapple/modules/PMKIDAttack/scripts/ipk/hcxtools_5.1.3-1_ar71xx.ipk
+
+ if [[ $? -ne 0 ]]; then
+ echo "$TIMESTAMP ERROR: opkg install hcxtools_5.1.3-1_ar71xx.ipk failed" >> $LOGFILE
+ exit 1
+ fi
+
+ opkg install /pineapple/modules/PMKIDAttack/scripts/ipk/hcxdumptool_5.1.3-1_ar71xx.ipk
+
+ if [[ $? -ne 0 ]]; then
+ echo "$TIMESTAMP ERROR: opkg install hcxdumptool_5.1.3-1_ar71xx.ipk failed" >> $LOGFILE
+ exit 1
+ fi
+ fi
+
+ echo "$TIMESTAMP Installation complete!" >> $LOGFILE
+
+ touch /etc/config/pmkidattack
+
+ echo "config pmkidattack 'settings'" > /etc/config/pmkidattack
+ echo "config pmkidattack 'module'" >> /etc/config/pmkidattack
+ echo "config pmkidattack 'attack'" >> /etc/config/pmkidattack
+
+ uci set pmkidattack.module.installed=1
+ uci commit pmkidattack.module.installed
+fi
+
+if [[ "$1" = "remove" ]]; then
+ echo "$TIMESTAMP Removing PMKIDAttack module" >> $LOGFILE
- uci set pmkidattack.module.installed=1
- uci commit pmkidattack.module.installed
+ rm -rf /etc/config/PMKIDAttack
+
+ opkg remove hcxtools
+ opkg remove hcxdumptool
-elif [[ "$1" = "remove" ]]; then
- opkg remove hcxdumptool
- opkg remove hcxtools
- rm -rf /etc/config/pmkidattack
+ echo "$TIMESTAMP Removing complete!" >> $LOGFILE
fi
rm /tmp/PMKIDAttack.progress
diff --git a/scripts/ipk/hcxdumptool_5.1.3-1_ar71xx.ipk b/scripts/ipk/hcxdumptool_5.1.3-1_ar71xx.ipk
new file mode 100755
index 0000000..d1ce8b6
Binary files /dev/null and b/scripts/ipk/hcxdumptool_5.1.3-1_ar71xx.ipk differ
diff --git a/scripts/ipk/hcxtools_5.1.3-1_ar71xx.ipk b/scripts/ipk/hcxtools_5.1.3-1_ar71xx.ipk
new file mode 100755
index 0000000..43f3a6b
Binary files /dev/null and b/scripts/ipk/hcxtools_5.1.3-1_ar71xx.ipk differ