Decrypting DUP2 Patcher
Disclaimer
----------
Tutorial ini hanya untuk tujuan pembelajaran. Penulis tidak bertanggungjawab
atas penggunaan maupun penyalahgunaan dari tutorial ini. Use at your own risk!
Pendahuluan
-----------
Dup2 Universal Patcher adalah aplikasi yang dapat digunakan untuk membuat patch
pada sistem operasi Microsoft Windows. Aplikasi tersebut bersifat freeware dan
dibuat oleh diablo2oo2. Pada tutorial kali ini, akan dibahas sedikit mengenai
cara untuk melakukan dekripsi secara manual dll yang terdapat pada rilis yang
menggunakan dup2 universal patcher.
Cara pertama
------------
Cara pertama, cukup mudah, cukup jalankan patcher/crack yang dibuat menggunakan
dup2 dan lihat direktori temporary (%temp%) menggunakan windows explorer. Pada
direktori tersebut nantinya akan ada file "dup2patcher.dll"
Cara ke-dua
-----------
Cara ke-dua ini adalah cara yang ditempuh jika Anda ingin mengetahui proses
ekstraksi library "dup2patcher.dll" tersebut dari resource. Sebagai catatan,
cara ke-2 ini dilakukan dengan static analysis pada sistem operasi GNU/Linux.
Berikut ini adalah langkah-langkahnya:
* Siapkan aplikasi target yang dibuat menggunakan dup2.
* Dengan melakukan disassembly, bisa terlihat bahwa aplikasi tersebut akan
mengekstrak resource berupa "dll" dengan memperhatikan pada alamat 0040107D
terdapat pemanggilan API "LoadResource", dan berikut ini adalah listing
disassemblynya:
* Setelah melakukan alokasi memori dan resource dll disalin ke memori tersebut,
selanjutnya aplikasi akan melakukan dekripsi dengan memanggil fungsi yang me-
miliki 3 parameter yaitu: alamat memori yang berisi resource dll, ukuran memori
dan key untuk dekripsi, seperti yang bisa dilihat pada snippet di atas, di bagian
ini:
* Dari snippet di atas, bisa terlihat bahwa key yang digunakan adalah 0xDEADBEEF.
Selanjutnya adalah melihat fungsi yang dipanggil, yang bertanggungjawab untuk
proses dekripsi. Berikut ini adalah fungsi tersebut:
* Bisa terlihat bahwa fungsinya menggunakan algoritma yang cukup sederhana,
yang jika dibuat dalam bahasa sederhana kurang lebih seperti ini:
1. Register EBX pada awalnya berisi key 0xDEADBEEF.
2. Register ECX berisi ukuran data yang terenkripsi (DLL).
3. Ambil 1 byte dari data yang terenkripsi.
4. Simpan/copy byte tersebut di register DL.
5. Lakukan operasi XOR pada byte tersebut dengan byte key yang ada di register EBX.
6. Simpan hasilnya pada lokasi memori data yang terenkripsi sesuai urutannya.
7. Lakukan operasi ROR pada key yang ada pada EBX sebanyak 1x.
8. Lakukan operasi XOR pada byte key dengan byte yang berada pada register DL (byte yang belum didekripsi).
9. Tambahkan key dengan counter yang berada pada register ECX.
10. Kurangi counter, dan jika data yang akan didekripsi masih ada, maka ulangi dari langkah ke-3.
* Urutan algoritma di atas jika dibuat dalam bentuk kode, kurang lebih seperti ini:
* Selanjutnya, untuk melakukan dekripsi tanpa menjalankan aplikasinya, kita
terlebih dahulu harus mengekstrak resource yang ada pada aplikasi tersebut.
Cara yang dapat ditempuh adalah, dengan menggunakan 7zip
* Akan terlihat bahwa terdapat peringatan mengenai CRC, namun hal tersebut dapat
diabaikan. Selanjutnya adalah melihat file resource yang akan didekripsi. Perlu
diingat bahwa direktori ".rsrc" bersifat "hidden" jika menggunakan sistem operasi
GNU/Linux dan file tersebut tidak dikenali formatnya:
* Selanjutnya, karena kita telah mengetahui algoritma untuk dekripsinya, kita dapat
membuat aplikasi sederhana untuk melakukan dekripsi. Berikut ini adalah contoh
PoC untuk melakukan dekripsi terhadap resource yang telah diekstrak:
* Periksa apakah resource dll tersebut berhasil didekripsi:
* Bisa terlihat bahwa proses dekripsi berhasil. Selanjutnya, kita dapat melakukan
proses analisis terhadap file yang telah didekripsi.
* Sekian tutorial singkat kali ini, semoga bermanfaat.
Gambar Ilustrasi decrypt
Credits: RNDC - Eric Draven aka Drubizca
Disclaimer
----------
Tutorial ini hanya untuk tujuan pembelajaran. Penulis tidak bertanggungjawab
atas penggunaan maupun penyalahgunaan dari tutorial ini. Use at your own risk!
Pendahuluan
-----------
Dup2 Universal Patcher adalah aplikasi yang dapat digunakan untuk membuat patch
pada sistem operasi Microsoft Windows. Aplikasi tersebut bersifat freeware dan
dibuat oleh diablo2oo2. Pada tutorial kali ini, akan dibahas sedikit mengenai
cara untuk melakukan dekripsi secara manual dll yang terdapat pada rilis yang
menggunakan dup2 universal patcher.
Cara pertama
------------
Cara pertama, cukup mudah, cukup jalankan patcher/crack yang dibuat menggunakan
dup2 dan lihat direktori temporary (%temp%) menggunakan windows explorer. Pada
direktori tersebut nantinya akan ada file "dup2patcher.dll"
Cara ke-dua
-----------
Cara ke-dua ini adalah cara yang ditempuh jika Anda ingin mengetahui proses
ekstraksi library "dup2patcher.dll" tersebut dari resource. Sebagai catatan,
cara ke-2 ini dilakukan dengan static analysis pada sistem operasi GNU/Linux.
Berikut ini adalah langkah-langkahnya:
* Siapkan aplikasi target yang dibuat menggunakan dup2.
* Dengan melakukan disassembly, bisa terlihat bahwa aplikasi tersebut akan
mengekstrak resource berupa "dll" dengan memperhatikan pada alamat 0040107D
terdapat pemanggilan API "LoadResource", dan berikut ini adalah listing
disassemblynya:
Code:
.text:00401037 ; =============== S U B R O U T I N E =======================================
.text:00401037
.text:00401037 ; Attributes: bp-based frame
.text:00401037
.text:00401037 sub_401037 proc near ; CODE XREF: start^p
.text:00401037
.text:00401037 LibFileName = byte ptr -40Ch
.text:00401037 nNumberOfBytesToWrite= dword ptr -0Ch
.text:00401037 lpBuffer = dword ptr -8
.text:00401037 hResInfo = dword ptr -4
.text:00401037
.text:00401037 push ebp
.text:00401038 mov ebp, esp
.text:0040103A add esp, 0FFFFFBF4h
.text:00401040 push esi
.text:00401041 push edi
.text:00401042 push ebx
.text:00401043 push 0 ; lpModuleName
.text:00401045 call GetModuleHandleA
.text:0040104A mov dword_403030, eax
.text:0040104F mov [ebp+lpBuffer], 0
.text:00401056 push 0Ah ; lpType
.text:00401058 push offset Name ; "DLL"
.text:0040105D push 0 ; hModule
.text:0040105F call FindResourceA
.text:00401064 or eax, eax
.text:00401066 jz short loc_401089
.text:00401068 mov [ebp+hResInfo], eax
.text:0040106B push [ebp+hResInfo] ; hResInfo
.text:0040106E push 0 ; hModule
.text:00401070 call SizeofResource
.text:00401075 mov [ebp+nNumberOfBytesToWrite], eax
.text:00401078 push [ebp+hResInfo] ; hResInfo
.text:0040107B push 0 ; hModule
.text:0040107D call LoadResource
.text:00401082 or eax, eax
.text:00401084 jz short loc_401089
.text:00401086 mov [ebp+lpBuffer], eax
.text:00401089
.text:00401089 loc_401089: ; CODE XREF: sub_401037+2F^j
.text:00401089 ; sub_401037+4D^j
.text:00401089 cmp [ebp+lpBuffer], 0
.text:0040108D jz short loc_4010C1
.text:0040108F push 4 ; flProtect
.text:00401091 push 1000h ; flAllocationType
.text:00401096 push [ebp+nNumberOfBytesToWrite] ; dwSize
.text:00401099 push 0 ; lpAddress
.text:0040109B call VirtualAlloc
.text:004010A0 mov edi, eax
.text:004010A2 push [ebp+nNumberOfBytesToWrite]
.text:004010A5 push [ebp+lpBuffer]
.text:004010A8 push edi
.text:004010A9 call RtlMoveMemory
.text:004010AE mov [ebp+lpBuffer], edi
.text:004010B1 push 0DEADBEEFh ; 0xDEADBEEF
.text:004010B6 push [ebp+nNumberOfBytesToWrite] ; DLL size
.text:004010B9 push [ebp+lpBuffer] ; DLL resource
.text:004010BC call sub_401000 ; decrypt the DLL
.text:004010C1
.text:004010C1 loc_4010C1: ; CODE XREF: sub_401037+56^j
.text:004010C1 cmp [ebp+lpBuffer], 0
.text:004010C5 jz short loc_4010FB
.text:004010C7 lea eax, [ebp+LibFileName]
.text:004010CD push eax ; lpBuffer
.text:004010CE push 400h ; nBufferLength
.text:004010D3 call GetTempPathA
.text:004010D8 push offset String2 ; "\\dup2patcher.dll"
.text:004010DD lea eax, [ebp+LibFileName]
.text:004010E3 push eax ; lpString1
.text:004010E4 call lstrcatA
.text:004010E9 push [ebp+nNumberOfBytesToWrite] ; nNumberOfBytesToWrite
.text:004010EC push [ebp+lpBuffer] ; lpBuffer
.text:004010EF lea eax, [ebp+LibFileName]
.text:004010F5 push eax ; lpFileName
.text:004010F6 call sub_401184
.text:004010FB
.text:004010FB loc_4010FB: ; CODE XREF: sub_401037+8E^j
.text:004010FB lea eax, [ebp+LibFileName]
.text:00401101 push eax ; lpLibFileName
.text:00401102 call LoadLibraryA
.text:00401107 or eax, eax
.text:00401109 jz short loc_401130
.text:0040110B mov ebx, eax
.text:0040110D push offset ProcName ; "load_patcher"
.text:00401112 push ebx ; hModule
.text:00401113 call GetProcAddress
.text:00401118 or eax, eax
.text:0040111A jz short loc_40111E
.text:0040111C call eax
.text:0040111E
.text:0040111E loc_40111E: ; CODE XREF: sub_401037+E3^j
.text:0040111E push ebx ; hLibModule
.text:0040111F call FreeLibrary
.text:00401124 lea eax, [ebp+LibFileName]
.text:0040112A push eax ; lpFileName
.text:0040112B call DeleteFileA
.text:00401130
.text:00401130 loc_401130: ; CODE XREF: sub_401037+D2^j
.text:00401130 pop ebx
.text:00401131 pop edi
.text:00401132 pop esi
.text:00401133 leave
.text:00401134 retn
.text:00401134 sub_401037 endp
selanjutnya aplikasi akan melakukan dekripsi dengan memanggil fungsi yang me-
miliki 3 parameter yaitu: alamat memori yang berisi resource dll, ukuran memori
dan key untuk dekripsi, seperti yang bisa dilihat pada snippet di atas, di bagian
ini:
Code:
.text:004010B1 push 0DEADBEEFh ; key: 0xDEADBEEF
.text:004010B6 push [ebp+nNumberOfBytesToWrite] ; DLL resource size
.text:004010B9 push [ebp+lpBuffer] ; DLL resource address
.text:004010BC call sub_401000 ; decrypt the DLL
Selanjutnya adalah melihat fungsi yang dipanggil, yang bertanggungjawab untuk
proses dekripsi. Berikut ini adalah fungsi tersebut:
Code:
.text:00401000 ; =============== S U B R O U T I N E =======================================
.text:00401000
.text:00401000 ; Attributes: bp-based frame
.text:00401000
.text:00401000 sub_401000 proc near ; CODE XREF: sub_401037+85^p
.text:00401000
.text:00401000 arg_0 = dword ptr 8 ; encrypted DLL buffer
.text:00401000 arg_4 = dword ptr 0Ch ; DLL size
.text:00401000 arg_8 = dword ptr 10h ; 0xDEADBEEF
.text:00401000
.text:00401000 push ebp ;
.text:00401001 mov ebp, esp ; prepare the stack
.text:00401003 push esi ;
.text:00401004 push edi ;
.text:00401005 push ebx ;
.text:00401006 mov esi, [ebp+arg_0] ; ESI = encrypted DLL buffer
.text:00401009 mov edi, esi ; EDI = ESI (source = dest)
.text:0040100B mov ebx, [ebp+arg_8] ; EBX = 0xDEADBEEF
.text:0040100E mov ecx, [ebp+arg_4] ; ECX = DLL size
.text:00401011 jmp short loc_401020 ; check if buffer not empty
.text:00401013 ; ---------------------------------------------------------------------------
.text:00401013
.text:00401013 loc_401013: ; CODE XREF: sub_401000+22^j
.text:00401013 lodsb ; get one byte from ESI and put it in AL
.text:00401014 mov dl, al ; DL = AL
.text:00401016 xor al, bl ; AL ^= BL
.text:00401018 stosb ; store the result from AL to EDI
.text:00401019 ror ebx, 1 ; EBX >> 1
.text:0040101B xor bl, dl ; BL ^= DL
.text:0040101D add ebx, ecx ; EBX += ECX
.text:0040101F dec ecx ; ECX-- (counter)
.text:00401020
.text:00401020 loc_401020: ; CODE XREF: sub_401000+11^j
.text:00401020 or ecx, ecx ; is it the last byte?
.text:00401022 jnz short loc_401013 ; if not, repeat
.text:00401024 pop ebx ;
.text:00401025 pop edi ;
.text:00401026 pop esi ;
.text:00401027 leave ; restore stack
.text:00401028 retn 0Ch ; return
.text:00401028 sub_401000 endp
yang jika dibuat dalam bahasa sederhana kurang lebih seperti ini:
1. Register EBX pada awalnya berisi key 0xDEADBEEF.
2. Register ECX berisi ukuran data yang terenkripsi (DLL).
3. Ambil 1 byte dari data yang terenkripsi.
4. Simpan/copy byte tersebut di register DL.
5. Lakukan operasi XOR pada byte tersebut dengan byte key yang ada di register EBX.
6. Simpan hasilnya pada lokasi memori data yang terenkripsi sesuai urutannya.
7. Lakukan operasi ROR pada key yang ada pada EBX sebanyak 1x.
8. Lakukan operasi XOR pada byte key dengan byte yang berada pada register DL (byte yang belum didekripsi).
9. Tambahkan key dengan counter yang berada pada register ECX.
10. Kurangi counter, dan jika data yang akan didekripsi masih ada, maka ulangi dari langkah ke-3.
* Urutan algoritma di atas jika dibuat dalam bentuk kode, kurang lebih seperti ini:
Code:
key = 0xdeadbeef;
for (i=0; i<DLL_SIZE; i++)
{
dl = buff[i];
buff[i] ^= (key & 0xff);
key >>= 1;
key ^= dl;
key += (DLL_SIZE - i);
}
terlebih dahulu harus mengekstrak resource yang ada pada aplikasi tersebut.
Cara yang dapat ditempuh adalah, dengan menggunakan 7zip
Code:
% 7z x target.exe
7-Zip [64] 9.20 Copyright (c) 1999-2010 Igor Pavlov 2010-11-18
p7zip Version 9.20 (locale=en_US.utf8,Utf16=on,HugeFiles=on,4 CPUs)
Processing archive: target.exe
Extracting .text CRC Failed
Extracting .rdata CRC Failed
Extracting .data CRC Failed
Extracting .rsrc/ICON/1.ico CRC Failed
Extracting .rsrc/RCDATA/DLL CRC Failed
Extracting .rsrc/GROUP_ICON/500 CRC Failed
Extracting .rsrc/MANIFEST/1 CRC Failed
Extracting .reloc CRC Failed
Sub items Errors: 8
diabaikan. Selanjutnya adalah melihat file resource yang akan didekripsi. Perlu
diingat bahwa direktori ".rsrc" bersifat "hidden" jika menggunakan sistem operasi
GNU/Linux dan file tersebut tidak dikenali formatnya:
Code:
% file .rsrc/RCDATA/DLL
.rsrc/RCDATA/DLL: data
% hexdump -C -n128 .rsrc/RCDATA/DLL
00000000 a2 8f f4 44 e0 0d 86 3f 9d 49 e4 8c c0 2c b8 d6 |...D...?.I...,..|
00000010 96 71 b8 52 e8 08 f7 76 f6 15 86 ab e3 f6 70 2a |.q.R...v......p*|
00000020 a0 50 d7 9a b4 4a ca 89 a6 cd 02 d9 0a 63 a5 c9 |.P...J.......c..|
00000030 7e 11 68 2a 8c 16 e8 e6 5e b9 2c 00 3d a3 35 71 |~.h*....^.,.=.5q|
00000040 04 de c7 b9 1f 78 d0 bb 98 44 70 32 8f c3 31 5d |.....x...Dp2..1]|
00000050 11 2e 8f 76 d0 42 18 23 55 9a a8 71 fc b8 98 6a |...v.B.#U..q...j|
00000060 fd 79 96 ef 67 92 88 7e 2f a9 0e 74 b7 ad bc fd |.y..g..~/..t....|
00000070 c9 44 84 67 5d fd 9d 55 27 2e 40 e6 9a db 39 a7 |.D.g]..U'[email protected].|
membuat aplikasi sederhana untuk melakukan dekripsi. Berikut ini adalah contoh
PoC untuk melakukan dekripsi terhadap resource yang telah diekstrak:
Code:
% gcc -Wall -s -o decryptor decryptor.c && ./decryptor .rsrc/RCDATA/DLL
All done...
Code:
% file .rsrc/RCDATA/DLL
.rsrc/RCDATA/DLL: MS-DOS executable, MZ for MS-DOS
% hexdump -C -n128 .rsrc/RCDATA/DLL
00000000 4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00 |MZ..............|
00000010 b8 00 00 00 00 00 00 00 40 80 c0 20 30 98 d4 2e |........@.. 0...|
00000020 a9 d4 26 97 4d ee b9 c4 ae 37 85 4e ed 2e 3d f2 |..&.M....7.N..=.|
00000030 5b ad f6 5f d1 f8 c4 ae 55 1a 03 81 b8 60 30 08 |[.._....U....`0.|
00000040 8a 5d 19 df d8 40 4f 62 08 4c 07 b3 28 d3 cf 5d |.][email protected]..(..]|
00000050 9f a8 13 99 7e 71 9e a6 df a2 05 d5 b4 44 f1 a4 |....~q.......D..|
00000060 53 33 ed 26 4f 1d 78 f4 7b b4 b0 93 2b 20 42 a8 |S3.&O.x.{...+ B.|
00000070 21 09 f5 ad d2 5b a4 de be dd 9e 53 db 65 3e 9b |!....[.....S.e>.|
proses analisis terhadap file yang telah didekripsi.
* Sekian tutorial singkat kali ini, semoga bermanfaat.
Gambar Ilustrasi decrypt
Credits: RNDC - Eric Draven aka Drubizca