Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update gpp.rb to display GPO name #12258

Merged
merged 5 commits into from
Sep 26, 2019
Merged

Conversation

gkweb76
Copy link
Contributor

@gkweb76 gkweb76 commented Aug 31, 2019

What the changes do:

GPO files on SYSVOL do only include the GPO GUID, not the GPO name defined by the administrator. This modification makes this gpp module make an ADSI query to retrieve all of the domain's GPOs, and compare their GUID. If one GUID matches, then we know the GPO name and we can display it. On a pentest, a client is much more interested by knowing the GPO name rather than the obscure GUID. The ADSI query relies on meterpreter "extapi" extension.

Verification

  1. Get a meterpreter shell on a Windows host being in a domain
  2. meterpreter > run post/windows/gather/credentials/gpp
  3. If the domain has credentials stored in GPO, it will be displayed

Example

[*] Checking for group policy history objects...
[+] Cached Group Policy folder found locally
[*] Checking for SYSVOL locally...
[-] Error accessing C:\WINDOWS\SYSVOL\sysvol : stdapi_fs_ls: Operation failed: The system cannot find the path specified.
[*] Enumerating Domains on the Network...
[*] Retrieved Domain(s) HACKME2 from network
[*] Enumerating domain information from the local registry...
[*] Retrieved Domain(s) HACKME2 from registry
[*] Retrieved DC WIN-VGVKT0O3U4K.HACKME2.LOCAL from registry
[*] Enumerating DCs for HACKME2 on the network...
[+] DC Found: WIN-VGVKT0O3U4K
[*] Searching for Policy Share on WIN-VGVKT0O3U4K...
[+] Found Policy Share on WIN-VGVKT0O3U4K
[*] Searching for Group Policy XML Files...
[*] Parsing file: \\WIN-VGVKT0O3U4K\SYSVOL\hackme2.local\Policies\{D5323F3D-FD71-4A72-9449-6A918DCFFADE}\USER\Preferences\Groups\Groups.xml ...
[+] Group Policy Credential Info
================================

 Name               Value
 ----               -----
 NAME               Local admin
 TYPE               Groups.xml
 USERNAME           localadminyea
 PASSWORD           localadminyea!!
 DOMAIN CONTROLLER  WIN-VGVKT0O3U4K
 DOMAIN             hackme2.local
 CHANGED            2018-10-25 12:59:50
 NEVER_EXPIRES?     0
 DISABLED           0

[+] XML file saved to: /root/.msf4/loot/20190831035335_test2_192.168.56.119_microsoft.window_582450.txt

The field NAME Local admin is added at the begining, where "Local admin" is the GPO name in this example.

GPO files on SYSVOL do only include the GPO GUID, not the GPO name defined by the administrator. This modification makes this gpp module make an ADSI query to retrieve all of the domain's GPOs, and compare their GUID. If one GUID matches, then we know the GPO name and we can display it. On a pentest, a client is much more interested by knowing the GPO name rather than the obscure GUID. The ADSI query relies on meterpreter "extapi" extension.
@@ -241,7 +266,19 @@ def parse_xml(xmlfile)
tables = Rex::Parser::GPP.create_tables(results, filetype, xmlfile[:domain], xmlfile[:dc])

tables.each do |table|
print_good table.to_s
# We have to manually format the results as we want to insert a new line
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason that using table << ['NAME', xmlfile[:name]] if xmlfile.member?(:name) to add a row to the table doesn't work?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I simply did not think about it ^^ I wanted to insert this new field on top of other values. However the method you suggested is much simpler and cleaner, and I commited your idea to the code. The "NAME" field is added so it goes to the end instead, but the code simplification is worth it. Thanks :-)

Copy link
Contributor

Choose a reason for hiding this comment

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

Another (perhaps more correct option) would be to have Rex::Parser::GPP.create_tables take the name as an option parameter and add it to the table around https://github.com/rapid7/metasploit-framework/blob/master/lib/rex/parser/group_policy_preferences.rb#L102

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, thanks for making the change! The code is definitely much cleaner for it.

Directly insert the new value in the "table", instead of modifying the screen output manually. Simpler and cleaner, thanks @acammack-r7 !
Aesthetics modification
@busterb busterb self-assigned this Sep 23, 2019
busterb added a commit to busterb/metasploit-framework that referenced this pull request Sep 26, 2019
@busterb busterb merged commit 795e0eb into rapid7:master Sep 26, 2019
@busterb
Copy link
Member

busterb commented Sep 26, 2019

Release Notes

This improves the windows/gather/credentials/gpp module by displaying the name as well as the GUID for Group Policy Objects (GPO). It relies on the 'extapi' extension for Meterpreter in order to perform ADSI queries for obtaining the name to GUID mapping.

@tperry-r7 tperry-r7 added the rn-enhancement release notes enhancement label Oct 1, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants