[ETC][Pawnyable] Tools and Setups

pawnyable.cafe์—์„œ ์ปค๋„ ํ•ดํ‚น์„ ๊ณต๋ถ€ํ•˜๋‹ค ๋ณด๋ฉด

  1. ์ž์ฃผ ์“ฐ๋Š” ์„ค์ • ํŒŒ์ผ / ์Šคํฌ๋ฆฝํŠธ๋“ค
  2. ์ž์ฃผ ์“ฐ๋Š” ์ฝ”๋“œ ํ…œํ”Œ๋ฆฟ๋“ฏ
  3. ์ž์ฃผ ์“ฐ๋Š” ํˆด๋“ค ๊ทธ๋Ÿฐ๋ฐ ์ด์— ๋Œ€ํ•œ ์„ค๋ช…์ด ์ข€ ๋ถ€์กฑํ•œ ๊ฒƒ ๊ฐ™์•„์„œ ๋ณด์ถฉ ์„ค๋ช…์„ ๋‚จ๊ธฐ๊ณ , ๋˜ ์ด๋“ค์— ๋ณด๋‹ค ์‰ฝ๊ฒŒ ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด ๋‚ด๊ฐ€ ์“ฐ๋Š” alias์™€ ํŒ๋“ค์„ ์ •๋ฆฌํ•ด ๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

์ด์— ์•ž์„œ ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • LKXX
    • qemu/
      • root/
        • exploit.c (์ง์ ‘ ๋งŒ๋“ฆ)
      • bzImage
      • rootfs.cpio
      • run.sh
    • src/
      • vuln.c
      • vuln.ko

(์ฒ˜์Œ ๋ฐ›์œผ๋ฉด rootfs.cpio๋งŒ ์žˆ์„ ๊ฒƒ์ด๋‹ค. mkdir root; cd root; cpio -idv < ../rootfs.cpio๋ฅผ ํ†ตํ•ด cpio๋ฅผ ํ’€์–ด์ฃผ์ž)

1. ์Šคํฌ๋ฆฝํŠธ / ์„ค์ • ํŒŒ์ผ

1-1. run.sh

qemu๋ฅผ ์‹œ์ž‘ํ•˜๊ธฐ ์œ„ํ•ด ์“ฐ์ด๋Š” ์Šคํฌ๋ฆฝํŠธ์ด๋‹ค.

1-1-1. qemu ์˜ต์…˜

์ฒ˜์Œ ๋ฐ›์•„ ์—ด์–ด๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์„ ๊ฒƒ์ด๋‹ค.

#!/bin/sh

qemu-system-x86_64 \
    -m 64M \
    -nographic \
    -kernel bzImage \
    -append "console=ttyS0 loglevel=3 oops=panic panic=-1" \
    -no-reboot \
    -cpu kvm64,+smep\
    -smp 1 \
    -monitor /dev/null \
    -initrd rootfs.cpio \
    -net nic,model=virtio \
    -net user

์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ์˜ต์…˜์€ -append ์˜ต์…˜๊ณผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๋Š” -gdb ์˜ต์…˜์ด๋‹ค.

  • -append ์˜ต์…˜์€ ์ปค๋„์— ๋‹ค์–‘ํ•œ ์ธ์ˆ˜๋ฅผ ์ฃผ์–ด ์‹คํ–‰์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ์˜ต์…˜์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด nopti ์˜ต์…˜์„ ์ฃผ๋ฉด KPTI๊ฐ€ ๋น„ํ™œ์„ฑํ™”๋˜๋ฉฐ, nokaslr ์˜ต์…˜์„ ์ฃผ๋ฉด KASLR์ด ๋น„ํ™œ์„ฑํ™”๋œ๋‹ค.
  • -gdb ์˜ต์…˜์€ ์ปค๋„์— GDB๋ฅผ remote๋กœ ๋ถ™์—ฌ ๋””๋ฒ„๊น…์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ํ•œ๋‹ค. -gdb tcp::6626์ฒ˜๋Ÿผ ๊ตฌ์„ฑํ•ด ์ปค๋„์„ ์‹คํ–‰ํ•˜๋ฉด gdb์—์„œ target remote 6626 ๋ช…๋ น์„ ์ด์šฉํ•ด ์ปค๋„ ๋””๋ฒ„๊น…์„ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

