- Randar คือ exploit ใน Minecraft Beta 1.8~1.12.2 ที่ใช้พิกัดของไอเทมดรอปซึ่งเกิดขึ้นตอนทำลายบล็อก เพื่อกู้คืนสถานะ
java.util.Random ของเซิร์ฟเวอร์ และย้อนรอยตำแหน่งของผู้เล่นคนอื่น
- สาเหตุหลักคือ การใช้ RNG ซ้ำ โดยการสร้างภูมิประเทศ/สิ่งปลูกสร้างและอีเวนต์ขุดแร่แชร์ตัวสร้างเลขสุ่มตัวเดียวกัน ทำให้ตำแหน่งดรอปที่สังเกตได้กลายเป็นเบาะแสของสถานะภายใน
- offset X/Y/Z ของไอเทมดรอปคือเอาต์พุตต่อเนื่องสามครั้งของ
World.rand.nextFloat() จึงเผยบิตบน 24 บิตของ seed ขนาด 48 บิต และสามารถกู้คืน seed ได้อย่างรวดเร็วด้วย การลดรูปแลตทิซ LLL
- seed ที่กู้คืนได้จะถูกย้อนกลับไปตรวจสอบว่าเป็นค่าที่มาจากการตรวจ Woodland Mansion หรือไม่ ถ้าใช่จะระบุ Woodland region ขนาด 1280×1280 บล็อก ที่เพิ่งถูกโหลดล่าสุดได้
- หากข้อมูลดรอปยังอยู่ในบันทึกแพ็กเก็ตเก่า เช่น ReplayMod แม้เซิร์ฟเวอร์จะถูกแพตช์แล้ว ตำแหน่งกิจกรรมในยุค Beta 1.8~1.12.2 ก็อาจถูกเปิดเผยย้อนหลังได้
ข้อมูลที่ Randar มุ่งเป้า
- เป้าหมายคือการหาพิกัด ในเกม ของผู้เล่นคนอื่นที่อยู่ในโลกเดียวกัน
- 2b2t ถูกใช้เป็นกรณีศึกษาหลัก
- 2b2t คือเซิร์ฟเวอร์ Minecraft แบบ “anarchy” ที่ไม่มีข้อกำหนด
- แผนที่เซิร์ฟเวอร์มีขนาด 3.6 quadrillion square tiles ดังนั้นการปกปิดตำแหน่งจึงเป็นเงื่อนไขสำคัญในการปกป้องไอเทม
- ก่อน Randar บน 2b2t ก็เคยมี coordinate exploit ชื่อ Nocom ที่ใช้ในช่วงปี 2018~2021
เวอร์ชันที่มีช่องโหว่และความผิดพลาดในโค้ด
- ปัญหานี้มีอยู่ตั้งแต่ Minecraft Beta 1.8 ที่ออกในปี 2011 ถึง 1.12.2 ที่ออกในปี 2017
- 2b2t ยังคงอยู่ที่ 1.12.2 จนถึงวันที่ 14 สิงหาคม 2023
- ความผิดพลาดหลักคือการนำอินสแตนซ์
java.util.Random กลับมาใช้ซ้ำอย่างไม่ระมัดระวังในหลายเส้นทางของโค้ด
- RNG ถูกแชร์ระหว่างการทำงานของเกม เช่น การสร้างภูมิประเทศและการขุดแร่
- ตัว
java.util.Random เองก็ไม่ใช่ RNG สำหรับงานด้านความปลอดภัย
- Minecraft ใช้ การสร้างแบบกำหนดได้แน่นอน เพื่อให้โลก seed เดียวกันและตำแหน่งเดียวกันให้ภูมิประเทศเหมือนกัน
- การใช้
java.util.Random เพื่อจุดประสงค์นี้ถือเป็นเรื่องธรรมชาติ
- ปัญหาคือการจัดการ RNG สำหรับการสร้างโลกซึ่งควรคาดเดาได้ ไปกระทบถึงอีเวนต์ที่ควรคาดเดาไม่ได้ด้วย
การตรวจ Woodland Mansion และ World.rand แบบ global
- ในกระบวนการตรวจตำแหน่งสร้าง Woodland Mansion จะมีการรีเซ็ต
World.rand
- Woodland region ถูกคำนวณเป็นหน่วย chunk 80×80
- มีการเรียก
random.nextInt(60) สี่ครั้งเพื่อเลือก chunk ที่ Mansion จะเกิดภายใน region นั้น
- flow ที่มีช่องโหว่คือ
World.setRandomSeed(seedX, seedY, seedZ) ตั้ง seed ใหม่ให้ this.rand แบบ global แล้วคืนอ็อบเจกต์ตัวเดิมกลับมา
- สูตรเฉพาะของ 2b2t เป็นดังนี้
seed = x * 341873128712 + z * 132897987541 - 4172144997891902323 mod 2^48
setRandomSeed ถูกเรียกเพื่อการตรวจสอบ ทุกครั้งที่โหลด chunk ไม่ใช่เฉพาะตอนอยู่ใกล้ Woodland Mansion จริงเท่านั้น
- ผลกระทบแตกต่างกันตามมิติ
- Overworld เป็นเป้าหมายที่ได้รับผลกระทบหลัก
- Nether ปลอดภัย เพราะการสร้างสิ่งปลูกสร้างใช้ RNG ที่ปลอดภัยเสมอ
- The End ได้รับผลกระทบตอนสร้างครั้งแรกเนื่องจาก end city แต่จะไม่กระทบทุกครั้งที่ chunk เดิมถูกโหลดใหม่ในภายหลัง จึงค่อนข้างปลอดภัยกว่า
พิกัดไอเทมดรอปเผย RNG อย่างไร
- เมื่อขุดบล็อก ไอเทมจะดรอปที่ตำแหน่งสุ่มภายในบล็อก
- เช่น หากพิกัดบล็อกคือ
(10, 20, 30) ไอเทมจะปรากฏระหว่าง (10.25, 20.25, 30.25) ถึง (10.75, 20.75, 30.75)
- ตำแหน่งนี้กำหนด offset X, Y, Z ด้วย
world.rand.nextFloat() สามครั้ง
- จากพิกัดดรอปสามารถย้อนกลับไปเป็นค่า
nextFloat() เดิมได้
- ขั้นตอนการคูณ float ด้วย 0.5 เพียงลด exponent ลง จึงไม่ทำให้ข้อมูลสูญหาย
- จากนั้นถูกแปลงเป็น double แล้วบวกพิกัดบล็อก ก่อนส่งผ่านเครือข่ายแบบ full precision
java.util.Random.nextFloat() จะอัปเดต seed ขนาด 48 บิตก่อน แล้วดึงบิตบน 24 บิตออกมาเป็นจำนวนเต็มและหารด้วย 2^24
- สูตร LCG คือ
newSeed = oldSeed * 25214903917 + 11 mod 2^48
- float ต่อเนื่องสามค่าจึงให้บิตบน 24 บิตของ seed ต่อเนื่องสามตัว
กู้คืน seed ด้วยการลดรูปแลตทิซ LLL
- วิธีตรงไปตรงมาคือทดลอง candidate บิตล่าง 24 บิตจำนวน
2^24 ตัวที่ตรงกับค่าที่วัดได้ครั้งแรกทั้งหมด
- วิธีนี้ก็ทำงานได้ แต่ช้า จึงใช้วิธีแลตทิซแทน
- ค่าที่วัดได้สามค่าบอกช่วงของสามค่าต่อไปนี้
seed
nextSeed(seed)
nextSeed(nextSeed(seed))
- ถ้ามองสามค่านี้เป็นจุด 3 มิติ
(seed, nextSeed(seed), nextSeed(nextSeed(seed))) seed ที่เป็นไปได้ทั้งหมดจะก่อตัวเป็นโครงสร้างแลตทิซ
- เลือกเวกเตอร์ฐานดังนี้
(1, a, a^2)
(0, c, 0)
(0, 0, c)
- โดย
a = 25214903917, c = 2^48
- LLL basis reduction หา basis ที่สั้นกว่าและเกือบตั้งฉากกัน ซึ่งยังสร้างแลตทิซเดียวกัน
- ตัวอย่าง Mathematica คือ
LatticeReduce[{{1, a, a^2}, {0, c, 0}, {0, 0, c}}]
- basis ที่ได้คือ
(1270789291, -2446815537, 2154219555), (-2355713969, 1026597795, 4110294631), (-3756485696, -2345310016, -2015749696)
- เมื่อแปลงจุดศูนย์กลางของ cube การวัดไปยังพื้นที่ basis ที่ลดรูปแล้ว และปัดเศษ coefficient แต่ละตัวเป็นจำนวนเต็มที่ใกล้ที่สุด จะได้จุดแลตทิซที่ถูกต้อง โดยพิกัดแรกคือ internal seed ที่กู้คืนได้
- ตัวอย่างโค้ด Java ที่ปรับแต่งแล้วสามารถกู้คืน seed จากค่าที่วัดได้สามค่าในระดับประมาณ 10ns
กระบวนการย้อน seed เพื่อหาตำแหน่ง
- LCG ของ
java.util.Random สามารถเดินหน้าและถอยหลังได้
- เดินหน้า:
newSeed = oldSeed * 25214903917 + 11 mod 2^48
- ถอยหลัง:
oldSeed = (newSeed - 11) * 246154705703781 mod 2^48
- seed ที่กู้คืนได้จะถูกย้อนกลับไปเรื่อย ๆ เพื่อตรวจว่าแต่ละ seed อาจเป็น seed ที่มาจากการตรวจ Woodland Mansion หรือไม่
- ขอบเขตโลก Minecraft อยู่ตั้งแต่ -30 million ถึง +30 million บล็อก
- implementation กำหนดขอบเขต Woodland region ของแต่ละแกนไว้ตั้งแต่ -23440 ถึง +23440
- จำนวน Woodland region ที่เป็นไปได้คือ
(23440*2+1)^2 หรือ 2,197,828,161 รายการ
- การเทียบ candidate ทั้ง 2.2 พันล้านรายการช้า และ
HashSet ขนาดใหญ่ก็ใช้หน่วยความจำมาก
- coefficient Z
132897987541 เป็นเลขคี่ จึงมี inverse ใน mod 2^48
- inverse คือ
211541297333629
- ใช้สิ่งนี้เพื่อวนดูเฉพาะ candidate X จำนวน 46,881 ตัว แล้วคำนวณ Z เพื่อหา region candidate ได้
การปรับแต่งด้วย GPU และตาราง lookup
- วิธีวนเฉพาะ X ถือว่าสมเหตุสมผลสำหรับ seed เดียว แต่เมื่อมีบอทจำนวนมากขุดหลายบล็อกต่อวินาที และต้องตรวจหลายพัน RNG step ต่อการวัดแต่ละครั้ง การประมวลผลแบบเรียลไทม์บน VPS สเปกต่ำจึงทำได้ยาก
- implementation ต่อมาจึงเปลี่ยนเป็น CUDA batch job และตาราง lookup
- key ของตาราง lookup คือบิตล่าง 32 บิตของ mansion seed
- value คือพิกัด X ของ Woodland region
- เขียนไว้ว่าคีย์บิตล่าง 32 บิตไม่มี collision และไม่เข้าใจเหตุผล
- ตารางใช้
2^32 entry และ entry ละ 2 ไบต์ จึงต้องใช้ VRAM ประมาณ 9GB
- บน RTX 3090 สามารถ crack ได้ประมาณ 10 ล้าน seeds ต่อวินาที
- ผลการกู้คืนจะบอก Woodland region ขนาด 1280×1280 บล็อกที่มีการโหลด chunk ล่าสุด และขนาดนั้นเพียงพอให้ค้นหาไม่กี่นาทีก็ระบุตำแหน่งได้
การกระจายของ step ที่สังเกตได้บนเซิร์ฟเวอร์จริง
- ตามทฤษฎี ระยะห่างเฉลี่ยระหว่าง Woodland seed คือประมาณ 128,000 RNG steps
- บน 2b2t ส่วนใหญ่พบ Woodland seed ภายในไม่กี่สิบ step
- การวัดเกิดขึ้นช่วงต้นมากของ tick เนื่องจากจังหวะการประมวลผลแพ็กเก็ต
- โดยทั่วไป chunk ถูกโหลดไว้ใน tick ก่อนหน้า
- การวัดที่เชื่อถือได้เริ่มตั้งแต่ขั้นต่ำ 4 RNG steps
- เพราะโค้ด Woodland Mansion เรียก
rand.nextInt สี่ครั้งก่อนการสังเกต
- spike ใหญ่เกิดที่จำนวน step เป็นพหุคูณของ 1354
- มีการเสนอว่าอาจเป็นการระเบิดของ end crystal หรือ wither skull
- ในกรณี end crystal explosion การคำนวณความเสียหายบล็อก
16^3-14^3=1352 รวมกับเอฟเฟกต์เสียง 2 ครั้ง ทำให้ได้ 1354 step พอดี
ReplayMod และความเสี่ยงการเปิดเผยย้อนหลัง
- แม้เซิร์ฟเวอร์จะอัปเดตเป็นเวอร์ชันล่าสุดหรือแพตช์การจัดการ RNG แล้ว หากข้อมูลเก่ายังคงอยู่ ความเสี่ยงจาก Randar ก็ยังเหลืออยู่
- ผู้เล่น Minecraft บางคนบันทึกแพ็กเก็ตด้วย mod เช่น ReplayMod
- หากไฟล์บันทึกมีไอเทมดรอปอยู่ ก็สามารถกู้คืนสถานะ RNG ของเซิร์ฟเวอร์ในขณะนั้นได้
- การทุบบล็อกเป็นการกระทำที่พบบ่อยมาก จึงมีความเป็นไปได้สูงว่าจะอยู่ในบันทึก
- ตำแหน่งทั้งหมดที่เคย active ใน Beta 1.8~1.12.2 ควรถูกถือว่าเปิดเผยแล้ว แม้เซิร์ฟเวอร์จะอัปเดตไปนานแล้วก็ตาม
- มีเครื่องมือเว็บฝั่ง client ให้ลองรัน Randar เอง
- ที่ hobune.stream/randar สามารถลากไฟล์ ReplayMod ของ 1.12.2 เข้าไปเพื่อตรวจพิกัดได้
- ไฟล์บันทึกจะไม่ออกจากเบราว์เซอร์
การใช้งาน Randar และ heatmap
- SpawnMasons เริ่มบันทึกพิกัดไอเทมดรอปจากบัญชีที่ขุด stone/cobblestone ตลอด 24/7 อยู่แล้วเพราะโปรเจกต์อื่น
- นำระบบ Minecraft แบบ headless ที่เคยใช้กับ Nocom กลับมาใช้ และเพิ่มฐานข้อมูล Postgres เพื่อจัดเก็บค่าที่วัดได้
- ซอฟต์แวร์ที่ crack ค่าการวัด RNG ถูกปรับปรุงหลายครั้ง และสุดท้ายลงตัวที่ async CUDA batch job
- เมื่อค่าการวัดที่ crack แล้วถูกเพิ่มเข้า database ตารางวิเคราะห์ heatmap ก็ถูกอัปเดตด้วย
- เก็บ hit count ตามทั้งช่วงเวลา รายวัน และรายชั่วโมง
- ทำให้เลือกช่วงเวลาและ granularity เฉพาะใน Plotly Dash UI แล้วดูผ่านเบราว์เซอร์ได้
- chunk load spam ที่เกิดจาก Elytra stash hunting ถูกตัดออกด้วยวิธีพิจารณาเฉพาะพิกัดที่ถูกโหลดข้าม distinct hour หลายช่วง
- มีการเพิ่มระบบ annotation แบบแชร์อย่างง่ายเพื่อไล่ติดตาม hotspot ที่พบ
- ใช้ Baritone bot ที่นำมาจาก Nocom เพื่อทำให้กระบวนการขโมยและจัดระเบียบ item stash เป็นอัตโนมัติแบบ AFK
Woodland region ล่อสำหรับการป้องกัน
- Randar ไม่ได้หาชิ้น chunk ล่าสุดได้แม่นยำเสมอไป
- เมื่อย้อน RNG กลับ หากเจอ Woodland region ล่อที่ใหม่กว่าก่อน exploit ที่คืนค่า match แรกอาจให้ false positive ได้
- โดยรวมแล้ว Woodland seed มีประมาณหนึ่งในทุก ๆ 130,000 RNG seed แต่การกระจายมี outlier
- บน 2b2t ระบุว่าประมาณ หนึ่งใน Woodland region ทุก 20,000 แห่ง มี hiding property พิเศษคือมี Woodland region อื่นอยู่ภายใน 4 RNG step ถัดไป
- SpawnMasons สร้าง stash ใน region เหล่านี้
- สร้างโครงสร้างให้ compact เพื่อไม่ให้ chunk นอก region ป้องกันถูกโหลดเพราะ render distance
- วางบัญชี AFK และ base เล็ก ๆ ไว้ที่ตำแหน่ง decoy เพื่อพยายามให้ผู้ใช้ Randar คนอื่นเห็นตำแหน่งล่อ
- ตาม log Randar ของตนเอง stash เหล่านี้อยู่ในสถานะ “clean” ตลอดช่วงเวลา เพราะไม่ได้โหลด Woodland region ข้างเคียงโดยไม่ตั้งใจ
- ระบุว่า ณ เวลาที่เผยแพร่ ได้ย้าย stash เหล่านั้นไปแล้ว
ตัวอย่างสมบูรณ์และข้อจำกัดตามเวอร์ชัน
- มีตัวอย่าง Java ที่ตรวจจับไอเทมใน
SPacketSpawnObject ซึ่งดูเหมือนดรอปจากการขุด แปลงพิกัดดรอปกลับเป็นค่าการวัด float สามค่า จากนั้น crack ด้วย LLL และย้อนหา Woodland region
- ตัวอย่างค่าที่วัดได้จริงจาก 2b2t ให้ผลดังนี้
- item drop:
0.41882818937301636, 0.6833633482456207, 0.46088552474975586
- RNG measurements:
5664934 14541261 7076144
- internal seed:
95041827771683
- Woodland region:
-12008 0
- ช่วงตำแหน่ง: จาก
-15370368,-128 ถึง -15369089,1151
- ตัวอย่างสำหรับไดอะแกรมพบ Woodland Region
123,456
- ช่วงตำแหน่งสุดท้ายคือจาก
157312,583552 ถึง 158591,584831
- รวมพิกัดเดิม
x=157440 z=583680 อยู่ภายใน
- เวอร์ชันก่อน 1.11 ต้องใช้โค้ดอื่น เพราะ exploitable structure ไม่ใช่ Woodland Mansion แต่เป็นสิ่งปลูกสร้างอื่น
- ก่อน 1.9 ตำแหน่งไอเทมถูกส่งเป็น fractional part แบบ fixed-point 5 บิต ไม่ใช่ double ทำให้การ crack สถานะ RNG จากไอเทมเดียวแทบทำไม่ได้ในทางปฏิบัติ และต้องใช้กลยุทธ์การวัดแบบอื่น
วิธีแพตช์
- วิธีง่ายคือหาแพตช์หรือการตั้งค่าที่ปิด RNG manipulation
- implementation ที่มีช่องโหว่คือ
World.setRandomSeed ตั้ง seed ให้ this.rand แบบ global แล้วคืนค่านั้น
public Random setRandomSeed(int seedX, int seedY, int seedZ) {
this.rand.setSeed(seedX * 341873128712L + seedY * 132897987541L + seedZ + this.getWorldInfo().getSeed());
return this.rand;
}
- หากต้องการป้องกันอย่างสมบูรณ์ สามารถเปลี่ยนให้คืน
Random ตัวใหม่ทุกครั้งที่เรียกได้
public Random setRandomSeed(int seedX, int seedY, int seedZ) {
return new Random(seedX * 341873128712L + seedY * 132897987541L + seedZ + this.getWorldInfo().getSeed());
}
ภาคผนวกของ n0pf0x: วิธีค้นหาพิกัดแบบอื่นและ The End
- n0pf0x ใช้วิธีค้นหาพิกัดแบบ cache-based แทนตาราง lookup ขนาดใหญ่บน GPU ของฝั่ง Mason
- เมื่อเกิด hit จะใส่พิกัดนั้นและพิกัดใน radius รอบ ๆ ลงใน
HashMap
- pass แรกย้อน RNG กลับ พร้อมตรวจ cache hit หรือค่าซ้ำกับ seed ที่เพิ่งประมวลผลก่อนหน้าอย่างรวดเร็ว
- pass ที่สองทำเฉพาะเมื่อ pass แรกล้มเหลว และใช้ algorithm หาพิกัดที่มีต้นทุนสูงตามที่อธิบายข้างต้น
- วิธี cache นี้มีผลช่วยข้าม valid location ที่ดูมีความเป็นไปได้น้อยกว่า จึงอาจช่วยลด false positive ได้
- ใน The End RNG จะได้รับผลกระทบเฉพาะตอน chunk ถูกสร้างครั้งแรก จึงสังเกตการโหลด chunk ของ base ซ้ำ ๆ ได้ยากเหมือน Overworld
- สถานการณ์ที่พึ่งพาได้ใน The End มีสองแบบ
- ผู้เล่นที่อยู่ใน base เดินไปรอบ ๆ แล้วสร้าง chunk ที่ยังไม่เคยสร้าง
- ผู้เล่นที่กำลังเดินทางไป base สร้าง trail ของ chunk ใหม่ตามเส้นทาง
- trail สามารถสร้างระบบระบุอัตโนมัติได้ แต่ n0pf0x ไม่ได้ implement และติดตามด้วยสายตาแบบ manual
- การระบุตัวผู้เล่นใช้ไอเดีย End Occupancy Tracker(EOT)
- อิงสมมติฐานว่าจำนวนการเรียก RNG ต่อ tick มีความสัมพันธ์ระดับหนึ่งกับจำนวน chunk ที่ถูกโหลด และสิ่งนี้เชื่อมโยงกับจำนวนผู้เล่นในมิตินั้น
- ดูว่าจำนวนการเรียก RNG พุ่งขึ้นหรือลดลงทันทีหลังผู้เล่น join/leave หรือไม่ เพื่อประเมินผู้เล่นที่อยู่ใน The End
- EOT ถูกทดสอบเฉพาะบน 9b9t และอาจใช้ไม่ได้ภายใต้เงื่อนไขของเซิร์ฟเวอร์อื่น เช่น 2b2t
- ต้องสามารถ sample RNG ได้อย่างเสถียรทุก tick
- หากกิจกรรมของผู้เล่นใน The End มากกว่านี้มาก ก็อาจยากขึ้น
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
ช่วงปี 1999–2000 เคยมี International RoShamBo Programming Competition ที่ให้บอตคอมพิวเตอร์เล่นเป่ายิ้งฉุบมาแข่งกัน [1]
บอตมาตรฐานใช้กลยุทธ์เลือกแบบสุ่ม ซึ่งในทางทฤษฎีไม่มีทางเอาชนะได้ แต่ผลงานที่ส่งเข้าประกวดแบบขำ ๆ ชิ้นหนึ่งถูกออกแบบให้ย้อนหาสถานะของตัวสร้างเลขสุ่ม แล้วทำนายได้ถูกต้อง 100% ว่าผู้เล่นแบบสุ่มจะออกอะไร
แก้ไข: บอตตัวนั้นคือ “Nostradamus” ของ Tim Dierks และถูกประกาศให้เป็นผู้ชนะหมวด “supermodified” ในการแข่งขันครั้งแรก [2]
[1] https://web.archive.org/web/20180719050311/http://webdocs.cs...
[2] https://groups.google.com/g/comp.ai.games/c/qvJqOLOg-oc
แต่จริง ๆ แล้วผมไปสาย ความปลอดภัย เขียน RFC ของ TLS และกลายเป็น Distinguished Engineer ฝ่ายความปลอดภัยของ Google ขอบคุณที่ทำให้นึกถึงความหลัง
https://web.archive.org/web/20180719050236/http://webdocs.cs...
Nostradamus เขียนโดย Tim Dierks รองประธานฝ่ายวิศวกรรมของ Certicom ผู้เชี่ยวชาญด้านคริปโตสูงมาก และเอาชนะผู้เล่นที่เหมาะที่สุดด้วยการ reverse engineer สถานะภายในของตัวสร้าง
random()เจ้าตัวบอกว่า “ทั้งง่ายและยากกว่าที่คิด” แต่เพื่อสปิริตนักกีฬา เขายังเล่นอย่างเหมาะที่สุดกับคู่แข่งอื่นทั้งหมดFork Bot มาจากไอเดียที่ Dan Egnor คิดขึ้นได้ไม่กี่นาทีหลังได้ยินเรื่องการแข่งขัน โดยใช้ประโยชน์จากกติกา “อนุญาตให้ใช้รูทีนไลบรารี” ด้วยการใช้
fork()เปิดสามโปรเซส ให้แต่ละโปรเซสออกคนละอย่าง แล้วฆ่าสองตัวที่แพ้ Andreas Junghanns นำไปเขียนเป็นโค้ดราว 10 บรรทัด แต่หลังตาแรก ทั้งสามแบบแพ้ให้กับ Psychic Friends Network หมด โปรแกรมเลยจบการทำงาน และแมตช์ที่เหลือถูกนับว่าสละสิทธิ์Psychic Friends Network เป็นโค้ด C แบบ obfuscated ที่ตลกจริง ๆ เขียนโดย Michael Schatz กับคนของ RST Corporation มีทั้งฟังก์ชันช่วยหากรรมดี คำปรึกษาดวงชะตา การปรุงสปาเกตตีและพิซซ่าลึกลับ ใช้
#defineเปลี่ยนสมาชิกพรรคเดโมแครตให้เป็นคอมมิวนิสต์ และundefพระเจ้า เป็นต้น ตอนนี้ยังพยายามทำความเข้าใจอยู่ว่ามันทำอะไรกับ stack frame กันแน่ แต่ตราบใดที่ไม่ได้เจอ meta-meta-cheater มันไม่เคยได้ต่ำกว่า +998 ในหนึ่งแมตช์The Matrix เขียนโดย Darse Billings ผู้มีตำแหน่งอันทรงเกียรติว่า “Student for Life” และเอาชนะคู่แข่งทั้งหมดด้วยคะแนนสมบูรณ์แบบตามหลักการง่าย ๆ ว่า “ไม่มีช้อน”
The Matrix ยังเป็นโปรแกรมทัวร์นาเมนต์ด้วย จึงเข้าถึงอัลกอริทึม โครงสร้างข้อมูล และรูทีนเอาต์พุตอื่นทั้งหมดได้เต็มที่ ทำให้ไม่น่าจะมีใครแซงได้ในอนาคต ดังนั้นหมวดนี้จึงถูกประกาศว่าแก้จบแล้ว และถูกยกเลิกในรายการแข่งขันครั้งต่อ ๆ มา
สุดท้ายความโปร่งใสนั้นก็ช่วยให้ความปลอดภัยดีขึ้นจริง ๆ
LLL lattice reduction คืออัลกอริทึมเดียวกับที่ถูกใช้เจาะคีย์ PuTTY จาก nonce ที่มี bias ใน CVE เมื่อไม่กี่วันก่อน
tptacekอธิบายการโจมตีไว้เล็กน้อย และลิงก์โจทย์ cryptopals ที่ถ้าหรี่ตาดูแล้วก็พอแกล้งทำเป็นเข้าใจได้เกือบหมด https://news.ycombinator.com/item?id=40045377คล้าย ๆ กัน เซิร์ฟเวอร์ Minecraft ของ SciCraft เคยมีฟาร์ม creeper ที่ใช้เครื่องมือเหมือนมนตร์ดำบางอย่างควบคุมสถานะตัวสร้างเลขสุ่มแบบกำหนดได้ ทำให้สายฟ้า “สุ่ม” ผ่าบล็อกที่เจาะจงในทุกเฟรม เพื่อให้ได้ดรอปจาก creeper ดีขึ้น https://youtu.be/TM7SutJyDCk
ทั้งสามกรณี สิ่งที่ต้องใช้ก็แค่พีชคณิตเชิงเส้นพื้นฐาน และไม่เยอะด้วยซ้ำ Kelby อยากให้เข้าใจ Gram–Schmidt ซึ่งเป็นเนื้อหาราว ๆ ก่อนสอบกลางภาคของวิชาแนะนำพีชคณิตเชิงเส้นระดับปริญญาตรี
ไม่รู้จะหาคำไหนมาบรรยายว่าบทความนี้ยอดเยี่ยมแค่ไหน มันทำให้สัปดาห์นี้ดีขึ้นเลย
คำอธิบายแบบสั้นกระชับมากของกระบวนการเดียวกันที่ภายหลังสามารถลองทำตามด้วย Python ได้:
https://crypto.stackexchange.com/questions/37836/problem-wit...
https://youtu.be/ZcdN1wCJPqM?t=390
ตื่นมาตอนเช้าแล้วนึกภาพว่ามีบล็อกที่เมื่อคืนก่อนยังไม่มี ลอยอยู่บนฟ้า ตอนแรกดูเหมือนหมอกคล้ายผี แล้วไม่นานก็เห็นเป็นเรดสโตน, observer, บล็อกสไลม์ และเห็น TNT ร่วงลงมาแบบไม่รู้จบ
ทั้งหมดเกิดขึ้นเพียงเพราะเซิร์ฟเวอร์ทำตำแหน่งของฉันรั่วไหล ถึงอย่างนั้นก็ยังพอหนีได้อยู่ อาจมีเวลาไม่กี่วินาทีหยิบของจำเป็นจากหีบแล้วเผ่น หรือสร้างที่หลบภัยจาก obsidian ได้ แต่ก็มีเท่านั้น
เวลาไม่พอจะสร้างปืนใหญ่เล็งแม่น ๆ และยังไงก็คงเล็งระดับความสูงไม่ตรงอยู่ดี ถ้ามี elytra กับจรวดก็อาจบินไปก่อกวนได้ แต่มีหลุม world eater ขนาดยักษ์อยู่ห่างออกไปแค่ 16 ชังก์ เขาจะวางกับดักลาวาไว้ตามพอร์ทัล Nether แถว ๆ นั้นทุกแห่งหรือเปล่า?
เคยเห็น ปัญหาเครื่องกำเนิดเลขสุ่ม ที่น่าสนใจและตลกมามาก แต่กรณีนี้เป็นหนึ่งใน exploit ที่ซับซ้อนที่สุดเมื่อเทียบกับสิ่งที่ได้มา เหมือนผลงานศิลปะชั้นเยี่ยม
เป็น exploit ที่เจ๋งมาก
ไอเดียของเซิร์ฟเวอร์ที่ปล่อยให้ใช้บั๊กได้อย่างอิสระก็ดี และดูเหมือนเป็นอีกขั้นของเกมไปเลย
ถ้า metaverse เกิดขึ้นจริง การ “สู้กันจริง ๆ” คงจะมีหน้าตาแบบนี้ มากกว่าแค่ใช้กลไกต่อสู้ในเกม
เพราะมีไอเท็มราคาแพงที่ถูกปั๊มซ้ำกันมานานแล้ว PvP จึงกลายเป็นการโปรย end crystal ที่ถ้าทำลายแล้วสร้างความเสียหายมหาศาลอย่างต่อเนื่อง ส่วนการป้องกันก็ขึ้นอยู่กับว่ามี “Totem of Undying” ที่ดูดซับความเสียหายถึงตายได้มากแค่ไหน
แน่นอนว่าไคลเอนต์แฮ็กจะทำให้การวาง end crystal, การเติม totem, การระบุตำแหน่งอ่อนแอและแข็งแกร่งเป็นอัตโนมัติ แล้วผู้เล่นก็ทำตามคำแนะนำนั้นเพื่อสร้างความเสียหายต่อเนื่อง
ก่อนหน้านั้นอีกเล็กน้อย ยังมีดาบแฮ็กความเสียหาย +32,767 ที่ฆ่าทันที จนกว่าจะถูกแพตช์บนเซิร์ฟเวอร์
ARK: Survival Evolved และ Eve Online ขึ้นชื่อเรื่องแคลนยักษ์ระดับหลายพันคนที่ไปสุดทางกับเมตาเกมและการใช้บั๊ก
มันไม่ได้โรแมนติกเสมอไป ใน ARK เคยมีกลไกที่ทำให้ doxxing ผู้เล่นและบัญชี Steam หลายบัญชีของพวกเขาได้ และดูเหมือนว่าช่วง Great War ก็มีบางกรณีที่ความสัมพันธ์ในเกมลามออกไปสู่โลกจริง
บางครั้งก็เป็นวิธีพื้นฐานมาก ๆ เช่น ตอนถูกบุก ให้สร้างหอคอยยักษ์แล้วทำให้ถล่มเพื่อก่อ denial of service ให้เซิร์ฟเวอร์แครช จากนั้นเซิร์ฟเวอร์จะ rollback ไปยังแบ็กอัปเมื่อ 10–20 นาทีก่อน ทำให้ฐานที่มีผู้เล่นออนไลน์อยู่ถูกบุกได้ยากมาก เป็นวิธีเก่ามากและถูกแก้ไปหลายปีก่อนแล้ว
Rust ก็เคยมีนโยบายสนับสนุนให้เผยแพร่บั๊กและ exploit บน YouTube และเปิดเผยต่อสาธารณะ แต่มีเป้าหมายต่างออกไป คือให้ผู้พัฒนารู้เร็วขึ้นและแพตช์ได้เร็วขึ้น ผลคือมันกลายเป็นเกมที่ค่อนข้างแข็งแรง ซึ่งจะใช้ประโยชน์จากช่องโหว่ได้ยากมากถ้าไม่ใช้แฮ็กภายนอกจริง ๆ
แต่จำกัดเฉพาะสิ่งที่ใช้ประโยชน์ได้ด้วยมือผ่านคอนโทรลเลอร์ปกติเท่านั้น ไม่ใช่การแฮ็กจริง ๆ exploit หนึ่งชื่อ Wobbling ถูกแบนในปี 2019 ทั้งที่เกมนี้เป็นเกมปี 2001
เพิ่งดูวิดีโอหัวข้อนี้มา เป็นกรณีเตือนใจที่ชัดเจนถึงอันตรายเมื่อ แหล่งที่มาของความสุ่มหลายแห่งมีปฏิสัมพันธ์กัน และใช้ได้กับระบบสำคัญจำนวนมากด้วย
เพื่อประสิทธิภาพ เรามักแชร์เครื่องกำเนิดเลขสุ่มในโค้ด พอเจอเรื่องแบบนี้ก็ทำให้ต้องหยุดคิดจริง ๆ
เพราะจุดที่มีการอัปเดตน่าจะสังเกตได้ยากพอสมควร แต่กรณีนี้แสดงให้เห็นได้อย่างน่าประทับใจและสนุกว่าสัญชาตญาณนั้นผิด
วิดีโอนี้น่าทึ่ง: https://www.youtube.com/watch?v=maMpMOnIJDE
ไม่รู้มาก่อนว่าคอมมูนิตี้ซับซ้อนขนาดนี้
ถ้าเรื่องนี้ทำให้ทึ่ง ลองดูอันนี้ด้วย หัวจะระเบิด
https://www.youtube.com/watch?v=ea6py9q46QU
แล้วก็
https://www.youtube.com/watch?v=GaRurhiK-Lk
ยิ่งไปกว่านั้น การแคร็กเครื่องกำเนิดเลขสุ่ม แบบนี้เคยถูกนำไปทำไว้ภายในเกมด้วย
https://youtu.be/FPmQ0rnJjNc?si=tTFObcfZ-ILanL_A
น่าทึ่งที่มีเครื่องที่สร้างขึ้นใน Minecraft เองชื่อ Mess Detector มันใช้ตำแหน่งของ TNT ที่ถูกจุดชนวนแทน block drop เพื่อคาดเดาสถานะภายในของเครื่องกำเนิดเลขสุ่ม
https://www.youtube.com/watch?v=FPmQ0rnJjNc
อันนี้ดูเหมือน การโจมตีขยายผลจากความเสียหายของสถานะ (https://en.wikipedia.org/wiki/Random_number_generator_attack)
เป็นการโจมตีที่ PRNG ซึ่งไม่ใช่ตัวสร้างเลขสุ่มเทียมที่ปลอดภัยเชิงเข้ารหัส (CSPRNG) อาจโดนได้
ตอนนี้การที่ไลบรารีให้ PRNG เป็นค่าเริ่มต้นเองเริ่มรู้สึกไม่ค่อยปลอดภัยแล้ว คล้ายกับการอนุญาต TLSv1.0 หรือ blowfish เป็นค่าเริ่มต้นในปี 2024