Monday, 16 October 2017

Teknik Malware Menggunakan TLS Callback

Entry point suatu program merupakan lokasi yang berisi instruksi kode yang akan dieksekusi pertama kali oleh sistem. Entry point dapat dianalogikan sebagai void main pada kode bahasa pemrograman.

Rutin yang sering dilakukan virus yaitu dengan memanipulasi entry point. Virus menginfeksi suatu program dengan menaruh kode virus di awal atau akhir pada program yang akan diinfeksi (host). Langkah selanjutnya virus mengubah entry point untuk menjalankan kode virus terlebih dahulu dan setelah itu host pun dipanggil.

Teknik lain yang digunakan virus dalam menginfeksi program yaitu dengan memakai teknik Entry Point Obscuring (EPO). Virus yang mempunyai kemampuan EPO akan lebih susah dideteksi oleh antivirus karena virus tidak akan memodifikasi entry point melainkan dengan melakukan patching atau mengubah data pada rutin yang memanggil suatu fungsi tertentu. Dengan melakukan patching ini, ketika fungsi yang diubah sedang dipanggil, kode virus pun dapat terpanggil juga.

Pada tahun 2002, virus Chton merupakan virus pertama yang menggunakan teknik Thread Local Storage (TLS) Callback. Dengan teknik ini, kode virus akan aktif terlebih dahulu sebelum entry point dieksekusi oleh sistem.  

Dengan adanya TLS Callback ini, tentunya dapat membuat penganalisa virus mengalami kebingungan karena virus akan aktif terlebih dahulu sebelum dianalisa. Sebagai contoh , jika Anda membuka program yang mempunya TLS Callback menggunakan OllyDbg, saat proses inisialisasi program, virus akan aktif. Hal ini akan berlaku jika Anda menggunakan OllyDbg versi 2.0 ke bawah. Untuk versi terbaru pun Anda harus mengkonfigurasi lagi untuk menghindari dampak dari TLS Callback, yaitu melalui menu Options | Debugging options | Events.  Pilih System breakpoint.

Gambar 1. Kode yang tereksekusi akibat TLS Callback pada OllyDbg
Gambar 1. Kode yang tereksekusi akibat TLS Callback pada OllyDbg
Pada IDA Pro, antisipasi terhadap TLS Callback sudah terdapat pada versi  4.2 yaitu yang diedarkan pada tahun 2001. Untuk versi lama dari IDA Pro, Anda akan menjalankan kode sebelum entry point saat mulai men-debug. Skenarionya yaitu buka program menggunakan IDA Pro, lalu tekan F2. IDA Pro akan otomatis membuat breakpoint pada entry point. Lalu jalankan program dengan harapan kode akan break di entry point. Tapi apa yang terjadi? TLS Callback pun beraksi. Untuk mencegah hal ini, tekan Ctrl-E, Anda akan melihat fungsi dengan nama TLSCallback_0.

Gambar 2. Kode yang tereksekusi akibat TLS Callback pada IDA Pro
Gambar 2. Kode yang tereksekusi akibat TLS Callback pada IDA Pro
Gambar 3. Pilihan entry point pada IDA Pro
Gambar 3. Pilihan entry point pada IDA Pro
Thread Local Storage Callback
Ketika thread pada program menggunakan local variables yang berupa stack, maka setiap thread akan mempunyai akses tersendiri terhadap variables tersebut.  Hal ini untuk mencegah pemakaian variables secara bersamaan oleh thread lain agar tidak menimbulkan crash pada program. Local data merupakan global variables yang memiliki setiap thread tersendiri. Suatu thread dapat menaruh local data berupa pointer pada TLS array. TLS Array merupakan array yang bernilai 4 bytes DWORD. 
Pengaturan data pada TLS Array dapat dilakukan dengan menggunakan fungsi API TLSAlloc dan TLSFree. 

Cara lain yang digunakan bahasa pemrograman agar mendukung TLS adalah dengan mendeklarasi kata tambahan pada global variables.

Deklarasi pada bahasa Object Pascal yaitu :

