pwn文字列フォーマット脆弱性02-スタックの内容を上書き
4150 ワード
1.1概略方向
スタックとメモリを変更してプログラムの実行フローをハイジャックし、%n変換インジケータは、現在ストリームに正常に書き込まれているバッファの文字列個数をパラメータで指定された整数に格納します.
1.2引き続きフラワーハローワールド
実行:
1.3解析:ここでのiには初期値は付加されていないが、出力は6 である.理由:変換インジケータの前に6文字(スペースを含む)の文字(h e l l o')が書き込まれ、長さ修飾がない場合、デフォルトでintタイプの値が書き込まれます. 1.4一般利用状況:
通常、上書きする値はshellcodeのアドレスであり、このアドレスは大きな数字であることが多い.この場合、特定の幅または精度の変換仕様を使用して、フォーマット文字列に10進数の整数を加算して出力の最小ビット数を表し、実際のビット数が定義の幅より大きい場合は実際のビット数で出力し、逆にスペースまたは0で補正する必要があります.
just like this:
実行結果:
よく考えてみると、メモリメモにアドレスを書き込むことができます. 64ビットでは、RDIがフォーマット文字列を渡すために使用されるため、パラメータを書き換えることはできません. 形式文字列(「aa%15$na」)このように、必ず8バイトを に揃えます.
2.パラメータ位置の計算について
(変更するアドレス-入力するアドレス)/8+gdbでのオフセット=パラメータ位置
ここはついでにcanryが参考題を迂回することができます:攻防の世界Mary_Morton(ASIS-TF-FInals-2017)WP:(推奨)Mary Morton wp WPの説明の比較的詳しい
3.pwntoolsの関連ツール:
3.1pwntools pwnlib.fmtstr
1-自動化された文字列脆弱性の利用:
class pwnlib.fmtstr.FmtStr(execute_fmt, offset=None, padlen=0, n umbwritten=0) excute_fmt(funtion):脆弱性プロセスとインタラクティブ offset(int):あなたが制御する最初のプログラムのオフセット量 padlen(int):payloadの前にpadサイズ を追加 numbwritten(int):書き込みバイト数 2-payloadの自動生成
pwnlib.fmtstr.fmtstr_payload(offset, writes, numbwritten=0, writ e_size='byte') offset(int):あなたが制御する最初のフォーマットプログラムのオフセット量 writes(dict):フォーマット{addr:value,addr 2:value 2}、addrにvalueの値を書き込むための numbwritten(int):printf関数によって書き込まれたバイト数 write_size(str):byte、shortまたはintでなければなりません.byte単位で書くかshort単位で書くかint単位で書くか(hhn,hnまたはn) ========================
3.2直接問題を出す
3.2.1ソース:
3.2.2一般的な方法:
3.2.3考え方:
printf()関数のアドレスをsystem()関数のアドレスに変更することで,/bin/shを再入力するとshellが得られると考えられる.
====================================
4.1 CVE-2012-0809
公式解釈EXP構想は後でCVEの合集で更新しましょう
4.2補足
文字列関数のフォーマット
一般的なフォーマット文字列関数は入力 scanf
出力 関数#カンスウ#
基本的な紹介
printf
stdoutに出力
fprintf
指定されたFILEストリームに出力
vprintf
パラメータリストに基づいてstdoutにフォーマット出力
vfprintf
パラメータリストに従って指定されたFILEストリームにフォーマット出力
sprintf
文字列に出力
snprintf
指定したバイト数を文字列に出力
vsprintf
パラメータリストに基づいて文字列にフォーマット出力
vsnprintf
パラメータリストに基づいて出力をフォーマットして文字列にバイトを指定
setproctitle
argvの設定
syslog
出力ログ
Err,verr,warn,vwarnなど
...
--------ctfwikiから
スタックとメモリを変更してプログラムの実行フローをハイジャックし、%n変換インジケータは、現在ストリームに正常に書き込まれているバッファの文字列個数をパラメータで指定された整数に格納します.
1.2引き続きフラワーハローワールド
#include
int main()
{
int i;
char str[] = "hello";
printf("%s %n
",str,&i);
printf("%d
",i);
}
実行:
root@MSI:/mnt/c/Users/13013/Desktop/PWN/pwn /02- # ./example
hello
6
1.3
通常、上書きする値はshellcodeのアドレスであり、このアドレスは大きな数字であることが多い.この場合、特定の幅または精度の変換仕様を使用して、フォーマット文字列に10進数の整数を加算して出力の最小ビット数を表し、実際のビット数が定義の幅より大きい場合は実際のビット数で出力し、逆にスペースまたは0で補正する必要があります.
just like this:
#include
int main()
{
int i;
printf("%10u%n
",1,&i);
printf("%d
",i);
printf("%.50u%n
",1,&i);
printf("%d
",i);
printf("%0100u%n
",1,&i);
printf("%d
",i);
}
実行結果:
root@MSI:/mnt/c/Users/13013/Desktop/PWN/pwn /02- # ./shellcode
1
10
00000000000000000000000000000000000000000000000001
50
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
100
よく考えてみると、メモリメモにアドレスを書き込むことができます.
2.パラメータ位置の計算について
(変更するアドレス-入力するアドレス)/8+gdbでのオフセット=パラメータ位置
ここはついでにcanryが参考題を迂回することができます:攻防の世界Mary_Morton(ASIS-TF-FInals-2017)WP:(推奨)Mary Morton wp WPの説明の比較的詳しい
3.pwntoolsの関連ツール:
3.1pwntools pwnlib.fmtstr
1-自動化された文字列脆弱性の利用:
class pwnlib.fmtstr.FmtStr(execute_fmt, offset=None, padlen=0, n umbwritten=0)
pwnlib.fmtstr.fmtstr_payload(offset, writes, numbwritten=0, writ e_size='byte')
3.2直接問題を出す
3.2.1ソース:
#include
int main()
{
char str[1024];
while(1)
{
memset(str,'\0',1024);
read(0,str,1024);
printf(str);
fflush(stdout);
}
}
3.2.2一般的な方法:
root@MSI:/mnt/c/Users/13013/Desktop/PWN/pwn /02- # rabin2 -I fmt
arch x86
baddr 0x400000
binsz 6814
bintype elf
bits 64
canary false
class ELF64
compiler GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609
crypto false
endian little
havecode true
intrp /lib64/ld-linux-x86-64.so.2
laddr 0x0
lang c
linenum true
lsyms true
machine AMD x86-64 architecture
maxopsz 16
minopsz 1
nx true
os linux
pcalign 0
pic false
relocs true
relro partial
rpath NONE
sanitiz false
static false
stripped false
subsys linux
va true
3.2.3考え方:
printf()関数のアドレスをsystem()関数のアドレスに変更することで,/bin/shを再入力するとshellが得られると考えられる.
====================================
4.1 CVE-2012-0809
公式解釈EXP構想は後でCVEの合集で更新しましょう
4.2補足
文字列関数のフォーマット
一般的なフォーマット文字列関数は
基本的な紹介
printf
stdoutに出力
fprintf
指定されたFILEストリームに出力
vprintf
パラメータリストに基づいてstdoutにフォーマット出力
vfprintf
パラメータリストに従って指定されたFILEストリームにフォーマット出力
sprintf
文字列に出力
snprintf
指定したバイト数を文字列に出力
vsprintf
パラメータリストに基づいて文字列にフォーマット出力
vsnprintf
パラメータリストに基づいて出力をフォーマットして文字列にバイトを指定
setproctitle
argvの設定
syslog
出力ログ
Err,verr,warn,vwarnなど
...
--------ctfwikiから