5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PHPの脆弱性を検出するソリューションを作る

Last updated at Posted at 2015-06-04

##モチベーション
Webアプリの脆弱性を検出するアプリケーションをオープンソースで出せば、サポートで儲かるかなと思って作ります。
ちなみに、PHP言語とかの使い方を説明したものではなく、構想を描いたもので、PHPの勉強したい人が読んでも役に立たない可能性があるから注意

##脆弱性検出の原理
とりあえず、今考えているシステムは、機械学習によりソフトウェアの脆弱性を検出しようというもので、基本的にはMITライセンスのオープンソースで作ろうとしている。
機械学習においては、トレーニングセット、特徴抽出などが必要になる。僕は、脆弱性の種類ごとにそれぞれのトレーニングセット、特徴抽出をしようと思う。
こうなると、スキャンの時にかなりのコンピューティングパワーを使うことになりそうだが、まあ仕方がない。

##特徴抽出
とりあえず、SQLインジェクションの特徴抽出を書いていこうかと思う。
とりあえず、ファイルの中から$_GETのキーワードを検索する。これは、ユーザから入力されたもので、汚染されている可能性がある変数である。
 これを、この変数が伝播していく方向でトレースダウンして行って、どのような処理をされるかをベクトル化していくのである。
 これは、グラフを使って定式化することができるんじゃないかなと思っている。
 
##場合分け

まず、変数同士のつながりはいろいろと場合分けをすることができる。

つながりにはいろいろ種類がある。以下に場合分けをしていこう

###⑴関数呼び出しによる伝播

func1($_GET['pass']);

function func1($param)
{
    .. = $param
}

関数呼び出しによる伝播は、パラメータ自体は変更されない。

###(2)メソッド呼び出しによる伝播

class simpleclass
{
   public func2($param){
        ..= $param
   }

}

$obj = new simpleClass();

$obj->func2($_GET['pass']);

###(3)代入による伝播

$param = $_GET['pass'];

###(4)関数の帰り値による伝播

function func5()
{
	return $_GET['pass'];
}

$param = func5();

これらの「汚れた変数」の伝播をどのようなデータ構造で表すかが難しいところではある。

ここは、例えば、実際に入力するデータと出力を定義して、その後にテスト駆動開発により中身を開発していけばいいことがわかる。

では、実際に入力するデータを脆弱性データベースより持ってこようかと思う。

とりあえず、エイヤで決めてみる

これが脆弱性のあるソースコードの部分である
http://plugins.svn.wordpress.org/newstatpress/tags/0.9.8/includes/nsp_search.php

で、以下が修正されたやつ
http://plugins.svn.wordpress.org/newstatpress/tags/1.0.0/includes/nsp_search.php

脆弱性の部分は以下のようなところである
以下のソースコードは脆弱性のあるところを抜き出してある

   for($i=1;$i<=3;$i++) {
     if(($_GET["what$i"] != '') && ($_GET["where$i"] != '')) {
       $where.=" AND ".$_GET["where$i"]." LIKE '%".$_GET["what$i"]."%'";
     }
   }

   for($i=1;$i<=3;$i++) {   
     if(($_GET["what$i"] != '') && ($_GET["where$i"] != '')) {
       $where_i=esc_sql($_GET["where$i"]);
       $what_i=esc_sql($_GET["what$i"]);
       $where.=" AND ".$where_i." LIKE '%".$what_i."%'";
     }
   }

さて、トレースの起点はこの場合は$_GETである。つまり、$_GETパラメータが使われている部分を全部取り出してトレースする必要がある。

ちなみに、一つのファイルに複数の$_GETが使われている可能性があるので、入力が一つのファイルだったとしても(複数のファイルの可能性もあるが)出力は複数である。

では、続きは別の回に

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?