質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Security+

Security+は、IT業界団体であるCompTIA認定の資格の一つです。ネットワークセキュリティやコンプライアンスと運用セキュリティといったセキュリティ分野における知識・技術の証明になり、セキュリティインシデントに対応するための知識も評価されます。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

WSL(Windows Subsystem for Linux)

WSL (Windows Subsystem for Linux) は、Windows10のOS上でLinux向けのバイナリプログラムを実行可能にする機能です。また、WindowsOSのAPIを用いた仕組みを提供しており、Linux側からWindowsOSへのファイルアクセスもできます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Q&A

解決済

4回答

1105閲覧

WSL echo scanf関数バッファを溢れさせると警告がでる。visual stdio

kazuyakazuya

総合スコア193

Security+

Security+は、IT業界団体であるCompTIA認定の資格の一つです。ネットワークセキュリティやコンプライアンスと運用セキュリティといったセキュリティ分野における知識・技術の証明になり、セキュリティインシデントに対応するための知識も評価されます。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

WSL(Windows Subsystem for Linux)

WSL (Windows Subsystem for Linux) は、Windows10のOS上でLinux向けのバイナリプログラムを実行可能にする機能です。また、WindowsOSのAPIを用いた仕組みを提供しており、Linux側からWindowsOSへのファイルアクセスもできます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

0グッド

1クリップ

投稿2019/10/08 03:33

知恵袋のほうでもしたのですが解決できそうにないのでお願いします。

#やりたいこと これまでの過程

echoコマンドを使いパイプを作って文字列をプロンプトへ流したい。
(表現がおかしいかもしれません)

使うソースコード

c

1#pragma warning(disable: 4996) 2#include <intrin.h> 3#include<stdio.h> 4#include <string.h> 5 6int sample(int con); 7int sub(int a); 8 9 10int sample(int con) { 11 int (*func)(int a); 12 func = sub; 13 14 printf("sub関数のアドレス・・・%p\n", *func); 15 void* a = _ReturnAddress(); 16 17 18 19 printf("リターンアドレス・・・%p\n", a); 20 char moji[15]; 21 int* p; 22 p = (int*)moji; 23 int ebpofs; 24 int ebpofs2; 25 int* ebp; 26 ebp = &con; 27 28 unsigned* retaddr = (unsigned*)_AddressOfReturnAddress(); 29 unsigned* pp = retaddr - 1; 30 printf("保存されたebp:%p\n", *pp); 31 32 scanf("%s", moji); 33 printf("%s\n", "ローカル変数"); 34 printf("%s\n", "ローカル変数 4バイト出力 16進数 0 80"); 35 36 for (ebpofs = 0; ebpofs < 80; ebpofs++) { 37 printf("addr:%p price:%x\n", p + ebpofs, p[ebpofs]); 38 } 39 printf("%s\n", "--------------------------------------------"); 40 printf("%s\n", "コマンド引数 4バイト入力 16進数 -5 40"); 41 for (ebpofs2 = -5; ebpofs2 < 40; ebpofs2++) { 42 printf("addr:%p price:%x\n", ebp + ebpofs2, ebp[ebpofs2]); 43 } 44 //リターンアドレス破壊4 45 void* b = _ReturnAddress(); 46 printf("return:%p\n", b); 47 printf("price:%x\n", p[13]); 48 //p[13] = (int)func; 49 //p[13] = ((p[13] >> 6) | (p[13] >> 9)) + 80485; 50 //printf("price:%x\n", p[13]); 51 void* c = _ReturnAddress(); 52 printf("return:%p\n", c); 53 54 unsigned* retaddr2 = (unsigned*)_AddressOfReturnAddress(); 55 unsigned* pp2 = retaddr2 - 1; 56 printf("ebp:%p\n", *pp2); 57 return 0; 58} 59 60int main(int a) { 61 sample(8); 62 return 0; 63} 64 65 66int sub(int a) { 67 printf("%s\n", "破壊成功!"); 68 return 0; 69} 70

