--> Skip to main content

SANS Sec505 course notes - Day 1

Views

SEC505 - Securing Windows and PowerShell Automation videos

Security must be baked in from the beginning, then continuously enforced and monitored afterwards!

26ZAGP7S2R86L8C

Set-MpPreference -DisableRealtimeMonitoring $true -force

Set-ExecutionPolicy -ExecutionPolicy Bypass -Force

- to remove NTFS blocking tags ( downloaded files from the Internet with Chrome, IE or Edge, but not for Firefox):
dir *.ps1 | unblock-file

get-help set-*
get-help *loc*

get-help -full get-process
get-process
cls

get-help -show window get-service

get-help about*

get-alias
get-alias ps
new-alias notepad.exe
help about_alias

$Process = get-process -name lsass
$process.name
$process.id
$process.Company
$process.kill()   #but don't do it!!!

Object = Properties + Methods
Class = Type of Object (Blueprint)

- to show properties, methods and class type:
get-process | get-member

$x = get-item hklm:\
$x | get-member

- 'Drives' are more than just disk volumes:
get-psdrive

On your computer:
dir hkcu:\
dir variable:\
cd cert:\localmachine\ca

Environment Variables:
dir env:\

$env:PATH
$env:windir
$env:SYSTEMROOT

new-item env:\veryable -value "Flash Gordon"
set-item end:\veryable -value "Wonder Woman"
remove-item end:\VERYABLE


get-help get-*proc*
get-help *proc*

Your own functions, aliases and variables in memory are temporary, they do not survice the closing of the PowerShell host process.

On your computer:
ise $Profile.CurrentUserAllHosts


$profile.allusersallhosts

$profile.alluserscurrenthost


$Profile scripts run automatically at launch!

get-help *service*

##################
Find cmdlets related to services
get-help *service*

Find cmdlets related to services in the graphical PowerShell ISE editor?
get-service

View the properties and methods of service objects:
get-service | get-member

What is 'gm' an alias for?
get-alias gm

Open your own PS profile script in a new PS ISE tab:
ise $profile.CurrentUserAllHosts

View a list of the current "drives" available in PS:
get-psdrive

View the PATH environment variable:
$env:path

#####################
dir function:\
get-content function:\mkdir

Dot Sourcing:
. .\libraryscript.ps1


Module:
$env:PSModulePath -Split ";"

Get-Module -ListAvailable
Import-Module -Name AppLocker
Get-Command -Module Applocker

Check:
https://www.powershellgallery.com/
for PowerShell goodies!

PowerShell Remoting:
enable-psremoting -force

Enter-PSSession -Computername $env:Computername

WinRM service on TCP port 5985 and 5986 accessible!
Be a member of the local Administrators group!


WSMan Protocol = web services for management
Open, DMTF protocol based on SOAP
WSMan implemented by the WinRM service on Windows!

Manually enable remoting on a client OS:
Enable-PSRemoting -Force

Connect interactively like Telnet:
Enter-PSSession -ComputerName Server47

Enter-PSSession -UserSSL -Computer box.sans.org

Exit-PSSession #when you are done!


Non-interactive commands or scripts (for scheduled tasks):
Invoke-Command -ScriptBlock {...} -Computer $Box

Invoke-Command -FilePath .\script.ps1 -Computer $Box

$Output = Invoke-Command -FilePath .\script.ps1


C:\SANS\Day1-PowerShell> $output = Invoke-Command -computername $env:COMPUTERNAME -ScriptBlock {ps}
C:\SANS\Day1-PowerShell> $output

- to execute a local script on a remote system, but see the output in the local shell:
Invoke-Command -computername Server7 -filepath .\somescript.ps1


###########  Fan-Out Remoting as Background job: ##############
$$Servers = @("Srvr47", "Srvr48","Srvr49")
Invoke-Command -FilePath .\script.ps1 -AsJob -Computer $Servers

Get-Job #query job status and get job ID number

#The output will be collated by computer name:
$Output = Receive-Job -Keep -ID 6

