Follow-Up Work
Autodidactic Learning Time
Complete these videos on TCM Academy. Ask your peers (I'm happy to field questions as well) if you have any issues completing these lessons.
- Sockets video
- Reading/Writing Files video
- Building a Port Scanner video
- Building a Shoe Budget Tool video
Supplementary PowerShell Code
- Just to stay consistent with the rest of today's lesson
- TCM will show you how to do these things in Python, I'll show you the PowerShell way
Reading & Writing Files in PowerShell
PowerShell Code Example
$name = 'John Doe'
$favoriteFood = 'Pizza'
$todaysDate = Get-Date
# Create a dummy file
$pathToFile = "$env:UserProfile\Desktop\test-file.txt"
New-Item -ItemType File -Path $pathToFile | Out-Null
# Write contents to the dummy file
$contentsToWrite = @"
Hello! My name is $name
My favorite food is $favoriteFood
Today's date is $($todaysDate.ToShortDateString())
"@
# Overwrite the file
Out-File -FilePath $pathToFile -InputObject $contentsToWrite -Encoding UTF8 -Force
# Append to the end of the file
Out-File -FilePath $pathToFile -InputObject $contentsToWrite -Encoding UTF8 -Force -Append
# Retrieve the contents of the file
$fileContents = Get-Content $pathToFile
$fileContents
My TCP Port Scanner in PowerShell
- It's definitely not the best TCP port scanner, but can serve as example code
- Does not do UDP
- I'm not a big fan of rewriting tools where better exist (e.g.
nmap
)
Test-TcpPort
function Test-TcpPort {
[CmdletBinding()]
param (
[Parameter(
Mandatory = $true,
Position = 0,
HelpMessage = 'Enter an IP address, hostname, or FQDN.'
)]
[String[]]
$TargetHost,
[Parameter(
Mandatory = $true,
Position = 1,
HelpMessage = 'Enter a TCP port between 1 and 65535. It may be a single port, comma separated, or a range; or a combination.'
)]
[ValidateRange(1,65535)]
[Int[]]
$Port,
[Parameter(Position = 2)]
[ValidateRange(1,100)]
[Int]
$Threads = 10,
[Parameter(Position = 3)]
[ValidateRange(100,10000)]
[Int]
$TimeOutMilliseconds = 1000
)
begin {
$jobs = @()
$scriptBlock = {
$target = $args[0]
$ports = $args[1]
$timeout = $args[2]
$result = [PSCustomObject]@{
'Target' = $target
'Ports' = @()
}
$ports | ForEach-Object {
$port = $_
$tcpClient = New-Object Net.Sockets.TcpClient
if ($tcpClient.ConnectAsync($target, $port).Wait($timeout)) {
$state = 'Open'
}
else {
$state = 'Closed'
}
$result.Ports += [PSCustomObject]@{
'Protocol' = 'TCP'
'Port' = $port
'State' = $state
}
$tcpClient.Close()
$tcpClient.Dispose()
}
return $result
}
}
process {
for ($i = 0; $i -le $TargetHost.Count; $i += $Threads) {
$start = $i
$end = ($i + $Threads) - 1
$TargetHost[$start..$end] | ForEach-Object {
$target = $_
Write-Verbose "Processing host: $target"
$jobs += Start-Job -Name $target -ScriptBlock $scriptBlock -ArgumentList $target, $Port, $TimeOutMilliseconds
}
$jobs | Wait-Job | Out-Null
}
}
end {
$jobs | Receive-Job | Select-Object -Property * -ExcludeProperty PSComputerName, PSShowComputerName, RunspaceId
$jobs | Remove-Job -Force
}
}
https://github.com/0xBEN/PSToolbox/blob/master/Public/ps1/Test-TcpPort.ps1