バッファオーバーフローを起こしてリターンアドレスを書き換えたいです。
(任意のアドレスに書き換えることは確かにできたが・・・
今回のと話は関係ない)

scanf関数の標準入力からエスケープシーケンスで16進数(アドレス)を指定したかったのですが

エスケープシーケンスはあくまでソースコード上のきまりということで・・・
(入力に¥x61を入れると {'','x','6','1'}となってしまう。)

echoコマンドから文字列を入れることにしました。
(windows標準のコマンドプロンプトではエスケープシーケンスが認識されなかったから
WSLを使用。)

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

cmd

1echo -e "バッファを溢れさせられる文字列" | 上記のソースコード

すると

イメージ説明

このようなデバッグエラーが出てきます。

WSLを導入したときはバッファを溢れさせる入力をしても

このような警告?は出なかったのですが、あるときパソコンを再起動したときから

このようなエラーが出てきました。

このエラーの中の「無視」を選択するとそのまま実行できます。

ただ、バッファがあふれる入力が44バイト以上だと「無視」を選択しても

実行できません。

リターンアドレスまでは52バイトあるのでどうしても44バイト以上の入力になってしまいます。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
#やったこと

WSLを再インストールしました。
→結果は変わらず

visual stdio のプロジェクトを変更して実行してみたのですが
→結果は変わらず

プロジェクト>パロディ をいろいろいじってみたのですが

そちらもなにも変わらず。

ネットサーフィンしていても

echoコマンドからバッファを溢れさせたら警告がでるなんていう

事例も発見できず・・・。

何が原因なのかが検討がつかないのですが何かアドバイスをください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

異常を検出した、というメッセージで至極正常な動作です

原因はあなたが異常を発生させてるから。

投稿2019/10/08 03:37

y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazuyakazuya

2019/10/08 03:39

回答ありがとうございます。 WSLを導入した直後はバッファを溢れさせても このようなエラーが起こることはありませんでした。 なので、再インストールしたのですが 結果は変わらなかった・・・と書きました。
y_waiwai

2019/10/08 03:52 編集

だからなんでしょう。 スピード違反したけど捕まりませんでした。 だけど、XXXをしたら捕まりました。なぜでしょう、と聞いてるのと同じですがな そもそもの考え方が間違ってますね
kazuyakazuya

2019/10/08 03:57

やりたいことはこの警告がでないようにしたいです。 で、さっきから書いていますがWSL導入直後は バッファを溢れさせてもこのような警告は一回たりとも出ていません。 が、パソコンを再起動した後バッファを溢れさせてみようとすると 謎の警告がでるようになったという話。 異常を検出した、というメッセージで至極正常な動作です 原因はあなたが異常を発生させてるから。 →それはバッファを溢れさせているから・・・ということくらいわかります。 どうやったら、再起動する前のようにバッファを溢れさせる入力ができるのか・ という意図の質問なのですが 異常を検出した、というメッセージで至極正常な動作です 原因はあなたが異常を発生させてるから。 →?
yoorwm

2019/10/08 04:08

> バッファを溢れさせてもこのような警告は一回たりとも出ていません。 いや、そういう異常な操作に対しての動作は一定していないんですよ。 「警告が出るか?についても保証されない」、と言えば分かりますか?
kazuyakazuya

2019/10/08 04:19

ありがとうございます。 (メモリの配置やバッファオーバーフロー検知・・・不安定とはいえ全く打つ手がないというわけではないじゃないんですか?) なんか具体的な対抗策を教えてほしかったですねぇ・・・。
maisumakun

2019/10/08 04:22

> 不安定とはいえ全く打つ手がないというわけではないじゃないんですか? 攻撃者なら別ですが、そうでないならこのようなルートで特定の実行を行おうとすること自体が必要とされません。
kazuyakazuya

2019/10/08 04:29

