analizând transcrierile PowerShell

de Raido Karro și Liisa Tallinn
28 mai 2020

chiar dacă nu utilizați PowerShell în mașinile Windows, adversarii și pen-testerii dvs. sunt. De ce să folosiți instrumente personalizate hax0r atunci când fiecare mașină Windows vine cu un mediu de scriptare încorporat? Powershell permite atacatorului să facă aproape orice, fără a lăsa urme pe discuri. Este o greșeală să nu iubești PowerShell ca atacator și o greșeală să nu iubești jurnalele PowerShell ca apărător.

Următorul este un tutorial de analiză și interogare folosind analizorul de jurnal gratuit al SpectX pentru a obține statistici generale, precum și informații specifice din jurnalele de transcriere PowerShell care sunt notoriu greu de analizat. Nu este nevoie să importați sau să ingerați fișierele din directorul lor de ieșire Curent – SpectX rulează interogări direct pe jurnalele raw. Crearea unei vizualizări curate din jurnalele brute durează doar câteva minute.

am încărcat un mic set de fișiere de transcriere în depozitul nostru public S3 – nu ezitați să rulați interogările de mai jos pe aceste date eșantion. Întrebările pe care le-am pus în interogări au ca scop explorarea liniei de bază și depistarea comportamentului anormal (potențial rău intenționat). Care au fost comenzile de top? Când au fost executate cele mai multe comenzi? Când au fugit pentru prima dată? Care au fost ieșirile de comandă care au apărut pe consolă la rularea comenzii – ceva neobișnuit? Cine sunt utilizatorii de top? Orice utilizatori care rulează comenzi care nu ar trebui să fie difuzate? Aplicații gazdă de top? Câte comenzi pe oră / zi / săptămână? Cum rămâne cu comenzile ascunse? Și așa mai departe-odată ce te obișnuiești cu interogările SpectX, întrebările de urmărire nu se opresc niciodată.

cuprins

despre Transcrieri
cum se activează înregistrarea transcrierii
formatul jurnalelor de transcriere
citirea și analizarea jurnalelor cu SpectX
cine? Ce? Când? Cum? – interogările

transcrierile știu totul… sau aproape 1258

există 3 tipuri de logare care pot fi activate pentru PowerShell: logare modul, bloc script și transcriere. Deoarece primele două pot fi văzute ca evenimente Windows, este adesea recomandat să citiți manual fișierele text de transcriere numai atunci când apare o problemă din monitorizarea primelor două. În același timp, Informațiile conținute în transcrieri sunt cele mai cuprinzătoare dintre cele trei, iar fișierele text plate sunt mult mai eficiente din punct de vedere al stocării decât evenimentele Windows produse de înregistrarea blocurilor de module și scripturi. De exemplu, rularea unui simplu write-host ‘hello world’ sau în acest caz ‘All you Need is Logs’ produce 22 de evenimente Windows din înregistrarea blocurilor de module și scripturi, dar aceleași informații plus ieșirea comenzii sunt, de asemenea, conectate la această transcriere PowerShell de 1kb:

**********************
Windows PowerShell transcript start
Start time: 20200521135800
Username: DESKTOP-7KL6SCQ\Loki
RunAs User: DESKTOP-7KL6SCQ\Loki
Configuration Name:
Machine: DESKTOP-7KL6SCQ (Microsoft Windows NT 10.0.18363.0)
Host Application: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Process ID: 5624
PSVersion: 5.1.18362.752
PSEdition: Desktop
PSCompatibleVersions: 1.0, 2.0, 3.0, 4.0, 5.0, 5.1.18362.752
BuildVersion: 10.0.18362.752
CLRVersion: 4.0.30319.42000
WSManStackVersion: 3.0
PSRemotingProtocolVersion: 2.3
SerializationVersion: 1.1.0.1
**********************
**********************
Command start time: 20200521135818
**********************
PS C:\Users\Loki> write-host "All You Need is Logs"
All You Need is Logs
**********************
Command start time: 20200521135821
**********************
PS C:\Users\Loki> exit
**********************
Windows PowerShell transcript end
End time: 20200521135821
**********************

problema este că jurnalele de transcriere au fost proiectate istoric în scopuri de depanare, adică mai degrabă pentru oameni decât pentru mașini. Conținutul lor este aproape liber și notoriu greu de analizat. Săpând în web, puteți găsi câteva încercări pe web de a ingera transcrieri într-un instrument de procesare a jurnalului, dar niciuna dintre ele nu realizează extragerea comenzilor, precum și ieșirile de comandă în câmpuri separate. Acest lucru este păcat, deoarece ieșirile de comandă sunt înregistrate doar la transcrieri și informații despre ceea ce s-a întâmplat de fapt ca urmare a comenzilor PS pot fi valoroase.
Introduceți SpectX. Sărind peste faza de ingestie și folosind blocuri de construcție în limba de parsare se poate extrage nu numai utilizator și gazdă/mașină câmpurile din prolog, dar, de asemenea, ori de pornire de comandă, comenzi și ieșiri. Deoarece parserul SpectX este aplicat fișierelor jurnal raw în timpul rulării interogării, înseamnă, de asemenea, că puteți depana, îmbunătăți și repara parserul cu fiecare interogare în cazul în care formatul jurnalului se schimbă. Și jurnalele de transcriere PowerShell sunt într-adevăr volatile.
când am început să scriem această postare, am crezut că transcrierile PowerShell sunt atotputernice și înregistrăm totul. Cu toate acestea, jucând cu comenzi și ieșiri, sa dovedit că există o excepție. Când rulați un script PS dintr-o adresă URL, transcrierea captează comanda (inclusiv adresa URL) și ieșirea, dar vă lasă complet orb în ceea ce privește conținutul scriptului sau comenzile rulate de script. De exemplu, pentru a afla ce a făcut acest script special dintr-o adresă url, va trebui să apelați la evenimente Windows produse de înregistrarea modulelor.

**********************
Windows PowerShell transcript start
Start time: 20200521141014
Username: DESKTOP-7KL6SCQ\Loki
RunAs User: DESKTOP-7KL6SCQ\Loki
Configuration Name:
Machine: DESKTOP-7KL6SCQ (Microsoft Windows NT 10.0.18363.0)
Host Application: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Process ID: 788
PSVersion: 5.1.18362.752
PSEdition: Desktop
PSCompatibleVersions: 1.0, 2.0, 3.0, 4.0, 5.0, 5.1.18362.752
BuildVersion: 10.0.18362.752
CLRVersion: 4.0.30319.42000
WSManStackVersion: 3.0
PSRemotingProtocolVersion: 2.3
SerializationVersion: 1.1.0.1
**********************
**********************
Command start time: 20200521141021
**********************
PS C:\Users\Loki> iex (New-Object "net.webclient").DownloadString("http://spectx.com/test.ps1")
All You Need is Logs!
**********************
Command start time: 20200521141023
**********************
PS C:\Users\Loki> exit
**********************
Windows PowerShell transcript end
End time: 20200521141023
**********************

cum să activați înregistrarea în jurnal a transcrierii PowerShell∞

1. Deschideți meniul Start și tastați ‘gpedit’ pentru a deschide o fereastră editor de Politici de grup Local

2. Navigați la șabloane de administrare > Componente Windows > Windows PowerShell

3. Faceți clic pe ‘Activați Transcrierea PowerShell’

4. Selectați ‘Enabled’ și specificați calea către directorul de ieșire. Important! Bifați caseta pentru a activa anteturile de invocare. Aceasta va înregistra fiecare comandă executată cu o oră de pornire a Comenzii.

5. Faceți clic pe OK
6. Deschideți o fereastră PowerShell pentru a testa dacă înregistrarea funcționează. Tastați o comandă, de ex. un simplu scrie-gazdă:’ tot ce ai nevoie este busteni ‘urmat de’exit’.

7. Verificați dacă directorul de ieșire specificat la Pasul 4 conține o transcriere cu marcajele de timp și acțiunile din Pasul 6.

pe termen lung, este o idee bună să centralizați colecția de transcrieri PowerShell pentru a le analiza la scară, de ex. verificați acest tutorial de @ dan_franciscus în blogul 4sysops.

transcriere log format

