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

Node debug. De la desilusión al conformismo

Últimamente se han puesto de moda una serie de tendencias que no se donde nos van a conducir, pero porque no probar.

La verdad que me inspiraron estos post que me encontré del amigo Juanma (@gulnor).

http://blog.koalite.com/2011/12/mas-sobre-el-tutorial-node-js-express-jquery/

Así como ver esto en el build 2012.

Para ello no me plantee grandes cosas sino algo muy concreto quiero depurar el ejemplo que hay en la página de Node el típico “hello world”

var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello Worldn');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
He dicho claro no quiero hacer el “Hello World” quiero depurarlo. Ya veréis en que se convierte esto.
 
Primer Intento (Depurar con node).
Antes de empezar os recomiendo esta lectura
 

1. Si no tenéis node instalado lo podéis hacer desde

http://nodejs.org/download/

2. Abrimos el Notepad.

3. Copiamos el código y lo guardamos en una carpeta yo para el ejemplo he creado una con nombre “debugnode”. La extensión del archivo es indiferente un .txt también funciona aunque lo normal es que lo guardes con extensión .js. Te lo dejo a tu elección.

4. Ejecutamos el command prompt de node.

 

Command

No esperéis grandes cosas, alguno puede intuir que se le va a abrir una bonita pantalla negra como la vida mismoSonrisa. Y preparados para teclear muchas veces “Ctrl+C” o si te agobias más fácil la cruz roja.

5. Tecleamos el siguiente comando “node debug server.js” y el resultado es la siguiente ventana.

debug1

Anda no te quejes que algo de color hay. La verdad que da miedo y la sensación es como de impotencia. Primer “Ctrl+C”. bueno como no vas a romper nada vuelve a entrar si haces lo mismo que yo hice y piensa un poco. Tienes dos caminos uno imprimir la página de la documentación y tenerla siempre a tu derecha. La otra es tener un poco de imaginación e intentar pulsar algo,  que te parece “help” o “quit” o de nuevo “Ctrl+c” o bien eso la cruz Roja.

Si llegado a este punto no has cerrado y te has ido a tomar una caña al pulsar “help” te aparece lo siguiente.

debug2

Es decir comandos bastante intuitivos y con una gran similitud con el debug de Visual Studio.

Node Visual Studio
cont o c F5
next n F10
step p F11
SetBreakPoint sb (nº linea) F9

 

Al resto le podeís buscar vosotros su pareja en visual studio.

4. Vamos a jugar con algunos comandos

a) pulsamos list() muestra las 6 primeras lineas de código.

b) una vez que vemos todo el código este concretamente tiene 6, imaginemos uno con 2000, menudo sudor frio te puede dar. tecleamos sb(3) y ya tenemos nuestro primer breakpoint, como siempre intuitivo y por eso nos muestra un “*” a la izquierda de linea 3.

c) pulsamos c para que se pueda ejecutar todo el código y podamos invocar nuestro “hello world” desde el explorador.

d) Abrimos en el explorador la siguiente url “http://localhost:1337” y vemos que el explorador se queda dando vueltas y sin responder, no os preocupéis. Estamos en el breakpoint.

e) ahora quiero ver el valor de req. Request para los amigos. sencillo pulsas repl y ya tienes un magnifico entorno para evaluar expresiones.

    Aqui te invito a que ejecutes los siguientes comandos.

    req.headers.

    req.method.

    req.url.

El resultado obtenido es el esperado.

debug4 

Estamos viendo las cabeceras http el metodo y la url que nos invoca, como podéis observar todo un logro.

Seguro que alguno a estas altura piensa lo mismo que yo y se siente desilusionado con tanto bombo para tan poca cosa o tiene las mismas sensaciones que yo una buena y otra mala.

La buena,  por un momento me sentí con 20 años menos en plenos 90 , rejuvenecido con ganas y con una herramienta mejor que la utilizaba entonces que no era otra que poner banderas y compilar, porque ni depurador había. Ves hemos progresado eres más joven y más listo. Ya tienes depurador.

La mala es que me levante de la silla y me fui corriendo al espejo a ver si de verdad tenía 20 años menos y efectivamente estaba en 2012 utilizando algo que ya había utilizado en los 90. De hay mi gran desilusión.

Pero como se puede hablar bien de esto, esa debería haber sido mi siguiente reacción y un helper a la cruz roja, pero como ha tozudo no me gana nadie, me di otra oportunidad.

Segundo Intento (node-inpector).

Buscando por la web me encontré con esta otra herramienta https://github.com/dannycoates/node-inspector.

Bueno piensa que si la gente habla bien de node algo tiene que tener. Vamos a hacer lo siguiente e instalamos node-inspector.

1. Ejecutamos el siguiente comando desde el directorio npm install node-inspector.

npm es un gestor de paquetes de node parecido a nuget.

2. Ejecutamos el siguiente comando.

node –debug server.js y obtenemos el siguiente resultado.

nodeinspector1

3. Abrimos otra ventana con el command prompt y ejecutamos lo siguiente comando después de lógicamente entrar en el directorio “nodedebug” o en el que hayas creado.

“.node_modules.binnode-inspector &”

El resultado es el siguiente

nodeinspector2

Bueno y ahora como depuro, pues sencillo lee los mensajes de ambas pantallas y tira de tu imaginación o de alguna que otra búsqueda por internet. Piensa un poco tienes primero un mensaje diciendo que tu servidor esta corriendo en el puerto 1337 por otra parte un mensaje de alguien escuchando en el puerto 5858 y en la última ventana un mensaje que me dice que vaya a la dirección tal y que empezare a hacer debugging.

Pues vamos a hacerle caso.