この提示したソースコードの中の sub関数 を呼び出すことを最終目標に掲げています。 (ReturnAddress(); 関数や p[数値] などで直接リターンアドレスを書き換える手もありますが それでは勉強にならないので) そういった意味で、バッファを溢れる入力する段階で そもそも入力ができない・・・というのは・・・ ーーーーーーーーーーーーーーーーーーーーーーー パソコンを再起動する前は エスケープシーケンスを使って任意のアドレスに書き換えることができました。 ただ、それと同時に 保存された(積まれた)EBPまで破壊してしまい 正常にsub関数が呼び出されないという状況でした。 そこで、リターンアドレスと同時にEBPも書き換えてしまおうと 段階に入ったところで、今回の警告が出てくるようになりました・・・。
y_waiwai

2019/10/08 04:36

えーと、、アソコでスピード出したら警察に捕まりました。捕まりたくないんですがどうしたらいいんでしょうか、という質問をあなたが見たときにどう感じるでしょう ちょうどそのときにあなたが思ってるようなことを私も思ってますw
kazuyakazuya

2019/10/08 04:39

あぁ・・・ まぁなんとなくわかります。 けど、そこをなんとか教えてほしいですねぇ 何か犯罪に関連するようなものでもないですし(たぶん)
y_waiwai

2019/10/08 04:40

真面目な話をしますと、、 スタックオーバフローに関しては過去、いろんな攻撃がなされいろんな被害が発生したため、それに関してはある程度の対策がなされてます あなたがリターンアドレスを書き換える、といってますが、最近はそういう事ができないように対策がなされるようになってきてます
maisumakun

2019/10/08 04:41

> そういった意味で、バッファを溢れる入力する段階で そもそも入力ができない・・・というのは・・・ ほとんどの人間にとって、それが望ましい動作です。
maisumakun

2019/10/08 04:43

> けど、そこをなんとか教えてほしいですねぇ 仮想マシンを立ててFreeDOSでも使ったらどうでしょうか。ろくに保護もない環境です。
kazuyakazuya

2019/10/08 04:46

ありがとうございます。 とりあえず、それで試してみます。 もしそれで警告が出たらWSL,visual stdioいずれかが要因ですね。
maisumakun

2019/10/08 04:47

> もしそれで警告が出たらWSL,visual stdioいずれかが要因ですね。 あの、FreeDOSではどちらも動かないかと思います。
kazuyakazuya

2019/10/08 04:51

あ・・・すみません。 C言語でも専用の環境があるみたいですね。
dodox86

2019/10/08 05:06

FreeDOSで動作する16ビットCコンパイラを使ってください。レジスター長16ビット、基本は20ビットのアドレス空間、リアルモードです。更に頑張れば32ビットのプロテクトモードの勉強になるでしょう。そこなら一般保護例外起きるかも、ですね。
kazuyakazuya

2019/10/08 05:14

ありがとうございます。面白そうなのでやってみます。
guest

0

ベストアンサー

MSVCでバッファオーバーランを実験するのはいろいろ厄介ですね。デバッグビルドの場合は asm さんが指摘されている“セキュリティチェック”のほかに“基本ランタイムチェック” (デフォルトで /RTC1) をやめる必要があります。
当方の環境ではそれで、“破壊成功”が表示されました。
なお、入力にはWSLechoではなく、次のようなプログラムを作って標準入力に流し込んでいます。

c

1#include <stdio.h> 2 3int main(void) 4{ 5 for (int i = 0; i < 28; ++i) putchar(0x00); 6 putchar(0x7b); 7 putchar(0x12); 8 putchar(0x2f); 9 putchar(0x00); 10} 11

リターンアドレスはその都度変わりますので、調査が必要です。

実行結果

cmd