câteva cuvinte despre formatul jurnal și logica parser. Dacă preferați să faceți interogări și nu sunteți interesat de anatomia fișierelor jurnal și a analizorului, treceți la secțiunea următoare. Iată un eșantion dintr-un jurnal de transcriere PS V. 5.1 brut:

**********************
Windows PowerShell transcript start
Start time: 20171030223248
Username: WIN-FT17VBNL4B2\Administrator
RunAs User: WIN-FT17VBNL4B2\Administrator
Machine: WIN-FT17VBNL4B2 (Microsoft Windows NT 10.0.14393.0)
Host Application: C:\Windows\system32\WindowsPowerShell\v1.0\PowerShell.exe
Process ID: 4268
PSVersion: 5.1.14393.1770
PSEdition: Desktop
PSCompatibleVersions: 1.0, 2.0, 3.0, 4.0, 5.0, 5.1.14393.1770
BuildVersion: 10.0.14393.1770
CLRVersion: 4.0.30319.42000
WSManStackVersion: 3.0
PSRemotingProtocolVersion: 2.3
SerializationVersion: 1.1.0.1
**********************
**********************
Command start time: 20171030223255
**********************
PS C:\Users\Administrator> echo test
test
**********************
Command start time: 20171030223256
**********************
PS C:\Users\Administrator> exit
**********************
Windows PowerShell transcript end
End time: 20171030223256
**********************

un fișier de transcriere este creat cu fiecare sesiune PowerShell. Prima secțiune a transcrierii este un prolog care conține câmpuri specifice sesiunii, cum ar fi ora de începere a sesiunii, utilizatorul, versiunea PowerShell etc. Apoi, după o linie de asteriscuri, colecția de comenzi și ieșiri rulează în timpul acestei sesiuni. În cele din urmă, o secțiune epilog opțională la sfârșitul fișierului cu ora de încheiere a sesiunii, dar numai dacă sesiunea a fost terminată cu o comandă de ieșire (și nu prin închiderea ferestrei).

Numărul de comenzi între prolog și epilog variază. Acesta este motivul pentru care am adoptat o abordare în doi pași: mai întâi parsarea prologului, epilogului și comenzilor-ieșiri în bloc; apoi extragerea comenzilor și ieșirilor în câmpuri separate din stratul de interogare.

cum se citesc și se analizează transcrierile

SpectX citește datele direct din fișierele jurnal raw și le analizează în timpul rulării. În model, presupunem că ați activat anteturile de invocare, adică fiecare comandă PowerShell este înregistrată cu o oră de pornire a comenzii. Pentru a vizualiza transcrierile ca un tabel curat:

1. Descărcați și instalați gratuit SpectX.

2. Copiați această interogare de bază (Github) în fereastra de interogare

3. Modificați calea de pe linia 47 pentru a se potrivi cu directorul de ieșire al fișierelor jurnal de transcriere. Nu modificați variabilele de timp din cale – aceasta va permite filtrarea jurnalelor pe baza marcajelor de timp din calea fișierului. De exemplu, dacă calea către unul dintre fișierele dvs. de transcriere este

C:\Logs\powershell200405\PowerShell_transcript.WS01.5OoA7WLR.20200405152828.txt

atunci URI-ul din interogarea SpectX care indică toate fișierele jurnal cu o cale similară în C:\Logs\powershell dosarul ar fi:

file:/C:/Logs/powershell/$yyyy$$MM$$dd$/PowerShell_transcript.*.$yyyy$$MM$$dd$$HH$$mm$$ss$.txt

4. Modificați numărul de zile din scriptul de inițializare chiar la începutul scriptului (liniile 2-4) dacă doriți să aruncați o privire la jurnalele mai vechi/mai noi.

5. Apăsați run. Rezultatele ar trebui să arate similar cu acest lucru:

cine? Ce? Când? Cum? Interogările

atunci când pune întrebări din jurnalele, sunteți fie în căutarea pentru cunoscut sau necunoscut. Căutarea cunoscutului este ușoară-filtrați doar datele de care aveți nevoie. De exemplu:

| filter(lower(output) CONTAINS 'error') 

Vă oferă toate comenzile care conțin șirul ‘eroare’ în ieșire.

dacă doriți să vă uitați la o anumită perioadă de timp, modificați blocul de inițializare care conține marcajele de timp chiar la începutul scriptului de interogare de bază.

