Ethernuat part 8 (Gatekeeper II & Naught coin)

Nattawat Songsom
3 min readJan 13, 2023

--

First to the key, first to the egg

image from https://www.insider.com/ready-player-one-movie-vs-book-2018-3#4-the-entire-movie-takes-place-over-the-course-of-a-few-days-but-in-the-book-its-much-longer-4

Gatekeeper II

Problem:

จาก code ทำให้ entrant ไม่เท่ากับ address(0)

Solution

GateOne:

อันนี้เราเคยแก้ไปแล้วใน part ที่แล้ว ดังนั้นขอข้ามเลยนะ

GateTwo:

อันนี้จะขัดแย้งกับ GateOne เพราะถ้าเราใช้ proxy contract เราก็จะมี contract size ของ caller ไม่เท่ากับ 0

แต่จาก yellow paper ของ ethereum ตาม link

เราจะพบว่า

ในระหว่างการเรียก function constructor EXTCODESIZE จะเท่ากับ 0

ดังนั้น เราก็แค่เรียก enter จาก constructor ของ proxy contract ก็พอ

GateThree:

อันนี้จะให้เราหา gateKey ที่ถูกต้องมาให้ได้

ซึ่งมีเงื่อนไขคือ

uint64(bytes8(keccak256(abi.encodePacked(msg.sender)))) ^ uint64(_gateKey) == type(uint64).max

โดยจากตาราง XOR

เราจะพบว่า จาก A^B = C

จะได้ว่า A^C=B ด้วย

เช่น

จาก msg.sender ^ gateKey = maxInt

ในเมื่อเราไม่รู้ gateKey ดังนั้น หาได้จาก

gateKey = msg.sender ^ maxInt

โอเค เคลียร์ทั้ง 3 gate ละ จะได้ code ประมาณนี้

จากบรรทัด 12: คือการใช้แก้ gateTwo

จากบรรทัด 16–21: คือการใช้แก้ gateThree โดย msg.sender ใน contract ที่ถูกเรียก คือ address(this) ของ contract ที่เรียกนั่นเอง ดังนั้นนำ code ในโจทย์มาแก้จาก msg.sender เป็น address(this)

NaughtCoin

Problem

จาก code มีการ mint ให้เรา 100k Token โดยโจทย์คือ ทำให้ balance Token ของเราเป็น 0

Solution

เมื่อเราลอง transfer ดูจะพบว่า error

โดยเมื่อไปดู code การ transfer จะพบว่ามีการเช็ค msg.sender โดยต้องไม่เท่ากับ player เอง

ดังนั้นเราสามารถ bypass ได้โดยการ approve ให้ proxy contract ก่อน แล้วค่อยสั่ง transferFrom แทน transfer

โดย proxy contract จะมี code ตามนี้

เมื่อเรา deploy แล้ว ก็ทำการ approve ให้ proxy contract

จากนั้นสั่ง attack เป็นการจบกระบวนการ จะได้ว่า balance ของ player เหลือ 0 แล้ว

โอเค ประมาณนี้ละนะ

--

--

No responses yet