Abrimos chrome o cualquier explorador webkit(yo solo lo he probado en chrome) y hacemos caso a la pantalla negra que para eso es vieja y sabia. El resultado sería el siguiente.

nodeinspector3

La primera exclamación es “jo que bueno” si son las developer tool de chrome. No te confundas es una buena pagina web que hace lo mismo o parecido a las devtools. Vamos a verlo para ello podemos pulamos F12 y nos aparecen las verdaderas devtools y ahora para picaros un poquito más quiero que pongáis un breakpoint no en el primer texto que vemos sino en la linea 13 del archivo overrides.js tal y como os muestro.

socket

y ahora un breakpoint en el impostor el resultado es que el legitimo se para en la linea 13 y podemos ver que recibe un mensaje al servidor con el siguiente formato.

«{«id»:25,»result»:{«breakpointId»:»1″,»locations»:[{«lineNumber»:2,»columnNumber»:6,»scriptId»:»23″}]}}»

Ya sabeís a jugar o mejor a estudiar si queréis haceros vuestro propio depurador .

DebuggerProtocol.

El código fuente de esta pagina web no devtool lo tenéis en la carpeta “node_modulesnode-inspectorfront-end”

Bueno parece que esto mejora, pero si analizamos  necesito 4 ventanas para depurar dos negras y otras dos con el explorador chorme que lo mismo no lo quiero instalar y otra con el explorador que utilizas para hacer peticiones. He aprovechado para conciliar a dos rivales IE10 y Chrome todo ello para depurar una app desarrollada en node. Todo un logro por mi parte sentar en la misma mesa a los dosSonrisa.

nodeinspector4

Desilusionado pues igual que yo pero un poco menos.

Tercer intento(Microsoft viene a salvarnos).

Ante estas dos frustrantes actuaciones y recordando un poco me vino a la cabeza que webMatrix soportaba node. Pues vamos a ello.

1. Descarga WebMatrix.

2. Desístala iisnode si lo tienes instalado, creo que lo instala webMatrix en algún momento, no estoy seguro.

3. Instala la versión de iisnode desde esta url

https://github.com/tjanczuk/iisnode/downloads

Yo concretamente instale esta para una máquina de 32

https://github.com/downloads/tjanczuk/iisnode/iisnode-iis7express-v0.1.13-x86.msi

Y comprueba si quieres depurar node  con el siguiente comando

%localappdata%iisnode existe la carpeta iisnode en la ruta y que en vez de encontrarte con un archivo js te encuentras con una dll llamada iisnode-inspector.dll.

4. Creo que tienes que hacer algún cambio en el archivo applicationhost.config.

%userprofile%documentsIISExpressconfigapplicationhost.config

concretamente este

<section name=»handlers» overrideModeDefault=»Allow» /> su default value es “Deny”

5. Por último tienes que cambiar el webConfig de las plantillas que trae webMatrix por defecto con lo siguiente.

<!-- 
This configuration file is required if iisnode is used to run node processes behind
IIS or IIS Express. For more information, visit:

https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/web.config
-->
<configuration>
<system.webServer>
<handlers>
<!-- indicates that the server.js file is a node.js application to be handled by the iisnode module -->
<add name="iisnode" path="server.js" verb="*" modules="iisnode"/>
</handlers>
<rewrite>
<rules>
<!-- Don't interfere with requests for logs -->
<rule name="LogFile" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^[a-zA-Z0-9_-]+.js.logs/d+.txt$"/>
</rule>
<!-- Don't interfere with requests for node-inspector debugging -->
<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^server.js/debug[/]?"/>
</rule>
<!-- First we consider whether the incoming URL matches a physical file in the /public folder -->
<rule name="StaticContent">
<action type="Rewrite" url="public{REQUEST_URI}"/>
</rule>
<!-- All other URLs are mapped to the Node.js application entry point -->
<rule name="DynamicContent">
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/>
</conditions>
<action type="Rewrite" url="server.js"/>
</rule>
</rules>
</rewrite>
<iisnode>
debuggerPortRange="5058-6058"
debuggerPathSegment="debug"
maxNamedPipeConnectionRetry="3"
namedPipeConnectionRetryDelay="2000"
</iisnode>
</system.webServer>
<system.web>
</configuration>

A partir de este momento ya podemos ejecutar y depurar nuestra app node con webMatrix. para ejecutarla simplemente ir al sitio de webMatrix tal y como muestro.

 
webmatrix

Desde otra ventana del depurador podeís ejecutar la siguiente url y a depurar “http://localhost:33732/server.js/debug/”.

Como podéis ver algo que no te lleva unas pocas horas y es por eso por lo que uno se encuentra al final ya no desilusionado sino conformista, porque aun habiéndolo logrado esto no es ninguna maravilla hemos pasado de 4 a 3 ventanas y un entorno más amigable, pero con deficiencias en Intellisense y demás…

Otras opciones que podéis probar son.

Cloud 9 ide

WebStorm

o incluso el propio eclipse https://github.com/joyent/node/wiki/Using-Eclipse-as-Node-Applications-Debugger.

Pero vamos nada parecido a lo que Microsoft podría hacer con Node y que sería integrarlo en Visual Studio.

Conclusiones.

Que tristemente Microsoft apuesta por node porque realmente esta Azure e interesa. Pero veo que el esfuerzo realizado no compensa lo que node me da frente a lo que me da MVC como desarrollador .net aunque es algo que no tenemos que dejar pasar y seguir muy de cerca.

Espero dos cosas.

1. Que Microsoft lo integre en Visual Studio.

2. Que deje node donde esta que como servicio gratuito ya ha hecho creo yo lo que le corresponde. Dar herramientas medianamente decentes. Y que apueste por TypeScript y haga su propio motor con “chakra”.

Estoy soñando o me lo estoy creyendoSonrisa