ホーム   »  スポンサー広告  »  スポンサーサイト  »  PSP改造・関連   »  CFW  »  Pro CFWで使われている6.60 kxploitの仕組み

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Pro CFWで使われている6.60 kxploitの仕組み

これも難しい。


サイト更新は停止しました。m(_ _)m

wololo.netでjigsaw氏がPSPのexploitが内部でどのような動作をしているのかについての解説記事を投稿していました。6.60 kxploitはsome1氏が発見し、Pro CFWで使われているカーネルexploitです。その6.60 kxploitに焦点を当てて解説されていますので翻訳してみました。



6.60 kxploit(注: kernel exploitのことをいつからかkxploitと呼ぶようになっています)はmbuf[1]をPSPに移植したifhandle.pfxの中にあります。mbufはネットワークパケットやソケットバッファのメモリ管理をする基本的なユニットです。元々はBSDのものですがBSDライセンスに従って広く商用利用されています。ifhandleはFreeBSD 4のものに若干の修正を加えて移植されたものです。一部のifhandleのルーチンは100%オリジナルのmbufコードそのものです。


kxploitを調べる前に、まずkxploitでどんなことができるのかを確認しておきましょう。その答えは単刀直入に言うとカーネル特権で自分で用意したルーチンを実行することが可能になるということです。カーネル特権があれば非署名自作コードの実行やバージョンチェックスキップなどを実行するためにカーネルへパッチをすることができます。


複雑な話ではありませんが、どうすればカーネル特権を得ることができるのかは簡単な話ではありません。カーネルルーチン[3]を実行するためのsyscallを思い出してみてください。カーネルルーチンをどうにかして自分で用意したルーチンへリダイレクトできれば、その用意したルーチンは即座にカーネルレベルのルーチンになります。カーネルルーチンのリダイレクトはどのようにすれば可能なのかについて考えてみましょう。ケースバイケースですが、殆どの場合カーネルルーチンが配置されるカーネル領域のモディファイが必要になります。


それはまるでジレンマです。カーネル特権を得るためにはカーネル特権が要求されるカーネル領域をモディファイしなければならないということだからです。これこそ

kxploitが必要な理由です。殆どの場合、kxploitはカーネル領域に値を書き込むことができてしまうというカーネルのバグのことです。


通常kxploitにはある種の制限が存在します。例えば6.39 kxploitの場合どこにでも0xFFFFFFFFという値が書き込めますが、6.20 kxploitの場合はその値が0×0です。こういったケースの場合アドレスのコントロールはできますが、そこに書き込む値はコントロールできません。とはいってもそれ以上のことは必要ないので実はそれで十分なのです。カーネル特権をチェックしたりルーチンのオフセットをロードするところを1文字変えるだけでカーネルルーチンのリダイレクトは可能になります。肝心なチェックポイントだけを変えてやることで自分で用意したルーチンのアドレスをロードしてコールできるようカーネルに命令を下せることができるようになります。


通常はカーネル領域にゼロの値を書き込みます。これはMIPSのゼロというのがNOP、つまりNo-operation(何もしない)を意味し、他のMIPS命令をマスクするのに都合が良いからです。


つまり、結論としてはこうです: カーネル領域の任意のアドレスにゼロという値を書き込む方法を探す必要がある。[4]


では、6.60 kxploitを詳しく見て行きましょう。


以下はsceNetMCopydataの1行です:



    0x00001DDC: 0x0C000C8C '....' - jal memcpy


memcpyの第1と第2引数に注目します。それぞれ行き先とデータのソースです。

規則[5]ではルーチンの第1引数である$a0を見てみます。


    ...

    ...

    0x00001D18: 0x00E09021 '!...' - addu $s2, $a3, $zr

    ...

    ...

    0x00001D98: 0x02402021 '! @.' - addu $a0, $s2, $zr

sceNetMCopydataの第4引数($a3)はmemcpyの行き先にあたります。引数に関してはチェックされません。そのためカーネル領域のアドレスを引数にセットすることが可能であれば…

しかし、sceNetMCopydataはユーザー領域へエクスポートできません。つまり直接コールすることができないということです。ところが運良くsceNetMCopydataはユーザー領域から簡単にアクセスできる他のsyscallからコールされるのです。ここではsceNetMPulldownがターゲットです。


ここでsceNetMCopydataをコールする方法を見つけるためsceNetMPulldownの主要部分を解析してみましょう。sceNetMPulldownでは2ヶ所でsceNetMPulldownをコールしています。ここでは0×00003018でのコールに注目します。その理由は0x00002E9Cでのコールがユーザーでは扱えないsceNetMallocInternalによって割り当てられるmbufへのデータコピーだからです。


既に述べた通り、ifhandleはmubfが実装されたものがベースになっていますので、参考としてオリジナルのFreeBSDのコードを入手することができます。ifhandleのライン間マッピングのことがこれで分かります。m_pulldownについては http://fxr.watson.org/fxr/source/kern/uipc_mbuf2.c?v=FREEBSD4 で分かります。


MIPSアセンブラについては詳しくなっておいてください。簡単に理解できるようコメントを多用してあります。



struct m_hdr {

struct mbuf *mh_next; /* next buffer in chain */

struct mbuf *mh_nextpkt; /* next chain in queue/record */

caddr_t mh_data; /* location of data */

int mh_len; /* amount of data in this mbuf */

short mh_type; /* type of data in this mbuf */

short mh_flags; /* flags; see below */

};


