0%

minGasPoc

尝试构造out of gas的攻击

攻击概述

目的:使得jsevm run out of gas

方法:设置geth pyevm jsevm当前交易的gaslimt为0xccc,jsevm需要0x168a

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# geth 修改调用evm的gas不起作用,只能修改genesis.json中的gaslimit

"gasLimit": "0xccc",

# pyevm runBytecode.py
call_txn = new_transaction(
chain.get_vm(),
SENDER,
simple_contract_address,
private_key=SENDER_PRIVATE_KEY,
gas=0xffff,
# data=function_selector,
data=decode_hex(args.signature),
)

# runBytecode.js
const results = await evm.runCall({
gasLimit: BigInt('0x'+'ccc'),
data: hexToBytes(sig),
to: contractAddress,
caller: new Address(hexToBytes("0x1c7cd2d37ffd63856a5bd56a9af1643f2bcf545f"))
});

给定输入data=0xfe575a87000000000000000000000000bffd98ec9ba3dc965b8a97d876670bb367fa84c2,执行函数isBlacklisted(),成功

image-20240113213936348

但是目前的问题是geth和pyevm均是revert,交易没有真正执行

1
2
3
4
5
6
7
8
9
# geth
{"pc":23471,"op":253,"gas":"0x2fe312","gasCost":"0x0","memSize":192,"stack":["0xfe575a87","0xcaf","0xbffd98ec9ba3dc965b8a97d876670bb367fa84c2","0x0","0x3f94","0x80","0x80","0x0","0x7018"],"depth":1,"refund":0,"opName":"REVERT","error":"execution reverted"}
{"output":"","gasUsed":"0xcc6","error":"execution reverted"}
# python
{"pc": 23471, "op": 253, "gas": "0x9f81", "gasCost": "0x0", "stack": ["0xfe575a87", "0xaf0c", "0xc284fa67b30b6776d8978a5b96dca39bec98fdbf", "0x0", "0x943f", "0x80", "0x8000000000000000000000000000000000000000000000000000000000000000", "0x0", "0x1870", "0x0", "0x0"], "depth": 0, "opName": "REVERT", "error": "None" }
{"output": "", "gasUsed": "0xcc6"}
# jsevm
{"pc":16225,"gas":"0x107","gasCost":"0x0","memory":"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012800000000000000000000000000000000254879013500000000000019125315223615516322015091138151216118103111791032501321940000000000000000000000000000","memsize":"6","stack":["0xfe575a87","0xcaf","0xbffd98ec9ba3dc965b8a97d876670bb367fa84c2","0x0","0x0","0xfe575a87","0xa4","0x20","0x80","0x24","0x80","0x0","0x107"],"depth":0,"opName":"STATICCALL"}
{"output":"","gasUsed":"0xccc","error":{"error":"out of gas","errorType":"EvmError"}}

问题似乎在于ethereumjs的staticcall的gas被计算了,而gas和pyevm执行staticcall的gas消耗被忽略了

1
2
3
4
5
6
// initializer is not initialized
function isBlacklisted(address account) external view returns (bool) {

return initializer.isBlacklisted(account);

}

在remix上不支持过长的合约,只能开启optimizer(200),然后调用isBlacklisted函数,注意到remix VM的gas消耗为5366

image-20240113220635216

remix报错

1
"error": "Failed to decode output: Error: hex data is odd-length (argument="value", value="0x0", code=INVALID_ARGUMENT, version=bytes/5.7.0)"

尝试了不同的地址依然存在问题

在remix中先执行setInitializer,依然执行错误

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function setInitializer(address init) public onlyOwner {

require(!tradingEnabled);

require(init != address(this), "Can't be self.");

initializer = Initializer(init);

try initializer.getConfig() returns (address router, address constructorLP) {

dexRouter = IRouter02(router); lpPair = constructorLP; lpPairs[lpPair] = true;

_approve(_owner, address(dexRouter), type(uint256).max);

_approve(address(this), address(dexRouter), type(uint256).max);

} catch { revert(); }

}

image-20240113222653503