Foros del Web » Programando para Internet » ASP Clásico »

Soluciones a inyección SQL y captcha

Estas en el tema de Soluciones a inyección SQL y captcha en el foro de ASP Clásico en Foros del Web. Este post no es una consulta, es para ayudar a otros usuarios. Bueno, pues estoy siendo acosado por un islamista turco que está jaqueando todas ...
  #1 (permalink)  
Antiguo 11/04/2012, 02:32
 
Fecha de Ingreso: diciembre-2010
Mensajes: 236
Antigüedad: 13 años, 4 meses
Puntos: 6
Soluciones a inyección SQL y captcha

Este post no es una consulta, es para ayudar a otros usuarios.

Bueno, pues estoy siendo acosado por un islamista turco que está jaqueando todas mis Webs colándose en mi gestor de contenido, una vez dentro os podéis imaginar la que me lía en las páginas.

Las páginas estaban desarrolladas en ASP y con bases de datos Access. Esto ya pasó a la historia, las soluciones que he tenido que implementar son las siguientes:

Inclusión de método Captcha
- Solución sacada de http://www.tipstricks.org/

Función ComprobarCaptcha:

Código ASP:
Ver original
  1. <%
  2.  
  3. ' Implementada a trav s del c digo de http://www.tipstricks.org/
  4. ' La funci n devuelve verdadero o falso despu s de comprobar el valor captcha
  5. ' introducido.
  6. '
  7. ' Se le pasan como par metros el valor del m todo post del formulario y el valor
  8. ' del bot n reintentar, este deber  estar en blanco.
  9. '
  10. '
  11.  
  12. Function ComprobarCaptcha(request_method, btnretry)
  13.    
  14.    'Iniciamos el valor de la funci n a falso
  15.    ComprobarCaptcha = False
  16.    
  17.    'Comprobamos el valor de los par metros.
  18.    if request_method = "POST" and IsEmpty(btnretry) then
  19.  
  20.       'La variable de sesi n se crea al crear el gr fico captcha a trav s del archivo
  21.       'captcha.asp, si no se ha creado devolvemos falso.
  22.       if IsEmpty(Session("ASPCAPTCHA")) or Trim(Session("ASPCAPTCHA")) = "" then
  23.  
  24.          ComprobarCaptcha = False
  25.  
  26.       else
  27.  
  28.          Dim TestValue : TestValue = Trim(Request.Form("txtCaptcha"))
  29.          '//Uppercase fix for turkish charset//
  30.          TestValue = Replace(TestValue, "i", "I", 1, -1, 1)
  31.          TestValue = Replace(TestValue, "I", "I", 1, -1, 1)
  32.          TestValue = Replace(TestValue, "i", "I", 1, -1, 1)
  33.          '////////////////////
  34.          TestValue = UCase(TestValue)
  35.                
  36.          if StrComp(TestValue, Trim(Session("ASPCAPTCHA")), 1) = 0 then
  37.             ComprobarCaptcha = True
  38.          else
  39.             ComprobarCaptcha = False
  40.          end if
  41.  
  42.          '//IMPORTANT: You must remove session value for security after the CAPTCHA test//
  43.          Session("ASPCAPTCHA") = vbNullString
  44.          Session.Contents.Remove("ASPCAPTCHA")
  45.          '////////////////////
  46.  
  47.       end if
  48.     end if
  49.  
  50. End Function
  51. %>

La función la tenemos a parte en un include y así deben de ser los formularios:
Código HTML:
Ver original
  1. <form method="post" action="admin_loginadmin.asp?login=si">
  2.             <fieldset>
  3.                 <ul>
  4.                     <li>Usuario : <input type="text" name="usuario" size="20"/></li>
  5.                     <li>Contraseña: <input type="password" name="Contrasena" size="10"/></li>
  6.                     <li><img src="captcha.asp" id="imgCaptcha" /></li>
  7.                     <li><input type="text" name="txtCaptcha" id="txtCaptcha" value="" /></li>
  8.                     <li><input type="submit" value="Enviar" name="Enviar"/></li>
  9.                     <li><input type="submit" name="btnRetry" id="btnRetry" value="Cargar de nuevo" /></li>
  10.                 </ul>
  11.             </fieldset>
  12.             </form>

Esta es la breve explicación que he creado y puesto en mi código para no olvidarme:

