Nytro Posted March 1, 2013 Report Posted March 1, 2013 Solving ESET’s CONfidence 2012 CrackmeSolving ESET’s CONfidence 2012 Crackme 12 comments IntroHave You heard / read about CONfidence? It’s two days IT security conference, organized annualy in Cracow, Poland. (Here you can read more…). It used to be a tradition, that ESET company prepares a CrackMe, for atendees of the conference. This year the rules were different: they published the CrackMe before, and decided to reward first 5 solvers by CONfidence tickets ^^. And it happend – I was the one of them … So, now I have a pleasure to describe for You what the CrackMe was about and how did i aproached it. CrackMe Here You can find original CrackMe: CONfidence CrackMe2012 (password to rar: ESET)If you are not interested to unpack it, but just to play with algo, here i prepared unpacked version: Unpacked CrackMeThe CrackMe was writen in assembler and packed with MPRESS. It uses 2 custom hashing procedures – one of them was generated on the base of username. Unpacking it was very easy – i did it just by stepping in OllyDbg, and then dumping the memory. No external tools for imports rebuilding were required. Tools used PEid (optional) ImmunityDbg / OllyDbg - with OllyDump plugin (for unpacking) Tiny self-made tools writen in C++ (i will describe them further) What CrackMe does- gets the username (length of username: from 4 to 31)- gets the password (must be exactly 24 characters long, containing characters [A-Za-o])- generates 3 MD5 hashes in following manner:#1 -> md5(username)#2 -> md5(#1)#3 -> md5(#2)input: hasherezade hash#1 = D88EB947A504FCF6C3D9DCA5F84DE42Ahash#2 = 12EB2430F671103B94D11F34D375CC0Dhash#3 = B23D343E81CEE206B9D180B7B0189010Sample Md5 generator Hashes are used to generate an MMX code, used in password verification. The most (the only?) challenging part was to crack this MMX hash. It’s easy to spot this function, because it is called just before the decision, whether the password is correct or not. It’s result is compared with hash#1, and when it is equal, then our password is accepted. The address of the function is hidden in EAX… The function is placed at memory address 0×403090 (till 0×404355). 1536 MMX instructions… Looks long and messy? Think so… It’s just a begining… First impresion was to brutforce it… But never mind, first impressions are often just delusions Obviously, brutforcing this would take ages! So there must be some other way…If You look closer, You see, that it’s not such a mess as it seems to be.I always like to start by sorting out what’s searched and what’s given Searched and given: Input is placed in registers MM0 to MM5. Output – placed in: MM0 to MM1 Registers at the begining of function execution:MM0,MM1 -> ? (our password in processed form)MM2,MM3 -> hash#2MM4,MM5 -> hash#3(mind endians!) MM0 and MM1 are filled with some “mysterious” hash – by simple experiments you can see that it is related with given password, but now we will not go into details of it…In the registers [MM2, MM3] hash#2 is placed and in [MM4, MM5] hash#3. Note, that these registers are not changing till the end of the procedure. (When i noticed it, i got sure that it is reversable ) Registers at the end of the function execution (changes are in highlighted)MM0,MM1 -> ?? (should be hash#1)MM2,MM3 -> hash#2MM4,MM5 -> hash#3 The registers MM7, MM8 are used as helpers in calculation…The correct output should be the hash#1 placed in MM0, MM1… In short words, we must input into MM0, MM1 something, which after all this operations will let us have hash#1 in MM0, MM1… No other option – this long function must be reversed.Let’s take a closer look.There are 256 blocks of 6 instructions, which follows similar logic. See the samples below: For every N-th block:1. Result from N-1 block (stored in MM0 or MM1) is moved to “helper register” – MM7 or MM62. Part of hash#2 or hash#3 os moved to “helper register” – MM6 or MM73. Some 3 operations are performed on this “hash part”4. Result of these operations is addes/substracted/xored with result of N-2 block, stored in MM0 or MM1 It gives us plenty of information! For every operation, we can easly calculate the value, with which MM0/MM1 is modified. And we KNOW the last value of MM0, MM1! It’s hash#1. If take a closer look, you notice, that the only things we must do is:- reverse the last instruction in every block (change from PADDB to PSUBB and so on…)- set the blocks in opposit order (the last block must be the first one)- then – if you give hash#1 as an input (in MM0, MM1) – you will get as an output the searched value (the encoded password )How to do it? There are many ways, and i am gona demontrate some more interesting examples later on. But, actually, the task specified by ESET was just to find the proper key for one’s name and surname (not to write a keygen). So i did it in very fast and dirty way – on the original exe. I coppied the piece of memory containing all these instruction, then reversed it by my small parsing tool (written in C++), and copied again at the place. Left -bottom fragment of original;Right – top fragment of reversed When i inserted hash#1 as the initial value of MM0 and MM1, it gave me at the end the searched – means – encoded password! MM0 = AFEC FFD1 F7D1 9AE0MM1 = 8597 249E 0642 1F2D Now it’s not a big deal to decode it. Password encoding/decoding Password encoding goes along with password verification. It is very simple. Every character of the password is processed in a following way (let’s denote the processing function by f1: ) f1:if pass in [a-o] : value = pass – 0×41 – 0×6if pass in [A-Z] : value = pass – 0×41otherwise – incorrect passwordBut not only they are processed, they are also added into a polynominal… Password is divided into chunks of 3 characters :3 chars of password ->( f1(pass[n]) * 0×29 +f1( pass[n+1] ) ) * 0×29 + f1(pass[n+2]) –>4 bytes of the “encoded password”To ilustrate, how it can be reversed, I placed here a source of my Simple Chunk Decoder.MM0 = AFEC FFD1 F7D1 9AE0MM1 = 8597 249E 0642 1F2D 9AE0 F7D1 FFD1 AFEC 1F2D 0642 249E 8597Password decoded by the Simple Chunk Decoder Now just copy the password into the field… And it’s done! Post ScriptumDue to the fact, that some people are interested, I am prepairing a new post on keygenning this crackme – including analysis of the MMX instructions generating code. If You want to see alternative solution, take a look on Vnd’s homepage Sursa: Solving ESET’s CONfidence 2012 Crackme | hasherezade's 1001 nights Quote