Exploit

Metasploit patternによるEIPまでのオフセット計算

スタックバッファオーバーフロー脆弱性が存在する状況において、送り込む文字列と実際に書き変わったEIPを比べることで、EIPまでのオフセットを計算することができる。 ここでは、Metasploit pattern(あるいはcyclic pattern)と呼ばれる文字列を使ったオフ…

x64でスタックバッファオーバーフローをやってみる

Intel x64 (x86-64) 環境のもとで、スタックバッファオーバーフローによるシェルコード実行およびROPをやってみる。 環境 Ubuntu 12.04 LTS 64bit版 $ uname -a Linux vm-ubuntu64 3.11.0-15-generic #25~precise1-Ubuntu SMP Thu Jan 30 17:39:31 UTC 2014 …

Smashing the stack bypassing ASLR+PIE+DEP+SSP(+RELRO)

buffer over-readおよびスタックバッファオーバーフローを利用し、ASLR+PIE+DEP+SSP(+RELRO)がすべて有効な条件下におけるシェル起動をやってみる。 なお、ここではGOT overwriteなどは行わないため、RELROの有無に意味はない。 環境 Ubuntu 12.04 LTS 32bit…

ROP stager + read/writeによるASLR+DEP回避

「ROP stagerによるシェルコード実行をやってみる」では、mmapにより動的に実行可能なメモリを確保しシェルコード実行を行った。 ROP stagerには、ほかにもmprotectなどを使いすでに存在するメモリ領域を実行可能に変更するアプローチもある。 さらに、脆弱…

ROP stagerによるシェルコード実行をやってみる

DEPが有効な状況では、スタックバッファオーバーフローなどから命令を実行させるためにROPと呼ばれる手法が使われる。 さらに、ROPを使って任意の処理を実行させる方法として、実行可能なメモリ領域(stage)を動的に確保し、そこに通常のシェルコードをコピ…

byte-by-byte bruteforceによるSSP回避

「Improper Null Terminationを利用したSSP回避」では、stack canaryの先頭にあるNULLバイトを上書きすることでcanaryの読み出しを行った。 この方法のほかにも、ネットワークサーバがforkサーバとして実装されている場合、1バイトごとのブルートフォースでc…

use-after-freeによるC++ vtable overwriteをやってみる

一つ前のエントリではuse-after-freeによるGOT overwriteを行ったが、C++におけるvtable overwriteもヒープオーバーフローの場合と同様に行うことができる。 ここでは、use-after-freeによるC++ vtable overwriteを行い、シェルを起動してみる。 またDEPが有…

use-after-freeによるGOT overwriteをやってみる

ヒープ領域に関連する脆弱性には、ヒープオーバーフローのほかにuse-after-freeと呼ばれるものがある。 これは、意図しない条件分岐などから発生するプログラムの不整合により解放済みのヒープメモリアドレスが参照される状況が存在する場合、任意のコード実…

Improper Null Terminationを利用したSSP回避

スタックバッファオーバーフローを防ぐセキュリティ機構の一つに、SSPがある。 SSPを有効にすると、関数の呼び出し時にスタックにcanaryと呼ばれる値が置かれ、これが書き換えられたとき強制終了するようになる。 しかし、何らかの方法でcanaryの値が知るこ…

jmp espによるASLR回避

スタックバッファオーバーフローを利用してスタック上のシェルコードにジャンプするには前もってシェルコードが置かれているアドレスを知る必要があるが、ASLRが有効な場合スタック領域のベースアドレスがランダム化されてしまう。 しかしこのような場合でも…

アセンブリ命令と機械語の相互変換

アセンブリ命令(asm)と機械語(opcode)を相互に変換する方法のメモ。 GNU Binutilsを使う asmからopcodeに変換するには、asコマンドを使う。 $ echo jmp esp | as -msyntax=intel -mnaked-reg -aln -o /dev/null 1 0000 FFE4 jmp esp ここで、-msyntax=in…

ネットワークソケットを利用したシェル起動

これまでのエントリでは、バッファオーバーフローなどにより起動させたシェルはローカルの端末から操作していた。 これをリモートからネットワーク越しに操作するには、シェルの標準入出力をネットワークソケットに繋ぎ変えておく必要がある。 ここでは、い…

ヒープオーバーフローによるC++ vtable overwriteをやってみる

「ヒープオーバーフローによるGOT overwriteをやってみる」ではプログラム中にて定義した構造体を利用してヒープオーバーフローを行った。 これに関連して、C++において仮想関数をメンバ関数に持つクラスを利用すると、ヒープオーバーフローにより任意のアド…

GOT overwriteとStack pivotによるDEP回避(add esp型)

一つ前のエントリではヒープオーバーフローを利用したGOT overwriteを行い、ジャンプ時eaxレジスタにバッファのアドレスが入っていることを利用することによりStack pivotを行った。 しかし、そのようなライブラリ関数呼び出しが見つからない場合もありうる…

GOT overwriteとStack pivotによるDEP回避(xchg esp型)

一つ前のエントリではヒープオーバーフローを利用したGOT overwriteによりシェルコードの実行を行ったが、DEPが有効な場合ヒープ領域に置いたシェルコードを実行することはできなくなる。 スタックバッファオーバーフローにおいてDEPを回避する方法にはRetur…

