メモリ破壊
提供: セキュリティ
スポンサーリンク
メモリ破壊 (memory corruption, メモリコラプション)とは、不正なメモリの書き換え・操作によって、データを破壊してしまうことです。
読み方
- メモリ破壊
- めもりはかい
- memory corruption
- めもり こらぷしょん
概要
メモリ破壊は、メモリの操作を誤ったときに発生します。
- ポインタ操作、誤ったアドレスの計算などにより、割り当てられた領域をこえて、参照、書き込みを行う(バッファオーバーラン)
- すでに解放済みのメモリ領域に参照、書き込みを行う (Use After Free)
- 動的に確保したメモリを解放したあとに、再び解放してしまう
メモリ破壊の脆弱性がある場合、サービス妨害攻撃によりDoS状態に陥ったり、任意のコードを実行させられてしまう可能性があります。
二重解放の例
ファイルポインタ
double_fp_free.c
/* * double_fp_free.c * Copyright (C) 2015 kaoru <kaoru@bsd> */ #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { FILE *fp = fopen ("/etc/services", "r"); if ( fclose(fp) != 0) { perror("fclose 1"); } ; if ( fclose(fp) != 0) { perror("fclose 2"); } ; exit(EXIT_SUCCESS); }
実行結果
$ ./a.out *** Error in `./a.out': double free or corruption (top): 0x000000000216a010 *** [1] 7304 abort (core dumped) ./a.out
gdb
(gdb) b main Breakpoint 1 at 0x40061c: file double_fp_free.c, line 12. (gdb) run Starting program: /tmp/a.out Breakpoint 1, main (argc=1, argv=0x7fffffffc608) at double_fp_free.c:12 12 FILE *fp = fopen ("/etc/services", "r"); (gdb) n 13 if ( fclose(fp) != 0) { perror("fclose 1"); } ; (gdb) n 14 if ( fclose(fp) != 0) { perror("fclose 2"); } ; (gdb) n *** Error in `/tmp/a.out': double free or corruption (top): 0x0000000000602010 *** Program received signal SIGABRT, Aborted. 0x00007ffff7a4bcc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 56 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory. (gdb) strace warning: Couldn't determine the static tracepoint marker to probe Static tracepoint 2 at 0x7ffff7a4bcc9: file ../nptl/sysdeps/unix/sysv/linux/raise.c, line 56.
strace
straceの結果
$ strace ./a.out execve("./a.out", ["./a.out"], [/* 85 vars */]) = 0 brk(0) = 0xdbd000 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa6fe72d000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=96509, ...}) = 0 mmap(NULL, 96509, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fa6fe715000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320\37\2\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=1840928, ...}) = 0 mmap(NULL, 3949248, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fa6fe148000 mprotect(0x7fa6fe303000, 2093056, PROT_NONE) = 0 mmap(0x7fa6fe502000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1ba000) = 0x7fa6fe502000 mmap(0x7fa6fe508000, 17088, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fa6fe508000 close(3) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa6fe714000 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa6fe712000 arch_prctl(ARCH_SET_FS, 0x7fa6fe712740) = 0 mprotect(0x7fa6fe502000, 16384, PROT_READ) = 0 mprotect(0x600000, 4096, PROT_READ) = 0 mprotect(0x7fa6fe72f000, 4096, PROT_READ) = 0 munmap(0x7fa6fe715000, 96509) = 0 brk(0) = 0xdbd000 brk(0xdde000) = 0xdde000 open("/etc/services", O_RDONLY) = 3 close(3) = 0 open("/dev/tty", O_RDWR|O_NOCTTY|O_NONBLOCK) = 3 writev(3, [{"*** Error in `", 14}, {"./a.out", 7}, {"': ", 3}, {"double free or corruption (top)", 31}, {": 0x", 4}, {"0000000000dbd010", 16}, {" ***\n", 5}], 7*** Error in `./a.out': double free or corruption (top): 0x0000000000dbd010 *** ) = 80 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa6fe72c000 rt_sigprocmask(SIG_UNBLOCK, [ABRT], NULL, 8) = 0 gettid() = 7277 tgkill(7277, 7277, SIGABRT) = 0 --- SIGABRT {si_signo=SIGABRT, si_code=SI_TKILL, si_pid=7277, si_uid=1000} --- +++ killed by SIGABRT (core dumped) +++ [1] 7274 abort (core dumped) strace ./a.out
関連項目
ツイート
スポンサーリンク