Lompat ke konten
dokumentasi.id
Commit 89c41b0
v1
Star3,2 rb

Kamu membaca versi lama. Halaman ini hanya bisa dibaca.

3.2

Aset In-scope, Bruteforce, dan Wordlist

Dua katalog program publik adalah titik awal termurah untuk menyusun daftar target. Halaman ini menunjukkan cara menarik aset in-scope dari keduanya dengan jq, cara memakai hasilnya sebagai bahan bruteforce host dengan ffuf dan resolver DNS, lalu cara membentuk wordlist kustom dari URL historis dan dari respons HTTP. Semua perintah memakai placeholder HOST, HOSTS.txt, FILE.txt, dan OUT.txt yang definisinya ada di README.md:10-15; aturan pemakaiannya dibahas di Placeholder dan Konvensi Penulisan One-liner.

Dari katalog program ke daftar target

chaos-bugbounty-list menyimpan satu berkas untuk semua program, sedangkan bounty-targets-data memecah data per platform. Keduanya berakhir di daftar yang sama bentuknya: satu baris per aset.

graph LR
  chaos["chaos-bugbounty-list.json"] --> qc["jq: programs, domains, to_entries"]
  qc --> hosts["Daftar host in-scope"]
  h1["hackerone_data.json"] --> qb["jq: targets.in_scope, @tsv"]
  bc["bugcrowd_data.json"] --> qb
  ig["intigriti_data.json"] --> qb
  ywh["yeswehack_data.json"] --> qb
  hp["hackenproof_data.json"] --> qb
  fd["federacy_data.json"] --> qb
  qb --> tsv["Pasangan identifier dan tipe (TSV)"]
  hosts --> feed["Daftar target untuk bruteforce"]
  tsv --> feed
  style chaos fill:#336791,color:#fff
  style h1 fill:#336791,color:#fff
  style bc fill:#336791,color:#fff
  style ig fill:#336791,color:#fff
  style ywh fill:#336791,color:#fff
  style hp fill:#336791,color:#fff
  style fd fill:#336791,color:#fff
  style qc fill:#8b5cf6,color:#fff
  style qb fill:#8b5cf6,color:#fff
  style tsv fill:#8b5cf6,color:#fff
  style hosts fill:#2d7d46,color:#fff
  style feed fill:#2d7d46,color:#fff
%% fig: Dua katalog program menuju satu daftar target
%% desc: chaos-bugbounty-list dan enam berkas bounty-targets-data diolah dengan jq lalu menyatu sebagai bahan bruteforce host.
Fig. 1: Dua katalog program menuju satu daftar targetchaos-bugbounty-list dan enam berkas bounty-targets-data diolah dengan jq lalu menyatu sebagai bahan bruteforce host.

Untuk chaos-bugbounty-list, satu curl ke berkas JSON di repository public-bugbounty-programs sudah cukup. Ekspresi jq mengambil nilai dari setiap entri domains sehingga keluarannya hanya satu kolom host, tanpa informasi tipe aset karena kuncinya dibuang oleh .[].value (README.md:284-289).

Untuk bounty-targets-data, setiap platform punya berkas sendiri dan setiap berkas memakai nama field yang berbeda. Empat platform memakai target dan type; HackerOne memakai asset_identifier dan asset_type; Intigriti memakai endpoint dan type; HackenProof menambahkan instruction sebagai kolom ketiga (README.md:291-298, README.md:300-328).

PlatformBerkasField identifierField tipe
HackerOnehackerone_data.jsonasset_identifierasset_type
BugCrowdbugcrowd_data.jsontargettype
Intigritiintigriti_data.jsonendpointtype
YesWeHackyeswehack_data.jsontargettype
HackenProofhackenproof_data.jsontargettype, instruction
Federacyfederacy_data.jsontargettype

Semua varian bounty-targets-data mengakhiri pipeline dengan @tsv, sehingga keluarannya berupa kolom yang dipisah tab dan bisa dipotong dengan cut atau awk. Karena tipe aset ikut sebagai kolom kedua, penyaringan jenis aset dilakukan setelah dump, bukan di dalam jq.

⚠️ Perhatikan bentuk URL sumbernya. Varian HackerOne memakai path blob/ dengan query ?raw=true, sedangkan lima platform lain memakai path raw/ langsung (README.md:291-298, README.md:300-328). Kalau query raw itu hilang, curl mengunduh halaman HTML GitHub dan jq langsung gagal mem-parse.

Bruteforce host dengan wordlist

Bruteforce di sini berarti menebak nama host dari kata-kata di FILE.txt. Ada tiga varian yang tersedia, dan ketiganya berbeda pada tempat FUZZ atau $sub disisipkan.

VarianInti perintahPosisi tebakanPenapis keluaran
Subdomain lewat HTTPffuf -u https://FUZZ.HOST -w FILE.txt -vlabel subdomain`grep "
Virtual host dan panel adminffuf -c -u URL -H "Host: FUZZ" -w FILE.txtheader Hosttidak ada, keluaran ffuf apa adanya
Subdomain lewat DNSwhile read sub; do echo "https://dns.google.com/resolve?name=$sub.HOST&type=A&cd=true" ... done < FILE.txtlabel subdomain pada query DNSgrep "name" lalu regex hostname dan sort -u

Varian pertama membaca FILE.txt sebagai daftar kata dan menaruh setiap kata di depan HOST. Flag -v membuat ffuf mencetak tabel, lalu grep "| URL |" menyisakan baris yang memuat kolom URL dan awk '{print $4}' mengambil kolom keempat saja (README.md:217-222).

Varian kedua memindahkan tebakan ke header Host, jadi URL tujuan tetap satu sedangkan nama virtual host yang berubah-ubah. Pola ini dipakai untuk mencari hidden server dan panel admin yang tidak muncul di DNS (README.md:358-363).

Varian ketiga tidak memakai ffuf. Setiap kata dari FILE.txt dikirim sebagai name=$sub.HOST ke resolver JSON dns.google.com, dijalankan paralel dengan parallel -j100, lalu hasilnya disaring jq dan regex sampai tersisa hostname yang berakhiran HOST (README.md:182-187). Varian ini bekerja tanpa koneksi HTTP ke target, sehingga tetap berguna ketika port 80 dan 443 tertutup.

⚠️ Pada varian DNS, -j100 mengirim 100 query serentak ke resolver publik. Turunkan jumlah itu atau pakai resolver sendiri kalau kuota harian jadi masalah; kegagalan resolver akan tampak sebagai keluaran kosong, bukan sebagai error.

Menyusun wordlist kustom

Wordlist kustom lebih baik daripada wordlist umum karena diturunkan dari URL yang benar-benar pernah dilihat target. Ada dua jalur penyusunan, dan keduanya bisa dijalankan berurutan.

graph LR
  subgraph dari_url["dari URL historis"]
    gau["gau HOST"] --> keys["unfurl -u keys"]
    gau --> paths["unfurl -u paths"]
    keys --> f1["FILE1.txt"]
    paths --> flat["sed pecah path per baris, sort -u"]
    flat --> f1
    f1 --> strip["sed -i buang .css .png .jpeg .jpg .svg .gif .wolf .bmp"]
  end
  subgraph dari_respons["dari respons HTTP"]
    hosts["HOSTS.txt"] --> probe["httprobe"]
    probe --> cur["xargs curl"]
    cur --> tok["tok"]
    tok --> lower["tr lower + sort -u"]
  end
  strip --> wl["Wordlist kustom"]
  lower --> wl
  style gau fill:#8b5cf6,color:#fff
  style keys fill:#8b5cf6,color:#fff
  style paths fill:#8b5cf6,color:#fff
  style hosts fill:#336791,color:#fff
  style strip fill:#f59e0b,color:#000
  style wl fill:#2d7d46,color:#fff
%% fig: Dua jalur penyusunan wordlist kustom
%% desc: Jalur pertama memecah key dan path dari URL gau, jalur kedua menormalkan token dari respons httprobe dan curl.
Fig. 2: Dua jalur penyusunan wordlist kustomJalur pertama memecah key dan path dari URL gau, jalur kedua menormalkan token dari respons httprobe dan curl.

Jalur pertama memakai gau HOST dua kali: sekali untuk unfurl -u keys yang mengambil nama parameter, sekali untuk unfurl -u paths yang mengambil path. Keluaran path dipecah per / dengan sed, diurutkan unik, lalu digabung ke FILE1.txt. Akhir pipeline membuang ekstensi aset statis .css, .png, .jpeg, .jpg, .svg, .gif, .wolf, dan .bmp langsung di dalam berkas (README.md:245-254).

Jalur kedua berangkat dari HOSTS.txt: httprobe menyaring host yang hidup, curl mengambil isinya, tok memecahnya menjadi token, lalu tr '[:upper:]' '[:lower:]' dan sort -u menormalkan hasil sebelum ditulis ke FILE.txt (README.md:245-254).

⚠️ Langkah terakhir jalur pertama memakai sed -i pada FILE1.txt, jadi berkas itu ditimpa dan tidak ada salinan cadangan. Perintah rm FILE2.txt juga digabung ke pipeline yang sama dengan sed -i, padahal keluaran rm tidak pernah dibaca sed; sed bekerja langsung pada FILE1.txt (README.md:245-254). Simpan salinan FILE1.txt sebelum menjalankannya.

Daftar host hasil dua bagian di atas dipakai lagi di Pemetaan URL, Berkas JavaScript, dan Endpoint. Untuk daftar subdomain pasif yang lebih dulu dikumpulkan tanpa bruteforce, lihat Enumerasi Subdomain dan Deteksi Takeover.