北海道苫小牧市出身の初老PGが書くブログ

永遠のプログラマを夢見る、苫小牧市出身のおじさんのちらしの裏

今日はShibuya.pm #11の日です

no Perl; use x86; *1ですので、Perlにそんなに興味がない方でも楽しめると思います!!(笑)

今日はユニバーサルアクセスを兼ねて内容を細か目に書いたのですが、書いてる本人もあまり理解してないので雰囲気だけ読み取って下さい・・・。誤りの指摘は大歓迎ですorz

4/23追記: 内容の補完のために、すぎゃーんメモさんとこのメモも合わせてどうぞ。

第一部 sandbox特集

バイナリ畑で捕まえて - inside lleval / dankogaiさん

  • バイナリ麦畑で捕まえて → lleval というサービス
  • デモ
    • Perlのコード(CSSの都合で動かない)
    • BASICのコード
    • postscript
    • Perl6 → 重いけど動く
  • 動かすのは簡単 → 不正なコードを動かされると困る → 捕まえて欲しい
    • 1分を越すとタイムアウトする
    • fork爆弾
    • 外部モジュール(syscall.ph)を経由したコード
    • LWPは動く(大抵のサービスでは許していない)
    • ファイルシステム → 何も見えない(中身を表示しない)
  • Inside lleval
    • シンプルなCGIchrootして動く
    • ディレクトリ構成は、シンプル
    • eval.pl (実行スクリプト)
    • /etcには、localtimeやprotocols、servicesだけ
    • ld-elfの親玉
    • 後は/usr/bin だけ。/usr/lib もない。
    • FreeBSDの nullfs を使っている ← ディレクトリに、マウントする機能
  • forkさせないテクニックは?? → FreeBSD::i386::Ptrace を利用
  • kazuhookuさんによる指摘
  • ファイルの書き込みができないようにしたい
    • pt_getregsによってレジスタを見る。
    • スタックの2番目の引数をチェックする
    • スタックにnull pointerを書けば、ファイルが開かれずに済む
  • 課題 → forkは引数をとらない・・・
    • SEGVで落とす
    • →$SIG{SEGV}を拾える
    • sigactionで止める。こちらは引数をとるので止めれる
  • SYS_mmapで0x00000000 に値を突っ込まれると困る(ぬるぽなので)
    • mmap も引数をとるので、OK
  • まとめ: 子供達には、思う存分遊んで頂きたい

The Perl Sandbox / tokuhiromさん

  • llevalはいいけど、FreeBSD専用(どこでも動く物が欲しい)
  • Sys::Protect →安全じゃないことが知られている
  • 動機: evalができるIRCが欲しい
  • 新しいプロセスを作って動かす作戦
    • IPC::Open3でforkし、時間が経ったらSIGKILL
    • vmのopcodeをマスクするといいでしょう
    • OP_system や OP_exec が、perl5 VMのopコードになってる
    • ↑これらをマスクすればOK
    • PL_op_mask や PL_ppaddr によって、任意のopコードを禁止できる
    • opsと言う組み込みモジュールがある。
    • -ops=systemとすると、systemを禁止できる
    • 組み込みなので簡単
    • Opcode.pm / PL_op_maskをマスクしてるだけ
  • DynaLoaderが非常に危険
    • XS/DLLを読む。XSはvmの外でシステムコールし放題
    • DynaLoader::boot_DynaLoader で呼べる
    • dl_find_symbol で myforkと言う名前で登録できてしまう
    • バイナリをpackしてdl_install_xsubに直接放り込むことも
  • JSON::XSやautoboxは安全、PadWalkerとかは危険
    • Devel::SafeEval / DynaLoaderのloadを、置き換える。
    • レキシカル変数に隠すのはあまりよくない
    • → DB::DBやtieやoverloadで突破できる
    • overload のstringfy は危険
  • Scalar::Util::blessedでチェック??
    • → 0や空文字列にblessすると、上記チェックは偽となる*2
  • tieで、@INCや%SIGとかtieすると非常に危険
    • tiedでチェック?
  • まとめ: Pure perlで書くと危険なので全てXSで書きました

How about Kindle hacking? / obraさん

英語で聞き取れませんでした・・・。

  • マインスイーパーが動く
  • いろんなフォーマットの文書を読みたい
  • GPSがある
  • ネットワーク で Mac Book につなげる
  • busyboxtelnetを使える
  • Kindle2とKindle1は少し違う
  • login prompt → root はだめ・・・
  • Kernelを再構築
  • NFSがあった
  • ロスコンパイルしなきゃ?? ARM build
  • apt-get で gccを入れる
  • PerlよりPythonのほうが楽っぽい
    • CPANがない → easy_installがあるが、全然easyじゃない
  • QtとPyQT → でもX11じゃない
    • HTMLサポートが、貧弱
  • Pythonコード書いた
  • 時間切れ(まだスライド結構あったみたいです)

第二部 x86 binary hacks

世界のセキュリティコンテスト(Capture the Flag)ってどんなもの? / kenjiさん

  • サーバを守ったり攻撃したり。戦争ゲーム
  • 問題
    • Binary、Exploit、Web、Forensic、Trivia
  • Binary
    • 例: 実行ファイルが配られて、パスワードを解析する問題
    • file + strings ← .koファイルっぽい
    • OSにロードしてみるとロードできない → 単体ロードできない
    • 動かせないので、静的デバッグ。解析してExploitコード
    • 難読可を解除 ← jmp命令があやしい
    • とび先は何もしてない ←回答者を騙す罠
    • IDTを書き換えて(sidt 命令)、システムコールフックしている
    • uprintfでパスワードが出るだろう。戻って解析して行く。
    • 00000B11があやしい。Exploitを作成
    • 0x5be90000を総当たり。パスワードが突き止められる。
  • 難読化はよく使われる
    • 難しい問題だと、逆アセンブラを失敗させる
    • jmpをpush,retや stc, jbに変換。無意味な命令を追加等
    • →jmp命令一個で済むものを、たくさんの命令にする。
    • 難読化によって、解析者を試す
  • Forensic問題
    • 例: 物理メモリのダンプイメージから、仮想メモリアドレスを答える(2007年の一番難しい問題)
    • 1. 何のシステムのメモリか特定
    • 2. プロセスを特定(先頭のバイトパターンが決まってる??)
    • 3. PDBを見て、物理メモリと仮想メモリを変換
    • foo.exe モジュール内をgrep。対応を見つけ、問題の文字列の位置から計算
  • Trivia問題
    • 例: x86の\xEB\xFEと同じ意味を持つPowerPCの命令は?
    • 環境によって、調べ方を考える
    • PS3Linuxを入れて動かしてもOK
  • まとめ: 世界のエンジニアと切磋琢磨できる

Native Client Hacks / Fukumori Daikiさん

  • ブラウザのサンドボックスが壊れている
    • Active X → なんでもあり。電卓起動とか
    • プログラムミスによって、脆弱性がつかれている
  • Google Native Client
    • x86バイナリを安全に実行する仕組み
    • nacl-gcc (gccにパッチをあてたもの)
    • ELFチックだが、ELFじゃない。ブラウザ上にNaclが載ってて具極
    • システムコールの発行が特殊 → トランポリン
  • 静的解析でintコールはできないので、自己書き換えコードで試してみる
    • ロード時のチェックは通る。
    • 動的チェックできちんと引っかかる
  • jmpは32バイト強制。中途半端なアドレスへのジャンプは封じられている
    • jmp先のコードも動的チェック(到達可能か)
  • スタックの制御
    • オーバフローが出て、実行できなくしている
  • 攻撃への耐性が強い → 色んな攻撃が失敗した
  • でも、電卓を実行してみる(計算は大事!)
    • 整数オーバフローを利用 →電卓実行できた
    • ↑今はもう直っている
  • 他のドメインからの情報を読みたい
    • 普通にdo_getfileで別のドメインのファイル取得はできない(試した当時は)
    • 先人に学ぶ → 画像をエンベッドすればいい(Google的には仕様)
    • ローカルに画像を保存できる。クロスドメインを突破
    • ↑報告して修正済
  • 環境変数の情報の取得
  • まとめ: サンドボックスは破られる。みんなで破れば強くなる。みんなで破りましょう!

Perl で学ぶ x86 アセンブラ入門 / takesakoさん

  • 16bit時代: MS-DOSの.comファイル形式
  • Win32API時代
    • Hello Worldのメッセージボックスが出るデモ
    • GOLFすると90byte程度のものが作れる
  • Win32::APIを使ってPerlで書く
    • 簡単にできる。デモ。
  • DynaLoaderを使ってやってみよう!
    • マシン語を直接指定
      • h(\x68)はpushの意
      • 後はpack使いまくりで
    • デモ → 動くよ!
  • DEP → リードオンリーの領域で実行できない制限。解除しとくこと*3
  • PerlベースのJITコンパイラを作ろう
    • 0xc3を使う
  • JIT
    • TRAPを使う。PERL_SIGNALS=unsafeを指定して実行しないと実行できない
  • INT3はWindowsでは動かない
    • UD2を利用 → ILLをトラップする
  • 64bit OSでは?
    • syscall命令が使われるようになった
    • CPUID CPUの名前を得られる
  • Inline::x86Linuxでは工夫が必要
    • x86_sub にコードを渡すだけ
    • 64bit判別法など

第三部 Perl Internals

use Acme::Perl::VM; / gfxさん

  • 復習
  • デモ
    • use Acme::Perl::VM::Runがなくても一緒じゃん?
    • デバグモードで実行 → opコードが表示される。動いてる!
  • Perl VM概要
    • スタックでやりとり
    • PPcode と呼ぶ
  • opコードを、 pushで実装
    • C実装は、PL_Stack_base ← @PL_stackで済む
  • 可変長引数 → マーカーを利用
  • Opcode → 手続きとデータを持った構造体
    • 例: OP_CONST: スタックに積む / 定数
    • 例: OP_COND_EXPR: 分岐 / 他の経路
  • Opcodeは連結リスト。木構造構文木
  • 説明してないこと → SVファミリ、スクラッチパッド、ブロック、コンテキスト、スコープ、一次変数とか
  • ソースを読んだ感想
    • 自動最適化とかはできそう
    • ByteLoaderは再考の余地がある
  • デモ
    • 関数呼び出しの例
    • まだshiftは実装してない
    • printだけなら簡単

CPUの気持ちは大事だけど、VMの気持ちも考えよう / Yappoさん

  • 申し込もうとしたら、すでに発表することが決まっていたらしい
  • B::Concise で、構文木が見れる
  • B::TerseはConciesにterseオプションでも同等
  • B::Deparse : Perlがどう解釈をしてるか
    • 例: warn (1+2) * (2-1) は、warn(3) * 1
  • Devel::Peek: Perlの世界の変数の中身
    • CURが実際に使われてる量。LENが確保されてる量(by dankogaiさん)
  • Scope::Upper : 上のスコープをいじれる
  • Devel::RunOpsAnalize : 実行しながらopコードの呼び出し回数を解析
    • デモ : print文、for文
    • 99 * 99 とかも、コンパイル時に展開してくれる
    • &foo、foo()、fooの違い → 同じ
    • メソッド呼び出し: $self, $class, can経由とか → canはやっぱりコスト高いね
    • use, require, do の違い
    • loopの違い → Cスタイルは明らかに遅い
  • まとめ: VMのことを考えるときりがない。それでもプロファイリングするならDevel::NYProfを使おう

Devel::BindPP をつかって簡単に C++Perl の拡張モジュールをつくろう! / tokuhiromさん

  • 初めに: SysProtectがなぜ駄目かを言い忘れてた → 全部脆弱
  • XSを使う理由 : Cのライブラリが使いたい。他、変態的hackとか
  • XSは簡単ってのは嘘
  • XSは外部DSLなので、覚えるのは大変
    • Python的なインデントとか(個人的にPythonは好きだけど)
    • ↑CODE: ブロック
    • カジュアルXSを目指す。XSを書きたくはない。
  • XS = C + macro + シュガー
  • Cのマクロが多過ぎる。暗号的
  • my_perl undefinde this functionとか。どうすればいいのかわからナイ
    • dTHXとかaTHX_ とかで直るけど、初心者はわからないでしょう
  • newSVpvのSVとpvは何の略??わかりにくい
    • SvREFCNT_inc_・・・とか覚えられない
  • v8の拡張は書きやすい。C++の学習コストは安価
    • XS()がエントリポイント。::は__に直す
    • pl::BootStrapCtx、pl::Package、とか書ける
    • newはxs_new
    • pl::Pointerとかクラスで書ける。
    • pl::Ctx c(1); → 引数を一個とる
    • キャストはas_pointer とか
  • BindPPは1ファイル。ヘッダファイル。
    • ドキュメントはdoxy。読んで下さい。
    • pl::Hashとか、わかりやすいメソッド名になってる
  • BindPPのソースを読んでも参考になる。
    • XSの書き方とか。Perlのドキュメントよりわかりやすいでしょう

第四部 Lightning Talks

Devel::NYTProf / clkaoさん

  • 台湾の方。Englishで。
  • 直す前に必ずプロファイル
  • Devel::DProf
    • サブルーチンレベルで分析
    • 時々セグフォる
  • Devel::NYTProf
    • DBI作者が作ってる
    • 行レベル、ブラックレベル、双方に対応
    • eval内でも動いてくれる
  • PHPでのcalltree → グラフィカルに見れる
    • nyprof + kcache--- → 同じことできる
  • Jiftyでリクエストごとの分析

マルウェアの検出 / sonodamさん

ブラマンのブラックな話 / isidaiさん

  • 先月まで現役高校生
  • ブラッディマンディ→漫画+ドラマ化
    • なぜか主人公は攻撃先のサーバ情報を知っている
    • ハッキングシーンがまともに作られている。脆弱性も実在するもの。
    • 例: telnet脆弱性 "-froot" ユーザ名
    • 例: camera_hijack.pl
    • まとめ: 不正アクセス禁止法に触れるので、やらないでね

5分で danbot server を立ち上げる方法 / Yappoさん

  • IRC上でsafeなevalができるサーバ
    • セキュリティが破られると、色々される
    • xenですると安全でしょう
    • コマンドでインストール。ググると出ます。3分待つ
  • 時間があるのでHatetterの話をする
    • はてなお気に入りアンテナ → 便利なナイスなツール
    • POSTした時間がプライバシーのうんぬんで消えてしまった・・・
    • 気になるユーザの情報を勝手に追跡!便利!
  • 構成
    • HTTP::Engine + Q4M + memcached
    • nonblocking
    • Data::Model::...::Q4Mを作ったので使うといい
    • mashupサイトはデータベース使ったら負け
  • インストール終わった。次はモジュール必要
    • local::libに色々入れてあるものを用意している
  • 完成!動いた。

Windowsユーザのための初めてのPerlプログラミング / HASEGAWA Yosukeさん

  • Perl → Active Perlでどうぞ
  • Win32::API でOK
  • x86コード
  • x86コードからPerlのコードを呼ぶ。
    • シグナルハンドラで
    • BREAK_EVENTの時はPerlのコードを呼ぶ感じ
  • シグナルを使ったプロセス内通信 / シグナルの使い分け
    • バッドシグナル通信
  • Win32::API::Callbackでできる
    • Perlバイナリの世界の引数も受け取れる
    • シグナルより自然
  • stdcall以外のDLL関数呼び出し
  • unpackのprintfdebugバンザイ

閉会の挨拶

今日の内容は、わからなくて普通です(id:TAKESAKOさん談)。

*1:「今回のプログラムは XS Nite のときよりも低レベルになる予定です」って初心者向けなのかと捉えてたんですが、これはやっぱりもしや・・・。 → やっぱりそう言うことでしたorz

*2:audreyさんがよく使うらしい

*3:危険なので試すとき以外はやらないこと

*4:最近は攻撃は流行ってないとのこと