Skip to content

Commit

Permalink
v0.1.6
Browse files Browse the repository at this point in the history
  • Loading branch information
Kiersten Gross committed Aug 7, 2024
0 parents commit d2d7ec9
Show file tree
Hide file tree
Showing 26 changed files with 2,788 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/target
/gpo-insight
Cargo.lock
14 changes: 14 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "gpo-insight"
version = "0.1.6"
edition = "2021"

[dependencies]
anyhow = "1.0.86"
clap = {version = "4.5.4", features = ["derive"]}
console = "0.15.8"
dirs = "5.0.1"
encoding_rs = "0.8.34"
encoding_rs_io = "0.1.7"
html2text = "0.12.5"
lazy_static = "1.4.0"
674 changes: 674 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

241 changes: 241 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
# GPO Insight

GPO Insight accepts GPO Exports created using the Get-GPOReport CMDLET in Active Directory.
The following is an example of the command used to create the GPO Export.

```powershell
Get-GPOReport -All -Domain "domain.com" -Server "ACME-DC1" -ReportType HTML -Path "C:\GPOReport.html"
```

Specify GPO Exports using the `-i` (input) flag. No default value exists for this flag.
Once the GPO Export is imported to GPO-Insight, the GPOs will be broken down into individual files that reflect each individual GPO.
Outputs from GPO-Insight will be generated in the directory specified by the `-o` (output) flag, or will default to the Present Working Directory.
GPOs are broken down into both `HTML` and `TXT` files.
The `TXT` outputs are cleaned up `HTML2TXT` outputs of the `HTML` files.

Only the `TXT` outputs are used to analyze GPOs.
GPO Insight uses it's own "GPO Query Syntax" to specify desirable, undesirable, and warning search criteria.
A directory named `queries` in the same directory as the GPO Insight EXE or the current working directory needs to exist to perform analysis. All of the individual files in the `queries` directory needs to follow GPO Query Syntax.
Completed analysis can be found in the output `analysis.txt` created in the directory specified by the `-o` flag.

## GPO Query Syntax
GPO Insight uses "GPO Query Syntax" to search GPOs to find GPOs that match the given criteria.
To create a gpo query, the following syntax elements may be used.
Be sure to follow the syntax closely, as anything that does not follow the syntax will be assumed by GPO-Insight to be a comment.

`Name::Value` where `Value` is the name of the GPO.

`Details::Owner` where `Owner` is the value of the GPO's owner.

`Links::Location` where `Location` is the Organizational Unit of the link.

`Filtering::Value` where `Value` is the Security Filtering member.

`Delegation::Name::Permissions::Inherited` where:
- `Name` is the user or group associated with the delegation.
- `Permissions` is the permission of the associated user or group (i.e. Read, Edit, Delete, Modify).
- `Inherited` is if the Delegation's permission is inherited.

`Policy::Value::Setting` where:
- `Value` is the policy being set.
- `Setting` is the configured setting for the policy.

## Syntax Modifiers, Specifics, & Examples

Syntax modifiers give the base GPO Query Syntax more flexibility in searching GPOs.
Syntax modifiers should always be applied to the beginning of the option.

### Name
#### Modifiers

No modifiers can be applied.

#### Examples
Match Example
```
Name::Test GPO
```

### Details
#### Modifiers

The **Owner** value for the Details query syntax can apply the following modifiers.

| Modifier | Description |
| --- | --- |
| `>` | "Ends With" |
| `<` | "Starts With" |
| `!` | "Is Not" |

#### Examples
Match Example
```
Details::LABS\\Domain Admins
```
Ends With Example
```
Details::>Domain Admins
```
Starts With Example
```
Details::<LABS
```
Is Not Example
```
Details::!>Domain Admins
```

### Links
#### Modifiers

The **Location** value for the Links query syntax can apply the following modifiers.

| Modifier | Description |
| --- | --- |
| `>` | "Ends With" |
| `<` | "Starts With" |

#### Examples
Match Example
```
Links::Domain Controllers
```
Ends With Example
```
Links::>Users
```
Starts With Example
```
Links::<Domain
```

### Filtering
#### Modifiers

No modifiers can be applied.

#### Examples
Match Example
```
Filtering::NT AUTHORITY\\Authenticated Users
```

### Delegation
#### Modifiers

The **Name** and **Permissions** values for the Delegation query syntax can apply the following modifiers.

| Modifier | Description |
| --- | --- |
| `>` | "Ends With" |
| `<` | "Starts With" |

#### Notes

Additionally, the **Inherited** value can be left blank if it is unimportant to the condition.
However, if the **Inherited** value is left blank, you cannot ommit the trailing `::` idenfitiers.

#### Examples
Match Example
```
Delegation::NT AUTHORITY\\Authenticated Users::Read (from Security Filtering)::
```
Ends With Example(s)
```
Delegation::>Authenticated Users::>(from Security Filtering)::
```
Starts With Example(s)
```
Delegation::<NT AUTHORITY::<Read::
```

### Policy
#### Modifiers

The **Value** and **Setting** values for the Policy query syntax can apply the following modifiers.

| Modifier | Description |
| --- | --- |
| `>` | "Ends With" |
| `<` | "Starts With" |

The **Setting** values for the Policy query syntax can apply the following additional modifiers.

| Modifier | Description |
| --- | --- |
| `#>=` | "Numerical Greater-Than-or-Equal-To" |
| `#>` | "Numerical Greater-Than" |
| `#<=` | "Numerical Less-Than-or-Equal-To" |
| `#<` | "Numerical Less-Than" |
| `!` | "Is Not" |

Numerical modifiers should only contain numbers and no spaces, or the modifer will break the condition.

The "Is Not" modifier for policy settings should only be used for registry values that can be a single value -- **Lists will result in unintended behaviors.** For example, if the intention of a query is to ensure that ONLY the Domain Admins group could debug a program, the following query would fail the purpose: `Policy::Debug program::!>Domain Admins`. This is because if anyone is added to the permission that is not Domain Admin, but the Domain Admins remains in the permission, the query will fail to trigger because Domain Admins IS in the setting's list. Future versions will aim to improve and add additional "is not" functionality.

#### Notes

Additionally, the **Setting** value can be left blank if it is unimportant to the condition.
However, if the **Setting** value is left blank, you cannot ommit the trailing `::` idenfitiers.

#### Examples
Match Example
```
Policy::Debug programs::NT AUTHORITY\\Authenticated Users
```
Ends With Example
```
Policy::Debug programs::>Authenticated Users
```
Starts With Example
```
Policy::<Debug::<NT AUTHORITY
```
Numerical Greater-Than-Or-Equal-To Example
```
Policy::Minimum password length::#>=14
```
Numerical Less-Than Example
```
Policy::Minimum password length::#<14
```
Is Not Example
```
Policy::Debug Programs::!>Domain Admins
```

## Using GPO Query Syntax in queries files
`Queries` files should prepend their GPO Query Syntax with one of the following:
| Flag | Description |
| `D -- ` | The Query identifies a desirable GPO value. |
| `U -- ` | The Query identifies an undesirable GPO value. |
| `W -- ` | The Query identifies a GPO value that may or may not be undesirable. |
| `M -- ` | The Query identifies a missing GPO value that should exist. |

## Combining Queries
Queries using the GPO Query Syntax can be combined into compound conditions using the "|" (pipe) symbol.

#### Examples
Compound query using a Link condition and a Policy condition
```
Links::Domain Controllers | Policy::Domain controller: LDAP server signing requirements::None
```

## Comments
Any line in the configuration files that does not match the GPO Query Syntax will be considered a comment.
Additionally, all valid lines of GPO Query Syntax can use "//" to end the line with a comment.
#### Examples
```
// This is a comment
This is a comment, as well.
Links::Domain Controllers | Policy::Domain controller: LDAP server signing requirements::None // This is a comment after a valid query
```

## Acknowledgements
Thanks to the team at Black Hills Information Security (BHIS) that have contributed to this tool by sharing their knowledge and insights of Active Directory.

## Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

## License
[GPLv3](https://www.gnu.org/licenses/)
3 changes: 3 additions & 0 deletions queries/add_workstations.queries
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Within most environments, authenticated users shouldn't be able to add machines to the domain.
W -- Policy::Add workstations to domain::>Users
W -- Policy::Add workstations to domain::Everybody
13 changes: 13 additions & 0 deletions queries/anonymous_enumeration_of_SAM.queries
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// By default this value is set as disabled on servers.
// https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/security-policy-settings/network-access-do-not-allow-anonymous-enumeration-of-sam-accounts
W -- Policy::Network access: Do not allow anonymous enumeration of SAM accounts::Disabled
// This GPO value would be to enforce these settings and prevent modification.
D -- Policy::Network access: Do not allow anonymous enumeration of SAM accounts::Enabled
// Don't warn on missing values. This is a hardening GPO and might not be suitable for everyone.

// By default this value is set as disabled on servers.
// https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/security-policy-settings/network-access-do-not-allow-anonymous-enumeration-of-sam-accounts-and-shares
W -- Policy::Network access: Do not allow anonymous enumeration of SAM accounts and shares::Disabled
// This GPO value would be to enforce these settings and prevent modification.
D -- Policy::Network access: Do not allow anonymous enumeration of SAM accounts and shares::Enabled
// Don't warn on missing values. This is a hardening GPO and might not be suitable for everyone.
7 changes: 7 additions & 0 deletions queries/delegation_standard_users.queries
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// If Standard Users have permissions to modify GPOs
U -- Delegation::>Users::<Edit::
U -- Delegation::>Users::<Delete::
U -- Delegation::>Users::<Modify::
U -- Delegation::Everybody::<Edit::
U -- Delegation::Everybody::<Delete::
U -- Delegation::Everybody::<Modify::
7 changes: 7 additions & 0 deletions queries/delegation_system_user.queries
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Local Computer accounts should not have have permissions to modify GPOs
U -- Delegation::>$::<Edit::
U -- Delegation::>$::<Delete::
U -- Delegation::>$::<Modify::
U -- Delegation::>Computers::<Edit::
U -- Delegation::>Computers::<Delete::
U -- Delegation::>Computers::<Modify::
5 changes: 5 additions & 0 deletions queries/disable_llmnr.queries
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// LLMNR should always be disabled to prevent LLMNR Responder-like attacks
// https://github.com/lgandx/Responder
U -- Policy::Turn off multicast name resolution::!Enabled
D -- Policy::Turn off multicast name resolution::Enabled
M -- Policy::Turn off multicast name resolution::
15 changes: 15 additions & 0 deletions queries/domain_controller_debug_programs.queries
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Only Domain Admins or Enterprise Admins should be able to Debug on a Domain Controller
// The following query won't work in this version of gpo-insight. Slated for future release.
// U -- Links::Domain Controllers | Policy::Debug programs::>!Administrators | Policy::Debug programs::>!Admins | Policy::Debug programs::>!Service | Policy::Debug programs::>!System

// Caution should be exercised when giving debug permissions
// The following query won't work in this version of gpo-insight. Slated for future release.
// W -- !Link::Domain Controllers | Policy::Debug programs::>!Administrators | Policy::Debug programs::>!Admins | Policy::Debug programs::>!Service | Policy::Debug programs::>!System

// Queries for now until future features.
U -- Policy::Debug programs::>Users
U -- Policy::Debug programs::>Everybody
U -- Policy::Debug programs::>Users
U -- Policy::Debug programs::>Everybody
U -- Policy::Debug programs::>Users
U -- Policy::Debug programs::>Everybody
13 changes: 13 additions & 0 deletions queries/domain_controller_logon.queries
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Only Domain Admins or Enterprise Admins should be able to log onto the domain controller
// The following queries won't work in the current version of gpo-insight.
// U -- Links::Domain Controllers | Policy::Allow log on locally::!>Administrators | Policy::Allow log on locally::!>Admins | Policy::Allow log on locally::!>Print Operators | Policy::Allow log on locally::!>Server Operators | Policy::Allow log on locally::!>Backup Operators | Policy::Allow log on locally::!>Account Operators
// U -- Links::Domain Controllers | Policy::Allow log on through Terminal Services::!>Administrators | Policy::Allow log on through Terminal Services::!>Admins | Policy::Allow log on through Terminal Services::!>Print Operators | Policy::Allow log on through Terminal Services::!>Server Operators | Policy::Allow log on through Terminal Services::!>Backup Operators | Policy::Allow log on through Terminal Services::!>Account Operators
// U -- Links::Domain Controllers | Policy::Allow log on through Remote Desktop Services::!>Administrators | Policy::Allow log on through Remote Desktop Services::!>Admins | Policy::Allow log on through Remote Desktop Services::!>Print Operators | Policy::Allow log on through Remote Desktop Services::!>Server Operators | Policy::Allow log on through Remote Desktop Services::!>Backup Operators | Policy::Allow log on through Remote Desktop Services::!>Account Operators

// Temporary queries until future features.
U -- Links::Domain Controllers | Policy::Allow log on locally::>Users
U -- Links::Domain Controllers | Policy::Allow log on locally::>Everybody
U -- Links::Domain Controllers | Policy::Allow log on through Terminal Services::>Users
U -- Links::Domain Controllers | Policy::Allow log on through Terminal Services::>Everybody
U -- Links::Domain Controllers | Policy::Allow log on through Remote Desktop Services::>Users
U -- Links::Domain Controllers | Policy::Allow log on through Remote Desktop Services::>Everybody
7 changes: 7 additions & 0 deletions queries/encrypt_secure_channels.queries
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Encrypt Secure Channels
D -- policy::Domain member: Digitally encrypt or sign secure channel data (always)::Enabled
U -- policy::Domain member: Digitally encrypt or sign secure channel data (always)::!Enabled
M -- policy::<Domain member: Digitally encrypt or sign secure channel data::

D -- policy::Microsoft network server: Digitally sign communications (always)::Enabled
U -- policy::Microsoft network server: Digitally sign communications (always)::!Enabled
2 changes: 2 additions & 0 deletions queries/gpo_owners.queries
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Caution should be exercised in assigning owners of GPOs that isn't Domain Admins
U -- Details::!>Domain Admins
6 changes: 6 additions & 0 deletions queries/guest_account_status.queries
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// By default this value is set as disabled on servers and clients.
// https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/security-policy-settings/accounts-guest-account-status
U -- Policy::Accounts: Guest account status::!Disabled
// Users should require a password to logon to the domain.
D -- Policy::Accounts: Guest account status::Disabled
// Don't warn on missing values. This is a hardening GPO and might not be suitable for everyone.
3 changes: 3 additions & 0 deletions queries/kerberos_encryptions.queries
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// AES is the current ideal in kerberos encryption
U -- Network security: Configure encryption types allowed for Kerberos::<DES
U -- Network security: Configure encryption types allowed for Kerberos::<RC4
4 changes: 4 additions & 0 deletions queries/ldap_server_signing_requirements.queries
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// LDAP signing should be required.
U -- Links::Domain Controllers | Policy::Domain controller: LDAP server signing requirements::!Require signature
D -- Links::Domain Controllers | Policy::Domain controller: LDAP server signing requirements::Require signature
M -- Links::Domain Controllers | Policy::Domain controller: LDAP server signing requirements::
14 changes: 14 additions & 0 deletions queries/ntlm_authentication_levels.queries
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Mark as Desirable if LAN Manager authentication level is 5.
D -- Policy::Network security: LAN Manager authentication level::<Send NTLMv2 response | Policy::Network security: LAN Manager authentication level::>Refuse LM & NTLM

// Trigger if the LAN Manager authentication level isn't 4 or 5.
U -- Policy::Network security: LAN Manager authentication level::!Send NTLMv2 responses only. Refuse LM & NTLM | Policy::Network security: LAN Manager authentication level::!Send NTLMv2 responses only. Refuse LM | Policy::Network security: LAN Manager authentication level::!Send NTLMv2 response only. Refuse LM & NTLM | Policy::Network security: LAN Manager authentication level::!Send NTLMv2 response only. Refuse LM

// Warn if the LAN Manager authentication level is 4.
W -- Policy::Network security: LAN Manager authentication level::Send NTLMv2 responses only. Refuse LM
W -- Policy::Network security: LAN Manager authentication level::Send NTLMv2 response only. Refuse LM

// LAN Manager authentication level should be set SOMEWHERE
// Undesirables will trigger if this isn't set to a desirable value.
// This will trigger as missing if NO policy exists for LAN Manager authentication level.
M -- Policy::Network security: LAN Manager authentication level::
17 changes: 17 additions & 0 deletions queries/password_policies.queries
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// The best password length available via GPO is 14.
// Passwords should be longer, but need to be configured another way.
// It is best to configure the GPO to 14 and then configure the PSOs for longer password requirements to overwrite the GPO
// https://www.blackhillsinfosec.com/increase-minimum-character-password-length-15-policies-active-directory/
// https://adsecurity.org/?p=3377
U -- Policy::Minimum password length::#!14

U -- Policy::Maximum Password Age::#>365
M -- Policy::Maximum Password Age::
M -- Policy::Account lockout duration::
M -- Policy::Account lockout threshold::

// Passwords should not use a reversible encryption
U -- Policy::Store passwords using reversible encryption::!Disabled

// LM Should be prohibited
U -- Network security: Do not store LAN Manager hash value on next password change::!Enabled
Loading

0 comments on commit d2d7ec9

Please sign in to comment.