1sub関数のアドレス・・・002F127B 2リターンアドレス・・・002F194A 3保存されたebp:00AFFE10 4ローカル変数 5ローカル変数 4バイト出力 16進数 0 80 6addr:00AFFDA0 price:0 7addr:00AFFDA4 price:0 8addr:00AFFDA8 price:0 9addr:00AFFDAC price:0 10addr:00AFFDB0 price:0 11addr:00AFFDB4 price:0 12addr:00AFFDB8 price:0 13addr:00AFFDBC price:2f127b 14addr:00AFFDC0 price:0 15addr:00AFFDC4 price:2f1348 16addr:00AFFDC8 price:2f1348 17addr:00AFFDCC price:885000 18addr:00AFFDD0 price:affdec 19addr:00AFFDD4 price:7ad5c922 20addr:00AFFDD8 price:0 21addr:00AFFDDC price:2f1348 22addr:00AFFDE0 price:0 23addr:00AFFDE4 price:7ad8e62e 24addr:00AFFDE8 price:7ae64e64 25addr:00AFFDEC price:affe00 26addr:00AFFDF0 price:7ad8e8f2 27addr:00AFFDF4 price:2f1348 28addr:00AFFDF8 price:1 29addr:00AFFDFC price:1 30addr:00AFFE00 price:affe0c 31addr:00AFFE04 price:2f2213 32addr:00AFFE08 price:0 33addr:00AFFE0C price:affe1c 34addr:00AFFE10 price:affe24 35addr:00AFFE14 price:2f252e 36addr:00AFFE18 price:1 37addr:00AFFE1C price:b2af80 38addr:00AFFE20 price:b35270 39addr:00AFFE24 price:affe80 40addr:00AFFE28 price:2f2397 41addr:00AFFE2C price:6ecf2c37 42addr:00AFFE30 price:2f1348 43addr:00AFFE34 price:2f1348 44addr:00AFFE38 price:885000 45addr:00AFFE3C price:0 46addr:00AFFE40 price:0 47addr:00AFFE44 price:0 48addr:00AFFE48 price:0 49addr:00AFFE4C price:0 50addr:00AFFE50 price:0 51addr:00AFFE54 price:0 52addr:00AFFE58 price:0 53addr:00AFFE5C price:2fa5a0 54addr:00AFFE60 price:2fa5ac 55addr:00AFFE64 price:0 56addr:00AFFE68 price:affe2c 57addr:00AFFE6C price:0 58addr:00AFFE70 price:affeec 59addr:00AFFE74 price:2f4230 60addr:00AFFE78 price:6e4f4287 61addr:00AFFE7C price:0 62addr:00AFFE80 price:affe88 63addr:00AFFE84 price:2f222d 64addr:00AFFE88 price:affe90 65addr:00AFFE8C price:2f25a8 66addr:00AFFE90 price:affea0 67addr:00AFFE94 price:75d96359 68addr:00AFFE98 price:885000 69addr:00AFFE9C price:75d96340 70addr:00AFFEA0 price:affefc 71addr:00AFFEA4 price:77ad7b74 72addr:00AFFEA8 price:885000 73addr:00AFFEAC price:bdee94af 74addr:00AFFEB0 price:0 75addr:00AFFEB4 price:0 76addr:00AFFEB8 price:885000 77addr:00AFFEBC price:0 78addr:00AFFEC0 price:0 79addr:00AFFEC4 price:0 80addr:00AFFEC8 price:0 81addr:00AFFECC price:0 82addr:00AFFED0 price:0 83addr:00AFFED4 price:0 84addr:00AFFED8 price:0 85addr:00AFFEDC price:0 86-------------------------------------------- 87コマンド引数 4バイト入力 16進数 -5 40 88addr:00AFFDAC price:0 89addr:00AFFDB0 price:0 90addr:00AFFDB4 price:0 91addr:00AFFDB8 price:0 92addr:00AFFDBC price:2f127b 93addr:00AFFDC0 price:0 94addr:00AFFDC4 price:2f1348 95addr:00AFFDC8 price:2f1348 96addr:00AFFDCC price:885000 97addr:00AFFDD0 price:affdec 98addr:00AFFDD4 price:7ad5c922 99addr:00AFFDD8 price:0 100addr:00AFFDDC price:2f1348 101addr:00AFFDE0 price:0 102addr:00AFFDE4 price:7ad8e62e 103addr:00AFFDE8 price:7ae64e64 104addr:00AFFDEC price:affe00 105addr:00AFFDF0 price:7ad8e8f2 106addr:00AFFDF4 price:2f1348 107addr:00AFFDF8 price:1 108addr:00AFFDFC price:1 109addr:00AFFE00 price:affe0c 110addr:00AFFE04 price:2f2213 111addr:00AFFE08 price:0 112addr:00AFFE0C price:affe1c 113addr:00AFFE10 price:affe24 114addr:00AFFE14 price:2f252e 115addr:00AFFE18 price:1 116addr:00AFFE1C price:b2af80 117addr:00AFFE20 price:b35270 118addr:00AFFE24 price:affe80 119addr:00AFFE28 price:2f2397 120addr:00AFFE2C price:6ecf2c37 121addr:00AFFE30 price:2f1348 122addr:00AFFE34 price:2f1348 123addr:00AFFE38 price:885000 124addr:00AFFE3C price:0 125addr:00AFFE40 price:0 126addr:00AFFE44 price:0 127addr:00AFFE48 price:0 128addr:00AFFE4C price:0 129addr:00AFFE50 price:0 130addr:00AFFE54 price:0 131addr:00AFFE58 price:0 132addr:00AFFE5C price:2fa5a0 133return:002F127B 134price:7ad5c922 135return:002F127B 136ebp:00000000 137破壊成功!

環境を追記しておきます。
Windows10
Visual Studio 2019

投稿2019/10/08 07:12

編集2019/10/08 08:41
Bull

総合スコア986

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazuyakazuya

2019/10/08 09:45

回答ありがとうございます。 「既定」にした結果、警告が出なくなりました が、プログラムが開始されないまま終了してしまいます。
kazuyakazuya

2019/10/08 09:45

echoじゃできないのかなぁ・・・
Bull

2019/10/08 12:23

コマンドプロンプトで wsl.exe echo -e 'xxxx' | プログラム で出来ませんか?
kazuyakazuya

2019/10/08 18:03

そちらでも結果に変化はありませんでした。
asm

2019/10/08 18:17

正直、実行しているexeが正しいものかが疑わしいですね デバッグビルドとリリースビルドでexeファイルが出力される場所が変わる事はご存知ですよね? 一度、出力メッセージなどを変化させて実行しているファイルが追随しているかを試した方がよいように思います。
kazuyakazuya

2019/10/08 18:34 編集

正直、実行しているexeが正しいものかが疑わしいですね →コードを変更したところechoでの結果も変わったので大丈夫です。 こんかいは23バイト(8バイト漏れ)までならプログラムが実行されますが 24バイト以上の入力で実行されずプログラムが終了してしまいます。 これはバッファ検知とかの問題ではなく 24バイト目の、プログラムを実行するにあたって何か大事な ものも破壊してしまっている・・・? で、今思ったのですが 書き換えたいリターンアドレス以外の値を適当に 'a' で埋めていたわけですが EBPや何か大事なものも破壊してしまうため aではなく ひとつひとつ任意の値(入っていた値を再現)を入れる必要があるのかぁ・・・
Bull

2019/10/09 12:05 編集

バッファ (char moji[15];) とリターンアドレスの間に 以前の ebp が保存されているので、バッファオーバーランで ebp は破壊されますが、ebp が破壊されても sub 関数が呼ばれることは確認できています。 sub 関数から return するときに異常終了しますが、これを回避して正常終了させるのはなかなか大変です。手っ取り早いのは sub 関数で exit 関数を呼んで終了させることでしょう。 あと、プログラムがどこで終了してるのかデバッグして確かめましょう。C のソースコードでのトレースではなく、アセンブリコードでトレースしてレジスタの値も確認すれば、どこに問題があるのかがわるのではないでしょうか。
kazuyakazuya

