~/tiramisaks
← back to /home

GEMASTIK XIX: Nimbus Manual Recon & SIMD Analysis

GEMASTIK XIX 2026-08-23 Binary Analysis
#GEMASTIK19 #x86_64 #SIMD #AVX #Assembly #Recon

Nimbus v3.1: Catatan Recon Manual dan Pengembangan Exploit

Kategori: Binary Exploitation / Pwn
Target: 15.232.64.175:13341
Artefak: nimbus, libc.so.6
Cakupan: Tantangan CTF Resmi / Terotorisasi
Pendekatan: Analisis mengutamakan cara manual menggunakan file, readelf, objdump, strings, dan GDB. Python 2 tidak diperlukan.


1. Ringkasan Tantangan

Nimbus adalah layanan ELF AMD64 yang di-strip (stripped) yang mengimplementasikan protokol paket berformat prefix-panjang secara khusus. Setiap paket berisi panjang 32-bit little-endian diikuti oleh muatan (payload). Sebelum menerima paket, penangan (handler) memverifikasi panjang dan checksum dari muatan tersebut.

Tujuan dari recon ini adalah untuk membuktikan secara empiris, bukan menebak:

  1. Arsitektur dan format ELF.
  2. Mitigasi biner yang aktif.
  3. Bingkai paket (packet framing) dan urutan byte (byte order).
  4. Rentang panjang paket yang valid.
  5. Algoritma checksum dan nilai targetnya.
  6. Lokasi buffer muatan (payload-buffer).
  7. Jarak (offset) dari buffer ke RIP yang tersimpan (saved RIP).
  8. Entri PLT/GOT yang tersedia.
  9. Gadget ROP yang tersedia beserta efek samping persisnya.
  10. Offset dan identitas dari libc yang disediakan.

Dokumen ini secara sengaja memisahkan fakta yang telah dikonfirmasi, hipotesis kerja, dan item yang masih harus diverifikasi secara lokal.


2. Berkas dan Integritas

Ubah nama file yang diunduh jika diperlukan:

mv "nimbus (this is file not txt).txt" nimbus 2>/dev/null || true
mv "libc.so (3).6.txt" libc.so.6 2>/dev/null || true
chmod +x nimbus
mkdir -p recon

Identifikasi dan buat nilai hash untuk kedua artefak:

file nimbus libc.so.6 | tee recon/00-file.txt
sha256sum nimbus libc.so.6 | tee recon/01-sha256.txt

Hasil hash teramati untuk artefak yang diberikan:

nimbus
9602099e01761d60dadab13d8a5038d82989a10521ae76a954ba956d88b17b16

libc.so.6
8db37cf3f2169f59a0f07ef1fea308c35656668c64c8ff294e1860f4121eb161

Hasil identifikasi file teramati:

nimbus: ELF 64-bit LSB executable, x86-64, dynamically linked,
        interpreter /lib64/ld-linux-x86-64.so.2, stripped

libc.so.6: ELF 64-bit LSB shared object, x86-64, dynamically linked

Karena Nimbus di-strip, nama fungsi internal tidak dapat diandalkan ketersediaannya. Sebagai gantinya, referensi silang (cross-references), panggilan impor (imported calls), string, perilaku stack, dan alur kontrol (control flow) harus digunakan.


3. Recon Header ELF

Kumpulkan header ELF:

readelf -hW nimbus | tee recon/02-elf-header.txt

Bidang (field) penting yang teramati:

Class:       ELF64
Data:        2's complement, little endian
Type:        EXEC
Machine:     Advanced Micro Devices X86-64
Entry point: 0x401320

Interpretasi

  • Biner berbasis arsitektur AMD64.
  • Bidang multi-byte bawaan diperkirakan menggunakan urutan little-endian kecuali program secara eksplisit mengubahnya.
  • Type: EXEC menunjukkan bahwa executable utama bukan PIE (Position-Independent Executable).
  • Alamat statis dalam executable, seperti .text, .plt, .got, dan .rodata, akan tetap stabil saat biner yang sama digunakan.

4. Header Program dan Izin Memori

readelf -lW nimbus | tee recon/03-program-headers.txt
readelf -SW nimbus | tee recon/04-sections.txt
readelf -dW nimbus | tee recon/05-dynamic.txt

Segmen relevan yang teramati meliputi:

LOAD  ... 0x401000 ... R E
LOAD  ... 0x40c000 ... R
LOAD  ... 0x40fdf0 ... RW
GNU_STACK                RW
GNU_RELRO

Kesimpulan Awal Mitigasi

  • Segmen kode eksekusi dapat dibaca dan dieksekusi (R E).
  • Data yang dapat ditulis berada dalam pemetaan RW terpisah.
  • GNU_STACK bernilai RW, bukan RWE, sehingga stack tidak dapat dieksekusi (non-executable).
  • Oleh karena itu, fitur NX (No-Execute) aktif.
  • GNU_RELRO ada, tetapi BIND_NOW harus diperiksa untuk membedakan antara partial RELRO dan full RELRO.

Periksa RELRO secara manual:

readelf -lW nimbus | grep GNU_RELRO
readelf -dW nimbus | grep BIND_NOW

Interpretasi:

GNU_RELRO ada + tidak ada BIND_NOW  -> Partial RELRO
GNU_RELRO ada + ada BIND_NOW        -> Full RELRO

Periksa impor pelindung stack (stack-protector):

readelf -Ws nimbus | grep -E '__stack_chk_fail|__stack_chk_guard'

Hasil kosong adalah bukti bahwa impor pelindung stack kompilator standar tidak ada, namun pembongkaran kode (disassembly) penangan harus tetap diperiksa untuk memastikan ada tidaknya pemeriksaan manual mirip canary.

Jika terpasang, jalankan:

checksec --file=nimbus | tee recon/06-checksec.txt

5. Fungsi Impor, PLT, GOT, dan Relokasi

Daftarkan simbol dinamis yang belum terresolusi:

readelf -Ws nimbus | grep ' UND ' | tee recon/07-imports.txt

Impor relevan yang teramati:

read
write
mmap
munmap
memcpy
memset
strlen
signal
raise
exit
fwrite
fflush

Dump PLT, relokasi dinamis, dan entri terkait GOT:

objdump -d -Mintel --section=.plt nimbus | tee recon/08-plt.txt
objdump -R nimbus | tee recon/09-got.txt
readelf -rW nimbus | tee recon/10-relocations.txt

Catat dari biner Anda sendiri:

read@plt  = __________________
read@got  = __________________
write@plt = __________________
write@got = __________________

Jangan menyalin alamat-alamat ini dari write-up lain. Artefak lokal adalah sumber kebenaran utama.


6. Recon String dan Referensi Silang

Dump string beserta offset berkasnya:

strings -a -t x -n 4 nimbus | tee recon/11-strings.txt

Filter pesan yang berhubungan dengan protokol:

grep -Ei 'nimbus|ready|invalid|length|checksum|ok|error' \
  recon/11-strings.txt | tee recon/12-interesting-strings.txt

String yang teramati:

c1cf INVALID LENGTH
c1df INVALID CHECKSUM
c1f1 OK
c1f5 NIMBUS v3.1
c202 READY

Perintah strings -t x mencetak offset berkas. Jangan langsung menganggapnya sebagai alamat virtual. Verifikasi pemetaan .rodata:

readelf -SW nimbus | grep -E '\.rodata'
objdump -s -j .rodata nimbus | tee recon/13-rodata.txt

Untuk artefak ini, .rodata terbariskan sehingga kandidat yang teramati dipetakan sebagai berikut:

0xc1cf -> 0x40c1cf  INVALID LENGTH
0xc1df -> 0x40c1df  INVALID CHECKSUM
0xc1f1 -> 0x40c1f1  OK
0xc1f5 -> 0x40c1f5  NIMBUS v3.1
0xc202 -> 0x40c202  READY

