A Django site.
10月 14, 2008
» book review: XSS Exploits

結論: XSSの(現時点での)すべてをまとめた良書(ISBN-10: 1597491543)。

あのRSnake氏が書いた本ということでゲットした(死語)。まぁ、よく網羅したというか。基本的に、pentester向けの本なので、それが本職じゃないひとにはやや冗長かもしれない。でも、XSSの仕組みから具体的なexploitの作成、XSSがもたらすconsequenceまでが解説される過程で、攻撃者の豊かな想像力に圧倒され「中途半端な対策は無駄だ」と否が応でも悟らせる。自分は、防御側の方がはるかに困難で、だからこそやりがいもあると感じているひとなのだけど、これを読むとblack hatに(金銭的な側面を別としても)魅力を感じるのもわかる。この本の中で取り上げられているexploitはそのまま防御に役立つというわけではないけれど、攻撃者の思考や方法論を知ることはまったく役に立たないわけではない。でも、開発者としてXSS対策を学びたいというのであれば、この本にその直接的な回答はないので別の本を当たるべきだと思う。

ということで、pentester志望なら買え。今すぐ。「XSSってJavaScriptが実行されちゃうあれでしょ」としか理解していない開発者なら、XSSの潜在的な可能性を知るために買った方がいい。すでにXSSの破壊力を理解しているなら、防御側の視点に立った別の本にあたったほうがいいかも。480ページだけど、実質400ページクラスだと考えていい。通勤時間に1週間もあれば読める。

appendixにexploitableなURLをこれでもかというくらいに列挙しているんだけど、大丈夫なのかな。

9月 4, 2008
» ModSecurityネタでしゃべります

Tokyo Linux Users Groupのtechnical sessionで、GPLなWeb Application FirewallであるModSecurityについてお話しします。

内容はシステム管理者、Webアプリケーション開発者を対象に、ModSecurityのuse case、設置例、ルールの書き方、最近の新機能、テストや運用に役立つツールの紹介などです。今回はたっぷり時間があるので、Yokohama.pmで話した内容に大幅加筆しています。2本目のsessionがまだ未定ですが、LT形式で参加者に何かしゃべってもらおうという話もあります。話したいというひともぜひ。終了後は任意参加の懇親会もあります。Tokyo Linux Users Groupと名前は付いていますが、Linux、BSD、Solarisなどなんでもありです。お気軽にどうぞ。

UPDATE: LTはいっぱいみたいです

8月 22, 2008
» Yokohama.pm #2でしゃべってきた

お題は「mod_securityとParse::ModSecurity::AuditLog」でしゃべってきました。YAPCの容赦ない進行に恐れをなして、10分の制限時間で終われるように初めて事前にプレゼンのリハーサルしましたよ。実際には、ちょっと大目に見ていただけたようで、「時間が来たのでぶちっ」ということはありませんでしたが。

肝心のモジュールはまだCPANにあげてません。てか、CPANのアカウント申請してから音沙汰がないのであげられません。ということで、興味のある方はこちらからどうぞ。スライドもありますので、合わせてどうぞ。

結果はどうだったのかというと、「正直、むずかしいですねぇ」という反応が大勢で。ま、あまり期待はしていないというか、受け入れられるには時間がかかるだろうと予測はしているので、簡単にはあきらめません。あきらめない心が大事だってのは、この五輪で教わったしな!くじけない心でこの先も続けます。

super cookie問題は知っているひとはいたけど、public suffix問題については、あまり知られていないようだった。これについては自分でも書く予定。

次に話せる機会があれば、純粋にPerlのネタとかやりたいね。POEとか。securityネタは好きでやってるわけではないから。ま、そんなことを言っていてもしかたがないので、気持ちを切り替えて次のセミナーに向けて頑張ります。前回は即日満席でしたが、まだ空きはありますので、network securityに興味があるという奇特な人はぜひご参加ください。

最後に、会場を提供していただいたデジタルハリウッド様、運営の皆様、ありがとうございました。

7月 19, 2008
» mod_securityでif … then

特定の条件に特化したruleを書いていると、if … thenが欲しくなる。明示的に「こういう条件下でのみこれを評価しろ」と書きたいこともあるし、いちいちchainを書くのが面倒ということもある。これを実現するにはactionのskipとskipAfterを組み合わせる。

# if any arg matches "foo"...
SecRule ARGS "foo" "phase:2,t:none,t:lowercase,skip:1,pass,nolog"
SecAction "phase:2,pass,nolog,skipAfter:1000"

# then find "bar" in the args...
SecRule ARGS "bar" "phase:2,t:lowercase,deny,log"
# or buz...
SecRule ARGS "buz" "phase:2,t:lowercase,deny,log"

SecMarker 1000

よーするに、最初の条件にマッチしたら、skip 1で次のSecActionを無視して(つまりSecMarkerの部分までskip*しない*)、続く条件を評価する。

6月 3, 2008
» mod_security 2.5.xでLua

SecRuleScript (Experimental)にはそっけなくサンプルが書いてあるだけで、正確にどういうAPIなのかよくわからん(サンプルで確かに必要なことはわかるんだけど)。

ソースコードのmsc_lua.cを読むと、mがmod_securityとのインターフェースになってて、そのメソッド(?)には、log、getvar、getvarsがあるらしい。

static const struct luaL_Reg mylib[] = {
    { "log", l_log },
    { "getvar", l_getvar },
    { "getvars", l_getvars },
    { NULL, NULL }
};

適当にテストスクリプトを書いてみる。

function main()
    -- Retrieve script parameters.
    local vars = m.getvars("ARGS", {})
    for i = 1, #vars do
        m.log(0, "vars[" .. i .. "].name = " .. vars[i].name)
        m.log(0, "vars[" .. i .. "].value = " .. vars[i].value)
    end
    local var = m.getvar("ARGS", nil)
    m.log(0, "var = " .. var)
    local filename = m.getvar("REQUEST_FILENAME", nil)
    m.log(0, filename)
    return nil
end

httpd.conf(もしくはそれに相当するもの)の適切な箇所に以下を追加。

SecRuleScript "/path/to/script.lua" "deny"

で、apacheをrestartさせる。GET requestを発行。

> GET http://example.org/index.php?foo=bar&hoge=fuga&foo=buz

debug logの出力は以下。

vars[1].name = ARGS:foo
vars[1].value = bar
vars[2].name = ARGS:hoge
vars[2].value = fuga
vars[3].name = ARGS:foo
vars[3].value = buz
var = bar
/index.php
Rule returned 0

Luaはなぜかarrayが1-basedなので、最初の出力はvars[1]になってる。つまりこういうことなのか。

void log( int loglevel, string text )
string getvar( string name, [ string transformation | table { string transformation [, ... ] } ] )
table getvars( string name, [ string transformation | table { string transformation [, ... ] } ] )

transformationにはTransformation functionsが使えるみたい。で、return valueがtrueの場合、SecRuleScriptのactionが実行されると。これって、return valueを{ action = “action”, message = “message” }とかにした方がいいんじゃないかなぁ。設定でactionをhardcodeってイヤ。

インターフェースはsubject to changeらしいので、この先も同じという保証はない。nmapみたいにluaからpcreが使えるとうれしい。

5月 29, 2008
» mod_security 2.5をインストール

テスト環境をFreeBSD 7.0-STABLEにあげたついでに、先延ばしになってたmod_securityで遊ぶ。

2.5.xはminorアップグレードなんだけど、変更の多さはメジャー級。個人的には組み込みluaをサポートするSecRuleScript、クライアントの地理位置を条件にできるSecGeoLookupDB、output filterを使ったコンテンツのインジェクションが可能になるSecContentInjectionがおもしろそう。PDF XSS対策もできるらしい(Universal PDF XSS Revisited)。

まずはluaをサポートさせるのに、luaのライブラリをshared libでインストールしておかないといけない。defaultではsoを作ってくれないので、lang/luaにパッチ。

===> Generating patch
===> Viewing diff with more
diff -ruN --exclude=CVS /usr/ports/lang/lua/Makefile /usr/home/cherry/svk/ports/lang/lua/Makefile
--- /usr/ports/lang/lua/Makefile	2008-03-20 01:20:31.000000000 +0900
+++ /usr/home/cherry/svk/ports/lang/lua/Makefile	2008-05-31 20:27:59.000000000 +0900
@@ -7,7 +7,7 @@

 PORTNAME=	lua
 PORTVERSION=	5.1.3
-PORTREVISION=	1
+PORTREVISION=	2
 CATEGORIES=	lang
 MASTER_SITES=	http://www.lua.org/ftp/ \
 		ftp://ftp.tecgraf.puc-rio.br/pub/lua/ \
@@ -38,6 +38,13 @@
 		printf.lua readonly.lua sieve.lua sort.lua table.lua \
 		trace-calls.lua trace-globals.lua xd.lua

+.if defined(WITH_SHAREDLIB)
+LUA_LIB_VERSION=	0
+LUA_LIB_FILE=	liblua
+PLIST_SUB+=	LUA_LIB_VERSION=${LUA_LIB_VERSION}
+USE_LDCONFIG=	${LUA_LIBDIR}
+.endif
+
 post-patch:
 	@${REINPLACE_CMD} -Ee \
 		'/^INSTALL_.*=/s/INSTALL_TOP/prefix/ ; \
@@ -74,6 +81,13 @@
 # Libraries.
 	${MKDIR} ${LUA_LIBDIR}
 	${INSTALL_DATA} ${WRKSRC}/src/liblua.a ${LUA_LIBDIR}
+.if defined(WITH_SHAREDLIB)
+	${INSTALL_PROGRAM} ${WRKSRC}/src/liblua.so ${LUA_LIBDIR}/${LUA_LIB_FILE}.so.${LUA_LIB_VERSION}
+	${ECHO} "${LUA_LIBDIR}/${LUA_LIB_FILE}.so" | ${SED} 's,^${PREFIX}/,,' >> ${TMPPLIST}
+	${LN} -sf ${LUA_LIBDIR}/${LUA_LIB_FILE}.so.${LUA_LIB_VERSION} ${LUA_LIBDIR}/${LUA_LIB_FILE}.so
+	${ECHO} "${LUA_LIBDIR}/${LUA_LIB_FILE}.so.${LUA_LIB_VERSION}" | ${SED} 's,^${PREFIX}/,,' >> ${TMPPLIST}
+	${ECHO} "@dirrm ${LUA_LIBDIR}" | ${SED} 's,^${PREFIX}/,,' >> ${TMPPLIST}
+.endif
 # Manual pages.
 .for f in ${LUA_MAN}
 	${INSTALL_MAN} ${WRKSRC}/doc/${f} \
@@ -95,7 +109,7 @@
 .endif
 # lua.pc
 	${MKDIR} ${LOCALBASE}/libdata/pkgconfig
-	${INSTALL_DATA} ${WRKSRC}/etc/lua.pc ${LOCALBASE}/libdata/pkgconfig/lua-${LUA_VER}.pc
+	${INSTALL_DATA} ${WRKSRC}/etc/lua.pc ${PREFIX}/libdata/pkgconfig/lua-${LUA_VER}.pc
 # Module directories.
 	${MKDIR} ${LUA_MODLIBDIR}
 	${MKDIR} ${LUA_MODSHAREDIR}
diff -ruN --exclude=CVS /usr/ports/lang/lua/files/patch-src-Makefile /usr/home/cherry/svk/ports/lang/lua/files/patch-src-Makefile
--- /usr/ports/lang/lua/files/patch-src-Makefile	1970-01-01 09:00:00.000000000 +0900
+++ /usr/home/cherry/svk/ports/lang/lua/files/patch-src-Makefile	2008-05-29 20:16:13.000000000 +0900
@@ -0,0 +1,27 @@
+--- src/Makefile.orig	2008-05-29 19:24:46.000000000 +0900
++++ src/Makefile	2008-05-29 19:27:30.000000000 +0900
+@@ -31,12 +31,13 @@
+
+ LUA_T=	lua
+ LUA_O=	lua.o
++LUA_SO=	liblua.so
+
+ LUAC_T=	luac
+ LUAC_O=	luac.o print.o
+
+ ALL_O= $(CORE_O) $(LIB_O) $(LUA_O) $(LUAC_O)
+-ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T)
++ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) $(LUA_SO)
+ ALL_A= $(LUA_A)
+
+ default: $(PLAT)
+@@ -47,6 +48,9 @@
+
+ a:	$(ALL_A)
+
++$(LUA_SO):	$(CORE_O) $(LIB_O)
++	$(CC) -o $@ $(MYLDFLAGS) -shared $?
++
+ $(LUA_A): $(CORE_O) $(LIB_O)
+ 	$(AR) $@ $?
+ 	$(RANLIB) $@
===> Done

liblua.n.soにしなくていいのかという話もあるけれど、テスト環境なので。

UPDATE: WITH_SHAREDLIBでbuildするようにした。(てきとーだけど)バージョンもつけるようにした。

次に、www/mod_security2にパッチ。configureベースになったのはいいのだけど、libluaを見つけてくれない。test関連のファイルがコンパイルできないのでカット。

diff -ruN --exclude=CVS /usr/ports/www/mod_security2/Makefile /usr/home/cherry/svk/ports/www/mod_security2/Makefile
--- /usr/ports/www/mod_security2/Makefile	2008-04-11 23:33:37.000000000 +0900
+++ /usr/home/cherry/svk/ports/www/mod_security2/Makefile	2008-05-29 19:39:29.000000000 +0900
@@ -6,8 +6,7 @@
 #

 PORTNAME=	mod_security2
-PORTVERSION=	2.1.7
-PORTREVISION=	1
+PORTVERSION=	2.5.4
 CATEGORIES=	www security
 MASTER_SITES=	http://www.modsecurity.org/download/
 DISTNAME=	${PORTNAME:S/_//:S/2//}-apache_${PORTVERSION}
@@ -31,6 +30,8 @@
 DOCSDIR=	${PREFIX}/share/doc/${MODULENAME}
 SUB_FILES+=	mod_security2.conf
 SUB_LIST+=	APACHEETCDIR="${APACHEETCDIR}"
+HAS_CONFIGURE=	yes
+OPTIONS=	LUA "Embedded Lua language support (EXPERIMENTAL)" off

 .if !defined(SKIP_RULES)
 SUB_FILES+=	pkg-message.rules
@@ -66,6 +67,11 @@
 LIB_DEPENDS+=	pcre.0:${PORTSDIR}/devel/pcre
 .endif

+.if defined(WITH_LUA)
+CONFIGURE_ARGS+=	--with-lua=${LUA_LIBDIR}
+USE_LUA=	5.1+
+.endif
+
 post-patch:
 	@${REINPLACE_CMD} -e '\
 		s|SecRuleEngine On|SecRuleEngine DetectionOnly|; \
@@ -73,6 +79,11 @@
 		s|SecDebugLog.*logs/modsec_debug.log|SecDebugLog /var/log/httpd-modsec2_debug.log|; \
 		s|SecServerSignature "Apache/2.2.0 (Fedora)"|SecServerSignature "Apache/${APACHE_VERSION:C/[0-9]/\0./g}x (${OPSYS})"|; \
 		' ${WRKSRCTOP}/rules/modsecurity_crs_10_config.conf
+	# XXX prevent it from compiling
+	${RM} ${WRKSRC}/msc_test.*
+.if defined(WITH_LUA)
+	${REINPLACE_CMD} -e 's|%%LUA_INCDIR%%|${LUA_INCDIR}|' ${WRKSRC}/configure
+.endif

 post-install:
 .if !defined(NOPORTDOCS)
diff -ruN --exclude=CVS /usr/ports/www/mod_security2/distinfo /usr/home/cherry/svk/ports/www/mod_security2/distinfo
--- /usr/ports/www/mod_security2/distinfo	2008-04-08 12:23:57.000000000 +0900
+++ /usr/home/cherry/svk/ports/www/mod_security2/distinfo	2008-05-29 18:23:18.000000000 +0900
@@ -1,3 +1,3 @@
-MD5 (modsecurity-apache_2.1.7.tar.gz) = 19c34dd5611e0c516c0717de793f4640
-SHA256 (modsecurity-apache_2.1.7.tar.gz) = 3960aaa4a4f6087f990b0d25c3756c3a505f3b19a909e4724980dc5bbc583513
-SIZE (modsecurity-apache_2.1.7.tar.gz) = 679496
+MD5 (modsecurity-apache_2.5.4.tar.gz) = 9fe4d4cb481e00c2a49a65e59261f622
+SHA256 (modsecurity-apache_2.5.4.tar.gz) = be515456add43ecac6c441da1fcdb1ab94908ae6ff0c837854bcf141343932ae
+SIZE (modsecurity-apache_2.5.4.tar.gz) = 1071980
diff -ruN --exclude=CVS /usr/ports/www/mod_security2/files/patch-apache2-Makefile.in /usr/home/cherry/svk/ports/www/mod_security2/files/patch-apache2-Makefile.in
--- /usr/ports/www/mod_security2/files/patch-apache2-Makefile.in	1970-01-01 09:00:00.000000000 +0900
+++ /usr/home/cherry/svk/ports/www/mod_security2/files/patch-apache2-Makefile.in	2008-05-29 17:59:44.000000000 +0900
@@ -0,0 +1,20 @@
+--- Makefile.in.orig	2008-05-29 17:59:26.000000000 +0900
++++ Makefile.in	2008-05-29 17:59:41.000000000 +0900
+@@ -112,17 +112,6 @@
+ 	&& echo "See: mlogc-src/INSTALL" \
+ 	&& echo
+
+-### Experimental Test Framework (*NIX only right now)
+-msc_test.lo: msc_test.c
+-	$(LIBTOOL) --mode=compile $(CC) $(APXS_INCLUDES) $(APXS_CFLAGS) $(EXTRA_CFLAGS) $(MODSEC_EXTRA_CFLAGS) $(CPPFLAGS) $(APR_CFLAGS) $(APU_CFLAGS) -o msc_test.lo -c msc_test.c
+-
+-msc_test: $(TESTOBJS) $(MOD_SECURITY2_H}) msc_test.lo
+-	@objs=""; \
+-	for f in $(MSC_TEST); do \
+-		objs="$$objs $$f.lo"; \
+-	done; \
+-	$(LIBTOOL) --mode=link $(CC) $$objs -o msc_test msc_test.lo $(LDFLAGS) $(LIBS) $(APR_LINK_LD) $(APU_LINK_LD)
+-
+ test: t/run-tests.pl msc_test
+ 	@rm -f msc-test-debug.log; \
+ 	$(PERL) t/run-tests.pl
diff -ruN --exclude=CVS /usr/ports/www/mod_security2/files/patch-configure /usr/home/cherry/svk/ports/www/mod_security2/files/patch-configure
--- /usr/ports/www/mod_security2/files/patch-configure	1970-01-01 09:00:00.000000000 +0900
+++ /usr/home/cherry/svk/ports/www/mod_security2/files/patch-configure	2008-05-29 18:19:29.000000000 +0900
@@ -0,0 +1,11 @@
+--- configure.orig	2008-05-29 18:16:45.000000000 +0900
++++ configure	2008-05-29 18:18:56.000000000 +0900
+@@ -5620,7 +5620,7 @@
+                 lua_lib_name=""
+             fi
+         done
+-        for x in ${test_paths}; do
++        for x in ${test_paths} %%LUA_INCDIR%% ; do
+             if test -e "${x}/lua.h"; then
+                 with_lua_inc="${x}"
+                 break
diff -ruN --exclude=CVS /usr/ports/www/mod_security2/files/pkg-message.rules.in /usr/home/cherry/svk/ports/www/mod_security2/files/pkg-message.rules.in
--- /usr/ports/www/mod_security2/files/pkg-message.rules.in	2007-03-09 18:46:21.000000000 +0900
+++ /usr/home/cherry/svk/ports/www/mod_security2/files/pkg-message.rules.in	2008-05-29 19:02:18.000000000 +0900
@@ -8,3 +8,8 @@
 Please read http://www.modsecurity.org/projects/rules/index.html

 Logging is done to /var/log/httpd-modsec-*.log
+
+You need to add:
+    LoadFile %%PREFIX%%/lib/libxml2.so
+    LoadFile %%PREFIX%%/lua51/liblua.a
+before "LoadModule security2_module modules/mod_security2.so"
===> Done

httpd.confに追加。

LoadFile /usr/local/lib/libxml2.so
LoadFile /usr/local/lib/lua51/liblua.so
LoadModule security2_module   libexec/apache22/mod_security2.so

これで動く。動作確認ができるまではsend-prはおあずけ。

4月 25, 2008
» MOONGIFTがまたヤラレてた

[重要なお知らせ] MOONGIFTがハッキングされました

先日にも同様のお知らせをしておきながら、大変申し訳ありません。本日、MOONGIFTがハッキングされました。内容としては、GreeTz: XP HACKER〜という文字列と画像が表示されるものです(ウィルスアラートは出ず、ユーザへの実害はない模様です)。

前にも書いたけど、今度は何かなーと思ったら

ログに記載されていた内容は以下の通りです。[…] このログにもある、UltimateTagWarriorというプラグインのセキュリティホールをついたもの、[…] にあるwpSSのセキュリティホールをついたものの二つがありました。これにより、adminのパスワードが書き換えられ、その上で表示内容を変更したようです。

ログを開示しているように見えて、実は無関係なログ、という罠。ultimate-tag-warrior-ajax-js.phpにおける$ajaxurlの扱いを見るだけでも、あららーというコードなので、こいつが原因の一つだとしてもおかしくないのですけど(他のコードは見てません)。

テーマファイルは読み込みのみに設定

とあるのは、httpdの権限にファイルのwriteが可能だったのでしょうか。WordPressにはbrowserからテーマを書き換える機能があるので、その可能性はある。adminのパスワードが書き換えられてたそうなので、SQL injectionっぽいですが。実はallow_url_fopenがonになってるとかいう話だったりしませんか。だとしたら、この先もご愁傷様です。

WordPressはpluginに安全なAPIを提供できていないから(そもそも本体がアレだし)、pluginの穴も多い。だからpluginも極力使わない。

一応警告はしておきました、ということで。「オープンソースのほとんどはカス」と言われていますが、WordPressおよびその界隈はまさにその通りですから。

ここもいつヤラれてしまうかわからんから、早く移行したい。

2月 26, 2008
» 技術系listのRSS feed

いーかげん、メーリングリストが面倒になってきた。よっぽど興味があるものしかsubscribeしなくなってずいぶん経つ。発言しないのならアーカイブに目を通せばいいのだけど、どれもUIが違ったり使いにくかったりで、「あーRSSで全部読めれば楽なのに」とか思ってた。検索結果の中にforumっぽいのにMLのアーカイブというNabbleがあった。しかも全文RSS feedあるし!とりあえず雰囲気を追っかけたいだけなら、これで良さそう。

2月 23, 2008
» 自分ならシリーズ: インシデント対応

[重要なお知らせ] MOONGIFTにてウィルスが感知されました

本日、読者の方からのご指摘により判明したのですが、jWorkSheetという記事中において、ウィルスが検知されました。検知されたウィルスは以下のものです。大変申し訳ございません。

感染経路については、確定ではありませんがWordPressのXML-RPCのバグ(最新版では解決済みと思われます)をついたものと思われます。

なお、この問題についてはWordPressの最新版の適用と、問題になったXML-RPCについてもデフォルト名は利用しないように修正したことで解決したと思われます(まだ情報がおいきれておりません)。全てはMOONGIFTにおいてWordPressの更新を怠ったことが原因です。申し訳ございません。今後、同様の問題が発生しないよう、注意致します。

とりあえず「うちではよくわからんから、他をあたってくれ」というニュアンスについてはスルーの方向で。

いつからiframe埋め込まれてたのかもわからないんですかね。最悪、postの作成時刻から対応を終えた時刻までのログをひっくり返して、明らかなbotによるアクセスを除外すれば、影響を受けたおそれのあるユーザはわかるはず。疑ってる脆弱性があるスクリプトに対するPOSTアクセスもログに残ってるはずなので、確かめることもできるはず。あ、残念、POSTリクエストのbodyはaccess.logには残りませんね。でも、そんなに多いものではないだろうから、ある程度当たりはつけられるんじゃないですか。いずれにせよ、何が起きたのか突き止められそうにないなら、やっても無駄かもしれませんが。

問題のURLのJavaScriptはUPXで圧縮された複数のWindowsバイナリをダウンロードさせる。ClamAVはTrojan.Downloader-24394と言ってるので、一般的なbootstrapプログラムなんじゃないかな。知らんけど。

「アップデートしなかった」のが原因だと思い込んでるみたいだけど、WordPressはしょっちゅう穴が見つかるし、ここのWordPressだってどっかに出かけている間にやられてしまうおそれはある。だから「次からすぐにアップデートします」というのは再発防止策とはならない。

WordPressはpluginに安全なAPIを提供できていないから(そもそも本体がアレだし)、pluginの穴も多い。だからpluginも極力使わない。んで、mod_securityを使う。zero dayが出てきてもしのげるし、WordPress固有のルールを書くのは大変だけど、Core ModSecurity Rule Setだけでもだいぶ違う。Apacheの仕組みにPOSTのbodyを記録する機能はないけど、mod_securityならそれが可能。POSTのbodyは任意の長さだからすべて記録するのも現実的ではないかもしれない。けど、怪しそうなリクエストを記録するなら無理な話ではない。output filterも書けるから、iframeを絶対使わないなら、そのタグがHTTP responseに含まれてる場合はblockとかも可能。レンタルサーバでもroot権限があればこれくらいはできるし、Webの仕事が本業らしいからやる価値はあるんじゃないかな。

ここでWordPressを使いつづける理由は、惰性。何度か他への移行を試みたけれど、細かい差異の問題とかで、実現しないまま。たぶん、他に乗り換えてから、過去のpostは機能を削ぎ落としたWordPressで残すという方法しかないような気がしてる。仕事では絶対使わない。

11月 26, 2007
» 楽天テクノロジーカンファレンスに行ってみた

Sunの役員は何をしにきたのかよくわからんかった。二言目には「楽天さんに買っていただきたいのですが」って、営業は別の場所でやれよ。スライドにアメリカのネズミ使ってたけど、許可取ってんですかね。知らんけど。

あまりに暇だったので、kismetでごにょってみた。ユニークSSIDが100ちょい、ユニークMACアドレスが50ちょい。Intel強し。SuperMicroのprefixがあってちょっと驚いた。使わないならwirelessは切っておきましょう。

Rubyのまつもとさんの肩書きである「フェロー」って何よ、という疑問はわからずじまい。これはどうでもいいですね。進めているプロジェクトについては、どっかが書いていると思うので省略。成果はオープンなライセンスさせるという約束も取り付けているそうだし、なにより楽天の膨大なトラフィックはRubyのtest bedとして(言い方悪いけど)プロジェクトの財産になるでしょう。高負荷環境でしか再現しないbugとか、負荷が低いと問題にならなくても、高負荷だとデザインの問題点が出てきたりすっからなー。

まつもとさんも繰り返していた「楽天は技術の企業だと思われていない」点はちょっと違う気がする。あんだけのサイトで技術がまるでないなんてことはありえない訳で、能無しばかりの企業ではないことぐらい想像は付く。そうじゃなくて、「楽天はopennessが足りない」というイメージのほうが適切なんじゃないか。何千人技術者がいるのか知らんけど、思い浮かぶ楽天の技術者なんていない。LKLMやFreeBSD.orgでrakuten.co.jp探してもなにも出てこないし。自分にJavaやPHPの世界とのお付き合いがないからかもしらんね。今後、Rubyプロジェクトにフィードバックするそうだから、期待しておけばいいんだろうか。

武田さんのお話はガッカリ。初心者向けの内容だったから、という訳ではなくて、Web系の開発者が集まると思われるテクノロジーと名の付いたカンファレンスで、彼が選んだネタがあの内容だと思うとね。武田さんが思い描いた開発者らのawarenessはその程度なのかということに。おそらく、あちこちで話をしている人だから、きっとその判断は現状を反映しているんだろうな。そう考えると、セキュリティの不毛さを改めて考えてしまった。それとは別に「すでにご存知かもしれませんが」といちいち繰り返すのはいかがなものか。「そう思っているなら話すなよ」と突っ込んでしまうので。話すべきだと思うのなら話せばいいわけだし。

インフラの話に興味があったのだけれど、セールストークを聞いているみたいで、特筆すべきネタはなかった。STP使ってるって言ってたけど、困ったことなかったんだろうか。IPv6のリサーチ始める前に、DNS見直した方がいいと思う。

CSIRT始めましたつーネタで、9G+のトラフィックを監視してると言ってたけど、社員3人派遣2人でどの程度の監視ができてるんですかね。24時間体制じゃなかったりするのかなー。それともどっかに外注してるのか。セキュリティトレーニング、セキュリティQA、監査、フォレンジック、セキュリティ情報の収集、インシデント対応をやってるらしいけどさ、あの規模なのに専門部署が5人しかいないという悲しい現実です。

全体的に、姿勢はわかったからあとは行動で示してね、という感じ。おもしろいネタはあるだろうから、あとはどう外に発信できるか、でしょうか。まずは今回のproceedingsをwebで公開すること。話はそれからだ。

11月 19, 2007
» 3ヵ月ほどhoneypotを動かしてみた

Catalystにはまってた時期に書いたlow-interactiveなhoneypotをお客様に見せてあげたら、スゲースゲーうるさかったので、そんなものかなと思いつつ分かったことを書いてみる。

Catalystで書いたWeb apprication honeypotで、あらゆるHTTPリクエストを受け付けて、HTTP headerおよびbodyをすべて記録する。やってることはPHP.Hopとほぼ同じ。よく狙われそうな偽のWeb applicationを複数設置して、検索エンジンに引っかかるようにして、しばらく待つだけ。HTTP requestにURLっぽいものが含まれていれば、それをfetchしてClamAVでscanしてから中身を記録(コンテンツのhash値をprimary keyにしてる)。

PHP applicationっぽくしているせいかもしれないけど、ほぼすべてがregister globalかurl_fopenを狙ったPHP command inclusionのexploit。fetchした内容は、だいたいPHP.Shellかホストの情報を表示するPHP script。requestは1位がトルコ、2位がアメリカ(これはsearch engineのcrowlerが多い)、3位がサウジアラビア。4位が日本で(これもあるsearch engineのものが多数)、5位がインド。全般的に見て、中東からのアクセスが多い。それもbotではなくほんとにブラウザでアクセスしてるっぽい(HTTP headerから判断)。さすがにIEによるアクセス(UAの偽装は多いけど)は少ない。それから中東からのアクセスは、ある特有のheaderが付いていることが多い。たぶん、ISPレベルで透過的なproxyによる検閲がされている模様。大変ですね。今のところ、ゼロデイをひっかけるには至っていない。たまにアラビア語の掲示板で晒されたりしてる。

そもそもの目的は、IP addressをrbldnsdに喰わせてからmod_securityから参照して、spam対策その他に使おうと目論んでた。まだやってないけど。偽のWordPressとかMTを設置すれば、いい感じのDNSBLになりそうな気配。コメントspamはapplicationを叩かれたら負けだからね。

改善点は、fetch先のホストのIP addr.を国別で表示させる、もっと多くのWeb applicationを簡単に設置する、複数のhoneypotを一括管理する機能かな。

欲しい人いたらあげます。

9月 3, 2007
» SSLクライアント認証でFakeBasicAuthとSSLUserNameを使う

以前に、mod_dav_svnでSSL+client認証で書いたけど、SSLのclient認証(Client Authentication and Access Control)で、.htpasswdに

/C=JP/ST=Somewhere/L=Somewhere/O=Example CA/OU=myUnit/CN=user@example.org:xxj31ZMTZzkVA

とか書いたりするのに嫌になった。post-commitのメールも意味不明だし。ASF Bugzilla Bug 31418 SSLUserName is not usable by other modulesは依然として放置されているし、mod_sslに投稿されたSome changes in mod_ssl APIも放置。

patch-server-ssl_engine_kernel.cは2.2.4にきちんとあたらないので、修正。

--- modules/ssl/ssl_engine_kernel.c.orig        Fri Aug 31 10:25:34 2007
+++ modules/ssl/ssl_engine_kernel.c     Fri Aug 31 10:27:36 2007
@@ -858,7 +858,13 @@
         modssl_free(cp);
     }

-    clientdn = (char *)sslconn->client_dn;
+    if (dc->szUserName && *(dc->szUserName))
+    {
+    clientdn = ssl_var_lookup(r->pool, r->server, r->connection,
+                                      r, (char *)dc->szUserName);
+    if (!clientdn || !*clientdn) { return DECLINED; }
+    }
+    else { clientdn = (char *)sslconn->client_dn; }

     /*
      * Fake a password - which one would be immaterial, as, it seems, an empty

httpd.confのSSLの部分にSSLUserNameを追加。

SSLUserName SSL_CLIENT_S_DN_CN

ユーザ名はCNを使うことにする。これで.htaccessには

user@example.org:xxj31ZMTZzkVA

と書くだけでいい。これでlogも簡潔になった。

10.10.0.1 - user@example.org [31/Aug/2007:11:08:17 +0900] "PROPFIND /svn/module HTTP/1.1" 207 645

AuthzSVNAccessFile(Path-Based Authorization)を使っている場合は、こちらもユーザ名をCNのものに変更すること。

8月 29, 2007
» tide526.microsoft.comはMicrosoftのclient honeypotという仮説

Connection: Keep-Alive
Pragma: no-cache
Via: 1.0 SEA-PRXY-02
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
Accept-Language: en-us
Host: example.org
Referer: http://search.live.com/results.aspx?q=rolex&mrt=en-us&FORM=LIVSOP
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; WOW64; SV1; .NET CLR 2.0.50727)
UA-CPU: x86

どーみても、”rolex”で検索してでてくるはずのないページにこんなアクセスが。うそくさいヘッダだけど、whoisによると131.107.0.96はMSFTだそうです。More on tide526.microsoft.comによると、あちこちで同様のアクセスがあるらしい(google://tide526.microsoft.com google://site:www.webmasterworld.com+tide526.microsoft.com)。最近の(まともなサイトの)ログをひっくりかえしてみたけど、131.107.0.96からのアクセスはなし。/24からのアクセスはあった。google://FORM=LIVSOPとかも同類なのかな。

robots.txtも読まないし、ふつーのcrawlerではないのは間違いない。Referer:を偽装していることからも、ふつーのクライアントでもない。で、想像してみたのは、ごく一部で盛り上がっているclient honeypotではなかろうかと(Microsoft’s “monkeys” find first zero-day exploit)。

こんなことがわかるのも、こっちもhoneypotを使っているからなわけですが。