Cet article propose quelques fonctions utiles à avoir sous le coude en Powershell.
Powershell est un "langage" devenu incontournable dans l’administration des systèmes d’exploitation Microsoft Windows.
Très riche en fonctionnalités; il permet "assez aisément" de fouiller dans les classes WMI, de parcourir facilement la base de registre ou encore d’interroger les magasins de certificats SSL.
Couplé à des modules, il permet la manipulation d’objets faisant interface avec l’annuaire Active Directory, avec Hyper-V ou encore avec VSphere grâce à l’extension PowerCLI.
0x01. PRESENTATION
Les fonctions ci-dessous sont écrite avec la logique Powershell: Verb-Object. Elles seront catégories par rapport à leurs actions et leurs portées, exemple: lister les services sera une fonction système, calculer un SHA1 une opération sur les fichiers et récupérer le résultat d’une page Web ... une action sur le Web.
Ecrire un bloc d’aide en Powershell se fait ainsi:
<# .SYNOPSIS Une description succinte en une seule ligne. .DESCRIPTION Une description plus complète de la fonction, de ces actions et de son périmètre. Peut être un bloc de texte. .PARAMETER Argument1 Donne le nom de l'argument et expliquer son utilité. .PARAMETER Argument2 Les arguments peuvent être listés distinctements. .EXAMPLE Un ou plusieurs examples. Inutile de chercher à être exhaustif. #>
La liste des fonctions qui seront abordées :
Fichiers : Get-MD5 Fichiers : Get-SHA1 Système : Get-PFX Système : Get-UUID Système : Get-Clipboard Système : Eject-USBKey Système : Get-FileVersion Traitement : Convert-StrToHex Réseau : Get-SvcName Réseau : Test-TCPPort Réseau : Test-ICMP Web : Get-HTTPContent Web : Flood-HTTPServer
0x02. Fichiers : Get-MD5
Function Get-MD5() { <# .SYNOPSIS Calcul le hash MD5 d'une chaine ou d'un bloc de donnée .PARAMETER Data Le bloc de donnée en entrée .EXAMPLE Get-MD5 "passw0rd" #> Param( [String] $Data ) $StringBuilder = New-Object System.Text.StringBuilder [System.Security.Cryptography.HashAlgorithm]::Create("MD5").ComputeHash([System.Text.Encoding]::UTF8.GetBytes($Data))|%{ [Void]$StringBuilder.Append($_.ToString("x2")) } Return $StringBuilder.ToString() }
0x03. Fichiers : Get-SHA1
Function Get-SHA1() { <# .SYNOPSIS Calcul le hash SHA1 d'une chaine ou d'un bloc de donnée .PARAMETER Data Le bloc de donnée en entrée .EXAMPLE Get-SHA1 "passw0rd" #> Param( [String] $Data ) $StringBuilder = New-Object System.Text.StringBuilder [System.Security.Cryptography.HashAlgorithm]::Create("SHA1").ComputeHash([System.Text.Encoding]::UTF8.GetBytes($Data))|%{ [Void]$StringBuilder.Append($_.ToString("x2")) } Return $StringBuilder.ToString() }
0x04. Système : Get-PFX
Function Get-PFX() { <# .SYNOPSIS Obtient la liste des informations personnelles d'échanges (personal information exchange) de l'utilisateur courant .EXAMPLE Get-PFX #> $Keys = Get-Item CERT:CurrentUserMy $Ret = @{} ForEach( $Key in $Keys ) { if( $Key.HasPrivateKey ) { $Res = ($Key).Subject -Split "=" $Ret += $Res[1] } } return $Ret; }
0x05. Système : Get-UUID
function Get-UUID() { <# .SYNOPSIS Obtient l'identifiant unique matériel (UUID) au format de la RFC-4122. Ne demande aucun argument. .EXAMPLE Get-UUID #> $UUID = Get-WmiObject -Class Win32_ComputerSystemProduct|Select-Object UUID return $UUID }
0x06. Système : Get-Clipboard
function Get-ClipboardText() { <# .SYNOPSIS Obtient le contenu du "presse-papiers" Windows (clipboard). Ne demande aucun argument. .EXAMPLE Get-ClipboardText #> Add-Type -AssemblyName System.Windows.Forms $tb = New-Object System.Windows.Forms.TextBox $tb.Multiline = $true $tb.Paste() # Affiche le résultat récupéré return $tb.Text }
0x07. Système : Get-FileVersion
function Get-FileVersion { param([String] $filename) $ComputerName=$env:ComputerName $filename = "c:windowssystem32macromedlashlash*.ocx" $file = Get-Item $filename $strCurrVersion = $file.versionInfo.fileversion -replace ",","." return $strCurrVersion }
0x08. Traitement : Convert-StrToHex
function Convert-StrToHex($Source) { <# .SYNOPSIS Convertit une chaine en son équivalent hexadécimal. .DESCRIPTION 'Hello World !' -> 'Hello World !' .EXAMPLE Convert-StrToHex('Hello World !') #> $Encode = new-object "System.Text.UTF8Encoding" $bytearray = $Encode.GetBytes($Source) $res = "x" Foreach ($i in $bytearray) { $res = $res + $i.ToString("x").PadLeft(2,"0") + "x" } $res = $res.Substring(0,$res.Length - 1) return $res }
0x09. Réseau : Get-SvcName
Function Get-SvcName($Port) { <# .SYNOPSIS Récupère le nom du port s'il est présent dans le fichiers etc/services de Windows .PARAMETER Port Le numéro de port .EXAMPLE TCPPort-SvcName (445) #> Try { $svc = (((Get-Content c:windowssystem32driverstcservices) -match " $Port/" -split("/"))[0] -split(" "))[0] } Catch { $svc = "" } return( $svc ) }
0x010. Réseau : Test-TCPPort
Function Test-TCPPort() { <# .SYNOPSIS Tente une connexion sur un port distant sur le protocol TCP .PARAMETER Targets Une adresse IP ou une liste d'adresse .PARAMETER Ports Un numéro de port ou une liste de ports .EXAMPLE TCPPort-Test ("127.0.0.1") (33685) TCPPort-Test ("127.0.0.1") (3389,445,80) TCPPort-Test ("127.0.0.1","127.1.2.3","127.2.2.2") (3389,445,80,135) TCPPort-Test (Get-Content "serveurs.lst") (Get-Content "ports.lst") #> param([Array]$Targets, [Array]$Ports) $results = @{} foreach( $Target in $Targets ) { $results[$Target] = @{} foreach( $Port in $Ports ) { $sock = New-Object Net.Sockets.TcpClient try { $sock.Connect($Target,$Port) $sock.Close() $state = "open" } catch { $state = "closed" } $results[$Target][$Port] = @{} $results[$Target][$Port]["state"]= $state try { # Récupère le nom du service, si la fonction # Get-SvcName est disponible $results[$Target][$Port]["name"]= Get-SvcName $Port } catch { ; } } } return($results) }
0x011. Réseau : Test-ICMP
Function Test-ICMP($Target) { <# .SYNOPSIS Envoie une requête ICMP .PARAMETER Target Une adresse IP .EXAMPLE Test-ICMP ("127.0.0.1") .LINK https://msdn.microsoft.com/en-us/library/aa394350(v=vs.85).aspx #> $Res = Get-WmiObject Win32_PingStatus -f "Address='$Target'" switch($Res.StatusCode) { 0 { $Reason="Success" } 11001 { $Reason="Buffer Too Small" } 11002 { $Reason="Destination Net Unreachable" } 11003 { $Reason="Destination Host Unreachable" } 11004 { $Reason="Destination Protocol Unreachable" } 11005 { $Reason="Destination Port Unreachable" } 11006 { $Reason="No Resources" } 11007 { $Reason="Bad Option" } 11008 { $Reason="Hardware Error" } 11009 { $Reason="Packet Too Big" } 11010 { $Reason="Request Timed Out" } 11011 { $Reason="Bad Request" } 11012 { $Reason="Bad Route" } 11013 { $Reason="TimeToLive Expired Transit" } 11014 { $Reason="TimeToLive Expired Reassembly" } 11015 { $Reason="Parameter Problem" } 11016 { $Reason="Source Quench" } 11017 { $Reason="Option Too Big" } 11018 { $Reason="Bad Destination" } 11032 { $Reason="Negotiating IPSEC" } 11050 { $Reason="General Failure" } } return( ($Res.StatusCode,$Reason) ) }
0x012. Web : Get-HTTPContent
function Send-HTTPRequest($URL,$file) { <# .SYNOPSIS Envoie une requête HTTP et prends en charge la méthode (GET, POST) et les proxy .DESCRIPTION Compatible Powershell 2.0 .PARAMETER URL L'URL de destination .EXAMPLE Send-HTTPRequest "http://secureinfo.free.fr/ip.php" "GET" "http://192.168.1.3:3128/" "ip-externe.txt" Send-HTTPRequest -URL "http://secureinfo.free.fr/ip.php" -HTTPVerb "GET" -Proxy "http://192.168.1.3:3128/" -Content "ip-externe.txt" $HTML = Send-HTTPRequest "http://secureinfo.free.fr/s.php?s=éopç-test-avec-accents" "GET" $Txt = Get-Content "u: est.txt" $HTML = Send-HTTPRequest "http://secureinfo.free.fr/form.php" "POST" "filename=$Txt" #> [CmdletBinding()] Param( [Parameter(Mandatory=$True,Position=1)] [string] $URL, [Parameter(Mandatory=$True,Position=2)] [string] $HTTPVerb, [Parameter(Mandatory=$False,Position=3)] [string] $Proxy, [Parameter(Mandatory=$False,Position=4)] [string] $Content ) $webRequest = [System.Net.WebRequest]::Create($URL) $encodedContent = [System.Text.Encoding]::UTF8.GetBytes($content) $webRequest.Method = $HTTPVerb if( $proxy.Length > "http://".Length ) { $webRequst.Proxy = $proxy } if($encodedContent.length -gt 0) { $webRequest.ContentLength = $encodedContent.length $requestStream = $webRequest.GetRequestStream() $requestStream.Write($encodedContent, 0, $encodedContent.length) $requestStream.Close() } [System.Net.WebResponse] $resp = $webRequest.GetResponse(); if($resp -ne $null) { $Stream = $resp.GetResponseStream(); [System.IO.StreamReader] $Handle = New-Object System.IO.StreamReader -argumentList $Stream; [string] $Result = $Handle.ReadToEnd(); } return $Result }
0x013. Web : Flood-HTTPServer
function Flood-HTTPServer($url) { <# .SYNOPSIS Envoie des requêtes HTTP en continue .PARAMETER URL L'URL de destination .EXAMPLE Flood-HTTPServer ("http://secureinfo.free.fr/floodme.php") #> $objWebRq = [System.Net.WebRequest]::Create($url) while( 1 ) { $objWebRq.GetRequestStream() } }
=> Écrit par : Nicolas, le 04 juillet 2017