Friday, June 29, 2012

Simple IRC/Twitter Irssi Bot

Yesterday I had some free time and I wanted to play a bit with the Perl API for Irssi, that is a console IRC client if not *THE* client.

I don't like like Perl, but it is always nice to learn something new because I always use Python for scripting, that is my preferred language :)

The Perl script is a very basic bot that allows the members of a channel to send twits and also to fetch the timeline.  For being on the safe side, sending twits is only allowed for a list of nicks within an specific channel in order to avoid people sending shit or flooding the public chat.

If you want to play a bit,  the API is focused on signals, that are sent when an event happens (e.g. you receive a message). The events can be hooked, stopped, forwarded, etc.. so it is pretty straightforward. But you have to find the right event and it may be not that easy.

For interacting with Twitter, it uses the module Net::Twitter:Lite and oAuth authentication.

Monday, June 11, 2012

When The Comparison Functions Do Not Compare: The MySQL Fail

I have learned via Mikko Hypponen's twitter account about an epic bug in MySQL. 

This bug  demonstrates why I hate C so much. It is not enough that you have to be really careful when writing code that you also have to be aware of tricks and optimizations applied by the compilers. I cannot point to details but it is not the first time that something like this happens.

In a nutshell (read this post from Rapid7) the memcmp() function does not behave as expected when gcc uses the SSE optimization. As you may have noticed, I am not an expert in C so do not expect a long and detailed explanation.

The documentation states:

Compares the first num bytes of the block of memory pointed by ptr1 to the first num bytes pointed by ptr2, returning zero if they all match or a value different from zero representing which is greater if they do not.

There is no warning whatsoever, but it seems that it is not always the case. As H.D. Moore explains  in his post:

On some platforms and with certain optimizations enabled, this routine can return values outside of this range, eventually causing the code that compares a hashed password to sometimes return true even when the wrong password is specified. Since the authentication protocol generates a different hash each time this comparison is done, there is a 1 in 256 chance that ANY password would be accepted for authentication.

The exploit? Pretty simple: we try to authenticate in  a for loop until the bug appears.

$ for i in `seq 1 1000`; do mysql -u root --password=bad -h 2>/dev/null; done

Update: this post from Hispasec (Spanish) has more information regarding the vulnerability.

It seems the vulnerability would be a truncation from int to char, put together with a compiler optimization.

The function that compares the hash given with the stored in the database can be found in the file  'sql/password.c':
check_scramble(const char *scramble_arg, const char *message, const uint8 *hash_stage2)

return memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE);


As we can see, memcmp() will return an  int, that will be truncated to a char. Therefore, the hash is valid if check_scramble returns the char 0 (non-zero is a wrong hash). As a side note: the type my_bool is defined as char in 'include/my_global.h'.

The patch changes this behaviour to ensure the result. Now, the function check_scramble returns:

return test(memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE));

being test() a macro defined in include/my_global.h

#define test(a) ((a) ? 1 : 0)

This time, we have a boolean operation: return 1 if the value of 'a' is different to 0 and return 0 in other case.

Cracking Hashes Online

Perhaps this tool is well known within the community, but I was not aware of it until now. findmyhash is a Python script that searches for hashes in different online services, supporting the most common ones: MD5, SHA1, LM, NTLM, etc. (check the website for more details) .

Looking at the source code, it uses many  websites I was not aware of.

It is kinda neat that you may not need to use brute force to crack a hash, but the downside ,of course, is that you are sending your hashes to services you may not trust 100%.  Would it be legit to use it during a pentest since we are sending data from our costumers to third party services?