rosieblue
article thumbnail
728x90

 

์˜ค๋Š˜์€ 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

mmap์ด๋ž€?

35. ์‹œ์Šคํ…œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ - ๋ฉ”๋ชจ๋ฆฌ & mmap

๋ฉ”๋ชจ๋ฆฌ ๋งตํ•‘(mapping) - mmap() / munmap()

profile

rosieblue

@Rosieblue

ํฌ์ŠคํŒ…์ด ์ข‹์•˜๋‹ค๋ฉด "์ข‹์•„์š”โค๏ธ" ๋˜๋Š” "๊ตฌ๋…๐Ÿ‘๐Ÿป" ํ•ด์ฃผ์„ธ์š”!