2019/10/09 13:01

アドバイスありがとうございます。 (中間考査あるので。。。) 確かめるのは後になります。。。
kazuyakazuya

2019/10/16 11:22

ご提示いただいた以下のコード int main(void) { for (int i = 0; i < 28; ++i) putchar(0x00); putchar(0x7b); putchar(0x12); putchar(0x2f); putchar(0x00); } (私自身putchar・getchar関数を使ったことがなくて・・・) このコードは私が提示したソースファイルとは別のところから 実行(ビルド・・・)するのですよね? このプログラムをビルドすると標準入力へ(私が提示したコード) 値が入るのかと思っていたのですが 実際に入ることはありませんでした。 putchar関数について調べていても 標準入力へ文字列を流すような説明はなかったのですが・・・ そういったことでこのコード自体の糸が(どうやって使用するのか?) 分からないです。ご教授いただけませんでしょうか?
Bull

2019/10/16 13:05 編集

このプログラムは wsl.exe echo の代わりです。 このプログラムを bin.exe、テストするプログラムを prog.exe とすると bin.exe | prog.exe などとパイプでつなげば、テストプログラムでバイナリーデータを受け取れます。 Windows の echo はエスケープ文字を使って、バイナリーデータを出力することは出来ないので、決め打ちでバイナリーデータを標準出力に出力しています。 sub 関数のアドレスを調査した後プログラムを書き換えて、コンパイルしなければならないので二度手間です。 asm さんの提示されたプログラムはそれを自動的にやってくれるので、実験するならそちらの方がいいと思います。
kazuyakazuya

2019/10/18 02:13

ありがとうございます。 パイプで繋げた結果 任意のアドレスに書き換えることはできたのですが sub関数を呼び出すことはできませんでした・・・。 sub関数のアドレス・・・ 011E12C1 addr:0053FD60 price:0 addr:0053FD64 price:0 addr:0053FD68 price:0 addr:0053FD6C price:0 addr:0053FD70 price:0 addr:0053FD74 price:0 addr:0053FD78 price:0 addr:0053FD7C price:0 addr:0053FD80 price:0 addr:0053FD84 price:0 addr:0053FD88 price:0 addr:0053FD8C price:0 addr:0053FD90 price:0 addr:0053FD94 price:11e12c1
kazuyakazuya

2019/10/18 02:15

あ!できました!!!!!! ありがとうございます!!!!!!!!
kazuyakazuya

2019/10/18 02:17

言われた通り いざバッファオーバーフローを起こそうとすると大変ですね・・・。 なので仮想環境はそちらはそちらでやろうと思います。 (あと、リターンアドレスを書き換えてsub関数を呼び出したのですが 正常に終了しました・・・なぜだろう)
guest

0

ちなみに

c++

