ikepyonのお気楽な日々〜技術ネタ風味〜 このページをアンテナに追加 RSSフィード

気になった日々のニュースとメモのためのリンクと戯言のページ

To Do(というかやりたいこと。何時終わることやら)
-ITIL導入のための成熟度チェックシートみたいなの(あると便利だよね?)
-Hacknotes Web Security Portable Reference和訳(出版社募集中)
-Webアプリケーションセキュリティ検査ツールの改良(一応完成)
-Hacker HighSchoolの資料の日本語訳
-OSSTMMの日本語訳
-「燃えるセキュアプログラミング」若しくは「サルでも分かるセキュアプログラミング」とか書いてみたいなぁみたいな。

これだけはチェックしときなはれ!!受入れテスト用セキュリティチェックリスト公開中
Webアプリケーションセキュリティはてなぐるーぷ(テスト中やで)
SQL Injectionの仕組みと対策公開中
RSS feed meter for http://d.hatena.ne.jp/ikepyon/
Secure Coding に入ろう!! [MLの詳細]
メールアドレス
SKUF Meeting なかのひと

2008-12-29 規制中

というわけで、実家に帰ってきた。

[]趣味検査ツール作成 趣味の検査ツール作成を含むブックマーク 趣味の検査ツール作成のブックマークコメント

http://d.hatena.ne.jp/teracc/20081227

id:ripjyrさんに突っ込まれてますが、アプローチの仕方が違いますね。

私は、なるべく自動で検出できるように、多少送信パターンが増えてもいいという考え&テスト環境に対してテストを実施するというコンセプトで考えています。

また、根本的な考え方として、エラー発生時と正常時ではレスポンスタグ構造が違うだろうと想定しています。もっとも、この手法では検出できないケースもあるかと思うけど。

検出手法は、以下の日記を参考に

http://d.hatena.ne.jp/ikepyon/20070702

http://d.hatena.ne.jp/ikepyon/20041129

http://d.hatena.ne.jp/ikepyon/20041124

http://d.hatena.ne.jp/ikepyon/20080411

SQLインジェクションでは「'」と「''」のレスポンスの違いで確認するけど、場合によってはわからんけどな。

teraccteracc 2009/01/04 01:01 ご無沙汰してます。寺田です。

> 私は、なるべく自動で検出できるように、多少送信パターンが増えてもいいという考え&テスト環境に対してテストを実施するというコンセプトで考えています。

この辺りは1日に検査しなければならないボリュームや、アプリケーションの応答速度などによります。実際のところ、検査パターンを絞り込まないと、シビアなケースではツールをまわすだけでかなりの時間を取られてしまいます。

> また、根本的な考え方として、エラー発生時と正常時ではレスポンスのタグの構造が違うだろうと想定しています。もっとも、この手法では検出できないケースもあるかと思うけど。

少なくともOSコマンドインジェクションに関しては、その前提は置かない方がよいと思います。メールを送るためにshellを叩くアプリなどは、その前提を置くと検出できないケースがかなりあると思うので。その前提を置かずに検出できる方法を模索した結果があれなんですね。

ikepyonikepyon 2009/01/05 10:23 寺田さんのコンセプトはAuditの補助に使用するツールですもんね。私のは開発者がテストに使うというコンセプトなんで、速度はあんまり考えてませんw
確かにOSコマンドインジェクションではエラー発生時と正常時のレスポンスの違いでは検出できないと思います。したがって、このケースでは、対象のアプリサーバから、TCP接続要求がツール側に発生したかどうかで検出してます。
これも、Firewallの内側で使うと言うことが前提だから意味あることですけどねw

h-fujitah-fujita 2009/01/06 09:03 本年もよろしくお願いいたします。h-fujitaと申します。
今回の記事とそれに対するコメント、興味深く拝見いたしました。検査ツールの志向を開発者よりに振るのか、監査者よりに振るかでかなり変わってきますね。そして、それにより、検査ツールに求める操作性や検出能力も変わってきますね。
一個のツールで万人向け、というのは作れないとは思いますが、せめてそういう方向に向けたものを、自分でもつくれればなぁ、と思ってます。 UNIXがコマンドライン中心だったころの小気味よいコマンド群のようなものがあればなぁ、と思っています。

トラックバック - http://d.hatena.ne.jp/ikepyon/20081229

2008-12-24 コードは踊る

[]MySQLのPreparedStatement MySQLのPreparedStatementを含むブックマーク MySQLのPreparedStatementのブックマークコメント

というわけで、実証コード例を作った。SQLインジェクションが発生していれば、「result:0」にはならない。

徳丸さんのサンプルコードをパクって見たw(Thx:徳丸さん)

import java.sql.*;

public class TestUnicode {

  /**
   * @param args
   */
  public static void main(String[] args) throws Exception {
        try {
          String charEncoding = "sjis";
          Class.forName("com.mysql.jdbc.Driver");
          Connection con = DriverManager.getConnection(
            "jdbc:mysql://localhost/test?user=root&useUnicode=true&characterEncoding=" + charEncoding);
          Statement stmt = con.createStatement();

          String param = "\u00a5'or 1=1#";

          stmt.execute("create table if not exists test (name text, id INT UNSIGNED NOT NULL AUTO_INCREMENT, primary key(id));");
          stmt.execute("insert into test (name) values ('test');");
          stmt.execute("insert into test (name) values ('test2');");
          String sql = "SELECT count(*) FROM test WHERE name = ? ;";
          PreparedStatement preparedStmt = con.prepareStatement(sql);
          
          preparedStmt.setString(1, param);
          ResultSet rs = preparedStmt.executeQuery();
          while(rs.next()){
            int id = rs.getInt(1);
            System.out.println("result:" + id);
          }
          stmt.close();
          preparedStmt.close();
          con.close();
        } catch (Exception e) {
          e.printStackTrace();
        }
  }

}

[]クライアントサイドのPreparedStatementの問題点 クライアントサイドのPreparedStatementの問題点を含むブックマーク クライアントサイドのPreparedStatementの問題点のブックマークコメント

クライアント側のPreparedStatementでは、クライアント側で文字列結合でSQL文を作成し、そのSQL文をDBに送信する。

文字列として取り扱うので、リテラルを結合する際、メタ文字がある場合、適切なエスケープ処理を行わなければならない。

パラメータ言語側で使用しているデータ)の文字コードDBで取り扱っている文字コードと同じ場合は、適切なエスケープ処理さえしておけば問題ない。しかし、これらのコードが異なる場合、文字コードの変換処理が必要となる。

UTF-8から他の日本語文字コードに変換すると一部の文字でn:1の変換されることがある。このため、正しい処理方法は、文字コードの変換処理->エスケープ処理である(そうしないとエスケープすべき文字が文字コード変換によってエスケープされずに残る可能性がある)。しかし、MySQLJDBCではエスケープ処理->文字コードの変換処理が行われているため、PreparedStatementを使用していても、SQLインジェクションが発生することがある。

今回発見したのは、MySQLJDBC依存するものだったけど、他にも同様の処理を行っている場合に発生することがある。したがって、クライアントサイドのPreparedStatementを使用している場合は注意が必要。

最も、DBインターフェース文字コードを同じにしておけば問題は発生しないと思われるけど・・・最近携帯PCで同じDB使っていることがあるから、PC携帯文字コードが違う場合は注意が必要かな。

[]誰ですか? 誰ですか?を含むブックマーク 誰ですか?のブックマークコメント

http://openmya.hacker.jp/hiki/hiki.cgi?一人寂しくクリスマスを過ごす会

なんてとこから飛んできた人は?手を挙げなさいw

2008-12-23 ガーシュウィンいいなぁ

[]MySQLのPreparedStatement MySQLのPreparedStatementを含むブックマーク MySQLのPreparedStatementのブックマークコメント

MySQL4.1以降でないとサーバーサイドPreparedStatementはサポートされていないようだ。

http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html

http://dev.mysql.com/doc/refman/5.1/ja/connector-j-reference-implementation-notes.html

従って、昨日書いたようなコードになっている模様。

PreparedStatement

PreparedStatements は、MySQL がプリペアド ステートメント機能を持たないため、ドライバによって実装されます。これにより、ドライバクライアントの完全な SQL のパーサを持つことが要求されるため、ドライバは getParameterMetaData() または getMetaData() を実装しません。

MySQL Connector/J 3.1.0 からは、サーバ側プリペアド ステートメントおよびバイナリ エンコードされた結果セットは、サーバがそれらをサポートする場合に使用されます。

http://dev.mysql.com/doc/refman/5.1/ja/connector-j-reference-implementation-notes.html

となっているので、サーバーサイドPreparedStatementが使える場合には使うはずなんだけど、徳丸さんの検証からは使ってないように見えるなぁ。

昨日見つけたコードMySQL Connector/J 5.1 なんだけど・・・

(追記)

5.1ではデフォルトではサーバーサイドPreparedStatementを使用しないようになっているらしい。

http://dev.mysql.com/doc/refman/5.1/en/cj-news-5-1-0.html

http://www.geminium.com/chiba_blog/2008/12/23/33/

というわけで、一安心?

トラックバック - http://d.hatena.ne.jp/ikepyon/20081223

2008-12-22 寝れん刈田orz

[]JavaMySQLの組み合わせでUnicodeのU+00A5を用いたSQLインジェクションの可能性 JavaとMySQLの組み合わせでUnicodeのU+00A5を用いたSQLインジェクションの可能性 を含むブックマーク JavaとMySQLの組み合わせでUnicodeのU+00A5を用いたSQLインジェクションの可能性 のブックマークコメント

http://www.tokumaru.org/d/20081222.html#p01

PreparedStatementに関することが書いていないので、参考まで。

http://d.hatena.ne.jp/ikepyon/20061215#p2

http://d.hatena.ne.jp/ikepyon/20070216#p1

http://d.hatena.ne.jp/ikepyon/20061208#p2

ま、一文だけだけどなw

一応実証したところ、MySQL4.0ではPreparedStatementを使用してもUnicodeのU+00A5を使用した攻撃は有効。

ただし、MySQL5.xでは無効。

その後の確認で、MySQLJDBCとは全く関係なかったということも追記しとく。同じJDBCで4.xでは発生したけど、5.0では発生しなかった。なので、原因はMySQL4.0側のPreparedStatement関連がタコなことらしい。

ということで、最新のものにしときましょう。

(追記)

徳丸さんのところで追試した結果、MySQL5.1でもPreparedStatementがだめだったらしい。うーん、そうなると何が依然やったときダメだったんだろう?

(追記ソノに)

最新のMsSQLJDBCでは、デフォルトではサーバーサイドPreparedStatementを使用しないらしい。以前のバージョンでは使える場合は、デフォルトサーバーサイドPreparedStatementを使用していたようだ。

そのため、サーバーサイドPreparedStatementが使用できるMySQL5.xでの、私の検証では問題が無かったようだ。

[]MySQLJDBC MySQLのJDBCを含むブックマーク MySQLのJDBCのブックマークコメント

と言う疑問がわいてきたので、ざっとソースを確認してみた。

PreparedStatement関連はcom.mysql.jdbc.PreparedStatement.javaかなぁと思ってsetStringメソッドを見てみた。

	public void setString(int parameterIndex, String x) throws SQLException {
		// if the passed string is null, then set this column to null
		if (x == null) {
			setNull(parameterIndex, Types.CHAR);
		} else {
ちょっと割愛
			String parameterAsString = x;
			boolean needsQuoted = true;
			
			if (this.isLoadDataQuery || isEscapeNeededForString(x, stringLength)) {
				needsQuoted = false; // saves an allocation later
				
				StringBuffer buf = new StringBuffer((int) (x.length() * 1.1));
				
				buf.append('\'');
	
				//
				// Note: buf.append(char) is _faster_ than
				// appending in blocks, because the block
				// append requires a System.arraycopy()....
				// go figure...
				//
	
				for (int i = 0; i < stringLength; ++i) {
					char c = x.charAt(i);
	
					switch (c) {
					case 0: /* Must be escaped for 'mysql' */
						buf.append('\\');
						buf.append('0');
	
						break;
	
					case '\n': /* Must be escaped for logs */
						buf.append('\\');
						buf.append('n');
	
						break;
	
					case '\r':
						buf.append('\\');
						buf.append('r');
	
						break;
	
					case '\\':
						buf.append('\\');
						buf.append('\\');
	
						break;
	
					case '\'':
						buf.append('\\');
						buf.append('\'');
	
						break;
	
					case '"': /* Better safe than sorry */
						if (this.usingAnsiMode) {
							buf.append('\\');
						}
	
						buf.append('"');
	
						break;
	
					case '\032': /* This gives problems on Win32 */
						buf.append('\\');
						buf.append('Z');
	
						break;
	
					default:
						buf.append(c);
					}
				}
	
				buf.append('\'');
	
				parameterAsString = buf.toString();
			}

			byte[] parameterAsBytes = null;

			if (!this.isLoadDataQuery) {
				if (needsQuoted) {
					parameterAsBytes = StringUtils.getBytesWrapped(parameterAsString,
						'\'', '\'', this.charConverter, this.charEncoding, this.connection
								.getServerCharacterEncoding(), this.connection
								.parserKnowsUnicode());
				} else {
					parameterAsBytes = StringUtils.getBytes(parameterAsString,
							this.charConverter, this.charEncoding, this.connection
									.getServerCharacterEncoding(), this.connection
									.parserKnowsUnicode());
				}
			} else {
				// Send with platform character encoding
				parameterAsBytes = parameterAsString.getBytes();
			}

			setInternal(parameterIndex, parameterAsBytes);
			
			this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.VARCHAR;
		}
	}

えーと、「'」とか「¥」をエスケープしてからコード変換かけているように見えるんですが・・・

ちなみにStringUtils.getBytesWrappedでパラメータデータ文字コード変換をやっているようだ。

やっぱり検証しないといけないかなぁ?

トラックバック - http://d.hatena.ne.jp/ikepyon/20081222

2008-12-11 風邪流行中?

[]無線LANセキュリティの強化書 無線LANセキュリティの強化書を含むブックマーク 無線LANセキュリティの強化書のブックマークコメント

http://hackerjapan.blog55.fc2.com/blog-entry-109.html

というのが出るらしい。無線LANはあんまし追ってないからなぁ

と、モニター目当てで書いてみるw

トラックバック - http://d.hatena.ne.jp/ikepyon/20081211

2008-12-10 ねむい

資料作りが進まないorz

[]Software Security:Being Secure in an Insecure World Software Security:Being Secure in an Insecure Worldを含むブックマーク Software Security:Being Secure in an Insecure Worldのブックマークコメント

http://www.isc2.org/uploadedFiles/(ISC)2_Public_Content/Certification_Programs/CSSLP/CSSLP_WhitePaper_3.pdf

後で

トラックバック - http://d.hatena.ne.jp/ikepyon/20081210

2008-12-08 眠い このエントリーを含むブックマーク このエントリーのブックマークコメント

トラックバック - http://d.hatena.ne.jp/ikepyon/20081208

2008-12-02 ねむ、さぶ、祓いたい

トラックバック - http://d.hatena.ne.jp/ikepyon/20081202

2008-12-01 眠い

[]第3回まっちゃ445勉強会 第3回まっちゃ445勉強会を含むブックマーク 第3回まっちゃ445勉強会のブックマークコメント

講師田口さん、参加した方ありがとうございました。

個人的にセキュアOSは興味がかつてあったのですが、設定が面倒だったので放置してました。

これからはちょっと試してみたいと思う。

[]私が経験していないスゴイことは、きっとあなたが経験している 私が経験していないスゴイことは、きっとあなたが経験しているを含むブックマーク 私が経験していないスゴイことは、きっとあなたが経験しているのブックマークコメント

前から思っていたことなんだけど、人が経験できることというのは、意外と少ない。また、事実小説より奇なりとも言うように、実体験することは思っていたことや、想像していたことよりスゴイということが多々ある。

普段自分が何気なく体験していることが、他人にとっては未知の体験ということもあるだろうし、逆もまた然りだろう。

そうした他人の経験の中には、自分がたまたま運よく遭遇していないだけということもあるだろう。

そういった個人の経験をみんなで共有することは、きっとみんなの役に立つんじゃないかな?

もちろん、機密事項で話せないことなんかもあるとは思うけど、そこは別に共有してもらわなくてもいいと思う。経験したことに対して、自分がどう考え、どう行動したかということを共有し、同じようなことが起こったときにどうすればよいか?みんなで考えるというのは結構有意義だと思う。

そういった場として、ライトニングトークは非常にいい場だと思うんだよねぇ。

というわけで、自己紹介だけでなく、自分経験したことをどんな些細なことでもいいから、話せる範囲で話してほしいなぁと思った今日この頃


1900 | 01 | 06 |
2003 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2004 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2005 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2006 | 01 | 02 | 03 | 04 | 05 | 06 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 02 | 03 | 04 |
2011 | 01 | 02 |
Connection: close