devine mai interesant dacă căutați necunoscutul și doriți să detaliați la ceva neobișnuit. Primul pas aici este să stabiliți linia de bază-obișnuitul și apoi să filtrați ca ceva care nu vă interesează. De exemplu, un truc elegant este să te uiți la momentul în care a fost executată prima comandă și apoi să te concentrezi pe comenzile care au fost văzute mai târziu decât altele (Vezi exemplu de interogare #2 de mai jos).
copiați și lipiți aceste interogări unul câte unul până la sfârșitul interogării de bază. Faceți dublu clic pe o înregistrare pentru a vedea tot conținutul acesteia, faceți clic dreapta pe un câmp pentru a aplica filtre (negative).

Insights în comenzi și ieșiri de comandă

1. Comenzi de Top

| select(cnt:count(*), command)
| group(@2)
| sort(cnt DESC)

2. Când a fost prima dată când a fost executată o comandă?

| select(min(commandStartTime),count(*),command,*)
| group(command)
| sort(min_commandStartTime)

3. Perechi de comandă-ieșire de top

| select(cnt:count(*), command,output)
| group(command,output)
| sort(cnt DESC)

4. Numărul de comenzi pe oră

| select(count(*),trunc_cmd_start:commandStartTime)
| group(trunc_cmd_start)

5. Comenzi care probabil au fost scrise manual, adică comenzi care încep cu ‘ c:\\’

| select(start_time, end_time, Username, RunAs_User, Machine, PID, PSVersion, commandText)
| filter(lower(commandText) contains 'c:\')

6. Analizați din nou câmpul de ieșire pentru a detecta adresele IP în commandText

| select(parse("DATA* IPADDR:ip DATA*", commandText), commandText, *)
| filter_out(ip IS NULL)

7. Găsiți șirul ‘descărcați’ în interiorul command_output chiar dacă este obfuscat (eliminați punctuația). De exemplu, dacă comanda invoke arăta astfel:

| select(deobf_commandText:lower(REPLACEALL(commandText, "" , '')) ) 
| filter(deobf_commandText contains 'download')

statistici generice

8. Câte sesiuni PowerShell pe oră?

| select(start_time:start_time,count(*))
| group(start_time)

9. TOP 100 nume de utilizator

| select(Username, cnt:count(*))
| group(@1)
| sort(cnt DESC)
| limit(100)

10. Câte înregistrări a generat un utilizator pe mașină?

| select(Username,Machine,cnt:count(*))
| group(@1,@2)
| limit(100)

11. Aplicații gazdă de top-lista aplicațiilor care rulează PowerShell, inclusiv parametrii suplimentari de comandă.

| select(cnt:count(*),Host_Application)
| group(@2)
| sort(cnt DESC)
| limit(100)

12. Top 100 de aplicații gazdă per utilizator

| select(Host_Application, Username, cnt:count(*))
| group(@1,@2)
| sort(cnt DESC)
| limit(100)

13. Aruncați o privire mai atentă la punctuația din comenzi. Comenzile care sunt aberante (numărul este mic) merită o privire detaliată.

| select(PUNCT(command, 64, false), cnt:count(*),uniq_commands:ARRAY_LEN(ARRAY_UNIQ(ARRAY_AGG(command))),commands_array:ARRAY_UNIQ(ARRAY_AGG(command)))
| group(@1)
| sort(cnt)
| limit(100)

concluzie

chiar dacă jurnalele de transcriere PowerShell nu sunt ușor de citit pentru mașini, informațiile pe care le conțin sunt cuprinzătoare și merită analizate. La urma urmei, PowerShell este un instrument pentru automatizarea și configurarea aproape a oricărei sarcini în Windows – este un ‘inel pentru a le conduce pe toate’. Aruncând o privire concentrată asupra statisticilor PowerShell, a comenzilor și a rezultatelor acestora este o modalitate bună de a vă asigura că inelul nu este în mâini greșite sau nu este folosit fără cusur.
mulțumiri
vă mulțumesc Taavi @ securitate clarificată. Transcrierile de la cursul Hunt The Hacker au fost un punct de plecare excelent pentru acest articol.

înapoi la articole

Lasă un răspuns

Adresa ta de email nu va fi publicată.