- เริ่มจากการทดลอง QR Code ที่เปลี่ยนตามมุมมองของ Guy Dupont แล้ว Christian Walther ได้สร้าง QR Code ที่อ่านเป็นปลายทางต่างกันได้ตามเงื่อนไขการสแกน โดยไม่ต้องใช้เลนส์
- โครงสร้างหลักคือ มาสก์ลายตารางหมากรุก ที่นำ QR Code ขนาดเท่ากัน 2 อันมาซ้อนกัน แล้วแบ่งแต่ละพิกเซลเพื่อจัดวาง
- หากตัวอ่าน QR สุ่มตัวอย่างบริเวณศูนย์กลางของพิกเซลที่คาดไว้ เมื่อภาพขยับเล็กน้อย จุดสุ่มตัวอย่างอาจเอนไปทางโค้ดฝั่งหนึ่ง ทำให้ได้ผลลัพธ์ต่างกัน
- ในการทดลอง มาสก์ลายตารางหมากรุกทำงานได้ดีกว่าลายเส้นแนวตั้งหรือแนวทแยง และระดับ การแก้ไขข้อผิดพลาด ที่สูงก็เป็นประโยชน์ แต่ผลลัพธ์ยังแตกต่างกันไปตามดีโคดเดอร์
- แสดงให้เห็นว่า QR ภาพเดียวก็อาจถูกตีความเป็นผลลัพธ์หลายแบบได้ ขึ้นอยู่กับมุม การเลื่อน การทำงานของดีโคดเดอร์ และวิธีจัดการสี/ช่องอัลฟา
QR Code แบบคู่ที่ทำโดยไม่ใช้เลนส์
- Guy Dupont ทดลอง QR Code ที่ส่งไปยัง แหล่งที่มาต่างกันตามมุมมอง ด้วยไอเดีย “มุมมองต่างกันของเรื่องเดียวกัน”
- Christian Walther ลองต่อยอดไอเดียนี้ว่า “ทำได้ไหมโดยไม่ใช้เลนส์” และระบุว่าได้สร้างภาพ QR ที่ใช้งานได้จริง
- Dupont ตอบสนองต่อผลลัพธ์ของ Walther ว่าอ่านได้เป็นปลายทางสองแห่งคือ GitHub และ Mastodon
- Matt Lacey ก็กล่าวว่าในโทรศัพท์ของเขา URL ของ Mastodon ถูกจับได้ง่ายกว่า แต่ URL ของ GitHub ก็อ่านได้เช่นกัน
โครงสร้างที่แบ่งพิกเซลอย่างละครึ่ง
- วิธีพื้นฐานคือสร้าง QR Code ขนาดเท่ากัน 2 อัน แล้วซ้อนรวมเป็นภาพเดียว
- ครึ่งหนึ่งของแต่ละพิกเซลนำมาจาก QR Code อันหนึ่ง
- อีกครึ่งหนึ่งนำมาจาก QR Code อีกอัน
- ในคำอธิบายต่อมา ระบุว่าโค้ดหนึ่งถูกทำให้ปรากฏใน จตุภาคซ้ายบนและขวาล่าง ของแต่ละพิกเซล ส่วนอีกโค้ดปรากฏในพื้นที่ที่เหลือ
- มีการกล่าวถึงความเป็นไปได้ว่าวิธีสร้างคือการเติม เลเยอร์มาสก์ลายตารางหมากรุก ใน Photoshop
เหตุผลที่ผลการสแกนแยกกัน
- Walther สมมติว่าตัวอ่าน QR จะ สุ่มตัวอย่างบริเวณศูนย์กลาง ของตำแหน่งพิกเซลที่คาดไว้ โดยอ้างอิงจากบล็อกจัดแนว
- หากใช้มาสก์เดียวกันกับทุกพิกเซล และศูนย์กลางพิกเซลอยู่บนขอบของมาสก์ เมื่อมีการเลื่อนเพียงเล็กน้อย จุดสุ่มตัวอย่างอาจเอนไปยังพื้นที่ของโค้ดฝั่งหนึ่งพร้อมกันได้
- ผลคือภาพเดียวกันอาจถูกอ่านเป็น QR Code คนละอันตามปริมาณการเลื่อน
- Walther เองระบุว่าคำอธิบายเรื่องการสุ่มตัวอย่างนี้เป็นเพียง การคาดเดา ไม่ใช่ผลจากการศึกษาการทำงานจริงของดีโคดเดอร์
- ผู้ใช้รายหนึ่งกล่าวว่าเมื่อนำ PNG ใส่เข้าไปในดีโคดเดอร์
zbar-toolsโดยตรง ไม่สามารถตรวจพบโค้ดได้
ความแตกต่างที่เกิดจากมาสก์และดีโคดเดอร์
- ในการทดลองของ Walther มาสก์ลายตารางหมากรุก ให้ผลดีกว่าลายเส้นแนวตั้งหรือลายเส้นแนวทแยง
- เมื่อใช้ การแก้ไขข้อผิดพลาด ระดับสูงสุดจะทำงานได้ดีกว่า แต่ระบุว่ายังต้องทดลองเพิ่มเติม
- การแบ่งแนวทแยงดูสวยกว่า แต่ในแง่การทำงานจริง ลายตารางหมากรุกทำได้ดีกว่า
- มีรายงานว่าความถี่ของผลลัพธ์แตกต่างกันระหว่างแอปสแกนกับแอปกล้องพื้นฐาน
- ผู้ใช้รายหนึ่งกล่าวว่าในแอปสแกน QR Code ลิงก์ Mastodon ออกมาบ่อยกว่า ส่วนในแอปกล้องพื้นฐานดูเหมือนว่าอ่านได้ทั้งสองแบบ
- Attie Grande กล่าวว่าแม้แต่ระหว่างดีโคดเดอร์ซอฟต์แวร์ก็ยังดูมีความแปรผัน
- Hadley กล่าวว่าเมื่อถือโทรศัพท์นิ่ง ๆ จะสแกนไม่ติด แต่เมื่อเริ่มขยับไปยังมุมอื่น ก็สแกนได้อย่างเสถียรระหว่างที่กำลังเคลื่อนไหว
การทดลองดัดแปลงและเครื่องมือสาธารณะ
- ระหว่างการสนทนา Walther แนะนำ dualqrcode.com และ รีโพซิทอรี DualQRCode บน GitHub ว่าเป็นเวอร์ชันแบบอินเทอร์แอคทีฟ
- xssfox กล่าวถึงแนวทางการหาการชนกันที่ใกล้เคียงเพื่อลดจำนวนบิตที่ต่างกัน และบอกว่าการ brute force เพื่อหาความต่าง 30 บิตดูค่อนข้างเรียบง่าย
- Walther เคยทดลองเลือกแพตเทิร์นมาสก์ของ QR Code สองอันให้ต่างกันเพื่อลดความแตกต่าง แต่กรณีที่ใช้มาสก์เดียวกันกับทั้งสองโค้ดกลับมีความต่างน้อยที่สุด
- proof of concept เดิมก็ใช้ mask 6 กับทั้งสองโค้ด เพราะตัวสร้างเลือกให้อัตโนมัติ ดังนั้นในกรณีนี้จึงไม่มีประโยชน์เพิ่มเติม
- Walther กล่าวว่าแอปกล้องของ iOS แสดงเฉพาะโดเมนในพรีวิวแบบเรียลไทม์ และต้องแตะจึงจะแสดงเนื้อหาทั้งหมด เขาจึงตั้งใจเลือกโดเมนที่ต่างกัน
ช่องสี·อัลฟา และการทดลองโค้ด 4 อัน
- Nemo Thorx แชร์การทดลองที่สร้าง QR Code จาก
42ซึ่งแสดงในสามรูปแบบ แล้วรวมเข้าไว้ใน ช่อง RGB- สีแดงคือ
6x9 - สีเขียวคือ
XLII - สีน้ำเงินคือ
Forty-two - ในการสนทนาต่อมา มีการยืนยันว่าในช่องอัลฟามีโค้ด
㊷
- สีแดงคือ
- Walther กล่าวว่าเมื่อมองข้ามช่องอัลฟาในภาพดังกล่าวแล้ว เขาก็เข้าใจว่ามันทำงานอย่างไร
- เมื่อ Pixel Dunn พยายามใส่หลายโค้ดด้วยการผสมสี Walther มองว่าวิธีผสมสีแบบนั้นทำให้ดีโคดเดอร์แยกโค้ด 4 อันออกจากกันไม่ได้ จึงไม่น่าทำงาน
- Walther กล่าวว่าเขาเคยใส่โค้ด 4 อันโดยใช้ บล็อกจัดแนวที่ขยับได้ และจตุภาคของพิกเซล
- เมื่อขยับเป้าจัดแนวเพียงเล็กน้อย โฟกัสจะไปอยู่ที่จตุภาคอื่นของพิกเซล
- วิธีที่ชุดโค้ดสองชุดเปลี่ยนไปตามพื้นหลังโปร่งใสและธีมอาจเป็นไปได้ แต่ iPhone ของ Walther ไม่สามารถรู้จำได้ทั้งบนพื้นหลังสีขาวและสีดำ และทำงานได้เฉพาะเมื่อใช้การประมวลผล threshold แบบปรับเอง
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
ดูเหมือนจะเป็นไปได้ที่จะโจมตีโดยให้หน้าจอในที่สาธารณะปรับ QR code เล็กน้อยตามข้อมูลของผู้ใช้ปัจจุบัน โดยภายนอกดูไม่ต่างไปมากนัก
เช่น สร้าง QR code ที่ผสมกันครึ่งต่อครึ่ง แล้วใช้ข้อมูลนำเข้าภายนอกอย่างการประเมินลักษณะผ่านกล้องเพื่อกำหนดเป้าหมาย จากนั้นปรับสีของโค้ดเพียงเล็กน้อยเพื่อเพิ่มโอกาสให้ถูกอ่านเป็นฝั่งที่ต้องการ
วิธีนำไปใช้ในทางที่ผิดอาจมีตั้งแต่การแสดงแบบฟอร์ม feedback คนละแบบให้กลุ่มประชากรต่างกันเพื่อบิดเบือนผลลัพธ์, ทำให้โอกาสถูกรางวัลเอนเอียงตามลักษณะที่ระบุตัวตนได้อย่างเชื้อชาติ อายุ หรือหน้าตา, หรือส่งเฉพาะบางคนไปยังเครือข่าย Wi-Fi หรือหน้าชำระเงินอีกแห่งหนึ่ง
ในสภาพแวดล้อมแบบคงที่คงได้ผลน้อยกว่า และยังนึกไม่ออกทันทีว่าการโจมตีแบบคงที่ที่คัดผู้ใช้บางส่วนออกมาเพื่อหาประโยชน์จะเป็นแบบไหน ภายใต้แสงไฟสาธารณะ คนส่วนใหญ่น่าจะสังเกตได้ยากว่า QR code กำลังเปลี่ยนแบบไดนามิก
เทคนิคแฮ็กในต้นฉบับน่าจะมีที่ใช้จริงในกรณีที่ผู้โจมตีเอาโค้ดของตัวเองไปแปะทับ QR code ปกติ มากกว่า เพราะโค้ดที่จะถูกอ่านค่อนข้างสุ่ม ผู้ใช้บางส่วนจึงยังถูกส่งไปปลายทางเดิม ทำให้ตรวจจับช้าลงได้ แต่ก็ไม่แน่ใจว่าจะชดเชยกับทราฟฟิกที่เข้า link ของตัวเองลดลงได้หรือไม่
ไม่จำเป็นต้องซับซ้อนแบบ QR code สองชั้นแบบนี้ด้วยซ้ำ แค่ไปที่ป้าย “ชำระเงินด้วยมือถือ” ในลานจอดรถ แปะ QR code ของตัวเองทับ QR code “สแกนเพื่อชำระเงิน” แล้วรอให้ข้อมูลบัตรเครดิตไหลเข้ามาก็พอ
อีกวิธีคือใช้โปสเตอร์ที่ไม่ได้แบนสนิท ทำให้พิกเซลต่าง ๆ นูนขึ้นเล็กน้อยเป็นทรงพีระมิด และทาสีแต่ละด้านต่างกัน ก็อาจทำให้ QR code ถูกสแกนเป็นคนละแบบตามมุมมองได้
ธนาคารรายใหญ่แห่งหนึ่งใน Tbilisi ให้แชร์หมายเลข IBAN เป็น QR code ได้ ในทางทฤษฎีเทคนิคแบบนี้อาจใช้ขโมยเงินได้ แต่ในทางปฏิบัติแอปธนาคารมีมาตรการป้องกันหลายอย่าง เช่น แสดงชื่อผู้รับก่อนยืนยันการโอน
ในหัวผม การควบคุมแบบนี้ดูเหมือนใช้บังคับให้เลือกไพ่ใบหนึ่งได้ เลยคิดถึงทาง มายากล ก่อน
ผมทำเว็บไซต์ให้ลองทดสอบเองได้: https://dualqrcode.com/
ไม่มีวิธีการที่ Christian ใช้แบบตรง ๆ ดังนั้นที่นี่จึงรวม QR code สองอันเป็นภาพเดียวด้วย แพตเทิร์นแบ่งแนวทแยง ถ้าแพตเทิร์นตำแหน่งเดียวกันต่างกัน ก็แบ่งเซลล์เป็นแนวทแยง ด้านหนึ่งแทน QR code อันแรก อีกด้านแทนอันที่สอง และถ้าทั้งคู่เป็นสีดำหรือสีขาวเหมือนกันก็เติมเป็นสีเดียว
ด้วยความสามารถแก้ข้อผิดพลาดที่สูงของ QR code โดยเฉพาะระดับการแก้ข้อผิดพลาด ‘H’ ทำให้ URL ใด URL หนึ่งถูกอ่านได้ตามมุมสแกน อย่างไรก็ตามอย่างที่เขียนไว้ใน UI มักจะเอนเอียงไปทาง URL ที่สองบ่อยกว่า
สิ่งที่น่าสนใจที่สุดคือบน iOS เมื่อกดค้างที่รูป มันแสดงว่าจะไป github.com แต่ตัว preview กลับเป็น Mastodon
น่าจะหมายความว่ามีการ parse QR code สองครั้ง แล้วได้ผลลัพธ์ต่างกัน ดูเหมือนจะใช้หลอกผู้ใช้บางส่วนได้ แต่ก็ไม่รู้ว่ามีกี่คนที่ดู URL ใน dropdown หลังจากกดค้าง
ผมเลยเคยทำเรื่องโง่ ๆ อย่าง AirDrop screenshot ไปที่โน้ตบุ๊ก แล้วใช้กล้องมือถือสแกน หรือให้เพื่อนหรือคนในครอบครัวเอามือถือมาสแกนโค้ดบนหน้าจอโทรศัพท์ผม
แต่วันนี้เพิ่งรู้ว่า ถ้ากดค้าง QR code ใน screenshot ที่อยู่ใน camera roll มันจะ parse แล้วเปิดลิงก์ได้เลย เหมือนผมเคยลองกดค้างที่รูปมาก่อนแล้วก็ได้ แต่หลังจากนั้นอาจเพิ่งเพิ่มฟีเจอร์นี้ หรือผมอาจไม่เคยลองจริง ๆ หรืออาจกดผิดส่วนของ QR code ก็ได้ ไม่ว่าอย่างไร ดีมากที่ได้รู้ว่าทำได้
น่าจะทำเรื่องเดียวกันได้แม้กับ QR code มาตรฐานที่ใส่ข้อผิดพลาดโดยตั้งใจ แค่ต้องหาว่าแต่ละตัวแก้ข้อผิดพลาดต่างกันอย่างไร
เหมือนค้นพบ bug bounty bug ที่รอให้ใครสักคนไปเก็บแล้ว
ทำให้นึกถึงโค้ดอย่าง
if someCondition(getFoo()) then doSomethingWith(getFoo())หรือโค้ดที่เรียกdoSomethingWith(getFoo())แล้วตามด้วยdoAnotherThingWith(getFoo())เรื่องแบบนี้มักมีกลิ่น code smell อยู่เสมอ ต่างจากการรับค่าครั้งเดียวด้วยfoo := getFoo()แล้วนำไปใช้ถ้าเลื่อนขึ้นจากตำแหน่งเริ่มต้น จะเห็นเวอร์ชัน lenticular ได้
แรงมาก iPhone ของผมมีแนวโน้มจะล็อกอยู่กับอันใดอันหนึ่ง และการหมุนโทรศัพท์ช่วยให้ไปฝั่งหนึ่งหรืออีกฝั่งหนึ่งได้
บางครั้งลิงก์ Mastodon กับ GitHub ก็กะพริบสลับกันไปมา
ถ้าอยากลองทำเอง สามารถใช้โค้ดที่เขียนขึ้นอย่างรวดเร็วนี้ได้ ติดตั้งแพ็กเกจ Python
qrcodeแล้วรันโค้ดด้านล่างจะได้ QR code คู่ ที่ใส่
fooกับbarจริง ๆ แต่ใน HN ใช้ Unicode ไม่ได้ และถ้าแทนด้วย8หรือ0มือถือของผมก็อ่านไม่ออก เลยแปะตรง ๆ ได้ยากถ้าเอาไปใช้กับ เกมล่าขุมทรัพย์ น่าจะเจ๋ง
QR code เหมาะจะถูกนำไปใช้ในทางที่ผิดพอ ๆ กับ URL ย่อ
โดยพื้นฐานแล้วมันเป็น URL ที่อ่านไม่ได้เลย จึงไม่รู้เลยว่าจะถูกส่งไปที่ไหน หรือจะถูก redirect กี่ครั้ง ดังนั้นผมไม่ใช้
เป็นแนวคิดที่เจ๋งจริง ๆ ถ้าโฟกัสที่เป้าหมายปลายทาง อีกแนวทางหนึ่งคือวาง สวิตช์ ไว้ที่ปลายทาง URL
คือ redirect ไปหน้าต่าง ๆ ตามการสุ่ม ข้อมูลผู้ใช้ หรือเกณฑ์อื่น ๆ ถ้าอยากทดลองฟีเจอร์แบบนี้และถึงขั้นทดสอบสติกเกอร์จริง ผมทำงานกับบริษัท SaaS หลายแห่งเรื่องฉลากแบบเปลี่ยนค่าได้ จึงแชร์ insight พิมพ์ตัวอย่าง หรือร่วมมือกันได้