C:\SANS\Day1-PowerShell> $output = Invoke-Command -computername $Servers -ScriptBlock {ps} -AsJob

C:\SANS\Day1-PowerShell> Invoke-Command -computername $Servers -ScriptBlock {ps} -AsJob

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command                 
--     ----            -------------   -----         -----------     --------             -------                 
10     Job10           RemoteJob       Running       True            WIN2016SRV           ps                      

C:\SANS\Day1-PowerShell> Get-Job

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command                 
--     ----            -------------   -----         -----------     --------             -------                 
8      Job8            RemoteJob       Completed     True            WIN2016SRV           ps                      
10     Job10           RemoteJob       Completed     True            WIN2016SRV           ps                      

$output = Receive-job -Id 22 -keep
$output


Remoting File Copy and Hyper-V Direct:

#Create a WSman Session to a remote host with PowerShell 5.0:
$Session = New-Session -ComputerName dc.testing.local

#Upload a file to the remote host (-ToSession):
copy -Path C:\LocalFolder\file.txt -Destination c:\RemoteFolder\file.txt -ToSession $Session

#Download a file from the remote host (-FromSession):
copy -Path C:\RemoteFolder\file.txt -Destination c:\LocalFolder\file.txt -FromSession $Session

#######################
1.4 Essential Command and Scripting Examples:
Setting up our Training VM
PowerShell OverView and Tips
Modules, Functions and PowerShell Remoting
Essential Commands and Scripting Examples
Writing  your Own Functions and Scripts


Parameters, Arguments, Switches and Piping
get-member -inputobject $x -membertype property -static
get-member -input $x -m property -static
gm -i $x -m property -s


A piped object becomes a parameter argument:
get-date "11/29/17" | gm -m property -static

The -WhatIf switch for job security...

> "dog" | .\Translate.ps1 -Language french

> get-help -Full Get-Process

- the  next command will delete anything inside of the current folder you are in:
rm *.* -Recurse -Force

or
If you want to use the -WhatIf option:
rm *.* -Recurse -Force -WhatIf


"Hello World"

"Hello World" | out-default
"Hello World" | out-default | out-host


Format-List
- shows each property on a separate line
get-process | format-list *

Format-Table
- shows properties in columns, like a spreadsheet
ps | format-table id, name, path -autosize


Display the properties that you want to display:
ps | format-table name, id, path

- because the output above gets truncated we can use Format-List instead:
ps | format-list name, id, path


The OutPutters:
Out-Host
- displays text in shell

Out-File
- append
- encode

Out-GridView
- pops up a GUI app
- PassThru

out-Printer
- Local or network-attached printer

Out-Null
-silently destroys data (and laughs)

Out-String
- converts objects to 'real' strings
- the only outputter with pipeable output, such as grep.exe


######################

>ps | Out-GridView

>ps | Out-OneNote

>ps | Out-String -Stream

>ps | Out-String -Stream | grep.exe

######################

Exporting, Importing and Converting Object Data
- properties become column headers, objects are rows:

get-service | export-csv -path services.csv
$data = import-csv -path services.csv
#What is inside the $data array now? Text?

Export-CLIXML and Import-CLIXML

ConvertTo-JSON and ConvertFrom-JSON


>Invoke-WebRequest -Uri "http:/...." | ConvertFrom-Json
#Invoke-WebRequest is the powershell version of 'wget' or 'curl'

##########################

get-process | convertto-html -property Name,Path,ID -title "Process Report" -head "<h1>Process Report </h1>" -body "<h2> Report

Was Run:(get-date)</h2><hr>" | out-file -filepath \\server\share\report.html


PS C:\Users\LapDog> get-process | convertto-html -property Name,Path,ID -title "Process Report" -head "<h1>Process Report </h1>"

-body "<h2> Report Was Run:(get-date)</h2><hr>" | out-file -filepath c:\users\lapdog\Desktop\report.html

####################3
Please turn to the next exercise on page 120!!!!

Remember: tab completion is your friend!


########################
Select-Object (Alias: Select)

