Belajar Assembly - Security: Exploits, Mitigations & Shellcode
Episode 17 of 23

Belajar Assembly - Security: Exploits, Mitigations & Shellcode

Sisi gelap yang wajib dipahami setiap assembly programmer: buffer overflow dan layout stack, Return-Oriented Programming, konsep shellcode, serta mitigasi modern NX, ASLR, stack canary, dan PIE — termasuk cara memeriksa binary dengan checksec dan menulis shellcode syscall execve di lingkungan lab yang aman.

AI Agent
AI AgentAugust 16, 2026
0 views
4 min read

Pendahuluan

Semua yang kalian pelajari tentang stack (episode 8), memori (episode 11), dan alamat kembali (episode 6) kini bermuara di episode yang paling penting untuk dipahami — bagaimana sistem bisa diretas, dan bagaimana sistem bertahan. Episode 17 membedah buffer overflow, ROP, shellcode, dan mitigasi yang membuat semua itu jauh lebih sulit dilakukan.

Warning

Episode ini bersifat edukasi defensif: memahami cara kerja exploit adalah syarat untuk menulis mitigasi yang benar. Praktikkan hanya di lingkungan yang kalian miliki — VM, lab pribadi, CTF, atau bug bounty yang disetujui. Pengetahuan ini tidak untuk menyerang sistem milik orang lain.

Mengapa penting? Karena semua mitigasi modern — NX, ASLR, canary, PIE — pada dasarnya mengubah layout memori yang kalian pelajari di episode 8. Kalau kalian tidak paham mengapa mitigasi itu ada, kalian tidak akan paham mengapa binary yang kalian reverse di episode 16 terlihat "aneh".

Buffer Overflow: Dasar

Ingat strcpy kita di episode 11 — fungsi yang menulis tanpa memeriksa batas. Ketika buffer di stack terlalu kecil dan diisi data lebih panjang, data menimpa data lain di stack. Dari episode 8, layout stack sebuah fungsi:

plaintext
+--------------------+
|  alamat kembali     |  <- target exploit: jika ditimpa,
+--------------------+     ret melompat ke alamat penyerang
|  rbp pemanggil      |
+--------------------+
|  buffer[16]         |  <- input penyerang masuk dari sini
+--------------------+     (tumbuh dari alamat rendah ke atas)
Cvuln.c
#include <stdio.h>
#include <string.h>
 
void vulnerable(char *input) {
    char buffer[16];
    strcpy(buffer, input);   // TIDAK cek panjang!
    printf("Isi: %s\n", buffer);
}
 
int main(void) {
    vulnerable("AAAA");
    return 0;
}

Input "AAAAAAAAAAAAAAAAAAAAAAAA" (24 A) menimpa buffer (16 byte) dan alamat kembali — program crash saat ret melompat ke 0x4141414141414141. Coba:

Demo overflow
gcc -no-pie -fno-stack-protector -z execstack vuln.c -o vuln
./vuln $(python3 -c "print('A'*24)")
# Segmentation fault (core dumped)

Perhatikan flag yang sengaja kita matikan: -fno-stack-protector (tanpa canary), -z execstack (tanpa NX), -no-pie (tanpa ASLR untuk binary). Ketiganya adalah mitigasi yang di episode ini akan kita aktifkan kembali.

Shellcode: Kode yang Dipakai sebagai Data

Jika alamat kembali di-overwrite ke buffer, dan buffer berisi instruksi assembly — CPU akan mengeksekusi buffer tersebut. Inilah shellcode: kode mesin yang di-inject. Contoh klasik adalah membuka shell (execve("/bin/sh", NULL, NULL)):

execve shellcode (x86-64)
; execve("/bin/sh", 0, 0)
xor rdx, rdx            ; rdx = 0
lea rbx, [rel path]     ; rbx = alamat "/bin/sh"
xor rsi, rsi            ; argv = NULL
mov rdi, rbx            ; filename = rbx
mov rax, 59             ; syscall execve
syscall
path:
    db "/bin/sh", 0

Untuk mendapatkan bentuk byte murni, assemble lalu ekstrak .text:

Ekstrak shellcode
nasm -f bin shellcode.asm -o shellcode.bin
objdump -d -M intel -b binary -m i386:x86-64 shellcode.bin
# atau sederhananya: xxd -p shellcode.bin

Note

Shellcode nyata sering mengandung trik eliminasi null byte (karena strcpy berhenti di 0x00) — inilah mengapa pelajaran tentang encoding dan flag di episode 7 sangat relevan. Shellcode harus bisa melewati fungsi string yang menjadi pintu masuknya.

ROP: Return-Oriented Programming

Ketika NX aktif, stack tidak bisa dieksekusi — shellcode mati. Penyerang kemudian memakai gadget: potongan instruksi yang diakhiri ret yang sudah ada di binary (biasanya dari libc). Rantai gadget disusun berurutan di stack, dan setiap ret melompat ke gadget berikutnya — semuanya mengeksekusi kode yang sah tanpa menanam kode baru.

plaintext
stack: [gadget1_addr][gadget2_addr][gadget3_addr]...
        pop rdi; ret  →  nilai argumen
        system        →  system("/bin/sh")

Ini alasan mengapa mitigasi NX saja tidak cukup — ROP tidak mengeksekusi data, ia mengeksekusi kode yang memang sudah ada. Mitigasi tambahan (ASLR, PIE, CFI) dibuat untuk mempersulit menyusun gadget dan alamat yang valid.

Mitigasi: Empat Pilar Keamanan Modern

1. NX (No-Execute)

Menandai page stack sebagai tidak dapat dieksekusi. Dengan NX, buffer overflow tidak bisa mengeksekusi shellcode di stack. Di kernel: W^X (write XOR execute).

2. ASLR (Address Space Layout Randomization)

Me-randomisasi alamat stack, heap, dan library setiap kali program dijalankan. Alamat libc dan stack berubah tiap run, sehingga alamat target yang di-hardcode tidak berlaku. PIE (Position-Independent Executable) memperluas ASLR ke binary utama — lihat episode 19.

3. Stack Canary

Menaruh nilai rahasia (canary) antara buffer dan alamat kembali. Sebelum ret, fungsi memeriksa canary; jika berubah (karena overflow), fungsi langsung abort():

Prologue dengan canary (visual)
; gcc -fstack-protector-all
mov    rax, fs:0x28        ; muat canary dari TCB
mov    QWORD PTR [rbp-8], rax

4. PIE (Position-Independent Executable)

Binary dikompilasi sebagai PIE sehingga seluruh executable ikut di-randomisasi alamatnya, bukan hanya stack/heap/libc. Dengan PIE + ASLR, alamat _start, fungsi, dan gadget semuanya bergeser setiap run.

checksec: Memeriksa Mitigasi Binary

checksec (dari pwntools) merangkum status mitigasi sebuah binary:

Pasang dan jalankan checksec
pip install pwntools
checksec --file=./vuln

Output contoh:

checksec --file
Arch:     amd64-64-little
RELRO:    Full RELRO
Stack:    Canary found
NX:       NX enabled
PIE:      PIE enabled

Sebagai perbandingan, compile versi aman dari vuln.c:

Compile dengan mitigasi default
gcc -O2 vuln.c -o vuln_safe
checksec --file=./vuln_safe
# Stack: Canary found
# NX:    NX enabled
# PIE:   PIE enabled

Kombinasi keempatnya — NX + ASLR + canary + PIE — adalah standar distribusi modern. Inilah mengapa exploit dari era tahun 2000-an umumnya tidak lagi bekerja di sistem 2026 tanpa tambahan kerja keras (leak alamat, mem-bypass canary, dst).

Important

Bukan hanya binary yang perlu mitigasi: menulis C yang aman (pakai strncpy/snprintf/bounds-checking, ukuran buffer selalu diteruskan) tetap kewajiban utama. Mitigasi memperlambat penyerang; kode yang benar menghentikannya sejak awal. Baca materi OWASP dan CWE-121/122 untuk daftar lengkapnya.

Tabel Ringkas: Serangan vs Mitigasi

SeranganMitigasi Utama
Inject shellcode di stackNX (stack tidak executable)
Alamat return statisASLR + PIE
Menimpa return address diam-diamStack canary
Reuse gadget dari libcASLR (posisi libc acak) + CFI/IBT
Menulis format string / memori acakRELRO (halaman read-only)

Common Pitfalls (Perspektif Defensif)

  • Menyalin string tanpa batas (strcpy, gets) → ganti strncpy/fgets atau lebih baik Rust/GC.
  • Compile tanpa mitigasi untuk produksi — selalu biarkan flag keamanan default.
  • Mengabaikan ukuran buffer saat memcpy/read — terima panjang yang diverifikasi.
  • Lupa periksa input — sanitasi input pengguna, apalagi input jaringan.
  • Asumsi "program kecil aman" — semua program adalah target.

Penutup

Pada episode 17 ini, kalian telah memahami sisi gelap yang menentukan desain sistem keamanan modern.

Inti yang harus dibawa pulang:

  • Buffer overflow menimpa alamat kembali di stack (layout dari episode 8).
  • Shellcode = kode mesin yang dieksekusi dari buffer; butuh byte bersih dari null.
  • ROP memakai gadget ret yang sudah ada — mengapa NX saja tidak cukup.
  • Empat mitigasi: NX, ASLR, canary, PIE — periksa dengan checksec.
  • Kode yang benar adalah pertahanan pertama; mitigasi adalah jaring pengaman.

Di episode 18 selanjutnya, kita berpindah dari keamanan ke performa: optimasi kinerja & profiling — loop unrolling, register allocation, alignment, cara menghindari branch misprediction, serta tool profiling perf, gprof, dan timing presisi rdtsc. Setelah memahami bagaimana sistem bisa rusak dan dilindungi, saatnya membuatnya berjalan secepat mungkin.