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 @@ -
- -
-
-
-
-

Controls

-
-
- - - - - -
Dependencies - -
-
+ +
+
+
+
+

Controls

-
-
-
-
-
-
-

Captured WPA PMKID

-
-
-
- - - - - - - - - - - - - - - - - -
NameView LogDownloadDelete
{{ pmkid.name }} - - - - - -
-
-
- No PMKID results. -
-
+
+ + + + + +
Dependencies + +
+
+
-
-
-
-

Scan Settings

-
-
-
-
-
-
- - - -
- -
-
-
-
- -

-
- - - - - - - -
-
-
-
-
-
{{ percent | roundCeil }}% -
-
{{ error }}
-
-
-
-
- +
+
+
+
+

Captured WPA PMKID

-
-
-
-
-
-
-

- Scan Results -

-
-
- +
+
+
- - - - - - - - + + + + - - + + - - - -
SSID MAC Security WPS Channel Signal Last Seen NameView LogDownloadDelete
- 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 }} + +
+
+
+ No scan results. +
+
+ +
- 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