<![CDATA[Latest posts for the topic "[Thảo luận] Phân tích một crackme trên Linux :)"]]> /hvaonline/posts/list/36.html JForum - http://www.jforum.net [Thảo luận] Phân tích một crackme trên Linux :) http://www.reversing.be/article.php?story=2005030218092760&query=linux Download http://www.reversing.be/easyfile/file.php?download=20050302180927229 Nhìn sơ qua mình thấy có ít nhất 4 cách để reverse nó (patching, serial hịacking, kegen ...) và đặc biệt là phần nhập username/serial bị buffer overflow. Các bạn có thể dùng mọi cách miễn là cho nó hiện ra good boy :) Demo Code:
user / serial : meoluoi / 9118715
Xin mời các bạn!]]>
/hvaonline/posts/list/22743.html#135429 /hvaonline/posts/list/22743.html#135429 GMT
Re: [Thảo luận] Phân tích một crackme trên Linux :) Code:
int __cdecl main()
{
    char szName[72];
    char szInputSerial[64];
    int idx;
    char szRealSerial[64];

    cout << "-> Small crackme for Stingduk <-" << endl;
    cout << ""Give me your name (max 50 chars): ";
    cin >> szName;
    cout << "Pass me the serial (max 50 chars): ";
    cin >> szInputSerial;

    idx = 0;
    while (szName[idx] != 0)
    {
        char ch  = szName[idx];
        szRealSerial[idx++] = ch % 10 + 48;
    }
    szRealSerial[idx] = 0;

    if (0 != strcmp(szRealSerial, szInputSerial))
   {
        cout << "No luck here mate :(" << endl;
    }
    else
    {
        cout << "Great work!" << endl;
    }

    return 0;
}
Crackme này đơn giản, chỉ làm nhiêu đó thôi. Tool: IDA + HexRays. Thời gian đọc, phân tích: 2 phút. Thời gian copy&paste: 30 phút. Cái này mới lâu nè, làm biếng mà.]]>
/hvaonline/posts/list/22743.html#135444 /hvaonline/posts/list/22743.html#135444 GMT
Re: [Thảo luận] Phân tích một crackme trên Linux :) /hvaonline/posts/list/22743.html#135455 /hvaonline/posts/list/22743.html#135455 GMT Re: [Thảo luận] Phân tích một crackme trên Linux :) Prototype: int strcmp (const char *string1, const char *string2); Header File: string.h (C) or cstring (C++) Explanation: Tests the strings for equality. Returns a negative number if string1 is less than string2, returns zero if the two strings are equal, and returns a positive number is string1 is greater than string2   Chúng ta sẽ set một bp tại strcmp để fishing real serial: B1:
$ file small small: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), not stripped 
--> Trông cái executable thấy bình thường, em nghĩ hình nó ko bị pack (ko biết đúng ko?) Bác nào có kinh nghiệm về detect các packer trong linux xin chia sẻ. B2:
$ gdb ./small -q Using host libthread_db library "/lib/libthread_db.so.1". (gdb) disassemble main Dump of assembler code for function main: 0x080487bc <main+0>: push %ebp 0x080487bd <main+1>: mov %esp,%ebp 0x080487bf <main+3>: sub $0xe8,%esp ......................... ......................... 0x080488c4 <main+264>: push %eax ; fake serial 0x080488c5 <main+265>: push %edx ; real serial 0x080488c6 <main+266>: call 0x8048668 <strcmp@plt> ;bp here 0x080488cb <main+271>: add $0x10,%esp 0x080488ce <main+274>: test %eax,%eax 0x080488d0 <main+276>: jne 0x80488fa <main+318> ; Nhảy đến Bad boy nếu sai serial, có thể patch tại đây 0x080488d2 <main+278>: sub $0x8,%esp 0x080488d5 <main+281>: push $0x80486d8 ---Type <return> to continue, or q <return> to quit---return 0x080488da <main+286>: sub $0xc,%esp 0x080488dd <main+289>: push $0x8048b84 ; Great work! 0x080488e2 <main+294>: push $0x8049db8 0x080488e7 <main+299>: call 0x8048698 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt> 0x080488ec <main+304>: add $0x14,%esp 0x080488ef <main+307>: push %eax 0x080488f0 <main+308>: call 0x8048658 <_ZNSolsEPFRSoS_E@plt> 0x080488f5 <main+313>: add $0x10,%esp 0x080488f8 <main+316>: jmp 0x8048920 <main+356> 0x080488fa <main+318>: sub $0x8,%esp 0x080488fd <main+321>: push $0x80486d8 0x08048902 <main+326>: sub $0xc,%esp 0x08048905 <main+329>: push $0x8048b90 ; No luck here mate :( 0x0804890a <main+334>: push $0x8049db8  
B3:
(gdb) break *main+266 Breakpoint 1 at 0x80488c6 (gdb) run Starting program: /usr/local/src/crackme/small -> Small crackme for Stingduk <- Give me your name (max 50 chars): hvaonline.net Pass me the serial (max 50 chars): 123456 Breakpoint 1, 0x080488c6 in main () (gdb) i r eax 0xbfb03a80 -1078969728 ecx 0xbfb03a4c -1078969780 edx 0xbfb03a40 -1078969792 ebx 0xb7ed3ff4 -1209188364 esp 0xbfb03a10 0xbfb03a10 ebp 0xbfb03b08 0xbfb03b08 esi 0xb7fedce0 -1208034080 edi 0x0 0 eip 0x80488c6 0x80488c6 <main+266> eflags 0x200296 [ PF AF SF IF ID ] cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51 (gdb) x/s $eax 0xbfb03a80: "123456" <-- FAke Serial (gdb) x/s $edx 0xbfb03a40: "4871085016016" <-- Real Serial  
...!!! Done Vậy là ta mới câu được
hvaonline.net / 4871085016016 
Xin mời các bác thảo luận tiếp :) ]]>
/hvaonline/posts/list/22743.html#135779 /hvaonline/posts/list/22743.html#135779 GMT
Re: [Thảo luận] Phân tích một crackme trên Linux :)

TQN wrote:
Cho tui khai trương trước, crack thì tui hơi lười, chỉ RE ra source để bà con crack tiếp ;) Code:
int __cdecl main()
{
    char szName[72];
    char szInputSerial[64];
    int idx;
    char szRealSerial[64];

    cout << "-> Small crackme for Stingduk <-" << endl;
    cout << ""Give me your name (max 50 chars): ";
    cin >> szName;
    cout << "Pass me the serial (max 50 chars): ";
    cin >> szInputSerial;

    idx = 0;
    while (szName[idx] != 0)
    {
        char ch  = szName[idx];
        szRealSerial[idx++] = ch % 10 + 48;
    }
    szRealSerial[idx] = 0;

    if (0 != strcmp(szRealSerial, szInputSerial))
   {
        cout << "No luck here mate :(" << endl;
    }
    else
    {
        cout << "Great work!" << endl;
    }

    return 0;
}
Crackme này đơn giản, chỉ làm nhiêu đó thôi. Tool: IDA + HexRays. Thời gian đọc, phân tích: 2 phút. Thời gian copy&paste: 30 phút. Cái này mới lâu nè, làm biếng mà. 
Ok, đây là cách solve thứ 2: Nhìn đoạn code mà anh TQN đã decompiler, chúng ta sẽ tận dụng lỗi buffer overflow do cin đọc vào. 1. Chúng ta tận dụng làm tràn bộ đệm của szName[72], hoặc szInputSerial[64]; Điều cần làm trước tiên là phải tính toán chính xác cần đủ bao nhiêu byte để ghi đè lên con trỏ EIP. Chúng ta hãy hình dung stack như sau
High mem (đáy stack) ....... ....... EIP EBP szName[72]; szInputSerial[64]; idx ...... Low mem (đỉnh stack) 
Nhìn cấu trúc stack trên ta dễ dàng phán đoán, nếu khai thác vào phần input username của bộ đệm szName[72] chúng ta cần 72 + 4 (EBP)+ 4(EIP) =80byte để ghi đè đủ vừa khít lên 4 byte EIP Tương tự cần 64+72+4+4=142 byte ghi đè vừa khít lên 4 byte EiP (thôi coi đá banh, mai post tiếp :D ]]>
/hvaonline/posts/list/22743.html#138996 /hvaonline/posts/list/22743.html#138996 GMT
Re: [Thảo luận] Phân tích một crackme trên Linux :) /hvaonline/posts/list/22743.html#139006 /hvaonline/posts/list/22743.html#139006 GMT Re: [Thảo luận] Phân tích một crackme trên Linux :)

