From fc2d7c2c8f57f28e2c1095d18b0ad9f1a097de6a Mon Sep 17 00:00:00 2001 From: 0cmenog Date: Mon, 15 May 2023 09:58:40 +0200 Subject: [PATCH 1/4] add GPOChanges from Domain ou OU to Computer and manage enforced and blockInheritance precedences --- src/components/Menu/MenuContainer.jsx | 33 +++-- src/js/ingestion_types.js | 11 ++ src/js/newingestion.js | 188 +++++++++++++++++++++++++- 3 files changed, 217 insertions(+), 15 deletions(-) diff --git a/src/components/Menu/MenuContainer.jsx b/src/components/Menu/MenuContainer.jsx index cb187209e..50eb3dfe0 100644 --- a/src/components/Menu/MenuContainer.jsx +++ b/src/components/Menu/MenuContainer.jsx @@ -308,14 +308,31 @@ const MenuContainer = () => { } } } else { - for (let key in processedData) { - let props = processedData[key].props; - if (props.length === 0) continue; - let chunked = props.chunk(); - let statement = processedData[key].statement; - - for (let chunk of chunked) { - await uploadData(statement, chunk); + if (Array.isArray(processedData)) { + for (let data in processedData) { + data = processedData[data]; + for (let key in data) { + let props = data[key].props; + if (props.length === 0) continue; + let chunked = props.chunk(); + let statement = data[key].statement; + + for (let chunk of chunked) { + await uploadData(statement, chunk); + } + } + } + } + else { + for (let key in processedData) { + let props = processedData[key].props; + if (props.length === 0) continue; + let chunked = props.chunk(); + let statement = processedData[key].statement; + + for (let chunk of chunked) { + await uploadData(statement, chunk); + } } } } diff --git a/src/js/ingestion_types.js b/src/js/ingestion_types.js index c8984cbc8..3c1bdd248 100644 --- a/src/js/ingestion_types.js +++ b/src/js/ingestion_types.js @@ -115,6 +115,17 @@ * @property {Array.} DcomUsers * @property {Array.} PSRemoteUsers * @property {Array.} AffectedComputers + * @property {boolean} BlockInheritance + * @property {LinkType} Unenforced + * @property {LinkType} Enforced + */ + +/** + * @typedef {Object} LinkType + * @property {Dictionary.} PasswordPolicies + * @property {Dictionary.} SMBSigning + * @property {Dictionary.} LDAPSigning + * @property {Dictionary.} LMAuthenticationLevel */ /** diff --git a/src/js/newingestion.js b/src/js/newingestion.js index 3cc024c8e..7f9dd8629 100644 --- a/src/js/newingestion.js +++ b/src/js/newingestion.js @@ -1,5 +1,6 @@ import { groupBy } from 'lodash/collection'; +var blockInheritanceComputers = []; const TRUST_DIRECTION_INBOUND = 'Inbound'; const TRUST_DIRECTION_OUTBOUND = 'Outbound'; const TRUST_DIRECTION_BIDIRECTIONAL = 'Bidirectional'; @@ -34,6 +35,11 @@ export const ADLabels = { Contains: 'Contains', GPLink: 'GPLink', TrustedBy: 'TrustedBy', + PasswordPolicies: 'PasswordPolicies', + SMBSigning: 'SMBSigning', + LDAPSigning: 'LDAPSigning', + LMAuthenticationLevel: 'LMAuthenticationLevel', + GPOChanges: 'GPOChanges', }; const AzureApplicationAdministratorRoleId = @@ -527,7 +533,7 @@ export function buildContainerJsonNew(chunk) { /** * @param {Array.} chunk * @return {{}} - */ +*/ export function buildOuJsonNew(chunk) { let queries = {}; queries.properties = { @@ -535,6 +541,10 @@ export function buildOuJsonNew(chunk) { props: [], }; + let computerStatement = PROP_QUERY.format(ADLabels.Computer); + let queriesComputers = {}; + var linkTypeProperties = []; + for (let ou of chunk) { let properties = ou.Properties; let links = ou.Links; @@ -543,6 +553,7 @@ export function buildOuJsonNew(chunk) { let identifier = ou.ObjectIdentifier.toUpperCase(); properties.objectid = identifier; let aces = ou.Aces; + let blockInheritance = ou.GPOChanges.BlockInheritance; processAceArrayNew(aces, identifier, 'OU', queries); @@ -550,6 +561,100 @@ export function buildOuJsonNew(chunk) { objectid: identifier, map: properties, }); + // add GPOChanges properties to the affected computers + let computers = ou.GPOChanges.AffectedComputers; + let computerProperties = {"unenforced": {}, "enforced": {}}; + let linkType = [ou.GPOChanges.Unenforced, ou.GPOChanges.Enforced]; + // add enforced and unenforced properties separatly + for (let index=0;index Date: Tue, 16 May 2023 16:19:05 +0200 Subject: [PATCH 2/4] correct GPOChanges priorities --- src/js/newingestion.js | 126 +++++++++++++++++++++++++++-------------- 1 file changed, 84 insertions(+), 42 deletions(-) diff --git a/src/js/newingestion.js b/src/js/newingestion.js index 7f9dd8629..6d275aaf1 100644 --- a/src/js/newingestion.js +++ b/src/js/newingestion.js @@ -1,6 +1,8 @@ import { groupBy } from 'lodash/collection'; var blockInheritanceComputers = []; +var linkTypeProperties = []; +var enforcedProperties = {}; const TRUST_DIRECTION_INBOUND = 'Inbound'; const TRUST_DIRECTION_OUTBOUND = 'Outbound'; const TRUST_DIRECTION_BIDIRECTIONAL = 'Bidirectional'; @@ -543,7 +545,11 @@ export function buildOuJsonNew(chunk) { let computerStatement = PROP_QUERY.format(ADLabels.Computer); let queriesComputers = {}; - var linkTypeProperties = []; + + // sort OU from the children to the parent using the length of the distinguished name + chunk.sort((a,b) => { + return b.Properties.distinguishedname.length - a.Properties.distinguishedname.length; + }); for (let ou of chunk) { let properties = ou.Properties; @@ -594,7 +600,7 @@ export function buildOuJsonNew(chunk) { var computerIdentifier = ""; var found; - // add properties for each affected computer + // build a vector of properties for each affected computer, taking into account the blocInheritance and the enforced precedences for (let index=0;index Date: Thu, 25 May 2023 11:35:40 +0200 Subject: [PATCH 3/4] fix OU/Domain GPO precedences and code cleaning --- src/js/ingestion_types.js | 1 + src/js/newingestion.js | 187 ++++++++++++++++++-------------------- 2 files changed, 87 insertions(+), 101 deletions(-) diff --git a/src/js/ingestion_types.js b/src/js/ingestion_types.js index 3c1bdd248..422c73056 100644 --- a/src/js/ingestion_types.js +++ b/src/js/ingestion_types.js @@ -123,6 +123,7 @@ /** * @typedef {Object} LinkType * @property {Dictionary.} PasswordPolicies + * @property {Dictionary.} LockoutPolicies * @property {Dictionary.} SMBSigning * @property {Dictionary.} LDAPSigning * @property {Dictionary.} LMAuthenticationLevel diff --git a/src/js/newingestion.js b/src/js/newingestion.js index 6d275aaf1..8eed2284c 100644 --- a/src/js/newingestion.js +++ b/src/js/newingestion.js @@ -1,8 +1,7 @@ import { groupBy } from 'lodash/collection'; -var blockInheritanceComputers = []; -var linkTypeProperties = []; -var enforcedProperties = {}; +let unenforcedDomainProperties = {}; +let enforcedDomainPropertyKeys = {}; const TRUST_DIRECTION_INBOUND = 'Inbound'; const TRUST_DIRECTION_OUTBOUND = 'Outbound'; const TRUST_DIRECTION_BIDIRECTIONAL = 'Bidirectional'; @@ -38,6 +37,7 @@ export const ADLabels = { GPLink: 'GPLink', TrustedBy: 'TrustedBy', PasswordPolicies: 'PasswordPolicies', + LockoutPolicies: 'LockoutPolicies', SMBSigning: 'SMBSigning', LDAPSigning: 'LDAPSigning', LMAuthenticationLevel: 'LMAuthenticationLevel', @@ -544,13 +544,17 @@ export function buildOuJsonNew(chunk) { }; let computerStatement = PROP_QUERY.format(ADLabels.Computer); - let queriesComputers = {}; + let computerQuery = {}; + let computerProperties = []; + let blockInheritanceComputers = []; + let enforcedOuProperties = {}; // sort OU from the children to the parent using the length of the distinguished name chunk.sort((a,b) => { return b.Properties.distinguishedname.length - a.Properties.distinguishedname.length; }); + // OU are processed from the bottom up, so the default behavior is to not override already set properties for (let ou of chunk) { let properties = ou.Properties; let links = ou.Links; @@ -567,13 +571,15 @@ export function buildOuJsonNew(chunk) { objectid: identifier, map: properties, }); + // add GPOChanges properties to the affected computers let computers = ou.GPOChanges.AffectedComputers; - let computerProperties = {"unenforced": {}, "enforced": {}}; + let ouProperties = {"unenforced": {}, "enforced": {}}; let linkType = [ou.GPOChanges.Unenforced, ou.GPOChanges.Enforced]; + // add enforced and unenforced properties separatly for (let index=0;index domainProperties["enforced"][key] !== undefined); } processAceArrayNew(aces, identifier, 'Domain', queries); @@ -1070,14 +1055,14 @@ export function buildDomainJsonNew(chunk) { } } - queriesComputers = { + computerQuery = { properties: { statement: computerStatement, - props: linkTypeProperties, + props: computerProperties, } }; - return [queries, queriesComputers]; + return [queries, computerQuery]; } const baseInsertStatement = From c8638e9b135667827200a515314f7c9739bc008d Mon Sep 17 00:00:00 2001 From: 0cmenog Date: Mon, 24 Jul 2023 12:15:10 +0200 Subject: [PATCH 4/4] fix a precedence rule (multiple enforced properties) --- src/js/newingestion.js | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/js/newingestion.js b/src/js/newingestion.js index 8eed2284c..dc0b7103e 100644 --- a/src/js/newingestion.js +++ b/src/js/newingestion.js @@ -547,7 +547,6 @@ export function buildOuJsonNew(chunk) { let computerQuery = {}; let computerProperties = []; let blockInheritanceComputers = []; - let enforcedOuProperties = {}; // sort OU from the children to the parent using the length of the distinguished name chunk.sort((a,b) => { @@ -652,15 +651,9 @@ export function buildOuJsonNew(chunk) { for (let prop of computerProperties){ if(computerIdentifier === prop.objectid){ for(let [key, value] of Object.entries(ouProperties["enforced"])){ - // override the property if it is empty or an not enforced at a lower OU level - if(value !== undefined && (!Object.keys(enforcedOuProperties).includes(computerIdentifier) || !(enforcedOuProperties[computerIdentifier].includes(key)))){ + // override the property if it is empty or an not enforced at domain level + if(value !== undefined && (!Object.keys(enforcedDomainPropertyKeys).includes(computerIdentifier) || !(enforcedDomainPropertyKeys[computerIdentifier].includes(key)))){ prop.map[key] = value; - // store the property keys as enforced - try{ - enforcedOuProperties[computerIdentifier].push(key); - } catch (ReferenceRerror){ - enforcedOuProperties[computerIdentifier] = [key]; - } } } found = true; @@ -673,8 +666,6 @@ export function buildOuJsonNew(chunk) { objectid: computerIdentifier, map: Object.assign({}, ouProperties["enforced"]), }); - // store the property keys as enforced - enforcedOuProperties[computerIdentifier] = Object.keys(ouProperties["enforced"]); } }