วิธีใช้งานฟีเจอร์ Discord Nitro ได้ฟรี
(archive.md)- Discord ซึ่งเป็นแอปเดสก์ท็อปที่สร้างบน Electron ทำงานภายในเป็นหน้าต่าง Chromium จึงสามารถเปิดเครื่องมือนักพัฒนาเว็บได้ และใช้แก้ไขโค้ดฝั่งไคลเอนต์ได้
- ไคลเอนต์ม็อดและปลั๊กอินบางตัวสามารถปลดล็อกฟีเจอร์บางส่วนที่ต้องใช้ สมาชิกแบบเสียเงิน Nitro ได้จากฝั่งไคลเอนต์
- แกนสำคัญคือการฉีดโค้ดเข้าไปในตัวแปร
webpackChunkdiscord_appซึ่งเก็บโมดูลที่ถูกแยกด้วย Webpack code splitting เพื่อสำรวจและแทนที่ฟังก์ชันภายใน - ฟังก์ชันตรวจสอบคุณภาพการแชร์หน้าจอถูกตรวจสอบแค่ฝั่งไคลเอนต์จึงเลี่ยงได้ แต่ ธีมพรีเมียม มีการตรวจสอบการซิงก์จากเซิร์ฟเวอร์เพิ่มเติม
- เทคนิคสาธิตทั้งหมด ละเมิดข้อกำหนดการใช้งานของ Discord และมีความเสี่ยงทั้งการถูกระงับบัญชีและการถูกขโมยบัญชีจากการรันโค้ดที่ไม่ได้รับการตรวจสอบ
ภาพรวม
- มี ไคลเอนต์ Discord แบบม็อด จำนวนมากที่เปลี่ยนหน้าตาหรือเพิ่มฟีเจอร์ได้ และปลั๊กอินบางตัวถึงขั้นปลดล็อกฟีเจอร์ที่ต้องใช้ Nitro แบบเสียเงิน
- บทความนี้อธิบายหลักการทางเทคนิคที่ทำให้สิ่งเหล่านี้เป็นไปได้ผ่านการวิเคราะห์โครงสร้างของไคลเอนต์
การเปิดใช้งานเครื่องมือนักพัฒนา
- Discord พัฒนาด้วยเฟรมเวิร์ก Electron สำหรับสร้างแอปข้ามแพลตฟอร์มด้วยเทคโนโลยีเว็บ จึงมีลักษณะคล้ายเว็บไซต์ที่ทำงานอยู่ในเว็บเบราว์เซอร์
- โดยแก่นแล้วมันคือ หน้าต่าง Chromium จึงเปิดเครื่องมือนักพัฒนาได้ แต่ค่าเริ่มต้นจะปิดไว้
- มีหลายกรณีที่ผู้ใช้ถูก social engineering จากผู้ไม่หวังดีให้วางคำสั่งอันตราย จนบัญชีถูกขโมย ทำให้ฟีเจอร์นี้ถูกปิดกั้น
- หากเข้าใจความเสี่ยงแล้ว สามารถเปิดได้โดยเพิ่มค่า
DANGEROUS_ENABLE_DEVTOOLS_ONLY_ENABLE_IF_YOU_KNOW_WHAT_YOURE_DOINGเป็นtrueในไฟล์ตั้งค่า%appdata%/discord/settings.json- จากนั้นใช้
ctrl + shift + iเพื่อเปิดคอนโซลนักพัฒนา
- จากนั้นใช้
การแพตช์ฟังก์ชันของ Discord
- เพื่อเพิ่มประสิทธิภาพตอนโหลดครั้งแรก โค้ดจะถูกแยกเป็นหลายชังก์และโหลดแบบขนานหรือแบบหน่วงเวลา (lazy-loaded) โดยใช้ฟีเจอร์ code splitting ของ Webpack
- ชังก์ที่โหลดแล้วทั้งหมดจะถูกเก็บไว้ในตัวแปร
webpackChunkdiscord_app - หากต้องการรันโค้ดที่ใช้ตัวแปรหรือฟังก์ชันของ Discord จำเป็นต้อง ฉีด (inject) โค้ดเข้าไปในตัวแปรนี้
a.cคืออ็อบเจ็กต์ที่เก็บ โมดูล ทั้งหมด โดยแต่ละโมดูลมีรูปแบบchunk_id,loaded,exports- ใน
exportsจะมีฟังก์ชัน อ็อบเจ็กต์ หรือค่าพื้นฐานที่โมดูลนั้น export ออกมา
- สามารถสร้างฟังก์ชัน
findเพื่อวนดู JavaScript หลายโมดูลแล้วค้นหาและเรียกใช้ฟังก์ชันเป้าหมายได้- ตัวอย่าง: ค้นหาและเรียกฟังก์ชัน
getCurrentUser()
- ตัวอย่าง: ค้นหาและเรียกฟังก์ชัน
- ฟังก์ชันต้นฉบับยังสามารถถูก แทนที่ (replace) ด้วยฟังก์ชันอื่นเพื่อเปลี่ยนพฤติกรรมได้ จึงแก้ไขโค้ดได้โดยตรง
การปลดล็อกสตรีมคุณภาพสูง
- เนื้อหาหลังจากนี้ ขัดต่อข้อกำหนดการใช้งานของ Discord อย่างชัดเจน และอาจนำไปสู่การถูกระงับบัญชี ผู้ใช้ต้องยอมรับความเสี่ยงเอง
- ฟังก์ชัน
canStreamMidQualityและcanStreamHighQualityที่ใช้ตรวจสอบระดับสมาชิกของผู้ใช้จะถูกเรียกก่อนหน้าหน้าจอเลือกคุณภาพการแชร์หน้าจอ- หากบังคับให้ค่าที่ทั้งสองฟังก์ชันส่งคืนเป็น
trueก็จะสามารถเลือกแชร์หน้าจอที่ ความละเอียดต้นฉบับ 60 FPS ได้แม้ไม่ได้สมัคร Nitro
- หากบังคับให้ค่าที่ทั้งสองฟังก์ชันส่งคืนเป็น
- ปัจจุบันดูเหมือนว่า Discord ไม่ได้ตรวจสอบจากฝั่งเซิร์ฟเวอร์ ว่าสตรีมที่ส่งออกมาปฏิบัติตามข้อจำกัดของผู้ไม่สมัครจริงหรือไม่
- อย่างไรก็ตาม Discord ยังไม่ได้ใช้ End-to-End encryption จึงยังมีความเป็นไปได้ที่จะตรวจจับได้
- ตามบทความอ้างอิง Discord มีการตรวจสอบคอนเทนต์เสียงและวิดีโอของผู้ใช้อยู่แล้ว และอาจเพิ่มการตรวจสอบฝั่งเซิร์ฟเวอร์ก่อนการแชร์หน้าจอในอนาคต
การปลดล็อกธีมพรีเมียม
- หากเปลี่ยนค่าที่ฟังก์ชัน
canUseClientThemesส่งคืน ซึ่งบอกว่าผู้ใช้สามารถใช้ธีม Nitro ได้หรือไม่ ให้เป็นtrueปุ่มเลือกธีมพรีเมียมก็จะถูกปลดล็อก - แต่ธีมจะถูกใช้เพียงชั่วครู่แล้วกลับไปเป็นธีมเริ่มต้นทันที
- เพราะไคลเอนต์พยายามบันทึกการเปลี่ยนธีม แต่ เซิร์ฟเวอร์ตรวจสอบว่าไม่มีสิทธิ์ และเมื่อได้รับการตอบกลับก็จะนำธีมเริ่มต้นกลับมาใช้อีกครั้ง
- หากแพตช์ฟังก์ชัน
shouldSyncให้คืนค่าfalseเมื่อค่าเป็นappearanceเพื่อบล็อกเฉพาะการซิงก์การตั้งค่ารูปลักษณ์ การเปลี่ยนธีมก็จะคงอยู่ - ธีมถูกจัดการ ทั้งหมดจากฝั่งไคลเอนต์ และยังสามารถแก้ CSS ได้โดยตรงเสมอ จึงเป็นเรื่องยากที่ Discord จะป้องกันสิ่งนี้ได้
บทสรุป
- แม้จะมีโค้ดที่ทำให้การแฮ็กตามตัวอย่างนำไปใช้ได้ง่าย แต่การแก้ไขไคลเอนต์หรือใช้ม็อดควรทำอย่างระมัดระวัง
- Discord สามารถระงับบัญชีที่ละเมิดข้อกำหนดการใช้งานได้ทุกเมื่อ และการ รันโค้ดที่ไม่ได้รับการตรวจสอบ ซึ่งมีสิทธิ์เข้าถึงบัญชีนั้นอันตรายอย่างยิ่ง
- ข้อความที่เข้ารหัสไว้ในบทความ: "อย่าวางโค้ดที่คุณไม่เข้าใจลงในคอนโซลนักพัฒนา — นี่คือวิธีที่ง่ายที่สุดในการถูกขโมยบัญชี"
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
ถ้าใช้วิธีให้รัน blob ที่เข้ารหัส base64 ง่าย ๆ ต่อท้ายแล้วเปิดใช้ทุกฟีเจอร์ได้ทั้งหมด ก็คิดว่าอาจกลายเป็นช่องทางโจมตีที่ค่อนข้างง่ายได้
ไม่ได้หมายความว่าสงสัยผู้เขียนนะ แต่เมื่อกี้ลองถอดรหัสดูแล้วโดนเข้าให้เต็ม ๆ
base64 --decodeผลลัพธ์เป็นแบบนี้:// Here's a cake if you thought about inspecting the code before executing it:let css = 'font-size: 36px; font-weight: bold; color: red';console.log("%cNEVER paste code you don't understand into the development console.", css);console.log("%cThis is the best way to compromise your account.", css);“ตอนนี้ดูเหมือนว่า Discord ไม่ได้ตรวจสอบฝั่งเซิร์ฟเวอร์ว่าสตรีมที่ส่งอยู่นั้นปฏิบัติตามเกณฑ์ของผู้ไม่ได้สมัครสมาชิกจริงหรือไม่” ฟังแล้วสงสัยว่าใครคิดว่านี่เป็นการ implement ที่ดี
การตรวจสอบฝั่งไคลเอนต์ ดูเหมือนความผิดพลาดระดับมือใหม่จริง ๆ
ผมใช้ Discord มาหลายปี เพิ่งเคยได้ยินครั้งแรกว่ามีความพยายามเลี่ยงโครงสร้างสิทธิ์เข้าถึงของ Nitro และถ้ามันไม่ได้แพร่หลาย ก็ไม่เห็นเหตุผลให้ต้องใส่ใจนัก
อีกเรื่องหนึ่ง เดือนนี้ผมเพิ่งเริ่มงานใหม่เป็นงานที่ห้าแล้ว และดูเหมือนจะเข้ากับ project manager ไม่ได้เอาเสียเลย
คิดว่าคงมีสักกี่คนที่เข้าใจการแฮ็กแบบนี้และยังเต็มใจจ่ายเงินให้ Nitro อยู่ดี อาจมีคนใช้ม็อดไคลเอนต์ Discord หลายตัวที่เปิดใช้ฟีเจอร์บางส่วนหรือทั้งหมดของ Nitro อยู่เป็นพัน ๆ หรืออาจเป็นหมื่น ๆ คน แต่ก็สงสัยว่าถ้าบล็อกสิ่งนี้ได้จะทำให้เกิดรายได้จริงเพิ่มขึ้นสักเท่าไร
ส่วนตัวถ้าจำเป็นหรือต้องการฟีเจอร์นั้น ผมยอมจ่ายเดือนละ 10 ดอลลาร์จะยุ่งยากน้อยกว่ามาก ดีกว่าต้องคอยตามม็อดที่จะพังทุกครั้งที่ Discord อัปเดต และต้องหวังว่าผู้ดูแลจะไม่ใส่โค้ดอันตรายลงไป
ช่องถูกซ่อนเฉพาะฝั่งไคลเอนต์เท่านั้น เพื่อให้ชัดเจน ถึงอย่างนั้นก็ไม่ได้แปลว่าจะดูเนื้อหาข้อความในช่องนั้นได้
เซิร์ฟเวอร์เสียงแค่ตรวจสอบกับ API ว่ามีสิทธิ์เข้าหรือไม่ และหลังจากนั้นก็ทำงานเหมือนตัว broadcast แพ็กเก็ตแบบหนึ่งต่อหลาย
นี่ใกล้เคียงกับ แฮ็กเกอร์ แบบคลาสสิกในความหมายของคนที่อยากรู้อยากเห็นและมีฝีมือ
ไม่มีความเสียหายร้ายแรง และช่วยเตือนอีกครั้งว่าแอปไม่ใช่เวทมนตร์ และโค้ดก็เจ๋ง
เพราะจะได้พยายามรีดเงินจากเราให้มากขึ้นโดยไม่มีแรงต้าน
ขอเตือนอีกครั้งว่า ทุกอย่างที่ส่งผ่าน Discord รวมถึง DM จะถูกบันทึกเป็นข้อความล้วนใน Discord และ Discord รวมถึงผู้ที่ซื้อบริษัทนั้นจะเข้าถึงได้
ครั้งหนึ่งดูเหมือน Microsoft จะซื้อ และตอนนี้ดูเหมือนจะมุ่งไปทาง IPO
แค่มีบัญชีก็ทำให้บทสนทนาส่วนตัวที่เอื้อต่อการทำ data mining สำหรับ AI หรือการใช้งานโดย Discord และผู้ดูแลฐานข้อมูล/ระบบ กลายเป็นเรื่องปกติ Section 702 ของ FISA Amendments Act (FAA702) อนุญาตให้หน่วยสืบสวนของรัฐบาลกลางเข้าถึงข้อมูลแบบนั้นได้โดยไม่ต้องมีหมายค้น
แค่ความเป็นไปได้ในการ front-run คริปโต ก็น่าจะมีมูลค่าหลายสิบล้านดอลลาร์ต่อวันแล้ว
ถ้าเป็นเพื่อนกัน ก็ไม่ควรแนะนำให้เพื่อนใช้ระบบแชตที่ไม่ใช่การเข้ารหัสแบบ end-to-end อย่ากลายเป็นน้ำผึ้งในกับดัก
นี่เป็นเรื่องปกติ เว้นแต่ว่าคุณจะใช้หนึ่งในไม่กี่บริการที่ implement zero trust model ของจริงซึ่งผู้ใช้จัดการกุญแจเอง เหตุผลที่เก็บข้อความก็เพื่อให้ผู้ใช้กลับมาเข้าถึงได้อีก
มีบริการอย่าง Matrix ที่ทำ group messaging แบบเข้ารหัส end-to-end ได้ในวิธีที่ค่อนข้างเป็นมิตร แต่ก็เป็นข้อยกเว้น การกล่าวหาเฉพาะ Discord ว่ามีเจตนาร้ายเป็นพิเศษเพียงเพราะทำแบบเดียวกับที่แพลตฟอร์มสื่อสารอิเล็กทรอนิกส์ 95% ทำกันมานั้นไม่ยุติธรรม
ไม่ได้หมายความว่านั่นเป็นเรื่องดี แต่ในบางชุมชนไม่มีทางเลือกอื่นนอกจากไม่เข้าร่วม
แย่กว่าสมัย “ทุกคนใช้ WhatsApp” ด้วยซ้ำ ตอนนั้นเรายังมีเบอร์ของอีกฝ่าย เลยติดต่อด้วยวิธีอื่นได้ง่าย แต่เสน่ห์ของ Discord ไม่ใช่บทสนทนาส่วนตัว แต่เป็นชุมชนที่มีพื้นที่กึ่งสาธารณะ ในที่นี้ “สาธารณะ” ไม่ได้หมายถึงเปิดให้ทุกคน แต่ใกล้เคียงกับมีคนอ่านสัก 100 คน
เมื่อลบข้อความแล้ว ข้อความจะไม่ถูกเก็บในฐานข้อมูลอีกต่อไป
เมื่อไม่นานมานี้ OpenAI ปิด Discord สำหรับ beta tester อย่างกะทันหัน ทำให้เราไม่สามารถดูได้อีกว่าเคยคุยกับใครและคุยเรื่องอะไร
ผมสงสัยว่ามีวิธี export แชตเพื่อไม่ให้ผู้ดูแลเซิร์ฟเวอร์ตัดขาดชุมชนออกจากกันโดยไม่เหลือวิธีไล่ดูประวัติหรือไม่
มี Chrome extension สำหรับ export แชต Discord อยู่พอสมควร แต่ดูเหมือนส่วนใหญ่จะล็อกฟีเจอร์บางส่วนไว้แบบเสียเงิน
ปรากฏว่ามันง่ายมากที่จะคัดลอก ซอร์สของ extension จากโฟลเดอร์ Chrome แล้วแก้ boolean check อย่าง
is_proใน JavaScript จากนั้นโหลดกลับเข้าไปใหม่เป็น unpacked extensionเป็นโปรแกรม standalone ที่ใช้ API แบบไม่เป็นทางการ แต่ผมยังไม่เคยเห็นใครถูกแบนเพราะใช้สิ่งนี้
เขาเตือนอย่างถูกต้องว่าใช้ทริกแบบนี้แล้วอาจถูกแบนได้ แต่ Discord เคยมี ประวัติแบน ผู้ใช้เพราะเรื่องแบบนี้หรือเปล่า?
แม้แต่การใช้ไคลเอนต์ทางเลือกก็ถูกห้าม ถ้าบัญชีสำคัญ ก็อย่าไปยุ่งกับ Discord จะดีกว่า
“การแก้ไขไคลเอนต์ขัดต่อข้อกำหนดการใช้บริการของ Discord”
อย่างไรก็ตาม Discord ค่อนข้างไม่สนใจเรื่องนี้ และไม่มีกรณีที่เป็นที่รู้จักว่าถูกแบนเพราะใช้ม็อดไคลเอนต์ ดังนั้นถ้าไม่ใช้ปลั๊กอินที่ implement พฤติกรรมในทางละเมิด โดยทั่วไปก็น่าจะไม่เป็นไร ไม่ต้องกังวล เพราะว่ากันว่าปลั๊กอินในตัวทั้งหมดปลอดภัย
พอเข้าใจได้ว่าธีมบางอย่างเปิดใช้ด้วยวิธีแบบนี้ แต่การให้ คุณภาพการสตรีม ถูกตัดสินด้วยการตรวจฝั่งไคลเอนต์แทนที่จะเป็นฝั่งเซิร์ฟเวอร์นั้นค่อนข้างเข้าใจยาก
ไม่จำเป็นต้องเข้าถึงวิดีโอจริง และแม้จะเข้ารหัสเต็มรูปแบบ ก็ยังดูจากปริมาณข้อมูลที่ส่งได้ว่ากำลังสตรีมด้วยคุณภาพใด
หลักใหญ่ของวิศวกรรม frontend ถูกพิสูจน์ว่าถูกต้องอีกครั้ง
“อย่าเชื่อใจ ไคลเอนต์ เด็ดขาด ไม่มีวัน”
ตั้งแต่เห็นว่ามันทำได้ฝั่งไคลเอนต์อย่างเดียว ผมก็เปิด developer tools แล้วใช้ ปุ่มสตรีม 1080p60 มาตลอด และมันใช้งานได้จริง
ไม่รู้ว่ากี่ปีแล้ว แต่ดูเหมือนฝั่ง Discord ไม่มีใครสนใจ
เมื่อก่อนเคยพยายามเดินเส้นทางนี้ แต่สุดท้ายก็ยอมแพ้ เพราะหาวิธีแพตช์ไคลเอนต์ให้สม่ำเสมอไม่ได้ โดยเฉพาะหลังอัปเดต
แต่พอเห็นวิธีนี้แล้วก็เกิดแรงกระตุ้นอีกครั้งว่า “อยากแกะดูแล้วจิ้ม ๆ”
มีวิธีง่าย ๆ สำหรับไล่ดู API ที่ใช้ได้ด้วยวิธีนี้ไหม? เคยพยายาม log ทุกอย่าง แต่เละเทะเกินไปเพราะมี map, i18n และอื่น ๆ สงสัยว่ามีใครลงแรงทำ เอกสาร reverse engineering อะไรไว้บ้างหรือเปล่า