Use PowerShell to Discover Network Information from Shares

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.

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.

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:

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 \srv01Share -Recurse | Select FullName

FullName

--------

\srv01Sharefolder

\srv01ShareDocument001.docx

\srv01ShareDocument002.docx

\srv01ShareDocument003.docx

\srv01ShareDocument004.docx

\srv01ShareDocument005.docx

\srv01Sharetestscript.ps1

\srv01SharefolderFoo

\srv01Sharefolderold.vbs

\srv01SharefolderFooNew 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 \srv01Share -Recurse -Include *.txt,*.vbs,*.ps1,*.xml |

Select-String -Pattern "username|password"

\srv01SharefolderInput.xml:5: <Username>hacmespaccount</Username>

\srv01SharefolderInput.xml:6: <Password>Summer2012!</Password>

\srv01Sharetestscript.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.

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 \srv01Share -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:tempDocument001.docx")

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