ヒープオーバーフローによるGOT overwriteをやってみる

プログラムの実行時にデータが置かれる場所にはスタックとヒープがあり、スタックと同様ヒープについてもバッファオーバーフローが起こりうる。 ヒープ領域で起こるバッファオーバーフローは、Heap-based buffer overflowあるいはHeap overflowと呼ばれる。 …

ASCII-armorとReturn-to-plt、Return-to-strcpyによるシェル起動

Red HatやCentOSなど、Exec-Shieldと呼ばれるセキュリティモジュールが利用されているOSには、ASCII-armorと呼ばれるセキュリティ機構が存在する。 ここでは、ASCII-armorの動作を確認し、Return-to-strcpy、Return-to-pltと呼ばれる方法によるシェル起動を…

ASLR+PIEとformat string attackによるInformation Leak

ASLRが有効な場合、スタック領域・ヒープ領域や共有ライブラリが置かれるアドレスは一定の範囲の中でランダムに決められる。 一方、実行ファイルそのものが置かれるアドレスは基本的には固定であるが、PIE (Position-Independent Executables) となるように…

RELROとformat string attackによるリターンアドレス書き換え

一つ前のエントリでは、format string attackでGOTに書かれたアドレスの書き換えを行ったが、RELRO (RELocation Read-Only) と呼ばれるセキュリティ機構を完全に有効にすることでGOTを書き換えられないようにできる。 ここでは、RELROに関連するリンカオプシ…

format string attackによるGOT overwriteをやってみる

一つ前のエントリではformat string attackによるメモリ読み出しをやってみたが、format string attackでは任意の位置のメモリ内容を書き換えることもできる。 ここでは、実際にGOT (Global Offset Table) と呼ばれるセクションに置かれるライブラリ関数のア…

format string attackによるメモリ読み出しをやってみる

バッファスタックオーバーフローに並んでよく知られている攻撃に、format string attack(書式文字列攻撃)がある。 これは、printf系関数のフォーマット文字列が外部から操作可能になっている場合に、細工した文字列を送り込んでメモリ内容の読み出しや書き…

Return-to-libcとmprotect(2)でDEPを回避してみる

Return-to-libcによるDEP回避ではすでに存在する関数しか呼ぶことができないが、実行時に動的にメモリ領域のアクセス保護オプションを書き換えることでスタック上の任意のコードを実行させることができる。 メモリ領域のアクセス保護オプションを書き換える…

ROPとブルートフォースで32bit ASLR+DEPを回避してみる

ROPを使ってDEPを回避するには共有ライブラリのベースアドレスを知る必要がある。 しかしASLRが有効な場合においても、32bitであればブルートフォースで回避できることが知られている。 ここでは、ROPとブルートフォースを組み合わせることで32bit ASLR+DEP…

Return-oriented Programming (ROP) でDEPを回避してみる

Return-to-libcによるDEP回避では、libc内の関数を呼び出すことでシェル起動を行った。 そして連続して関数を呼び出すために、pop命令+ret命令の先頭にジャンプしてスタックを操作するということを行った。 この手法を発展させ、ret命令で終わる命令列の先…

Return-to-libcで連続して関数を呼んでみる

一つ前のエントリでは、Return-to-libcでsystem関数を呼び出しシェル起動を行った。 ここでは、複数の関数を連続して呼び出してみる。 環境 Ubuntu 12.04 LTS 32bit版 $ uname -a Linux vm-ubuntu32 3.11.0-15-generic #25~precise1-Ubuntu SMP Thu Jan 30 1…

Return-to-libcでDEPを回避してみる

DEPが有効になっていると、データ領域に実行可能ビットが立たなくなるため、スタックに置いたシェルコードを実行させることができなくなる。 しかしこのような場合でも、スタックの状態を調整した上でライブラリ関数にジャンプすることで、関数を実行させる…

ブルートフォースによる32bit ASLR回避

「単純なスタックバッファオーバーフロー攻撃をやってみる」では、ASLRとSSP、DEPが無効な状態でのスタックバッファオーバーフロー攻撃を行った。 このうちASLRについては、32bit環境であればブルートフォースで回避できることが知られている。 ここでは、実…

スタックバッファオーバーフローによる標準入力からのシェル起動

一つ前のエントリでは、コマンドライン引数からデータを送り込みスタックバッファオーバーフローを起こした。 標準入力からデータを送り込むときも基本的には同じようにすればよいが、標準入力が端末ではなくなるため、シェルの起動には一工夫が必要になる。…

単純なスタックバッファオーバーフロー攻撃をやってみる

一つ前のエントリで作ったシェルコードを使って、スタックバッファオーバーフローを利用したシェル起動をやってみる。 環境 Ubuntu 12.04 LTS 32bit版 $ uname -a Linux vm-ubuntu32 3.11.0-15-generic #25~precise1-Ubuntu SMP Thu Jan 30 17:42:40 UTC 201…

Linux x86用のシェルコードを書いてみる

なにごともまずは基本から、ということでシェルコードを自分で書いてみる。 なお、アセンブリコードはIntel記法を用いて表す。 環境 Ubuntu 12.04 LTS 32bit版 $ uname -a Linux vm-ubuntu32 3.11.0-15-generic #25~precise1-Ubuntu SMP Thu Jan 30 17:42:40…