Number of crackmes:
Number of writeups:
Comments:
| Name | Author | Language | Arch | Difficulty | Quality | Platform | Date | Downloads | Writeups | Comments |
|---|
| Crackme | Date | Infos | Actions |
|---|
| Crackme | Comment | Date |
|---|---|---|
| Level 10 | [Click to reveal]The end hash is 0x3D17141A. It uses formula of looping total = each_byte_of_string + 0x1F * total. Any text string that works with formula will be succeeded. Password: "6656=, !U656= Flags: Perfect! | 2026-07-13 23:22 |
| Level 9 | [Click to reveal] This one is very tricky for me. I really burnt out when calculate on hexs. But I passed finally. correct 8 letter password: lrys'ume correct flags: Pass!!!! Very great series indeed. | 2026-07-13 22:16 |
| Level 8 | [Click to reveal]“matrix” and the flag is “Matrix!” Keep reading only if you are stuck. There are two pointers. The first pointer contains 7 values and is related to the flag. The second pointer contains 54 encrypted values. These can be divided into 18 groups, with 3 values in each group: label, value, zero - Label 1 represents the index of each character in the 6-letter password. - Label 2 contains an encrypted value that is XORed with the input character at the index specified by Label 1. - Label 3 contains the expected result used to verify the XOR operation. Therefore, XORing the value from Label 2 with the value from Label 3 reveals the correct input character. Repeating this for all six characters gives the password: matrix For the flag, I could only find references such as “Matrix!” or “mATRIX/0x1”, but I could not obtain another printable 6-character password from it. This is a very good educational crackme series. | 2026-07-13 16:58 |
| Level 7 | [Click to reveal] There are 2 enc sequence pointers now. The first one is ignorable since the result is only shown when failure as garbage flags. The real useful sequence is 2nd pointer that has only 7 values. We can also see its being xored with 0x5A. If we do that, we get the strong called license. Very cool lesson. | 2026-07-13 14:48 |
| Level 6 | [Click to reveal] I'm really not sure how to pass this one. It checks 5 letter key and show decrypted flags based on input key. In assembler, program use the text "crack" for +Correct. Any other key will results in Access Denied. If I use "crack" key, program says it's correct but shows random garbage decrypted flag. I don't see any other keys to make it show correct and correct meaningful flags at the same time. To get meaningful flags, I first hooked a pointer in loop that has 8 enc hex. I then brute force on the 8 enc hex by xoring with from 0x1 to 0xFF xor key. It gives me 2 candidates which are Sicceed! with xor key 0x52 and sICCEED/0x1 with xor key 0x72. In assembler, we saw the correct xor key was xored with 0x55 in the first place. If we do it, we will get original value 0x7 for Sicceed! flags or 0x27 for sICCEED/0x1. We also know that value is the last hex byte of total sum of input key. For Sicceed!, candidates total sum of input are 263 (0x107) with , 519 (0x207). Such as amber, angel, cobra, etc. For sICCEED/0x1, candidates are 295 (0x127), 551 (0x227) such as bonus, crops, guess, etc. Or may be I am dumb to not know how to get Access correct and correct flags together. | 2026-07-12 22:01 |
| Level 5 | [Click to reveal]This level is also similar with previous one but with more math logic. Still the same though. We find the pointer of 8 enc hex sequel. And brute force it by xoring with 0x1 to 0xFF and collect meaningful flags. and we will get "Victory!". I also see vICTORY/0x1 too. 0x1 is shown in my windows cmd line as smile emoji. But unpredictable and unprintable in my phone. Not sure if we can take it as valid flags or not. So, I will leave 2 solution here. If we want to use Victory! flags, the xor key is 0xBD. 0xBD is also the end hex of second key. So second key must be any 0xFFFFBD. With the math logic to filter from cmp in assembler, here is lua code to get valid candidates for flags Victory!. local target = 0xBD for key1 = 0, 0xFFFF, 17 do local key2 = (key1 ~ 0x1337) + 42 if key2 & 0xFF == target then print(string.format( "Key1: %d (0x%X) | Key2: %d (0x%X)", key1, key1, key2, key2)) end end If we want to use flags vCTORY/0x1, the xor key would be 0x9D. Any 0xFFFFFF9D for key 2 with math logic from cmp will give us validated license and flag. So just use the above lua script but replace 0xBD with 0x9D. | 2026-07-12 18:37 |
| Level 4 | [Click to reveal] This level is also very similar to the last one, level 3. But now with more strict gateway to make it show meaningful flags. For the username and password part, it is easy since any password would make the job done according to its username. It use simple logic like sum of bytes of username * 0x7b is password. For example, for username Hungary, password is 90282 and it will show Success. Now, we need to find flag. In assembler, I saw a pointer is being used in the loop. If we breakpoint there, we can follow it and see 7 hex in memory. There was also a variable that comes from Xoring between the last 2 hex of serial and 0x34. We can see this one as our xor key. The xor key is used to xor with all the values of pointer one by one in the loop. The result is then shown on output as decrypted flags. So, what we need now is to start from meaningful flags. We will copy the hex values from pointer. Then we will try to brute force it by xoring with the xor key starting from 0x01 to 0xFF. And filter to get only meaningful printable texts. We will then see one among them showing "Solved!" with xored key being 0x67. Probably valid flags. But we have a condition here. We can't use any username and serial to get flags Solved!. So, we need to find only valid username that can show correct flags. The xored key is 0x67. If we revert it as my third paragraph, we should xor 0x67 and 0x34 which will give us 0x53 (The last 2 hex digit of serial). So, The serial must be something like 0xFFFFFF53 but it must be also divisible by 0x7b (123 in decimal). By writing a function, it will give us multiple candidates such as 0xFA53, 0x17553. The smallest one would be 0xFA53 (64083 in dec). 521 in decimal if it is devided by 123. any printable username that has total bytes of 521 will make the job done with serial being 64083. For example, username: zlaaa, serial: 64083 will give us Success with Solved! flags. I like this series very much and it is my first time solving level 4 too. | 2026-07-12 16:44 |
| Level 3 | [Click to reveal]Very Educational program. Not so hard. Not so easy. This is my very first level 3 solving problem. The password is generated according to the input user name. So, every username will work once we find out which solution the program use to generate password and compare to what. We have to really try to understand what is being compared to get Granted response. In the program asm, we see that it get total decimal bytes of the input username and multiply it with 1337 and xor with 0x5a5a. and the result is compared to input password. So, by writing the solution to generate password according to whatever username input, we will pass for every username. Below is my lua version to generate valid password. local User = "liuasfuhflkwe" local function getValidPassword(username) local username_total_bytes = 0 for i=1, #username do local decimal = string.byte(username, i) username_total_bytes = username_total_bytes + decimal end return (username_total_bytes*1337) ~ 0x5a5a end local validPassword = getValidPassword(User) print(validPassword) | 2026-07-11 20:02 |