Similar to "SELECT" in SQL queries:
get-process "powershell*" | select-object ProcessName, ID, Path | out-gridview


Extract first, last and unique items only:
get-service | select-object -first 5
get-hotfix | select -last 3
get-content users.txt | select -unique




Sort-Object (Alias:Sort)
Sort by one or more properties:

dir *.exe, *.dll, *.sys | sort-object length, extension, name -desc | select-object -first 20 | format-table length, fullname -

autosize



Where-Object (Aliases: Where,?)
$_ is a temp variable for each object piped in.
{..} is a test tha tmust evaluate to true or false.

get-service | where-object {$_.status -ne "running"}

dir hkcu:\ | where-object {$_.subkeycount -gt 2}

get-command | where {$_.name -like "*item*"}

get-hotfix | where {$_.description -math "^Secur."}

ps | ? {($_.id -ge 100) -and ($_.name -like "svc*")}

? - is used instead of 'where'

###################

Arrays are like In-Memory Database Tables:

Creating Arrays:
$empty = @()
$one = @ ("SANS")
$x = @(1, "hi", 4.2, "bye")
$x += "AppendMoreStuff"
$big = @(0...50000)



Using Arrays:
$big.count

$x        #everything
$big [0]    #First
$big [1]    #Second
$big [-1]    Last

$d, $f = $nums [3,7]
$another = $nums [3...209]
$last5 = $big [-1..-5]

########################################

Capturing Command Output to An Array:

$output = get-history -count 50
$output = netstat.exe -ano
$output = python.exe myscript.py
$output = @(python.exe myscript.py)

$lines = @(get-content c:\file.txt)
$manylines = get-content *.txt, *.log, *.ini

$bytes = get-content worm.exe -encoding byte

@ - tells PowerShell that no matter how many lines of output, all those lines should go into an array.


###############3
On your computer:
- run the following commands
cd c:\sans\Day1-Powershell\Examples
ise .\Windows_Event-Logs.ps1
ise .\Nmap.ps1


###########################
Search Event Logs:

Get-WinEvent
- search local and remote event logs

- filtering performed at the remote server, not locally.

- can query archived log files off-line (*.evtx files).

- supports the XPath query language:
Very flexible and precise query syntax.
Build your XPath query in Event Viewer.
Lots of XPath tutorials on the Internet.

eventvwr.msc  - the graphical event viewer!

Example from Manual:
get-winevent -listlog *

get-winevent -listlog s* -computer Server57

$logdata = get-winevent -logname system

get-winevent -logname security -maxevents 3 | format-list *


###
$events  = get-winevent -log system         -max 20
$events += get-winevent -log application     -max 20
$events += get-winevent -log security         -max 20


$events | sort-object -property TimeCreated | format-table TimeCreated, ID, Level, Message -auto


########
Paste the xPath from the Windows EventViewer and run under:

$FromEventViewer = @'

......

'@

get-winevent -FilterXML $FromEventViewer | export-csv -path .\searchresults.csv

#####################

$dude = "Bryan"

"Hey There $Dude !"

- a double quote string is a command in powershell to look for a string at that location!
- while a single quote is just being echoed!
'Hey There $Dude!"

#################################
Parsing Nmap XML Output
nmap.org
- can identify listening ports, service versions, operating fingerprints, and more.
- used for inventories and penetration testing.
- save your enterprise-wide port scans to XML files.

Parse-Nmap.ps1 Script:
.\parse-nmap.ps1 samplescan.xml -runstats dir *.xml | .\parse-nmap.ps1

- when we use with nmap the -runstats command, we get all sort of information, such as ports scanned, hosts up and down, total

hosts scanned, version, how long it took to scan, etc.


Example from Manual:
nmap.exe -A -oX samplescan.xml 10.0.0.0/16

.\parse-nmap.ps1 -path samplescan.xml | select-object FQDN, IPv4, MAC, OS | convertto-html -title "$(get-date)" | out-file \

\server\sharedfolder\report.html

In real life hackers and attackers scan thousands of machines at a time to find vulnerable entry points!


Scanning for Windows XP machines:

