Cross-site Scripting (XSS)

Cross-site Scripting (XSS) ก็เป็นอีกเทคนิคที่ แฮกเกอร์ชอบใช้เป็นประจำ โดยแฮกเกอร์ใช้ web application เพื่อส่ง client-side script เช่น Javascript เป็นต้นไปทำงานที่เว็บบราวเซอร์ของเหยื่อเพื่อทำงานตามที่แฮกเกอร์ ต้องการ

ช่องโหว่ที่สามารถทำให้เกิดการ XSS ได้ก็เนื่องมาจาก web application รับข้อมูลเข้ามาจากผู้ใช้ ซึ่งโปรแกรมเมอร์ที่พัฒนา web application ดังกล่าวไม่ได้ทำการตรวจสอบความถูกต้องของข้อมูลนั้น แล้วนำข้อมูลดังกล่าวไปแสดงบนเว็บเพจ

แม้ว่าแฮกเกอร์ไม่สามารถใช้ XSS ในการทำอันตรายเครื่องคอมพิวเตอร์ที่ตกเป็นเหยื่อย เช่นสั่งฟอร์แมต Harddisk หรือทำ remote conrol ได้เพราะว่ากลไกการทำงานของ client-side script ไม่อนุญาตให้ทำงานดังกล่าว แต่ความน่ากลัวของ XSS มีอยู่ไม่น้อยเนื่องจาก XSS ยังเป็นช่องทางที่ทำให้ Hacker สามาถ ขโมย Cookie ซึ่งอาจจะทำให้ hacker ใช้ cookie เพื่อใช้ในการแย่ง session ของเหยื่อได้ หรือ แก้ข้อมูลของ form ที่ใช้ในการกรอก username/password ให้ส่งไปยังเครื่องของ hacker ก่อนแล้วค่อยส่งไปยังเว็บไซต์จริง ๆ หรือแก้ไขข้อมูลที่แสดงอยู่บนเว็บเพจเพื่อหลอกให้เหยื่อหลงเชื่อแล้วทำให้ เหยื่อทำอะไรบางอย่างที่เป็นผลดีต่อแฮกเกอร

ซึ่งวิธีการโจมตีแบบ XSS อาจจะแบ่งได้เป็น 2 ประเภทคือ

  1. Stored XSS: แฮกเกอร์จะฝัง javascript code ไว้ในเว็บบอร์ด, คอมเม้นต์, ฯลฯ ซึ่งเมื่อเหยื่อเข้ามาดูหน้าเพจดังกล่าวก็จะถูกโจมตีด้วย XSS
  2. Reflected XSS: แฮกเกอร์จะฝัง script ไว้ใน CGI Parameters ของ URL แล้วส่ง link ดังกล่าวไปให้เหยื่อซึ่งเมื่อเหยื่อเปิดลิงก์ดังกล่าวก็จะถูกโจมตีด้วย XSS

เรามาลองศึกษาดูกันดีกว่าว่า Cross-site Scripting ทำกันอย่างไร ซึ่งผมจะทำโจมตีแบบ Reflected XSS โดยเว็บเป้าหมายที่เราจะทำการทดลองในวันนี้ก็คือ www.sanook.com

หมายเหตุ: ทำการทดลอง ณ วันที่ 4 พฤศจิกายน 2550 ซึ่งหลังจากที่พบช่องโหว่ผมก็ได้แจ้ง sanook.com ให้แก้ไขช่องโหว่นี้แล้ว ทำให้ผลลัพธ์ที่ได้จากการกดลิงก์ต่าง ๆ ด้านล่างไม่ตรงกับรูปภาพที่แสดง

เครื่องมือที่ต้องใช้

  1. Web Browser (IE, Firefox, etc)
  2. Web Scarab อาจจะใช้โปรแกรมอื่นในการแปลง URL encode/decode แทนได้

ขั้นตอนการทดลอง

ขั้นที่ 1: ทดลองใส่ username/password ที่ไม่น่าจะมีเพื่อดู ข้อความแจ้งข้อผิดพลาดขั้นที่ 1: ทดลองใส่ username/password ที่ไม่น่าจะมีเพื่อดู ข้อความแจ้งข้อผิดพลาด ขั้นที่ 2: พบว่าข้อความแจ้งข้อผิดพลาดดังกล่าวใช้ Alert Box ในการแสดงผลขั้นที่ 2: พบว่าข้อความแจ้งข้อผิดพลาดดังกล่าวใช้ Alert Box ในการแสดงผล

โดย URL ด้านล่างก็ืคือ URL ที่ใช้แสดงข้อความผิดพลาดซึ่งมีการส่งข้อมูล แบบ url encode ด้วย

http://www.sanook.com/?smistatuscode=0&smierrormessage=%E0%B9%84%E0%B8%A1%E0%B9%88
%E0%B8%9E%E0%B8%9A%E0%B8%AD%E0%B8%B5%E0%B9%80%E0%B8%A1%E0%B8%A5%E0%B9
%8C%E0%B8%99%E0%B8%B5%E0%B9%89%E0%B9%83%E0%B8%99%E0%B8%A3%E0%B8%B0%E0%
B8%9A%E0%B8%9A&email=hack%40hack.com

เมื่อสังเกตุดี ๆ ก็พบตัวแปรที่น่าสนใจคือ "smierrormessage" ซึ่งเราก็สามารถ decode ข้อมูลดังกล่าว ได้ง่าย ๆ ด้วย Web Scarab ซึ่งเป็นเครื่องมือที่ใช้ในการวิเคราะ์ห์แอพลิเคชั่นที่ติดต่อสื่อสารผ่านทาง HTTP Protocol ในโปรแกรม Web Scarab จะมีส่วนของ tool ที่ชื่อว่า Transcoder ซึ่งสามารถใช้ในการแปลงข้อมูลได้ ผมจึงคัดลอก URL ดังกล่าวเข้าไปใส่ไว้ใน Transcoder

ขั้นที่ 3: ใช้ Transcode แปลงข้อมูลที่ encode ไว้เป็นข้อมูลแบบ plain-textขั้นที่ 3: ใช้ Transcode แปลงข้อมูลที่ encode ไว้เป็นข้อมูลแบบ plain-text

กดปุ่ม URL decode จะได้ผลลัพธ์ดังรูปด้านล่าง
ขั้นที่ 4: ผลลัพธ์ของการ decodeขั้นที่ 4: ผลลัพธ์ของการ decode

พบว่าข้อความที่ถูกส่งมาทางตัวแปร "smierrormessage" เป็นข้อมความเดียวกับที่แสดงใน Alert Box จึงลองดู HTML source พบว่ามีการเรียกคำสั่ง javascript แบบ in-line เพื่อแสดง Alert Box
ขั้นที่ 5: ดู HTML Source Codeขั้นที่ 5: ดู HTML Source Code

ทดลองทำ Code Injection โดยเปลี่ยนค่าที่ส่งให้ตัวแปร "smierrormessage" จาก "ไม่พบอีเมล์นี้ในระบบ" เป็น

Welcome to sanook.com");document.write("<h1>XSS Attack</h1>")("
ซึ่งจะทำให้ in-line javascript เปลี่ยนจาำก
alert("ไม่พบอีเมล์นี้ในระบบ"); เป็น
alert("Welcome to sanook.com");document.write("<h1>XSS Attack</h1>")("");
ซึ่ง Javascript ดังกล่าวจะเปลี่ยนข้อความใน Alert Box จาก "ไม่พบอีเมล์นี้ในระบบ" เป็น "Welcome to sanook.com" แทน แล้วยังเขียนคำว่า "XSS Attack" เพิ่มลงไปในหน้าเพจอีกด้วย

