Fixed how the Windows MeshAgent's are downloaded from the server.

Ylian Saint-Hilaire committed Oct 23, 2019 at 13:12 UTC cfc5cc501685b885d108e609d89cbdc17dfbcff9
4 files changed +33 -5
exeHandler.js
+4 -2
@@ -24,6 +24,7 @@ limitations under the License.
24
25 const exeJavaScriptGuid = 'B996015880544A19B7F7E9BE44914C18';
26 const exeMeshPolicyGuid = 'B996015880544A19B7F7E9BE44914C19';
27 +const exeNullPolicyGuid = 'B996015880544A19B7F7E9BE44914C20';
28
29
30 // Changes a Windows Executable to add JavaScript inside of it.
@@ -76,6 +77,7 @@ module.exports.streamExeWithJavaScript = function (options) {
77 // sourceFileName: 'pathToBinary',
78 // destinationStream: 'outputStream'
79 // msh: 'mshContent',
80 +// randomPolicy: true, // Set is the MSH contains random data
81 // peinfo {} // Optional, if PE header already parsed place it here.
82 // }
83 //
@@ -100,7 +102,7 @@ module.exports.streamExeWithMeshPolicy = function (options) {
102 var sz = Buffer.alloc(4);
103 sz.writeUInt32BE(this.options.msh.length, 0);
104 this.options.destinationStream.write(sz); // Length in small endian
103 - this.options.destinationStream.end(Buffer.from(exeMeshPolicyGuid, 'hex')); // Guid
105 + this.options.destinationStream.end(Buffer.from((this.options.randomPolicy === true) ? exeNullPolicyGuid : exeMeshPolicyGuid, 'hex')); // Guid
106 });
107 // Pipe the entire source binary without ending the stream.
108 options.destinationStream.sourceStream.pipe(options.destinationStream, { end: false });
@@ -140,7 +142,7 @@ module.exports.streamExeWithMeshPolicy = function (options) {
142 var sz = Buffer.alloc(4);
143 sz.writeUInt32BE(this.options.msh.length, 0);
144 this.options.destinationStream.write(sz); // MSH Length, small-endian
143 - this.options.destinationStream.end(Buffer.from(exeMeshPolicyGuid, 'hex')); // MSH GUID
145 + this.options.destinationStream.end(Buffer.from((this.options.randomPolicy === true) ? exeNullPolicyGuid : exeMeshPolicyGuid, 'hex')); // Guid
146 });
147 source3.pipe(this.options.destinationStream, { end: false });
148 this.options.sourceStream = source3;
meshcentral.js
+27 -1
@@ -1626,12 +1626,38 @@ function CreateMeshCentralServer(config, args) {
1626 obj.meshAgentBinaries[archid].path = agentpath;
1627 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;
1628 obj.meshAgentBinaries[archid].size = stats.size;
1629 - if (obj.args.agentsinram) { obj.meshAgentBinaries[archid].data = obj.fs.readFileSync(agentpath); }
1629 +
1630 // If this is a windows binary, pull binary information
1631 if (obj.meshAgentsArchitectureNumbers[archid].platform == 'win32') {
1632 try { obj.meshAgentBinaries[archid].pe = obj.exeHandler.parseWindowsExecutable(agentpath); } catch (e) { }
1633 }
1634
1635 + // If agents must be stored in RAM or if this is a Windows 32/64 agent, load the agent in RAM.
1636 + if ((obj.args.agentsinram) || (archid == 3) || (archid == 4)) {
1637 + if ((archid == 3) || (archid == 4)) {
1638 + // Load the agent with a random msh added to it.
1639 + var outStream = new require('stream').Duplex();
1640 + outStream.meshAgentBinary = obj.meshAgentBinaries[archid];
1641 + outStream.meshAgentBinary.randomMsh = Buffer.from(obj.crypto.randomBytes(64), 'binary').toString('base64');
1642 + outStream.bufferList = [];
1643 + outStream._write = function (chunk, encoding, callback) { this.bufferList.push(chunk); if (callback) callback(); }; // Append the chuck.
1644 + outStream._read = function (size) { }; // Do nothing, this is not going to be called.
1645 + outStream.on('finish', function () { this.meshAgentBinary.data = Buffer.concat(this.bufferList); this.meshAgentBinary.size = this.meshAgentBinary.data.length; delete this.bufferList; }) // Merge all chunks
1646 + obj.exeHandler.streamExeWithMeshPolicy(
1647 + {
1648 + platform: 'win32',
1649 + sourceFileName: agentpath,
1650 + destinationStream: outStream,
1651 + randomPolicy: true, // Indicates that the msh policy is random data.
1652 + msh: outStream.meshAgentBinary.randomMsh,
1653 + peinfo: obj.meshAgentBinaries[archid].pe
1654 + });
1655 + } else {
1656 + // Load the agent as-is
1657 + obj.meshAgentBinaries[archid].data = obj.fs.readFileSync(agentpath);
1658 + }
1659 + }
1660 +
1661 // Hash the binary
1662 var hashStream = obj.crypto.createHash('sha384');
1663 hashStream.archid = archid;
package.json
+1 -1
@@ -1,6 +1,6 @@
1 {
2 "name": "meshcentral",
3 - "version": "0.4.2-z",
3 + "version": "0.4.3-a",
4 "keywords": [
5 "Remote Management",
6 "Intel AMT",
webserver.js
+1 -1
@@ -2854,7 +2854,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2854 if (argentInfo == null) { res.sendStatus(404); return; }
2855 if ((req.query.meshid == null) || (argentInfo.platform != 'win32')) {
2856 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 + '"' });
2857 - res.sendFile(argentInfo.path);
2857 + if (argentInfo.data == null) { res.sendFile(argentInfo.path); } else { res.end(argentInfo.data); }
2858 } else {
2859 // We are going to embed the .msh file into the Windows executable (signed or not).
2860 // First, fetch the mesh object to build the .msh file