64-bit Linux stack smashing tutorial: Part 1は、Get environment variable address gistを使用して環境変数のアドレスを取得します。前提条件は、まずecho 0 > proc/sys/kernel/randomize_va_space
でASLRを無効にすることです。なぜこのコードは環境変数のアドレスを取得できますか?
要旨の内容は次のとおりです。
/*
* I'm not the author of this code, and I'm not sure who is.
* There are several variants floating around on the Internet,
* but this is the one I use.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char *ptr;
if(argc < 3) {
printf("Usage: %s <environment variable> <target program name>\n", argv[0]);
exit(0);
}
ptr = getenv(argv[1]); /* get env var location */
ptr += (strlen(argv[0]) - strlen(argv[2]))*2; /* adjust for program name */
printf("%s will be at %p\n", argv[1], ptr);
}
*2
は、プログラム名を調整するために使用されているのはなぜ?
私の推測では、プログラム名はスタックの上に2回保存されます。
https://lwn.net/Articles/631631/から次の図は、詳細を与える:この図で
------------------------------------------------------------- 0x7fff6c845000
0x7fff6c844ff8: 0x0000000000000000
_ 4fec: './stackdump\0' <------+
env/ 4fe2: 'ENVVAR2=2\0' | <----+
\_ 4fd8: 'ENVVAR1=1\0' | <---+ |
/ 4fd4: 'two\0' | | | <----+
args | 4fd0: 'one\0' | | | <---+ |
\_ 4fcb: 'zero\0' | | | <--+ | |
3020: random gap padded to 16B boundary | | | | | |
、./stackdump
は、プログラムを実行するために使用されます。だから私は、プログラム名./stackdump
が環境文字列の上に一度保存されていることがわかります。そして./stackdump
がBashellキー_
と環境文字列に保存されます、bashのシェルから起動された場合:
_
(アンダースコア)。シェルの起動時に、シェルを呼び出すために使用される絶対パス名に設定またはシェルスクリプトは、 環境または引数リストで渡されたとおりに実行されます。その後、展開後に前のコマンドの最後の 引数に展開されます。そのコマンドにエクスポートされた 環境に配置され実行された各コマンドを呼び出すために使用されるフルパス名 にも設定します。メールをチェックするとき、この パラメータはメールファイルの名前を保持します。
環境ストリングはスタックの上にあります。したがって、プログラム名はスタックの上に別の時間に保存されます。
正確に何を求めていますか?コードはgetenvが環境変数のアドレスを取得し、プログラムへの呼び出しもスタック上の領域を占めるため、ポインタが適切に調整されるため、コードは機能します。それはコードのコメントです。 –
私の知る限り、スタックに割り当てられたプログラム名には、通常、1文字あたり約2バイトあります。このコードを最初に見たのは、Jon Ericksonの「Hacking:The Exploitation *」です。私はそこでもっと読んだり、スタックがどのようにメモリ内にあるかを理解するためにLinuxカーネルを研究したりすることをお勧めします。 –
@JacobHはい、コードはJon Ericksonによる* Hacking:The Exploitation、2nd Edition *の147ページと148ページに由来しています。しかし、この本はそれがなぜ機能するのか説明していない。 –