Yes. we noticed that the plains this year have been a good mix between artifical and real passwords (artificial due to the rule processing). So it was much better than last year.
However, the best part was that you added those "tasks". The mt_rand and the wonderful tasks were very challenging, but moreover it was a lot of fun and that was the coolest part about it. Also the tomato stuff was funny :)
The fact that the contest was running for 3 days instead of 2 was also very nice change. It was really necessary with all those challenges that involved real coding.
Members
Most of us were available all the time. We can say we had around 20 members 16H/day working on it. We had tons of GPU, both AMD and some NVidias, but this time with much less problems regarding to driver and overheating since we were prepared carefully. However, in this contest, it was not the hardware power that matters. If you have bcrypt with $12$ multiplier then the only way to crack multiples of them is with a 100% straight attack and with a set of password candidates that you really expect to hit.
Tools used
What I really liked is the fact that we did not need JtR or any other cracker this time. Since oclHashcat became very mature most of the algorithms were already in oclHashcat or they were so strange (like sha1crypt) that we wrote them in a standalone tool or added them (mt_rand md4) to oclHashcat quickly.
Organization
This year we put alot of effort in our internal organization. We learned the last year that the organization can be very important, more important that we thought of in the first place. We starting by choosing dropdead as teamleader whos task it was to think about a better organizational structure.
We divided the team in 4 groups in advance to be able to delegate tasks efficiently. During the contest this turned out to be a good choice, since most of the members could just focus on their share instead of worrying about everything. Dropdead made sure to get constant reports from everyone and shift resources accordingly as necessary. The central hub of communication was an IRC channel that was complimented by a google spreadsheet, an extra site for the management of Hashlists and a Teamspeak Server.
Spreadsheet:
Colaboration System:
Preparation oclHashcat
Two weeks before the contest started hashrunner organizers gave informations about the hashtypes that are being used in the contest. In comparison to last years contest there was Notes5 and Notes6 (dominosec) added, so we expected that those algorithms will be kind of important. Since this algorithm can be handy in pentests as well we decide to add support for them to oclHashcat beforehand. That took longer than expected, because lotus6 encoding was somehow strange to understand. However we finished it in time. Of course we will release oclHashcat v1.21 with lotus5 and lotus6 added soon to public.
Another new feature that helps in different situations (not just contests) was the addition of a basic logfile to oclHashcat. This logfile was planned to be both human- and machine-readable. I don't want to go to much into detail about this feature in this writeup, but related to the contest this logfile gave us the possibility to see which type of attack has been done by who. Due to the very flexible use of oclHashcat this is more a semi-automated process. Each member took the logfile as it is and uploads it to our team collaboration system. It gets automatically parsed and stored in the database so that every other member can filter for a specific hash and to find out what has been done to that particular list before by other team members. Still, the interpretation of that relies to the user of course. It's not perfect yet and I think most members did not use it, but it's a start and we saw how we can improve it further.
Realtime oclHashcat code changes
It was clear that we will face "problems". It's always like this that contest organizer add some "evil" thing into the contest that forces us to make changes to our main software while the contest is running. The mt_rand contest was such a thing, but it was also really cool, here's why:
To solve that mt_rand our first idea was that there is a flaw in the implementation. The mt_rand() will produce random numbers in a sequence, however it's only as random as it's seed is. For example, if mt_srand is initialized to the value 0, the sequence of all numbers produced by mt_rand() is the same. Problem here was there was no guarantee that mt_srand() is called, unless rand() == 42, but then we realized that, depending on the attack we planned, it did not matter at all. The function mt_srand() takes a 32 bit unsigned integer, that means that it takes only values between 0-4294967295 which is inside a brute-force able range. The idea was to go through all possible seeds and since the code was written, the first call to mt_rand() must be used for plaintext generation and if we do the same calculation as razor api does + the custom function from organizers we should hit some hash and therefore know about the seed being used (we'd had expect 25 seeds). From there we could simply brute-force all ongoing mt_rand() calculations, since it's only 25 seeds left. However that strategy did not work and we still don't know why. What we found out that there was a change in PHP 5.2.0 and 5.2.1 where they changes the way how mt_srand() is initialized and therefore results in a different sequence of numbers produced by mt_rand(). That forced us the brute-force all the seeds with older PHP version but for some unknown reason nothing was found. Otherwise we could have cracked 100% of all the mt_rand task hashes.
But then, Xanadrel found another weakness. Since the ..password1() custom function multiplied the value with the previous one it was highly likely that in the end, after 3 multiplications of huge numbers, it would result in an very very huge number. PHP therefore switches the numbers to a scientific notation internally (known weakness in PHP when it comes to crypto) and this put it back into a brute-force able range. Since the resulting mask was always of size 19 or 20 and a portion of 6 static values, it also forced the razor api to use a a specific branch in the create_hash function, the branch to do hash(hash(pass).salt). When we realized that all we had to do is to hack the DCC1 kernel of oclHashcat which does md4(md4(pass).salt) but with unicode, however this took me just 30 minutes and then were able to brute force the entire lower mt_rand() database in a few hours.
Other coding stuff during contest
While both hashcat and oclHashcat support several SHA based crypt functions like sha256crypt and sha512crypt, there was no such implementation based on sha1 available in hashcat crackers. We also quickly discovered that (almost) none other cracker supports sha1crypt nor is it a very used algorithm nowadays. Since we had already cracked several other 'TomatO' hashes of different hash types (like md5crypt, grub2, ...) and we had already collected some possible password candidates in dictionaries, we've developed and run a simple standalone cracker and we quickly discovered that this was the way to go. With this simple test program (little standalone cracker) we got all the cracks we have submitted later on very fast and only very few hashes remained uncracked (2). From this sha1crypt challenge we've learnt that it is not always the speed that matters but having well-drafted input dictionary together with a little bit of luck can help a lot to manage the challenges.
That wonderful task was simply to crazy to port to GPU, so we simply added a while loop around it and piped hashcat data using --stdout into it. Again that wasn't overly fast, but with carefully designed candidates it was fast enough to find at least a few hashes.
Thanks
We want to thank the organizers, you did a very good job this year!!
Gleb Gritsai @repdet
Gifts @GiftsUngiven
Aleksandr Timorin @atimorin
Valentin Shilnenkov
And, of course, we also want to congratulate InsidePro for winning! See you at CMIYC 2014 :)
Thanks to @nicolasbrulez for letting me use his GPUS :)
However, the best part was that you added those "tasks". The mt_rand and the wonderful tasks were very challenging, but moreover it was a lot of fun and that was the coolest part about it. Also the tomato stuff was funny :)
The fact that the contest was running for 3 days instead of 2 was also very nice change. It was really necessary with all those challenges that involved real coding.
Members
- atom
- BlandyUK
- blaz
- chancas
- dakykilla
- Dropdead
- epixoip
- EvilMog
- Hydraze
- K9
- kontrast23
- legion
- m3g9tr0n
- Minga
- NullMode
- philsmd
- purehate
- radix
- Rolf
- rurapenthe
- T0XlC
- unix-ninja
- Xanadrel
- xmisery
Most of us were available all the time. We can say we had around 20 members 16H/day working on it. We had tons of GPU, both AMD and some NVidias, but this time with much less problems regarding to driver and overheating since we were prepared carefully. However, in this contest, it was not the hardware power that matters. If you have bcrypt with $12$ multiplier then the only way to crack multiples of them is with a 100% straight attack and with a set of password candidates that you really expect to hit.
Tools used
- oclHashcat
- hashcat
- maskprocessor
- hashtopus
- PACK
- Google Spreadsheet
What I really liked is the fact that we did not need JtR or any other cracker this time. Since oclHashcat became very mature most of the algorithms were already in oclHashcat or they were so strange (like sha1crypt) that we wrote them in a standalone tool or added them (mt_rand md4) to oclHashcat quickly.
Organization
This year we put alot of effort in our internal organization. We learned the last year that the organization can be very important, more important that we thought of in the first place. We starting by choosing dropdead as teamleader whos task it was to think about a better organizational structure.
We divided the team in 4 groups in advance to be able to delegate tasks efficiently. During the contest this turned out to be a good choice, since most of the members could just focus on their share instead of worrying about everything. Dropdead made sure to get constant reports from everyone and shift resources accordingly as necessary. The central hub of communication was an IRC channel that was complimented by a google spreadsheet, an extra site for the management of Hashlists and a Teamspeak Server.
Spreadsheet:
Colaboration System:
Preparation oclHashcat
Two weeks before the contest started hashrunner organizers gave informations about the hashtypes that are being used in the contest. In comparison to last years contest there was Notes5 and Notes6 (dominosec) added, so we expected that those algorithms will be kind of important. Since this algorithm can be handy in pentests as well we decide to add support for them to oclHashcat beforehand. That took longer than expected, because lotus6 encoding was somehow strange to understand. However we finished it in time. Of course we will release oclHashcat v1.21 with lotus5 and lotus6 added soon to public.
Another new feature that helps in different situations (not just contests) was the addition of a basic logfile to oclHashcat. This logfile was planned to be both human- and machine-readable. I don't want to go to much into detail about this feature in this writeup, but related to the contest this logfile gave us the possibility to see which type of attack has been done by who. Due to the very flexible use of oclHashcat this is more a semi-automated process. Each member took the logfile as it is and uploads it to our team collaboration system. It gets automatically parsed and stored in the database so that every other member can filter for a specific hash and to find out what has been done to that particular list before by other team members. Still, the interpretation of that relies to the user of course. It's not perfect yet and I think most members did not use it, but it's a start and we saw how we can improve it further.
Realtime oclHashcat code changes
It was clear that we will face "problems". It's always like this that contest organizer add some "evil" thing into the contest that forces us to make changes to our main software while the contest is running. The mt_rand contest was such a thing, but it was also really cool, here's why:
To solve that mt_rand our first idea was that there is a flaw in the implementation. The mt_rand() will produce random numbers in a sequence, however it's only as random as it's seed is. For example, if mt_srand is initialized to the value 0, the sequence of all numbers produced by mt_rand() is the same. Problem here was there was no guarantee that mt_srand() is called, unless rand() == 42, but then we realized that, depending on the attack we planned, it did not matter at all. The function mt_srand() takes a 32 bit unsigned integer, that means that it takes only values between 0-4294967295 which is inside a brute-force able range. The idea was to go through all possible seeds and since the code was written, the first call to mt_rand() must be used for plaintext generation and if we do the same calculation as razor api does + the custom function from organizers we should hit some hash and therefore know about the seed being used (we'd had expect 25 seeds). From there we could simply brute-force all ongoing mt_rand() calculations, since it's only 25 seeds left. However that strategy did not work and we still don't know why. What we found out that there was a change in PHP 5.2.0 and 5.2.1 where they changes the way how mt_srand() is initialized and therefore results in a different sequence of numbers produced by mt_rand(). That forced us the brute-force all the seeds with older PHP version but for some unknown reason nothing was found. Otherwise we could have cracked 100% of all the mt_rand task hashes.
But then, Xanadrel found another weakness. Since the ..password1() custom function multiplied the value with the previous one it was highly likely that in the end, after 3 multiplications of huge numbers, it would result in an very very huge number. PHP therefore switches the numbers to a scientific notation internally (known weakness in PHP when it comes to crypto) and this put it back into a brute-force able range. Since the resulting mask was always of size 19 or 20 and a portion of 6 static values, it also forced the razor api to use a a specific branch in the create_hash function, the branch to do hash(hash(pass).salt). When we realized that all we had to do is to hack the DCC1 kernel of oclHashcat which does md4(md4(pass).salt) but with unicode, however this took me just 30 minutes and then were able to brute force the entire lower mt_rand() database in a few hours.
Other coding stuff during contest
While both hashcat and oclHashcat support several SHA based crypt functions like sha256crypt and sha512crypt, there was no such implementation based on sha1 available in hashcat crackers. We also quickly discovered that (almost) none other cracker supports sha1crypt nor is it a very used algorithm nowadays. Since we had already cracked several other 'TomatO' hashes of different hash types (like md5crypt, grub2, ...) and we had already collected some possible password candidates in dictionaries, we've developed and run a simple standalone cracker and we quickly discovered that this was the way to go. With this simple test program (little standalone cracker) we got all the cracks we have submitted later on very fast and only very few hashes remained uncracked (2). From this sha1crypt challenge we've learnt that it is not always the speed that matters but having well-drafted input dictionary together with a little bit of luck can help a lot to manage the challenges.
That wonderful task was simply to crazy to port to GPU, so we simply added a while loop around it and piped hashcat data using --stdout into it. Again that wasn't overly fast, but with carefully designed candidates it was fast enough to find at least a few hashes.
Thanks
We want to thank the organizers, you did a very good job this year!!
Gleb Gritsai @repdet
Gifts @GiftsUngiven
Aleksandr Timorin @atimorin
Valentin Shilnenkov
And, of course, we also want to congratulate InsidePro for winning! See you at CMIYC 2014 :)
Thanks to @nicolasbrulez for letting me use his GPUS :)