Ethernaut part 9 (Preservation & Recovery)
Let’s do more ctf
Preservation
Problem
จาก code
จงเปลี่ยน owner เป็น address ของเราเอง
Solution
โอเค มีการใช้ delegatecall ใน function setFirstTime และ setSecondTime ไปย้อนดูการใช้ delegatecall กัน
จาก code ตัวอย่างการใช้ delegatecall จะพบว่า contract A สามารถใช้ logic ของ function จาก contract B มาเปลี่ยนค่า storage ของ contract B ได้
แต่ จากตัวอย่าง contract A และ B มีการวางค่าตัวแปรเหมือนกันเป๊ะ เพื่อให้ storage layout ตรงกัน
แต่จาก contract Preservation และ LibraryContract เราจะพบว่าจริงๆแล้ว ส่วนที่ storage layout ตรงกันคือ
timeZone1Library = storedTime ตามภาพ
ดังนั้น ถ้าเราส่ง address นึงเป็น input ของ setFirstTime => address นั้นจะถูกนำมา save เป็น timeZone1Library เนื่องจากบรรทัด storedTime = _time เป็นการ save storage ที่ slot 0 ของ contract Preservation นั่นคือ timeZone1Library
โอเค ทดสอบกัน
ก่อนยิง
ลองยิงด้วย
หลังยิง
โอเค เรามีวิธีแก้ตัวแปร timeZone1Library ละ
คำถามคือ เราทำอะไรต่อได้บ้าง ?
ถ้าเราอยากแก้ตัวแปร owner เราก็แค่สร้าง contract ที่วาง storage layout และมีการทำงานของ setTime แบบนี้
โดยเรียก contract นี้ว่า PreservationAttack
โดยขั้นตอนในการโจมตีคือ
- set timeZone1Library เป็น address ของ PreservationAttack
- เรียก setFirstTime อีกที เพื่อเปลี่ยน owner ของ contract Preservation ตาม logic ใน setTime
โอเค ข้อนี้ประมาณนี้ละนะ
Recovery
problem
จาก code มีการเรียกใช้งาน generateToken เพื่อ deploy SimepleToken จากนั้นมีการโอน 0.001 Ether เข้าไปใน SimpleToken
จงทำให้ Ether balance ของ SimpleToken ที่ถูก deploy ไปนั้น กลายเป็น 0
Solution
โอเค จาก address ที่โจทย์ให้มา พอไปดูใน internal tx จะพบว่า contract นี้ไป deploy contract อื่น
ดังนั้น contract ที่ถูก contract นี้ deploy คือ SimpleToken นั่นเอง
จะได้ address ของ SimpleToken มาละ
ต่อมา ทำการเรียก function destroy ของ SimpleToken
โดยวิธีที่ง่ายสุด คงเป็นการเรียกผ่าน remix
เมื่อเรียก destroy จะเป็นการ selfdestruct ซึ่งจะโอน Ether ทั้งหมดของ SimpleToken ออกมา
โอเค ข้อนี้ประมาณนี้ละนะ
FYI
เค้าแนะนำวิธีคำนวณ contract address มาด้วย อันนี้คล้ายกับ real case ที่เคยเกิดขึ้นอยู่นะ https://rekt.news/wintermute-rekt/ ไว้ค่อยมาลองกัน