struct mbuf {

struct m_hdr m_hdr;

union {

struct {

struct pkthdr MH_pkthdr; /* M_PKTHDR set */

union {

struct m_ext MH_ext; /* M_EXT set */

char MH_databuf[MHLEN];

} MH_dat;

} MH;

char M_databuf[MLEN]; /* !M_PKTHDR, !M_EXT */

} M_dat;

};


#define mtod(m, t) ((t)((m)->m_data))

#define m_next m_hdr.mh_next // 0

#define m_len m_hdr.mh_len // c

#define m_data m_hdr.mh_data // 8

#define m_type m_hdr.mh_type // 10

#define m_flags m_hdr.mh_flags // 12


struct mbuf *sceNetMPulldown(struct mbuf *m, int off, int len, int *offp)

{

struct mbuf *n, *o;

int hlen, tlen, olen;

// fp = offp

// s6 = len

// s4 = m

// s2 = off

// s1 = n

//0x00002C10

if (m == NULL)

return NULL;

//0x00002C18

if (m 0x800) {

sceNetMFreem(m);

return NULL;

}

//0x00002C4C

n = m; // s1 = n

//0x00002C50

while (n != NULL && off > 0) {

if (n->m_len > off)

break;

off -= n->m_len;

n = n->m_next;

}

//0x00002C84

while (n != NULL && n->m_len == 0) {

n = n->m_next;

if (n < 0) //kernel space pointer?

return NULL;

}

//0x00002CB8

if (n == NULL) {

sceNetMFreem(m);

return NULL;

}

//0x00002CBC

if ((off == 0 || offp) && len m_len - off)

goto out;

//0x00002CE0

if (len m_len - off) {

goto loc_00003050; //not interested

}

//0x00002CEC

hlen = n->m_len - off; // s3 = hlen

tlen = len - hlen; // s7 = tlen

olen = 0; // v1 = olen

// s0 = o

//0x00002D00

for (o = n->m_next; o != NULL; o = o->m_next)

olen += o->m_len;

//0x00002D18

if (hlen + olen m_flags & 1)) {

//0x00002D3C

if (_lw(n + 0x34) != 0) {

// we can't go now

goto loc_00002D50;

}

//0x00002D4C

a2 = (_lw(n + 0x44) == n); // a2 MUST equal to 0

}

//loc_00002D50

if ((off == 0 || offp)) {

//0x00002D60

if ((m->m_flags & 1) == 0) {

// we have to stay here

goto loc_00003040;

}

//0x00002D7C

x = (_lw(n + 0x30) + _lw(n + 0x3c)) - (n->m_data + n->m_len);

// x is the macro M_TRAILINGSPACE

if (x >= tlen && a2 == 0) {

// finally...

//0x00003018

m_copydata(n->m_next, 0, tlen, mtod(n, caddr_t) + n->m_len);

}

}

}



見ての通り、コードはほとんどがmbufそのものです。

0×00003018のsceNetMCopydataに行くまでにいくつものトラップを回避しています。例えばm_flagsやm_len、m_nextがセットしてあるところなどです。一方で2つのmbufが互いに行き来できるようなリンクが必要です。自分で考えて欲しいのと、PRO CFWを見れば分かることなのでこのkxploitを有効にするにはどうすればいいのかについてはここでお話しするつもりはありません。

これはkxploitがどんなものなのかをお見せして、どうすればkxploitを見つけることができるのかをお見せするためのものです。今までに公開されたほとんどのkxploitはメモリーアドレスのチェックを無くすという同じような内容です。


理論的にはユーザー領域からカーネル領域のポインター(メモリーアドレス)はどれも有効になるはずです。しかし経験上PSPが発表されてから10年近く経ちますがまだこういったkxploitが存在しています。もちろんこういったkxploitを見つかることはめったにありませんし、場合によってはsyscallの制限[6]のため必ず有効なものとも限りません。


一方で他の種類のkxploitも存在します。カーネルメモリーのモディファイなしに直接コールすることでユーザーコードを有効にできるスタックオーバーフロー(プログラム中で関数呼び出しが多すぎる時に発生する脆弱性で、バッファオーバーフローの一種)もその一つです。次回はそのことについて触れてみましょう。


ところで、kxploitにはWindowsやLinuxのような主要なOSではありがちなヒープオーバーフロー(OSやアプリケーションが動的に確保するメモリ領域(ヒープ)からデータがあふれてしまう脆弱性で、バッファオーバーフローの一種)というものもあります。しかしPSPでは見つかったことも公開されたこともありません。いつかヒープオーバーフローの美しさもお見せできる機会があるといいですね。




【ソース:まもすけblog


う~ん。半分ぐらいしかわからないです。
関連記事
ブログパーツ
コメント
トラックバック
トラックバック URL
コメント
管理者にだけ表示を許可する
アクセスカウンター
検索フォーム
商品検索
サイト内検索
プロフィール


管理人:tomoki
ページランク
にほんブログ村 ゲームブログへ にほんブログ村 ゲームブログ ゲーム分解・改造へ にほんブログ村 ゲームブログ ゲーム情報へ にほんブログ村 音楽ブログ 音楽ダウンロードへ
Skype : tomoki122263
Twitter 本垢 :
Twitterブログ : iroiroblog
本垢と同じにしました。
My Twitter
Follow me
PSP改造
電動ガン・次世代ガン
動画
顔文字ボタン


トータルアクセスカウンター
ランキング
最新記事
PlayStation Vitaシステムソフトウェア
げん玉

■げん玉
下準備
げん玉とは?
ポイントの森
お友達紹介
ポイント交換方法
相互リンク
リンク