私は、スタックを制御することによって、教育目的でCコードの脆弱性を悪用しようとしています。スタックベースの単純なバッファオーバーフローで、シェルコードを実行するアドレスでリターンアドレスを上書きします。このコードは引数としてバッファをとり、バッファを固定サイズにしてstrcpy()
を試みる単純な関数です。 mainから与えられるパラメータはargv[1]
です。だから、もし私が上書きしなければならない正確な量のメモリを見つけたら、単に入力として\x90
(NOP命令)とシェルコードと最後にこのバッファのアドレスで構成される文字列を与えることができると思います。これは最初の引数であるため、そのアドレスは$ebp+8
であり、これはgdb
を実行して見つけることができます。関数の先頭にブレークポイントを設定し、i args
と入力すると、引数として渡される文字列のアドレスが得られます。だから、もし私がn
バイトを上書きしてからアドレスの値を与えると、これは正確にリターンアドレスを上書きすることに気づきました。だから私はこのような入力を持っています:retアドレスのオーバーフロー後に関数の引数として与えられた文字列のアドレスが変更されたのはなぜですか?
perl -e print(\x90 x n-sizeof(shellcode) . shellcode . address)'
それはうまくいかず、なぜ私は理解しようとしました。 gdb
と私はプログラムを実行します。私はstrcpy()
の機能の前にブレークポイントを置いています。その時点で、私は自分の入力を指す文字列ポインタであり、そのアドレスは文字列入力の最後に与えられたものと同じである引数を持っています。私は1命令先に進んでいます。私はスタックを調べた。私は今、argv[1]
の最後に与えられたアドレスの値を持っていて、期待された振る舞いである(つまり、最初の引数の値であるretアドレスより上の他のアドレスを上書きしないことを意味する)eip
($ebp + 4
) )。奇妙なことは今、$ebp+8
の内容は "アドレス"ではなく、何か他のものではないということですか?しかし、保存されたeip
の内容は、犯罪を悪用する私の文字列を指すアドレスです。しかし、ret addrがそのアドレスの内容を実行するとは思われません。
コンパイラが 'buf'をどこに配置するかを知る必要がありますか? –
なぜ私は場所を知る必要があるのですか?これはサイズとどう関係していますか? – curious
スタックのどこで書き込みを開始するのかを知る必要があるためです。 –