¡La mentalidad de Pentester!

Salga de la mentalidad limitada de OWASP TOP-10/SANS TOP-25/Bug Bounty

por Ravikumar Paghdal - ravi en net-square.com , @_RaviRamesh noviembre de 2019

TL;RD:

"Sal de la mentalidad limitada de OWASP TOP-10 / SANS TOP-25 / Bug Bounty ". Este documento analiza múltiples estudios de casos para transmitir el mensaje de que si piensas limitado, serás limitado. El enfoque de recompensa por errores ha degradado la calidad de las pruebas de penetración, tanto para los clientes como para los profesionales. Es difícil para el cliente diferenciar entre una buena prueba de penetración y un enfoque rápido y sucio de los 10 principales o los 25 principales. Este documento ayudará a aquellos que acaban de entrar en el campo de la seguridad de la información y a los cazarrecompensas de errores.

Precaución: este artículo puede cambiar y cambiará la mentalidad y el hábito del pentester típico. Proceda con precaución. Esto puede causarle un serio dolor de cabeza a sus sentimientos.

1. Introducción

કેમ છો? મજામાં. Soy Ravikumar Paghdal, actualmente trabajo como gerente sénior en Net Square Solutions Pvt. Ltd. _ En mi experiencia anterior, he revisado cientos de evaluaciones de vulnerabilidades de aplicaciones web/móviles e informes de pruebas de penetración de múltiples organizaciones y hay una cosa que siempre es común en todos los informes, ¿adivina qué?

"Lo más común son las vulnerabilidades conocidas".

Sí, estoy hablando de inyección de SQL, XSS, CSRF, IDOR, encabezados de seguridad faltantes, etc.

La parte impactante es que, según una encuesta realizada por HackerOne en 2019 "La encuesta y las estadísticas de la comunidad de hackers éticos" (página 39), más del 50 % de los cazadores de BugBounty se centran únicamente en XSS y SQLi.

CADA VEZ MÁS HACKERS NOMBRAN XSS SU VECTOR DE ATAQUE FAVORITO

Cuando se les preguntó acerca de su vector, técnica o método de ataque favorito, más del 38% de los piratas informáticos encuestados dijeron que prefieren buscar vulnerabilidades de secuencias de comandos entre sitios (XSS). Eso es solo un 28 % más que el año pasado y coloca a XSS significativamente por delante de todas las demás preferencias de vector de ataque. La inyección de SQL ocupó el segundo lugar con un 13,5 %, mientras que el fuzzing, la lógica empresarial y la recopilación de información completaron los cinco primeros. En 2017, ni la lógica empresarial ni la recopilación de información se ubicaron en el top 10 el año pasado.- "La encuesta y estadística de la comunidad de hackers éticos" (página 38)

Después de dedicar suficiente tiempo a pensar por qué estos hallazgos son más comunes en todos los informes de seguridad. Finalmente concluí la respuesta y es tan simple.

"Porque un analista de seguridad o un probador de penetración solo se enfoca en vulnerabilidades conocidas".

Desde mi experiencia, puedo decir que se trata de los comportamientos habituales o patrones de práctica . Esto es lo que he observado en base a la mayoría de los mecanismos de prueba o mentalidad de los analistas hacia las pruebas, la estrategia básica es interceptar la solicitud HTTP e inyectar comillas simples ( ), comillas dobles ( ), signo mayor que ( ) y signo 'menor "que >( <) para identificar vulnerabilidades. Al inyectar esos caracteres especiales, la mente de un analista tiene un proceso de pensamiento que eventualmente conduce a encontrar solo XSS y SQLi;)

