Cảnh báo rủi ro: Đề phòng huy động vốn bất hợp pháp dưới danh nghĩa 'tiền điện tử' và 'blockchain'. — Năm cơ quan bao gồm Ủy ban Giám sát Ngân hàng và Bảo hiểm
Tìm kiếm
Đăng nhập
简中
繁中
English
日本語
한국어
ภาษาไทย
Tiếng Việt
BTC
ETH
HTX
SOL
BNB
Xem thị trường
Lỗ hổng "đầu vào bút danh" hợp đồng zkSNARK khiến nhiều dự án trộn coin bùng nổ
安比(SECBIT)实验室
特邀专栏作者
2019-07-29 07:41
Bài viết này có khoảng 4349 từ, đọc toàn bộ bài viết mất khoảng 7 phút
Tôi hy vọng rằng trong làn sóng công nghệ mới này, cộng đồng có thể tiếp thu đầy đủ những bài học đau đớn trong quá khứ và chú ý đến các vấn đề bảo mật.

Lưu ý của biên tập viên: Bài viết này đến từ Lưu ý của biên tập viên: Bài viết này đến từ(ID:secbitlabs)Phòng thí nghiệm Amby

Do sử dụng nhầm một thư viện hợp đồng zkSNARKs nhất định trong một số lượng lớn các dự án bằng chứng không có kiến ​​thức, lỗ hổng "Bí danh đầu vào" được đưa ra, có thể dẫn đến chứng chỉ giả mạo, chi tiêu gấp đôi, phát lại và các cuộc tấn công khác cũng như chi phí tấn công là cực kỳ thấp. Nhiều dự án mã nguồn mở trong cộng đồng Ethereum bị ảnh hưởng, bao gồm ba thư viện phát triển không kiến ​​thức zkSNARK được sử dụng phổ biến nhất là snarkjs, ethsnarks và ZoKrates, cũng như ba phễu ứng dụng trộn tiền (chuyển tiền ẩn danh) phổ biến gần đây, Heiswap và Miximus. Đây là một vụ giết người gây ra bởi một đoạn mã do Chris, cha đẻ của ngôn ngữ Solidity, đăng tải hai năm trước.

tiêu đề phụ

Lỗ hổng chi tiêu gấp đôi: Tiếp xúc ban đầu

Semaphore là một hệ thống semaphore ẩn danh sử dụng công nghệ bằng chứng không có kiến ​​thức, được phát triển từ dự án trộn tiền trước đây của nhà phát triển nổi tiếng barryWhiteHat.

Nhà phát triển người Nga poma lần đầu tiên chỉ ra rằng dự án có thể có lỗ hổng chi tiêu gấp đôi [1].

Vấn đề nằm ở dòng 83 code [2], bạn xem kỹ nhé.

Chức năng này yêu cầu người gọi xây dựng bằng chứng không biết rằng anh ta có thể rút tiền từ hợp đồng. Để ngăn "chi tiêu gấp đôi" xảy ra, chức năng này cũng đọc "danh sách loại bỏ" để kiểm tra xem một thành phần cụ thể của chứng chỉ có được đánh dấu hay không. Nếu chứng chỉ nằm trong danh sách bị bỏ rơi, hợp đồng xác định rằng việc xác minh không thành công và người gọi không thể rút tiền. Nhà phát triển tin rằng theo cách này, cùng một chứng chỉ không thể được gửi đi nhiều lần để kiếm lợi nhuận và tin rằng điều này có thể ngăn chặn hiệu quả các cuộc tấn công chi tiêu gấp đôi hoặc phát lại.

Vấn đề này có thể bắt nguồn từ năm 2017. Christian Reitwiessner, người phát minh ra ngôn ngữ Solidity, đã cung cấp một ví dụ về triển khai mã hóa hợp đồng zkSNARKs [3]. Kể từ đó, hầu hết tất cả các hợp đồng sử dụng công nghệ zkSNARKs trên Ethereum đều tuân theo cách triển khai này. Do đó, có thể bị tấn công bởi các quy trình sau.

tiêu đề phụ

Ứng dụng trộn tiền tệ: Khu vực chịu ảnh hưởng nặng nề nhất của sự cố bảo mật này