1-1-2. ์ž๋™ ์ปดํŒŒ์ผ / ์•„์นด์ด๋น™

๋‚˜๋Š” ๋ณดํ†ต root ๋””๋ ‰ํ† ๋ฆฌ ์•ˆ์— exploit.c๋ฅผ ๋งŒ๋“ค๊ณ  ์ปดํŒŒ์ผํ•œ ํ›„, ์ „์ฒด๋ฅผ cpio๋กœ ์•„์นด์ด๋น™ํ•ด ํŒŒ์ผ์‹œ์Šคํ…œ์„ ๊ตฌ์„ฑํ•˜๋Š” ํŽธ์ด๋‹ค. ๋”ฐ๋ผ์„œ ๋งค ์‹คํ–‰์‹œ๋งˆ๋‹ค exploit.c๋ฅผ ๋‹ค์‹œ ์ปดํŒŒ์ผํ•˜๊ณ  ์•„์นด์ด๋น™ํ•˜๋Š” ๊ณผ์ •์ด ํ•„์š”ํ•ด run.sh ์•ž ๋ถ€๋ถ„์— ๋‹ค์Œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

#!/bin/sh

cd root
# ๋ฏธ๋ฆฌ ์ปดํŒŒ์ผํ•ด๋’€๋˜ ํŒŒ์ผ๋“ค์„ ์‚ญ์ œํ•จ
rm exploit 
rm test

# ๋‹ค์‹œ ์ปดํŒŒ์ผํ•จ
musl-gcc -o exploit exploit.c -static
musl-gcc -o test test.c -static

# cpio๋กœ ์•„์นด์ด๋น™ํ•ด์„œ ํŒŒ์ผ์‹œ์Šคํ…œ์„ ๊ตฌ์„ฑํ•จ
find . -print0 | cpio -o --format=newc --null --owner=root > ../rootfs_updated.cpio
cd ..

qemu-system-x86_64 \
    ...
    -initrd rootfs_updated.cpio \   # ์—ฌ๊ธฐ๊ฐ€ ๋ฐ”๋€œ!
    ...

์ „์ฒด ์Šคํฌ๋ฆฝํŠธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

ํŽผ์น˜๊ธฐ/์ ‘๊ธฐ
#!/bin/sh

cd root
rm exploit
rm test

musl-gcc -o exploit exploit.c -static
musl-gcc -o test test.c -static

find . -print0 | cpio -o --format=newc --null --owner=root > ../rootfs_updated.cpio
cd ..

qemu-system-x86_64 \
    -m 64M \
    -nographic \
    -kernel bzImage \
    -append "console=ttyS0 loglevel=3 oops=panic panic=-1" \
    -no-reboot \
    -cpu kvm64,+smep \
    -smp 1 \
    -monitor /dev/null \
    -initrd rootfs_updated.cpio \
    -net nic,model=virtio \
    -net user \
    -gdb tcp::6626

์ˆ˜์ •ํ•  ์ผ๋„ ๋งŽ๊ณ  ์‹คํ–‰ํ•  ์ผ๋„ ๋งŽ์•„์„œ ๋‚˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ alias๋ฅผ ์ง€์ •ํ•ด๋‘๊ณ  ์‚ฌ์šฉํ•˜๋Š” ํŽธ์ด๋‹ค.

vimsh='vim run.sh'
runsh=./run.sh

1-2. S99pawnyable

init ์Šคํฌ๋ฆฝํŠธ ์ค‘ ํ•˜๋‚˜๋กœ, ๋ถ€ํŒ… ํ›„ ์‰˜์„ ๋งŒ๋“ค์–ด์ฃผ๊ณ  ๊ฐ์ข… ๋ณด์•ˆ ์˜ต์…˜๋“ค์„ ์„ค์ •ํ•˜๋Š” ํŒŒ์ผ์ด๋‹ค. ์•„๋งˆ ์ด๋ ‡๊ฒŒ ๋˜์–ด์žˆ์„ ๊ฒƒ์ด๋‹ค.