Buat hasil pembongkaran kode (disassembly) lengkap:

objdump -d -Mintel nimbus > recon/14-disassembly.txt

Lacak referensinya:

grep -n -B8 -A16 -E \
  '40c1cf|40c1df|40c1f1|40c1f5|40c202' \
  recon/14-disassembly.txt \
  | tee recon/15-string-xrefs.txt

Penangan protokol teramati pada alamat:

0x40ad80

Dump hanya rentang yang relevan:

objdump -d -Mintel \
  --start-address=0x40ad80 \
  --stop-address=0x40b070 \
  nimbus | tee recon/16-handler.txt

7. Memulai Sesi GDB Bersih

gdb -q ./nimbus

Konfigurasi GDB yang direkomendasikan:

set pagination off
set confirm off
set disassembly-flavor intel
set print pretty on
set disable-randomization on
info files
x/60i 0x40ad80

Prinsip pentingnya adalah memeriksa argumen tepat sebelum panggilan fungsi impor dan nilai kembalian tepat setelahnya.

Pada arsitektur AMD64 System V, tiga argumen integer atau pointer pertama biasanya dilewatkan melalui:

RDI, RSI, RDX

8. Prolog Penangan dan Tata Letak Stack

Prolog yang teramati:

0x40ad80  endbr64
0x40ad84  push r13
0x40ad86  xor edi, edi
0x40ad88  mov edx, 4
0x40ad8d  push r12
0x40ad8f  push rbp
0x40ad90  push rbx
0x40ad91  sub rsp, 0x48
0x40ad95  lea rsi, [rsp+0xc]

Saat masuk ke penangan:

entry_rsp + 0x00 = alamat kembalian tersimpan (saved return address)

Empat perintah push mengkonsumsi:

4 * 8 = 0x20 byte

Alokasi lokal mengkonsumsi tambahan:

0x48 byte

Setelah prolog:

saved RIP = current_rsp + 0x20 + 0x48
          = current_rsp + 0x68

Kemudian, buffer muatan dibentuk dengan:

lea rbx, [rsp+0x10]

Oleh karena itu:

buffer    = current_rsp + 0x10
saved RIP = current_rsp + 0x68

Kalkulasi offset statis:

0x68 - 0x10 = 0x58 = 88 byte

Koreksi Penting

Hasil 0x38 atau 56 byte akan mengabaikan empat perintah push register tersimpan. Kandidat statis yang benar adalah 88 byte, tetapi harus tetap diverifikasi secara dinamis di GDB.


9. Membuat Paket Penguji Tanpa Python

Buat paket minimal dengan panjang 1 dan byte muatan 0x5a:

printf '\x01\x00\x00\x00\x5a' > packet-minimal.bin
hexdump -C packet-minimal.bin

Byte yang diharapkan:

01 00 00 00 5a

Buat penguji dengan panjang tidak valid:

printf '\x00\x00\x00\x00' > packet-zero.bin
printf '\x01\x08\x00\x00' > packet-too-large.bin

Header kedua adalah 0x801 dalam format little-endian.

Buat paket dengan checksum tidak valid:

printf '\x01\x00\x00\x00\x41' > packet-bad-checksum.bin

Buat paket dua-byte dengan checksum valid:

printf '\x02\x00\x00\x00\x41\x1b' > packet-two-byte.bin

Karena:

0x41 XOR 0x1b = 0x5a

10. Membuktikan Parsing Header di GDB

Set breakpoint di awal masuk penangan dan tepat setelah pemanggilan read pertama:

break *0x40ad80
break *0x40ada7
run < packet-minimal.bin

Saat masuk penangan:

info registers rip rsp
x/16gx $rsp

Lanjutkan:

continue

Pada 0x40ada7:

info registers rax rsp
x/wx $rsp+0xc

Pengamatan yang diharapkan:

RAX = 4
[rsp+0xc] = 1

Panggilan pertama konsisten dengan:

read(0, &length, 4);