Código ASP:
Ver original
  1. <!--
  2.  
  3.     Incluye Captcha de http://www.tipstricks.org/
  4.  
  5.     A parte del código de esta página, se tienen que añadir los archivos
  6.     captcha.asp y wordlist.asp al raiz de la web, explicamos el por qué de cada archivo
  7.    
  8.     captcha.asp : Es un código en asp que genera un gráfico captcha, el tipo de gráfico que genera
  9.                   es configurable desde la web del fabricante.
  10.                  
  11.     wordlist.asp: Es la lista de las palabras a generar, cogerá una palabra aleatoria de este
  12.                   fichero para generar el gráfico captcha.
  13.    
  14.     Al formulario de logeo se añade:
  15.        
  16.         <li><img src="captcha.asp" id="imgCaptcha" /></li>
  17.         Esta línea crea/genera la imagen Captcha
  18.        
  19.         <li><input type="text" name="txtCaptcha" id="txtCaptcha" value="" /></li>
  20.         Es el cuadro de texto donde debemos escribir el captcha, dejamos los mismos
  21.         nombres para que el código funcione.
  22.        
  23.         <li><input type="submit" name="btnRetry" id="btnRetry" value="Cargar de nuevo" /></li>
  24.         No sé la idea del fabricante, yo he eliminado un script de java para regenerar el gráfico
  25.         captcha sin cargar de nuevo la página. Se usa este botón para volver a cargar la página y
  26.         que muestre otro gráfico captcha.
  27.  
  28.     En el código sólo tenemos que hacer uso de la función ComprobarCaptcha que devuelve verdadero o falso
  29.     después de comprobar el valor introducido en txtCaptcha, se le pasan dos parámetros, el método de envío
  30.     del formulario y el valor del botón de reintento.
  31.  
  32. -->


Siguiente paso: Migración de Access a MySQL

Aún en proceso. Una putada las tildes como siempre y estoy teniendo problemas con las sentencias SQL que no son las mismas, os pongo ejemplos:

El Select Top n ya no funciona, hay que poner un Limit n al final, el Delete * tampoco funciona por seguridad y así muchas cosas más.

Lo más jodido son las tildes ahí estamos liado con el utf8 y compañía como siempre.

Siguiente paso: Evitar inyección SQL

El que no sepa de qué trata que pinche aquí

He creado el siguiente código con la ayuda de este enlace

He puesto esta función a parte, es la que comprueba que no haya código malicioso en una cadena

Código ASP:
Ver original
  1. <%
  2.  
  3.     '''''''''''''''''''''''''''''''''''''''''''''''''''              
  4.     '  This function does not check for encoded characters
  5.     '  since we do not know the form of encoding your application
  6.     '  uses. Add the appropriate logic to deal with encoded characters
  7.     '  in here
  8.     '''''''''''''''''''''''''''''''''''''''''''''''''''
  9.     Function CheckStringForSQL(str)
  10.       On Error Resume Next
  11.      
  12.       Dim lstr, BlackList
  13.  
  14.     BlackList = Array(" or ", "'", "--", ";", "/*", "*/", "@@", "@",_
  15.                           "char", "nchar", "varchar", "nvarchar",_
  16.                           "alter", "begin", "cast", "create", "cursor",_
  17.                           "declare", "delete", "drop", "end", "exec",_
  18.                           "execute", "fetch", "insert", "kill", "open",_
  19.                           "select", "sys", "sysobjects", "syscolumns",_
  20.                           "table", "update")
  21.      
  22.      
  23.       ' If the string is empty, return true
  24.       If ( IsEmpty(str) ) Then
  25.         CheckStringForSQL = false
  26.         Exit Function
  27.       ElseIf ( StrComp(str, "") = 0 ) Then
  28.         CheckStringForSQL = false
  29.         Exit Function
  30.       End If
  31.      
  32.       lstr = LCase(str)
  33.      
  34.       ' Check if the string contains any patterns in our
  35.       ' black list
  36.       For Each s in BlackList
  37.      
  38.         If ( InStr (lstr, s) <> 0 ) Then
  39.           CheckStringForSQL = true
  40.           Exit Function
  41.         End If
  42.      
  43.       Next
  44.      
  45.       CheckStringForSQL = false
  46.      
  47.     End Function
  48.  
  49. %>

Y creado este procedimiento:

Código ASP:
Ver original
  1. <%
  2. 'Este Procedimiento evita la inyección SQL
  3. 'Comprueba que los datos de formularios, querystrings y cookies no sean
  4. 'maliciosos
  5. ' sacado de:
  6. ' http://blogs.iis.net/nazim/archive/2008/04/28/filtering-sql-injection-from-classic-asp.aspxhttp://blogs.iis.net/nazim/archive/2008/04/28/filtering-sql-injection-from-classic-asp.aspx
  7.  
  8. Public Sub ComprobarFormulario ()
  9.  
  10.     Dim ErrorPage, s
  11.  
  12.     '
  13.     '  Below is a black list that will block certain SQL commands and
  14.     '  sequences used in SQL injection will help with input sanitization
  15.     '
  16.     '  However this is may not suffice, because:
  17.     '  1) These might not cover all the cases (like encoded characters)
  18.     '  2) This may disallow legitimate input
  19.     '
  20.     '  Creating a raw sql query strings by concatenating user input is
  21.     '  unsafe programming practice. It is advised that you use parameterized
  22.     '  SQL instead. Check http://support.microsoft.com/kb/q164485/ for information
  23.     '  on how to do this using ADO from ASP.
  24.     '
  25.     '  Moreover, you need to also implement a white list for your parameters.
  26.     '  For example, if you are expecting input for a zipcode you should create
  27.     '  a validation rule that will only allow 5 characters in [0-9].
  28.     '
  29.  
  30.  
  31.     '  Populate the error page you want to redirect to in case the
  32.     '  check fails.
  33.    
  34.     ErrorPage = "/ErrorPage.asp"
  35.                
  36.  
  37.  
  38.     '''''''''''''''''''''''''''''''''''''''''''''''''''
  39.     '  Check forms data
  40.     '''''''''''''''''''''''''''''''''''''''''''''''''''
  41.    
  42.     For Each s in Request.Form
  43.       If ( CheckStringForSQL(Request.Form(s)) ) Then
  44.      
  45.         ' Redirect to an error page
  46.         Response.Redirect(ErrorPage)
  47.      
  48.       End If
  49.     Next
  50.    
  51.     '''''''''''''''''''''''''''''''''''''''''''''''''''
  52.     '  Check query string
  53.     '''''''''''''''''''''''''''''''''''''''''''''''''''
  54.    
  55.     For Each s in Request.QueryString
  56.       If ( CheckStringForSQL(Request.QueryString(s)) ) Then
  57.      
  58.         ' Redirect to error page
  59.         Response.Redirect(ErrorPage)
  60.    
  61.         End If
  62.      
  63.     Next
  64.    
  65.    
  66.     '''''''''''''''''''''''''''''''''''''''''''''''''''
  67.     '  Check cookies
  68.     '''''''''''''''''''''''''''''''''''''''''''''''''''
  69.    
  70.     For Each s in Request.Cookies
  71.       If ( CheckStringForSQL(Request.Cookies(s)) ) Then
  72.      
  73.         ' Redirect to error page
  74.         Response.Redirect(ErrorPage)
  75.    
  76.       End If
  77.      
  78.     Next
  79. End Sub
  80. %>



El procedimiento lo ejecuto en toooooodas las páginas que haya formularios y espero que el dichoso turco islamista me deje en paz.

Última edición por PabloManuel; 11/04/2012 a las 02:35 Razón: error
  #2 (permalink)  
Antiguo 11/04/2012, 03:27
 
Fecha de Ingreso: diciembre-2010
Mensajes: 236
Antigüedad: 13 años, 4 meses
Puntos: 6
Respuesta: Soluciones a inyección SQL y captcha

Bueno, hay una pega. He tenido que cambiar la lista de palabras:

Código ASP:
Ver original
  1. BlackList = Array("'", "--", "/*", "*/", "@@",_
  2.                           " char ", " nchar ", " varchar ", " nvarchar ",_
  3.                           " alter ", " begin ", " cast ", " create ", " cursor ",_
  4.                           " declare ", " delete ", " drop ", " end ", " exec ",_
  5.                           " execute ", " fetch ", " insert ", " kill ", " open ",_
  6.                           " select ", " sys ", " sysobjects ", " syscolumns ",_
  7.                           " table ", " update ")

Añadiendo espacios delante y atrás de cada palabar, porque si un usuario escribe por ejemplo escuchar, soportable o algo por el estilo no sería aceptado por el sistema.
  #3 (permalink)  
Antiguo 12/04/2012, 03:59
Avatar de pempas  
Fecha de Ingreso: diciembre-2003
Ubicación: Barcelona
Mensajes: 985
Antigüedad: 20 años, 3 meses
Puntos: 6
Respuesta: Soluciones a inyección SQL y captcha

Cita:
Iniciado por PabloManuel Ver Mensaje
Bueno, hay una pega. He tenido que cambiar la lista de palabras:

Código ASP:
Ver original
  1. BlackList = Array("'", "--", "/*", "*/", "@@",_
  2.                           " char ", " nchar ", " varchar ", " nvarchar ",_
  3.                           " alter ", " begin ", " cast ", " create ", " cursor ",_
  4.                           " declare ", " delete ", " drop ", " end ", " exec ",_
  5.                           " execute ", " fetch ", " insert ", " kill ", " open ",_
  6.                           " select ", " sys ", " sysobjects ", " syscolumns ",_
  7.                           " table ", " update ")

Añadiendo espacios delante y atrás de cada palabar, porque si un usuario escribe por ejemplo escuchar, soportable o algo por el estilo no sería aceptado por el sistema.
Justo te iba a decir eso antes de leer el segundo post jeje

Muy buen aportación! y suerte con tu web!
  #4 (permalink)  
Antiguo 12/04/2012, 08:48
 
Fecha de Ingreso: diciembre-2010
Mensajes: 236
Antigüedad: 13 años, 4 meses
Puntos: 6
Respuesta: Soluciones a inyección SQL y captcha

funciona correctamente pero hay que seguir depurando, lo que me tiene loco es mysql, hay muuuuuuchas cosas que no funcionan en lo que se refiere a código SQL Access Vs. Código SQL mysql.

Siguiendo con el hilo, por ejemplo, una intrusión fácil en un panel de gestión que se accede con usuario y contraseña es poner en ambos casos:

' or '1'='1

Con esta cadena se entraría si apenas se controlan las cadenas de texto y con una de estas me entraron a mi, pero claro ¿que restringimos? ¿las comillas? ¿el igual? es complejo esto, así que seguiremos insistiendo / investigando.

Me temo que voy a crear el manual Guía de migración sin dolor de Access a MySQL jajajja y también la Guia para no recibir dolor de hackers con ASP
  #5 (permalink)  
Antiguo 13/04/2012, 03:13
Avatar de pempas  
Fecha de Ingreso: diciembre-2003
Ubicación: Barcelona
Mensajes: 985
Antigüedad: 20 años, 3 meses
Puntos: 6
Respuesta: Soluciones a inyección SQL y captcha

Una forma muy sencilla de evitar el ' or 1=1 es hacer esto:

Replace(SQL, "'", "''")

Con eso evitamos que el SQL tome esa parte como independiente, y lo agrega a la propia comparación, pruébalo, verás que con eso se acabó el problema.
  #6 (permalink)  
Antiguo 13/04/2012, 08:22
 
Fecha de Ingreso: diciembre-2010
Mensajes: 236
Antigüedad: 13 años, 4 meses
Puntos: 6
Respuesta: Soluciones a inyección SQL y captcha

Cita:
Iniciado por pempas Ver Mensaje
Una forma muy sencilla de evitar el ' or 1=1 es hacer esto:

Replace(SQL, "'", "''")

Con eso evitamos que el SQL tome esa parte como independiente, y lo agrega a la propia comparación, pruébalo, verás que con eso se acabó el problema.
Gracias, me voy a tomar un fin de semana sabático, tengo los ojos cuadrados con tanta línea de código que estoy depurando, pero el lunes lo añado a la función.
  #7 (permalink)  
Antiguo 07/02/2013, 21:22
 
Fecha de Ingreso: enero-2011
Ubicación: España
Mensajes: 7
Antigüedad: 13 años, 3 meses
Puntos: 0
Respuesta: Soluciones a inyección SQL y captcha

Hola yo también quiero aportar algo.
Este método es para protegernos de un ataque mediante inyección de sql, podemos ponerlo en nuestra clase.

Código PHP:
Ver original
  1. public static function parsearParametros ( $param ) {
  2.  
  3.         $cross_site_scripting = array ( '@<!--]*?>.*?// -->@si',
  4.  
  5.                                  '@<[\/\!]*?[^<>]*?>@si' );
  6.  
  7.         $inyeccion_sql = array (
  8.  
  9.                                  '/\bAND\b/i', '/\bOR\b/i',
  10.  
  11.                                  '/\bSELECT\b/i', '/\bFROM\b/i',
  12.  
  13.                                  '/\bWHERE\b/i', '/\bUPDATE\b/i',
  14.  
  15.                                  '/\bDELETE\b/i', '/\b\*\b/i',
  16.  
  17.                                  '/\bCREATE\b/i', '/\bDROP\b/i' );
  18.  
  19.         $retorno = preg_replace ( $inyeccion_sql, "", $param );
  20.  
  21.         $retorno = preg_replace ( $cross_site_scripting, "", $retorno );
  22.  
  23.         $retorno = strip_tags( $retorno, ENT_QUOTES );
  24.  
  25.         return trim( $retorno );
  26.  
  27.     }

A continuación debemos pasar nuestras variables por el método.

ejemplo.

$Mivariable=$_GET["Mivariable"];

parsearParametros ( $Mivariable );

Y así estaremos algo mas protegidos ante algun ataque de inyección sql.

Última edición por leonbis; 07/02/2013 a las 21:25 Razón: no puse tíldes..

Etiquetas: captcha, inyección, sql, vulnerabilidad
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 14:13.