What is Powershell?
PowerShell là ngôn ngữ scripting của Windows và là một shell environment được xây dựng bằng .NET framework. Điều này đồng nghĩa với việc chúng ta có thể thực thi các hàm của .NET trong PowerShell.
Đa số các câu lệnh PowerShell (còn được gọi là các cmdlet) đều được viết bằng .NET nên output của nó là các đối tượng nên có thể nói rằng PowerShell mang tính hướng đối tượng. Dạng đơn giản nhất của cmdlet là động từ-danh từ, ví dụ: câu lệnh để liệt kê danh sách các câu lệnh là Get-Command
.
Một số động từ thường gặp:
- Get
- Start
- Stop
- Read
- Write
- New
- Out
Seealso
Approved Verbs for PowerShell Commands - PowerShell | Microsoft Learn
Basic Powershell Commands
Using Get-Help
Câu lệnh Get-Help
giúp hiển thị thông tin hướng dẫn về một câu lệnh nào đó. Ví dụ:
Get-Help Command-Name
Có thể thêm flag -Examples
để in ra ví dụ:
Get-Help Get-Command -Examples
NAME
Get-Command
SYNOPSIS
Gets all commands.
-------- Example 1: Get cmdlets, functions, and aliases --------
Get-Command
-------- Example 2: Get commands in the current session --------
Get-Command -ListImported
------- Example 3: Get cmdlets and display them in order -------
Get-Command -Type Cmdlet | Sort-Object -Property Noun | Format-Table -GroupBy Noun
------------- Example 4: Get commands in a module -------------
Get-Command -Module Microsoft.PowerShell.Security, Microsoft.PowerShell.Utility
---------- Example 5: Get information about a cmdlet ----------
Get-Command Get-AppLockerPolicy
Using Get-Command
Câu lệnh Get-Command
liệt kê tất cả các cmdlet trên máy hiện tại. Câu lệnh này cho phép sử dụng pattern matching. Ví dụ: Get-Command Verb-*
hoặc Get-Command *-Noun
.
Câu lệnh sau sẽ giúp liệt kê tất cả các cmdlet có động từ là New
:
Get-Command New-*
Object Manipulation
Chúng ta có thể dùng toán tử |
(pipeline) để truyền output từ cmdlet này sang cmdlet khác (tương tự như Linux). Điểm khác biệt lớn nhất giữa PowerShell và các loại shell khác là nó truyền object sang cmdlet kế tiếp thay vì truyền chuỗi.
Các object cũng có các thuộc tính và phương thức tương tự như một object trong OOP. Có thể xem các thuộc tính là các biến có trong output của cmdlet và các phương thức là các hàm mà có thể áp dụng trên output của cmdlet. Để xem thuộc tính hoặc phương thức của một output, chúng ta có thể truyền nó vào cmdlet Get-Member
như sau:
Verb-Noun | Get-Member
Ví dụ:
Get-Command | Get-Member -MemberType Method
TypeName: System.Management.Automation.AliasInfo
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ResolveParameter Method System.Management.Automation.ParameterMetadata ResolveParameter(string name)
ToString Method string ToString()
TypeName: System.Management.Automation.FunctionInfo
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ResolveParameter Method System.Management.Automation.ParameterMetadata ResolveParameter(string name)
ToString Method string ToString()
TypeName: System.Management.Automation.CmdletInfo
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ResolveParameter Method System.Management.Automation.ParameterMetadata ResolveParameter(string name)
ToString Method string ToString()
Để xem các thuộc tính thì có thể dùng option -MemberType Property
.
Creating Objects From Previous Cmdlets
Chúng ta có thể trích xuất các thuộc tính từ output của một cmdlet để tạo thành một object mới thông qua cmdlet Select-Object
.
Ví dụ bên dưới liệt kê các thư mục mà chỉ trích xuất mode và name:
Get-ChildItem | Select-Object -Property Mode, Name
Mode Name
---- ----
d-r-- Documents
d-r-- Downloads
d-r-- Music
d-r-- Pictures
d---- temp
d-r-- Videos
Chúng ta cũng có thể dùng các option sau đối với output là mảng các object:
-First n
- lấyn
object đầu tiên.-Last n
- lấyn
object cuối cùng.-Unique
- chỉ hiển thị các object độc nhất.-Skip n
- bỏ quan
object.
Filtering Objects
Để lọc ra các object thỏa một điều kiện nào đó thì ta có thể dùng cmdlet Where-Object
.
Dạng tổng quát:
Verb-Noun | Where-Object -Property PropertyName -Operator Value
Verb-Noun | Where-Object {$_.PropertyName -Operator Value}
Câu lệnh thứ 2 sử dụng toán tử $_
để lặp qua từng object có trong mảng các object.
Một số giá trị của -Operator
:
-Contains
: chứa một giá trị nào đó.-EQ
: so sánh bằng.-GT
: so sánh lớn hơn.
Seealso
Ví dụ bên dưới tìm ra các dic đã bị dừng:
Get-Service | Where-Object -Property Status -eq Stopped
Sort-Object
Để sắp xếp các object thì có thể pipe với cmdlet Sort-Object
.
Ví dụ bên dưới sẽ sắp xếp các thư mục con:
Get-ChildItem | Sort-Object
Exercises
What is the location of the file "interesting-file.txt"
PS C:\Users\Administrator> Get-ChildItem -Path C:\ -File -Recurse -Filter *interesting-file.txt*
Tìm được ở thư mục
C:\Program Files
Specify the contents of this file
PS C:\Users\Administrator> Get-Content -Path "C:\Program Files\interesting-file.txt.txt" notsointerestingcontent
How many cmdlets are installed on the system(only cmdlets, not functions and aliases)?
PS C:\Users\Administrator> Get-Command -CommandType Cmdlet | Measure-Object -Line
Kết quả là 6638.
Get the MD5 hash of interesting-file.txt
PS C:\Users\Administrator> Get-FileHash -Path "C:\Program Files\interesting-file.txt.txt" -Algorithm MD5
Kết quả là
49A586A2A9456226F8A1B4CEC6FAB329
What is the command to get the current working directory?
Get-Location
Does the path "C:\Users\Administrator\Documents\Passwords" Exist (Y/N)?
PS C:\Users\Administrator> Test-Path -Path "C:\Users\Administrator\Documents\Passwords" False
What command would you use to make a request to a web server?
Invoke-WebRequest
Ví dụ:
$response = Invoke-WebRequest -Uri "http://www.example.com" $response.Content
Base64 decode the file b64.txt on Windows.
Tìm vị trí của file:
Get-ChildItem -Path C:\ -Recurse -Filter *b64.txt*
Tìm được ở thư mục
C:\Uses\Administrator\Desktop
.Sử dụng ba câu lệnh sau:
# Read the content of the file $base64Content = Get-Content -Path "C:\Uses\Administrator\Desktop\b64.txt" -Raw # Decode the Base64 content $decodedContent = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($base64Content)) # Output the decoded content Write-Output $decodedContent
Optionn
-Raw
dùng để lấy nội dung của file dưới dạng một chuỗi.Flag:
ihopeyoudidthisonwindows
Enumeration
Khi thâm nhập được vào máy mục tiêu, chúng ta cần enumerate những thông tin sau:
- Các người dùng
- Thông tin mạng cơ bản
- Các quyền trên tập tin
- Các quyền trên registry
- Các task đang chạy và các task được lập lịch
- Các tập tin không an toàn
How many users are there on the machine?
PS C:\Users\Administrator> Get-LocalUser
Thu được 5 người dùng:
Administrator
,DefaultAccount
,duck
,duck2
,Guest
.
Which local user does this SID(S-1-5-21-1394777289-3961777894-1791813945-501) belong to?
PS C:\Users\Administrator> Get-LocalUser -Name Guest | Select-Object -Property SID
How many users have their password required values set to False?
PS C:\Users\Administrator> Get-LocalUser | Where-Object {$_.PasswordRequired -eq $false}
Kết quả là 4 (không có Administrator).
How many local groups exist?
PS C:\Users\Administrator> Get-LocalGroup | Measure-Object -Line
Kết quả là 24.
What command did you use to get the IP address info?
Get-NetIPAddress
How many ports are listed as listening?
PS C:\Users\Administrator> Get-NetTCPConnection | Where-Object {$_.State -eq 'Listen'} | Measure-Object -Line
Kết quả là 20.
How many patches have been applied?
PS C:\Users\Administrator> Get-HotFix | Measure-Object -Line
Kết quả là 20.
Find the contents of a backup file.
Tìm vị trí của file backup:
PS C:\Users\Administrator> Get-ChildItem -Path C:\ -Filter *.bak* -Recurse
Tìm được ở:
C:\Program Files (x86)\Internet Explorer\passwords.bak.txt
.Đọc nội dung:
PS C:\Users\Administrator> Get-Content -Path "C:\Program Files (x86)\Internet Explorer\passwords.bak.txt" backpassflag
Search for all files containing API_KEY
Get-ChildItem -Path C:\ -Recurse | Select-String -Pattern API_KEY -Context 0,10
Kết quả xuất hiện gần thông báo lỗi
> C:\Users\Public\Music\config.xml:1:API_KEY=fakekey123 Select-String : The file C:\Windows\appcompat\Programs\Amcache.hve cannot be read: The process At line:1 char:42 + ... ath C:\ -Recurse -File | Select-String -Pattern API_KEY -Context 0,10 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [Select-String], ArgumentException + FullyQualifiedErrorId : ProcessingFile,Microsoft.PowerShell.Commands.SelectStringCommand
What command do you do to list all the running processes?
Get-Process
What is the path of the scheduled task called new-sched-task?
Get-ScheduledTask -TaskName "new-sched-task"
Kết quả:
/
Who is the owner of the
C:\
Get-Acl -Path C:\
Kết quả:
NT SERVICE\TrustedInstaller
Basic Scripting Challenge
Đoạn script bên dưới sẽ in các port đang chạy có trong một file:
$system_ports = Get-NetTCPConnection -State Listen
$text_port = Get-Content -Path C:\Users\Administrator\Desktop\ports.txt
foreach($port in $text_port){
if($port -in $system_ports.LocalPort){
echo $port
}
}
Đuôi của file PowerShell script là ps1
.
Cú pháp tạo biến:
$variable_name = value
Cú pháp vòng lặp:
foreach($new_var in $existing_var){}
Có thể thấy, chúng ta sử dụng toán tử -in
để kiểm tra xem một port trong file ($port
) có trong danh sách các port đang chạy hay không.
Windows cung cấp chương trình Powershell ISE (the Powershell Text Editor) để có thể chỉnh sửa PowerShell script.
Câu lệnh cho phép thực thi PowerShell script:
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted
What file contains the password? and What is the password?
Get-ChildItem -Path "C:\Users\Administrator\Desktop\emails" -Recurse | Select-String password
Kết quả có dòng sau:
Desktop\emails\martha\Doc3M.txt:106:password is johnisalegend99
What files contains an HTTPS link?
Get-ChildItem -Path "C:\Users\Administrator\Desktop\emails" -Recurse | Select-String https
Kết quả có dòng sau:
Desktop\emails\mary\Doc2Mary.txt:5:https://www.howtoworkwell.rand/
Intermediate Scripting
Trong trường hợp host không có Nmap hoặc Python thì ta cần viết script PowerShell.
Ví dụ, viết một script để quét các port cho phép:
- Chỉ định khoảng IP để scan.
- Chỉ định khoảng port.
- Chỉ định loại scan (có thể là TCP connect scan).
Định nghĩa các tham số ở đầu script:
Param(
[Parameter(Mandatory = $true)]
[string]$HostName,
[Parameter(Mandatory = $true)]
[string]$Ports, # '1,2,3' or '1-100'
[Parameter(Mandatory = $true)]
[string]$Protocol # 'tcp' or 'udp'
)
Hàm tách port:
function ParsePort {
$PortList = @()
if ($Ports.Contains(",")) {
$PortList = $Ports.Split(",")
}
elseif ($Ports.Contains("-")) {
$portBoundaries = $Ports.Split("-")
$startPort = [int]$portBoundaries[0]
$endPort = [int]$portBoundaries[1]
if ($endPort -le $startPort) {
Write-Output "End port must be greater than start port"
exit
}
for ($i = $startPort; $i -le $endPort; $i++) {
$PortList += $i
}
}
return $PortList
}
Các hàm scan port:
function Scan {
param (
[string[]]$PortList
)
foreach ($Port in $PortList) {
if (IsPortOpen $Port) {
Write-Output "Port $Port is open"
}
else {
Write-Output "Port $Port is closed"
}
}
}
function IsPortOpen {
param (
[string]$Port
)
$Socket = $null
if ($Protocol -eq 'tcp') {
$Socket = New-Object System.Net.Sockets.TcpClient
}
elseif ($Protocol -eq 'udp') {
$Socket = New-Object System.Net.Sockets.UdpClient
}
try {
$Socket.Connect($HostName, $Port)
$Socket.Close()
return $true
}
catch {
return $false
}
}
Gọi sử dụng các hàm trên:
$PortList = ParsePort
Scan $PortList
Câu lệnh thực thi:
PS C:\Users\Administrator\Desktop> .\PortScanner.ps1 -HostName localhost -Ports 130-140 -Protocol tcp
Kết quả là chỉ có port 135 được mở. Mà câu trả lời này lại không đúng.
Tham khảo walkthrough thì thấy ngoài test bằng TCP còn cần test bằng ICMP (ping). Sửa lại hàm IsPortOpen
sử dụng Test-NetConnection
như sau:
function IsPortOpen {
param (
[string]$Port
)
$Connection = Test-NetConnection -ComputerName $HostName -Port $Port
return $Connection.TcpTestSucceeded -or $Connection.PingSucceeded
}
Nhớ bỏ tham số $Protocol
.
Câu lệnh trở thành:
PS C:\Users\Administrator\Desktop> .\PortScanner.ps1 -HostName localhost -Ports 130-140
Kết quả là cả 11 port từ 130 đến 140 đều được mở.
Related
list
from outgoing([[TryHackMe - Hacking with PowerShell]])
sort file.ctime asc