Siempre me he preguntado acerca de esta estrategia, por qué no inyectan caracteres como backtick ( `), pipe ( |), Null character ( %00), Zalgo text ( N̯̱̣͇̖̦̦̣ͥͮͩͪ̐͑͂̈̅ͦ͋̆̔͆̀̆̀̚̚̕ ), multibyte character ( , 𒐫), Carriage Return (ASCII 13, ), Line Feed ( ASCII 10, ) o caracteres diferentes, ¿por qué?

Entendamos el concepto de patrón de práctica de la forma más sencilla.

Recuerde esos días cuando comenzó con su primera prueba de aplicación web o puede decir su fase de aprendizaje inicial, durante ese tiempo tuvo la práctica de encontrar errores comunes como SQL Injection, XSS, CSRF, etc. Pero ahora hemos crecido y hay muchos errores nuevos en el mercado (según Common Weakness Enumeration ( CWE List versión 3.4 ), el número total de debilidades de software es 808 ), entonces, ¿por qué nos enfocamos solo en la vulnerabilidad común?

Creo firmemente que después de revisar los siguientes estudios de casos, podrá descubrir qué está mal con la mentalidad actual de pentester.

Tomemos una solicitud HTTP que contiene dos parámetros 'uid'y 'pass'.

Ahora, si sabe cómo encontrar vulnerabilidades en una aplicación web, proporcione una respuesta a algunas de mis preguntas simples.

  1. ¿Qué parte de la solicitud es vulnerable?

  2. ¿Qué vulnerabilidad afectará a la aplicación y en qué parte?

La respuesta más común sería dos parámetros 'uid'y, 'pass'o más, alguien responderá, incluidos los parámetros de cookies '_a', '_b'y '_c'también. Bien ??!!

Continuemos con los siguientes estudios de casos para cambiar su punto de vista sobre las pruebas de seguridad de aplicaciones web.

2. Estudios de casos

En los primeros cinco casos de estudio a continuación, Bes una empresa de servicios bancarios y financieros. Utilizan servidor web W, servidor de aplicaciones A, base de datos SQL S, base de datos NoSQL N, servidor de archivos F, servidores de registro L1(base de datos basada en Oracle) y L2(máquina Linux) y servidor de controlador de dominio ADpara la autenticación.

Tenga una cosa en mente, en todos los siguientes casos de estudio; solo tiene una única página de inicio de sesión en el lado del cliente para probar, la arquitectura se proporciona solo para su comprensión, sobre las posibles operaciones del lado del servidor. No hemos cubierto la vulnerabilidad de la lógica empresarial en los estudios de casos a continuación porque varía con las diferentes aplicaciones. Por lo tanto, nos centraremos solo en las vulnerabilidades técnicas.

2.1 Un estudio de caso con arquitectura de aplicación web típica

Se nos proporcionó una sola página para realizar pruebas de caja negra en una aplicación bancaria B, una vez que ingresamos el ID de usuario y la contraseña , estos dos parámetros 'uid'atravesarán 'pass'el servidor web Wy Wgenerarán consultas SQL dinámicas para recuperar los detalles del usuario de la base de datos MySQL S.

Pasos involucrados:

  1. El navegador enviará dos parámetros 'uid'y 'pass'al servidor web W.

  2. El servidor web Wrecibirá parámetros y generará una consulta SQL dinámica.

  3. SQL Query se activará en el servidor de la base de datos Sy proporcionará la salida deseada al servidor web W.

Nuestra primera solicitud con 'uid'y 'pass'recorre de la misma manera y generará una consulta SQL dinámica. Entonces, ¿nuestra página de inicio de sesión se ve afectada por qué vulnerabilidad? Inyección SQL, ¿verdad?

2.2 Un estudio de caso con un servidor de archivos habilitado para WebDAV

Igual que antes, tenemos una única página de inicio de sesión para realizar pruebas, pero el servidor de la base de datos no está implementado en el lado del servidor. Todos los datos se almacenan en formato de archivo en el servidor de archivos F. Una vez que el servidor web recibe los parámetros W, el servidor web se conectará al servidor de archivos usando métodos WebDAV ( PUT , PATCH , etc.) y esos métodos actualizarán los datos del usuario. Entonces, en este estudio de caso; los parámetros son los mismos 'uid'y 'pass'la vulnerabilidad diferirá.

Pasos involucrados:

  1. El navegador enviará dos parámetros 'uid'y 'pass'al servidor web W.

  2. El servidor web Wse conectará al servidor de archivos Futilizando métodos WebDAV .

  3. El servidor de archivos Frealizará la operación de archivo según el método WebDAV recibido .

En el estudio de caso 2.2, no tiene ningún control sobre las llamadas o los métodos de servidor a servidor, así que no piense en la explotación del método PUT . Solo tendrá control sobre dos parámetros 'uid', 'pass'así que piense detenidamente, ¿qué puede hacer con estos dos parámetros y qué tipo de vulnerabilidad puede descubrir?

Aquí hemos observado que el nombre del archivo de usuario se crea en función del nombre de usuario y cuando el usuario intente acceder al archivo, el servidor de archivos responderá con los datos del usuario del sistema de archivos, ¿y qué si inserta la siguiente carga útil en el parámetro 'uid'?

uid=../../../../../../../../../../../../../../etc/passwd&pass=xyz

Sí, está en el camino correcto... existe la posibilidad de una vulnerabilidad de cruce de ruta de archivo .

2.3 Un caso de estudio con base de datos NoSQL y procesamiento XML

Tenemos la misma página de inicio de sesión, pero esta vez se cambia la arquitectura del servidor; en esta arquitectura, la responsabilidad del servidor web es solo recibir parámetros, convertirlos a formato XML y reenviarlos al servidor de aplicaciones A.

El servidor de aplicaciones Asolo puede entender la solicitud XML o JSON. Si el servidor de aplicaciones Arecibe una solicitud del servidor web W, la analizará en una solicitud XML y, si la solicitud se recibe desde la aplicación de Android, ANla analizará en JSON.

En resumen, toda la lógica comercial codificada en el servidor de aplicaciones Ay el servidor DB Nse basa en mongoDB. Una vez que el servidor de aplicaciones recibe una solicitud de inicio de sesión, la procesará y creará consultas dinámicas y las pasará al servidor de base de datos N. Si el servidor de aplicaciones recibe una respuesta válida del servidor de base de datos N, pasará la respuesta al servidor web W, que luego creará una página HTML.

Pasos involucrados:

  1. El navegador enviará dos parámetros al servidor web 'uid'y , si está utilizando una aplicación móvil , enviará una solicitud JSON al servidor de la aplicación .'pass'WAN{uid:"<userid>",pass:"<password>"}A

  2. El servidor web Wrecibirá el parámetro; conviértalos a formato XML y reenvíelos al servidor de aplicaciones A.

  3. El servidor de aplicaciones Aanalizará la solicitud y realizará una llamada de inicio de sesión al servidor Mongo DB N.

En este caso, el valor de nuestro parámetro se convertirá en una solicitud XML. Por lo tanto, puede inyectar cargas útiles XML 'uid'y 'pass'parámetros y luego se analizará en el servidor de aplicaciones A. Por lo tanto, el atacante puede realizar todos los ataques XML posibles, como inyección XML , XXE , ataque XInclude , inyección XSLT e inyección XPATH [si las consultas XPath están involucradas en este proceso].

Otra observación es que mongoDB no acepta declaraciones SQL. Por lo tanto, debe inyectar declaraciones NoSQL y 'uid'es vulnerable a la inyección NoSQL .

2.4 Un estudio de caso con vulnerabilidades y explotación basadas en el servidor de registro

Nuevamente, tenemos la misma página de inicio de sesión con dos parámetros 'uid'y 'pass'también tenemos la misma arquitectura que el caso de estudio 2.3, pero además del caso de estudio anterior, tenemos dos servidores de registro.

Un servidor de registro L1se basa en ORACLE DB y el segundo servidor de registro L2se basa en el proceso de línea de comandos de Linux. Cada solicitud individual recibida por el servidor de la aplicación Ase copiará y enviará a ambos servidores de registro L1, L2y luego el servidor de la aplicación Aprocesará la solicitud.

Pasos involucrados:

  1. El navegador enviará dos parámetros al servidor web 'uid'y , si está utilizando una aplicación móvil , enviará una solicitud JSON al servidor de la aplicación .'pass'WAN{uid:"<userid>",pass:"<password>"}A

  2. El servidor web Wrecibirá el parámetro; conviértalos a formato XML y reenvíelos al servidor de aplicaciones A.

  3. Cada solicitud recibida por el servidor de la aplicación se Acopiará y enviará a ambos servidores de registro L1. L2Si el servidor de aplicaciones Arecibe una solicitud JSON, es {uid:"ravi",pass:"P@ssw0rd"} decir, el servidor de aplicaciones enviará este JSON al servidor de registro L1y al servidor de registro L2.

  • En el servidor de registro L1, la solicitud se generará como la siguiente consulta SQL

INSERT INTO LOG_2019 VALUES('{uid:"ravi",pass:"P@ssw0rd"}'); INSERT INTO LOG_2019 VALUES('{uid:"ravi",pass:"Wr0ng_P@55w0rd"}'); INSERT INTO LOG_2019 VALUES('{uid:"admin",pass:"admin"}'); INSERT INTO LOG_2019 VALUES('{uid:"test",pass:"test@123"}');

  • En el servidor de registro L2, la solicitud se generará como el siguiente comando para agregar la solicitud al archivo de registro.

echo '{uid:"ravi",pass:"P@ssw0rd"}' >> LOG_2019.log echo '{uid:"ravi",pass:"Wr0ng_P@55w0rd"}' >> LOG_2019.log echo '{uid:"admin",pass:"admin"}' >> LOG_2019.log echo '{uid:"test",pass:"test@123"}' >> LOG_2019.log

  1. El servidor de aplicaciones Aanalizará la solicitud y realizará una llamada de inicio de sesión al servidor Mongo DB N.

En este caso, todas las vulnerabilidades posibles son similares al estudio de caso 2.3, además, los valores de nuestros parámetros se invocan directamente en la solicitud de los servidores de registro para que el atacante pueda inyectar su carga útil en el proceso de registro. Por lo tanto, el servidor de registro L1es vulnerable a la inyección SQL y el servidor de registro L2es vulnerable a la inyección de comandos del sistema operativo .

La parte divertida es que puede inyectar su carga útil en cualquier lugar de la solicitud JSON, que no se limita solo al valor del parámetro, porque toda la solicitud JSON se registrará en el servidor de registro.

Una cosa más, si observa la arquitectura profundamente, toda la comunicación de servidor a servidor es bidireccional, pero solo las L1/L2llamadas del servidor de registro son en una sola dirección. Entonces, si desea identificar esta inyección ciega, debe conocer las técnicas fuera de banda , cómo funciona y debe aprender sobre el colaborador BURP para detectar este tipo de vulnerabilidades ocultas [ocultas porque no puede observar ningún error o tiempo retraso en la respuesta, hay que explotar este tipo de vulnerabilidades usando técnicas OOB].

2.5 Un caso de estudio con protocolo LDAP y JSON Web Token

De nuevo, tenemos la misma página de inicio de sesión con dos parámetros 'uid'y 'pass'tenemos la misma arquitectura que el caso de estudio 2.4, pero además del caso de estudio anterior, tenemos un proceso de autenticación para validar a un usuario mediante el protocolo LDAP .

Una vez que el servidor de aplicaciones Arecibe la solicitud de inicio de sesión, reenviará la solicitud al directorio activo o al controlador de dominio ADpara validar al usuario; basado en la autenticación de Windows y este proceso se implementa mediante cadenas LDAP dinámicas. Si el usuario y la contraseña de la solicitud son válidos, el servidor ADemitirá el token web JSON (JWT) y, además, toda la autenticación se llevará a cabo mediante la verificación del token JWT.

Pasos involucrados:

  1. El navegador enviará dos parámetros al servidor web 'uid'y , si está utilizando una aplicación móvil , enviará una solicitud JSON al servidor de la aplicación .'pass'WAN{uid:"<userid>",pass:"<password>"}A

  2. El servidor web Wrecibirá el parámetro.

  3. El servidor web Wlos convertirá a formato XML y los reenviará al servidor de aplicaciones A.

  4. Cada solicitud recibida por el servidor de la aplicación se Acopiará y enviará a ambos servidores de registro L1.L2

  5. El servidor de aplicaciones Acreará una consulta LDAP dinámica para validar una identificación de usuario y una contraseña y reenviará la solicitud al directorio activo o al controlador de dominio ADpara validar al usuario.

  6. Si el usuario es válido, el ADservidor emitirá JSON Web Token (JWT) .

  7. Si la solicitud del usuario tiene un token JWT, el servidor de aplicaciones Aanalizará la solicitud e iniciará el procesamiento de datos en el servidor Mongo DB N.

Todos los ataques posibles para este estudio de caso son similares a los del estudio de caso 2.4, además de la inyección de LDAP y la posibilidad de problemas relacionados con la configuración incorrecta de JWT .

2.6 No confíe en los encabezados HTTP: un estudio de caso con CVE-2019-5418

En este escenario, revisaremos algunas de las vulnerabilidades descubiertas en los encabezados HTTP.

CVE-2019-5418 : Divulgación de contenido de archivo en Rails encontrado por John Hawthorn

En este caso, el encabezado Aceptar HTTP es vulnerable a la divulgación del contenido del archivo.

Las imágenes a continuación muestran que el encabezado HTTP Referer es vulnerable a la inyección de SQL.

Entonces, mi pregunta para todos los evaluadores es: "¿Con qué frecuencia verifican las diferentes vulnerabilidades en dichos encabezados HTTP?".

2.7 Pruebas listas para usar o pruebas extrañas: un estudio de caso con CVE-2018-4124

CVE-2018-4124 జ్ఞా Este personaje telugu hace que los iPhone de Apple se bloqueen (Actualización: Error solucionado con iOS 11.2.6)

Alguien notó que mostrar una cadena escrita en el idioma telugu de la India ( జ్ఞా) provocó que muchas aplicaciones en iOS y macOS fallaran.

Apple se dio cuenta del problema después de que la noticia del error comenzó a difundirse en las redes sociales y los trolls y bromistas comenzaron a explotarlo. Aparentemente, un individuo mostró cómo podía bloquear la aplicación de Uber en los teléfonos de los conductores poniendo su nombre en la cadena problemática y luego solicitando un viaje.

Si bien inicialmente solo una determinada cadena de telugu parecía funcionar, algunos notaron más tarde que una cadena específica que usaba caracteres del idioma bengalí de la India también provocó que las aplicaciones en iOS y macOS fallaran. Hay varias teorías sobre lo que puede estar causando el bloqueo, incluso del ingeniero de investigación de Mozilla Manish Goregaokar y Philippe Verdy del Consorcio Unicode.

La compañía corrigió la falla con el lanzamiento de la actualización complementaria macOS High Sierra 10.13.3, iOS 11.2.6, watchOS 4.2.3 y tvOS 11.2.6.

Otro caso es Breaking Parser Logic: quite la normalización de su ruta y saque 0 días por @ orange_8361

CVE

marco de primavera

CVE-2018-1271

Marco de chispa

CVE-2018-9159

Jenkins

CVE-2018-1999002

Mojarra

CVE-2018-14371

Ruby on Rails

CVE-2018-3760

Sinatra

CVE-2018-7212

Siguiente.js

CVE-2018-6184

resolver-ruta

CVE-2018-3732

¡Así que después de una historia larga y otra corta!

¿Qué aprendemos como pentester basado en el estudio de caso 2.7 Pruebas listas para usar o pruebas extrañas?

No crea en ningún carácter Unicode único, debe verificar su servidor web con todos los Unicode posibles. Bien ?? No sabe qué Unicode bloqueará su servidor. ;)

Para jugar más con Unicode, debe consultar Unraveling Unicode: A Bag of Tricks for Bug Hunting and Exploiting Unicode-enabled Software de Chris Weber .


Siempre será un tema de debate, Por qué Johnny no puede hacer una prueba de penetración: un análisis de los escáneres de vulnerabilidad web de caja negra y las pruebas automáticas frente a las manuales. El escáner hará lo mismo, establecerá todos los puntos de inyección y el programa y la fumigación con cargas útiles predefinidas. Según la respuesta del servidor, el escáner decidirá si existen vulnerabilidades o no.

En muchos casos de prueba, el escáner automatizado fallará, los siguientes son algunos ejemplos.

  • Hemos enviado una solicitud de análisis automático y, durante el análisis, la sesión finaliza.

  • Durante el análisis, el servidor responde lentamente y el resto de la respuesta de la prueba se retrasará, el escáner detecta la vulnerabilidad basada en el tiempo (hallazgos falsos positivos).

  • El servidor arroja un mensaje de error que no está en la base de datos de la firma del escáner.

  • Las páginas web contienen las palabras que se enumeran en la firma DB.

  • Durante el escaneo: el servidor renueva el token de sesión.

  • ¡La nueva vulnerabilidad lanzada no es parte del escáner!

  • Las URL de aplicaciones creadas en tiempo de ejecución se basan en DOM o JS...

Conclusión

Por encima de todo, los 5 casos de estudio tienen una cosa en común, es la misma página de inicio de sesión con uidun passparámetro.

Como Black Box Tester, no conocemos la configuración y la arquitectura del lado del servidor. Entonces, debe seguir dos declaraciones durante la prueba.

Cada parte controlable por el usuario de la solicitud HTTP es vulnerable a todas las vulnerabilidades posibles. Así que piensa como un atacante y prueba como un atacante.

Los atacantes no siguen las normas y certificaciones de cumplimiento. -Samil Shah

Con base en los 5 estudios de casos anteriores, hemos llegado a la conclusión de que no se pueden juzgar las vulnerabilidades en función del nombre del parámetro, hemos visto una sola falla con dos parámetros uidy passtenemos la posibilidad de explotar múltiples vulnerabilidades (SQLi, RCE, LDAPi, NoSQLi, ataques XML, etc.) .) en la misma solicitud/petición.

En el caso de estudio 2.6, se menciona claramente que tampoco ignorar los encabezados HTTP, es tan importante como los parámetros.

Nunca se sabe en qué solicitud y en qué proceso el desarrollador involucra el encabezado HTTP durante la codificación de la aplicación. Así que no juzgues los encabezados a ciegas y realiza un pentesting adecuado.

En el estudio de caso 2.7, aprendimos que siempre se realizan pruebas inmediatas durante el pentest para descubrir más errores anormales (tal vez incluso 0 días).

Ahora, tienes la misma solicitud HTTP.

y usted tiene la misma pregunta.

  1. ¿Qué parte de la solicitud es vulnerable?

  2. ¿Qué vulnerabilidad afectará a la aplicación y en qué parte?

Tienes tu respuesta. ¿Bien?

Cada esquina de la solicitud incluye métodos HTTP , encabezados de mensajes y todos los parámetros son vulnerables a todas las vulnerabilidades posibles.

Incluso, hemos revisado algunos casos de prueba en los que fallará el escáner automático. Por lo tanto, debe crear dicho proceso o metodología de prueba para involucrar la mente humana en el proceso automatizado, una especie de enfoque mixto para alcanzar un nivel satisfactorio de su proceso de prueba.

"El mayor inconveniente para el pentester es el temor constante de 'perderse en la vulnerabilidad' y la falta de entusiasmo para encontrar un día cero o realizar pruebas extrañas debido a la fecha límite. Siempre podemos hacer un trabajo inteligente, pero si nos perdemos el día cero, eso es todo. sería nuestro mayor arrepentimiento".

¡¡Ohh sí!!. Por último, pero no menos importante, tengo un último caso de estudio para usted y debe hacerlo usted mismo.

Caja negra: hágalo usted mismo.


Apéndice A: Bibliografía

Herramientas/Código:

  1. Generador de texto Zalgo en línea https://zalgo.org/

Artículos/Publicaciones de blog:

Documentación de referencia:

  1. CWE/SANS TOP 25 Errores de software más peligrosos https://www.sans.org/top25-software-errors/

  2. Hábito, actitud y comportamiento planificado https://www.tandfonline.com/doi/abs/10.1080/14792779943000035

  3. Extensiones HTTP para creación y control de versiones distribuidas en la Web (WebDAV) https://www.ietf.org/rfc/rfc4918.txt

  4. Mejores prácticas actuales de JSON Web Token https://tools.ietf.org/html/draft-ietf-oauth-jwt-bcp-07

  5. Por qué Johnny no puede hacer una prueba de penetración: un análisis de los escáneres de vulnerabilidad web de caja negra https://sefcom.asu.edu/publications/black-box-scanners-dimva2010.pdf

Hazañas:

  1. Divulgación del contenido del archivo en Ruby on Rails https://github.com/mpgn/CVE-2019-5418

Presentaciones de conferencia:

  1. Rompiendo la lógica del analizador: desactive la normalización de su ruta y haga estallar 0 días fuera: Orange Tsai, Blackhat USA 2018 https://i.blackhat.com/us-18/Wed-August-8/us-18-Orange-Tsai-Breaking- Parser-Logic-Take-Your-Path-Normalization-Off-And-Pop-0days-Out-2.pdf

  2. Desentrañando Unicode: una bolsa de trucos para la caza de errores - Chris Weber https://www.blackhat.com/presentations/bh-usa-09/WEBER/BHUSA09-Weber-UnicodeSecurityPreview-SLIDES.pdf

Menciones personales:

  1. Saumil Shah @therealsaumil https://twitter.com/therealsaumil

  2. John Hawthorn @jhawthorn https://twitter.com/jhawthorn

  3. Cheng-Da Tsai @orange_8361 https://twitter.com/orange_8361

  4. Chris Weber @w3be https://twitter.com/w3be

  5. Binni Shah @binitamshah https://twitter.com/binitamshah

  6. Dafydd Stuttard @dafyddstuttard https://twitter.com/dafyddstuttard

Gracias especiales

  • samil shah

  • su sha

  • número de hígado

  • aditya modha

Last updated

Was this helpful?