[Writeup] MATESCTF – LicenseChecker (Re500)
Đây là một hệ thống kiểm tra licence rất phức tạp 🙂
Nếu bạn tìm được licence đúng, bạn sẽ có cờ
P/s: Nếu cờ không có dạng matesctf{…}, bạn hãy thêm nó vào cờ
LicenceChecker.zip
Giải SV-ATTT năm trước, mình nhớ cũng có một bài Re dạng VM thế này. Nhưng cái VM đó chỉ chạy trong một hàm, nhận vào một số 32 bit và trả kết quả về True/False, nên…
Mình đọc nhiều writeup có liên quan đến VM, hầu hết đều dùng Pin hoặc dùng một trick nào đó, ngoại trừ có writeup của PiggyBird giải nào chẳng nhớ, Boston Key Party chăng, viết lại cái VM đó, rất văn minh. Mình ước một ngày mình có thể làm được như thế.
Thực nhòng mà nói, với bài này, việc hiểu hết các hàm hay viết lại VM là không cần thiết, cứ debug mãi cũng sẽ ra thôi (chắc ý đồ của BTC cũng là vậy, vì mình cho rằng để một bài như thế này vào một cuộc thi kéo dài 12 tiếng là vô cùng “quá đáng”)
Sau khi dựng được lại cái struct, kiểu kiểu thế này (tên thanh ghi là mình đặt bừa):
[asm]
00000000 vm struc ; (sizeof=0x132, align=0x2) ; XREF: 001BF868r
00000000 ; 0023F778r …
00000000 reg_eax dw ?
00000002 reg_ebx dw ?
00000004 reg_ecx dw ?
00000006 reg_edx dw ?
00000008 reg_esi dw ?
0000000A reg_edi dw ?
0000000C reg_esp dw ?
0000000E reg_ebp dw ?
00000010 flags dd ?
00000014 reg_eip dd ?
00000018 files dd 20 dup(?) ; offset
00000068 unk dd ?
0000006C finish dd ?
00000070 error_code dd ?
00000074 functions dd 43 dup(?) ; offset
00000120 code_ dd ? ; offset
00000124 stack dd ? ; offset
00000128 code dd ? ; offset
0000012C code_size dd ?
00000130 buf_size dw ?
00000132 vm ends
00000132
[/asm]
việc đọc các hàm sẽ đơn giản hơn rất nhiều. Mình code lại một cái bằng python như sau, nó chạy khá đúng (đẹp thì khó), mất mấy tiếng debug và fix code (có lẽ chọn ngôn ngữ khác thì tốt hơn):
Phần 1
Mình sẽ demo một chút phần check key của target. Nó mở một file tên là license.drm:
[asm]
regs : eax: 0x0000 | ebx: 0x0026 | ecx: 0x0000 | edx: 0x003a
esi: 0x0045 | edi: 0x0050 | esp: 0x0100 | ebp: 0x0000
stack: [‘0x3a’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x00ec open(‘license.drm’, ‘rb’)
regs : eax: 0x0000 | ebx: 0x0026 | ecx: 0x0000 | edx: 0x003a
esi: 0x0045 | edi: 0x0050 | esp: 0x0100 | ebp: 0x0000
stack: [‘0x3a’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b1 (zero flag: 0 | error_flag: 1)
0x00ed jns 0x00f0
regs : eax: 0x0000 | ebx: 0x0026 | ecx: 0x0000 | edx: 0x003a
esi: 0x0045 | edi: 0x0050 | esp: 0x0100 | ebp: 0x0000
stack: [‘0x3a’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b1 (zero flag: 0 | error_flag: 1)
0x00f0 mov ecx, 0x002f
regs : eax: 0x0000 | ebx: 0x0026 | ecx: 0x002f | edx: 0x003a
esi: 0x0045 | edi: 0x0050 | esp: 0x0100 | ebp: 0x0000
stack: [‘0x3a’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b1 (zero flag: 0 | error_flag: 1)
0x00f3 add ecx, 0x003f
regs : eax: 0x0000 | ebx: 0x0026 | ecx: 0x006e | edx: 0x003a
esi: 0x0045 | edi: 0x0050 | esp: 0x0100 | ebp: 0x0000
stack: [‘0x3a’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b1 (zero flag: 0 | error_flag: 1)
0x00f6 print ‘n’
regs : eax: 0x0000 | ebx: 0x0026 | ecx: 0x006e | edx: 0x003a
esi: 0x0045 | edi: 0x0050 | esp: 0x0100 | ebp: 0x0000
stack: [‘0x3a’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b1 (zero flag: 0 | error_flag: 1)
0x00f7 mov ecx, 0x0030
regs : eax: 0x0000 | ebx: 0x0026 | ecx: 0x0030 | edx: 0x003a
esi: 0x0045 | edi: 0x0050 | esp: 0x0100 | ebp: 0x0000
stack: [‘0x3a’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b1 (zero flag: 0 | error_flag: 1)
0x00fa add ecx, 0x003f
regs : eax: 0x0000 | ebx: 0x0026 | ecx: 0x006f | edx: 0x003a
esi: 0x0045 | edi: 0x0050 | esp: 0x0100 | ebp: 0x0000
stack: [‘0x3a’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b1 (zero flag: 0 | error_flag: 1)
0x00fd print ‘o’
regs : eax: 0x0000 | ebx: 0x0026 | ecx: 0x006f | edx: 0x003a
esi: 0x0045 | edi: 0x0050 | esp: 0x0100 | ebp: 0x0000
stack: [‘0x3a’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b1 (zero flag: 0 | error_flag: 1)
0x00fe mov ecx, 0x0031
regs : eax: 0x0000 | ebx: 0x0026 | ecx: 0x0031 | edx: 0x003a
esi: 0x0045 | edi: 0x0050 | esp: 0x0100 | ebp: 0x0000
stack: [‘0x3a’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b1 (zero flag: 0 | error_flag: 1)
0x0101 add ecx, 0x003f
regs : eax: 0x0000 | ebx: 0x0026 | ecx: 0x0070 | edx: 0x003a
esi: 0x0045 | edi: 0x0050 | esp: 0x0100 | ebp: 0x0000
stack: [‘0x3a’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b1 (zero flag: 0 | error_flag: 1)
0x0104 print ‘p’
regs : eax: 0x0000 | ebx: 0x0026 | ecx: 0x0070 | edx: 0x003a
esi: 0x0045 | edi: 0x0050 | esp: 0x0100 | ebp: 0x0000
stack: [‘0x3a’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b1 (zero flag: 0 | error_flag: 1)
0x0105 mov ecx, 0x0026
regs : eax: 0x0000 | ebx: 0x0026 | ecx: 0x0026 | edx: 0x003a
esi: 0x0045 | edi: 0x0050 | esp: 0x0100 | ebp: 0x0000
stack: [‘0x3a’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b1 (zero flag: 0 | error_flag: 1)
0x0108 add ecx, 0x003f
regs : eax: 0x0000 | ebx: 0x0026 | ecx: 0x0065 | edx: 0x003a
esi: 0x0045 | edi: 0x0050 | esp: 0x0100 | ebp: 0x0000
stack: [‘0x3a’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b1 (zero flag: 0 | error_flag: 1)
0x010b print ‘e’
regs : eax: 0x0000 | ebx: 0x0026 | ecx: 0x0065 | edx: 0x003a
esi: 0x0045 | edi: 0x0050 | esp: 0x0100 | ebp: 0x0000
stack: [‘0x3a’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b1 (zero flag: 0 | error_flag: 1)
0x010c mov ecx, 0x000a
regs : eax: 0x0000 | ebx: 0x0026 | ecx: 0x000a | edx: 0x003a
esi: 0x0045 | edi: 0x0050 | esp: 0x0100 | ebp: 0x0000
stack: [‘0x3a’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b1 (zero flag: 0 | error_flag: 1)
0x010f print ‘\n’
regs : eax: 0x0000 | ebx: 0x0026 | ecx: 0x000a | edx: 0x003a
esi: 0x0045 | edi: 0x0050 | esp: 0x0100 | ebp: 0x0000
stack: [‘0x3a’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b1 (zero flag: 0 | error_flag: 1)
0x0110 exit
Welcome to VM system!
25%…
nope
[/asm]
Tạo file đó và nhập vào 123456789.
[asm]
regs : eax: 0x0000 | ebx: 0x0026 | ecx: 0x0000 | edx: 0x003a
esi: 0x0045 | edi: 0x0050 | esp: 0x0100 | ebp: 0x0000
stack: [‘0x3a’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x00ec open(‘license.drm’, ‘rb’)
regs : eax: 0x0000 | ebx: 0x0026 | ecx: 0x0000 | edx: 0x003a
esi: 0x0045 | edi: 0x0050 | esp: 0x0100 | ebp: 0x0000
stack: [‘0x3a’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x00ed jns 0x0111
regs : eax: 0x0000 | ebx: 0x0026 | ecx: 0x0000 | edx: 0x003a
esi: 0x0045 | edi: 0x0050 | esp: 0x0100 | ebp: 0x0000
stack: [‘0x3a’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0111 mov ebx, eax
regs : eax: 0x0000 | ebx: 0x0000 | ecx: 0x0000 | edx: 0x003a
esi: 0x0045 | edi: 0x0050 | esp: 0x0100 | ebp: 0x0000
stack: [‘0x3a’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0114 call 0x0127
regs : eax: 0x0000 | ebx: 0x0000 | ecx: 0x0000 | edx: 0x003a
esi: 0x0045 | edi: 0x0050 | esp: 0x00ff | ebp: 0x0000
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0127 pop ebp
regs : eax: 0x0000 | ebx: 0x0000 | ecx: 0x0000 | edx: 0x003a
esi: 0x0045 | edi: 0x0050 | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0129 mov ecx, ebx
regs : eax: 0x0000 | ebx: 0x0000 | ecx: 0x0000 | edx: 0x003a
esi: 0x0045 | edi: 0x0050 | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x012c mov edi, ebp
regs : eax: 0x0000 | ebx: 0x0000 | ecx: 0x0000 | edx: 0x003a
esi: 0x0045 | edi: 0x0116 | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x012f fgetc
regs : eax: 0x0031 | ebx: 0x0000 | ecx: 0x0000 | edx: 0x003a
esi: 0x0045 | edi: 0x0116 | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0130 js 0x0133
regs : eax: 0x0031 | ebx: 0x0000 | ecx: 0x0000 | edx: 0x003a
esi: 0x0045 | edi: 0x0116 | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0133 mov [edi], eax
inc edi
regs : eax: 0x0031 | ebx: 0x0000 | ecx: 0x0000 | edx: 0x003a
esi: 0x0045 | edi: 0x0117 | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0134 fgetc
regs : eax: 0x0032 | ebx: 0x0000 | ecx: 0x0000 | edx: 0x003a
esi: 0x0045 | edi: 0x0117 | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0135 js 0x0138
regs : eax: 0x0032 | ebx: 0x0000 | ecx: 0x0000 | edx: 0x003a
esi: 0x0045 | edi: 0x0117 | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0138 mov [edi], eax
inc edi
regs : eax: 0x0032 | ebx: 0x0000 | ecx: 0x0000 | edx: 0x003a
esi: 0x0045 | edi: 0x0118 | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0139 fgetc
regs : eax: 0x0033 | ebx: 0x0000 | ecx: 0x0000 | edx: 0x003a
esi: 0x0045 | edi: 0x0118 | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x013a js 0x013d
regs : eax: 0x0033 | ebx: 0x0000 | ecx: 0x0000 | edx: 0x003a
esi: 0x0045 | edi: 0x0118 | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x013d mov [edi], eax
inc edi
regs : eax: 0x0033 | ebx: 0x0000 | ecx: 0x0000 | edx: 0x003a
esi: 0x0045 | edi: 0x0119 | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x013e fgetc
regs : eax: 0x0034 | ebx: 0x0000 | ecx: 0x0000 | edx: 0x003a
esi: 0x0045 | edi: 0x0119 | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x013f js 0x0142
regs : eax: 0x0034 | ebx: 0x0000 | ecx: 0x0000 | edx: 0x003a
esi: 0x0045 | edi: 0x0119 | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0142 mov [edi], eax
inc edi
regs : eax: 0x0034 | ebx: 0x0000 | ecx: 0x0000 | edx: 0x003a
esi: 0x0045 | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0143 jmp 0x016b
regs : eax: 0x0034 | ebx: 0x0000 | ecx: 0x0000 | edx: 0x003a
esi: 0x0045 | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x016b mov ecx, 0x0030
regs : eax: 0x0034 | ebx: 0x0000 | ecx: 0x0030 | edx: 0x003a
esi: 0x0045 | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x016e mov esi, ebp
regs : eax: 0x0034 | ebx: 0x0000 | ecx: 0x0030 | edx: 0x003a
esi: 0x0116 | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0171 mov eax, [esi]
inc esi
regs : eax: 0x0031 | ebx: 0x0000 | ecx: 0x0030 | edx: 0x003a
esi: 0x0117 | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0172 sub eax, ecx
regs : eax: 0x0001 | ebx: 0x0000 | ecx: 0x0030 | edx: 0x003a
esi: 0x0117 | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0175 cmp eax, 0x001b
regs : eax: 0x0001 | ebx: 0x0000 | ecx: 0x0030 | edx: 0x003a
esi: 0x0117 | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0178 jnz 0x0146
regs : eax: 0x0001 | ebx: 0x0000 | ecx: 0x0030 | edx: 0x003a
esi: 0x0117 | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0146 mov ecx, 0x002f
regs : eax: 0x0001 | ebx: 0x0000 | ecx: 0x002f | edx: 0x003a
esi: 0x0117 | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0149 add ecx, 0x003f
regs : eax: 0x0001 | ebx: 0x0000 | ecx: 0x006e | edx: 0x003a
esi: 0x0117 | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x014c print ‘n’
[/asm]
Ta thấy hàm fgetc được gọi 4 lần, mỗi lần đọc 1 byte từ file license.drm và lưu vào [edi]. Sau đó là bước kiểm tra từng ký tự:
[asm]
regs : eax: 0x0034 | ebx: 0x0000 | ecx: 0x0030 | edx: 0x003a
esi: 0x0045 | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x016e mov esi, ebp
regs : eax: 0x0034 | ebx: 0x0000 | ecx: 0x0030 | edx: 0x003a
esi: 0x0116 | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0171 mov eax, [esi]
inc esi
regs : eax: 0x0031 | ebx: 0x0000 | ecx: 0x0030 | edx: 0x003a
esi: 0x0117 | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0172 sub eax, ecx
regs : eax: 0x0001 | ebx: 0x0000 | ecx: 0x0030 | edx: 0x003a
esi: 0x0117 | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0175 cmp eax, 0x001b
regs : eax: 0x0001 | ebx: 0x0000 | ecx: 0x0030 | edx: 0x003a
esi: 0x0117 | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0178 jnz 0x0146
[/asm]
mã giả
[python]
key[0] – 0x30 == 0x1B
[/python]
Điền lại key[0] = 0x1B + 0x30 = 0x4B, ta đến bước check ký tự thứ 2:
[asm]
regs : eax: 0x001b | ebx: 0x0000 | ecx: 0x0030 | edx: 0x003a
esi: 0x0117 | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0175 cmp eax, 0x001b
regs : eax: 0x001b | ebx: 0x0000 | ecx: 0x0030 | edx: 0x003a
esi: 0x0117 | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b1000 (zero flag: 1 | error_flag: 0)
0x0178 jnz 0x017b
regs : eax: 0x001b | ebx: 0x0000 | ecx: 0x0030 | edx: 0x003a
esi: 0x0117 | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b1000 (zero flag: 1 | error_flag: 0)
0x017b add ecx, ecx
regs : eax: 0x001b | ebx: 0x0000 | ecx: 0x0060 | edx: 0x003a
esi: 0x0117 | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b1000 (zero flag: 1 | error_flag: 0)
0x017e mov eax, [esi]
inc esi
regs : eax: 0x0032 | ebx: 0x0000 | ecx: 0x0060 | edx: 0x003a
esi: 0x0118 | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b1000 (zero flag: 1 | error_flag: 0)
0x017f sub eax, ecx
regs : eax: 0xffd2 | ebx: 0x0000 | ecx: 0x0060 | edx: 0x003a
esi: 0x0118 | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b1000 (zero flag: 1 | error_flag: 0)
0x0182 cmp eax, 0x002b
regs : eax: 0xffd2 | ebx: 0x0000 | ecx: 0x0060 | edx: 0x003a
esi: 0x0118 | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0185 jnz 0x0146
[/asm]
mã giả:
[python]
key[1] == 0x60 + 0x2B
[/python]
key[1] = 0x60 + 0x2B = 0x8B
Tương tự như vậy, ta có 4 ký tự đầu tiên là 4B 8B 04 ED.
Phần 2
[asm]
regs : eax: 0x0038 | ebx: 0x0000 | ecx: 0x0000 | edx: 0x003a
esi: 0x011a | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b1000 (zero flag: 1 | error_flag: 0)
0x0203 mov ecx, [edi]
regs : eax: 0x0038 | ebx: 0x0000 | ecx: 0x3635 | edx: 0x003a
esi: 0x011a | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b1000 (zero flag: 1 | error_flag: 0)
0x0206 ror ecx, 0x0008
regs : eax: 0x0038 | ebx: 0x0000 | ecx: 0x3536 | edx: 0x003a
esi: 0x011a | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b1000 (zero flag: 1 | error_flag: 0)
0x0209 call process_first_block
div ecx, 0xb
regs : eax: 0x04d6 | ebx: 0x0000 | ecx: 0x3536 | edx: 0x0004
esi: 0x011a | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x020b mov ecx, 0x0013
regs : eax: 0x04d6 | ebx: 0x0000 | ecx: 0x0013 | edx: 0x0004
esi: 0x011a | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x020e shl ecx, 0x0004
regs : eax: 0x04d6 | ebx: 0x0000 | ecx: 0x0130 | edx: 0x0004
esi: 0x011a | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0211 or ecx, 0x0008
regs : eax: 0x04d6 | ebx: 0x0000 | ecx: 0x0138 | edx: 0x0004
esi: 0x011a | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0214 shl ecx, 0x0004
regs : eax: 0x04d6 | ebx: 0x0000 | ecx: 0x1380 | edx: 0x0004
esi: 0x011a | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x0217 or ecx, 0x0005
regs : eax: 0x04d6 | ebx: 0x0000 | ecx: 0x1385 | edx: 0x0004
esi: 0x011a | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x021a cmp ecx, eax
regs : eax: 0x04d6 | ebx: 0x0000 | ecx: 0x1385 | edx: 0x0004
esi: 0x011a | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x021d jnz 0x01db
[/asm]
mã giả:
[python]
w1, w2 = key
w1 = ror(w1, 8)
ecx = (((0x13 << 4) | 8) << 4) | 5 = 0x1385
w1 / 11 == ecx
[/python]
Ta có thương của phép chia = 0x1385 => w1 = 0x1385 * 11 = 0xD6B7 => sửa 2 byte đầu của block 2 thành D6 B7.
[asm]
regs : eax: 0x1385 | ebx: 0x0000 | ecx: 0x1385 | edx: 0x0000
esi: 0x011a | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b0 (zero flag: 0 | error_flag: 0)
0x021a cmp ecx, eax
regs : eax: 0x1385 | ebx: 0x0000 | ecx: 0x1385 | edx: 0x0000
esi: 0x011a | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b1000 (zero flag: 1 | error_flag: 0)
0x021d jnz 0x0220
regs : eax: 0x1385 | ebx: 0x0000 | ecx: 0x1385 | edx: 0x0000
esi: 0x011a | edi: 0x011a | esp: 0x0100 | ebp: 0x0116
stack: [‘0x116’, ‘0x0’, ‘0x0’, ‘0x0’, ‘0x0’]
flag : 0b1000 (zero flag: 1 | error_flag: 0)
0x0220 cmp edx, 0x0006
[/asm]
Ta có thêm phần dư của phép chia = 6 => w1 = 0x1385 * 11 + 6 = 0xD6BD.
Tương tự vậy, 4 byte của block thứ 2 là D6 BD 06 5D.
Sau 4 block chính xác, chúng ta có flag:
[bash]
Welcome to VM system!
25%…
50%…
75%…
The flag is: ‘VM_c0de_1s_crazy’
[/bash]
Quả thật quá hư cấu.
Cho mình hỏi “VM” bạn nhắc đến ở đây là gì v ạ
Virtual Machine đó bạn 😀
Bài CTF có VM tui thấy bài này cực kỳ ấn tượng luôn http://www.vnsecurity.net/ctf%20-%20clgt%20crew/2010/03/19/codegate-2010-challenge2-xbox-pwned.html
Awesome xD
anh Sẻ có thể nói nôm nả cho em hiểu xíu về dạng VM(Virtual Machine) trong RE được không anh ? em chưa thể mường tượng nó là cái gì, hay dùng cho mục đích gì.
CTF thì anh thấy nó nhiều khi đánh đố nhau để cùng lên trình thôi chứ anh cũng không nắm được mục đích sâu xa là gì. Nhưng làm cho một phần mềm khó bị RE hơn thì cũng tốt, nếu em là người làm ra phần mềm đó và không muốn nó thành open source xD
vậy VM ở đây là tên của 1 packer hả anh? hay sao ạ.
VM thì như dịch nghĩa nó là máy ảo ấy em, mình hiểu nó hoạt động thế nào là được chứ khái niệm thì kệ nó đi. Mà thôi blog này bàn về kỹ thuật làm gì 🙁
vâng sorry anh