์ค๋์ pwnable์ ๋ง์ด ๋์ค๋ mmap ํจ์์ ๋ค๋ค๋ณด๋๋ก ํ๊ฒ ๋ค.
mmap์ด ๋ฌด์์ด๊ณ ์ ์ฐ๋์ง?
์ผ๋จ mmap์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ด๋ค ํ์ผ ํน์ ๋๋ฐ์ด์ค์ ๋์์ํค๋ ํจ์์ด๋ค.
๊ทธ๋ ๋ค๋ฉด "๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ์ผ๋ก ๋์์ํจ๋ค๋ ๊ฒ"์ด ๋ฌด์จ ๋ป์ด๊ณ "์" ๊ทธ๋์ผ๋ง ํ ๊น? ๐ค
์ปดํจํฐ ํ๋ก์ธ์ค์์ ๊ฐ ํ๋ก์ธ์ค๋ ๋ค๋ฅธ ํ๋ก์ธ์ค์ ๋ถ๋ฆฌ๋ ์ฃผ์๋ฅผ ๊ฐ์ง๊ณ ์์ด ์๋ก ๊ฒน์น์ง ์๋๋ค. ์ฆ ํ๋ก์ธ์ค ๋ฉ๋ชจ๋ฆฌ๋ ์๋ก ์ค๋ณต๋์ง ์๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ํ๋ก์ธ์ค ๊ฐ ๋ฐ์ดํฐ ๊ณต์ ๊ฐ ์ด๋ ต๋ค.
๋ฌผ๋ก ์ด๋ ํ๋ก์ธ์ค ์์ ๋ฐ์ดํฐ๋ฅผ ๋ณดํธํ๊ธฐ์๋ ์ข์ผ๋.. ์ ๋ฐ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ๊ณ ์ถ์ ๋๋ ์ฌ์ค ๋ถํธํ ๊ฒ์ด๋ค.
ํ์ง๋ง mmap์ ์ด์ฉํ๋ฉด ๊ณต์ ํ๊ณ ์ํ๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์์ ํ์ผ๋ก ๋์์์ผ๋๊ณ , ์ด๋ฅผ ์ฌ๋ฌ ํ๋ก์ธ์ค๊ฐ ์ฌ์ฉํ ์ ์๋ค. ํ์ผ์ ์ ์ญ์ ์ธ ๊ฐ์ฒด์ด๊ธฐ ๋๋ฌธ์ ๋ค๋ฅธ ํ๋ก์ธ์ค์์๋ ์ ๊ทผํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
๋ํ mmap์ ์ฌ์ฉํ๋ฉด ์ฑ๋ฅ ๊ฐ์ ๋ํ ๊ฐ๋ฅํ๋ค. ์ด๋ค ํ๋ก์ธ์ค๊ฐ ํ์ผ์ ์ฝ๊ธฐ ์ํด์๋ ์ ์ฅ๋งค์ฒด์ ์ ๊ทผํ๊ณ ์ฌ๋ฌ๊ฐ์ง ๊ท์ฐฎ์ ํจ์๋ค์ ํตํด ํ์ผ์ ์ ๊ทผํ๋ค.
ํ์ง๋ง ํ์ผ ์์ฒด๋ฅผ ๋ฉ๋ชจ๋ฆฌ๋ก ๋์์ํจ๋ค๋ฉด ํ๋ก์ธ์ค๋ ๊ทธ์ ๋ฉ๋ชจ๋ฆฌ์๋ง ์ ๊ทผํ๋ฉด ๋๊ธฐ ๋๋ฌธ์ ํธ๋ฆฌํ๋ค.
์ฆ mmap์ ์ฌ์ฉํ๋ ์ด์ ๋ ์ด๋ ๊ฒ ์ ๋ฆฌํ ์ ์๊ฒ ๋ค.
- ์๋ก ๋ค๋ฅธ ํ๋ก์ธ์ค ๊ฐ์ ๋ฐ์ดํฐ ๊ณต์ ๋ฅผ ์ฉ์ดํ๊ฒ ํ๋ค.
- ์ ์ฅ ๋งค์ฒด ์ ๊ทผ ๋์ ๋ฉ๋ชจ๋ฆฌ์ ์ ๊ทผํ ์ ์๊ฒํ์ฌ ์ฑ๋ฅ์ด ํฅ์๋๋ค.
mmap ํจ์ ์ค๋ช
#include <sys/mman.h>
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
void* start - ๋ฉ๋ชจ๋ฆฌ ์์์์น
๋ณดํต NULL(0)๋ก ์ค์ ํ์ฌ ์ปค๋์ ์์์ ์์น ์ค์ ํ๋๋ก ํ๋ค. ๋ง์ฝ ์ง์ ์ค์ ํ๊ณ ์ถ๋ค๋ฉด
void* start=0x00000000 ์ด๋ฐ ์์ผ๋ก ์ค์ ํ ์ ์๊ฒ ์ผ๋ ์ถฉ๋ ์ํ์ด ์๋ค.
size_t length - ํ ๋นํ ๋ฉ๋ชจ๋ฆฌ ๊ธธ์ด
int prot - ๋งตํ์ ์ํ๋ ๋ฉ๋ชจ๋ฆฌ ๋ณดํธ ์ ์ฑ
(์: ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ด์๋ค๋ฉด PROT_WRITE๋ฅผ ์ง์ ํ๋ฉด ์๋๋ค.)
- PROT_READ(์ฝ๊ธฐ ๊ฐ๋ฅ)
- PROT_WRITE(์ฐ๊ธฐ ๊ฐ๋ฅ)
- PROT_EXEC(์คํ ๊ฐ๋ฅ)
- PROT_NONE(์ ๊ทผ ๋ถ๊ฐ)
๋ฑ์ด ์๋ค.
int flags - ๋ฉ๋ชจ๋ฆฌ ์ฃผ์ ๊ณต๊ฐ ์ค์
๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ด๋์ ์์ฑํ ๊ฒ์ธ์ง ์ค์ ํ๋ค!
- MAP_SHARED(๋ค๋ฅธ ํ๋ก์ธ์ค์ ๊ณต์ ๊ฐ๋ฅ / ํ๋ก์ธ์ค ์ธ๋ถ ์์ฑ)
- MAP_PRIVATE(ํ๋ก์ธ์ค ๋ด์์๋ง ์ฌ์ฉ / ํ๋ก์ธ์ค ๋ด๋ถ ์์ฑ)
- MAP_FIXED(์ง์ ๋ ์ฃผ์๋ก ๊ณต๊ฐ์ง์ / ์ง์ ๋ ๊ณต๊ฐ์ ์์ฑ)
- MAP_ANONYMOUS(์ด๋ค ํ์ผ๊ณผ๋ ๋งคํ๋์ง ์์(?)) - addr=0, fd=-1(ํน์ ๋ฌด์)๋ก ์ค์ , offset=0 ์๋ ์ ์๊ธ์ ์ค๋ช
์์
MAP_ANONYMOUS
The mapping is not backed by any file; its contents are
initialized to zero. The fd argument is ignored; however,
some implementations require fd to be -1 if MAP_ANONYMOUS
(or MAP_ANON) is specified, and portable applications
should ensure this. The offset argument should be zero.
The use of MAP_ANONYMOUS in conjunction with MAP_SHARED is
supported on Linux only since kernel 2.4.
int fd - ์ด๋ค ํ์ผ์ ๋งคํ์ํฌ ๊ฒ์ผ์ง file descriptor ์ง์ (open ํจ์๊ฐ ๋ฐํํ๋ ์ !)
off_t offset - ์์์ฃผ์(start)๋ฅผ ๊ธฐ์ค์ผ๋ก ์ผ๋งํผ ๋จ์ด์ง ๊ณณ์ ์์ฑํ ๊ฑด์ง?
ex) offset์ด 10, start๊ฐ 1์ธ ๊ฒฝ์ฐ, ํ์ผ๊ณผ ๋งคํ๋๋ ๋ฉ๋ชจ๋ฆฌ๋ ์ฃผ์๋ 11๋ถํฐ ์์ํ๋ค.
๊ทธ๋ฆฌ๊ณ return value๋ ๋งคํ๋ ๋ฉ๋ชจ๋ฆฌ ์์น์ด๋ค.
์ฝ๋ ์)
handle = open(fname, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
mmap((void*)0, statbuf.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, handle, 0);
์ผ๋จ fname์ด๋ผ๋ ํ์ผ์ ์ด๊ณ ์ด fd๋ฅผ handle์ ํ ๋นํ๋ค.
๋๋ฒ์งธ mmap ์ฝ๋๋ฅผ ํด์ํด๋ณด๋ฉด ์ด๋ ๋ค.
handle์ ์ด์ ๋งคํํ๋๋ฐ statbuf.st_size ๋งํผ ํ ๋นํ ์ฝ๊ณ ์ธ ์ ์๊ฒํ๋ค. ๊ทธ๋ฆฌ๊ณ ๋ค๋ฅธ ํ๋ก์ธ์ค์ ๊ณต์ ํ ์ ์๊ฒํ๋ค.
์ค์ ์ฝ๋์์ ์๋ผ์จ ์์)
char *shellcode = mmap(NULL, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
0x1000๋งํผ ํ ๋นํ๊ณ r,w,x ๊ฐ๋ฅํ๋ค. MAP_PRIVATE | MAP_ANONYMOUS ๋ mmap (user space)์ MAP_ANONYMOUS ์ ๋ํด์... (tistory.com) ์ฐธ๊ณ ํ๋ฉด๋๋ค.(์์ง ๋ฌด์จ ์๋ฆฐ์ง ์ ๋ชจ๋ฅด๊ฒ ๋ค...) fd=-1๋ก ํด์ ์ด๋ค ํ์ผ๊ณผ๋ ๋งคํ๋์ง ์๋ ๊ฒ ๊ฐ๋ค.
References
https://man7.org/linux/man-pages/man2/mmap.2.html
'๐ฉโ๐ป Programming & Algorithm > C' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[C] enum(์ด๊ฑฐํ) ์ฌ์ฉํ๊ธฐ (0) | 2023.09.02 |
---|---|
[C/C++] setbuf,setvbuf ํจ์ ์ ๋ฆฌ (0) | 2023.03.29 |
[C/C++] What is Pointer? - Pointer and Addresses (0) | 2021.08.20 |