re study (36) watch snow CTF 2017 -Crackme

Baidu Netdisk has been collected. If you need to review it, you can view it in the folder [CTF question bank collection]

Just run it first

This is a crackme type question, a competition question on the Snow CTF. Use OD to analyze it.

I first used IDA analysis. After analyzing it for a long time, I couldn’t find anything. Then I searched online and found it. I directly raised the flag and solved my urgent problem. Haha, I looked at wp afterwards and found out. In order to find the real solution, we should still summarize it. After all, some questions cannot be found...

Question: Why use OD instead of IDA?

OD can dynamically track the variable change process. OD disassembly code can be colored to make it more eye-catching. Crackme type questions

                              →The first choice for dynamic tune

IDA can see the data structure and even disassemble it into C code, which is helpful to grasp the overall structure.

                              →The first choice for quiet tone

Run the program in OD and find that the message box appears after running the function at address 00401494. It can be seen that this is the key function. F2 sets the breakpoint and F7 follows up.

In the process of following this function, Windows GUI - message loop and messages will occur. You can refer to this article.

Windows GUI -- Message Loop and Message_gui Message Loop_My Blog with a Fish Pond at Home-CSDN Blog

It seems that you have to type something to get out of the loop, then set a breakpoint, run F9 and enter characters to get out of the loop.

Where to place a breakpoint? If you set a breakpoint here, as shown below,

After running, an error will be reported directly because the assembly instruction retn is used to end the current process and return to the previous calling process.

So you have to set a breakpoint at the earliest instruction next to this assembly instruction.

After successfully running at the breakpoint, the next step is the key code of disassembly:
 

CPU Disasm
地址        十六进制数据            指令                             注释                                                             标签
00401225   .  83F8 04       CMP EAX,4
00401228   .  59            POP ECX
00401229   .  0F85 A0000000 JNE 004012CF                   strlen()函数
0040122F   .  6A 30         PUSH 30
00401231   .  59            POP ECX
00401232   .  384D E4       CMP BYTE PTR SS:[EBP-1C],CL    判断key第1个字符是否为“0”
00401235   .  0F84 94000000 JE 004012CF
0040123B   .  384D E5       CMP BYTE PTR SS:[EBP-1B],CL    判断key第2个字符是否为“0”
0040123E   .  0F84 8B000000 JE 004012CF
00401244   .  384D E6       CMP BYTE PTR SS:[EBP-1A],CL    判断key第3个字符是否为“0”
00401247   .  0F84 82000000 JE 004012CF
0040124D   .  384D E7       CMP BYTE PTR SS:[EBP-19],CL    判断key第4个字符是否为“0”
00401250   .  74 7D         JE SHORT 004012CF
00401252   .  807D E4 31    CMP BYTE PTR SS:[EBP-1C],31    判断key第1个字符是否等于“1”,不等于则直接跳转弹出“error”
00401256   .  75 77         JNE SHORT 004012CF
00401258   .  807D E5 35    CMP BYTE PTR SS:[EBP-1B],35    判断key第2个字符是否等于“5”,不等于则直接跳转弹出“error”
0040125C   .  75 71         JNE SHORT 004012CF
0040125E   .  74 03         JE SHORT 00401263              花指令
00401260   .  75 01         JNE SHORT 00401263
00401262      E8            DB E8                          CHAR 'è'
00401263   >  66:B8 0800    MOV AX,8
00401267   .  66:35 0700    XOR AX,0007
0040126B   .  0FBE45 E6     MOVSX EAX,BYTE PTR SS:[EBP-1A] 取输入key的第3位数
0040126F   .  2BC1          SUB EAX,ECX                    减去0x30,得到a
00401271   .  8945 FC       MOV DWORD PTR SS:[EBP-4],EAX   把得到的值保存在[ebp-0x4]中
00401274   .  0FBE45 E4     MOVSX EAX,BYTE PTR SS:[EBP-1C] 取输入key的第1位值“1”
00401278   .  DB45 FC       FILD DWORD PTR SS:[EBP-4]      把[ebp-0x4]中保存的值压入到ST(0)中
0040127B   .  2BC1          SUB EAX,ECX                    0x31减去0x30,则为1
0040127D   .  8945 FC       MOV DWORD PTR SS:[EBP-4],EAX   把得到的值1保存在[ebp-0x4]中
00401280   .  0FBE45 E5     MOVSX EAX,BYTE PTR SS:[EBP-1B] 取输入key的第2位值“5”
00401284   .  DB45 FC       FILD DWORD PTR SS:[EBP-4]      把[ebp-0x4]中保存的值1压入到ST(0)中
00401287   .  2BC1          SUB EAX,ECX                    0x35减去0x30,则为5
00401289   .  8945 FC       MOV DWORD PTR SS:[EBP-4],EAX   把得到的值5保存在[ebp-0x4]中
0040128C   .  DA75 FC       FIDIV DWORD PTR SS:[EBP-4]     st(0)中的值1除以[ebp-0x4]中的值5,得到0.2保存到st(0)中
0040128F   .  0FBE45 E7     MOVSX EAX,BYTE PTR SS:[EBP-19] 取输入key的第4位值
00401293   .  2BC1          SUB EAX,ECX                    减去0x30,得到b
00401295   .  8945 FC       MOV DWORD PTR SS:[EBP-4],EAX   把得到的值b保存在[ebp-0x4]中
00401298   .  DEE9          FSUBP ST(1),ST                 st(1)-st并保存在st(0)中,即(a-0.2)
0040129A   .  DA4D FC       FIMUL DWORD PTR SS:[EBP-4]     st(0)乘以[ebp-0x4] 中保存的值b,结果保存在st(0)中
0040129D   .  D80D 1C714000 FMUL DWORD PTR DS:[40711C]     数据段ds:[0x40711C]值为16,这里则是st(0)乘以16
004012A3   .  D95D FC       FSTP DWORD PTR SS:[EBP-4]      把上面得到值保存在[ebp-0x4]中
004012A6   .  74 03         JE SHORT 004012AB
004012A8   .  75 01         JNE SHORT 004012AB
004012AA      E8            DB E8                          CHAR 'è'
004012AB  />  66:B8 0800    MOV AX,8
004012AF  |.  66:35 0700    XOR AX,0007
004012B3  |.  D945 FC       FLD DWORD PTR SS:[EBP-4]       取出[ebp-0x4]中保存的值
004012B6  |.  D81D 18714000 FCOMP DWORD PTR DS:[407118]    得出的值与384比较是否相等
004012BC  |.  6A 00         PUSH 0
004012BE  |.  68 78804000   PUSH OFFSET 00408078           ASCII "CrackMe 2017 CTF"
004012C3  |.  DFE0          FSTSW AX
004012C5  |.  9E            SAHF
004012C6  |.  75 0E         JNE SHORT 004012D6
004012C8  |.  68 5C804000   PUSH OFFSET 0040805C           ASCII "Registration successful !"
004012CD  \.  EB 0C         JMP SHORT 004012DB
004012CF  />  6A 00         PUSH 0
004012D1  |.  68 48804000   PUSH OFFSET 00408048           ASCII "CrackMe 2017 CTF v2"
004012D6  |>  68 40804000   PUSH OFFSET 00408040           ASCII "error !"

 0x01 determines the length of the input value

You can see the part of the value we passed in after input, and use strlen to get whether its length is 4. If it is not 4, it will jump directly to 004012CF.

Now it can be determined that the length of key is 4

0x02 Verify the value of the first 2 digits of the key

Here we verify whether the key values ​​are all string "0". If another 4-digit key is "0", jump directly to the "error" pop-up box.

Then continue to verify the value of the first 2 digits of the key string, that is, the first 2 digits of the given string are "15".
If the value of the first 2 digits of the key is not "15", jump directly to the "error" pop-up frame

Here we get the value of the first 2 keys as "15"

0x03 Analysis Algorithm

Here's how it works:

1. Take the hexadecimal value of the third digit in the key, and then subtract 0x30. Here, the value is assumed to be a

2. Take the hexadecimal value of the first bit in the key as "1", which is 0x31, and then subtract 0x30, 0x31-0x30 =1

3. Take the hexadecimal value of "5" in the second digit of the key, which is 0x35, then subtract 0x30, 0x31-0x30 =5, and then divide 1 by 5 to get the floating point number 0.2

4. Take the hexadecimal value of the 4th digit in the key, and then subtract 0x30. Here, the value is assumed to be b

5. Then the result of multiplying (a-0.2)*b by 16 is c

6. Determine whether c and 384 are equal. If they are equal, Registration successful!, if they are not the same, then "error"
formula: (a-0.2)*b*16 = 384 Solve a and b
0x04 Write an algorithm script

Based on the above analysis, I wrote a simple script and ran out two results: "151N" and "1555"

for i in range(126):
    for j in range(126):
        if(((i-48)-0.2)*(j-48) == 24):
            print(i)
            print(j)
            print("15"+"%s"%(chr(i))+"%s"%(chr(j)))
            print("------")

Guess you like

Origin blog.csdn.net/m0_66039322/article/details/132619302