Hello Web3!
http://web3.balsnctf.com:3000
Author: ysc
Category: Misc
Solved: 54 / 333
We should sign a message that ethers.getAddress(message)
is equal to the signer address, but the message should not match /^0x[0-9a-fA-F]+$/
.
It means that we are unable to sign a valid Ethereum address (e.g. 0x13f2788fF2A12d3373BaF8085a9047e12e4a5C21
).
But if you find the document of ethers.getAddress, you will find that we could use another valid address format - ICAP Address Format to bypass the check.
> const wallet = ethers.Wallet.createRandom()
> wallet.address
'0x13f2788fF2A12d3373BaF8085a9047e12e4a5C21'
> ethers.getIcapAddress(wallet.address)
'XE502BVQT21IVCDE0OITYNFBVFRGOPRB1NL'
> ethers.getAddress('XE502BVQT21IVCDE0OITYNFBVFRGOPRB1NL') // the key point
'0x13f2788fF2A12d3373BaF8085a9047e12e4a5C21'
> message = ethers.getIcapAddress(wallet.address)
'XE502BVQT21IVCDE0OITYNFBVFRGOPRB1NL'
> signature = await wallet.signMessage(message)
'0x9aed56940a5ce709dd65a212d40f9a7aa063c40ca85277a13f6919b9f228307d5ed4da850ebe8352bc2480885f0f475797d3b7f2fbc323bc780d1be42c0ac8851b'
> ethers.verifyMessage(message, signature) === ethers.getAddress(message)
true
I think this is a less noticeable feature of ethers.getAddress
, but you could find it just by checking the documentation. Share it with you :)
curl -v "http://web3.balsnctf.com:3000/exploit" -X POST --header "Content-Type: application/json" -d '{"message": "XE502BVQT21IVCDE0OITYNFBVFRGOPRB1NL", "signature": "0x9aed56940a5ce709dd65a212d40f9a7aa063c40ca85277a13f6919b9f228307d5ed4da850ebe8352bc2480885f0f475797d3b7f2fbc323bc780d1be42c0ac8851b"}'
Flag: BALSN{Inter_Exchange_Client_Address_Protocol}