Langkah tunggal (single step) pemuatan ke dalam r12d:

x/5i $rip
si
info registers r12

Hasil yang diharapkan:

R12 = 1

Ini membuktikan bahwa header empat-byte digunakan langsung sebagai nilai panjang 32-bit.


11. Membuktikan Rentang Panjang Paket

Validasi yang teramati:

lea eax, [r12-1]
cmp eax, 0x7ff
ja invalid_length

Karena ja adalah pembandingan unsigned (tanpa tanda), nilai yang diterima memenuhi:

length - 1 <= 0x7ff

Oleh karena itu:

1 <= length <= 0x800

Pengujian perilaku manual:

./nimbus < packet-zero.bin
./nimbus < packet-too-large.bin

Keduanya harus masuk ke alur INVALID LENGTH.


12. Membuktikan Pembacaan Muatan (Payload Reading)

Gunakan breakpoint di sekitar pemanggilan read kedua:

delete breakpoints
break *0x40adce
break *0x40adf1
break *0x40adf6
run < packet-minimal.bin

Pada 0x40adce, periksa dan langkah-tunggal kalkulasi alamat buffer:

x/12i $rip
si
info registers rbx rsp
p/x $rbx
p/x $rsp+0x10
p/x $rbx-$rsp

Hasil yang diharapkan:

RBX - RSP = 0x10

Lanjutkan sampai tepat sebelum pemanggilan fungsi:

continue
info registers rdi rsi rdx r12 r13 rbx

Keadaan panggilan yang diharapkan:

RDI = 0
RSI = RBX
RDX = panjang paket

Lanjutkan melewati panggilan fungsi:

continue
info registers rax rbx rsp
x/16bx $rbx

Untuk penguji minimal:

RAX = 1
[RBX] = 0x5a

Dengan demikian struktur paket dikonfirmasi sebagai:

uint32_t length_le;
uint8_t payload[length];

Catatan Pembacaan Singkat (Short-read Caveat)

Penangan tampaknya melakukan satu panggilan read saja untuk panjang muatan yang diminta. Satu panggilan read tidak secara otomatis membuktikan bahwa seluruh jumlah byte yang diminta telah tiba, sehingga perilaku jaringan harus diuji dengan cermat. Kirim header dan muatan secara bersamaan saat menguji layanan jarak jauh (remote service).


13. Membuktikan Offset Saved-RIP

Tepat setelah pembacaan muatan:

p/x $rsp
p/x $rbx
p/x $rsp+0x68
p/x $rbx+0x58
p/x ($rsp+0x68)-$rbx

Selisih yang diharapkan:

0x58

Baca alamat kembalian tersimpan (saved return address) dalam dua cara yang setara:

x/gx $rsp+0x68
x/gx $rbx+0x58

Kedua ekspresi tersebut harus menampilkan qword yang sama.

Tata letak statis dan dinamis yang dikonfirmasi:

awal buffer = rsp + 0x10
saved RIP   = rsp + 0x68
offset      = 0x58 = 88 byte

14. Membuktikan Checksum

Set breakpoint tepat sebelum perbandingan checksum akhir:

delete breakpoints
break *0x40afee
run < packet-minimal.bin

Periksa akumulator:

info registers rax rdx
x/8i $rip

Untuk muatan 0x5a, hasil yang diharapkan:

RAX = 0x5a

Perbandingannya adalah:

cmp rax, 0x5a
jne invalid_checksum

Uji paket buruk:

run < packet-bad-checksum.bin
info registers rax
si
si
x/i $rip

Untuk byte muatan 0x41, akumulator harus bernilai 0x41, dan alur kontrol harus masuk ke alur checksum tidak valid.

Uji paket dua-byte yang valid di luar GDB:

./nimbus < packet-two-byte.bin

Respon yang diharapkan:

OK

Aturan yang dikonfirmasi:

XOR(payload[0], payload[1], ..., payload[length-1]) == 0x5a

