Fixed ZoKrates vulnerability
parent
ec0fae56dc
commit
0f981ffea9
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
*Submitted for verification at polygonscan.com on 2022-08-24
|
*Submitted for verification at polygonscan.com on 2022-08-24
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Authors: six and Silur
|
// Authors: six and Silur
|
||||||
|
@ -8,8 +8,7 @@ pragma solidity ^0.8.16;
|
||||||
|
|
||||||
import "./verifier.sol";
|
import "./verifier.sol";
|
||||||
|
|
||||||
|
contract CCTF9 is Verifier {
|
||||||
contract CCTF9 is Verifier{
|
|
||||||
address public admin;
|
address public admin;
|
||||||
uint256 public volMaxPoints;
|
uint256 public volMaxPoints;
|
||||||
bool public started;
|
bool public started;
|
||||||
|
@ -25,12 +24,12 @@ contract CCTF9 is Verifier{
|
||||||
uint256 points;
|
uint256 points;
|
||||||
}
|
}
|
||||||
|
|
||||||
modifier onlyAdmin {
|
modifier onlyAdmin() {
|
||||||
require(msg.sender == admin, "Not admin");
|
require(msg.sender == admin, "Not admin");
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
modifier onlyActive {
|
modifier onlyActive() {
|
||||||
require(started == true, "CCTF not started.");
|
require(started == true, "CCTF not started.");
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
@ -46,8 +45,8 @@ contract CCTF9 is Verifier{
|
||||||
string skill_name;
|
string skill_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
mapping (address => Player) public players;
|
mapping(address => Player) public players;
|
||||||
mapping (uint256 => Flag) public flags;
|
mapping(uint256 => Flag) public flags;
|
||||||
|
|
||||||
event CCTFStarted(uint256 timestamp);
|
event CCTFStarted(uint256 timestamp);
|
||||||
event FlagAdded(uint256 indexed flagId, Hash flagHash);
|
event FlagAdded(uint256 indexed flagId, Hash flagHash);
|
||||||
|
@ -72,44 +71,66 @@ contract CCTF9 is Verifier{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// creates a new capturable flag according to the arguments
|
/// creates a new capturable flag according to the arguments
|
||||||
function setFlag(uint256 _flagId,Hash memory _flagHash, bool _onlyFirstSolver, uint256 _points, string memory _skill) external onlyAdmin{
|
function setFlag(
|
||||||
|
uint256 _flagId,
|
||||||
|
Hash memory _flagHash,
|
||||||
|
bool _onlyFirstSolver,
|
||||||
|
uint256 _points,
|
||||||
|
string memory _skill
|
||||||
|
) external onlyAdmin {
|
||||||
flags[_flagId] = Flag(_flagHash, _onlyFirstSolver, _points, _skill);
|
flags[_flagId] = Flag(_flagHash, _onlyFirstSolver, _points, _skill);
|
||||||
emit FlagAdded(_flagId, _flagHash);
|
emit FlagAdded(_flagId, _flagHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// registers the caller as a player
|
/// registers the caller as a player
|
||||||
function register() external {
|
function register() external {
|
||||||
require(players[msg.sender].status == PlayerStatus.Unverified, 'Already registered or banned');
|
require(
|
||||||
|
players[msg.sender].status == PlayerStatus.Unverified,
|
||||||
|
"Already registered or banned"
|
||||||
|
);
|
||||||
players[msg.sender].status = PlayerStatus.Verified;
|
players[msg.sender].status = PlayerStatus.Verified;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// sets the player's status either to Unverified, Verified or Banned
|
/// sets the player's status either to Unverified, Verified or Banned
|
||||||
function setPlayerStatus(address player, PlayerStatus status) external onlyAdmin {
|
function setPlayerStatus(address player, PlayerStatus status)
|
||||||
|
external
|
||||||
|
onlyAdmin
|
||||||
|
{
|
||||||
players[player].status = status;
|
players[player].status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////// Submit flags
|
////////// Submit flags
|
||||||
mapping (address => mapping (uint256 => bool)) Solves; // address -> challenge ID -> solved/not
|
mapping(address => mapping(uint256 => bool)) Solves; // address -> challenge ID -> solved/not
|
||||||
uint256 public submission_success_count = 0; // For statistics
|
uint256 public submission_success_count = 0; // For statistics
|
||||||
|
|
||||||
function SubmitFlag(Proof memory p, uint256 _submitFor) external onlyActive {
|
function SubmitFlag(Proof memory p, uint256 _submitFor)
|
||||||
require(players[msg.sender].status == PlayerStatus.Verified, "You are not even playing");
|
external
|
||||||
|
onlyActive
|
||||||
|
{
|
||||||
|
require(
|
||||||
|
players[msg.sender].status == PlayerStatus.Verified,
|
||||||
|
"You are not even playing"
|
||||||
|
);
|
||||||
|
|
||||||
uint[13] memory inputs;
|
uint256[13] memory inputs;
|
||||||
for(uint i =0 ; i < 8;++i){
|
for (uint256 i = 0; i < 8; ++i) {
|
||||||
inputs[i] = flags[_submitFor].flagHash.value[i];
|
inputs[i] = flags[_submitFor].flagHash.value[i];
|
||||||
}
|
}
|
||||||
uint32[5] memory addr = addressToUint32(msg.sender);
|
uint32[5] memory addr = addressToUint32(msg.sender);
|
||||||
for(uint i =0; i < 5;++i){
|
for (uint256 i = 0; i < 5; ++i) {
|
||||||
inputs[8+i] = addr[i];
|
inputs[8 + i] = addr[i];
|
||||||
}
|
}
|
||||||
bool valid = verifyTx(p,inputs);
|
|
||||||
assert(valid);
|
|
||||||
|
|
||||||
require(!Solves[msg.sender][_submitFor]); // can't submit the same flag multiple times
|
|
||||||
|
bool valid = verifyTx(p, inputs);
|
||||||
|
require(valid,"The proof is invalid");
|
||||||
|
|
||||||
|
require(!Solves[msg.sender][_submitFor],"You cannot submit your solution more than once"); // can't submit the same flag multiple times
|
||||||
Solves[msg.sender][_submitFor] = true;
|
Solves[msg.sender][_submitFor] = true;
|
||||||
players[msg.sender].points += flags[_submitFor].points;
|
players[msg.sender].points += flags[_submitFor].points;
|
||||||
players[msg.sender].points = players[msg.sender].points < volMaxPoints ? players[msg.sender].points : volMaxPoints;
|
players[msg.sender].points = players[msg.sender].points < volMaxPoints
|
||||||
|
? players[msg.sender].points
|
||||||
|
: volMaxPoints;
|
||||||
|
|
||||||
if (flags[_submitFor].onlyFirstSolver) {
|
if (flags[_submitFor].onlyFirstSolver) {
|
||||||
flags[_submitFor].points = 0;
|
flags[_submitFor].points = 0;
|
||||||
|
@ -120,27 +141,39 @@ contract CCTF9 is Verifier{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// maps an address to unsigned int
|
/// maps an address to unsigned int
|
||||||
function addressToUint32 (address _addr) public pure returns (uint32[5] memory)
|
function addressToUint32(address _addr)
|
||||||
|
public
|
||||||
|
pure
|
||||||
|
returns (uint32[5] memory)
|
||||||
{
|
{
|
||||||
uint256 targetUint = uint256(uint160(_addr));
|
uint256 targetUint = uint256(uint160(_addr));
|
||||||
uint32[5] memory addr = [uint32(targetUint/4294967296**4),
|
uint32[5] memory addr = [
|
||||||
uint32(targetUint/4294967296**3),
|
uint32(targetUint / 4294967296**4),
|
||||||
uint32(targetUint/4294967296**2),
|
uint32(targetUint / 4294967296**3),
|
||||||
uint32(targetUint/4294967296),
|
uint32(targetUint / 4294967296**2),
|
||||||
uint32(targetUint)];
|
uint32(targetUint / 4294967296),
|
||||||
|
uint32(targetUint)
|
||||||
|
];
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////// Check status, scores, etc
|
////////// Check status, scores, etc
|
||||||
function getPlayerStatus(address _player) external view returns (PlayerStatus) {
|
function getPlayerStatus(address _player)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (PlayerStatus)
|
||||||
|
{
|
||||||
return players[_player].status;
|
return players[_player].status;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPlayerPoints(address _player) external view returns (uint256) {
|
function getPlayerPoints(address _player) external view returns (uint256) {
|
||||||
return players[_player].points < volMaxPoints ? players[_player].points : volMaxPoints;
|
return
|
||||||
|
players[_player].points < volMaxPoints
|
||||||
|
? players[_player].points
|
||||||
|
: volMaxPoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSuccessfulSubmissionCount() external view returns (uint256){
|
function getSuccessfulSubmissionCount() external view returns (uint256) {
|
||||||
return submission_success_count;
|
return submission_success_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
import "hashes/sha256/sha256Padded.zok" as sha256;
|
import "hashes/sha256/sha256Padded.zok" as sha256;
|
||||||
from "utils/casts.zok" import cast;
|
from "utils/casts.zok" import cast;
|
||||||
|
|
||||||
def main(public u32[8] hash,public u32[5] address,private u8[64] flag) -> u32[8]{
|
def main(public u32[8] hash,public u32[5] address,private u8[64] flag){
|
||||||
u8[20] addr8 = cast(address);
|
u8[20] addr8 = cast(address);
|
||||||
u32[8] genHash = sha256(flag);
|
u32[8] genHash = sha256(flag);
|
||||||
log("Hash: {} {} {} {} {} {} {} {}",genHash[0],genHash[1],genHash[2],genHash[3],genHash[4],genHash[5],genHash[6],genHash[7]);
|
log("Hash: {} {} {} {} {} {} {} {}",genHash[0],genHash[1],genHash[2],genHash[3],genHash[4],genHash[5],genHash[6],genHash[7]);
|
||||||
assert(genHash == hash);
|
assert(genHash == hash);
|
||||||
u8[32] hash8 = cast(hash);
|
return;
|
||||||
return sha256([...addr8,...hash8]);
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue