Szarny.io

There should be one-- and preferably only one --obvious way to do it.

Webアプリケーションにおける脆弱性(Injection編)

SQLインジェクション

SQLインジェクションは,ユーザからの入力に基づいてデータベースに対してクエリを発行するWebアプリケーションにおいて発生し得る脆弱性です.

入力フォーム等から不正な値を注入することで,本来意図されていない動作を引き起こすことが可能になってしまいます.

例えば,2つの入力フォームから,それぞれIDとパスワードを入力し,その入力内容を基にSQL文を発行するアプリケーションを想定します.IDが変数$id,パスワードが変数#passwdに格納されるとき,以下のようなSQL文が発行され,結果が1件でも返却されればログイン成功となります.

SELECT * FROM user_table WHERE id = '$id' and passwd = '$passwd';

 

本来であれば,適切な値が入力(以下の例)されるはずです.

$id <- hogehoge
$passwd <- hugahuga

SELECT * FROM user_table WHERE id = 'hogehoge' and passwd = 'hugahuga';

 

ここで, パスワードを「hugahuga」から「a' OR '1' = '1」に変更します.この時,以下のようなSQL文が発行されますが,'a' OR '1' = '1'は常にTrueとなるため,任意のidに対するログインが可能になります.

 

$id <- hogehoge
$passwd <- a' OR '1' = '1

SELECT * FROM user_table WHERE id = 'hogehoge ' and passwd = 'a' OR '1' = '1';

他にも,idにUNION句を挿入することで,他テーブルの構造や内容を把握したり,--や#によるコメントアウトを行うことで,認証をバイパスしたりすることが可能になります.

これらの脆弱性は,適切なエスケープ処理を行うことやPrepared Statementを用いることで緩和させることができます.

 

HTTP ヘッダインジェクション

一般的に,HTTP RequestとHTTP Responseは以下のような形式をとります.

HTTP Request

GET /index.html HTTP/1.1
Host: www.examplem
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: ja

 

HTTP Response

HTTP/1.1 200 OK
Server: nginx
Content-Type: text/html;

...
Connection: keep-alive

 

<!DOCTYPE html>
<html lang="ja">
...
</html>

 HTTP Responseは,途中の空行を区切りとしてヘッダー部とボディ部を認識します.HTTPヘッダインジェクションとは,このヘッダ部分に意図的に不正な値を注入することで意図しない動作を引き起こさせる脆弱性です.

 

例えば,URL中のクエリストリングを用いてページ番号を指定することで,強制的に画面遷移を行うWebアプリケーションを想定します.

 HTTP Request(URL)

http://www.example.com/index.html?page=123 

正当な 

HTTP Response

HTTP/1.1 302 Found

Date: ...

Server: ...

Location: http://www.example.com/123

Content=length: 1024

 

<!doctype html>

<html>

...

</html> 

 

ここで,クエリストリングに「%0d%0aLocation:%20http://download.malware.com」と入力すると以下のようになります.(%0d%0aはCRLF改行コードを,%20はスペースをパーセントエンコーディングしたものです.)

 HTTP Request(URL)

http://www.example.com/index.html?page=%0d%0aLocation:%20http://download.malware.com 

不正な 

HTTP Response

HTTP/1.1 302 Found

Date: ...

Server: ...

Location: http://www.example.com/

Location: http://download.malware.com

Content=length: 1024

 

<!doctype html>

<html>

...

</html> 

以上の入力によって,HTTP Response内にLocationフィールドが重複して存在するようになります.しかし,Apache等のWebサーバは最後尾のフィールドのみを認識するようになっているので,結果として不正なURLに対して遷移が行われるようになります.

この手法を応用することで,任意のHTTP Responseを生成するHTTP Response Splittingを行うことも可能になります.