From 44994a5a9bc49726076b8ecbcc269d56d25325c1 Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Mon, 20 Jun 2022 12:03:23 -0700 Subject: [PATCH] Added experimental options to change the Windows agent resource executable information. --- authenticode.js | 5 +---- meshcentral.js | 31 ++++++++++++++++++++++++++++--- sample-config-advanced.json | 10 ++++++++++ 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/authenticode.js b/authenticode.js index daabd441..3ce33b5c 100644 --- a/authenticode.js +++ b/authenticode.js @@ -1639,7 +1639,6 @@ function createAuthenticodeHandler(path) { // Re-encode the executable signature block const p7signature = Buffer.from(forge.asn1.toDer(pkcs7der).data, 'binary'); - console.log('r3'); // Write the file with the signature block writeExecutableEx(output, p7signature, written, func); @@ -1830,16 +1829,14 @@ function start() { if (err == null) { console.log("Done."); } else { console.log(err); } if (exe != null) { exe.close(); } }); - return; } else { console.log("Changing resources and signing to " + args.out); exe.writeExecutable(args, cert, function (err) { // Signing with resources decoded and re-encoded. if (err == null) { console.log("Done."); } else { console.log(err); } if (exe != null) { exe.close(); } }); - return; } - console.log("Done."); + return; } if (command == 'unsign') { // Unsign an executable if (typeof args.exe != 'string') { console.log("Missing --exe [filename]"); return; } diff --git a/meshcentral.js b/meshcentral.js index cd3364f2..d717609a 100644 --- a/meshcentral.js +++ b/meshcentral.js @@ -2886,6 +2886,21 @@ function CreateMeshCentralServer(config, args) { if (args.agenttimestampserver === false) { timeStampUrl = null; } else if (typeof args.agenttimestampserver == 'string') { timeStampUrl = args.agenttimestampserver; } + // Setup agent signing arguments + const signingArguments = { desc: signDesc, url: signUrl, time: timeStampUrl }; + + // See if we have any resources we need to change in the agent + var resChanges = false; + if ((domain.agentfileinfo != null) && (typeof domain.agentfileinfo == 'object')) { + if (typeof domain.agentfileinfo.filedescription == 'string') { signingArguments.FileDescription = domain.agentfileinfo.filedescription; resChanges = true; } + if (typeof domain.agentfileinfo.fileversion == 'string') { signingArguments.FileVersion = domain.agentfileinfo.fileversion; resChanges = true; } + if (typeof domain.agentfileinfo.internalname == 'string') { signingArguments.InternalName = domain.agentfileinfo.internalname; resChanges = true; } + if (typeof domain.agentfileinfo.legalcopyright == 'string') { signingArguments.LegalCopyright = domain.agentfileinfo.legalcopyright; resChanges = true; } + if (typeof domain.agentfileinfo.originalfilename == 'string') { signingArguments.OriginalFilename = domain.agentfileinfo.originalfilename; resChanges = true; } + if (typeof domain.agentfileinfo.productname == 'string') { signingArguments.ProductName = domain.agentfileinfo.productname; resChanges = true; } + if (typeof domain.agentfileinfo.productversion == 'string') { signingArguments.ProductVersion = domain.agentfileinfo.productversion; resChanges = true; } + } + // Setup the pending operations counter var pendingOperations = 1; @@ -2905,7 +2920,7 @@ function CreateMeshCentralServer(config, args) { } // Open the original agent with authenticode - var signeedagentpath = obj.path.join(serverSignedAgentsPath, obj.meshAgentsArchitectureNumbers[archid].localname); + const signeedagentpath = obj.path.join(serverSignedAgentsPath, obj.meshAgentsArchitectureNumbers[archid].localname); const originalAgent = require('./authenticode.js').createAuthenticodeHandler(agentpath); if (originalAgent != null) { // Check if the agent is already signed correctly @@ -2937,8 +2952,18 @@ function CreateMeshCentralServer(config, args) { xagentSignedFunc.objx = objx; xagentSignedFunc.archid = archid; xagentSignedFunc.signeedagentpath = signeedagentpath; - obj.debug('main', "Code signing agent with arguments: " + JSON.stringify({ out: signeedagentpath, desc: signDesc, url: signUrl, time: timeStampUrl })); - originalAgent.sign(agentSignCertInfo, { out: signeedagentpath, desc: signDesc, url: signUrl, time: timeStampUrl }, xagentSignedFunc); + const xsigningArguments = Object.assign({}, signingArguments); // Shallow clone + xsigningArguments.out = signeedagentpath; + + obj.debug('main', "Code signing agent with arguments: " + JSON.stringify(signingArguments)); + if (resChanges == false) { + // Sign the agent the simple way, without changing any resources. + originalAgent.sign(agentSignCertInfo, xsigningArguments, xagentSignedFunc); + } else { + // Change the agent resources and sign the agent, this is a much more involved process. + // NOTE: This is experimental and could corupt the agent. + originalAgent.writeExecutable(xsigningArguments, agentSignCertInfo, xagentSignedFunc); + } } else { // Signed agent is already ok, use it. originalAgent.close(); diff --git a/sample-config-advanced.json b/sample-config-advanced.json index 69218339..e316f4b5 100644 --- a/sample-config-advanced.json +++ b/sample-config-advanced.json @@ -286,6 +286,16 @@ "image": "agent-logo.png", "fileName": "compagnyagent" }, + "_agentFileInfo": { + "__COMMENT__": "This section is experimental", + "_filedescription": "sample_filedescription", + "_fileversion": "0.1.2.3", + "_internalname": "sample_internalname", + "_legalcopyright": "sample_legalcopyright", + "_originalfilename": "sample_originalfilename", + "_productname": "sample_productname", + "_productversion": "0.1.2.3" + }, "_assistantCustomization": { "title": "Company® Product™", "image": "assistant-logo.png",