Avanzamos de Sql Inyection a SSJS(server Side javascript-inyection)

De esos días que a uno le quedan ganas de pasarse por el foro de c# veo esta pregunta y sus respectivas respuestas y ante eso reacciono e intenta evitar situaciones comprometidas.

Resultado  como se puede ver ni puto caso:). Vamos a ver si lo convencemos.

http://social.msdn.microsoft.com/Forums/es-ES/vcses/thread/55061187-d5ca-4d01-b5f6-6b6c9bd7ab86

Pero para ello, no lo voy a hacer con Sql Server, Oracle, My Sql,etc. Lo vamos a hacer con  Mongo y pronto podréis observar  como bien dicen que no todo lo que reluce es oro.

Lo digo por estas cosas que se pueden leer acerca de Mongo y bb.dd no Sql.

-No Sql Inyection

-No Join

-No schemas

Efectivamente toda una maravilla, excepto que como a todos siempre se nos olvida algo. Y es entonces cuando crean una bonita sentencia que no es otra $exists. Lo mismo la crearon por aquello de no tener shemas y podamos hacer query de aquellos documentos que no contiene tal campo, pero claro también podemos hacer query de todos los campos de un formulario donde $exists es verdadero y es aquí donde empieza la fiesta.

Pasitos.

Vamos a ser modernos y además de mongo hoy nos toca todo con Node. Con .Net y c# no tienes este problema, excepto … y ya lo contaré al final.

1. Creamos una carpeta llamada “nodemongo”. Tenemos node y mongodb instalado a jugar si no es así ya sabes Node y Mongo

2. instalamos express para ello sencillo “npm install express”

3. instalamos jade. Una joyita y de las buenas(Me parece buenísimo). “npm install jade”

4. instalamos mongo para node js “npm install mongodb”

5. ejecutamos la siguiente sentencia desde nuestra carpeta “express”

6. Esto nos va a crear una estructura de directorios con vistas,controladores(routes) y public(css y javascript). Es decir todo el esqueleto básico de una app con express.

7. Como somos tan chulos y no hacemos caso a aquello de utiliza estándares nos creamos una tabla(collection) en mongo db para almacenar nuestros login.

desde mongo ejecutamos lo siguiente.

db.login.insert({user:’admin’,password:’123456’})

Si posteriormente ejecutamos db.login.find() podemos ver que nos hemos ahorrado un montón de cosas.

-Create Table

-Insert

-etc,etc

Es decir lo acabas de comprar. Todo en uno y barato:)

Bueno llegado a este punto ya tenemos la suficiente infraestructura para modificar todo aquello que nos aporta express y no es más que modificar una vista para que solicite el login a nuestro sitio y otra página que nos dirá “estás conectado”  o “me quieres engañar”.

8. En las vista vamos a index.jade y la dejamos de la siguiente forma.

extends layout

block content
h1
p Welcome
form(action="/users",method='post')
input(type="text",name="user")
br
input(type="text",name="password")
br
input(type="submit",value="submit")

9. Modificamos el archivo app.js creado en los puntos 5 y 6 y lo dejamos de esta forma.


/**
* Module dependencies.
*/

var express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, http = require('http')
, path = require('path');

var app = express();

app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
});

app.configure('development', function(){
app.use(express.errorHandler());
});

app.get('/', routes.index);
app.post('/users', user.list);

http.createServer(app).listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});

Nuestra app responde a “/” para mostrar nuestro formulario y un post en “/users” para recoger los datos de autenticación.

