HTB Business CTF 2024 - NotADemocraticElection [blockchain]
Difficulty : easy
Team : Phreaks2600
In the post-apocalyptic wasteland, the remnants of human and machine factions vie for control over the last vestiges of civilization. The Automata Liberation Front (ALF) and the Cyborgs Independence Movement (CIM) are the two primary parties seeking to establish dominance. In this harsh and desolate world, democracy has taken a backseat, and power is conveyed by wealth. Will you be able to bring back some Democracy in this hopeless land?
Introduction
We have to make a political party “CIM” win by raising its votes above 1000 * 10^18 votes (we can notice that 10^18 wei = 1ether).
Recon
Code reading
NotADemocraticElection.sol
|
|
- You can register to vote by submitting your name and surname, and if you transfer ether your vote will carry more weight (I’m getting a kick out of this representation of corruption). A vote count 10 times if it’s weight is 10.
- When the contract is initialized, there’s a member who’s already registered with 100 ether = 100 * 10^18 (they can whippin everything by casting just 10 votes)
- His name is Satoshi Nakamoto
- Of course, you can’t vote for someone else.
- There’s a verification process based on the address that REGISTERED the person and the address that CARRIED out the vote.
- If the address is verified, the code will take the voter’s first and last name signature by doing: abiEncodePacked(first name, last name)
- This function is vulnerable because if I register a person called “Sato shiNakamoto”, his signature will be the same as that of “Satoshi Nakamoto” (everything is concatenated).
- Documentation mentioning [flaw](the https://docs.soliditylang.org/en/latest/abi-spec.html).
- Then all I have to do is vote with the fraudulent voter I’ve just created.
Solve
Steps to resolve:
- Start the instance and retrieve the addresses
- Make a call to depositVoteCollatoral with the following parameters: “Sato” “shiNakamoto” (could have been “Sat” “oshiNakamoto” etc)
- Vote 10 times
- Claim the flag
In commands it looks like this:
cast send $TARGET -r $RPC_URL --from $ATTACKER --private-key $PRIVATE_KEY "depositVoteCollateral(string,string)" Sato shiNakamoto
-
We vote for our favorite party 10 times:
cast send $TARGET --private-key $PRIVATE_KEY -r $RPC_URL "vote(bytes3,string,string)" 0x43494d Sato shiNakamoto
(execute the command 1 time like a clueless man, we’re not scripting here) -
You can check the number of votes with
cast call $TARGET -r $RPC_URL "getVotesCount(bytes3)" 0x43494d
. Where “0x43494d” is “CIM” in hex.
HTB{h4sh_c0ll1s10n_t0_br1ng_b4ck_d3m0cr4cy}