[Question] [Thảo luận] Phân tích một crackme trên Linux :) |
14/06/2008 03:48:27 (+0700) | #1 | 135429 |
mèo lười
Member
|
0 |
|
|
Joined: 13/06/2008 16:36:17
Messages: 7
Offline
|
|
Xin chào anh chị em HVA
Box reverse engineering này mình thấy rất hay, tuy nhiên chưa thấy bài nào bàn về thủ thuật reversing trên linux, nên mạn phép mở chủ đề này ra bàn bạc.
Chúng ta hãy đi phân tích crackme cơ bản này
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! |
|
|
|
|
[Question] Re: [Thảo luận] Phân tích một crackme trên Linux :) |
14/06/2008 05:16:01 (+0700) | #2 | 135444 |
TQN
Elite Member
|
0 |
|
|
Joined: 29/06/2006 22:28:01
Messages: 888
Location: Biết làm chi ?
Offline
|
|
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à. |
|
|
|
|
[Question] Re: [Thảo luận] Phân tích một crackme trên Linux :) |
14/06/2008 06:10:46 (+0700) | #3 | 135455 |
mèo lười
Member
|
0 |
|
|
Joined: 13/06/2008 16:36:17
Messages: 7
Offline
|
|
Chời, em quên giao kèo là chỉ xài các debugger, disassembler trên linux (gdb, objdump ..) . Thanks bác TQN, trông đoạn decompiler trên thì có thể keygen được rồi. Bác nào thử phân tích step by step bằng gdb xem, serial fishing, buffer overflow exploit blah blah được chấp nhận hết. |
|
|
|
|
[Question] Re: [Thảo luận] Phân tích một crackme trên Linux :) |
16/06/2008 23:56:58 (+0700) | #4 | 135779 |
mèo lười
Member
|
0 |
|
|
Joined: 13/06/2008 16:36:17
Messages: 7
Offline
|
|
Cách 1 [serial fishing]
Trông đoạn code decompiler của bác TQN, chúng ta dễ dàng nhận ra tử huyệt của crackme này là function strcmp.
Xem qua prototype của function strcmp:
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
|
|
|
|
|
[Question] Re: [Thảo luận] Phân tích một crackme trên Linux :) |
30/06/2008 14:46:21 (+0700) | #5 | 138996 |
mèo lười
Member
|
0 |
|
|
Joined: 13/06/2008 16:36:17
Messages: 7
Offline
|
|
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
|
|
|
|
|
[Question] Re: [Thảo luận] Phân tích một crackme trên Linux :) |
30/06/2008 17:33:55 (+0700) | #6 | 139006 |
mrro
Administrator
|
Joined: 27/12/2001 05:07:00
Messages: 745
Offline
|
|
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! |
|
http://tinsang.net
TetCon 2013 http://tetcon.org
Làm an toàn thông tin thì học gì?/hvaonline/posts/list/42133.html |
|
|
|
[Question] Re: [Thảo luận] Phân tích một crackme trên Linux :) |
30/06/2008 21:49:20 (+0700) | #7 | 139019 |
lamer
Elite Member
|
0 |
|
|
Joined: 26/02/2008 13:28:49
Messages: 215
Offline
|
|
|
|
[Question] Re: [Thảo luận] Phân tích một crackme trên Linux :) |
12/08/2008 23:18:02 (+0700) | #8 | 146396 |
Cognac
Member
|
0 |
|
|
Joined: 12/08/2008 02:28:47
Messages: 17
Offline
|
|
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
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!
|
|
|
|
|
[Question] Re: [Thảo luận] Phân tích một crackme trên Linux :) |
12/08/2008 23:32:22 (+0700) | #9 | 146400 |
Cognac
Member
|
0 |
|
|
Joined: 12/08/2008 02:28:47
Messages: 17
Offline
|
|
Còn một cách nữa để phishing serial là dùng cách này của bác Izik
Tham khảo
http://www.tty64.org/doc/revengwithld.txt |
|
|
Users currently in here |
1 Anonymous
|
|
Powered by JForum - Extended by HVAOnline
hvaonline.net | hvaforum.net | hvazone.net | hvanews.net | vnhacker.org
1999 - 2013 ©
v2012|0504|218|
|
|