Các kịch bản ứng dụng sớm nhất và phổ biến nhất của công nghệ bằng chứng không có kiến ​​thức trên Ethereum là hợp đồng trộn tiền tệ hoặc chuyển khoản ẩn danh và giao dịch riêng tư. Vì bản thân Ethereum không hỗ trợ các giao dịch ẩn danh và cộng đồng kêu gọi bảo vệ quyền riêng tư ngày càng mạnh mẽ hơn nên nhiều dự án nổi tiếng đã xuất hiện. Ở đây, lấy kịch bản ứng dụng của hợp đồng tiền tệ hỗn hợp làm ví dụ, chúng tôi sẽ giới thiệu mối đe dọa bảo mật của lỗ hổng "bút danh đầu vào" đối với các dự án không có kiến ​​thức.

Trộn hợp đồng hoặc chuyển khoản ẩn danh liên quan đến hai điểm chính:

1. Chứng minh rằng bạn có tiền

2. Chứng minh số tiền chưa được tiêu

Để dễ hiểu, đây là một mô tả ngắn gọn về quy trình:

1. A sẽ tiêu một khoản tiền.

2. A cần chứng minh mình sở hữu số tiền đó. A đưa ra một zkproof để chứng minh rằng anh ta biết tiền giả của hàm băm (HashA) và hàm băm này nằm trên lá của cây được đánh dấu bằng gốc và chứng minh rằng một hàm băm khác của tiền giả này là HashB. Trong số đó, HashA là nhân chứng và HashB là tuyên bố công khai. Vì A không cần tiết lộ HashA nên nó ẩn danh.

3. Hợp đồng xác minh zkproof và kiểm tra xem HashB có nằm trong danh sách loại bỏ hay không. Nếu không có nghĩa là số tiền đó chưa được tiêu và có thể được tiêu (việc gọi này của A được phép).

4. Nếu có thể chi tiêu, hợp đồng cần đưa HashB vào danh sách loại bỏ, cho biết rằng số tiền do HashB đại diện đã được chi tiêu và không thể chi tiêu trở lại.

Logic cốt lõi của nhiều hợp đồng zkSNARK, đặc biệt là hợp đồng tiền tệ hỗn hợp, tương tự như dòng 82 và 83, vì vậy chúng đều có cùng vấn đề bảo mật và có thể bị tấn công bằng cách khai thác lỗ hổng "bí danh đầu vào".

tiêu đề phụ

Phân tích lỗ hổng: Làm thế nào để chi tiêu ẩn danh số tiền gấp 5 lần?

Chức năng của hàm verifyProof(a, b, c, input) ở trên là thực hiện tính toán và xác minh trên đường cong elip theo giá trị đầu vào. Cốt lõi sử dụng một hàm có tên scalar_mul() để thực hiện phép nhân vô hướng trên đường cong elip [4 ].

Chúng tôi biết rằng Ethereum đã tích hợp sẵn nhiều hợp đồng được biên dịch sẵn để thực hiện các hoạt động mã hóa trên đường cong elip và giảm mức tiêu thụ gas của xác minh zkSNARK trên chuỗi. Việc triển khai hàm scalar_mul() gọi hợp đồng số 7 được biên dịch sẵn của Ethereum và nhận ra phép nhân vô hướng trên đường cong elip alt_bn128 theo EIP 196 [5]. Hình dưới đây cho thấy định nghĩa của hoạt động này trong Sách vàng, mà chúng ta thường gọi là ECMUL hoặc ecc_mul.

Trong mật mã học, miền giá trị của {x, y} của đường cong elliptic là một trường hữu hạn dựa trên mod p, và trường hữu hạn này được gọi là Zp hoặc Fp. Đó là, một điểm {x,y} trên đường cong elip trong đó x,y là giá trị trong Fp. Một số điểm trên đường cong elip tạo thành một nhóm tuần hoàn lớn hơn và số lượng các điểm này được gọi là bậc của nhóm, ký hiệu là q. Mã hóa dựa trên các đường cong elip được thực hiện trong nhóm tuần hoàn này. Nếu thứ tự (q) của nhóm tuần hoàn này là một số nguyên tố, thì mã hóa có thể được thực hiện trong trường hữu hạn mod q, được ký hiệu là Fq.

Nói chung, một nhóm tuần hoàn lớn hơn được chọn làm cơ sở tính toán mã hóa. Trong nhóm tuần hoàn, chọn ngẫu nhiên một điểm không phải vô cực làm bộ tạo G (thông thường thứ tự q của nhóm này là số nguyên tố lớn nên mọi điểm khác 0 đều tương đương) và tất cả các điểm khác có thể đi qua G+ G+. .. được tạo ra. Số phần tử của nhóm này là q, tức là có tổng cộng q điểm, khi đó ta có thể dùng 0,1,2,3,....q-1 để đánh số cho từng điểm. Điểm 0 ở đây là điểm ở vô cực, còn điểm 1 là điểm G vừa nhắc đến, còn gọi là điểm cơ sở. Điểm 2 là G+G, điểm 3 là G+G+G.

Vậy khi muốn biểu diễn một điểm ta có hai cách. Đầu tiên là cung cấp tọa độ {x,y} của điểm này, trong đó x,y thuộc Fp. Cách thứ hai là cho nó ở dạng n*G. Vì G là công khai nên chỉ cần cho n. n thuộc Fq.

Hãy xem chữ ký hàm scalar_mul(G1Point point, uint s), sử dụng point làm trình tạo, tính toán point+point+.....+point và thêm tổng cộng n điểm. Điều này thuộc về việc sử dụng phương pháp thứ hai ở trên để biểu diễn một điểm trong một nhóm tuần hoàn.

Khi triển khai hợp đồng thông minh Solidity, loại uint256 cần được sử dụng để mã hóa Fq, nhưng giá trị tối đa của loại uint256 lớn hơn giá trị của q, khi đó sẽ xảy ra tình huống: nhiều số trong uint256 sẽ tương ứng với cùng một Fq sau giá trị thao tác mod trong . Ví dụ: s và s + q biểu thị cùng một điểm, tức là điểm thứ. Điều này là do điểm q thực sự tương đương với điểm 0 trong nhóm tuần hoàn (mỗi điểm tương ứng với 0, 1, 2, 3, ... q-1). Tương tự, s + 2q, v.v. đều tương ứng với điểm s. Chúng tôi gọi hiện tượng có thể nhập nhiều số nguyên lớn tương ứng với giá trị trong cùng một Fq là "các biệt danh đầu vào", nghĩa là các số này là biệt danh của nhau.

Đường cong elip được thực hiện bởi hợp đồng Ethereum 7 là y^2 = ax^3+bx+c. p và q tương ứng như sau.

Giá trị q ở đây là thứ tự của nhóm được đề cập ở trên. Sau đó, trong phạm vi của loại uint256, có tổng số uint256_max/q, có nghĩa là sẽ có nhiều nhất 5 số nguyên biểu thị cùng một điểm (5 "bí danh đầu vào").

Do đó, khi người dùng đưa ra bằng chứng không có kiến ​​thức cho hợp đồng để rút tiền, hợp đồng sẽ đưa đầu vào[1] (nghĩa là một số s nhất định) vào danh sách vô hiệu. Người dùng (hoặc kẻ tấn công khác) cũng có thể gửi lại chứng thực với 4 giá trị khác. 4 giá trị này trước đây chưa được đưa vào "danh sách bị bỏ rơi", vì vậy bằng chứng "giả mạo" có thể vượt qua quá trình xác minh một cách suôn sẻ và có thể chi một khoản tiền gấp 5 lần bằng cách sử dụng 5 "bút danh đầu vào" và chi phí tấn công là rất thấp!

tiêu đề phụ

Và nhiều dự án bị ảnh hưởng khác

Trong số đó, một số dự án khung hoặc thư viện zkSNARKs nổi tiếng có tác động lớn nhất, bao gồm snarkjs, ethsnarks, ZoKrates, v.v. Nhiều dự án ứng dụng sẽ trích dẫn trực tiếp hoặc tham khảo mã của họ để phát triển, do đó ẩn chứa rủi ro bảo mật. Do đó, ba mục nói trên đã nhanh chóng được cập nhật các bản sửa lỗi bảo mật. Ngoài ra, một số dự án trộn tiền nổi tiếng sử dụng công nghệ zkSNARKs như hopper, Heiswap, Miximus cũng ngay lập tức tiến hành sửa chữa đồng bộ. Các dự án này rất phổ biến trong cộng đồng, trong đó Heiswap được gọi là "dự án yêu thích của Vitalik".

tiêu đề phụ

Giải pháp cho lỗ hổng "Input Pseudonym"

May mắn thay, cách khắc phục rất đơn giản. Chỉ cần thêm một kiểm tra về kích thước của tham số đầu vào trong chức năng xác thực, buộc giá trị đầu vào phải nhỏ hơn giá trị q đã đề cập ở trên. Đó là, nghiêm cấm "nhập một bút danh", và ngăn chặn việc sử dụng nhiều số để thể hiện cùng một điểm.

tiêu đề phụ

Những vấn đề sâu xa bị phơi bày đáng để suy ngẫm

Những lỗ hổng bảo mật gây ra bởi "bút danh đầu vào" này đáng được cộng đồng nghiêm túc phản ánh. Hãy xem lại toàn bộ câu chuyện một lần nữa. Vào năm 2017, Christian đã đăng triển khai tính toán hợp đồng zkSNARK của riêng mình trên trang web Gist. Là một thư viện máy tính, chúng tôi có thể nghĩ rằng việc triển khai nó không có vấn đề về bảo mật, không vi phạm bất kỳ ý nghĩa thông thường nào về mật mã và hoàn thành xuất sắc công việc xác minh bằng chứng trong hợp đồng. Trên thực tế, với tư cách là người phát minh ra ngôn ngữ Solidity, Christian chắc chắn sẽ không mắc phải bất kỳ sai lầm cấp thấp nào ở đây. Hôm nay, hai năm sau, mã này đã gây ra một cơn bão bảo mật như vậy. Trong hơn hai năm, vô số đồng nghiệp và chuyên gia có thể đã nhìn thấy hoặc sử dụng mã này chỉ với hơn hai trăm dòng, nhưng họ không tìm thấy bất kỳ vấn đề nào.

Vấn đề cốt lõi ở đâu? Có thể có sự sai lệch trong cách hiểu về giao diện chương trình giữa người triển khai thư viện cơ bản và người dùng thư viện. Nói cách khác: những người triển khai thư viện cơ bản thiếu cân nhắc về việc sử dụng không đúng cách của các nhà phát triển ứng dụng; trong khi các nhà phát triển ứng dụng cấp cao hơn không hiểu sâu về các nguyên tắc triển khai cơ bản và các biện pháp phòng ngừa trong quá trình sử dụng, đồng thời đưa ra các giả định bảo mật sai.

Lỗ hổng "Input Pseudonym" khiến chúng ta không khỏi liên tưởng đến lỗ hổng "Integer Overflow" thường xuyên bị lộ trước đây. Có khá nhiều điểm tương đồng giữa hai loại này: cả hai đều xuất phát từ những giả định sai lầm của một số lượng lớn các nhà phát triển; cả hai đều liên quan đến loại uint256 trong Solidity; cả hai đều có tác động rộng rãi; cũng có nhiều mã hướng dẫn ẩn hoặc hợp đồng thư viện lưu hành trên Internet. Nhưng rõ ràng là lỗ hổng "bí danh đầu vào" rõ ràng là khó phát hiện hơn, thời gian chờ lâu hơn và cần nhiều kiến ​​thức nền tảng hơn (liên quan đến các lý thuyết mã hóa và đường cong elip phức tạp). SECBIT Lab tin rằng với sự gia tăng của zkSNARK, các ứng dụng bằng chứng không có kiến ​​thức và các công nghệ bảo mật, nhiều ứng dụng mới sẽ xuất hiện trong cộng đồng và nhiều mối đe dọa bảo mật tiềm ẩn hơn có thể bị phơi bày. Tôi hy vọng rằng trong làn sóng công nghệ mới này, cộng đồng có thể tiếp thu đầy đủ những bài học đau đớn trong quá khứ và chú ý đến các vấn đề bảo mật.

người giới thiệu

[1]https://github.com/

[2]https://github.com/

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

[4]https://github.com/

[5]https://github.com/

开发者
Chào mừng tham gia cộng đồng chính thức của Odaily
Nhóm đăng ký
https://t.me/Odaily_News
Tài khoản chính thức
https://twitter.com/OdailyChina