よっしゃ、ブログ復旧したな。
超久々に超まともな記事を書いてやろう。
*事の発端
子供A「助けてお兄さん!悪いおじさんたちに追われてるの!!」
俺「なに?どんなやつにおわれt」
うん。ごめん。
掲示板がバグらされるからどうにかしてくれと某人から言われたのでその配布元からソースDLしてみたらPHPのコードが暗号化(暗黒微笑)されてたというお話。
詳しくは追記のほうで。
超久々に超まともな記事を書いてやろう。
*事の発端
子供A「助けてお兄さん!悪いおじさんたちに追われてるの!!」
俺「なに?どんなやつにおわれt」
うん。ごめん。
掲示板がバグらされるからどうにかしてくれと某人から言われたのでその配布元からソースDLしてみたらPHPのコードが暗号化(暗黒微笑)されてたというお話。
詳しくは追記のほうで。
まず問題の掲示板はこちら。
http://jubei.co.jp/bbs/
バグ内容としては、ログデータがズレるというものだ。
データがファイル管理されているので、区切り文字を滑り込ませることができるとかいうアレだろなと検討がついた。
ファイル見てもらえばわかるようにメインスクリプトが暗号化(獄爆微笑)されている。
とりあえず復号化しないとどうしようもないので、復号化した。
まずこの手のスクリプト言語の暗号化(悶殺微笑)は
*ソースコードを文字列として、別の文字列に変換する(キーとXORかけるだとか、もっと単純だとファイルサイズを犠牲にしてbase64かけるとか)
*evalで評価する
という方法と相場が決まっている。
今回もそのまんまでした。しかも暗号化(憐憫微笑)が自動化できるように2ステップに分かれてた。
「eval」を探すと謎の変数で定義された関数に文字列を渡していた。
渡している文字列のパターンもそうだけど、最後に=がついてるあたりでbase64臭がプンプン漂う。とりあえずどんな文字列をevalってるか調べるために謎変数$OOO0000O0を追ってみた。
と、その前に変数名がOと0で難読化されてるので今後適宜別名をつけていく。今回のは$decoded4としよう。
$decoded4こと$OOO0000O0は最初から2番目に定義されている。
しかしそれは$OOO000000に代入されている文字列の特定の1文字を連結して作っているようなのでまずこれを復元しないことにはダメだ。
$OOO000000の内容は特に問題なさげなので、直後にprintさせると
fg6sbehpra4co_tnd
という文字列が出てきた。
そして次に書かれてる定義どおり、この文字列の4,9,3,5,2,10,13,16番目を連結させると「base64_d」になる。やっぱりbase64だったようだ。
そしてこの文字列からも切り出したりしてるようで、最終的に$decoded4は「base64_decode」になった。順当ですね。
同様に、この後で定義している変数を最初のurldecodeの文字列から作ったりしたところ、fopen/fget/fgets/fgetc/fread/strtr等が出てきた。この時点で、return;?>後のデータもbase64かそれをさらに変換したデータであると推測。strtrがあるからなんらかの変換は行われていそう。
さてevalの中身を実行したところ、自身を開いたのち、0x49aバイトを捨てていた。これはおそらくreturn;?>までの部分だろうし、実際計るとそうなっていた。そしてその次から0x17cバイト読み込み、strtrで
'EnteryouwkhRHYKNWOUTAaBbCcDdFfGgIiJjLlMmPpQqSsVvXxZz0123456789+/='
を
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
に変換してbase64_decodeかけてまたまたevalしていた。
その中身は同様に、自身からさらに0x11804バイト読み込みーのstrtr変換しーのbase64_devodeしーのevalーのだった。ちったぁ手法変えるなりしてヒネれよ。
そしてめでたく生ソースファイルゲット。
いろいろ見ていくうちに1758行目の
$val = str_replace('/<>/','',$val);
が原因と判明。
str_replaceは正規表現による置換じゃないので、スラッシュで変換対象を囲う必要がないのに囲っていた。
つまり、<>を消そうと思っていたのに/<>/を消していたのだ。暗号化(翔寂微笑)する暇あったらテストぐらいしろ。
というわけで、公式が修正するまで修正版うpしとくね。
PHP掲示板0.22バグFIX版
インデントつけてたけど飽きたから途中までだよ。
拡張子phpにしてね。
追記の追記。
ん?str_replace?と思ったので、投降データに<<>>を入れたところ、見事にログがズレた。ダメじゃん。修正版(凶禽微笑)
というわけで該当行を
while(strpos($val,'<>') !== false) $val = str_replace('<>','',$val);
にした。
PHP掲示板0.22バグFIX版2
http://jubei.co.jp/bbs/
バグ内容としては、ログデータがズレるというものだ。
データがファイル管理されているので、区切り文字を滑り込ませることができるとかいうアレだろなと検討がついた。
ファイル見てもらえばわかるようにメインスクリプトが暗号化(獄爆微笑)されている。
とりあえず復号化しないとどうしようもないので、復号化した。
まずこの手のスクリプト言語の暗号化(悶殺微笑)は
*ソースコードを文字列として、別の文字列に変換する(キーとXORかけるだとか、もっと単純だとファイルサイズを犠牲にしてbase64かけるとか)
*evalで評価する
という方法と相場が決まっている。
今回もそのまんまでした。しかも暗号化(憐憫微笑)が自動化できるように2ステップに分かれてた。
「eval」を探すと謎の変数で定義された関数に文字列を渡していた。
渡している文字列のパターンもそうだけど、最後に=がついてるあたりでbase64臭がプンプン漂う。とりあえずどんな文字列をevalってるか調べるために謎変数$OOO0000O0を追ってみた。
と、その前に変数名がOと0で難読化されてるので今後適宜別名をつけていく。今回のは$decoded4としよう。
$decoded4こと$OOO0000O0は最初から2番目に定義されている。
しかしそれは$OOO000000に代入されている文字列の特定の1文字を連結して作っているようなのでまずこれを復元しないことにはダメだ。
$OOO000000の内容は特に問題なさげなので、直後にprintさせると
fg6sbehpra4co_tnd
という文字列が出てきた。
そして次に書かれてる定義どおり、この文字列の4,9,3,5,2,10,13,16番目を連結させると「base64_d」になる。やっぱりbase64だったようだ。
そしてこの文字列からも切り出したりしてるようで、最終的に$decoded4は「base64_decode」になった。順当ですね。
同様に、この後で定義している変数を最初のurldecodeの文字列から作ったりしたところ、fopen/fget/fgets/fgetc/fread/strtr等が出てきた。この時点で、return;?>後のデータもbase64かそれをさらに変換したデータであると推測。strtrがあるからなんらかの変換は行われていそう。
さてevalの中身を実行したところ、自身を開いたのち、0x49aバイトを捨てていた。これはおそらくreturn;?>までの部分だろうし、実際計るとそうなっていた。そしてその次から0x17cバイト読み込み、strtrで
'EnteryouwkhRHYKNWOUTAaBbCcDdFfGgIiJjLlMmPpQqSsVvXxZz0123456789+/='
を
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
に変換してbase64_decodeかけてまたまたevalしていた。
その中身は同様に、自身からさらに0x11804バイト読み込みーのstrtr変換しーのbase64_devodeしーのevalーのだった。ちったぁ手法変えるなりしてヒネれよ。
そしてめでたく生ソースファイルゲット。
いろいろ見ていくうちに1758行目の
$val = str_replace('/<>/','',$val);
が原因と判明。
str_replaceは正規表現による置換じゃないので、スラッシュで変換対象を囲う必要がないのに囲っていた。
つまり、<>を消そうと思っていたのに/<>/を消していたのだ。暗号化(翔寂微笑)する暇あったらテストぐらいしろ。
というわけで、公式が修正するまで修正版うpしとくね。
PHP掲示板0.22バグFIX版
インデントつけてたけど飽きたから途中までだよ。
拡張子phpにしてね。
追記の追記。
ん?str_replace?と思ったので、投降データに<<>>を入れたところ、見事にログがズレた。ダメじゃん。修正版(凶禽微笑)
というわけで該当行を
while(strpos($val,'<>') !== false) $val = str_replace('<>','',$val);
にした。
PHP掲示板0.22バグFIX版2
| ホーム |
copyright © 2005 GEEKy Script Writer [perl and more!] all rights reserved.
Powered by FC2ブログ.
FC2ブログ
Powered by FC2ブログ.
FC2ブログ