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