1 คะแนน โดย GN⁺ 2024-04-19 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • 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
    • คำอธิบายที่เกี่ยวข้องอยู่ที่ nocom-explanation

เวอร์ชันที่มีช่องโหว่และความผิดพลาดในโค้ด

  • ปัญหานี้มีอยู่ตั้งแต่ 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());
}
  • หากกังวลเรื่อง performance สามารถสร้างฟิลด์ RNG แยกสำหรับการสร้างโลกโดยเฉพาะชื่อ separateRandOnlyForWorldGen และไม่แชร์กับการใช้งานอื่น
  • แพตช์สำหรับ PaperMC 1.12.2 มีให้ที่ PaperWithRandarPatched commit และ ไฟล์ patch ทางเลือก

ภาคผนวกของ 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 ความคิดเห็น

 
GN⁺ 2024-04-19
ความคิดเห็นบน 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

    • นั่นแหละผมเอง ดีใจที่ได้เห็นคำพูดเก่า ๆ ถูกอ้างถึงอีกครั้ง: “ด้วยฝีมือทางเทคนิคที่ยอดเยี่ยมและทัศนคติแบบ ‘โกงให้เร็ว โกงให้บ่อย’ Tim น่าจะมีเส้นทางอาชีพที่สดใสในฐานะโปรแกรมเมอร์ AI ในอุตสาหกรรมเกมคอมพิวเตอร์ :)”
      แต่จริง ๆ แล้วผมไปสาย ความปลอดภัย เขียน RFC ของ TLS และกลายเป็น Distinguished Engineer ฝ่ายความปลอดภัยของ Google ขอบคุณที่ทำให้นึกถึงความหลัง
    • ปีแรกผมส่ง cheesebot ซึ่งเป็นผลงานที่แย่ที่สุดอย่างเหมาะเจาะเข้าประกวด
      https://web.archive.org/web/20180719050236/http://webdocs.cs...
    • คำอธิบายผลงานในหมวด “supermodified” ทั้งหมดนี่ตลกมาก
      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

    • Sean กับ Kelby อธิบายได้ดีกว่ามากว่า LLL คืออะไร แต่ถ้าถามว่าทำไม LLL ถึงมีอยู่ บทความนี้ใกล้เคียงกับสิ่งที่ดีที่สุดเท่าที่เคยเห็นมา
      ทั้งสามกรณี สิ่งที่ต้องใช้ก็แค่พีชคณิตเชิงเส้นพื้นฐาน และไม่เยอะด้วยซ้ำ Kelby อยากให้เข้าใจ Gram–Schmidt ซึ่งเป็นเนื้อหาราว ๆ ก่อนสอบกลางภาคของวิชาแนะนำพีชคณิตเชิงเส้นระดับปริญญาตรี
      ไม่รู้จะหาคำไหนมาบรรยายว่าบทความนี้ยอดเยี่ยมแค่ไหน มันทำให้สัปดาห์นี้ดีขึ้นเลย
      คำอธิบายแบบสั้นกระชับมากของกระบวนการเดียวกันที่ภายหลังสามารถลองทำตามด้วย Python ได้:
      https://crypto.stackexchange.com/questions/37836/problem-wit...
    • ยังมี การควบคุมเลขสุ่ม ที่ทำให้บล็อกตกเป็นค่าสูงสุดเสมอด้วย อธิบายไว้ที่นี่
      https://youtu.be/ZcdN1wCJPqM?t=390
    • “เครื่องมือเหมือนมนตร์ดำ”, “ถ้าหรี่ตาดูแล้วก็พอแกล้งทำเป็นเข้าใจได้เกือบหมด” นี่แหละตัวผมเวลาอ่านคริปโต :D
  • ตื่นมาตอนเช้าแล้วนึกภาพว่ามีบล็อกที่เมื่อคืนก่อนยังไม่มี ลอยอยู่บนฟ้า ตอนแรกดูเหมือนหมอกคล้ายผี แล้วไม่นานก็เห็นเป็นเรดสโตน, observer, บล็อกสไลม์ และเห็น TNT ร่วงลงมาแบบไม่รู้จบ
    ทั้งหมดเกิดขึ้นเพียงเพราะเซิร์ฟเวอร์ทำตำแหน่งของฉันรั่วไหล ถึงอย่างนั้นก็ยังพอหนีได้อยู่ อาจมีเวลาไม่กี่วินาทีหยิบของจำเป็นจากหีบแล้วเผ่น หรือสร้างที่หลบภัยจาก obsidian ได้ แต่ก็มีเท่านั้น
    เวลาไม่พอจะสร้างปืนใหญ่เล็งแม่น ๆ และยังไงก็คงเล็งระดับความสูงไม่ตรงอยู่ดี ถ้ามี elytra กับจรวดก็อาจบินไปก่อกวนได้ แต่มีหลุม world eater ขนาดยักษ์อยู่ห่างออกไปแค่ 16 ชังก์ เขาจะวางกับดักลาวาไว้ตามพอร์ทัล Nether แถว ๆ นั้นทุกแห่งหรือเปล่า?

  • เคยเห็น ปัญหาเครื่องกำเนิดเลขสุ่ม ที่น่าสนใจและตลกมามาก แต่กรณีนี้เป็นหนึ่งใน exploit ที่ซับซ้อนที่สุดเมื่อเทียบกับสิ่งที่ได้มา เหมือนผลงานศิลปะชั้นเยี่ยม

    • ถ้าขายไอเท็ม ก็น่าจะทำเงินได้บ้าง อาจระดับหลายพันดอลลาร์ แน่นอนว่าเมื่อเทียบกับงานที่ลงไปก็ยังเป็นผลตอบแทนเล็กน้อยอยู่ดี
    • ชอบมากที่การตัดสินใจของนักพัฒนา Mojang ซึ่งดูเหมือนไม่มีพิษภัย ถูกนำมาใช้โจมตีในกรณีนี้ได้อย่างไร เจ๋งสุด ๆ
  • เป็น exploit ที่เจ๋งมาก
    ไอเดียของเซิร์ฟเวอร์ที่ปล่อยให้ใช้บั๊กได้อย่างอิสระก็ดี และดูเหมือนเป็นอีกขั้นของเกมไปเลย
    ถ้า metaverse เกิดขึ้นจริง การ “สู้กันจริง ๆ” คงจะมีหน้าตาแบบนี้ มากกว่าแค่ใช้กลไกต่อสู้ในเกม

    • การต่อสู้ใน 2b2t ก็ไม่ได้ดูเหมือน Minecraft ปกติ
      เพราะมีไอเท็มราคาแพงที่ถูกปั๊มซ้ำกันมานานแล้ว PvP จึงกลายเป็นการโปรย end crystal ที่ถ้าทำลายแล้วสร้างความเสียหายมหาศาลอย่างต่อเนื่อง ส่วนการป้องกันก็ขึ้นอยู่กับว่ามี “Totem of Undying” ที่ดูดซับความเสียหายถึงตายได้มากแค่ไหน
      แน่นอนว่าไคลเอนต์แฮ็กจะทำให้การวาง end crystal, การเติม totem, การระบุตำแหน่งอ่อนแอและแข็งแกร่งเป็นอัตโนมัติ แล้วผู้เล่นก็ทำตามคำแนะนำนั้นเพื่อสร้างความเสียหายต่อเนื่อง
      ก่อนหน้านั้นอีกเล็กน้อย ยังมีดาบแฮ็กความเสียหาย +32,767 ที่ฆ่าทันที จนกว่าจะถูกแพตช์บนเซิร์ฟเวอร์
    • การที่สมดุลไหลไปรวมศูนย์อยู่รอบบั๊กและ exploit เป็นเรื่องค่อนข้างปกติใน เกมแซนด์บ็อกซ์ PvP ที่แข่งขันกันดุเดือด แม้เซิร์ฟเวอร์จะไม่อนุญาตก็ตาม
      ARK: Survival Evolved และ Eve Online ขึ้นชื่อเรื่องแคลนยักษ์ระดับหลายพันคนที่ไปสุดทางกับเมตาเกมและการใช้บั๊ก
      มันไม่ได้โรแมนติกเสมอไป ใน ARK เคยมีกลไกที่ทำให้ doxxing ผู้เล่นและบัญชี Steam หลายบัญชีของพวกเขาได้ และดูเหมือนว่าช่วง Great War ก็มีบางกรณีที่ความสัมพันธ์ในเกมลามออกไปสู่โลกจริง
      บางครั้งก็เป็นวิธีพื้นฐานมาก ๆ เช่น ตอนถูกบุก ให้สร้างหอคอยยักษ์แล้วทำให้ถล่มเพื่อก่อ denial of service ให้เซิร์ฟเวอร์แครช จากนั้นเซิร์ฟเวอร์จะ rollback ไปยังแบ็กอัปเมื่อ 10–20 นาทีก่อน ทำให้ฐานที่มีผู้เล่นออนไลน์อยู่ถูกบุกได้ยากมาก เป็นวิธีเก่ามากและถูกแก้ไปหลายปีก่อนแล้ว
      Rust ก็เคยมีนโยบายสนับสนุนให้เผยแพร่บั๊กและ exploit บน YouTube และเปิดเผยต่อสาธารณะ แต่มีเป้าหมายต่างออกไป คือให้ผู้พัฒนารู้เร็วขึ้นและแพตช์ได้เร็วขึ้น ผลคือมันกลายเป็นเกมที่ค่อนข้างแข็งแรง ซึ่งจะใช้ประโยชน์จากช่องโหว่ได้ยากมากถ้าไม่ใช้แฮ็กภายนอกจริง ๆ
    • จุดกึ่งกลางคือ Super Smash Bros Melee กลยุทธ์ในเกมจำนวนมากที่อนุญาตในการแข่งขันอาศัยบั๊ก
      แต่จำกัดเฉพาะสิ่งที่ใช้ประโยชน์ได้ด้วยมือผ่านคอนโทรลเลอร์ปกติเท่านั้น ไม่ใช่การแฮ็กจริง ๆ exploit หนึ่งชื่อ Wobbling ถูกแบนในปี 2019 ทั้งที่เกมนี้เป็นเกมปี 2001
    • ในมุมเกมเพลย์ ฉันค่อนข้างชอบไอเดียเซิร์ฟเวอร์อนาธิปไตยจริง ๆ แต่ใน 2b2t จริง ๆ แชตมีคำ n-word เยอะเกินไป เลยเลิกเล่น
    • “เซิร์ฟเวอร์ที่ปล่อยให้ใช้บั๊กได้อย่างอิสระ” นี่จริง ๆ แล้วก็เท่ากับ เซิร์ฟเวอร์ CS 1.6 ที่ไม่มี VAC ทั้งหมดไม่ใช่เหรอ?
  • เพิ่งดูวิดีโอหัวข้อนี้มา เป็นกรณีเตือนใจที่ชัดเจนถึงอันตรายเมื่อ แหล่งที่มาของความสุ่มหลายแห่งมีปฏิสัมพันธ์กัน และใช้ได้กับระบบสำคัญจำนวนมากด้วย
    เพื่อประสิทธิภาพ เรามักแชร์เครื่องกำเนิดเลขสุ่มในโค้ด พอเจอเรื่องแบบนี้ก็ทำให้ต้องหยุดคิดจริง ๆ

    • คิดว่าไม่เคยใช้ตัวสร้างเลขสุ่มเทียมในซอฟต์แวร์จริงจัง แต่ตามสัญชาตญาณเคยคิดว่าการใช้เครื่องกำเนิดเลขสุ่มตัวเดียวกันให้มากที่สุดน่าจะทำให้การโจมตีแบบนี้ยากขึ้น
      เพราะจุดที่มีการอัปเดตน่าจะสังเกตได้ยากพอสมควร แต่กรณีนี้แสดงให้เห็นได้อย่างน่าประทับใจและสนุกว่าสัญชาตญาณนั้นผิด
  • วิดีโอนี้น่าทึ่ง: https://www.youtube.com/watch?v=maMpMOnIJDE
    ไม่รู้มาก่อนว่าคอมมูนิตี้ซับซ้อนขนาดนี้

    • การบรรยายของวิดีโอนี้เวอร์มากจนเหมือนกำลังพูดถึง Stuxnet เลย แต่ก็ดี
    • Minecraft กับคอมมูนิตี้อนาธิปไตยของ MC นี่บ้าจริง ๆ
      ถ้าเรื่องนี้ทำให้ทึ่ง ลองดูอันนี้ด้วย หัวจะระเบิด
      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