ขั้นที่ 6: นำ Javascript Code ที่จะส่งให้ตัวแปร &quot;smierrormessage&quot; มาทำ URL encodeขั้นที่ 6: นำ Javascript Code ที่จะส่งให้ตัวแปร "smierrormessage" มาทำ URL encode

กด ปุ่ม URL encode เพื่อให้ได้ URL ที่ encode ตัวอักษรพิเศษ

ขั้นที่ 7: นำผลลัพธ์ที่ได้จากการทำ URL encode ไปใส่ไว้ในตัวแปร&quot;smierrormessage&quot;ขั้นที่ 7: นำผลลัพธ์ที่ได้จากการทำ URL encode ไปใส่ไว้ในตัวแปร"smierrormessage"

ซึ่งจะได้ URL ด้านล่าง:
http://www.sanook.com/?smistatuscode=0&smierrormessage=Welcome+to+sanook.com%22);
document.write(%22%3Ch1%3EXSS+Attack%3C/h1%3E%22);(%22

หรือถ้าจะให้แยบยลกว่านั้นเราก็ต้องทำ url encode ทุกตัวอักษรซึ่งจะได้ URL นี้:

http://www.sanook.com/?smistatuscode=0&smierrormessage=%57%65%6C%63%6F%6D%65
%20%74%6F%20%73%61%6E%6F%6F%6B%2E%63%6F%6D%22%29%3B%64%6F%63%75%6D
%65%6E%74%2E%77%72%69%74%65%28%22%3C%68%31%3E%58%53%53%20%41%74%74
%61%63%6B%3C%2F%68%31%3E%22%29%28%22%3E%22%3B%7D%28%22

ผลลัพธ์ที่ได้ก็คือ

การป้องกันการโจมตีแบบ XSS

จริง ๆ แล้วเราสามารถป้องกัน XSS ได้ง่าย ๆ โดยการทำการตรวจสอบข้อมูลขาเข้าทุกอันที่มาจาก headers, cookies, query strings, form fields, และ hidden fields ที่จะถูกนำไปไปแสดงบนเว็บเพจ ซึ่งหากมีตัวอักษรพิเศษเช่น <, >, ", ',(, ) ฯลฯ จะต้องทำการ escape ตัวอักษรเหล่านั้นก่อน อีกประเด็นหนึ่งที่เราเห็นได้จาก sanook.com คือการส่ง error message ผ่านมาทาง query strings ซึ่งเป็นการเปิดโอกาสให้แฮกเกอร์โจมตี วิธีที่ถูกต้องควรทำการสร้าง lookup table ที่เก็บข้อมูล error code กับ error message และหากมีข้อผิดพลาดเกิดขึ้นก็ส่ง error code แทน เช่น "50" คือ "ไม่พบอีเมล์นี้ในระบบ" ซึ่งเมื่อโปรแกรมได้รับ error code = "50" ก็จะไปดูในตารางดังกล่าวว่า error code = "50" นั้นต้องแสดง error message อย่างไร

สวัสดีครับ พอดีผมอ่านและเข้าใจว่า ท่านได้อธิบายเกี่ยวกับ

หมายเหตุ: ทำการทดลอง ณ วันที่ 4 พฤศจิกายน 2550 ซึ่งหลังจากที่พบช่องโหว่ผมก็ได้แจ้ง sanook.com ให้แก้ไขช่องโหว่นี้แล้ว ทำให้ผลลัพธ์ที่ได้จากการกดลิงก์ต่าง ๆ ด้านล่างไม่ตรงกับรูปภาพที่แสดง

หรือ แสดง Alert สคริป javascript ครับ

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd><img> <object> <embed> <param>
  • Lines and paragraphs break automatically.
  • Images can be added to this post.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Image CAPTCHA
Copy the characters (respecting upper/lower case) from the image.
ญาณรักข์ วรรณสาย