Summary: Guest blogger, Niklas Goude, shows how to use Windows PowerShell to discover valuable network information from shares and file metadata.

Microsoft Scripting Guy, Ed Wilson, is here. We now come to Part 3 of Security Week with another guest blog by Niklas Goude.

Niklas Goude is a Security Consultant at TrueSec and an MVP in Windows PowerShell. In addition to his work performing security assessments for a variety of clients, he also has extensive experience in using Windows PowerShell to automate and implement Windows environments. He has been speaking at TechDays; SharePoint conferences in the U.S., Australia, and New Zealand; and other events and conferences. He is the author of two books about Windows PowerShell, and he shares his knowledge at PowerShell.nu. He is a member of the TrueSec Expert Team, an independent, elite team of security and infrastructure consultants that operates all over the world. The security team at TrueSec performs various tasks and services related to IT security such as code review, security health checks, and penetration testing. TrueSec also delivers top-notch training sessions in advanced IT security. Check out the TruSec website for additional information.

This is the third blog in a series of five, and we will talk about basic penetration testing techniques and how they affect misconfigured systems. The series covers everything from initial network reconnaissance techniques and brute force attacks to advanced extraction of registry secrets to assess dangerous system dependencies.

The key learning point is to demonstrate how you can use Windows PowerShell to accomplish almost any task—no matter the subject. The secondary learning point is to make you aware of common security issues and misconfigurations that may occur in Microsoft infrastructures today. One important thing to keep in mind is that the vulnerabilities we are looking for exist simply because of misconfigurations made by administrators, such as weak passwords or system dependencies.

I hope you will learn and enjoy!

Part 3: Shares and metadata

Penetration testing is an important part of improving security in any network environment. A hacker only needs to find a few weaknesses (even one) to compromise important IT systems. An important task for an IT administrator is to identify potential weaknesses and mitigate them.

As soon as an attacker has access to a domain account, the attacker can start to collect information by asking questions to a service in various ways. One example would be to display all accounts that are available in the domain, determine the domain policy, search through shares for sensitive data and anything else that would help the attacker finding more privileged accounts.

In the previous scenario, we managed to get our hands on a domain user’s logon name and password. In today’s scenario, we will use the domain account and focus on how to enumerate domain groups, policies, and shared resources by using Windows PowerShell.

Scenario

This scenario is based on a Windows domain environment consisting of three machines:

  • DC01: domain controller
  • SRV01: SQL Server and IIS
  • SP01: SharePoint 2010, SQL Server, and IIS

In addition, we have a client on the same network as the domain; however, the client is not a member of the domain. Each command in this scenario is executed from the client.

The server, SRV01, has a share where the domain users have access. The share is used to back up Word documents, files, and other data. The Word documents have simply been copied to the share.

For mitigation information, please see Remove hidden data and personal information by inspecting documents.

Code

With an actual domain account and password available, we can start searching for more information. The first step is to start Windows PowerShell on our attack machine by using the runas command with the /netonly switch. The syntax of this command is shown here.

PS > runas /netonly /user:hacme\user008 powershell_ise.exe
Enter the password for hacme\user008

When prompted for a password, we enter the password that we discovered in a previous post. Next, we can use the WinNT provider and ask for the default domain password policy settings.

PS > $domain = [adsi]("WinNT://hacme.local")

$domain.Properties.Keys | Foreach {

  @{$_ = [string]$domain.Properties.Item($_) }

}

 

Name                           Value                                          

----                           -----                                          

MinPasswordLength              7                                              

MaxPasswordAge                 3628800                                        

MinPasswordAge                 86400                                          

PasswordHistoryLength          24                                             

Name                           hacme.local                                    

AutoUnlockInterval             1800                                           

LockoutObservationInterval     1800                                            

MaxBadPasswordsAllowed         0  

The output tells us that the minimum password length is 7 characters. It also displays that the maximum bad passwords allowed is set to 0, meaning that the system does not implement an account lockout policy. This means that we can make as many brute force attempts as we want without worrying about locking out an account.

One of our goals is to find high-privileged accounts, so let’s take a peek at the members of the Domain Admin group by using ADSI:

PS > $dAdmin = [adsi]"LDAP://CN=Domain Admins,CN=Users,DC=hacme,DC=local"

$dAdmin.member

CN=SQL-Serviceaccount,OU=ServiceAccounts,OU=Hacme,DC=hacme,DC=local

CN=Administrator,CN=Users,DC=hacme,DC=local

 The output tells us that there are three members of the Domain Admin group. We’ll get back to those accounts later.

For now, let us move on and look at enumerating shares and searching through files for sensitive data, such as connection strings and passwords. Because we are running the Windows PowerShell ISE by using a domain account, we can use dir (alias for Get-ChildItem) with the –Recurse switch to get the files and folders from a network drive.

To find out if a server is sharing any folders, we simply type dir \\SRV01\ and let the IntelliSense do the work for us. This technique is shown here.

Isn’t IntelliSense wonderful! Based on the information displayed in the previous example, we see that in addition to the hidden shares. We can test accessing a share by using the Get-ChildItem cmdlet. If our account has access, the command outputs the files and folders that we have access to.

PS > dir \\srv01\Share -Recurse | Select FullName

FullName                                                                      

--------                                                                      

\\srv01\Share\folder                                                          

\\srv01\Share\Document001.docx                                                

\\srv01\Share\Document002.docx                                                

\\srv01\Share\Document003.docx                                                

\\srv01\Share\Document004.docx                                                