10. Modificamos en la carpeta “routes” el archivo “users.js” y lo dejamos de la siguiente forma. Ahora entra mongo a realizar sus buenas labores(salvarnos de los join, será que no sabes como funcionanSonrisa.


/*
* GET users listing.
*/

exports.list = function(req, res){
var query = {'user':req.body.user,password:req.body.password};

var mongo = require('../node_modules/mongodb/index.js'),
Server = mongo.Server,
Db = mongo.Db;

var server = new Server('localhost',27017,{safe:false});
var db = new Db('test', server);

db.open(function(err, db) {
if(!err) {
db.collection('login', function(err, collection) {
collection.find(query).toArray(function(err, items) {
if(items.length)
res.send("conectado");
else
res.send("me estás engañando");
}
);

});
}
});
};

Bueno con estos pasos tenemos nuestro sistema preparado para hacer login, fácil no?

11. Ahora con esa maravilla que es node vamos a ejecutar lo siguiente.

node app.js

12. Desde el explorador tecleamos la siguiente url.

localhost:3000

13. Este es el número que me gustaSonrisa.  Jo tenemos un formulario para hacer login y una bb.dd con dos patadas. Esto es una maravilla!!!.

Bueno ahora toca ser malo y vamos a hacer lo siguiente.

1. Lo primero que vemos es una página fea, pero no os preocupéis que después llega el diseñador y todo arreglado.

login

2. Lo primero es conocer que hace esto . Sencillo tecleamos en usuario “admin” y en password lo mismo por si tenemos suerte. El resultado es evidente.

“me estás engañando”. Bien!!!!

3. Ahora vamos a ver que ha pasado entre bastidores, para ello F12 y developer tool->Network.

Network

 

El form data deja claro que hay dos campos uno llamado “user” y el otro “password”, nada fuera de lo normal.

4. Vamos a putear….

Lo más sencillo del mundo no comprobar que nuestro usuario y password es el mismo que nos pasan, es mas optimo hacer count(*) Sonrisa.

if(items.length)
res.send("conectado");
else
res.send("me estás engañando");
5. Vamos a cambiar de ventana en las dev tools y nos vamos a elements el objetivo no es otro que dejar nuestro html de la siguiente forma.
 
html
 
Algo sencillo cambiar el name del input user por user[$exists] y lo mismo con password para dejarlo como password[$exists]. Seguro que si lo dejo de esta forma alguno puede llegar hasta este punto y pensar que le estoy tomando el pelo, Nooooo!!!.
 
Es bastante más sencillo que teclear todo lo que nos dice esta pagina de las 1000 que hay por internet http://www.unixwiz.net/techtips/sql-injection.html y además se ha pasado de moda:). Es más sencillo teclear lo siguiente, sabes que? no te lo imaginas a estas alturas:). De lo más sencillo.
 
– En el campo user tecleamos “true”
– En el campo password tecleamos “true”.
 
Si al final lo que queremos es que exista el campo “user”  y el campo “password” en nuestra collection(tabla), menuda maravilla. La respuesta es clara acabas de pasar de impostor a ser el dueño del mambo.
true
 
Quieres ser el señor, pulsa en "submit”.
Conclusiones.
 
Si alguien está libre que tire la primera piedra a todas estas preguntas.
 
1. Quien no utiliza los mismos nombres de campos en sus formularios que en la bb.dd, yo diría que todos.
 
2. Quien no ha montado alguna vez un sistema de login así. Yo diria que todos.
 
3. Quien no se deja una entrada sin validar. Yo diría que alguna vez todos.
 
4. Quien ha creado para mongo un anti$exists. Ninguno.
 
5.  Como respuesta a los de c# estáis libres de pecado puesto que vuestro user y password es string (TIPADO) y mongo ante esta query
 
db.login.finc({user:'{$exists:true}’,password:'{$exists:true}’})
 
Responde con 0 registros( que sacrilegio registros, ¿no deberían ser documentos? y en vez de ORM ODM Sonrisa). Señores por una vez no somos los inseguros. Excepto que utilices el magnifico $where
 
6. Quien no ha validado basándose en Count y no hacer comprobaciones posteriores.
 
7. Podemos ver como cada día que nuestra profesión va en continua evolución hasta encontrar eso “la panacea”.
 
 
 
 

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *