如何Crack Command Line Program

本次破解练习的对象下载地址如下:https://github.com/GeoSn0w/Reverse-Engineering-Tutorials。选择了其中的Level 3, cat 这个例子。cat这个程序是个命令行程序,运行时输入正确的Serial即可通过验证。截图如下:

Snip20171025_1.png

这个例子比较简单,主要目的是演示如何用Hopper调试命令行程序。程序自带说明Readme如下。

  • The level 3 consists into a binary that requires a serial number to work. Once a serial number (the correct one) is fed to the app, a function executes that prints out data about the Kernel (uname).
    Your challenge is to bypass the signature check so that any serial would do.

0x1 代码分析

Hopper中可以看到代码如下。只有一个_main方法。

                     _main:
0000000100000a50         push       rbp
0000000100000a51         mov        rbp, rsp
0000000100000a54         sub        rsp, 0x580
0000000100000a5b         lea        rax, qword [0x100000d3c]                    ; "Welcome to the iOS Reverse Engineering Level 3! \\n"
0000000100000a62         mov        rcx, qword [___stack_chk_guard_100001000]
0000000100000a69         mov        rcx, qword [rcx]
0000000100000a6c         mov        qword [rbp+var_8], rcx
0000000100000a70         mov        dword [rbp+var_50C], 0x0
0000000100000a7a         mov        dword [rbp+var_510], edi
0000000100000a80         mov        qword [rbp+var_518], rsi
0000000100000a87         mov        rdi, rax                                    ; argument "format" for method imp___stubs__printf
0000000100000a8a         mov        al, 0x0
0000000100000a8c         call       imp___stubs__printf
0000000100000a91         lea        rdi, qword [0x100000d6e]                    ; "Created by GeoSn0w (@FCE365)\\n\\n", argument "format" for method imp___stubs__printf
0000000100000a98         mov        dword [rbp+var_524], eax
0000000100000a9e         mov        al, 0x0
0000000100000aa0         call       imp___stubs__printf
0000000100000aa5         lea        rdi, qword [0x100000d8d]                    ; "The challenge is to hack this application so that you can use it without any serial number and obtain the flag! \\n\\n", argument "format" for method imp___stubs__printf
0000000100000aac         mov        dword [rbp+var_528], eax
0000000100000ab2         mov        al, 0x0
0000000100000ab4         call       imp___stubs__printf
0000000100000ab9         lea        rdi, qword [0x100000e00]                    ; "**************** START **************** \\n\\n", argument "format" for method imp___stubs__printf
0000000100000ac0         mov        dword [rbp+var_52C], eax
0000000100000ac6         mov        al, 0x0
0000000100000ac8         call       imp___stubs__printf
0000000100000acd         cmp        dword [rbp+var_510], 0x2
0000000100000ad4         mov        dword [rbp+var_530], eax
0000000100000ada         jne        loc_100000c83

0000000100000ae0         lea        rdi, qword [0x100000e2b]                    ; "Preparing to check access key: %s\\n", argument "format" for method imp___stubs__printf
0000000100000ae7         mov        rax, qword [rbp+var_518]
0000000100000aee         mov        rsi, qword [rax+8]
0000000100000af2         mov        al, 0x0
0000000100000af4         call       imp___stubs__printf
0000000100000af9         mov        dword [rbp+var_51C], 0x0
0000000100000b03         mov        dword [rbp+var_520], 0x0
0000000100000b0d         mov        dword [rbp+var_534], eax

                     loc_100000b13:
0000000100000b13         movsxd     rax, dword [rbp+var_520]                    ; CODE XREF=_main+290
0000000100000b1a         mov        rcx, qword [rbp+var_518]
0000000100000b21         mov        rdi, qword [rcx+8]                          ; argument "s" for method imp___stubs__strlen
0000000100000b25         mov        qword [rbp+var_540], rax
0000000100000b2c         call       imp___stubs__strlen
0000000100000b31         mov        rcx, qword [rbp+var_540]
0000000100000b38         cmp        rcx, rax
0000000100000b3b         jae        loc_100000b77

0000000100000b41         movsxd     rax, dword [rbp+var_520]
0000000100000b48         mov        rcx, qword [rbp+var_518]
0000000100000b4f         mov        rcx, qword [rcx+8]
0000000100000b53         movsx      edx, byte [rcx+rax]
0000000100000b57         add        edx, dword [rbp+var_51C]
0000000100000b5d         mov        dword [rbp+var_51C], edx
0000000100000b63         mov        eax, dword [rbp+var_520]
0000000100000b69         add        eax, 0x1
0000000100000b6c         mov        dword [rbp+var_520], eax
0000000100000b72         jmp        loc_100000b13

                     loc_100000b77:
0000000100000b77         cmp        dword [rbp+var_51C], 0x4f4                  ; CODE XREF=_main+235
0000000100000b81         jne        loc_100000c56

0000000100000b87         lea        rdi, qword [0x100000e4e]                    ; "Welcome! F.C.E. 365 Tool v36.1\\n", argument "format" for method imp___stubs__printf
0000000100000b8e         mov        al, 0x0
0000000100000b90         call       imp___stubs__printf
0000000100000b95         lea        rdi, qword [0x100000e6e]                    ; "\\n", argument "format" for method imp___stubs__printf
0000000100000b9c         mov        dword [rbp+var_544], eax
0000000100000ba2         mov        al, 0x0
0000000100000ba4         call       imp___stubs__printf
0000000100000ba9         lea        rdi, qword [0x100000e70]                    ; "Blimey! You're not a good man! You've hacked the app!\\n \\n", argument "format" for method imp___stubs__printf
0000000100000bb0         mov        dword [rbp+var_548], eax
0000000100000bb6         mov        al, 0x0
0000000100000bb8         call       imp___stubs__printf
0000000100000bbd         lea        rdi, qword [0x100000ea9]                    ; "Flag: 0x038948FFFF83--DS \\n", argument "format" for method imp___stubs__printf
0000000100000bc4         mov        dword [rbp+var_54C], eax
0000000100000bca         mov        al, 0x0
0000000100000bcc         call       imp___stubs__printf
0000000100000bd1         lea        rdi, qword [0x100000ec4]                    ; "System Identity:\\n", argument "format" for method imp___stubs__printf
0000000100000bd8         mov        dword [rbp+var_550], eax
0000000100000bde         mov        al, 0x0
0000000100000be0         call       imp___stubs__printf
0000000100000be5         lea        rdi, qword [rbp+var_508]                    ; argument "name" for method imp___stubs__uname
0000000100000bec         mov        dword [rbp+var_554], eax
0000000100000bf2         call       imp___stubs__uname
0000000100000bf7         lea        rdi, qword [0x100000ed6]                    ; "%s Release %s (Version %s) on %s\\n", argument "format" for method imp___stubs__printf
0000000100000bfe         lea        rcx, qword [rbp+var_508]
0000000100000c05         mov        rdx, rcx
0000000100000c08         add        rdx, 0x200
0000000100000c0f         mov        rsi, rcx
0000000100000c12         add        rsi, 0x300
0000000100000c19         mov        r8, rcx
0000000100000c1c         add        r8, 0x400
0000000100000c23         mov        qword [rbp+var_560], rsi
0000000100000c2a         mov        rsi, rcx
0000000100000c2d         mov        rcx, qword [rbp+var_560]
0000000100000c34         mov        dword [rbp+var_564], eax
0000000100000c3a         mov        al, 0x0
0000000100000c3c         call       imp___stubs__printf
0000000100000c41         mov        dword [rbp+var_50C], 0x0
0000000100000c4b         mov        dword [rbp+var_568], eax
0000000100000c51         jmp        loc_100000cb5

                     loc_100000c56:
0000000100000c56         lea        rdi, qword [0x100000ef8]                    ; "The serial number is not correct!\\n", argument "format" for method imp___stubs__printf, CODE XREF=_main+305
0000000100000c5d         mov        al, 0x0
0000000100000c5f         call       imp___stubs__printf
0000000100000c64         lea        rdi, qword [0x100000f1b]                    ; "The application is locked!\\n", argument "format" for method imp___stubs__printf
0000000100000c6b         mov        dword [rbp+var_56C], eax
0000000100000c71         mov        al, 0x0
0000000100000c73         call       imp___stubs__printf
0000000100000c78         mov        dword [rbp+var_570], eax
0000000100000c7e         jmp        loc_100000cab

                     loc_100000c83:
0000000100000c83         lea        rdi, qword [0x100000f37]                    ; "This application requires a serial number to work! You can validate it with \\n", argument "format" for method imp___stubs__printf, CODE XREF=_main+138
0000000100000c8a         mov        al, 0x0
0000000100000c8c         call       imp___stubs__printf
0000000100000c91         lea        rdi, qword [0x100000f8a]                    ; "Or you can do what hackers do the best...\\n", argument "format" for method imp___stubs__printf
0000000100000c98         mov        dword [rbp+var_574], eax
0000000100000c9e         mov        al, 0x0
0000000100000ca0         call       imp___stubs__printf
0000000100000ca5         mov        dword [rbp+var_578], eax

                     loc_100000cab:
0000000100000cab         mov        dword [rbp+var_50C], 0x0                    ; CODE XREF=_main+558

                     loc_100000cb5:
0000000100000cb5         mov        rax, qword [___stack_chk_guard_100001000]   ; CODE XREF=_main+513
0000000100000cbc         mov        ecx, dword [rbp+var_50C]
0000000100000cc2         mov        rax, qword [rax]
0000000100000cc5         cmp        rax, qword [rbp+var_8]
0000000100000cc9         mov        dword [rbp+var_57C], ecx
0000000100000ccf         jne        loc_100000ce4

0000000100000cd5         mov        eax, dword [rbp+var_57C]
0000000100000cdb         add        rsp, 0x580
0000000100000ce2         pop        rbp
0000000100000ce3         ret
                        ; endp

                     loc_100000ce4:
0000000100000ce4         call       imp___stubs____stack_chk_fail               ; CODE XREF=_main+639
                        ; endp

静态分析代码,知 loc_100000b77为关键跳转。

       loc_100000b77:
0000000100000b77         cmp        dword [rbp+var_51C], 0x4f4                  ; CODE XREF=_main+235
0000000100000b81         jne        loc_100000c56

此处条件跳转,比较[rbp+var_51C]与0x4f4的大小,相等则通过。0x4f4为多少呢?转为十进制为1268。如下图。

Snip20171025_7.png

0x2动态分析

[rbp+var_51C] 的值是如何计算得来的呢?Hopper提供了动态调试功能,也能单步骤调试运行命令行程序。
见下图。Arguments 输入参数,Application Output窗口打印程序的输出。

Snip20171025_3.png

切换窗口到GPR,也可以看到各个寄存器值。

Snip20171025_2.png

通过运行,得知,程序遍历输入的参数,进行累加,最后的结果与1268相比较,相等则通过验证。

0x3验证

根据分析,可以算出Serial。例如:1268 = 120*10+68 ; ASCII码120对应的字符为x,ASCII码68对应的字符为D,所以Serial可以为:xxxxxxxxxxD。代入程序验证,成功。:)!

Snip20171025_8.png

打开练习对应的源码,分析也是对的。如下。

//GeoSn0w's Reverse Engineering Tutorial
//Use the code as you want, WTFPL
#include 
#include 
#include 

int main(int argc, char *argv[]) {
printf("Welcome to the iOS Reverse Engineering Level 3! \n");
printf("Created by GeoSn0w (@FCE365)\n\n");
printf("The challenge is to hack this application so that you can use it without any serial number and obtain the flag! \n\n");
printf("**************** START **************** \n\n");
if(argc==2) {
  printf("Preparing to check access key: %s\n", argv[1]);
  int hex = 0;
  for(int access=0; access\n");
   printf("Or you can do what hackers do the best...\n");
}
return 0;
}

你可能感兴趣的:(如何Crack Command Line Program)