MysteryBox.changeOwner() function doesn't check authority of the caller. Therefore attacker can change owner to himself.
Since there is no restriction on the changeOwner function, the user can reset any address as the owner.
MisteryBox.sol(111~113)
After attacker set himself as the owner, he can call the setBoxPrice function to set the price of the box to any price, so attacker can buy the box at an unintended price (close to 0).
Futhermore, attacker can withdraw all ethers of the contract by calling withdrawFunds() function.
Manual Review
Modify the changeOwner() function as follows.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.