ช่องโหว่การเล่นซ้ำลายเซ็นในสัญญาอัจฉริยะ | บล็อกการตรวจสอบ
เคล็ดลับที่เป็นประโยชน์คือการเซ็นข้อความนอกเครือข่ายและมีสัญญาที่ต้องการลายเซ็นนั้นก่อนดำเนินการ
ตัวอย่างเช่น เทคนิคนี้ใช้เพื่อ: -
-ลดจำนวนธุรกรรมในห่วงโซ่
- ธุรกรรมที่ไม่มีก๊าซ เรียกว่าmeta transaction
มาดูกันว่าเรากำลังพูดถึงอะไร
Blockchains พึ่งพาลายเซ็นเข้ารหัสเป็นอย่างมาก ธุรกรรมได้รับการลงนามด้วยคีย์ส่วนตัวที่เกี่ยวข้อง ทำให้ผู้ส่งธุรกรรมสามารถเชื่อมโยงกับบัญชีของตนได้ การทำบัญชีของ blockchain จะไม่สามารถใช้งานได้หากไม่มีคุณลักษณะนี้
ลายเซ็นดิจิทัลมักได้รับการตรวจสอบโดยตรงในสัญญาอัจฉริยะของ Ethereum ทำให้ผู้ตรวจสอบอย่างน้อยหนึ่งรายสามารถอนุญาตการดำเนินการโดยการส่งลายเซ็นออฟไลน์ ( หรือแม้แต่ลายเซ็นที่สร้างโดยสัญญาอัจฉริยะอื่น )
มักใช้ในห้องนิรภัยแบบหลายลายเซ็นหรือสัญญาการลงคะแนนเพื่อส่งลายเซ็นหลายรายการพร้อมกันหรือเพื่อมอบอำนาจ
การโจมตีซ้ำด้วยลายเซ็นเป็นช่องโหว่ทั่วไปในการใช้งานดังกล่าว
บางครั้งจำเป็นต้องมีการตรวจสอบลายเซ็นในสัญญาอัจฉริยะเพื่อปรับปรุงความสามารถในการใช้งานหรือประหยัดค่าน้ำมัน การใช้งานที่ปลอดภัยควรป้องกันการโจมตีซ้ำของลายเซ็น
ตัวอย่างเช่น: -
ติดตามแฮชข้อความที่ประมวลผลทั้งหมดและอนุญาตให้ประมวลผลแฮชข้อความใหม่เท่านั้น ผู้ใช้ที่ประสงค์ร้ายสามารถโจมตีสัญญาที่ขาดการควบคุมดังกล่าว และรับแฮชข้อความที่ส่งมาจากผู้ใช้รายอื่นและประมวลผลหลายครั้ง
ลายเซ็นดิจิทัลแบบเข้ารหัส
ลายเซ็นดิจิทัลเป็นรหัสสาธารณะดั้งเดิมของการรับรองความถูกต้องของข้อความ ในโลกทางกายภาพ ลายเซ็นที่เขียนด้วยลายมือมักใช้กับข้อความที่เขียนด้วยลายมือหรือข้อความที่พิมพ์ ใช้เพื่อผูกมัดผู้ลงนามกับข้อความ
ลายเซ็นดิจิทัลคือค่าการเข้ารหัสที่สร้างขึ้นโดยข้อมูลและรหัสลับที่ผู้ลงนามเท่านั้นที่รู้จัก
รูปแบบของลายเซ็นดิจิทัล
ขั้นตอนทั้งหมดได้รับการอธิบายอย่างละเอียดในประเด็นต่อไปนี้:
- ผู้ใช้แต่ละรายของโครงร่างนี้มีชุดของคีย์สาธารณะและส่วนตัว
- คู่คีย์ที่ใช้สำหรับการเข้ารหัส/ถอดรหัสและการเซ็นชื่อ/การตรวจสอบมักจะแตกต่างกัน รหัสสาธารณะเรียกว่ารหัสการตรวจสอบและรหัสส่วนตัวเรียกว่ารหัสลายเซ็น
- ข้อมูลถูกส่งไปยังฟังก์ชันแฮชโดยผู้ลงนามซึ่งสร้างแฮช
- อัลกอริทึมลายเซ็นจะสร้างลายเซ็นดิจิทัลบนแฮชที่ให้มาโดยใช้ค่าแฮชและคีย์ลายเซ็น ข้อมูลจะได้รับลายเซ็นและทั้งสองจะถูกส่งไปยังผู้ตรวจสอบในภายหลัง
- อัลกอริทึมการตรวจสอบถูกป้อนโดยผู้ตรวจสอบพร้อมกับลายเซ็นดิจิทัลและรหัสการตรวจสอบ ผลลัพธ์ของอัลกอริทึมการตรวจสอบเป็นสิ่งที่มีประโยชน์ สำหรับข้อมูลที่ได้รับ ผู้ตรวจสอบยังใช้อัลกอริทึมแฮชเดียวกันเพื่อสร้างค่าแฮช
- ค่าแฮชนี้และผลลัพธ์ของกระบวนการตรวจสอบจะถูกเปรียบเทียบเพื่อการตรวจสอบ ตัวตรวจสอบจะตัดสินว่าลายเซ็นดิจิทัลนั้นถูกต้องตามกฎหมายหรือไม่โดยพิจารณาจากผลลัพธ์ของการเปรียบเทียบ
- ไม่มีใครสามารถใช้คีย์ "ส่วนตัว" ของผู้ลงนามเพื่อสร้างลายเซ็นดิจิทัล ดังนั้นผู้ลงนามจึงไม่สามารถถอนลายเซ็นข้อมูลของตนได้ในภายหลัง
ชั้นโปรโตคอล
เฉพาะธุรกรรมที่มีลายเซ็นที่ถูกต้องเท่านั้นที่จะรวมอยู่ในบล็อกใหม่ ต้องขอบคุณ เครือ ข่ายEthereum สำหรับการทำธุรกรรม ข้อเสนอนี้มีแอตทริบิวต์ความปลอดภัยดังต่อไปนี้:
- การ รับรองความถูกต้อง : โหนด Ethereum ใช้ลายเซ็นเพื่อยืนยันว่าบุคคลที่ลงนามธุรกรรมเป็นเจ้าของคีย์ส่วนตัวที่เชื่อมต่อกับที่อยู่สาธารณะ ดังนั้นผู้พัฒนาอาจมั่นใจได้ว่า msg.sender เป็นของแท้
- ความสมบูรณ์ : ความสมบูรณ์เป็นเงื่อนไขที่ธุรกรรมจะไม่เปลี่ยนแปลงหลังจากลงนามแล้ว มิฉะนั้นลายมือชื่อจะเป็นโมฆะ
- การไม่ปฏิเสธ:ลายเซ็นของการทำธุรกรรมและการเปลี่ยนแปลงสถานะใด ๆ ที่ทำโดยฝ่ายที่ลงนามซึ่งครอบครองคีย์ส่วนตัวไม่สามารถโต้แย้งได้ รหัสส่วนตัวเป็นของที่อยู่สาธารณะที่แสดงอยู่ในช่องจาก
สามารถใช้ลายเซ็นเดียวกันได้หลายครั้งเพื่อเรียกใช้ฟังก์ชัน การดำเนินการนี้อาจเป็นอันตรายหากผู้ลงนามตั้งใจที่จะอนุมัติธุรกรรมเพียงครั้งเดียว
ตัวอย่างโค้ด
ลองตรวจสอบข้อผิดพลาด
function unlock(
address _to,
uint256 _amount,
uint8[] _v,
bytes32[] _r,
bytes32[] _s
)
external
{
require(_v.length >= 20);
bytes32 hashData = keccak256(_to, _amount);
for (uint i = 0; i < _v.length; i++) {
address recAddr = ecrecover(hashData, _v[i], _r[i], _s[i]);
require(_isValidator(recAddr));
}
to.transfer(_amount);
}
ข้อความที่ลงนามโดยผู้ตรวจสอบความถูกต้องโดยใช้เทคนิค ECDSA คือปัญหาของรหัสดังกล่าว ที่อยู่ผู้รับและเงินที่ต้องการเป็นข้อมูลเดียวในข้อความ ไม่มีอะไรในข้อความที่จะหลีกเลี่ยงการใช้ลายเซ็นเดียวกันมากกว่าหนึ่งครั้ง พิจารณากรณีต่อไปนี้:
- Sam โอน 2,000 ETH จากเครือข่ายที่เชื่อมโยงกลับไปยัง Ethereum chain โดยใช้สกุลเงินจำนวนเท่ากัน
- การประมวลผลธุรกรรมข้ามบล็อกเชนนี้คือ Tom ผู้ถ่ายทอด ในการปลด 2,000 ETH จากสัญญาและส่งไปยัง Sam เขารวบรวมลายเซ็นของผู้ตรวจสอบความถูกต้องที่จำเป็น ล็อคจำนวนที่ถูกต้องบนเชนที่เชื่อมต่อ จากนั้นใช้ฟังก์ชั่นปลดล็อค
- ใน blockchain ธุรกรรมที่มีอาร์เรย์ของค่าลายเซ็นจะถูกมองเห็นโดยทุกคน
- ตอนนี้ Sam ได้คัดลอกอาร์เรย์ลายเซ็นแล้ว เขาสามารถส่งการเรียกปลดล็อคได้อย่างอิสระ กระบวนการปลดล็อกจะสำเร็จอีกครั้ง ส่งผลให้มีการโอน 2,000 ETH ให้กับแซม
- แซมสามารถดำเนินการในลักษณะนี้ต่อไปได้จนกว่าสัญญาจะหมดลง
การโจมตีแบบเล่นซ้ำลายเซ็นคือสิ่งที่อธิบายไว้ในตัวอย่างด้านบน เป็นไปได้เนื่องจากไม่มีวิธีใดที่จะระบุได้ว่าข้อความที่เซ็นชื่อเฉพาะนี้ไม่ซ้ำกันหรือว่าเคยถูกใช้มาก่อนหรือไม่
ลงนามใน ข้อความnonce
และที่อยู่ของสัญญา
public uint256 nonce;
function unlock(
address _to,
uint256 _amount,
uint256 _nonce,
uint8[] _v,
bytes32[] _r,
bytes32[] _s
)
external
{
require(_v.length >= 20);
require(_nonce == nonce++);
bytes32 hashData = keccak256(_to, _amount, _nonce);
for (uint i = 0; i < _v.length; i++) {
address recAddr = ecrecover(hashData, _v[i], _r[i], _s[i]);
require(_isValidator(recAddr));
}
to.transfer(_amount);
}
เพื่อป้องกันการโจมตีซ้ำลายเซ็น ให้พิจารณาคำแนะนำต่อไปนี้:
- เก็บทุกแฮชข้อความที่ได้รับการประมวลผลโดยสัญญาอัจฉริยะ เมื่อได้รับข้อความใหม่ ให้ตรวจสอบกับข้อความที่มีอยู่แล้ว และดำเนินการตามตรรกะทางธุรกิจเฉพาะในกรณีที่เป็นแฮชข้อความใหม่
- รวมที่อยู่ของสัญญาที่ประมวลผลข้อความ สิ่งนี้ทำให้มั่นใจได้ว่าข้อความสามารถใช้ได้ในสัญญาเดียวเท่านั้น
- ไม่ว่าในกรณีใดจะไม่สร้างแฮชข้อความรวมถึงลายเซ็น ฟังก์ชัน
ecrecover
นี้อ่อนไหวต่อความอ่อนตัวของลายเซ็น
ลายเซ็นที่ไม่ซ้ำสามารถเล่นซ้ำได้ในหลายสถานการณ์ ดังตัวอย่างด้านบน เพื่อหลีกเลี่ยงการโจมตีซ้ำ ในสถานการณ์ส่วนใหญ่สิ่งสำคัญคือต้องแน่ใจว่าลายเซ็นตรงกันโดยเฉพาะกับการโทรแต่ละครั้ง นอกจากนี้ ด้วยเหตุนี้ nonce จึงรวมอยู่ในธุรกรรม Ethereum ทุกรายการ
อ้างอิง: -
https://solidity-by-example.org/hacks/signature-replay/
https://blog.finxter.com/smart-contract-replay-attack-solidity/
https://swcregistry.io/docs/SWC-121
เร่งมือกับ web3 Security!!! เชื่อมต่อกับเรา!!!
BlockAudit :- ทำไมเรา??
BlockAuditมีทรัพยากรและความรู้ในการสร้างโซลูชันความปลอดภัยทางไซเบอร์ที่ประหยัดเงินได้หลายล้านดอลลาร์
ลิงค์ดิน | เว็บไซต์ | ทวิตเตอร์