Saya mengetahui bahwa pemerintah Denmark tidak hanya
menghentikan program Monitor Ujian Digital, yang kami analisis dan sepenuhnya hindari dalam
artikel sebelumnya , tetapi mungkin
benar-benar mematikan sistem ini seminggu setelah kami memberi tahu mereka tentang metode peretasan. Saya tidak ingin berpikir bahwa itu murni karena kita bahwa pemerintah Denmark menolak gagasan memantau ujian, tetapi pekerjaan kami jelas diperhatikan.
Dalam artikel ini, kami akan menguraikan rincian teknis tentang cara kerja alat pelacakan anak sekolah lainnya: ExamCookie. Jika Anda hanya tertarik untuk melewati sistem, gulir ke bawah ke bagian yang sesuai.
ExamCookie
Baru-baru ini, alat ini
menjadi berita karena investigasi terhadap pelanggaran GDPR. Kami memutuskan untuk melihat pesaing terbesar kedua dari sistem pelacakan sekolah tersebut selama ujian:
ExamCookie . Ini adalah sistem pelacakan komersial yang digunakan oleh lebih dari 20 sekolah Denmark. Tidak ada dokumentasi di situs selain deskripsi berikut:
ExamCookie adalah perangkat lunak sederhana yang memantau aktivitas komputer siswa selama ujian untuk memastikan aturan diikuti. Program ini melarang siswa untuk menggunakan segala bentuk bantuan ilegal.
ExamCookie menyimpan semua aktivitas di komputer: URL aktif, koneksi jaringan, proses, clipboard, dan tangkapan layar saat mengubah ukuran jendela.
Program ini bekerja sederhana: dengan mengikuti ujian, Anda menjalankannya di komputer, dan memonitor aktivitas Anda. Ketika ujian selesai, program ditutup, dan Anda dapat menghapusnya dari komputer.
Untuk mulai melacak, Anda harus menggunakan login UNI Anda, yang berfungsi di berbagai situs pendidikan, atau secara manual memasukkan kredensial. Kami tidak menggunakan alat ini, jadi kami tidak dapat mengatakan dalam kasus mana entri manual digunakan. Mungkin ini dilakukan untuk siswa yang tidak memiliki login UNI, yang kami anggap tidak mungkin.
Informasi Biner
Program ini dapat diunduh dari halaman utama ExamCookie. Ini adalah aplikasi .NET x86. Untuk referensi, biner MD5 yang dianalisis
63AFD8A8EC26C1DC368D8FF8710E337D
tanda tangan EXAMCOOKIE APS tanggal 24 April 2019. Seperti yang ditunjukkan
artikel terakhir , analisis biner .NET hampir tidak dapat disebut rekayasa terbalik, karena kombinasi kode IL dan metadata yang mudah dibaca menyediakan kode sumber yang sempurna.
Berbeda dengan program pemantauan sebelumnya, para pengembang alat ini tidak hanya menghapusnya dari log debug, tetapi juga mengaburkannya. Setidaknya mereka mencoba :-)
Kebingungan (tertawa sampai menangis)
Ketika kami membuka aplikasi di dnSpy, kami dengan cepat melihat titik masuk yang hilang:
Aneh, semacam bungkus biasanya diasumsikan, itu mengubah tubuh metode dari konstruktor modul, yang berjalan ke titik entri aktual, mari kita lihat:
Keren Ini tahun 2019, dan orang-orang masih menggunakan Confuser (Ex).
Kami langsung mengenali kode dekompresi ini dan memeriksa header assembler:
[modul: ConfusedBy ("Confuser.Core 1.1.0 + a36320377a")]
Saat ini, kami berpikir bahwa kode sebenarnya akan dikaburkan, karena konstruktor di atas mendekripsi tubuh dan sumber daya dari metode ini. Tapi, yang mengejutkan kami, pengembang kebingungan memutuskan ... untuk tidak mengganti nama metadata:
Ini membunuh semua buzz rekayasa terbalik. Seperti yang kami katakan dalam
artikel sebelumnya , saya ingin menemukan masalah sebenarnya dari alat pengawasan berkualitas tinggi yang terlindungi dengan baik, yang analisisnya akan memakan waktu lebih dari lima menit.
Dalam kasus apa pun, membongkar setiap biner yang dilindungi oleh confuser (ex) sangat sederhana: gunakan .NET binaries dumper atau break break statement statement di <MODULE> .toror dan buang sendiri. Prosesnya memakan waktu 30 detik, dan paket ini akan selalu menjadi favorit saya, karena perlindungan terhadap debug
tidak pernah bekerja sama sekali .
Kami memutuskan untuk menggunakan MegaDumper: ini sedikit lebih cepat daripada membuang secara manual:
Setelah membuang biner ExamCookie, pesan berikut akan muncul:
Sekarang Anda memiliki direktori dengan semua fragmen assembler yang dimuat ke proses yang sesuai, kali ini dengan badan metode dekripsi.
Siapa pun yang menerapkan kebingungan ini, terima kasih Tuhan, setidaknya ia mengenkripsi baris:
else if (System.Windows.Forms.Clipboard.ContainsData(DataFormats.SymbolicLink)) { Module1.DebugPrint(<Module>.smethod_5<string>(1582642794u), new object[0]); } else if (System.Windows.Forms.Clipboard.ContainsData(DataFormats.Tiff)) { Module1.DebugPrint(<Module>.smethod_2<string>(4207351461u), new object[0]); } else if (System.Windows.Forms.Clipboard.ContainsData(DataFormats.UnicodeText)) { Module1.DebugPrint(<Module>.smethod_5<string>(3536903244u), new object[0]); } else if (System.Windows.Forms.Clipboard.ContainsData(DataFormats.WaveAudio)) { Module1.DebugPrint(<Module>.smethod_2<string>(2091555364u), new object[0]); }
Ya, enkripsi enkripsi string lama yang baik (Ex), pseudo-security terbaik di dunia .NET. Ada baiknya Confuser (Ex) diretas terlalu sering sehingga alat deobfusi tersedia di Internet untuk setiap mekanisme, jadi kami tidak akan menyentuh apa pun yang terkait dengan .NET. Jalankan ConfuserExStringDecryptor dari
CodeCracker di dump biner:
Ini mengubah cuplikan sebelumnya menjadi ini:
else if (System.Windows.Forms.Clipboard.ContainsData(DataFormats.SymbolicLink)) { Module1.DebugPrint("ContainsData.SymbolicLink", new object[0]); } else if (System.Windows.Forms.Clipboard.ContainsData(DataFormats.Tiff)) { Module1.DebugPrint("ContainsData.Tiff", new object[0]); } else if (System.Windows.Forms.Clipboard.ContainsData(DataFormats.UnicodeText)) { Module1.DebugPrint("ContainsData.UnicodeText", new object[0]); } else if (System.Windows.Forms.Clipboard.ContainsData(DataFormats.WaveAudio)) { Module1.DebugPrint("ContainsData.WaveAudio", new object[0]); }
Itu semua perlindungan aplikasi, rusak dalam waktu kurang dari satu menit ... Kami tidak akan memposting alat kami di sini, karena kami tidak mengembangkannya dan kami tidak memiliki kode sumber. Tetapi siapa pun yang ingin mengulang pekerjaan itu dapat menemukannya di
Tuts4You . Kami tidak lagi memiliki akun tuts4you, jadi kami tidak dapat menautkan ke mirror.
Fungsionalitas
Anehnya, tidak ada "fungsi tersembunyi" yang nyata ditemukan. Seperti yang ditunjukkan di situs web, informasi berikut secara berkala dikirimkan ke server:
- Daftar Proses (setiap 5000 ms)
- Aplikasi aktif (setiap 1000 ms)
- Papan klip (setiap 500 ms)
- Tangkapan layar (setiap 5000 ms)
- Daftar adapter jaringan (setiap 20.000 ms)
Sisa aplikasi sangat membosankan, jadi kami memutuskan untuk melewati seluruh prosedur inisialisasi dan langsung ke fungsi yang bertanggung jawab untuk mengambil informasi.
Adaptor
Adapter jaringan dirakit oleh fungsi .NET
NetworkInterface.GetAllNetworkInterfaces()
, persis seperti pada
artikel sebelumnya :
NetworkInterface[] allNetworkInterfaces = NetworkInterface.GetAllNetworkInterfaces(); foreach (NetworkInterface networkInterface in allNetworkInterfaces) { try {
Aplikasi aktif
Ini semakin menarik. Alih-alih mendaftarkan semua jendela yang terbuka, utilitas hanya mengontrol aplikasi yang aktif. Implementasinya overblown, oleh karena itu kami menyajikan pseudocode yang indah:
var whiteList = { "devenv", "ExamCookie.WinClient", "ExamCookie.WinClient.vshost", "wermgr", "ShellExperienceHost" };
Hebat ... orang masih menggunakan nama proses untuk membedakannya. Mereka tidak pernah berhenti dan tidak berpikir: "Tunggu sebentar, Anda dapat mengubah nama proses sesuka Anda," sehingga kami dapat dengan aman melewati perlindungan ini.
Jika Anda membaca artikel sebelumnya tentang program pelacakan ujian lain, Anda mungkin akan mengenali penerapan standar ini untuk browser:
private bool IsBrowser(System.Diagnostics.Process proc) { bool result; try { string left = proc.ProcessName.ToLower(); if (Operators.CompareString(left, "iexplore", false) != 0 && Operators.CompareString(left, "chrome", false) != 0 && Operators.CompareString(left, "firefox", false) != 0 && Operators.CompareString(left, "opera", false) != 0 && Operators.CompareString(left, "cliqz", false) != 0) { if (Operators.CompareString(left, "applicationframehost", false) != 0) { result = false; } else { result = proc.MainWindowTitle.Containing("Microsoft Edge"); } } else { result = true; } } catch (Exception ex) { result = false; } return result; }
private string GetBrowserName(string name) { if (Operators.CompareString(name.ToLower(), "iexplore", false) == 0) { return "IE-Explorer"; } else if (Operators.CompareString(name.ToLower(), "chrome", false) == 0) { return "Chrome"; } else if (Operators.CompareString(name.ToLower(), "firefox", false) == 0) { return "Firefox"; } else if (Operators.CompareString(name.ToLower(), "opera", false) == 0) { return "Opera"; } else if (Operators.CompareString(name.ToLower(), "cliqz", false) == 0) { return "Cliqz"; } else if (Operators.CompareString(name.ToLower(), "applicationframehost", false) == 0) { return "Microsoft Edge"; } return ""; }
Dan ceri di atas kue:
private static string GetBrowserUrlById(object processId, string name) {
Secara harfiah ini adalah implementasi yang sama seperti pada artikel sebelumnya. Sulit untuk memahami bagaimana pengembang masih belum menyadari betapa buruknya itu. Siapa pun dapat mengedit URL di browser, ini bahkan tidak layak ditunjukkan.
Penemuan mesin virtual
Bertentangan dengan apa yang dikatakan situs web, mulai dari mesin virtual menetapkan bendera. Implementasinya ... menarik.
File.WriteAllBytes("ecvmd.exe", Resources.VmDetect); using (Process process = new Process()) { process.StartInfo = new ProcessStartInfo("ecvmd.exe", "-d") { CreateNoWindow = true, UseShellExecute = false, RedirectStandardOutput = true }; process.Start(); try { using (StreamReader standardOutput = process.StandardOutput) { result = standardOutput.ReadToEnd().Replace("\r\n", ""); } } catch (Exception ex3) { result = "-5"; } }
Nah, untuk beberapa alasan, mereka menulis biner eksternal ke disk dan menjalankannya, dan kemudian bergantung sepenuhnya pada hasil I / O. Ini benar-benar sering terjadi, tetapi pemindahan pekerjaan penting seperti itu ke proses lain yang tidak terlindungi begitu-begitu. Mari kita lihat file mana yang sedang kita tangani:
Jadi sekarang kita menggunakan C ++? Nah, interoperabilitas sebenarnya tidak selalu buruk. Dan ini mungkin berarti bahwa kita sekarang benar-benar harus bekerja pada reverse engineering (!!). Mari kita lihat IDA:
int __cdecl main(int argc, const char **argv, const char **envp) { int v3;
Ini memverifikasi keberadaan VMWare I / O port 'VX':
int __fastcall vm_detect::vmware_port() { int result;
Selanjutnya, eksekusi instruksi
ekstensi pc virtual diperiksa, yang seharusnya hanya berfungsi ketika diluncurkan di lingkungan tervirtualisasi, jika tidak menyebabkan kerusakan mesin jika diproses secara salah;):
char vm_detect::vpcext() { char result;
... tidak ada rekayasa balik nyata, hanya 30 detik untuk mengubah nama dua fungsi :(
Program ini hanya membaca kunci registri dan menjalankan dua pemeriksaan hypervisor yang terlihat aneh dibandingkan dengan program mereka yang lain. Saya ingin tahu di mana mereka menyalinnya? Oh, lihat, artikel berjudul
"Metode untuk menemukan mesin virtual (sic)" yang menjelaskan metode ini :). Bagaimanapun, vektor-vektor deteksi ini dapat dielakkan dengan mengedit file .vmx atau menggunakan versi yang disempurnakan dari setiap hypervisor pilihan Anda.
Perlindungan data
Seperti disebutkan sebelumnya, penyelidikan sedang dilakukan untuk ketidakpatuhan dengan GDPR, dan
situs web mereka menyatakan:
Data dienkripsi dan dikirim ke server Microsoft Azure yang aman, yang hanya dapat diakses dengan kredensial yang benar. Setelah ujian, data disimpan hingga tiga bulan.
Kami tidak yakin bagaimana mereka menentukan "keamanan" server, karena kredensial di-hardcode dalam aplikasi dan disimpan dalam teks yang sepenuhnya jelas dalam sumber daya metadata:
Endpoint: https://examcookiewinapidk.azurewebsites.net
Nama Pengguna: VfUtTaNUEQ
Kata Sandi: AwWE9PHjVc
Kami tidak memeriksa konten server (ini ilegal), tetapi kami dapat berasumsi bahwa ada akses penuh. Karena akun tersebut di-hardcode dalam aplikasi, tidak ada isolasi antara wadah data siswa.
Penafian hukum: Kami berhak untuk mempublikasikan kredensial API karena disimpan dalam file biner publik dan oleh karena itu tidak diperoleh secara ilegal. Namun, menggunakannya dengan niat jahat jelas melanggar hukum, oleh karena itu kami sangat menyarankan agar pembaca tidak menggunakan kredensial yang disebutkan di atas dengan cara apa pun, dan kami tidak bertanggung jawab atas tindakan potensial apa pun.Lewati
Karena aplikasi ini sangat mengingatkan pada Digital Exam Monitor, kami baru saja memperbarui kode
ayyxam untuk mendukung ExamCookie.
Daftar proses
Antarmuka proses .NET secara internal melakukan cache data proses menggunakan panggilan sistem
ntdll!NtQuerySystemInformation
. Untuk menyembunyikan proses dari itu memerlukan beberapa pekerjaan, karena informasi tentang proses ditunjukkan di banyak tempat. Untungnya, .NET hanya mengambil satu jenis informasi tertentu, jadi Anda tidak perlu menggunakan semua metode
latebros .
Kode untuk mem-bypass validasi proses aktif.
NTSTATUS WINAPI ayyxam::hooks::nt_query_system_information( SYSTEM_INFORMATION_CLASS system_information_class, PVOID system_information, ULONG system_information_length, PULONG return_length) {
Buffer
ole32.dll!OleGetClipboard
, yang sangat rentan terhadap pengait, bertanggung jawab atas implementasi internal buffer di .NET. Alih-alih menghabiskan banyak waktu menganalisis struktur internal, Anda cukup mengembalikan
S_OK
, dan .NET penanganan kesalahan akan melakukan sisanya:
std::int32_t __stdcall ayyxam::hooks::get_clipboard(void* data_object[[maybe_unused]]) {
Ini akan menyembunyikan seluruh buffer dari alat pengawasan ExamCookie tanpa mengganggu fungsionalitas program.
Tangkapan layar
Seperti biasa, orang-orang mengambil implementasi .NET dari fungsi yang diinginkan. Untuk menyiasati fungsi ini, kami bahkan tidak perlu mengubah apa pun dalam kode sebelumnya. Tangkapan layar dikendalikan oleh fungsi
Graphics.CopyFromScreen
.NET. Ini pada dasarnya adalah pembungkus untuk mentransmisikan blok bit, yang memanggil
gdi32!BitBlt
. Seperti dalam gim video untuk memerangi sistem anti-cheat yang mengambil tangkapan layar, kita dapat menggunakan kait BitBlt dan menyembunyikan informasi yang tidak diinginkan sebelum mengambil tangkapan layar.
Situs pembukaan
URL grabber sepenuhnya disalin dari program sebelumnya, jadi sekali lagi kami dapat menggunakan kembali kode kami untuk memintas perlindungan. Dalam
artikel terakhir, kami mendokumentasikan struktur AutomationElement, sebagai akibatnya kait berikut diluncurkan:
std::int32_t __stdcall ayyxam::hooks::get_property_value(void* handle, std::int32_t property_id, void* value) { constexpr auto value_value_id = 0x755D; if (property_id != value_value_id) return ayyxam::hooks::original_get_property_value(handle, property_id, value); auto result = ayyxam::hooks::original_get_property_value(handle, property_id, value); if (result != S_OK)
Penemuan mesin virtual
Deteksi malas mesin virtual dapat dielakkan dengan dua cara: 1) tambalan program yang disiram ke disk; atau 2) pengalihan proses pembuatan proses ke aplikasi dummy. Yang terakhir tampaknya jelas lebih mudah :). Jadi, secara internal,
Process.Start()
memanggil
CreateProcess
, jadi cukup untuk menghubungkan dan mengarahkannya ke aplikasi dummy yang mencetak karakter '0'.
BOOL WINAPI ayyxam::hooks::create_process( LPCWSTR application_name, LPWSTR command_line, LPSECURITY_ATTRIBUTES process_attributes, LPSECURITY_ATTRIBUTES thread_attributes, BOOL inherit_handles, DWORD creation_flags, LPVOID environment, LPCWSTR current_directory, LPSTARTUPINFOW startup_information, LPPROCESS_INFORMATION process_information ) {
Unduh
Seluruh proyek tersedia di
repositori Github . Program ini bekerja dengan menyuntikkan biner x86 ke proses yang sesuai.