#!/bin/sh

##
## Setup
##
mdev -s
mount -t proc none /proc
mkdir -p /dev/pts
mount -vt devpts -o gid=4,mode=620 none /dev/pts
chmod 666 /dev/ptmx
stty -opost
echo 2 > /proc/sys/kernel/kptr_restrict       # (1)
echo 1 > /proc/sys/kernel/dmesg_restrict      # (2)

##
## Install driver
##
insmod /root/vuln.ko
mknod -m 666 /dev/holstein c `grep holstein /proc/devices | awk '{print $1;}'` 0

##
## User shell
##
echo -e "\nBoot took $(cut -d' ' -f1 /proc/uptime) seconds\n"
echo "[ Holstein v1 (LK01) - Pawnyable ]"
setsid cttyhack setuidgid 1337 sh            # (3)

##
## Cleanup
##
umount /proc
poweroff -d 0 -f

์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • (1) KADR (Kernel Address Display Restriction) ๊ด€๋ จ ๋‚ด์šฉ์ด๋‹ค.
    ์‹ค์ œ๋กœ ์ด๋ฅผ ์ฃผ์„์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๊ณ  ์ปค๋„์„ ๋ถ€ํŒ…ํ•œ ํ›„ /proc/kallsyms๋ฅผ ์ฝ์–ด ๋ณด๋ฉด ์ฃผ์†Œ๊ฐ€ ํ•˜๋‚˜๋„ ๋‚˜์˜ค์ง€ ์•Š๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ฃผ์„์ฒ˜๋ฆฌํ•ด๋‘์ž.
  • (2) dmesg๋ฅผ ๋ณผ ์ˆ˜ ์—†๋„๋ก ํ•˜๋Š” ์˜ต์…˜์ด๋‹ค. ์ด๊ฒƒ๋„ ๋””๋ฒ„๊น…ํ•  ๋•Œ ๋ฐฉํ•ด๊ฐ€ ๋˜๋ฏ€๋กœ ์ฃผ์„์ฒ˜๋ฆฌํ•ด๋‘์ž.
  • (3) setuidgid๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž์˜ uid์™€ gid๋ฅผ ์ง€์ •ํ•œ๋‹ค. ์ด๋•Œ 1337 ๋Œ€์‹  0์„ ์จ๋‘๋ฉด ๋ถ€ํŒ… ํ›„ ๋ฃจํŠธ ์‚ฌ์šฉ์ž๋กœ ์‰˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋””๋ฒ„๊น…ํ•  ๋•Œ๋Š” 0์œผ๋กœ ์„ค์ •ํ•˜์ž.

๋””๋ฒ„๊น…์„ ํ•˜๋‹ค ๋ณด๋ฉด (3)๋ฒˆ์„ ์ •๋ง ์ž์ฃผ ์„ค์ •ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ˆ˜์ •ํ•  ์ผ์ด ๋งŽ์€ ํŒŒ์ผ์ด๋‹ค. ๊ทธ๋ž˜์„œ ๋‚˜๋Š” ์ด ํŒŒ์ผ๋„ run.sh์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ alias๋ฅผ ์ง€์ •ํ•ด๋‘๊ณ  ์“ฐ๋Š” ํŽธ์ด๋‹ค.

vims99='vim root/etc/init.d/S99pawnyable'

2. ์ฝ”๋“œ ํ…œํ”Œ๋ฆฟ

์ด์— ๋Œ€ํ•œ ์„ค๋ช…์€ Kernel Exploit Tech์— ๋‚˜์™€ ์žˆ๋‹ค.

2-1. save_state()

static void save_state() {
    asm(
        "movq %%cs, %0\n"
        "movq %%ss, %1\n"
        "movq %%rsp, %2\n"
        "pushfq\n"
        "popq %3\n"
        : "=r"(user_cs), "=r"(user_ss), "=r"(user_rsp), "=r"(user_rflags)
        :
        : "memory");
}

