
Beacon Object File द्वारा Event Viewer deserialization UAC bypass का कार्यान्वयन
यह @orange_8361 द्वारा खोजे गए Event Viewer deserialization UAC बाईपास और CsEnox द्वारा तैयार किए गए POC का एक Beacon Object File कार्यान्वयन है।

x64 Win10/Win11 पर परीक्षित
यह UAC बाईपास निम्नलिखित क्रियाएँ करता है जिन्हें OPSEC के संदर्भ में ध्यान में रखा जाना चाहिए:
-1. %LOCALAPPDATA%\Microsoft\Event Viewer\RecentViews में एक बाइनरी फ़ाइल लिखता है
-2. mmc.exe / Event Viewer प्रारंभ करने के लिए ShellExecute() को कॉल करता है
--A. Event Viewer GUI में खुलेगा!
--B. Event Viewer cmd.exe को कॉल करेगा
---a. cmd.exe mmc.exe को बंद करने के लिए Taskkill को कॉल करेगा
---b. cmd.exe कभी-कभी खुले कंसोल विंडो पर एक त्रुटि संदेश प्रिंट करेगा ताकि उपयोगकर्ता को यह विश्वास दिलाया जा सके कि कुछ गलत नहीं है
---c. cmd.exe उपयोगकर्ता द्वारा दिए गए अन्य सभी कमांड निष्पादित करेगा
-3. बाइनरी फ़ाइल %LOCALAPPDATA%\Microsoft\Event Viewer\RecentViews से हटा दी जाती है
मूल प्रदर्शन और CsEnox के POC के बाद, एक प्रारंभिक पेलोड बनाने के लिए ysoserial का उपयोग किया गया:

ysoserial.exe -o raw -f BinaryFormatter -g TextFormattingRunProperties -c "taskkill /f /im mmc.exe >nul && echo Windows has Recovered from an Unexpected Error. You may Close this Window. &&" > cmd.bin
यह UAC बाईपास mmc.exe को आमंत्रित करके काम करता है, जो स्क्रीन पर खुलता है और इसे बंद करना आवश्यक है। दुर्भाग्य से, मुझे GUI को खोले बिना mmc.exe प्रारंभ करने का कोई तरीका नहीं मिला है; मैंने CreateProcess() और CREATE_NO_WINDOW फ़्लैग को देखा, हालाँकि CreateProcess() UAC के साथ अच्छी तरह से काम नहीं करता। इस विषय पर StackOverflow पोस्ट ने मुझे ShellExecuteA() API की ओर निर्देशित किया जिसमें SW_HIDE फ़्लैग (और अन्य) है, लेकिन यह सफल नहीं हुआ। स्क्रीन पर mmc.exe का फ्लैश होना अपरिहार्य लगता है।
Ysoserial cmd.exe /c को कॉल करता है, इसलिए इसका उपयोग mmc.exe को बंद करने के लिए taskkill को कॉल करने के लिए किया जाता है। && का उपयोग कमांड को एक साथ जोड़ने के लिए किया जाता है ताकि व्यवस्थापक के रूप में वांछित कार्रवाई निष्पादित की जा सके। परीक्षण में मैंने पाया कि कुछ मामलों में वह कार्रवाई mmc.exe द्वारा उत्पन्न cmd.exe प्रॉम्प्ट को खुला रखेगी; ऐसा तब होता है जब लोकल इंजेक्टर (सामान्य) पेलोड, जैसे डिफ़ॉल्ट Cobalt Strike निष्पादन योग्य पेलोड, कॉल किए जाते हैं। इसे संबोधित करने के लिए, मैंने taskkill कमांड से आउटपुट (जो पहले खुले cmd.exe पर प्रिंट होता था) को /dev/null पर भेजा, और स्क्रीन पर एक संदेश प्रिंट किया जो एक संभाले गए त्रुटि के बारे में है ताकि इस संदिग्ध व्यवहार से अशिक्षित उपयोगकर्ता को सचेत न किया जाए।
जो पेलोड एक प्रक्रिया को स्पॉन करते हैं, उसमें इंजेक्ट करते हैं, और फिर बाहर निकलते हैं, वे cmd.exe विंडो को खुला नहीं रखेंगे, और इस प्रकार संदेश अनावश्यक है। इसी प्रकार, जो कमांड निष्पादित होते हैं और बाहर निकलते हैं (जैसे net user Administrator newpassword) वे विंडो को खुला नहीं रखेंगे।
आप इस BOF के माध्यम से PowerShell एन्कोडेड कमांड निष्पादित कर सकते हैं:



taskkill कमांड और उपयोगकर्ता को संदेश ysoserial कमांड में बेक किए गए हैं। यदि आप इस व्यवहार को बदलना चाहते हैं, तो आपको अपना स्वयं का ysoserial कमांड चलाना होगा और नीचे दिए गए प्रदर्शन का पालन करना होगा कि कोड कैसे बनाया गया था।
एक कस्टम टूल का उपयोग करके, बाइनरी फ़ाइल को अंतर्ग्रहण किया गया और hex के रूप में मुद्रित किया गया:

