H30午後Ⅰ問1について
広告
よふか氏さん
(No.1)
設問2について教えてください。
下線①で読み込まれる攻撃者からの入力値については、図1「脆弱性が存在するC++ソースコード」の22行目のscanfで入力されると思いますが、%7sとなっているため、読み込まれる値が7文字までとなっています。
アドレスの値(8文字)が読み込まれるのはなぜでしょうか。
下線①で読み込まれる攻撃者からの入力値については、図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として用意
インプットをpiyoにする
c - Way to scanf binary number? - Stack Overflow のchqrlieの回答のサンプルコード
環境:WSL2 Ubuntu 20.04
こんなC言語のをfuga.cとして用意
#include <ctype.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でコンパイルする#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 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
参考(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コマンドで書いて、パイプで流してやることです。
ほんとうは、パイプでいけます。
GDBで値が見たかったので、GDBつないだらGDBはパイプ渡しがうまくいかないので、リダイレクトで再現しています。
そういう意味で、一番手っ取り早い渡し方は、バイナリを素直に渡せるprintfコマンドで書いて、パイプで流してやることです。
2024.04.14 20:07
よふか氏さん
(No.9)
>GinSanaさん
とても参考になります。
ありがとうございます。
2024.04.15 00:06
広告
返信投稿用フォーム
スパム防止のためにスレッド作成日から30日経過したスレッドへの投稿はできません。
広告