HOME»情報処理安全確保支援士掲示板»H30午後Ⅰ問1について
投稿する

H30午後Ⅰ問1について [1531]

 よふか氏さん(No.1) 
設問2について教えてください。
下線①で読み込まれる攻撃者からの入力値については、図1「脆弱性が存在するC++ソースコード」の22行目のscanfで入力されると思いますが、%7sとなっているため、読み込まれる値が7文字までとなっています。
アドレスの値(8文字)が読み込まれるのはなぜでしょうか。
2024.04.14 14:46
pixさん(No.2) 
SC ダイヤモンドマイスター
>アドレスの値(8文字)が読み込まれるのはなぜでしょうか
アドレス値なので、文字ではなくバイナリを読み込ませます。
アドレスは32ビットなので、バイト換算で4バイトです。
2024.04.14 14:57
 よふか氏さん(No.3) 
あまりプログラミングの知識がなく恐縮なのですが、変換指定子のあるscanfへバイナリを読み込ませることができるということでしょうか。
2024.04.14 17:15
pixさん(No.4) 
SC ダイヤモンドマイスター
>あまりプログラミングの知識がなく恐縮なのですが、変換指定子のある
>scanfへバイナリを読み込ませることができるということでしょうか。
通常のコンソールからは難しいと思われます。
コンソールの標準入力を何らかのプログラムに接続し、そこから
インタラクティブにバイナリを流し込むような手法を取ることになると
思われます。
工夫しだいでは、単純なパイプでも実現可能かと思われます。
2024.04.14 17:20
 よふか氏さん(No.5) 
何らかの手法が必要ということですね。
ご回答いただきありがとうございました。
2024.04.14 17:25
GinSanaさん(No.6) 
SC ブロンズマイスター
実験は、こんな感じでどうでしょう
こんなC言語のをfuga.cとして用意
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
    char buf[100];

    /* read a sequence of at most 99 binary digits into buf */
    if (scanf(" %99[01]", buf) == 1) {
        unsigned long d = strtoul(buf, NULL, 2);
        /* print value as a number */
        printf("%s -> %lu\n", buf, d);
        if (d == (unsigned char)d && isprint((unsigned char)d)) {
            /* print value as a character if printable */
            printf("%s -> %c\n", buf, (unsigned char)d);
        }
    }
    return 0;
}
gccでコンパイルする
gcc fuga.c -g3 -o fuga
バイナリがほしいので、今回はNULL文字で実験
printf 'This is \000 a pen.\n' > piyo
gdbで起動
インプットをpiyoにする
gdb ./fuga
(gdb) l
1       #include <ctype.h>
2       #include <stdio.h>
3       #include <stdlib.h>
4
5       int main() {
6           char buf[100];
7
8           /* read a sequence of at most 99 binary digits into buf */
9           if (scanf(" %99[01]", buf) == 1) {
10              unsigned long d = strtoul(buf, NULL, 2);
(gdb) b 9
Breakpoint 1 at 0x5555555551e4: file fuga.c, line 9.
(gdb) run < piyo
Starting program: /mnt/c/UbuntuWorks/20240414/fuga < piyo

Breakpoint 1, main () at fuga.c:9
9           if (scanf(" %99[01]", buf) == 1) {
(gdb) n
18          return 0;
(gdb) n
19      }
(gdb) n
(gdb) n
[Inferior 1 (process 289) exited normally]
(gdb) run < piyo
Starting program: /mnt/c/UbuntuWorks/20240414/fuga < piyo

Breakpoint 1, main () at fuga.c:9
9           if (scanf(" %99[01]", buf) == 1) {
(gdb) p buf
$1 = '\000' <repeats 16 times>, "@@UUUU\000\000\377\265\360\000\000\000\000\000\302\000\000\000\000\000\000\000\027\334\377\377\377\177\000\000\026\334\377\377\377\177\000\000\375RUUUU\000\000\350\342\373\367\377\177\000\000\260RUUUU\000\000\000\000\000\000\000\000\000\000\340PUUUU\000\000 \335\377\377"
(gdb) n
18          return 0;
(gdb) n
19      }
(gdb) quit
参考
c - Way to scanf binary number? - Stack Overflow のchqrlieの回答のサンプルコード
環境:WSL2 Ubuntu 20.04
2024.04.14 19:38
pixさん(No.7) 
SC ダイヤモンドマイスター
>GinSanaさん
サンプルの提示ありがとうございます。
本設問のポイントとして、
・通常コンソールからバイナリを入力することはできないと思ってしまっている
・しかし、知識とプログラミング技術があれば、脆弱性を突くことができる
です。
本設問も以上を踏まえていないと解答するのは難しいです。
2024.04.14 19:49
GinSanaさん(No.8) 
SC ブロンズマイスター
No.6の補足
ほんとうは、パイプでいけます。
GDBで値が見たかったので、GDBつないだらGDBはパイプ渡しがうまくいかないので、リダイレクトで再現しています。
そういう意味で、一番手っ取り早い渡し方は、バイナリを素直に渡せるprintfコマンドで書いて、パイプで流してやることです。
2024.04.14 20:07
 よふか氏さん(No.9) 
>GinSanaさん
とても参考になります。
ありがとうございます。
2024.04.15 00:06
返信投稿用フォームスパム防止のためにスレッド作成日から30日経過したスレッドへの投稿はできません。
© 2014-2024 情報処理安全確保支援士ドットコム All Rights Reserved.

Pagetop