Untuk muatan yang berisi satu byte penyesuaian (adjustment byte) cadangan yang diawali nilai nol:

adjustment = current_xor XOR 0x5a

15. Membuktikan Alur Sukses

Set breakpoint sebelum pemanggilan write pada alur sukses:

delete breakpoints
break *0x40b005
run < packet-minimal.bin

Periksa:

info registers rdi rsi rdx
x/s $rsi

Hasil yang diharapkan:

RDI = 1
RSI -> "OK\n"
RDX = 3

Perilaku yang setara:

write(1, "OK\n", 3);

16. Recon Gadget ROP

Jika tersedia:

ROPgadget --binary nimbus | tee recon/17-gadgets.txt

Filter gadget umum:

grep -E \
  'pop rdi ; ret$|pop rsi ; ret$|pop rdx ; ret$|leave ; ret$|ret$' \
  recon/17-gadgets.txt

Hasil tingkat tinggi yang teramati:

pop rdi; ret : tersedia
pop rsi; ret : tersedia
pop rdx; ret : tidak ditemukan

Setiap gadget yang dipilih harus diverifikasi secara langsung:

objdump -d -Mintel \
  --start-address=GADGET_ADDRESS \
  --stop-address=END_ADDRESS \
  nimbus

Jangan pernah mengasumsikan keberadaan pop rdx; ret langsung. Asumsi sebelumnya menghasilkan kegagalan NoneType saat pencarian gadget karena biner tidak memuat gadget tersebut.


17. Gadget RDX Kompleks

Alternatif yang dapat digunakan ditemukan pada alamat:

0x40a460

Verifikasi gadget tersebut:

objdump -d -Mintel \
  --start-address=0x40a450 \
  --stop-address=0x40a480 \
  nimbus

Instruksi teramati:

mov rdx, QWORD PTR [rsp+0x48]
add rsp, 0x58
pop rbx
pop rbp
pop r12
pop r13
pop r14
pop r15
ret

Tata letak stack presisi saat masuk ke gadget:

rsp awal + 0x00 : qword 0
rsp awal + 0x08 : qword 1
rsp awal + 0x10 : qword 2
rsp awal + 0x18 : qword 3
rsp awal + 0x20 : qword 4
rsp awal + 0x28 : qword 5
rsp awal + 0x30 : qword 6
rsp awal + 0x38 : qword 7
rsp awal + 0x40 : qword 8
rsp awal + 0x48 : qword 9  -> dimuat ke RDX
rsp awal + 0x50 : qword 10 -> dilewati oleh add rsp,0x58
rsp awal + 0x58 : qword 11 -> RBX
rsp awal + 0x60 : qword 12 -> RBP
rsp awal + 0x68 : qword 13 -> R12
rsp awal + 0x70 : qword 14 -> R13
rsp awal + 0x78 : qword 15 -> R14
rsp awal + 0x80 : qword 16 -> R15
rsp awal + 0x88 : qword 17 -> RIP kelanjutan

Efek penting:

RDX            = [RSP + 0x48] awal
RIP kelanjutan = [RSP + 0x88] awal
Register rusak = RBX, RBP, R12, R13, R14, R15

18. Membuktikan Gadget Kompleks di GDB

Jalankan proses:

starti
set $rsp = $rsp - 0x200
set $test_rsp = $rsp

Tempatkan nilai RDX yang mudah dikenali:

set {unsigned long long}($test_rsp+0x48) = 0x1122334455667788

Isi enam slot pop:

set {unsigned long long}($test_rsp+0x58) = 0x1111111111111111
set {unsigned long long}($test_rsp+0x60) = 0x2222222222222222
set {unsigned long long}($test_rsp+0x68) = 0x3333333333333333
set {unsigned long long}($test_rsp+0x70) = 0x4444444444444444
set {unsigned long long}($test_rsp+0x78) = 0x5555555555555555
set {unsigned long long}($test_rsp+0x80) = 0x6666666666666666

Gunakan alamat eksekusi yang diketahui sebagai kelanjutan terkontrol dan pasang breakpoint di sana:

set {unsigned long long}($test_rsp+0x88) = 0x40ad80
break *0x40ad80
set $rip = 0x40a460

Periksa dan lakukan langkah-tunggal:

x/20gx $rsp
info registers rsp rdx
si
info registers rdx

Hasil yang diharapkan:

RDX = 0x1122334455667788

Lanjutkan instruksi demi instruksi dan periksa $rsp, rbx, rbp, r12 hingga r15. Sebelum ret terakhir, $rsp harus menunjuk ke qword pada $test_rsp+0x88 awal.


19. Recon Libc

Kumpulkan informasi identitas dan pemetaan:

file libc.so.6
readelf -hW libc.so.6 | tee recon/18-libc-header.txt
readelf -lW libc.so.6 | tee recon/19-libc-segments.txt
readelf -n libc.so.6 | tee recon/20-libc-notes.txt

Cari Build ID:

readelf -n libc.so.6 | grep -A2 'Build ID'

Cari string versi GNU C Library:

strings -a libc.so.6 | grep -m1 'GNU C Library'

Cari offset simbol dinamis:

readelf -Ws libc.so.6 \
  | grep -E ' read@@| write@@| system@@' \
  | tee recon/21-libc-symbols.txt

Cari /bin/sh sebagai offset berkas:

grep -aob '/bin/sh' libc.so.6

Jangan secara otomatis menganggap offset berkas sebagai offset virtual. Cocokkan dengan segmen LOAD yang sesuai dari readelf -lW libc.so.6.

Catat:

Build ID      = __________________
read offset   = __________________
write offset  = __________________
system offset = __________________
/bin/sh vaddr = __________________

20. Rencana Validasi Kebocoran Libc (Libc-Leak Validation Plan)

Jika alamat runtime dari read diperoleh:

libc_base = leaked_read - read_offset

Pemeriksaan kelayakan (sanity check):

libc_base mod 0x1000 == 0

Validasi yang lebih kuat membutuhkan bocoran simbol kedua:

leaked_write - leaked_read

dan memeriksa apakah nilainya sama dengan:

write_offset - read_offset

Jika selisih tidak cocok, selidiki:

  • Artefak libc yang salah.
  • Alamat GOT yang salah.
  • Desinkronisasi stream di sekitar OK\n.
  • Panjang bocoran yang salah.
  • Urutan byte (byte order) yang salah.
  • Kegagalan pengaturan register.
  • Efek samping dari gadget kompleks.

21. Daftar Periksa Fakta Terkonfirmasi

Biner

  • ELF64 AMD64.
  • Little-endian.
  • Terhubung secara dinamis (dynamically linked).
  • Stripped.
  • Executable utama non-PIE.
  • Stack tidak dapat dieksekusi (non-executable).
  • Titik masuk (entry point) adalah 0x401320.

Protokol

  • Banner berisi NIMBUS v3.1 dan READY.
  • Header paket berupa panjang empat-byte.
  • Panjang diinterpretasikan secara little-endian.
  • Panjang yang diterima adalah 1..0x800 inklusif.
  • Muatan (payload) berada tepat setelah panjang.
  • Checksum valid adalah hasil XOR seluruh byte muatan sama dengan 0x5a.
  • Respon sukses adalah OK\n.
  • Alur tidak valid meliputi INVALID LENGTH dan INVALID CHECKSUM.

Stack

  • Alamat penangan adalah 0x40ad80.
  • Buffer muatan dimulai pada rsp+0x10 setelah prolog.
  • RIP tersimpan berada pada rsp+0x68 setelah prolog.
  • Jarak offset adalah 0x58, atau 88 byte.

Gadget ROP

  • Gadget pop rdx; ret langsung tidak ada.
  • Pemuat RDX kompleks ada di 0x40a460.
  • Sumber RDX berasal dari [rsp+0x48] awal.
  • Kelanjutan RIP dari [rsp+0x88] awal.
  • Gadget kompleks merusak enam register tambahan.