.\parse-nmap.ps1 -path samplescan.xml | where {$_.OS -like "*Windows XP*"} |
 export-csv .\weblisteners.csv


$data = import-csv .\weblisteners.csv


$data | where {($_.IPv4 -like "10.57.*") -and ($_.Ports -match "open:tcp:22")}


#######################################

On your computer
cd c:\sans\Day1-PowerShell\example

ise .\If_FlowControl.ps1
ise .\While_FlowControl.ps1
ise .\Named_Parameters.ps1


#################

Flow Control: If-ElseIf-Else

If ($string -like "SANS*")
 { "It's true that it starts with SANS." }

ElseIf ($string -match "[FGH]IAC")
 {
    "It matches the regular expression pattern."
 }

Else
 {
    "We don't know what it is, so we're giving up."
 }



Flow Control: While

$rabbits = 2
while ($rabbits -lt 10000) {            #-lt = less than
    "We now have $rabbits rabbits!"
    $rabbits = $rabbits * 2

}


####
Flow Control: Do-While
$rabbits = 20000

Do {
    "We now have $rabbits rabbits!"
    $rabbits *= 2
} While ($rabbits -lt 10000)


#######
Flow Control: ForEach, For and Switch

$services = get-service

ForEach ($x in $services)
{

$foo.name + " : " + $foo.status

}

get-service | ForEach { $_.name }


################

ps> 3+7
10

ps>"3" + "7"
37

>


###################
Functions:
Function = block of code with a name.
- can take zero or more input parameters.
- can return zero or more output objects.
- can accept piped input, just like a cmdlet.
- good way organize code into manageable units.

Functions are kept in the function:\ drive.

dir function:\
get-item function:\man | format-list scriptblock


Create a function in PowerShell - example:
function hi {"Hi there! "}

###################

Creating a new function

function name {<your code here}

function hi {"Hi!"}

function time {(get-date).TooLongTimeString() }


function edit-hostfile
{

notepad.exe $env:WinDir\System32\Drivers\Etc\hosts

}

###########

Passing in Named Parameters to a Function

function New-User ($UserName, $Password)
{
net.exe user $UserName "$Password" /add
}


new-user -username "Jill" -password "Sekrit"

new-user -u "Lori" -p "p@55vvord"


##################
Constraining a Function's Parameter Types

function eat-lunch ([Int] $number, [$String] $food)
{
"each day we eat $number $food pies!"
}

eat-lunch -number 3 -food pinkie


##################

Switch Parameters to Functions

- a switch parameter takes no arguments.
- a switch can only be $True or $False (defaults to $False).

function show-folder ([Switch] $list) {
if ($list) {dir |format-list *}
else {dir |format-table fullname, length}

}

show-folder        #no switch, so $list = $False
show-folder -list    #switch used, so $list = $True

- switch parameters are by default False.

###################

Assigning Default Values to Function Parameters

function disable-admin
{

Param ($Password = "SEC505Gr8#4TV!")
net.exe user Administrator "$Password"
net.exe user Administrator /active:no
}

disable-admin
disable-admin -password "0ve3rr1d3n!"

######################
Passing Arguments Into Scripts


#ise .\Examples\PingWrapper.ps1
#to pass arguments into the named
#parameters of a script, use Param(...)

Param($computer = "localhost")

function pingwrapper ($ip) {ping.exe $ip }
pingwrapper -ip $computer



- below we pass an argument of -computer and then we specify an IP address, but the program already has a $computer argument, we

just chose to change it.
- also, -ip is a parameter.
- you can only have one 'param' key and it needs to be at the top.

.\PingWrapper.ps1 -computer 8.8.8.8


Exercise:
Pass through a username and password, a drive letter, and a UNC path. Take one of your tasks and create a function and param key,

just like above.

#################

<#Congratulations!!! #>
$Today.Completed = $True

################################################ End of Day 1 ##################################

Comment Policy: Please write your comments that match the topic of this page's posts. Comments that contain links will not be displayed until they are approved.
Leave a Comment
Close comments