1__declspec(safebuffers) int sample(int con) { 2// 省略

で関数ごとにセキュリティチェックを無効化できるようです。


追記
以下で攻撃文字列の生成・読み込みに成功

demo.exe /dump 28 => dump.binに攻撃文字列を生成
type dump.bin | demo.exe => dump.binをwindowsの標準コマンドtypeで読み込みdemo.exeにわたす
demo.exe /echo 28 | demo.exe

プロジェクトのプロパティ

  • C/C++>コード生成>基本ランタイムチェック: 既定
  • C/C++>コード生成>セキュリティチェック: セキュリティチェックを無効にします
  • リンカー>詳細設定>ランダム化されたベースアドレス: いいえ

c++

1#pragma warning(disable: 4996) 2#include <intrin.h> 3#include <stdio.h> 4#include <stdlib.h> 5#include <string.h> 6 7int sample(int con); 8int sub(int a); 9 10 11int sample(int con) { 12 int(*func)(int a); 13 func = sub; 14 15 printf("sub関数のアドレス・・・%p\n", *func); 16 void* a = _ReturnAddress(); 17 18 19 20 printf("リターンアドレス・・・%p\n", a); 21 char moji[15]; 22 int* p; 23 p = (int*)moji; 24 int ebpofs; 25 int ebpofs2; 26 int* ebp; 27 ebp = &con; 28 29 unsigned* retaddr = (unsigned*)_AddressOfReturnAddress(); 30 unsigned* pp = retaddr - 1; 31 printf("書き換えたいアドレス: %p + %u\n", moji, (uintptr_t)retaddr - (uintptr_t)moji); 32 printf("保存されたebp:%p\n", *pp); 33 34 scanf("%s", moji); 35 puts("ローカル変数"); 36 puts("ローカル変数 4バイト出力 16進数 0 80"); 37 38 for (ebpofs = 0; ebpofs < 80; ebpofs++) { 39 printf("addr:%p price:%x\n", p + ebpofs, p[ebpofs]); 40 } 41 puts("--------------------------------------------"); 42 puts("コマンド引数 4バイト入力 16進数 -5 40"); 43 for (ebpofs2 = -5; ebpofs2 < 40; ebpofs2++) { 44 printf("addr:%p price:%x\n", ebp + ebpofs2, ebp[ebpofs2]); 45 } 46 //リターンアドレス破壊4 47 void* b = _ReturnAddress(); 48 printf("return:%p\n", b); 49 printf("price:%x\n", p[13]); 50 //p[13] = (int)func; 51 //p[13] = ((p[13] >> 6) | (p[13] >> 9)) + 80485; 52 //printf("price:%x\n", p[13]); 53 void* c = _ReturnAddress(); 54 printf("return:%p\n", c); 55 56 unsigned* retaddr2 = (unsigned*)_AddressOfReturnAddress(); 57 unsigned* pp2 = retaddr2 - 1; 58 printf("ebp:%p\n", *pp2); 59 return 0; 60} 61 62void dump(int argc, char** argv, FILE* fp) { 63 int offset = 0; 64 if (argc > 2) 65 offset = atoi(argv[2]); 66 for (int i = 0; i < offset; i++) 67 fputc('x', fp); 68 void* addr = sub; 69 fwrite(&addr, sizeof(addr), 1, fp); 70} 71 72int main(int argc, char** argv) { 73 if (argc > 1) { 74 if (!strcmp(argv[1], "/dump")) { 75 FILE* fp = fopen("dump.bin", "wb"); 76 dump(argc, argv, fp); 77 fclose(fp); 78 return 0; 79 } 80 else if (!strcmp(argv[1], "/echo")) { 81 dump(argc, argv, stdout); 82 return 0; 83 } 84 } 85 sample(8); 86 return 0; 87} 88 89 90int sub(int a) { 91 puts("破壊成功!"); 92 return 0; 93}

投稿2019/10/08 05:10

編集2019/10/08 19:59
asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazuyakazuya

2019/10/08 05:24

回答ありがとうございます。 セキュリティチェックを外して いただいたコードを貼り付けたのですが 結果に変化はありませんでした。 仮想環境でやってみます。
kazuyakazuya

2019/10/09 06:54

ありがとうございます。 時間の関係で実際に試すのは後になりそうです。
guest

0

このようなデバッグエラーが出てきます。

デバッグビルドでやっているからではないでしょうか。


このような、言語の枠外の脆弱性を狙うようなコードは、ちょっとした条件の変化で動いたり動かなくなったりします。

投稿2019/10/08 03:58

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazuyakazuya

2019/10/08 04:10

回答ありがとうございます。 デバッグビルドでやっているからではないでしょうか。 →知恵袋のほうでも指摘をいただきました。 デバッグなし で実行 なども試していたのですが(構成からデバッグを外したり) すべて結果は変わりませんでした。
maisumakun

2019/10/08 04:13

バッファオーバーフローが起きた場合は「未定義の動作」です。ライブラリのバージョンやメモリ配置など、なにか1つが変わっても動作が変わることが十分に考えられます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問