DEV Community

晓道
晓道

Posted on

一个蜜罐合约的解析(二)调用隐藏

前文

上次发了,一个蜜罐合约的解析 | 登链社区 | 深入浅出区块链技术 (learnblockchain.cn) 看的人很多,评论也不少,是我发的文章中评论最多的文章。

在写的过程中,我也是边写边试,边分析,前面的部分给部分看文章的人一些误导,深表歉意,在写的过程中,我也学习了不少。
我把上次那个过程再讲一次,并且把各个调用的链接在ethscan上的都发出来,后面再把调用New的合约代码复原一下。

流程

1,部署合约, Ethereum Transaction Hash (Txhash) Details | Etherscan
2,调用New设置答案hash Ethereum Transaction Hash (Txhash) Details | Etherscan
3,开始Start,投入2个eth Ethereum Transaction Hash (Txhash) Details | Etherscan
4,有人Try,投入至少1个eth Ethereum Transaction Hash (Txhash) Details | Etherscan
5,Stop 收入,转回自己的钱包。Ethereum Transaction Hash (Txhash) Details | Etherscan

合约的调用历史列表:

Contract d732e40d353aa772a7f82b4b310e75925853a040 in Ethereum - Ethereum Contract Library by Dedaub (contract-library.com)

小结

现在看来,其实这个合约没有什么技术含量,有两个可取之处:
1,部署合约时候设置管理员
2,在ethscan上隐藏了New调用。

合约调用隐藏

下面谈谈调用New调用的合约:
看上面的New调用记录可以知道,他是通过合约调用合约来隐藏这个调用的,而发起调用这个合约是没有审计的,所以你并不能在ethscan上看到发起New调用的函数名。
调用时候的input Ethereum Transaction Hash (Txhash) Details | Etherscan
16445505331.png

合约代码:
Contract 0x1ba21C6cfcD3D082d8Bbe95bC5B78F4eDC3e80D4 in Ethereum - Ethereum Contract Library by Dedaub (contract-library.com)

// Decompiled at www.contract-library.com // 2022.01.21 17:07 UTC // Data structures and variables inferred from the use of storage instructions address owner; //STORAGE[0x0] bytes 0 to 19 function fallback() public payable { find similar } function 0x2000df44(address varg0, uint256 varg1, uint256 varg2) public payable { find similar require(msg.data.length - 4 >= 96); require(varg0 == varg0); require(varg1 <= 0xffffffffffffffff); require(4 + varg1 + 31 < msg.data.length); require((?).length <= 0xffffffffffffffff); require(4 + varg1 + (?).length + 32 <= msg.data.length); require(msg.sender == owner); v0 = new array[]((?).length); MEM[4 + MEM[64] + (?).length + 96] = 0; require(varg0.code.size); v1 = varg0.New(v0, varg2).gas(msg.gas); require(v1); // checks call status, propagates error data on error } // Note: The function selector is not present in the original solidity code. // However, we display it for the sake of completeness. function __function_selector__(uint256 function_selector) public payable { MEM[64] = 128; require(!msg.value); if(msg.data.length >= 4) { if(0x2000df44 == function_selector >> 224) { 0x2000df44(); } } fallback(); } 
Enter fullscreen mode Exit fullscreen mode

翻译成solidity代码如下:

contract Hacker { address owner; constructor() { owner = msg.sender; } function myCall( address varg0, uint256 varg1, uint256 varg2 ) public payable { require(owner == msg.sender); defi_game(varg0).New(varg1, varg2); } } 
Enter fullscreen mode Exit fullscreen mode

所以就这么简单,就这样调用ethscan上就没有这个合约的这一条的调用记录。
ethscan上没有,其他地方还是有的。

一点猜想

我估计把multicall改改应该能够做到更好的隐藏。

function multicall(bytes[] calldata data) public payable override returns (bytes[] memory results) { results = new bytes[](data.length); for (uint256 i = 0; i < data.length; i++) { (bool success, bytes memory result) = address(this).delegatecall(data[i]); if (!success) { // Next 5 lines from https://ethereum.stackexchange.com/a/83577 if (result.length < 68) revert(); assembly { result := add(result, 0x04) } revert(abi.decode(result, (string))); } results[i] = result; } } 
Enter fullscreen mode Exit fullscreen mode

怎么改呢,就改个函数名就够了。
大家别干坏事,我也只是技术交流。

Top comments (0)