H30午後Ⅰ問1について

よふか氏さん  
(No.1)
設問2について教えてください。
下線①で読み込まれる攻撃者からの入力値については、図1「脆弱性が存在するC++ソースコード」の22行目のscanfで入力されると思いますが、%7sとなっているため、読み込まれる値が7文字までとなっています。
アドレスの値(8文字)が読み込まれるのはなぜでしょうか。
2024.04.14 14:46
pixさん 
SC ダイヤモンドマイスター
(No.2)
>アドレスの値(8文字)が読み込まれるのはなぜでしょうか
アドレス値なので、文字ではなくバイナリを読み込ませます。
アドレスは32ビットなので、バイト換算で4バイトです。
2024.04.14 14:57
よふか氏さん  
(No.3)
あまりプログラミングの知識がなく恐縮なのですが、変換指定子のあるscanfへバイナリを読み込ませることができるということでしょうか。
2024.04.14 17:15
pixさん 
SC ダイヤモンドマイスター
(No.4)
>あまりプログラミングの知識がなく恐縮なのですが、変換指定子のある
>scanfへバイナリを読み込ませることができるということでしょうか。
通常のコンソールからは難しいと思われます。
コンソールの標準入力を何らかのプログラムに接続し、そこから
インタラクティブにバイナリを流し込むような手法を取ることになると
思われます。
工夫しだいでは、単純なパイプでも実現可能かと思われます。
2024.04.14 17:20
よふか氏さん  
(No.5)
何らかの手法が必要ということですね。
ご回答いただきありがとうございました。
2024.04.14 17:25
GinSanaさん 
SC ブロンズマイスター
(No.6)
実験は、こんな感じでどうでしょう
こんな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さん 
SC ダイヤモンドマイスター
(No.7)
>GinSanaさん
サンプルの提示ありがとうございます。
本設問のポイントとして、
・通常コンソールからバイナリを入力することはできないと思ってしまっている
・しかし、知識とプログラミング技術があれば、脆弱性を突くことができる
です。
本設問も以上を踏まえていないと解答するのは難しいです。
2024.04.14 19:49
GinSanaさん 
SC ブロンズマイスター
(No.8)
No.6の補足
ほんとうは、パイプでいけます。
GDBで値が見たかったので、GDBつないだらGDBはパイプ渡しがうまくいかないので、リダイレクトで再現しています。
そういう意味で、一番手っ取り早い渡し方は、バイナリを素直に渡せるprintfコマンドで書いて、パイプで流してやることです。
2024.04.14 20:07
よふか氏さん  
(No.9)
>GinSanaさん
とても参考になります。
ありがとうございます。
2024.04.15 00:06

返信投稿用フォーム

※SQL文は全角文字で記載してください。
※宣伝や迷惑行為を防止するため当サイトとIPAサイト以外のURLを含む記事の投稿は禁止されています。

投稿記事削除用フォーム

投稿番号:
パスワード:

その他のスレッド


Pagetop