คำเตือนความเสี่ยง: ระวังความเสี่ยงจากการระดมทุนที่ผิดกฎหมายในนาม 'สกุลเงินเสมือน' 'บล็อกเชน' — จากห้าหน่วยงานรวมถึงคณะกรรมการกำกับดูแลการธนาคารและการประกันภัย
ข่าวสาร
ค้นพบ
ค้นหา
เข้าสู่ระบบ
简中
繁中
English
日本語
한국어
ภาษาไทย
Tiếng Việt
BTC
ETH
HTX
SOL
BNB
ดูตลาด
ช่องโหว่ "อินพุตนามแฝง" ของสัญญา zkSNARK ทำให้โครงการผสมเหรียญจำนวนมากระเบิด
安比(SECBIT)实验室
特邀专栏作者
2019-07-29 07:41
บทความนี้มีประมาณ 4349 คำ การอ่านทั้งหมดใช้เวลาประมาณ 7 นาที
ฉันหวังว่าเทคโนโลยีใหม่ๆ ระลอกนี้ ชุมชนจะสามารถซึมซับบทเรียนอันเจ็บปวดในอดีตได้อย่างเต

หมายเหตุบรรณาธิการ: บทความนี้มาจาก หมายเหตุบรรณาธิการ: บทความนี้มาจาก(ID:secbitlabs)แอมบี้ แลบอราทอรีส์

เนื่องจากมีการใช้ไลบรารีสัญญา zkSNARKs บางอย่างอย่างผิดพลาดในโครงการที่พิสูจน์แล้วไม่มีความรู้จำนวนมาก จึงมีการนำช่องโหว่ "Input Aliasing" มาใช้ ซึ่งอาจนำไปสู่การปลอมแปลงใบรับรอง การใช้จ่ายซ้ำซ้อน การเล่นซ้ำ และการโจมตีอื่นๆ และค่าใช้จ่ายในการโจมตี ต่ำมาก โครงการโอเพ่นซอร์สจำนวนมากในชุมชน Ethereum ได้รับผลกระทบ รวมถึง zkSNARKs ที่ใช้บ่อยที่สุดสามแห่งที่ใช้กันมากที่สุดคือ snarkjs, ethsnarks และ ZoKrates เช่นเดียวกับสามสกุลเงินที่ได้รับความนิยมล่าสุด นี่เป็นการฆาตกรรมที่เกิดจากรหัสที่โพสต์โดย Chris บิดาแห่งภาษา Solidity เมื่อสองปีที่แล้ว

ชื่อเรื่องรอง

ช่องโหว่การใช้จ่ายสองเท่า: การเปิดเผยครั้งแรก

Semaphore เป็นระบบ Semaphore ที่ไม่ระบุตัวตนโดยใช้เทคโนโลยีการพิสูจน์ความรู้เป็นศูนย์ ซึ่งพัฒนามาจากโครงการผสมเหรียญก่อนหน้านี้ของนักพัฒนาชื่อดัง barryWhiteHat

นักพัฒนาซอฟต์แวร์ชาวรัสเซีย poma ชี้ให้เห็นว่าโครงการอาจมีช่องโหว่แบบ double-spend [1]

ปัญหาอยู่ในรหัสบรรทัดที่ 83 [2] โปรดดูอย่างละเอียด

ฟังก์ชันนี้ต้องการให้ผู้โทรสร้างหลักฐานที่ไม่มีความรู้ว่าเขาสามารถถอนเงินจากสัญญาได้ เพื่อป้องกันไม่ให้เกิด "การใช้จ่ายซ้ำซ้อน" ฟังก์ชันยังอ่าน "รายการละทิ้ง" เพื่อตรวจสอบว่ามีการทำเครื่องหมายองค์ประกอบที่ระบุของใบรับรองหรือไม่ หากใบรับรองอยู่ในรายการละทิ้ง สัญญาระบุว่าการตรวจสอบล้มเหลว และผู้โทรไม่สามารถถอนเงินได้ นักพัฒนาเชื่อว่าด้วยวิธีนี้ ใบรับรองเดิมไม่สามารถส่งซ้ำเพื่อผลกำไร และเชื่อว่าสิ่งนี้สามารถป้องกันการโจมตีซ้ำซ้อนหรือเล่นซ้ำได้อย่างมีประสิทธิภาพ

ปัญหานี้สามารถย้อนไปถึงปี 2017 Christian Reitwiessner ผู้ประดิษฐ์ภาษา Solidity ได้ให้ตัวอย่างการใช้การเข้ารหัสตามสัญญาของ zkSNARK [3] ตั้งแต่นั้นมา สัญญาเกือบทั้งหมดที่ใช้เทคโนโลยี zkSNARKs บน Ethereum ได้ดำเนินการตามนี้ ดังนั้นจึงเป็นไปได้ที่จะถูกโจมตีด้วยกระบวนการดังต่อไปนี้

ชื่อเรื่องรอง

แอปพลิเคชันการผสมสกุลเงิน: พื้นที่ที่ได้รับผลกระทบหนักที่สุดของปัญหาด้านความปลอดภัยนี้

สถานการณ์การใช้งานที่เร็วที่สุดและแพร่หลายที่สุดของเทคโนโลยีการพิสูจน์ความรู้เป็นศูนย์บน Ethereum คือสัญญาผสมสกุลเงิน หรือการโอนเงินแบบไม่ระบุตัวตนและธุรกรรมส่วนตัว เนื่องจาก Ethereum เองไม่รองรับการทำธุรกรรมแบบนิรนาม และการเรียกร้องของชุมชนในการปกป้องความเป็นส่วนตัวก็แข็งแกร่งขึ้นเรื่อย ๆ โครงการยอดนิยมจำนวนมากจึงเกิดขึ้น ที่นี่ ยกตัวอย่างสถานการณ์การใช้งานของสัญญาสกุลเงินผสม เราจะแนะนำภัยคุกคามด้านความปลอดภัยของช่องโหว่ "นามแฝงสำหรับการป้อนข้อมูล" ให้กับโครงการที่ไม่มีความรู้

การผสมสัญญาหรือการโอนเงินแบบไม่ระบุชื่อเกี่ยวข้องกับสองประเด็นหลัก:

1. พิสูจน์ว่าคุณมีเงิน

2. พิสูจน์ว่าเงินไม่ได้ถูกใช้ไป

เพื่อให้เข้าใจง่าย นี่คือคำอธิบายโดยย่อของกระบวนการ:

1. A จะใช้เงินก้อนหนึ่ง

2. A ต้องพิสูจน์ว่าเขาเป็นเจ้าของเงิน A นำเสนอ zkproof เพื่อพิสูจน์ว่าเขารู้จักพรีอิมเมจของแฮช (HashA) และแฮชนี้อยู่บนใบของต้นไม้ที่ทำเครื่องหมายด้วยราก และพิสูจน์ว่าแฮชอื่นของพรีอิมเมจนี้คือ HashB ในหมู่พวกเขา HashA เป็นพยานและ HashB เป็นแถลงการณ์สาธารณะ เนื่องจาก A ไม่จำเป็นต้องเปิดเผย HashA จึงไม่เปิดเผยตัวตน

3. สัญญาจะตรวจสอบ zkproof และตรวจสอบว่า HashB อยู่ในรายการละทิ้งหรือไม่ ถ้าไม่มีแสดงว่ายังไม่ได้ใช้เงินและสามารถใช้ได้ (สายนี้ของ A ได้)

4. หากสามารถใช้ได้ สัญญาจำเป็นต้องใส่ HashB ลงในรายการละทิ้ง ซึ่งระบุว่าเงินที่ HashB เป็นตัวแทนของ HashB ถูกใช้ไปแล้วและไม่สามารถนำมาใช้ได้อีก

ตรรกะหลักของสัญญา zkSNARKs จำนวนมาก โดยเฉพาะสัญญาสกุลเงินผสม คล้ายกับบรรทัดที่ 82 และ 83 ดังนั้น สัญญาทั้งหมดจึงมีปัญหาด้านความปลอดภัยเหมือนกัน และสามารถถูกโจมตีได้โดยใช้ช่องโหว่ "นามแฝง"

ชื่อเรื่องรอง

การวิเคราะห์ช่องโหว่: จะใช้จ่ายเงิน 5 เท่าโดยไม่ระบุชื่อได้อย่างไร

ฟังก์ชันของฟังก์ชัน verifyProof(a, b, c, input) ข้างต้นจะทำการคำนวณและตรวจสอบบนเส้นโค้งวงรีตามค่าที่ป้อน แกนกลางใช้ ฟังก์ชันชื่อ scalar_mul() เพื่อรับรู้การคูณสเกลาร์บนเส้นโค้งวงรี [4 ].

เราทราบดีว่า Ethereum มีสัญญาที่คอมไพล์ไว้ล่วงหน้าหลายรายการในตัวเพื่อดำเนินการเข้ารหัสบนเส้นโค้งวงรี และลดการใช้ก๊าซของการตรวจสอบ zkSNARKs บนห่วงโซ่ การใช้งานฟังก์ชัน scalar_mul() เรียกใช้สัญญา Ethereum ที่คอมไพล์แล้วหมายเลข 7 และตระหนักถึงการคูณสเกลาร์บนเส้นโค้งวงรี alt_bn128 ตาม EIP 196 [5] ภาพด้านล่างแสดงคำจำกัดความของการดำเนินการนี้ใน Yellow Paper ซึ่งเรามักเรียกว่า ECMUL หรือ ecc_mul

ในการเข้ารหัส โดเมนค่าของ {x, y} ของเส้นโค้งวงรีเป็นฟิลด์จำกัดตาม mod p และฟิลด์จำกัดนี้เรียกว่า Zp หรือ Fp นั่นคือ จุด {x,y} บนเส้นโค้งวงรี โดยที่ x,y คือค่าในหน่วย Fp จุดบางจุดบนเส้นโค้งวงรีสร้างกลุ่มวงกลมที่ใหญ่ขึ้น และจำนวนของจุดเหล่านี้เรียกว่าลำดับของกลุ่ม ซึ่งเขียนแทนด้วย q การเข้ารหัสตามเส้นโค้งวงรีจะดำเนินการในกลุ่มวงจรนี้ หากลำดับ (q) ของกลุ่มวงจรนี้เป็นจำนวนเฉพาะ การเข้ารหัสสามารถทำได้ในฟิลด์จำกัด mod q ซึ่งแสดงเป็น Fq

โดยทั่วไป กลุ่มวงจรที่ใหญ่กว่าจะถูกเลือกเป็นพื้นฐานของการคำนวณการเข้ารหัส ในกลุ่มวงกลม สุ่มเลือกจุดที่ไม่เป็นอนันต์เป็นตัวสร้าง G (โดยปกติลำดับ q ของกลุ่มนี้เป็นจำนวนเฉพาะที่มาก ดังนั้นจุดที่ไม่เป็นศูนย์จะเทียบเท่า) และจุดอื่นๆ ทั้งหมดสามารถผ่าน G+ G+ ได้ ..สร้าง. จำนวนองค์ประกอบในกลุ่มนี้คือ q นั่นคือมีจุดทั้งหมด q จากนั้นเราสามารถใช้ 0,1,2,3,....q-1 เพื่อกำหนดหมายเลขแต่ละจุด จุดที่ 0 ตรงนี้คือจุดที่ไม่มีที่สิ้นสุด และจุดที่ 1 คือจุด G ที่พูดถึงเมื่อกี้นี้ เรียกอีกอย่างว่าจุดฐาน จุดที่ 2 คือ G+G จุดที่ 3 คือ G+G+G

ดังนั้นเมื่อเราต้องการแทนจุด เรามีสองวิธี อย่างแรกคือให้พิกัด {x,y} ของจุดนี้ โดยที่ x,y เป็นของ Fp วิธีที่สองคือให้ในรูปของ n*G เนื่องจาก G เป็นแบบสาธารณะ จึงจำเป็นต้องให้ n เท่านั้น n เป็นของ Fq

ดูลายเซ็นของฟังก์ชัน scalar_mul(G1Point point, uint s) ใช้ point เป็นตัวสร้าง คำนวณ point+point+.....+point และเพิ่มผลรวมของ n point นี่เป็นของการใช้วิธีที่สองด้านบนเพื่อแสดงจุดในกลุ่มวงจร

ในการดำเนินการตามสัญญา Solidity smart คุณต้องใช้ประเภท uint256 เพื่อเข้ารหัส Fq แต่ค่าสูงสุดของประเภท uint256 นั้นมากกว่าค่าของ q จากนั้นจะมีสถานการณ์เช่นนี้: ตัวเลขหลายตัวใน uint256 จะสอดคล้องกับ Fq เดียวกันหลังจากค่าการดำเนินการ mod ใน. ตัวอย่างเช่น s และ s + q แทนจุดเดียวกัน นั่นคือจุดที่ s นี่เป็นเพราะจุด q เทียบเท่ากับจุด 0 ในกลุ่มวงกลม (แต่ละจุดสอดคล้องกับ 0, 1, 2, 3, ... q-1) ในทำนองเดียวกัน s + 2q เป็นต้น ทั้งหมดสอดคล้องกับจุด s เราเรียกปรากฏการณ์นี้ว่าจำนวนเต็มจำนวนมากสามารถป้อนเข้าที่สอดคล้องกับค่าใน Fq เดียวกันว่า "อินพุตนามแฝง" นั่นคือ ตัวเลขเหล่านี้เป็นนามแฝงสำหรับกันและกัน

เส้นโค้งวงรีที่ใช้โดยสัญญา Ethereum 7 คือ y^2 = ax^3+bx+c p และ q เป็นดังนี้ตามลำดับ

ค่า q นี่คือลำดับของกลุ่มที่กล่าวถึงข้างต้น จากนั้นในช่วงของประเภท uint256 จะมีทั้งหมด uint256_max / q ซึ่งหมายความว่าจะมีจำนวนเต็มสูงสุด 5 ตัวที่แทนจุดเดียวกัน (5 "นามแฝงอินพุต")

ดังนั้น เมื่อผู้ใช้แสดงหลักฐานที่ไม่มีความรู้ในสัญญาสำหรับการถอน สัญญาจะใส่ข้อมูลเข้า[1] (นั่นคือ บางส่วน) ลงในรายการที่ใช้ไม่ได้ ผู้ใช้ (หรือผู้โจมตีรายอื่น) สามารถส่งการรับรองอีกครั้งด้วยค่าอีก 4 ค่า ค่าทั้ง 4 นี้ไม่เคยรวมอยู่ใน "รายการที่ถูกละทิ้ง" มาก่อน ดังนั้นการพิสูจน์ "การปลอมแปลง" จึงสามารถผ่านการตรวจสอบได้อย่างราบรื่น และสามารถใช้เงินก้อนหนึ่งได้ 5 ครั้งโดยใช้ "นามแฝงที่ป้อน" 5 ครั้ง และค่าใช้จ่ายในการโจมตี ต่ำมาก !

ชื่อเรื่องรอง

และอีกหลายโครงการที่ได้รับผลกระทบ

ในหมู่พวกเขา ไลบรารีหรือโครงการเฟรมเวิร์ก zkSNARKs ที่รู้จักกันดีหลายรายการมีผลกระทบมากที่สุด รวมถึง snarkjs, ethsnarks, ZoKrates เป็นต้น โครงการแอปพลิเคชันจำนวนมากจะอ้างอิงโดยตรงหรืออ้างถึงรหัสของพวกเขาสำหรับการพัฒนา ดังนั้นจึงเป็นการฝังความเสี่ยงด้านความปลอดภัย ด้วยเหตุนี้ ทั้งสามรายการดังกล่าวจึงได้รับการอัปเดตอย่างรวดเร็วด้วยการแก้ไขด้านความปลอดภัย นอกจากนี้ โครงการผสมสกุลเงินที่มีชื่อเสียงจำนวนหนึ่งซึ่งใช้เทคโนโลยี zkSNARKs เช่น hopper, Heiswap และ Miximus ก็ได้ดำเนินการซ่อมแซมแบบซิงโครนัสทันที โครงการเหล่านี้ได้รับความนิยมอย่างมากในชุมชน ซึ่ง Heiswap เรียกว่า "โครงการโปรดของ Vitalik"

ชื่อเรื่องรอง

การแก้ปัญหาช่องโหว่ "Input Pseudonym"

โชคดีที่การแก้ไขนั้นง่าย จำเป็นต้องเพิ่มการตรวจสอบขนาดของพารามิเตอร์อินพุตในฟังก์ชันการตรวจสอบเท่านั้น โดยบังคับให้ค่าอินพุตมีขนาดเล็กกว่าค่า q ที่กล่าวถึงข้างต้น นั่นคือห้ามไม่ให้ "ป้อนนามแฝง" โดยเด็ดขาด และเพื่อป้องกันการใช้ตัวเลขหลายตัวแทนจุดเดียวกัน

ชื่อเรื่องรอง

ปัญหาที่ฝังลึกที่ถูกเปิดเผยนั้นมีค่าควรแก่การไตร่ตรอง

ช่องโหว่ด้านความปลอดภัยที่เกิดจาก "นามแฝงสำหรับการป้อนข้อมูล" นี้สมควรได้รับการพิจารณาอย่างจริงจังจากชุมชน มาทบทวนเรื่องราวทั้งหมดอีกครั้ง ในปี 2560 Christian โพสต์การดำเนินการคำนวณสัญญา zkSNARKs ของเขาเองบนเว็บไซต์ Gist ในฐานะที่เป็นห้องสมุดคอมพิวเตอร์ เราอาจคิดว่าการใช้งานไม่มีปัญหาด้านความปลอดภัย ไม่ละเมิดสามัญสำนึกของการเข้ารหัส และดำเนินการตรวจสอบหลักฐานในสัญญาได้อย่างสมบูรณ์แบบ ในความเป็นจริง ในฐานะผู้ประดิษฐ์ภาษา Solidity คริสเตียนจะไม่ทำผิดพลาดในระดับต่ำที่นี่อย่างแน่นอน วันนี้ 2 ปีต่อมา รหัสนี้ทำให้เกิดพายุความปลอดภัยดังกล่าว เป็นเวลากว่าสองปี เพื่อนร่วมงานและผู้เชี่ยวชาญจำนวนนับไม่ถ้วนอาจเห็นหรือใช้รหัสนี้โดยมีมากกว่าสองร้อยบรรทัด แต่พวกเขาไม่พบปัญหาใดๆ

ปัญหาหลักอยู่ที่ไหน อาจเป็นไปได้ว่ามีความคลาดเคลื่อนในการทำความเข้าใจอินเทอร์เฟซของโปรแกรมระหว่างผู้ดำเนินการของไลบรารีต้นแบบและผู้ใช้ไลบรารี กล่าวอีกนัยหนึ่ง: ผู้ดำเนินการของไลบรารีพื้นฐานขาดการพิจารณาถึงการใช้งานที่ไม่เหมาะสมของผู้พัฒนาแอพพลิเคชั่น ในขณะที่ผู้พัฒนาแอพพลิเคชั่นระดับบนไม่มีความเข้าใจอย่างลึกซึ้งเกี่ยวกับหลักการการใช้งานพื้นฐานและข้อควรระวังระหว่างการใช้งาน และตั้งสมมติฐานด้านความปลอดภัยที่ผิด

ช่องโหว่ "Input Pseudonym" อดไม่ได้ที่จะเตือนเราถึงช่องโหว่ "Integer Overflow" ที่มักถูกเปิดเผยก่อนหน้านี้ มีความคล้ายคลึงกันค่อนข้างมากระหว่างทั้งสอง: ทั้งสองเกิดจากสมมติฐานที่ไม่ถูกต้องของนักพัฒนาจำนวนมาก ทั้งสองเกี่ยวข้องกับประเภท uint256 ใน Solidity ทั้งสองมีผลกระทบในวงกว้าง นอกจากนี้ยังมีรหัสการสอนหรือสัญญาห้องสมุดที่ซ่อนอยู่มากมาย เผยแพร่บนอินเทอร์เน็ต แต่เป็นที่ชัดเจนว่าช่องโหว่ "อินพุตนามแฝง" ตรวจจับได้ยากกว่าอย่างเห็นได้ชัด เวลาแฝงนานกว่า และจำเป็นต้องมีความรู้พื้นฐานเพิ่มเติม (ซึ่งเกี่ยวข้องกับเส้นโค้งวงรีที่ซับซ้อนและทฤษฎีการเข้ารหัส) SECBIT Lab เชื่อว่าด้วยการเพิ่มขึ้นของ zkSNARK แอปพลิเคชันที่ไม่มีความรู้ และเทคโนโลยีความเป็นส่วนตัว แอปพลิเคชันใหม่ๆ จะเกิดขึ้นในชุมชนมากขึ้น และภัยคุกคามความปลอดภัยที่ซ่อนอยู่อาจถูกเปิดเผยมากขึ้น ฉันหวังว่าเทคโนโลยีใหม่ๆ ระลอกนี้ ชุมชนจะสามารถซึมซับบทเรียนอันเจ็บปวดในอดีตได้อย่างเต็มที่ และให้ความสนใจกับปัญหาด้านความปลอดภัย

อ้างอิง

[1]https://github.com/

[2]https://github.com/

[3]https://gist.github.com/

[4]https://github.com/

[5]https://github.com/

开发者
ยินดีต้อนรับเข้าร่วมชุมชนทางการของ Odaily
กลุ่มสมาชิก
https://t.me/Odaily_News
กลุ่มสนทนา
https://t.me/Odaily_CryptoPunk
บัญชีทางการ
https://twitter.com/OdailyChina
กลุ่มสนทนา
https://t.me/Odaily_CryptoPunk
สรุปโดย AI
กลับไปด้านบน
ฉันหวังว่าเทคโนโลยีใหม่ๆ ระลอกนี้ ชุมชนจะสามารถซึมซับบทเรียนอันเจ็บปวดในอดีตได้อย่างเต
ดาวน์โหลดแอพ Odaily พลาเน็ตเดลี่
ให้คนบางกลุ่มเข้าใจ Web3.0 ก่อน
IOS
Android