Masih harus diverifikasi secara lokal

  • Status RELRO presisi dari output lokal.
  • Alamat PLT/GOT presisi.
  • Alamat gadget sederhana presisi.
  • Build ID libc dan offset simbol.
  • Pemeriksaan konsistensi dua simbol libc.
  • Status rantai (chain) lengkap pada pemanggilan target di GDB.

22. Modus Kegagalan Umum

22.1 Melupakan push register tersimpan

Kalkulasi yang salah:

0x48 - 0x10 = 0x38

Kalkulasi yang benar:

(4 * 8) + 0x48 - 0x10
= 0x20 + 0x48 - 0x10
= 0x58
= 88

22.2 Mengasumsikan gadget ada

Pencari gadget (gadget finder) bisa tidak mengembalikan hasil. Jangan pernah mengacu (dereference) bidang alamat sebelum memeriksa hasilnya.

22.3 Menganggap offset berkas sebagai alamat virtual

strings -t x dan grep -aob melaporkan offset berkas. Konversikan hanya setelah berkonsultasi dengan seksi ELF atau header program.

22.4 Mengabaikan efek samping gadget

Gadget yang memuat rdx juga dapat menggeser rsp, melakukan pop beberapa register, dan mengkonsumsi bingkai stack yang besar. Modelkan setiap instruksi dan setiap qword.

22.5 Membaca bocoran pada posisi stream yang salah

Jika program menulis OK\n sebelum alamat yang bocor, konsumsi marker tersebut terlebih dahulu. Jika tidak, byte banner ASCII dapat salah diartikan sebagai bocoran.

22.6 Pangkalan ulang (rebase) libc dua kali

Saat menggunakan kerangka kerja analisis di kemudian hari, pastikan apakah alamat simbol berupa offset atau alamat runtime yang sudah di-rebase.

22.7 Percaya pada satu bocoran saja

Base yang terbariskan halaman (page-aligned) adalah pemeriksaan kelayakan yang berguna, tetapi simbol kedua memberikan bukti lebih kuat bahwa libc yang disediakan cocok dengan layanan jarak jauh.


23. Struktur Direktori Recon yang Disarankan

recon/
├── 00-file.txt
├── 01-sha256.txt
├── 02-elf-header.txt
├── 03-program-headers.txt
├── 04-sections.txt
├── 05-dynamic.txt
├── 06-checksec.txt
├── 07-imports.txt
├── 08-plt.txt
├── 09-got.txt
├── 10-relocations.txt
├── 11-strings.txt
├── 12-interesting-strings.txt
├── 13-rodata.txt
├── 14-disassembly.txt
├── 15-string-xrefs.txt
├── 16-handler.txt
├── 17-gadgets.txt
├── 18-libc-header.txt
├── 19-libc-segments.txt
├── 20-libc-notes.txt
└── 21-libc-symbols.txt

Arsipkan bukti-bukti tersebut:

tar -czf nimbus-recon.tar.gz recon

24. Referensi Serupa dengan Tantangan Ini

Tidak ada write-up publik yang diverifikasi untuk artefak Nimbus v3.1 ini secara persis selama riset. Referensi berikut mirip dalam hal teknik atau alur kerja, bukan klaim bahwa mereka adalah tantangan yang sama.