इसे नोटपैड में कॉपी करके और hex में '&' खोजने से वांछित बाइट्स मिलते हैं (ध्यान दें कि इसके कई सेट हैं, हमें अंतिम की आवश्यकता है):

पेलोड को इन बाइट्स के तुरंत बाद दो भागों में विभाजित किया जाता है:

प्रत्येक भाग की लंबाई की गणना की जाती है और बाद के लिए नोट किया जाता है।
यहाँ चीजें जटिल हो जाती हैं।
सच कहूँ तो मैं डिसीरियलाइज़ेशन या ysoserial के बारे में ज्यादा नहीं जानता, लेकिन मैंने पाया कि पेलोड में बाइट्स का एक सेट होता है जो पेलोड के "महत्वपूर्ण" भाग की लंबाई को दर्शाता है, जिसमें उपयोगकर्ता द्वारा परिभाषित कमांड शामिल है। यह निम्नलिखित स्क्रीनशॉट में देखा जा सकता है जो ysoserial द्वारा बनाए गए दो अलग-अलग पेलोड के साइड-बाय-साइड hex डंप को दर्शाता है, जिनमें से प्रत्येक में निष्पादित करने के लिए एक अलग कमांड था:

जिन कारणों को मैं समझा नहीं सकता, ये बाइट्स पेलोड की लंबाई को बेस-128 में दर्शाती हैं; 0x05 को 128 से गुणा करने पर 640 मिलता है; इसे दूसरे बाइट (0xb0 या 0xd4) के मान में से 128 घटाकर जोड़ा जाता है; मैंने पाया कि जब दूसरा बाइट (0x05) रोल ओवर होता है (0x06), तो पहला बाइट 0x80 से शुरू होता है, जैसा कि 0x00 से शुरू होने की उम्मीद की जा सकती है।
इस टूल में उपयोग किया गया पेलोड इस प्रकार दिखता है:

सभी मानों को दशमलव में बदलने पर, गणित इस प्रकार दिखता है:
(6 x 128) + (180-128) = 820
फ़ाइल का आकार 1042 है; मैंने परीक्षण में पाया कि (इस गैजेट के साथ ysoserial से) फ़ाइल के आकार और बाइट्स के इस सेट में दर्शाई गई लंबाई के बीच हमेशा 222 बाइट का अंतर होता है। ये 222 बाइट पेलोड का "हेडर" प्रतीत होते हैं।
पेलोड के दोनों भागों को main.c में कॉपी किया जाता है, जहाँ मूल लंबाई 820 को एक चर के रूप में भी सेट किया जाता है। उपयोगकर्ता कमांड की लंबाई की गणना की जाती है, और इस मान को मूल 820 में जोड़ा जाता है (एक स्थान के लिए एक अतिरिक्त बाइट के अलावा जिसे डाला जाना चाहिए) ताकि अंतिम मान की गणना की जा सके जिसे बाइट्स के इस सेट में दर्शाया जाना चाहिए। दूसरे बाइट की गणना LenBytes को 128 से विभाजित करके की जाती है, और पहले बाइट की गणना LenBytes के शेषफल को ढूंढकर और 128 जोड़कर की जाती है (ताकि यह 0x80 से शुरू होने को समायोजित कर सके)।

एक बार ये बाइट सेट हो जाने के बाद, उन्हें Before बफ़र में उचित स्थान पर कॉपी किया जाता है ताकि पेलोड की लंबाई को सामग्री के अनुसार उचित मान पर सेट किया जा सके। फिर अंतिम बफ़र को इकट्ठा किया जाता है:

अंतिम पेलोड को डिस्क पर लिखा जाता है और इसे निष्पादित करने के लिए mmc.exe को कॉल किया जाता है। बाद में पेलोड को साफ किया जाता है।
x86_64-w64-mingw32-gcc -o EventViewerUAC.x64.o -Os -c main.c -DBOF
Ysoserial एक --rawcmd विकल्प प्रदान करता है जहाँ आप cmd.exe के अलावा एक अलग निष्पादन योग्य को आमंत्रित कर सकते हैं, हालाँकि आप इसे कोई तर्क प्रदान नहीं कर सकते। यह cmd.exe को कॉल किए बिना सीधे अपने पेलोड को आमंत्रित करने का द्वार खोलता है और इस प्रकार कंसोल विंडो को खुला नहीं छोड़ता; हालाँकि इस मामले में mmc.exe को बंद करने के लिए कुछ भी नहीं होगा। कोई अपने पेलोड को यह निर्धारित करने के लिए लिख सकता है कि पेलोड का मूल प्रक्रिया क्या है और यदि वह mmc.exe है, तो इस UAC बाईपास के बाद सफाई करने के लिए mmc.exe को मार दें। यह बहुत संभव है, हालाँकि मैंने ऐसा करने की जहमत नहीं उठाई क्योंकि यह कई UAC बाईपास में से एक है, और हर कोई इस तरह के कस्टम पेलोड नहीं बना रहा है। मैं अपने व्यक्तिगत रनर में इसे शामिल कर सकता हूँ।