逻辑陷阱型蜜罐合约
Posted 懒编程-二两
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了逻辑陷阱型蜜罐合约相关的知识,希望对你有一定的参考价值。
蜜罐是传统安全领域中的一个概念,通常指安全人员设置一些陷阱(比较明显的漏洞),让攻击者自己掉入我们设置好的陷阱中,以便安全人员分析攻击者的作恶手法。
蜜罐合约(HoneyPots Contract)也是类似的概念,但对象变了,一般指合约开发者设置了看似容易获利的合约逻辑,但其实是陷阱,普通用户观察合约,发现有利可图,便与蜜罐合约交互,结果发现交互的资产无法被自己提出。
蜜罐合约在中文圈子有时也称为貔貅合约,本文将简单讨论一下,我看见的几种逻辑陷阱型蜜罐合约。
逻辑陷阱蜜罐合约
比较多项目会在transfer函数(转账相关)中实现一些业务逻辑,蜜罐合约可能在transfer函数中加入一些强行限制用户交易的逻辑,从而实现截取用户资产的效果。
这类合约,我称为逻辑陷阱型蜜罐合约,是比较好识别的一类,主要关注其交易相关的逻辑在合约实现上是否透明以及是否有限制则可,这里介绍三个逻辑陷阱型蜜罐合约:
黑名单蜜罐合约
可变合约构成的蜜罐合约
限时限卖的蜜罐合约
黑名单蜜罐合约
我们看到BSC上一个叫Moco合约:https://bscscan.com/address/0x9d4bDdd642529a588f910Aad405C07e066A908Cf#code
Moco合约继承了ERC20,即是一个代币合约,看到合约中的_transfer函数,部分代码如下:
function _transfer(address sender, address recipient, uint256 amount) private returns (bool)
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
require(!_isbclisted[recipient] && !_isbclisted[sender], "bclisted address");
// ...
在用户进行交易时,会调用_transfer函数,它有3个require做条件判断,主要看到第三个,判断sender与recipient都不在黑名单内,才能进行交易。
根据_isbclisted进行搜索,可以发现addBot函数实现了将用户地址加入黑名单的操作。
function addBot(address recipient) internal
if (!_isbclisted[recipient]) _isbclisted[recipient] = true;
那什么地方调用了addBot函数呢?搜索一下,发现还是在_transfer函数中,相关代码如下:
if(sender == uniswapPair)
if (block.number <= launchedBlock + killblock)
addBot(recipient);
如果当前区块数小于launchedBlock + killblock,那么当前recipient会被加入黑名单,而launchedBlock与killblock这两个变量是被合约创建者控制的。
简而言之,合约创建者可以通过对launchedBlock与killblock的控制,将部分区块中发生交易的recipient地址加入黑名单,这样recipient后续就无法从Moco中转出代币了。
这便是典型的黑名单蜜罐,通常出现在土狗项目中,用于杀抢土狗机器人的。
很多土狗项目上线时,会进行拉盘操作,对普通用户而言,会发现土狗项目涨的很快,从而被利润吸引,参与到土狗的交互中,部分开发者也会发现这个土狗项目早期拉盘的特点,就开发了机器人,在开盘后立刻买入,然后等土狗项目方拉盘时,快速卖出,从而获得稳定的利润。
随后,项目方很快也发现土狗机器人的存在,这便进入了一个对抗过程,比如当前这种黑名单逻辑,因为土狗机器人交易速度很快,会抢到比较前的区块完成买入交易,一个土狗项目开盘后,可能会涌入大量机器人交易,通过黑名单的逻辑,就可以将机器人地址加入黑名单,直接让机器人损失本金。
可变合约制造蜜罐
我们看到BSC上,一个名叫SpaceXOver的合约:https://bscscan.com/address/0x60899ea0c86048eb5d8a7a2cf395c7cc58a9023a#code
先看transfer函数,代码如下:
function transfer(address to, uint256 amount) public returns (bool)
Acc(Acc_address).acc_Transfer(msg.sender, to, amount);
emit Transfer(msg.sender, to, amount);
return true;
transfer函数中,真正进行转账交易的逻辑没有在当前合约实现,而是通过Acc合约中的acc_transfer去做的,有猫腻。
翻看一下当前合约,发现Acc合约是在部署时设置了该合约的地址,即当前合约没有Acc合约的逻辑,相关代码如下:
constructor(address _acc) public
totalSupply_ = 8000000*10**18;
deployer = msg.sender;
// 设置 Acc 合约地址
Acc_address = _acc;
Acc(Acc_address).acc_setup(address(this), totalSupply_);
我们可以通过解析input data的形式,来获得部署SpaceXOver合约时,Acc合约的具体地址。
先尝试用bscscan提供的Decode Input Data
发现解析不出来,这里吐槽一下,感觉很多合约的input data都无法通过这种方式解析,不知道为何不去优化一下,对于开源合约,获得abi后,input data还是很好解析的。
这里,我们使用web3-input-decoder这个库来解析一下,先安装一下。
pip install web3-input-decoder
然后保存一下SpaceXOver合约的ABI用于解析input data,相关代码如下:
import json
from web3_input_decoder import decode_constructor, decode_function
# SpaceXOver的ABI JSON
p = '1.json'
with open(p, 'r', encoding='UTF-8') as f:
abi = f.read()
abiJson = json.loads(abi)
result = decode_constructor(abiJson, "0x6080604...(input data复制过来则可)")
print(result)
结果如下:
访问acc合约地址,发现这个地址下的合约是闭源的,无法看到合约代码,猫腻很大,因为我们不知道其交易时的具体逻辑是怎么样的,很有可能就是一个蜜罐合约,只可进,不可出。
限时限卖的蜜罐合约
我们看到BSC上名叫SW的合约:https://bscscan.com/address/0xa7d0741813d2ff189b172f68c1ce3f0aa101bd22#code
SW合约的中定义了多个mapping(address => uint256)类型的变量,通过这些变量来记录转账的值。
看到_transfer函数,有限制交易时间与限制交易金额比例的逻辑,相关代码如下:
// 限制交易时间
if(block.timestamp<_limitTime)
dayBuy[to]=dayBuy[to].add(amount);
require(dayBuy[to]<=300*10**18 ,"limit time max 300");
require(_isTrade ,"limit trade2 ");
// 限制交易金额比例,最多只能交易 90% 的金额
require(balanceOf(from).mul(90).div(100)>amount,"selle max 90%");
takeFee = true;
结尾
除了逻辑陷阱型蜜罐,还有其他类型的蜜罐合约,阅读【The Art of The Scam: Demystifying Honeypots in Ethereum Smart Contracts】论文可知还有如下几种类型的蜜罐合约:
级别 | 技巧 |
---|---|
Ethereum Virtual Machine(以太坊虚拟机级别) | Balance Disorder(平衡紊乱) |
Solidity编译器级别 | Inheritance Disorder(继承障碍) |
Skip Empty String Literal(跳过空字符串字面值) | |
Type Deduction Overflow(类别除法溢出) | |
Uninitialised Struct(未初始化结构) | |
以太扫描区块链探索器(Etherscan) | Hidden State Update(隐藏状态更新) |
Hidden Transfer(隐藏交易) | |
Straw Man Contract(稻草人合同) |
因为论文中讨论的比较细致且我自身没有进行复现验证,所以本文就不多讨论。
值得一提的是Skip Empty String Literal与Type Deduction Overflow已在高版本的Solidity中fix了,如果你用0.8.0以上版本的Solidity不会有这两个问题,其他的,需要自行验证一下。
相关参考:
【米斯特姚】的Youtube频道(https://www.youtube.com/watch?v=SAzZ61cvvn8)
【The Art of The Scam: Demystifying Honeypots in Ethereum Smart Contracts】论文(https://www.arxiv-vanity.com/papers/1902.06976/)
“蜜罐”合约中的哪个功能阻止买家出售他们的代币?
【中文标题】“蜜罐”合约中的哪个功能阻止买家出售他们的代币?【英文标题】:Which function in a ”honeypot” contract prevents buyers from selling their tokens? 【发布时间】:2021-08-16 09:48:23 【问题描述】:币安智能链代币世界的一个常见骗局是推出一个新的代币/合约,在普通人看来很诱人,但当买家购买代币时,他们很快发现他们无法出售它们,因此丢了钱。
我听说代币的开发者通过将除他们自己的钱包以外的所有其他钱包“列入黑名单”来实现这一点,但我不确定这种解释有多准确(或字面意思与委婉程度)。
有些人试图通过测试购买/销售微不足道的金额以确保代币能够出售来避免此类骗局。
我的问题是:合约中是否有特定的功能/设置可以被扫描和检查以确定硬币是否是这种类型的骗局,而不必进行测试购买就知道了?
【问题讨论】:
【参考方案1】:是的,
如果所有者将 swapandliquify 设置为 false,则所有交换都可以被锁定。有些人报告说诈骗者使用 uniswapv2pair 的方式相同。
编译器版本 0.5.17 也有很多漏洞/错误。
我们在 cointutu 每天都面临着与 BSC 诈骗作斗争的挑战。
【讨论】:
请添加更多详细信息以扩展您的答案,例如工作代码或文档引用。以上是关于逻辑陷阱型蜜罐合约的主要内容,如果未能解决你的问题,请参考以下文章