Kemiripan teknik terdekat

  1. ForeverCTF ret2libc write-up
    Kemiripan: AMD64, NX, non-PIE, tanpa stack canary, bocoran GOT/PLT, kalkulasi libc-base, dan rantai ret2libc tahap kedua.

  2. CTF Recipes: Leaking libc
    Kemiripan: mendemonstrasikan pendekatan umum ret2plt untuk membocorkan alamat fungsi libc melalui entri GOT, menghitung base libc, dan menemukan simbol libc lainnya.

  3. HackTricks: Leaking libc address with ROP
    Kemiripan: penemuan offset, pemilihan gadget, bocoran PLT/GOT, identifikasi libc, dan konstruksi tahap ROP selanjutnya.

  4. Practical CTF: ret2libc
    Kemiripan: menjelaskan penggunaan stack overflow untuk memanggil system("/bin/sh"), menangani libc yang diberikan atau diidentifikasi, dan memperhitungkan ASLR dengan bocoran.

  5. Practical CTF: Return-Oriented Programming
    Kemiripan: menjelaskan ROP gadget berantai, pengaturan register, panggilan fungsi, dan alternatif saat gadget pop sederhana tidak tersedia.

  6. CTF101: Return-Oriented Programming
    Kemiripan: mendemonstrasikan penggunaan kontrol stack dan urutan instruksi pendek untuk memanggil kode yang ada saat tidak ada fungsi pemanggil shell secara langsung.

Metodologi recon dan overflow serupa

  1. Binary Exploitation Writeups Collection
    Kemiripan: alur kerja terstruktur mencakup reconnaissance, proteksi biner, disassembly, penentuan offset, ROP, dan ret2libc.

  2. CTF Pwn Crash Course
    Kemiripan: alur kerja berorientasi alat menggunakan checksec, GDB, objdump, readelf, pola siklik, pencarian ROP gadget, dan pola pwn CTF umum.

  3. Basic Stack Buffer Overflow Write-up
    Kemiripan: dimulai dengan file dan checksec, memeriksa proteksi, menentukan offset overflow, dan bertransisi dari recon ke pengambilalihan RIP terkontrol.

  4. RE:HACK: How to Pwn Buffer Overflow
    Kemiripan: penjelasan edukatif tentang bagaimana input yang tidak diperiksa melampaui buffer stack dan merusak status stack di sekitarnya.

Dokumentasi alat resmi

  1. Dokumentasi GNU GDB
    Referensi utama untuk breakpoint, stepping, inspeksi register, dan pemeriksaan memori.

  2. Dokumentasi GNU readelf
    Referensi utama untuk header ELF, seksi, header program, simbol, relokasi, notes, dan entri dinamis.

  3. Manual objdump
    Referensi untuk disassembly, tampilan relokasi, dump seksi, sintaks Intel, dan pemfilteran rentang alamat.

  4. Dokumentasi ROP Pwntools
    Referensi untuk objek ROP, pencarian gadget, pembuatan stack, padding, dan gadget multi-pop. Gunakan setelah perilaku manual diverifikasi.


25. Kesimpulan Recon Akhir

Nimbus menggunakan antarmuka paket khusus daripada prompt berbasis baris konvensional. Layanan ini pertama-tama membaca panjang empat-byte little-endian dan kemudian membaca byte muatan sebanyak itu. Layanan menerima panjang dari 1 hingga 0x800 dan mensyaratkan hasil XOR dari semua byte muatan bernilai 0x5a.

Penangan menyimpan muatan pada rsp+0x10 setelah prolog. Karena pertama-tama melakukan push empat register tersimpan dan mengalokasikan 0x48 byte lokal, alamat kembalian tersimpan terletak pada rsp+0x68 setelah prolog. Jarak muatan ke RIP tersimpan adalah 0x58, atau 88 byte.

Fitur NX membuat kode stack yang diinjeksikan tidak cocok, sehingga penggunaan ulang kode (code reuse) adalah arah yang alami. Executable memiliki impor I/O yang berguna, tetapi tidak memiliki gadget pop rdx; ret langsung. Gadget kompleks di 0x40a460 dapat memuat RDX dari stack, tetapi juga mengkonsumsi bingkai stack yang besar dan merusak enam register. Setiap rantai lanjutan harus diverifikasi qword demi qword di GDB.

Pekerjaan yang tersisa bersifat mekanis dan berbasis bukti: catat alamat GOT/PLT presisi, verifikasi gadget sederhana, identifikasi libc yang disediakan, buktikan register status panggilan tepat sebelum bocoran, validasi libc dengan simbol kedua, dan baru kemudian buat rantai ROP akhir.