diff --git a/exeHandler.js b/exeHandler.js index 478c7434..5721f210 100644 --- a/exeHandler.js +++ b/exeHandler.js @@ -24,6 +24,7 @@ limitations under the License. const exeJavaScriptGuid = 'B996015880544A19B7F7E9BE44914C18'; const exeMeshPolicyGuid = 'B996015880544A19B7F7E9BE44914C19'; +const exeNullPolicyGuid = 'B996015880544A19B7F7E9BE44914C20'; // Changes a Windows Executable to add JavaScript inside of it. @@ -76,6 +77,7 @@ module.exports.streamExeWithJavaScript = function (options) { // sourceFileName: 'pathToBinary', // destinationStream: 'outputStream' // msh: 'mshContent', +// randomPolicy: true, // Set is the MSH contains random data // peinfo {} // Optional, if PE header already parsed place it here. // } // @@ -100,7 +102,7 @@ module.exports.streamExeWithMeshPolicy = function (options) { var sz = Buffer.alloc(4); sz.writeUInt32BE(this.options.msh.length, 0); this.options.destinationStream.write(sz); // Length in small endian - this.options.destinationStream.end(Buffer.from(exeMeshPolicyGuid, 'hex')); // Guid + this.options.destinationStream.end(Buffer.from((this.options.randomPolicy === true) ? exeNullPolicyGuid : exeMeshPolicyGuid, 'hex')); // Guid }); // Pipe the entire source binary without ending the stream. options.destinationStream.sourceStream.pipe(options.destinationStream, { end: false }); @@ -140,7 +142,7 @@ module.exports.streamExeWithMeshPolicy = function (options) { var sz = Buffer.alloc(4); sz.writeUInt32BE(this.options.msh.length, 0); this.options.destinationStream.write(sz); // MSH Length, small-endian - this.options.destinationStream.end(Buffer.from(exeMeshPolicyGuid, 'hex')); // MSH GUID + this.options.destinationStream.end(Buffer.from((this.options.randomPolicy === true) ? exeNullPolicyGuid : exeMeshPolicyGuid, 'hex')); // Guid }); source3.pipe(this.options.destinationStream, { end: false }); this.options.sourceStream = source3; diff --git a/meshcentral.js b/meshcentral.js index c961da22..8aa67245 100644 --- a/meshcentral.js +++ b/meshcentral.js @@ -1626,12 +1626,38 @@ function CreateMeshCentralServer(config, args) { obj.meshAgentBinaries[archid].path = agentpath; obj.meshAgentBinaries[archid].url = ((obj.args.notls == true) ? 'http://' : 'https://') + obj.certificates.CommonName + ':' + ((typeof obj.args.aliasport == 'number') ? obj.args.aliasport : obj.args.port) + '/meshagents?id=' + archid; obj.meshAgentBinaries[archid].size = stats.size; - if (obj.args.agentsinram) { obj.meshAgentBinaries[archid].data = obj.fs.readFileSync(agentpath); } + // If this is a windows binary, pull binary information if (obj.meshAgentsArchitectureNumbers[archid].platform == 'win32') { try { obj.meshAgentBinaries[archid].pe = obj.exeHandler.parseWindowsExecutable(agentpath); } catch (e) { } } + // If agents must be stored in RAM or if this is a Windows 32/64 agent, load the agent in RAM. + if ((obj.args.agentsinram) || (archid == 3) || (archid == 4)) { + if ((archid == 3) || (archid == 4)) { + // Load the agent with a random msh added to it. + var outStream = new require('stream').Duplex(); + outStream.meshAgentBinary = obj.meshAgentBinaries[archid]; + outStream.meshAgentBinary.randomMsh = Buffer.from(obj.crypto.randomBytes(64), 'binary').toString('base64'); + outStream.bufferList = []; + outStream._write = function (chunk, encoding, callback) { this.bufferList.push(chunk); if (callback) callback(); }; // Append the chuck. + outStream._read = function (size) { }; // Do nothing, this is not going to be called. + outStream.on('finish', function () { this.meshAgentBinary.data = Buffer.concat(this.bufferList); this.meshAgentBinary.size = this.meshAgentBinary.data.length; delete this.bufferList; }) // Merge all chunks + obj.exeHandler.streamExeWithMeshPolicy( + { + platform: 'win32', + sourceFileName: agentpath, + destinationStream: outStream, + randomPolicy: true, // Indicates that the msh policy is random data. + msh: outStream.meshAgentBinary.randomMsh, + peinfo: obj.meshAgentBinaries[archid].pe + }); + } else { + // Load the agent as-is + obj.meshAgentBinaries[archid].data = obj.fs.readFileSync(agentpath); + } + } + // Hash the binary var hashStream = obj.crypto.createHash('sha384'); hashStream.archid = archid; diff --git a/package.json b/package.json index 61210f73..7e32f108 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "meshcentral", - "version": "0.4.2-z", + "version": "0.4.3-a", "keywords": [ "Remote Management", "Intel AMT", diff --git a/webserver.js b/webserver.js index 129f25ce..d76bb172 100644 --- a/webserver.js +++ b/webserver.js @@ -2854,7 +2854,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { if (argentInfo == null) { res.sendStatus(404); return; } if ((req.query.meshid == null) || (argentInfo.platform != 'win32')) { res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="' + argentInfo.rname + '"' }); - res.sendFile(argentInfo.path); + if (argentInfo.data == null) { res.sendFile(argentInfo.path); } else { res.end(argentInfo.data); } } else { // We are going to embed the .msh file into the Windows executable (signed or not). // First, fetch the mesh object to build the .msh file