lunes, mayo 18, 2015

ASIS CTF Quals 2015 - sawthis writeup - srand remote prediction

The remote service ask for a name, if you send more than 64 bytes, a memory leak happens.
The buffer next to the name's is the first random value used to init the srand()

If we get this value, and set our local srand([leaked] ^ [luckyNumber]) we will be able to predict the following randoms and win the game, but we have to see few details more ;)

The function used to read the input until the byte \n appears, but also up to 64 bytes, if we trigger this second condition there is not 0x00 and the print shows the random buffer :)

The nickname buffer:

The seed buffer:

So here it is clear, but let's see that the random values are computed with several gpu instructions which are decompiled incorrectly:

We tried to predict the random and aply the gpu divisions without luck :(

There was a missing detail in this predcitor, but there are always other creative ways to do the things.
We use the local software as a predictor, we inject the leaked seed on the local binary of the remote server and got a perfect syncronization, predicting the remote random values:

The process is a bit ugly becouse we combined automated process of leak exctraction and socket interactive mode, with the manual gdb macro.

The macro:

Defcon 2015 coding skillz 1 writeup

Just connecting to the service, a 64bit cpu registers dump is received, and so does several binary code as you can see:

The registers represent an initial cpu state, and we have to reply with the registers result of the binary code execution. This must be automated becouse of the 10 seconds server socket timeout.

The exploit is quite simple, we have to set the cpu registers to this values, execute the code and get resulting registers.

In python we created two structures for the initial state and the ending state.

cpuRegs = {'rax':'','rbx':'','rcx':'','rdx':'','rsi':'','rdi':'','r8':'','r9':'','r10':'','r11':'','r12':'','r13':'','r14':'','r15':''}
finalRegs = {'rax':'','rbx':'','rcx':'','rdx':'','rsi':'','rdi':'','r8':'','r9':'','r10':'','r11':'','r12':'','r13':'','r14':'','r15':''}

We inject at the beginning several movs for setting the initial state:

for r in cpuRegs.keys():
    code.append('mov %s, %s' % (r, cpuRegs[r]))

The 64bit compilation of the movs and the binary code, but changing the last ret instruction by a sigtrap "int 3"
We compile with nasm in this way:

os.popen('nasm -f elf64 code.asm')
os.popen('ld -o code code.o ')

And use GDB to execute the code until the sigtrap, and then get the registers

fd = os.popen("gdb code -ex 'r' -ex 'i r' -ex 'quit'",'r')
for l in fd.readlines():
    for x in finalRegs.keys():

We just parse the registers and send the to the server in the same format, and got the key.

The code:

from libcookie import *
from asm import *
import os
import sys

host = ''
port = 9999

cpuRegs = {'rax':'','rbx':'','rcx':'','rdx':'','rsi':'','rdi':'','r8':'','r9':'','r10':'','r11':'','r12':'','r13':'','r14':'','r15':''}
finalRegs = {'rax':'','rbx':'','rcx':'','rdx':'','rsi':'','rdi':'','r8':'','r9':'','r10':'','r11':'','r12':'','r13':'','r14':'','r15':''}
fregs = 15

s = Sock(TCP)
s.timeout = 999

data = s.readUntil('bytes:')

#data =
#data = s.readAll()

sz = 0

for r in data.split('\n'):
    for rk in cpuRegs.keys():
        if r.startswith(rk):
            cpuRegs[rk] = r.split('=')[1]

    if 'bytes' in r:
        sz = int(r.split(' ')[3])

binary = data[-sz:]
code = []

print '[',binary,']'
print 'given size:',sz,'bin size:',len(binary)        
print cpuRegs

for r in cpuRegs.keys():
    code.append('mov %s, %s' % (r, cpuRegs[r]))

#print code

fd = open('code.asm','w')

print 'Compilando ...'
os.popen('nasm -f elf64 code.asm')
os.popen('ld -o code code.o ')

print 'Ejecutando ...'
fd = os.popen("gdb code -ex 'r' -ex 'i r' -ex 'quit'",'r')
for l in fd.readlines():
    for x in finalRegs.keys():
        if x in l:
            l = l.replace('\t',' ')
                i = 12
                spl = l.split(' ')
                if spl[i] == '':
                print 'reg: ',x
                finalRegs[x] = l.split(' ')[i].split('\t')[0]
                print 'err: '+l
            fregs -= 1
            if fregs == 0:
                #print 'sending regs ...'
                #print finalRegs
                buff = []
                for k in finalRegs.keys():
                    buff.append('%s=%s' % (k,finalRegs[k]))

                print '\n'.join(buff)+'\n'

                print s.readAll()
                print 'waiting flag ....'
                print s.readAll()

                print '----- yeah? -----'


lunes, marzo 30, 2015

TLS v1.2 sigalgs remote crash (CVE-2015-0291)

OpenSSL 1.0.2a fix several security issues, one of them let crash TLSv1.2 based services remotelly from internet.

Regarding to the TLSv1.2 RFC,  this version of TLS provides a "signature_algorithms" extension for the client_hello. 

Data Structures

If a bad signature is sent after the renegotiation, the structure will be corrupted, becouse structure pointer:
s->c->shared_sigalgs will be NULL, and the number of algorithms:
s->c->shared_sigalgslen will not be zeroed.
Which will be interpreted as one algorithm to process, but the pointer points to 0x00 address. 

Then tls1_process_sigalgs() will try to process one signature algorithm (becouse of shared_sigalgslen=1) then sigptr will be pointer to c->shared_sigalgs (NULL) and then will try to derreference sigptr->rhash. 

This mean a Segmentation Fault in  tls1_process_sigalgs() function, and called by tls1_set_server_sigalgs() with is called from ssl3_client_hello() as the stack trace shows.


The following code, points sigptr to null and try to read sigptr->rsign, which is assembled as movzbl eax,  byte ptr [0x0+R12] note in register window that R12 is 0x00

Debugger in the crash point.

radare2 static decompiled

The patch fix the vulnerability zeroing the sigalgslen.
Get  David A. Ramos' proof of concept exploit here

domingo, septiembre 21, 2014

S2 Dynamic tracer and decompiler for gdb

Decompiling is very useful for understanding srtipped binaries, most dissasemblers like IDA or Hopper have a plugin for decompiling binaries, generating a c like pseudocode.

Static analysis, is very useful in most of cases, specially when the binary is not so big, or when you just have an address where to start to analyze. But some algorithms will be learned in less time by dynamic analysis like tracing or debugging.

In cookiemonsters team, we are working on several tracers with different focus, but all of them mix the concept of tracing and decompiling to generate human-readable traces.

S2 is my tracer & decompiler plugin for gdb, very useful for ctfs.
Some of the features are:

- signed/unsigned detecion
- conditional pseudocode (if)
- syscall resolution
- unroll bucles
- used registers values
- mem states
- strings
- logging

lunes, septiembre 15, 2014

inBINcible writeup - golang binary reversing

This file is an 32bits elf binary, compiled from go language (i guess ... coded by @nibble_ds ;)
The binary has some debugging symbols, which is very helpful to locate the functions and api calls.

GO source functions:
-  main.main
-  main.function.001

If the binary is executed with no params, it prints "Nope!", the bad guy message.

~/ncn$ ./inbincible 

Decompiling the main.main function I saw two things:

1. The Argument validation: Only one 16 bytes long argument is needed, otherwise the execution is finished.

2. The key IF, the decision to dexor and print byte by byte the "Nope!" string OR dexor and print "Yeah!"

The incoming channel will determine the final message.

Dexor and print each byte of the "Nope!" message.

This IF, checks 16 times if the go channel reception value is 0x01, in this case the app show the "Yeah!" message.

Go channels are a kind of thread-safe queue, a channel_send is like a push, and channel_receive is like a pop.

If we fake this IF the 16 times, we got the "Yeah!" message:

(gdb) b *0x8049118
(gdb) commands
>set {char *}0xf7edeef3 = 0x01

(gdb) r 1234567890123456
tarting program: /home/sha0/ncn/inbincible 1234567890123456

Ok, but the problem is not in main.main, is main.function.001 who must sent the 0x01 via channel.
This function xors byte by byte the input "1234567890123456" with a byte array xor key, and is compared with another byte array.

=> 0x8049456:       xor    %ebp,%ecx
This xor,  encode the argument with a key byte by byte

The xor key can be dumped from memory but I prefer to use this macro:

(gdb) b *0x8049456
(gdb) commands
>i r  ecx
(gdb) c

Breakpoint 2, 0x08049456 in main.func ()
ecx            0x12 18

Breakpoint 2, 0x08049456 in main.func ()
ecx            0x45 69

Breakpoint 2, 0x08049456 in main.func ()
ecx            0x33 51

Breakpoint 2, 0x08049456 in main.func ()
ecx            0x87 135

Breakpoint 2, 0x08049456 in main.func ()
ecx            0x65 101

Breakpoint 2, 0x08049456 in main.func ()
ecx            0x12 18

Breakpoint 2, 0x08049456 in main.func ()
ecx            0x45 69

Breakpoint 2, 0x08049456 in main.func ()
ecx            0x33 51

Breakpoint 2, 0x08049456 in main.func ()
ecx            0x87 135

Breakpoint 2, 0x08049456 in main.func ()
ecx            0x65 101

Breakpoint 2, 0x08049456 in main.func ()
ecx            0x12 18

Breakpoint 2, 0x08049456 in main.func ()
ecx            0x45 69

Breakpoint 2, 0x08049456 in main.func ()
ecx            0x33 51

Breakpoint 2, 0x08049456 in main.func ()
ecx            0x87 135

Breakpoint 2, 0x08049456 in main.func ()
ecx            0x65 101

Breakpoint 2, 0x08049456 in main.func ()
ecx            0x12 18

The result of the xor will compared with another array byte,  each byte matched, a 0x01 will be sent.

The cmp of the xored argument byte,
will determine if the channel send 0 or 1

(gdb) b *0x0804946a
(gdb) commands
>i r al

At this point we have the byte array used to xor the argument, and the byte array to be compared with, if we provide an input that xored with the first byte array gets the second byte array, the code will send 0x01 by the channel the 16 times.

Now web have:



Xor is reversible, then we can get the input needed to dexor to the expected values in order to send 0x1 bytes through the go channel.

>>> x=''
>>> for i in range(len(xorKey)):
...     x+= chr(xorKey[i] ^ mustGive[i])
>>> print x


And that's the key :) let's try it:

~/ncn$ ./inbincible 'G0w1n!C0ngr4t5!!'

Got it!! thanx @nibble_ds for this funny crackme, programmed in the great go language. I'm also a golang lover.

martes, agosto 05, 2014

Web-fu - the ultimate web hacking chrome extension

Web-fu Is a web hacking tool focused on discovering and exploiting web vulnerabilitites.


This tool has many advantages, as a browser-embedded webhacking tool, is very useful for scanning browser-authenticated applications, if browser can authenticate and access to the web application, the tool also can. Note that some other tools do not support neither certificate authentication nor web vpn accesses.
The integration with chrome, provides a more comfortable and agile way of web-hacking, and you have all the application data loaded on the hacking tool, you don't need to copy the url, cookies, etc. to the tool, just right click and hack.
The browser rendering engine is also used in this tool, to draw the html of the responses.


When I coded this tool, I was obsessed with false positives, which is the main problem in all detection tools.  I have implemented a gauss algorithm, to reduce the faslse positives automatically which works very very well, and save a lot of time to the pentester.


 Here is a video, with some of the web-fu functionalitites:


This tool has a visual crawler. Normal crawlers doesn't parse the ajvascript, this tool does. The visual crawler loads each link of the web site, rendering the html and executing all the javascript as a normal load, then the links are processed from he DOM and clicked.
A visual form cracker, is also available, althow is experimental and only works on some kind of forms.


The web-fu's portscanner, has a database of a common web ports, like 80,81,8080 and so on.
The cracker module, can bruteforce web directories to find new attack vectors, and can fuzz get and post parameters for discovering vulns, and also crack passwords. There are 9 preloaded wordlists, and you can also load a custom wordlist. Prefilters, falsepositive reductor and render will be helpful. The scanners support SSL, if the website can be loaded in the chrome, can be scanned by web-fu.


The supported encoders and decoders are: base64, urlescape and urlencode


A web notepad is available, saving the information on the browser localStorage, there is one notepad per site. A cookie editor is also very useful for pentesting. The inteceptor, is like a web proxy but from the inside of the browser, you can intercept a request There is also a session locker and a exploit web search.

Here is the link to the chrome store, the prize is about one euro, very cheap if you compare with other scanners: Web-Fu on Chrome Store

 With webfu, you will do the best web site pentest and vulnerability assessment.

miércoles, julio 23, 2014

HTML5 Games on Android

On my last hollidays, I made two HTML5 games, and published on android market. Nowadays javascript has powerful libraries for doing almost everything, and also there are several compilers from java or c code to javascript, converting opengl c code to html5 canvas, but definitely, javascript execution is slower than dalvik applications, and of course much slower than arm c libs. For improving the speed of sounds and images loader, I have used javascript asynchronous execution and scheduling priority has been controlled with setTimeout/setInterval which deprioritize or priorize a code block. This games are published on the android market here: Android Planets and here: Far Planet

sábado, enero 14, 2012

Android SSHControl v1.0 relased!!!

Hoy sabado 15, he subido al Market de Android la versión 1.0 de SSHControl, con nuevas funcionalades y la esperada opción "Custom Commands".

Esta aplicación permite controlar tus servidores linux, bsd y unix con solo un dedo, mediante esta app Android.
Y soluciona las siguientes problemáticas:
- Manejar una shell desde el pequeño teclado de un móvil es engorroso.
- Leer todos los resultados de un comando en la pantalla del móvil, nos dejamos la vista.

Esta app permite interactuar con servidores remotos simplemente haciendo pulsaciones en la pantalla, mediante un explorador de ficheros, de conexiones, etc..

Las funcionalidades nuevas de esta versión 1.0 son:

- Administración del Firewall Iptables.
- Opción de Custom Commands, tal como había prometido.

Las funcionalidades ya presentes en la v0.8 son:

- escalada a root mediante su y sudo
- gestor de procesos
- explorador de ficheros, editor de ficheros, editor de permisos.
- monitorización y baneo de conexiones
- Visualizadores de logs
- administrador de drivers
- estadisticas de disco

Para la versión 2.0 preveo:

- Escuchar música remota
- Descarga de ficheros (wget)
- Transferencia segura de ficheros entre servidores (scp)
- Gestures, para administrar los sitemas en plan minority report :)

App disponible en el market para 861 tipos de dispositivos y pronto disponible en tablets.

Cualquier sugerencia de mejora: sha0 [4t] badchecksum [d0t] net