Slither Docker 环境搭建:从拉取镜像到成功扫描

Web2 转战 Web3 第一周:我如何搞定 Slither 漏洞扫描环境?(内附 Docker 避坑指南) 🧵↓

#Solidity #Slither #BlockchainSecurity

通过本文,你将能:

  1. 内网受限的虚拟机上,为Docker容器配置代理并访问外网。
  2. 使用固定镜像Digest,百分百复现本文的Slither扫描环境。
  3. 掌握 eth-security-toolbox 镜像的初始状态缺失依赖的安装方法。
  4. 对一个经典的ERC20重入漏洞合约完成你的第一次Slither扫描。

正文

镜像与容器

容器化环境可以隔离恶意合约,并快速切换不同版本的编译器环境

我使用的镜像的digest(固定镜像以保证可复现(非常重要))

1
trailofbits/eth-security-toolbox@sha256:726b78aac10d4113a81ccc9db62bc2e781a2d136dcb10ad245a6bd1950c42744

Digest 是镜像内容的唯一哈希值,即使原镜像标签(如 latest)被更新,Digest 也能保证下载到完全一致的内容

在宿主机上查看镜像 digest / history

1
2
docker inspect --format='{{index .RepoDigests 0}}' trailofbits/eth-security-toolbox:latest
docker history --no-trunc trailofbits/eth-security-toolbox:latest | sed -n '1,40p'

该镜像生成的容器里面的工具和版本如下:

1
2
3
4
5
6
7
slither --version → 0.11.3
echidna --version → 2.2.7
medusa --version → 1.3.1
node --version → v22.19.0
vyper --version → 0.4.3+commit.bff19ea2
foundry / forge 命令 不存在(command not found)。
solc-select versions → 报:未安装 solc 版本。

要使用slither主要会遇到3个问题:

  1. 是虚拟机(VMware上的ubuntu-24.04.3-live-server-amd64)不能访问外网,需要设置代理。
  2. docker容器不能访问网络,需要配置网络并设置代理。
  3. 该镜像未安装solc和foundry,需要安装。

设置代理

给虚拟机设置代理

1
nano ~/.bashrc

再文件最末尾添加

1
2
alias  proxy="export http_proxy=http://ip:port; export https_proxy=http://ip:port"
alias noproxy="unset http_proxy; unset https_proxy"

ctrl+o 保存,回车确认

ctrl+x 退出

1
source ~/.bashrc

proxy 设置代理;noproxy 关闭代理。好用😋

拉取镜像

1
docker pull trailofbits/eth-security-toolbox

docker容器联网

1
2
3
4
5
6
sudo docker run -it \
--network host \
--name solc_foundry \
--memory="3g" \
-v /home/weeks/ethsec/BCScanner:/app \
trailofbits/eth-security-toolbox:latest /bin/bash

--network host创建的容器直接走虚拟机的网络,

--name solc_foundry取一个目的性强的名字,以防下次忘记,

--memory="3g" 设置内存限制,

-v /home/weeks/ethsec/BCScanner:/app 挂载目录,传输文件方便,容器销毁后,宿主机文件依旧存在。

容器内部再设置一遍代理,和配置虚拟机的代理一样,此处不再赘述。

如果中途退出容器,使用命令再次进入。

1
docker exec -it <container_name_or_id> /bin/bash

如果停止, 使用下面的命令将容器重新启动

1
docker start 

扫描合约

安装solc,用slither扫描合约

1
2
solc-select install 0.8.19
solc-select use 0.8.19
1
slither Reentrancy_vulnerability.sol

我一共扫描了两个合约。
第一个合约内容如下,来自https://github.com/crytic/slither/wiki/Detector-Documentation#storage-abiencoderv2-array

1
2
3
4
5
6
7
8
contract A {
uint[2][3] bad_arr = [[1, 2], [3, 4], [5, 6]];

/* Array of arrays passed to abi.encode is vulnerable */
function bad() public {
bytes memory b = abi.encode(bad_arr);
}
}

扫描结果如下,

扫描结果

第二个合约内容如下,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

contract Vault {
mapping(address => uint256) public balances;

function deposit() public payable {
balances[msg.sender] += msg.value;
}

function withdraw() public {
uint256 amount = balances[msg.sender];
require(amount > 0, "Insufficient balance");

// 漏洞点:在修改余额之前进行了外部调用 (Low-level call)
(bool success, ) = msg.sender.call{value: amount}("");
require(success, "Transfer failed");

// 这一行在重入攻击中永远不会被执行,直到合约被抽干
balances[msg.sender] = 0;
}

function getBalance() public view returns (uint256) {
return address(this).balance;
}
}

扫描结果如下,

图2:Slither识别出经典重入漏洞 (reentrancy-eth)

下一步

  • 接下来我会对合约的内容和结果进行分析。

  • 下载foundry(等一等)

参考资料

  1. slither的的github仓库 https://github.com/crytic/slither
  2. The Trail of Bits Blog https://blog.trailofbits.com/
  3. https://hackenproof.com/run-bug-bounty
  4. eth-security-toolbox镜像 : https://github.com/trailofbits/eth-security-toolbox
  5. dockerhub:https://hub.docker.com/r/trailofbits/slither