2-2. win()

static void win() {
    char *argv[] = { "/bin/sh", NULL };
    char *envp[] = { NULL };
    puts("[+] win!");
    execve("/bin/sh", argv, envp);
}

2-3. ROP

p = (unsigned long *)&buf[0x100];
*p++ = 0xdeadbeef;
*p++ = pop_rdi_ret;
*p++ = 0;
*p++ = prepare_kernel_cred;
*p++ = pop_rcx_ret;
*p++ = 0;
*p++ = mov_rdi_rax_rep_movsq_ret;
*p++ = commit_creds;
*p++ = swapgs_restore_regs_and_return_to_usermode;
*p++ = 0xdeadbeef;
*p++ = 0xcafebebe;
*p++ = (unsigned long)&win;
*p++ = user_cs;
*p++ = user_rflags;
*p++ = user_rsp;
*p++ = user_ss;

2-4. Consts

#define koffset                                     

#define prepare_kernel_cred                         (kbase + )
#define commit_creds                                (kbase + )
#define swapgs_restore_regs_and_return_to_usermode  (kbase + )

#define pop_rdi_ret                                 (kbase + )
#define pop_rcx_ret                                 (kbase + )
#define mov_rdi_rax_rep_movsq_ret                   (kbase + )

3. ์ž์ฃผ ์“ฐ๋Š” ํˆด

3-1. extract-vmlinux

bzImage์—์„œ vmlinux๋ฅผ ๋ฝ‘์•„๋‚ด๊ธฐ ์œ„ํ•ด ์“ด๋‹ค. ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ROP gadget์„ ์ฐพ๋Š” ๊ณผ์ •์—์„œ vmlinux ํŒŒ์ผ์ด ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฑฐ์˜ ํ•„์ˆ˜์ด๋‹ค.

wget -O https://raw.githubusercontent.com/torvalds/linux/master/scripts/extract-vmlinux
./extract-vmlinux bzImage > vmlinux

3-2. ROPgadget

ROP ๊ฐ€์ ฏ์„ ์ฐพ๋Š” ๋ฐ ์žˆ์–ด์„œ ์ตœ๊ณ ์˜ ํˆด์ด๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ปค๋„ ์ด๋ฏธ์ง€๋Š” ๋„ˆ๋ฌด ์ปค์„œ ํ•œ ๋ฒˆ ์ฐพ๋Š” ๋ฐ ์‹œ๊ฐ„์ด ๋งŽ์ด ๊ฑธ๋ฆฌ๋ฏ€๋กœ ๊ฒฐ๊ณผ๋ฅผ ํŒŒ์ผ๋กœ ์ €์žฅํ•ด ๋’€๋‹ค ํ•„์š”ํ•  ๋•Œ cat์„ ํ†ตํ•ด ์ฐพ๋Š” ํŽธ์ด ์ข‹๋‹ค.

ROPgadget --binary vmlinux > gadgets.txt
cat gadgets.txt | grep ~~~

3-3. offsetcalc.py

์˜คํ”„์…‹์„ ์กฐ๊ธˆ ๋” ํŽธํ•˜๊ฒŒ ๊ณ„์‚ฐํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์—ˆ๋‹ค. KASLR์ด ๊บผ์ง„ ์ƒํ™ฉ์—์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

#!/usr/bin/python3
import sys

textbase = 0xffffffff81000000

if sys.argv[1] == "i":
    print(hex(int(sys.argv[2], 16) + textbase))
    exit(0)

target = int(sys.argv[1], 16)

print(hex(target - textbase))
# ์˜คํ”„์…‹ ๊ณ„์‚ฐ
~$ ./offsetcalc.py 0xffffffff811f32f2
0x1f32f2

# ์˜คํ”„์…‹์œผ๋กœ๋ถ€ํ„ฐ ์ฃผ์†Œ ๊ณ„์‚ฐ
~$ ./offsetcalc.py i 0x1f32f2
0xffffffff811f32f2

Categories:

Updated:

Leave a comment