mrro wrote:
Nếu chỉ cần hiện ra "Great work!" thì có cách đơn giản thế này: $ python -c 'print "\x00\x0a\x00\x0a"' | ./small -> Small crackme for Stingduk <- Give me your name (max 50 chars): Pass me the serial (max 50 chars): Great work! 
HOW? -:-) -:-) -:-) ]]>
/hvaonline/posts/list/22743.html#139019 /hvaonline/posts/list/22743.html#139019 GMT
Re: [Thảo luận] Phân tích một crackme trên Linux :)

mrro wrote:
Nếu chỉ cần hiện ra "Great work!" thì có cách đơn giản thế này: $ python -c 'print "\x00\x0a\x00\x0a"' | ./small -> Small crackme for Stingduk <- Give me your name (max 50 chars): Pass me the serial (max 50 chars): Great work! 
Trường hợp của bạn mrro là một tình huống đặc biệt của keygen :-/ và \x0a tương đương với "\r\n" :-/ :-/ Nên dùng python để input cái serial của bạn mèo thì cũng có thể làm thế này ? Code:
python -c 'print "meoluoi\x0a9118715\x0a"' |./small
hoặc đặc biệt hơn nữa Code:
python -c 'print "\x00\x20\x00"' |./small
:-/ Còn mình chỉ biết patch :D Code:
$ gdb --write ./small -q
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) disassemble main
Dump of assembler code for function main:
0x080487bc <main+0>: push %ebp
0x080487bd <main+1>: mov %esp,%ebp
0x080487bf <main+3>: sub $0xe8,%esp
.........................
.........................
0x080488c4 <main+264>: push %eax ; fake serial
0x080488c5 <main+265>: push %edx ; real serial
0x080488c6 <main+266>: call 0x8048668 <strcmp@plt> ;bp here
0x080488cb <main+271>: add $0x10,%esp
0x080488ce <main+274>: test %eax,%eax
0x080488d0 <main+276>: jne 0x80488fa <main+318> ; Nhảy đến Bad boy nếu sai serial, có thể patch tại đây
0x080488d2 <main+278>: sub $0x8,%esp
0x080488d5 <main+281>: push $0x80486d8
---Type <return> to continue, or q <return> to quit---return
0x080488da <main+286>: sub $0xc,%esp
0x080488dd <main+289>: push $0x8048b84 ; Great work!
0x080488e2 <main+294>: push $0x8049db8
0x080488e7 <main+299>: call 0x8048698 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
0x080488ec <main+304>: add $0x14,%esp
0x080488ef <main+307>: push %eax
0x080488f0 <main+308>: call 0x8048658 <_ZNSolsEPFRSoS_E@plt>
0x080488f5 <main+313>: add $0x10,%esp
0x080488f8 <main+316>: jmp 0x8048920 <main+356>
0x080488fa <main+318>: sub $0x8,%esp
0x080488fd <main+321>: push $0x80486d8
0x08048902 <main+326>: sub $0xc,%esp
0x08048905 <main+329>: push $0x8048b90 ; No luck here mate
0x0804890a <main+334>: push $0x8049db8
------
(gdb) x/x *0x080488d0
0xec832875:     Cannot access memory at address 0xec832875
(gdb) set {int} 0x080488d0=0xec832874
(gdb) quit
Code:
$ ./small 
-> Small crackme for Stingduk <-
Give me your name (max 50 chars): hello-world
Pass me the serial (max 50 chars): gudbye-world
Great work!
]]>
/hvaonline/posts/list/22743.html#146396 /hvaonline/posts/list/22743.html#146396 GMT
Re: [Thảo luận] Phân tích một crackme trên Linux :) http://www.tty64.org/doc/revengwithld.txt]]> /hvaonline/posts/list/22743.html#146400 /hvaonline/posts/list/22743.html#146400 GMT