var
   mydata_process: integer;
threadvar
   mydata_threadlocal: integer;
 
Pada bahasa C :

__declspec(thread) int number;

Format yang lain :

int __thread number;

Global variables yang dideklarasikan tersebut akan secara otomatis dikumpulkan oleh compiler atau linker menjadi suatu TLS Array yang terletak pada .tls section.

TLS terdapat pada IMAGE_TLS_DIRECTORY  yang merupakan bagian dari PE header. Berikut struktur dari IMAGE_TLS_DIRECTORY :

typedef struct _IMAGE_TLS_DIRECTORY {
    UINT32 StartAddressOfRawData;
    UINT32 EndAddressOfRawData;
    PUINT32 AddressOfIndex;
    PIMAGE_TLS_CALLBACK *AddressOfCallBacks;
    UINT32 SizeOfZeroFill;
    UINT32 Characteristics;
} IMAGE_TLS_DIRECTORY, *PIMAGE_TLS_DIRECTORY;

-          StartAddressOfRawData
Setiap thread baru dibuat, sistem akan mengalokasi local data baru berupa buffer untuk thread. Buffer ini terdapat pada alamat parameter ini. Alamat ini bukan berupa Relative Virtual Address (RVA) tetapi Virtual Address yang mempunyai relocation entry pada .reloc section .
-          EndAddressOfRawData
Parameter ini merupakan Virtual Address dari alamat akhir dari buffer.
-          AddressOfIndex
Ketika program dijalankan, sistem atau loader akan mengalokasikan TLS menggunakan TLSAlloc ke alamat AddressOfIndex . Program akan mengakses TLS variables melalui alamat ini.
-          AddressOfCallback
Merupakan alamat fungsi dari TLS yang berisi pointer. Setiap fungsi yang terdapat pada array ini akan dipanggil setial thread baru dibuat.
-          SizeOfZeroFill
Ukuran dalam bytes dari StartAddressOfRawData hingga EndAddressOfRawData.
-          Characteristics
Umumnya bernilai 0

Untuk melihat struktrur dari IMAGE_TLS_DIRECTORY, Anda dapat menggunakan program StudPE.

Buka program yang terdapat TLS Callback, pada bagian kanan yaitu Data Directory, pilih Image_Dir_Entry_TLS, di bawah pilihan tersebut terdapat tombol “++”, pilih tombol tersebut.  Pada gambar 5, Anda bisa melihat informasi pada TLS table.

Gambar 4. Tampilan StudPE
Gambar 4. Tampilan StudPE
Gambar 5. Informasi pada TLS
Gambar 5. Informasi pada TLS
Demo Program
Berikut kode program menggunakan editor Dev-Cpp :

#include <windows.h>
 
int MyFunction();
int tlsdone = 0;
 
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    ExitProcess(0);
    return 0;
}
 
int MyFunction ()
{
    if(tlsdone == 0)
    {
        MessageBox( NULL,
                    "hello",
                    "hello",
                    MB_OK | MB_ICONINFORMATION
);
        tlsdone = 1;
    }
    return 0;
}
 
Jika dilihat, maka fungsi MyFunction tidak dipanggil oleh fungsi main pada program sehingga kode berisi pesan tidak akan pernah ditampilkan. Tugas selanjutnya yaitu bagaimana menjalankan fungsi MyFunction dengan cara memanggilnya melalui teknik TLS Callback.
Untuk apa variable tlsdone?  Suatu program yang memakai TLS Callback, fungsi pada TLS akan dipanggil dua kali. Oleh karena itu, tlsdone digunakan untuk mencegak kode tereksekusi untuk kedua kalinya.

Selanjutnya, buka hasil compile dari kode di atas (misalnya dengan nama Project1.exe) menggunakan OllyDbg.  Cari string “hello”. Untuk mencari string, klik kanan pada jendela utama, pilih Search For | All referenced text strings. Muncul jendela baru yang berisi string pada program. Klik dua kali pada tulisan berikut :

004012C1  |.  C74424 04 003>MOV DWORD PTR SS:[ESP+4],Project1.00403000         ; |ASCII "hello"

Anda akan dibawa ke jendela berisi alamat asli dari string tersebut. Silahkan lihat pada gambar 6.

Gambar 6. String “hello” pada OllyDbg
Gambar 6. String “hello” pada OllyDbg
Lokasi asli dari string yaitu di 00403000. Pada jendel a dump, tekan Ctrl-G dan masukan alamat 00403000. Silahkan lihat pada gambar 7. Geser ke bawah untuk mendapatkan space yang kosong, sebagai contoh alamat yang diambil yaitu 004030D3. Tambahkan 004030D3 dengan 9 DWORD sehingga menghasilkan 004030F7 atau dalam format little indian ialah F7304000.

Gambar 7. Tampilan pada jendela dump
Gambar 7. Tampilan pada jendela dump
Berdasarkan gambar 6, alamat dimulainya fungsi yang ingin dieksekusi yaitu pada 004012A2.

Berikut baris fungsi dimulai :

004012A2  /.  55            PUSH EBP

Alamat 004012A2 jika diubah menjadi format little indian, yaitu A2124000. Blok empat bytes dari 004030F7 hingga 004030FA, tekan tombol spasi dan masukan nilai  A2124000. Setelah itu, dimulai dari 004030DF, masukan nilai F7304000 dimana nilai ini adalah nilai dari AddressOfCallback.

Gambar 8. Memasukan nilai A2124000
Gambar 8. Memasukan nilai A2124000
Gambar 9. Memasukan nilai F7304000
Gambar 9. Memasukan nilai F7304000
Berikutnya, silahkan lihat gambar 10 untuk memasukan nilai-nilai lain yang diperlukan untuk mengisi TLS table.

Gambar 10. Tampilan akhir hasil modifikasi di OllyDbg
Gambar 10. Tampilan akhir hasil modifikasi di OllyDbg
Untuk menyimpan program, blok semua bytes yang telah dimodifikasi, klik kanan pada pilihan tersebut, pilih Copy to executable file. Pada jendela baru, klik kanan lagi dan pilih save file. Anggap saja Anda menyimpan file tersebut dengan nama Project1_.exe

Sekarang  TLS table telah selesai, tapi fungsi MyFunction tidak akan dipanggil karena belum adanya perintah untuk memanggil TLS Table. Untuk itu Anda harus mengubah nilai pada Directory Data. Anda bisa menggunakan StudPE. Buka Project1_.exe dengan StudPE, pilih Data Dir agar berisi IMAGE_DIR_ENTRY_TLS. Masukan nilai 000030D3 (image base - 000030D3)di kolom RVA dan masukan nilai 30000000 di kolom Size. Setelah itu pilih tombol SAVE to file.

Gambar 11. Memodifikasi data pada IMAGE_DIR_ENTRY_TLS
Gambar 11. Memodifikasi data pada IMAGE_DIR_ENTRY_TLS
Jika Anda tutup StudPE dan menjalankannya lagi untuk membuka Project1_.exe, maka tombol “++” akan aktif. 

Jalankan file Project1_.exe. Tanpa bermain-main dengan entry point, program akan menampilkan kotak pesan.

Kesimpulan
TLS Callback sering digunakan malware untuk menyembunyikan teknik antidebugging agar terhindar dari proses analisa. Begitu juga dengan malware, program packer pun menggunakan konsep yang sama untuk melindungi program dari aktifitas ilegal.

Untuk membuat TLS Callback tidak mesti dilakukan secara hardcore atau manual. Dengan menggunakan compiler C atau ASM dapat dengan mudah membuat TLS Callback.

Dengan mengetahui adanya TLS Callback ini, setiap melakukan kegiatan debugging haruslah memperhatikan dari mana program debugger memulai operasi debugging. Hal ini untuk menghindari Anda kecolongan saat menganalisa suatu malware!

Ditulis untuk PC Media edisi 8 2010

No comments:

Post a Comment