توانایی دور زدن کنترل های پاورشِل یه مقوله مهم در دنیای امنیت به حساب میاد. این اتفاق می تونه یک تهدید جدی برای سیستم باشه، چون از این طریق کاربر می تونه کارها و خرابکارهای مختلفی روی سیستم انجام بده.
این دست اتفاقات را می توان با یک سری تنظیمات و فعال کردن یک سری بخش ها در سیستم های ویندوزی و در نهایت با پیگیری یک سری Event ID مثل Event ID 4688 در اکثر مواقع پیدا و از اونها جلوگیری کرد.
در اینگونه تهدیدات در نظر گرفتن ۲ اتفاق می تونه بسیار کمک کننده باشه:
اول: Execution Policy Bypass
سیاست های اجرایی که تنظیم می شوند می تونه توسط هرکسی که قصد خرابکاری داشته باشه دور بخوره. واسه چک کردن این اتفاق می تونیم روی موارد ذیل توی لاگ هامون تمرکز کنیم:
ExecutionPolicy bypass and/or
Ep bypass or –Exec bypass
ExecutionPolicy unrestricted
دوم: Profile Bypass
پروفایلی که برای تنظیم پاور شل ست شده تا وقتی که هر نشست (session) لانچ شد اونو کنترل کنه هم قابل دور خوردن هست. برای این قسمت هم می تونیم روی مورد ذیل توی لاگ هامون تمرکز کنیم:
noprofile or -nop
دستورات زیر معمولاْ توی این نوع رخدادهای خرابکارانه هست که می تونه توی فرم های مختلف باشه:
powershell.exe -executionpolicy bypass –noprofile –windowstyle hidden –file malicious.ps1
powershell.exe -NonInteractive -WindowStyle Hidden -Ep bypass –nop –File “malicious.ps1"
powershell.exe –e ZQBjAGgAbwAgACcAWQBvAHUAIABhAHIAZQAgAHAAdwBuAGUAZAAhACcA == (encoded)
در ادامه چندتا ایده برای شکار رفتار مشکوک پاور شل از لاگ ها با استفاده از اسپلانک که یک ابزار بسیار معروف و قوی توی تحلیل امنیتی و شکار تهدید به شمار میاد آورده شده. البته درسته که این مثال ها برای اسپلانک زده شده اما می توان با گرفتن ایده و منطق این مثال ها توی بقیه سیستم های مدیریت لاگ هم اونها را پیاده سازی کرد.
تو این قسمت ایده اینه که دنبال دور خوردن (bypass) های اجرایی باشیم. البته می تونه بهم ریخته یا همون obfuscate شده باشه که باز هم می شه با یه سری odd character و ticks پیداشون کرد:
index=windows source="WinEventLog:Security" (EventCode=4688) (powershell* AND -executionpolicy) OR (powershell* AND -ep) OR (powershell* AND bypass) OR (powershell* AND -noprofile) OR (powershell* AND -nop) NOT (“*\\some_expected_thing*”) | eval Message=split(Message,".") | eval Short_Message=mvindex(Message,0) | table _time, host, Account_Name, Process_Command_Line, New_Process_Name, New_Process_ID, Creator_Process_ID, Short_Message
این هم مثل بالایی عمل می کنه با این تفاوت که یه سری از اسم های بالایی حذف شدن و خب موارد تابلوتر را پیدا می کنه:
index=windows source="WinEventLog:Security" (EventCode=4688) (powershell* AND -ep) OR (powershell* AND -nop) NOT (“*\\some_expected_thing*”) | eval Message=split(Message,".") | eval Short_Message=mvindex(Message,0) | table _time, host, Account_Name, Process_Command_Line, New_Process_Name, New_Process_ID, Creator_Process_ID, Short_Message
توی این مثال تقریباْ کار قبلی را با استفاده از Event ID 4100 انجام میدیم:
index=powershell source="WinEventLog:Microsoft-Windows-PowerShell/Operational" (EventCode=4100) (-ep AND bypass) OR (-exp AND bypass) OR (-exec AND bypass) OR ("-nop") NOT (*something_normal*) | table host, ComputerName, User, Host_Version, PS_Version, Host_Application
ایده این مثال برای وقتی که یکسری ماژول برای فیلتر کردن ماژول هایی که می دونیم درست کار می کنند فعال می شوند :
index=powershell source="WinEventLog:Microsoft-Windows-PowerShell/Operational" EventCode=4104 NOT ("*Program Files\\SplunkUniversalForwarder\\etc\\apps*" OR "*SplunkUniversalForwarder\\bin\\splunk-powershell-common.ps1*" OR "*var\\log\\splunk\\splunk-powershell*" ) | eval Cmd_Length=len(Message) | where Cmd_Length > 1000 | table _time, host, Cmd_Length, Message
ایده این مثال برای وقتیه که از تیک یا یه سری کاراکتر خاص استفاده می شه. این کاراکترها معمولاْ توی obfuscate مورد استفاده قرار می گیرند.
index=windows LogName="Security" EventCode=4688 NOT ("*some_expected_thing*") | eval Orig_Command=Process_Command_Line | eval Clean_Command_Line = Process_Command_Line | eval Obfuscations=Process_Command_Line | rex field = Obfuscations mode = sed "s/[a-zA-Z0-9]//g" | rex field=Clean_Command_Line mode=sed "s/[']//g" | eval Tick_Count = mvcount(split(Obfuscations,"'"))-1 | eval Pct_Count = mvcount(split(Obfuscations,"%"))-1 | table _time host, Orig_Command, Clean_Command_Line, Obfuscations, Tick_Count, Pct_Count | where Tick_Count > 2
ایده این مثال هم برای وقتیه که از تیک یا یه سری کاراکتر خاص استفاده می شه. همونطور که توی قبلی گفتم این کاراکترها معمولاْ توی obfuscate مورد استفاده قرار می گیرند. توی این مثال این کار را با Event ID 400 انجام میدیم:
index=powershell LogName="Windows Powershell" EventCode=400 (Net.WebClient) | eval MessageA=split(Message,"Details:") | Eval Short_Message=mvindex(MessageA,1) | eval Clean_Host_Application=Host_Application | eval Obfuscations=Host_Application | rex field=Obfuscations mode=sed "s/[a-zA-Z0-9]//g" | rex field=Clean_Host_Application mode=sed "s/[']//g" | eval Tick_Count = mvcount(split(Obfuscations,"'"))-1 | eval Pct_Count = mvcount(split(Obfuscations,"%"))-1 | table _time, host, ComputerName, Host_Application, Clean_Host_Application, Obfuscations, Tick_Count, Pct_Count | where Tick_Count > 2
البته لازم به ذکر که نسخه های مختلف پاورشل مثل ۱، ۲ و ۳ با ۴ و ۵ یه مقداری متفاوت هستند و یه نکته دیگه اینکه برای این که بتونیم لاگ های این اتفاقاتی که برای پاورشل (Powershell) می افته را درست و درمون بگیریم یه سری تنظیمات نیازه که توی پست بعدی (که انشاالله تو همین نزدیکیا باشه، نریم واسه شیش ماه دیگه) به اونها هم اشاره می کنم.