\\srv01\Share\Document005.docx                                                 

\\srv01\Share\testscript.ps1                                                  

\\srv01\Share\folder\Foo                                                      

\\srv01\Share\folder\old.vbs                                                   

\\srv01\Share\folder\Foo\New Text Document.txt    

It seems as if our account has access to the share. The share contains a couple of Word documents, a .ps1 file, a .vbs file, an .xml file, and a .txt file. To find out if any of the files contain sensitive data, we can pipe the objects to the Select-String cmdlet and set up a pattern of interest. In this example, we will search for user name and password. We will also filter out the files with the extensions .ps1, .vbs, .xml, and .txt.

PS > dir \\srv01\Share -Recurse -Include *.txt,*.vbs,*.ps1,*.xml |

Select-String -Pattern "username|password"

 

\\srv01\Share\folder\Input.xml:5:            <Username>hacme\spaccount</Username>

\\srv01\Share\folder\Input.xml:6:            <Password>Summer2012!</Password>

\\srv01\Share\testscript.ps1:1:# Get Username and password

If we study the output, we notice that someone left a Windows PowerShell script with a comment about user name and password and an .xml file that contains a user name and password in clear text. Let’s take a closer look by adding the –Context parameter and look at the lines before and after the matched lines.

PS > dir \\srv01\Share -Recurse -Include *.txt,*.vbs,*.ps1,*.xml |

Select-String -Pattern "username|password" -Context 2,2

 

  \\srv01\Share\folder\Input.xml:3:        <Passphrase>P@ssPhrase</Passphrase>

  \\srv01\Share\folder\Input.xml:4:        <Account AddToLocalAdminsDuringSetup="true">>

 \\srv01\Share\folder\Input.xml:5:            <Username>hacme\spaccount</Username>>

  \\srv01\Share\folder\Input.xml:6:            <Password>Summer2012!</Password>

  \\srv01\Share\folder\Input.xml:7:            <Email>spaccount@hacme.local</Email>

  \\srv01\Share\folder\Input.xml:8:        </Account>>

  \\srv01\Share\testscript.ps1:1:# Get Username and password

  \\srv01\Share\testscript.ps1:2:$cred = Get-Credential

  \\srv01\Share\testscript.ps1:3:gwmi WIn32_OperatingSystem -COmputerName sp01 -Credential $cred

The Windows PowerShell script stored on the share uses Get-Credential as input, so it doesn’t tell us much. However, the input.xml file seems to be a configuration file for some product (probably SharePoint because the environment only uses three servers). What is even more interesting is that the .xml file has a line that says: <Account AddToLocalAdminsDuringSetupe=”true”>. We will investigate local admin accounts in the next post.

The share also contained some Word documents, and sometimes Word documents can contain metadata that describes user information such as a user’s logon name. Because we are already on the domain, this is not very interesting for us at the moment—we can simply enumerate the domain and retrieve all the domain accounts. However, this would be useful if we failed in any of our previous attacks.

There are a lot of public Word documents available on the Internet, and by simply looking at the metadata, we could find users logon names. Let us see how that works. In this example we’ll simply copy the Word documents from the share to a local folder and start peeking at the metadata.

PS > dir \\srv01\Share -Recurse -Include *.docx |

Copy-Item -Destination C:\temp

If we want to read the metadata, we can use the Com object Word.Application. The Com object requires that Word is installed on the system. First we create an instance of Word.Applciation. We also set the visible property to $false.

PS > $word = New-Object -comobject Word.Application

PS > $word.Visible = $false 

Next, we open the document by using the Open() method.

PS > $openDoc = $word.Documents.Open("C:\temp\Document001.docx") 

Then, we access the XML, and store the core.xml information in a variable.

PS > $docX = [xml]$OpenDoc.WordOpenXML

PS > $coreXML = $docX.package.part | Where { $_.name -eq "/docProps/core.xml" }

And now we can simply take a peek in the CoreProperties, which may give us information regarding user’s logon names.

PS > $coreXML.xmlData.coreProperties

 

cp             : http://schemas.openxmlformats.org/package/2006/metadata/core-properties

dc             : http://purl.org/dc/elements/1.1/

dcterms        : http://purl.org/dc/terms/

dcmitype       : http://purl.org/dc/dcmitype/

xsi            : http://www.w3.org/2001/XMLSchema-instance

creator        : Jean-Luc Picard (user001)

lastModifiedBy : Jean-Luc Picard (user001)

revision       : 1

created        : created

modified       : modified 

Notice how the metadata displays the user’s first name, last name, and logon name.

Now, let’s script it and repeat it on all the downloaded documents. In this example, we’ll use the Get-TSWordXMetadata function.

PS > dir C:\temp | Get-TSWordXMetadata |

Select Creator, LastModifiedBy

 

Creator                                  LastModifiedBy                         

-------                                  --------------                          

Jean-Luc Picard (user001)                Jean-Luc Picard (user001)              

William Riker (user002)                  William Riker (user002)                

Geordi LaForge (user003)                 Geordi LaForge (user003)               

Worf Son of Mogh (user004)               Worf Son of Mogh (user004)             

Beverly Crusher (user005)                Beverly Crusher (user005) 

 Download

  • The Get-TSWordXMetadata function can be downloaded from the Script Center Repository.
  • Additional functions and code related to security are available on the TruSec Tools site.

~Niklas

I want to thank Niklas for another very interesting blog. Join us tomorrow for another exciting blog as Security Week continues.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy