Skip to content
This repository was archived by the owner on Sep 2, 2022. It is now read-only.

Add LmCompatibilityLevel information in GPO objects#47

Open
Hackndo wants to merge 3 commits into
BloodHoundAD:masterfrom
Hackndo:patch-3
Open

Add LmCompatibilityLevel information in GPO objects#47
Hackndo wants to merge 3 commits into
BloodHoundAD:masterfrom
Hackndo:patch-3

Conversation

@Hackndo

@Hackndo Hackndo commented Nov 23, 2021

Copy link
Copy Markdown

If GPO object forces LmCompatibilityLevel to be less than 3, then the computers it will be applied on will use NTLMv1 when authenticating.

This information seems very useful from an attacking perspective as authentication can be coerced and NTLMv1 hash cracked.

If GPO object forces LmCompatibilityLevel to be less than 3, then the computers it will be applied on will use NTLMv1 when authenticating.

This information seems very useful from an attacking perspective as authentication can be coerced and NTLMv1 hash cracked.
@Hackndo

Hackndo commented Nov 23, 2021

Copy link
Copy Markdown
Author

Here are two queries that can be used with this PR. I'm not sure they are optimized but they work. :)

        {
            "name": "Find all hosts with NTLMv1",
            "queryList": [
                {
                    "final": true,
                    "query": "MATCH p=(n:GPO)-[r1:GpLink {enforced:true}]->(container1)-[r2:Contains*1..]->(c:Computer) WHERE n.ntlmv1 IS NOT NULL WITH n, length(p) AS len, c ORDER BY len ASC WITH HEAD(COLLECT(n.ntlmv1)) AS NTLMv1, HEAD(COLLECT(len)) AS lenHead, c WHERE NTLMv1 = true RETURN c AS computer UNION MATCH p=(n:GPO)-[r1:GpLink {enforced:false}]->(container1)-[r2:Contains*1..]->(c:Computer) WHERE NONE (x in NODES(p) WHERE x.blocksinheritance = true AND x:OU AND NOT (n)-->(x)) AND n.ntlmv1 IS NOT NULL WITH n, length(p) AS len, c ORDER BY len ASC WITH HEAD(COLLECT(n.ntlmv1)) AS NTLMv1, HEAD(COLLECT(len)) AS lenHead, c WHERE NTLMv1 = true RETURN c AS computer"
                }
            ]
        },
        {
            "name": "Find shortest paths from NTLMv1 to high value targets",
            "queryList": [
                {
                    "final": true,
                    "query": "MATCH p=(n:GPO)-[r1:GpLink {enforced:true}]->(container1)-[r2:Contains*1..]->(c:Computer) WHERE n.ntlmv1 IS NOT NULL WITH n, length(p) AS len, c ORDER BY len ASC WITH HEAD(COLLECT(n.ntlmv1)) AS NTLMv1, HEAD(COLLECT(len)) AS lenHead, c WHERE NTLMv1 = true WITH c MATCH p=allShortestPaths((c:Computer {name: c.name})-[]->(g:Group {highvalue:true})) RETURN p AS path  UNION MATCH p=(n:GPO)-[r1:GpLink {enforced:false}]->(container1)-[r2:Contains*1..]->(c:Computer) WHERE NONE (x in NODES(p) WHERE x.blocksinheritance = true AND x:OU AND NOT (n)-->(x)) AND n.ntlmv1 IS NOT NULL WITH n, length(p) AS len, c ORDER BY len ASC WITH HEAD(COLLECT(n.ntlmv1)) AS NTLMv1, HEAD(COLLECT(len)) AS lenHead, c WHERE NTLMv1 = true WITH c MATCH p=allShortestPaths((c:Computer {name: c.name})-[]->(g:Group {highvalue:true})) RETURN p AS path"
                }
            ]
        },

Depending on the environement, spaces may appear in file

@gladiatx0r gladiatx0r left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to account for tabs too? You could use a character class. I think /s is for whitespace but not sure you want to capture newline etc., maybe just tabs and spaces, e.g. "[ \t]*"

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants