// Contract that has to be displayed for challenge// SPDX-License-Identifier: MITpragmasolidity^0.8.10;contractdeception{addressprivateowner;boolpublicsolved;constructor(){owner=msg.sender;solved=false;}modifieronlyOwner(){require(msg.sender==owner,"Only owner can access");_;}functionchangeOwner(addressnewOwner)onlyOwnerpublic{owner=newOwner;}functionpassword()onlyOwnerpublicviewreturns(stringmemory){return"secret";}functionsolve(stringmemorysecret)public{require(keccak256(abi.encodePacked(secret))==0x65462b0520ef7d3df61b9992ed3bea0c56ead753be7c8b3614e0ce01e4cac41b,"invalid");solved=true;}}
From the source code, if we are able to provide a secret whose keccak256 hash is equal to 0x65462b0520ef7d3df61b9992ed3bea0c56ead753be7c8b3614e0ce01e4cac41b, then the challenge can be solved. And, the keccak256 hash of "secret" is exactly what we want XD
However, when I called the solve() function with the argument "secret", the transaction kept reverting :(
I suddenly realized that the secret provided in the source code is not the actual value. So, I got the bytecode and attempted to extract the password from it
It's not easy to get the secret even with decompiled bytecode
functionpassword()publicpayable{require(msg.sender==_changeOwner,Error('Only owner can access'));v0=_SafeExp(stor_1,stor_4);require(stor_2,Panic(18));// division by zeroif(76-v0%stor_2){MEM[MEM[64]+32]=v0%stor_2;v1=v2=MEM[64]+64;}else{require((stor_3==stor_3*(v0%stor_2)/(v0%stor_2))|!(v0%stor_2),Panic(17));// arithmetic overflow or underflowrequire(v0%stor_2,Panic(18));// division by zeroMEM[32+MEM[64]]=stor_3*(v0%stor_2)/(v0%stor_2);v3=0x18e(64+MEM[64],32,30);v4=_SafeAdd(0x616263,stor_3);v5=_SafeSub(v4,stor_3);MEM[32+MEM[64]]=v5;v6=0x18e(64+MEM[64],32,30);v7=v8=0;while(v7<v3.length){MEM[v7+(32+MEM[64])]=v3[v7];v7+=32;}MEM[v3.length+(32+MEM[64])]=0;v9=v10=0;while(v9<v6.length){MEM[v9+(32+MEM[64]+v3.length)]=v6[v9];v9+=32;}MEM[v6.length+(32+MEM[64]+v3.length)]=0;v1=v11=v6.length+(32+MEM[64]+v3.length);}v12=newarray[](v1-MEM[64]-32);v13=v14=0;while(v13<v1-MEM[64]-32){MEM[v13+v12.data]=MEM[v13+(MEM[64]+32)];v13+=32;}MEM[v1-MEM[64]-32+v12.data]=0;returnv12;}
Why not just fork the chain and impersonate the owner to call the password() function?