プロが教える店舗&オフィスのセキュリティ対策術

下に示すmsg_file.txtの内容を読み込んで表示するプログラムを使ってバッファオーバーランの危険性を検出するプログラムを作りたいのですが、どのように書き換えたら良いでしょうか。


プログラムソース

1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #define FILEPATH "msg_file.txt"
6
7 int main();
8 void vuln(const char* line);
9 void stack_dump(void* ptr, int counts);
10 void hello();
11
12 int main()
13 {
14 char linebuf[1024];
15 FILE *fp;
16 long mark1 = 0x11111111;
17 memset(linebuf, 0, sizeof(linebuf));
18
19 fp = fopen(FILEPATH, "r");
20 fgets(linebuf, sizeof(linebuf)-1, fp);
21 fclose(fp);
22
23 vuln(linebuf);
24
25 printf("------------- end of main() -------------\n");
26 }
27
28 void vuln(const char* line)
29 {
30 char msg[20];
31 long mark2 = 0x22222222;
32 memset(msg, 0, sizeof(msg));
33
34 strcpy(msg, line);
35
36 stack_dump(&mark2, 13);
37
38 printf("INPUT[%s]\n", msg);
39 }
40
41 void stack_dump(void* ptr, int counts)
42 {
43 int i;
44 unsigned long *ulong_ptr = (unsigned long *)ptr;
45 unsigned char uchar_buf[4];
46
47 printf("-----------------------------------------\n");
48 printf(" address | long var | +0 +1 +2 +3 | 0123\n");
49 printf("-----------------------------------------\n");
50 for(i=0; i<counts; i++) {
51 printf(" %08x| %08x", &ulong_ptr[i], ulong_ptr[i]);
52 memcpy(uchar_buf, &ulong_ptr[i], sizeof(uchar_buf));
53 printf(" | %02x %02x %02x %02x",
54 uchar_buf[0], uchar_buf[1], uchar_buf[2], uchar_buf[3]);
55 if(uchar_buf[0]<32 || uchar_buf[0]>126) uchar_buf[0] = '.';
56 if(uchar_buf[1]<32 || uchar_buf[1]>126) uchar_buf[1] = '.';
57 if(uchar_buf[2]<32 || uchar_buf[2]>126) uchar_buf[2] = '.';
58 if(uchar_buf[3]<32 || uchar_buf[3]>126) uchar_buf[3] = '.';
59 printf(" | %c%c%c%c\n",
60 uchar_buf[0], uchar_buf[1], uchar_buf[2], uchar_buf[3]);
61 }
62 printf("-----------------------------------------\n");
63 }
64
65 void hello()
66 {
67 printf("+----------+\n");
68 printf("| HELLO! |\n");
69 printf("+----------+\n");
70 exit(0);
71 }

A 回答 (2件)

14 char linebuf[1024];


15 FILE *fp;
16 long mark1 = 0x11111111;

30 char msg[20];
31 long mark2 = 0x22222222;
普通の変数の場合'linebuf'と'mark1'はどちらが先になるか分かりません。構造体にまとめましょう。

>printf(" %08x| %08x", &ulong_ptr[i], ulong_ptr[i]);
ポインタの表示にxを使っていますがK&R第2版のころから使えなくなっています。下記のようにしましょう。
printf("%p",ポインタ型の式);またはprintf("%x",(int)(ポインタ型の式));
    • good
    • 0

何をどう検出したいのか判りませんが…。



msg_file.txtが20バイト以上あれば、
>34 strcpy(msg, line);
の時点でめでたくバッファオーバーランしていますが…。

その後コールされるstack_dump()で、vuln()のローカル変数mark2の値が破壊されていることが確認できる…かも知れません。
# 実際にメモリ上にどのように配置されるか…で、破壊が確認できない場合もあります。
ぶち壊した後で壊れたことを検出したところで…手遅れですけどね。
# 生卵を叩きつけて割れてぐちゃぐちゃになったのを確認した後で、割れていない状態には戻せませんし。卵焼きは作れません。

で…vuln()のリターンアドレスも幸いにして破壊されているでしょうから、
その後の動作は保証できない。ということになります。
# HDDの中身ぶっ壊そうがリセットされようが不思議はない…ということに。
# まぁ、最近の普通のOSならプロセスがOSによって殺されるだけで済むはずですが。
## 割れた生卵を掃除して片付ける…みたいな。残念ながら卵焼きは諦めて頂くことに。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!