Powershell & .NET Classes

Being able to develop tools on the fly is a valuable skill in engagements. We can create tools in Powershell & .NET that can be run with basic privileges.


Bypassing Security

Chances are Administrators have set some type of security in place to restrict PowerShell scripts.

Change Execution Policy

Set-ExecutionPolicy determines what scripts and files are allowed to run on the current session. It can be Restricted, AllSigned, RemoteSigned Unrestricted, and Bypass.

PS C:\> powershell -ep bypass
PS C:\ Set-ExecutionPolicy -ExecutionPolicy bypass -Scope CurrentUser

Developing Powershell Scripts

Get Domain - .NET System.DirectoryServices.ActiveDirectory

In Microsoft .NET classes related to AD are found in the System.DirectoryServices.ActiveDirectory namespace.

Get Current Domain

PS C:\Users\stephanie> [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()

Forest                  : corp.com
DomainControllers       : {DC1.corp.com}
Children                : {}
DomainMode              : Unknown
DomainModeLevel         : 7
Parent                  :
PdcRoleOwner            : DC1.corp.com
RidRoleOwner            : DC1.corp.com
InfrastructureRoleOwner : DC1.corp.com
Name                    : corp.com

Let's making this into a PowerShell script file. We'll call it testing.ps1.

Powershell ISE ftw. Change ExecutionPolicy before running!

Active Directory relies on LDAP as it's communication protocol. Like other protocls we can specity a URI scheme. This scheme is known as the LDAP ADsPath.

LDAP://HostName[:PortNumber][/DistinguishedName]

We can build out this path and use it to create our own custom communication scripts to enumerate active directory.

Powershell .NET script to retrieve ADsPath

$PDC = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().PdcRoleOwner.Name
$DN = ([adsi]'').distinguishedName 
$LDAP = "LDAP://$PDC/$DN"
$LDAP

Active Directory Service Interfaces (ADSI)

We can use ADSI directly in PowerShell. This is a powerful tool when developing scripts.

PS C:\Users\stephanie\Desktop> ([adsi]'').distinguishedName

DC=corp,DC=com

Now that we have the LDAP URI Path we can start to perform queries.

Retrieving AD Entries - .NET DirectorySearcher

In .NET ADSI we can use the DirectorySearcher object to perform queries against Active Directory. We'll add a FindAll() query that finds all entries in Active Directory.

$PDC = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().PdcRoleOwner.Name
$DN = ([adsi]'').distinguishedName 
$LDAP = "LDAP://$PDC/$DN"

# Add Query to our script.
$direntry = New-Object System.DirectoryServices.DirectoryEntry($LDAP)

$dirsearcher = New-Object System.DirectoryServices.DirectorySearcher($direntry)
$dirsearcher.FindAll()
FindAll() retrievies all entries in the entire domain.

The above image returns all entries in the entire domain. This is a lot of information, it's best to filter out what we're looking for.

Filter AD Entries - Find All Users

One way we can find all users is by Sam-Account-Type. This is the attribute applied to all users, computers, and group objects.

  • SAM_USER_OBJECT 0x30000000

  • SAM_GROUP_OBJECT 0x10000000

  • SAM_MACHINE_ACCOUNT 0x30000001

$dirsearcher.filter="samAccountType=805306368" #0x30000000 in decimal 
Fetch all Users in AD with samAccountType. 0x3000000

Printing User Properties

Let's loop through the newly created Users object and print all the properties for each entry.

$dirsearcher.filter="samAccountType=805306368"
$result = $dirsearcher.FindAll()
ForEach($obj in $result) {
    $obj.Properties
    Write-Host "==================================================="
}
Listing all properties in user object. Yields lots of information!

Last updated