
सिस्टम कॉल टैम्परिंग के साथ स्वच्छ इनडायरेक्ट सिस्टम कॉल।
SyscallRevenant स्वच्छ इनडायरेक्ट सिसकॉल करने की एक नई विधि है।
मुख्य घटक System Service Numbers (SSNs) और syscall निर्देश पतों को गतिशील रूप से हल करता है।
यह निष्पादन के दौरान ट्रैप फ़्लैग सक्षम करके किया जाता है।
द्वितीयक घटक syscall से पहले पैरामीटर प्रतिस्थापन के माध्यम से छेड़छाड़ है।
यह संयोजन बाद के सिसकॉल आह्वान के दौरान यूज़रलैंड हुक्स को बायपास करने के लिए डिज़ाइन किया गया है, साथ ही शुरू में प्रस्तुत पैरामीटर को प्रतिस्थापित करता है।
अस्वीकरण: इसका उद्देश्य केवल शैक्षिक उद्देश्यों और परीक्षण के लिए है। इसका उपयोग उन मशीनों पर न करें जिनका उपयोग करने की आपको अनुमति नहीं है। इसका उपयोग उन मशीनों का लाभ उठाने और उनसे संचार करने के लिए न करें जिनका उपयोग करने के लिए आपके पास प्राधिकरण नहीं है।
इनडायरेक्ट सिसकॉल विश्वसनीय यूज़रलैंड स्पेस में syscall निर्देशों को निष्पादित करने की एक विधि है।
यदि कोई उपयोगकर्ता syscall निर्देश पाता है, तो वे अप्रत्यक्ष रूप से उस पर जंप कर सकते हैं।
ट्रेसिंग सत्र के दौरान सक्षम एक इवेंट निर्देश के तुरंत बाद रिटर्न पता प्रकट कर सकता है।
यह Endpoint Detection & Response (EDR) यूज़रलैंड हुक्स को ध्यान में नहीं रखता है।
एक EDR ntdll.dll में हुक्स डाल सकता है, जिससे SSNs और syscall निर्देशों के लिए लुकअप प्रक्रिया अप्रचलित हो जाती है।
किसी हुक में प्रवेश करना स्वामी थ्रेड को लाभ पहुँचाएगा, दुर्भावनापूर्ण स्कोर नहीं बढ़ाएगा।
किसी फ़ंक्शन में प्रवेश को देखना और परिणामी ऑपरेशन को देखना अलग-अलग चीज़ें हैं।
RevenantSyscalls उस अंतराल की जाँच करता है।
निम्नलिखित अनुभाग परियोजना के दो मुख्य घटकों की रूपरेखा प्रस्तुत करते हैं।
पहला घटक प्रक्रिया द्वारा लोड किए गए ntdll.dll से फ़ंक्शन पते हल करता है।
यदि सिसकॉल जानकारी की आवश्यकता हो तो फिर ट्रैप वॉक किया जा सकता है।
दूसरा घटक सहेजी गई फ़ंक्शन जानकारी पर अप्रत्यक्ष जंप करता है।
सेगमेंट रजिस्टर से पढ़कर Process Environment Block (PEB) प्राप्त किया जा सकता है।
LoaderData PEB में एक फ़ील्ड है जिसमें प्रत्येक प्रक्रिया के साथ लोड किया गया डेटा होता है।
LoaderData में प्रत्येक प्रक्रिया के साथ लोड किए गए मॉड्यूल के बारे में जानकारी होती है।
मॉड्यूल नाम और बेस पते मॉड्यूल प्रविष्टियों में मौजूद होते हैं।
एक Dynamically Linked Library (DLL) की एक्सपोर्ट जानकारी उसके द्वारा निर्यात किए गए प्रतीकों का वर्णन करती है। एक्सपोर्ट मेटाडेटा निर्यात किए गए प्रतीकों को खोजने का समर्थन करता है। किसी फ़ंक्शन का इंडेक्स केवल नामों और नाम क्रमांकों पर लागू होता है। कम मेमोरी वाले वातावरण के लिए फ़ंक्शन नाम को हैश करना सबसे अच्छा है।
वेक्टर्ड एक्सेप्शन हैंडलर एक एक्सेप्शन हैंडलिंग तंत्र है जो किसी प्रक्रिया के भीतर कहीं से भी एक्सेप्शन पकड़ता है।
ट्रैप फ़्लैग सक्षम करने से निष्पादित अगले निर्देश पर EXCEPTION_SINGLE_STEP एक्सेप्शन होता है।
एक कस्टम वेक्टर्ड एक्सेप्शन हैंडलर RIP का निरीक्षण कर सकता है और syscall की जाँच कर सकता है।
बार-बार ट्रैप फ़्लैग रीसेट करके, syscall पता खोजा जाएगा और SSN सहेजा जाएगा।
सिसकॉल लुकअप
|
सिसकॉल निष्पादन
|
प्रत्येक सिसकॉल में प्रारंभिक सिसकॉल जानकारी लुकअप होता है; सिसकॉल जानकारी प्राप्त करने के लिए हुक्स में प्रवेश किया जाएगा। आगे बढ़ते हुए, सिसकॉल पर एक अप्रत्यक्ष जंप किया जाएगा। एक संबद्ध RIP स्पूफ़ होगा (मूल प्रवेश से)। पुनः प्रवेश के साथ, प्रारंभिक पैरामीटर में छेड़छाड़ की गई है।
Event Tracing for Windows (ETW) के दृष्टिकोण से, संभावित रूप से उत्सर्जित होने वाले इवेंट हैं: SysEnter, SysExit, और दोनों के लिए StackWalk।
यदि कोई EDR समान, तुलनीय इवेंट बनाता है, तो ये लगभग एक जैसे दिखेंगे।
एकमात्र अंतर नाटकीय रूप से भिन्न Query Performance Counter (QPC) टाइम स्टैम्प में होंगे।
src/AsmRevenant.asm के साथ आगे बढ़ें REAL_RTN: DQ 0
FAKE_RTN: DQ 0
; If a syscall information lookup is in progress, the
; initial entry return address needs to be preserved.
MOV RAX, QWORD PTR [RSP]
MOV QWORD PTR [FAKE_RTN], RAX
; Once the re-entry is made, the real return is saved,
; and the current is spoofed with initial return.
MOV RAX, QWORD PTR [RSP]
MOV QWORD PTR [REAL_RTN], RAX
MOV RAX, QWORD PTR [FAKE_RTN]
MOV QWORD PTR [RSP], RAX
src/Revenant.c के साथ आगे बढ़ेंLONG VectoredExceptionHandler(EXCEPTION_POINTERS *BreakPoint) {
...
// If a syscall information lookup is being made, the
// syscall instruction address is saved, the SSN is
// saved, and the return is rerouted.
if (LookupInProgress && *(USHORT*)BreakPoint->Address == 0x050F) {
SyscallInstruction = BreakPoint->Address;
SyscallSSN = BreakPoint->Context->Rax;
BreakPoint->Context->Rip = SyscallExit;
}
// When re-entered, if the previous instruction was
// a syscall, reset return address, and exit.
if (!LookupInProgress && *(USHORT*)(BreakPoint->Address - 2) == 0x050F) {
*(VOID**)BreakPoint->Context->Rsp = REAL_RTN;
BreakPoint->Context->Rip = SyscallExit;
}
...
}