▼Este artículo se transfiere de "Bi Express"
A medida que la era blockchain 2.0 centrada en los contratos inteligentes (Smart Contracts) y las aplicaciones blockchain (DApps) se ha generalizado gradualmente, la seguridad de los contratos inteligentes y las aplicaciones blockchain se ha convertido cada vez más en el centro de atención de la industria.
En particular, después de experimentar incidentes como THE DAO y el robo de Binance , cómo verificar y garantizar la seguridad de los contratos inteligentes y las aplicaciones de blockchain se ha convertido en un punto crítico urgente en la industria blockchain actual.
El autor ha hecho estadísticas simples. Desde septiembre de 2017 hasta septiembre de 2018, las vulnerabilidades relacionadas de los contratos inteligentes y las aplicaciones de cadena de bloques mostraron un patrón de brotes frecuentes , y las consecuencias fueron de gran alcance. No solo causó directamente una enorme pérdida de dinero; desde la perspectiva del desarrollo a largo plazo, también afectó el desarrollo sostenible de la tecnología emergente de blockchain en el futuro.
Además, aunque las vulnerabilidades potenciales de los contratos inteligentes y las aplicaciones de cadena de bloques actuales no se han resuelto adecuadamente, el statu quo es que la cantidad de contratos inteligentes y aplicaciones de cadena de bloques sigue aumentando rápidamente a una tasa de crecimiento promedio de decenas de miles por día.
No es difícil ver que la tasa de crecimiento y la seguridad de los contratos inteligentes y las aplicaciones de cadena de bloques coexisten en una relación poco saludable. Si usamos la analogía de la oferta y la demanda (la tasa de crecimiento es "oferta"; la seguridad es "demanda"), el estado general actual de los contratos inteligentes y las aplicaciones de cadena de bloques es el estado de "la oferta supera la demanda " .
En base a esto, cómo garantizar la seguridad de los contratos inteligentes masivos y las aplicaciones de cadena de bloques se ha convertido en un tema central para las empresas e individuos con visión de futuro en la industria de la cadena de bloques. De hecho, actualmente existen métodos especiales en la industria para superar este punto débil, como la coincidencia de códigos de funciones, la auditoría automática basada en la ejecución simbólica y la abstracción simbólica, y la auditoría automática basada en la verificación formal . Entre ellos, después de una extensa exploración y práctica en la industria, la "auditoría automática basada en la verificación formal" se ha convertido en un método relativamente maduro y convencional en la industria.
Por lo tanto, el autor se enfoca específicamente en la "verificación formal", selecciona dos herramientas principales de verificación formal (VaaS y Mythril) en la industria actual y realiza una comparación de prueba simple. En particular, la versión de la herramienta Mythril utilizada para la prueba es "0.21.12".
El siguiente es el informe de prueba relevante, con la esperanza de arrojar ladrillos y chispas de jade, y brindar algunos sentimientos intuitivos y sugerencias objetivas a los lectores. Si hay algún problema, deje un mensaje para señalarlo. (Este artículo solo representa la sugerencia personal del autor después de la prueba y no respalda ningún producto ni herramienta)
Introducción a las herramientas VaaS y Mythril
01. Introducción a las herramientas VaaS
La herramienta VaaS es una herramienta de verificación formal automática desarrollada de forma independiente por Beosin Chengdu Lianan utilizando sus propios derechos de propiedad intelectual. Puede proporcionar servicios de verificación formal de "nivel militar" para contratos inteligentes y aplicaciones de cadena de bloques , y puede localizar con precisión códigos de riesgo. Se señala la causa del riesgo y se detectan de manera efectiva las lagunas de seguridad convencionales, los atributos de seguridad y la corrección funcional del contrato inteligente, con una precisión de más del 95 % .
02. Introducción a las herramientas Mythril
La herramienta Mythril es una herramienta de análisis de seguridad proporcionada por la comunidad de código abierto de Ethereum . Puede detectar vulnerabilidades de seguridad en los contratos inteligentes de Solidity y realizar un análisis en profundidad. Es una herramienta de análisis de seguridad para analizar la seguridad de los contratos inteligentes de Ethereum y las aplicaciones de cadena de bloques y Engine , admite la integración IDE común.
2
Composición del caso de prueba
El caso de prueba de contrato consta de 260 contratos de token y 20 contratos comerciales .
Los contratos de token incluyen contratos de token Top200 y 60 contratos de token típicos para auditoría, que cubren funciones como ICO, bloqueo, acuñación y quema .
Los contratos comerciales incluyen 20 contratos comerciales, como subastas, centros comerciales y trazabilidad .
3
Descripción general de los resultados de la prueba
Las herramientas de VaaS pueden detectar todos los casos de prueba de contrato de tokens y clases comerciales, pero las herramientas de Mythril solo pueden detectar contratos de token, pero no pueden detectar contratos comerciales. Por lo tanto, debe tenerse en cuenta que esta descripción general de los resultados de las pruebas es solo un análisis comparativo de la lista de contratos de token.
Las herramientas VaaS tienen un total de 28 comprobaciones de vulnerabilidad, pero la herramienta Mythril tiene solo 9 comprobaciones de vulnerabilidad en comparación con las herramientas VaaS. Por lo tanto, los elementos de detección de las herramientas VaaS son mucho más que los de las herramientas Mythril. Los elementos de detección específicos se comparan de la siguiente manera:
Comparación de elementos de detección de VaaS y Mythril
Elementos de detección de vulnerabilidades |
mitrilo |
Florero |
Especificación estándar ERC20 |
✘ |
✔ |
Vulnerabilidad de recarga falsa |
✘ |
✔ |
TransferToZeroAddress (detección de dirección cero objetivo) |
✘ |
✔ |
Volver a entrar |
✔ |
✔ |
TXOriginAuthentication (error de uso de tx.origin) |
✔ |
✔ |
Invocar llamadas de bajo nivel (llamada de llamada, llamada de delegado, llamada de función de suicidio) |
✔ |
✔ |
Manipulación de BlockMembers (dependencia de parámetros de bloque) |
✔ |
✔ |
Invocar Extcodesize (llamar a la función Extcodesize) |
✘ |
✔ |
Invocar Ecrecover (llamar a la función Ecrecover) |
✘ |
✔ |
Llamar o enviar valores devueltos sin marcar (llamar y enviar detección de valor devuelto) |
✔ |
✔ |
Negación de servicio |
✔ |
✔ |
Redefinir contratos variables desde base (cobertura variable en la herencia del contrato) |
✘ |
✔ |
Retiro de éter sin protección |
✔ |
✘ |
Verifique este saldo (los fondos del contrato están estrictamente limitados) |
✘ |
✔ |
ArbitraryJumpwith Function (arbitrario con variables de tipo función) |
✘ |
✔ |
Afirmación de sobrecarga (función de afirmación de reescritura) |
✘ |
✔ |
CompilerVersionDeclaration (declaración de versión del compilador) |
✘ |
✔ |
Error de escritura del constructor |
✘ |
✔ |
Código complejo en la función de respaldo (utilizado por la función de respaldo) |
✘ |
✔ |
Operación unaria (+= escrito como =+ ) |
✘ |
✔ |
No Return (adaptación del valor de retorno) |
✘ |
✔ |
Valores de retorno de API no verificados (no verifique el valor de retorno de API) |
✘ |
✔ |
Emit Event Beforeerevert (evento desencadenado antes de la reversión) |
✘ |
✔ |
Desbordamiento de enteros |
✔ |
✔ |
Estado de excepción (detección anormal, incluida la matriz fuera de los límites, división por 0, falla de afirmación, etc.) |
✔ |
✔ |
Problema de llamada |
✘ |
✔ |
Problema de función |
✘ |
✔ |
Requerir falla |
✘ |
✔ |
01. Los resultados de la prueba de los mismos elementos de prueba para ambos
Para los 260 casos de prueba de tokens seleccionados, la herramienta Mythril puede ejecutar 184 resultados de contrato en 15 minutos y 76 no tienen resultados de detección, mientras que la herramienta VaaS puede ejecutar todos los resultados. Tome los 184 resultados que tanto la herramienta Mythril como la herramienta VaaS pueden ejecutar para comparar, y los resultados son los siguientes.
Tasa de aciertos y tasa de falsos positivos
通过检测结果对比,之于相同的检测项,VaaS工具的检测能力是远远高于Mythril工具的检测能力。据计算,VaaS工具的检测精度为96.9%;Mythril工具的检测精度为36.6%;而VaaS工具的误报率为15.3%;Mythril工具的误报率为48.5%。具体见下图。
需要注意的是,命中率和误报率的计算公式为:
命中率 = 命中个数/总问题个数
误报率 = 误报个数/(误报个数+命中个数)
笔者统计,VaaS工具和Mythril工具两者都进行的检测项共计655个问题:
VaaS工具总计检测出635个问题,命中率为96.9%;误报共115个,误报率为15.3%
Mythril工具总计检测出240个问题,命中率为36.6%;误报共计226个,误报率为48.5%。其中,Mythril工具重入攻击和拒绝服务误报率较高,占总数的93.3%。
检测总数值具体对比如下表:
— |
VaaS |
Mythril |
检测用例个数 |
184 |
184 |
问题总数 |
655 |
655 |
命中个数 |
635 |
240 |
误报个数 |
115 |
226 |
命中率 |
96.9% |
36.6% |
误报率 |
15.3% |
48.5% |
针对每项详细结果对比如下表:
漏洞检测项 |
总数 |
Mythril |
VaaS |
||
命中 |
误报 |
命中 |
误报 |
||
Re Entrancy(重入) |
14 |
7 |
115 |
14 |
0 |
50% |
94.2% |
100% |
0 |
||
TXOrigin Authentication (tx.origin使用错误) |
4 |
4 |
0 |
4 |
0 |
100% |
0 |
100% |
0 |
||
BlockMembers Manipulation (区块参数依赖) |
116 |
21 |
0 |
116 |
0 |
18.1% |
0 |
100% |
0 |
||
Denial of service (拒绝服务) |
14 |
7 |
83 |
14 |
0 |
50% |
92.2% |
100% |
0 |
||
Invoke Low Level Calls (call调用,delegatecall调用,自杀函数调用) |
54 |
7 |
0 |
54 |
0 |
12.9% |
0 |
100% |
0 |
||
Unchecked Call Or Send Return Values (call和send的返回值检测) |
25 |
4 |
0 |
25 |
0 |
16% |
0 |
100% |
0 |
||
Integer Overflow (整数溢出) |
356 |
126 |
28 |
336 |
90 |
35.3% |
18.1% |
94.3% |
20.1% |
||
Exception State (assert失败) |
72 |
64 |
0 |
72 |
25 |
88.8% |
0 |
100% |
25.7% |
测试时限
Mythril工具的平均测试时间为226.2s;而VaaS工具的平均测试时间为164.4s。说明VaaS工具的运行效率优于Mythril工具。
02.之于VaaS工具特有检测项的检测结果
具体见下表:
VaaS工具特有检测项用例结果展示说明
分类 |
VaaS log 关键字 |
说明 |
ERC20 标准规范 |
Erc20 Variable |
ERC20 变量命名规范 |
Erc20 Function |
Erc20函数命名规范 |
|
Erc20 Event |
Erc20 event使用规范 |
|
Fake Recharge Vulnerability |
假充值 |
|
Transfer To Zero Address |
目标地址非零检查 |
|
敏感函数调用 |
Invoke Extcodesize |
调用Extcodesize函数 |
Invoke Ecrecover |
调用Ecrecover函数 |
|
不推荐使用 |
Redefine Variable From Base Contracts |
合约继承中的变量覆盖 |
check_this_balance |
合约资金受到严格限制 |
|
unused_variables |
未使用的变量 |
|
Arbitrary Jump with Function Type Variable |
具有函数类型变量的任意跳转 |
|
Overload Assert |
重写assert函数 |
|
Solidity编码规范 |
Compiler Version Declaration |
编译器版本声明 |
Constructor Mistyping |
构造函数失配 |
|
Complex Code In Fallback Function |
fallback函数使用 |
|
Unary Operation |
+= 写成=+ |
|
Constructor Warning |
缺少主构造函数 |
|
No Return |
返回值适配 |
|
Unchecked Api Return Values |
没检查API返回值 |
|
Emit Event Beforerevert |
事件在revert前触发了 |
|
逻辑验证 |
Call problem |
call调用执行总是revert |
Function problem |
Function执行总是失败 |
4
案例演示
01.两者相同检测项案例
Re Entrancy(重入)
案例:
interface TEST {
function test123() external view returns (uint256);
function getBlocknumber() external view returns (uint256);
}
contract test2 {
function testCalling(address _testAdddress) public {
TEST t = TEST(_testAdddress);
t.test123();//mythril 误报
}
function testFormal(address _testAdddress) public view returns(uint256 time){
TEST t = TEST(_testAdddress);
t.getBlocknumber();//mythril 误报
return time;
}
}
contract Reentrancy {
mapping(address => uint256) public balances;
event WithdrawFunds(address _to,uint256 _value);
function depositFunds() public payable {
balances[msg.sender] += msg.value;
}
function showbalance() public view returns (uint256 ){
return address(this).balance;
}
function withdrawFunds (uint256 _weiToWithdraw) public {
require(balances[msg.sender] >= _weiToWithdraw);
require(msg.sender.call.value(_weiToWithdraw)());
balances[msg.sender] -= _weiToWithdraw;//mythril 明显的误报
emit WithdrawFunds(msg.sender,_weiToWithdraw);
}
}
VaaS工具测试结果:
Mythril工具测试结果:
▷笔者分析,VaaS工具报出存在重入攻击的位置;而Mythril工具针对外部的call调用作了告警,总共有4处告警,其中2处是正常的外部调用,另1处是明显的误报,误报率较高。
TXOriginAuthentication(tx.origin使用错误)
案例:
contract TxUserWallet {
address owner;
constructor() public {
owner = msg.sender;
}
function transferTo(address dest, uint amount) public {
require(tx.origin == owner);
dest.transfer(amount);
}
}
VaaS工具测试结果:
Mythril工具测试结果:
▷笔者分析,VaaS工具和Mythril工具均能对tx.origin关键字进行检测报警。
Invoke Low Level Calls(call调用,delegatecall调用,自杀函数调用)
案例:
contract Delegatecall{
uint public q;
bool public b;
address addr = 0xde6a66562c299052b1cfd24abc1dc639d429e1d6;
function Delegatecall() public payable {
}
function call1() public returns(bool) {
b = addr.delegatecall
(bytes4(keccak256("fun(uint256,uint256)")),2,3);
return b;
}
function call2(address add) public returns(bool){
b=add.delegatecall
(bytes4(keccak256("fun(uint256,uint256)")),2,3);
return b;
}
}
VaaS工具测试结果:
Mythril工具测试结果:
▷笔者分析,案例有两处delegetacall调用,而Mythril工具仅报了一次,存在漏报风险。
BlockMembers Manipulation(区块参数依赖)
案例:
function createTokens() payable external {
if (isFinalized) throw;
if (block.number < fundingStartBlock) throw;
if (block.number > fundingEndBlock) throw;
if (msg.value == 0) throw;
uint256 tokens = safeMult(msg.value, tokenExchangeRate);
uint256 checkedSupply = safeAdd(totalSupply, tokens);
if (tokenCreationCap < checkedSupply) throw;
totalSupply = checkedSupply;
balances[msg.sender] += tokens;
CreateBAT(msg.sender, tokens);
}
function finalize() external {
if (isFinalized) throw;
if (msg.sender != ethFundDeposit) throw;
if(totalSupply < tokenCreationMin) throw;
if(block.number <= fundingEndBlock && totalSupply != tokenCreationCap) throw;
// move to operational
isFinalized = true;
if(!ethFundDeposit.send(this.balance)) throw;
}
function refund() external {
if(isFinalized) throw;
if (block.number <= fundingEndBlock) throw;
if(totalSupply >= tokenCreationMin) throw;
if(msg.sender == batFundDeposit) throw;
uint256 batVal = balances[msg.sender];
if (batVal == 0) throw;
balances[msg.sender] = 0;
totalSupply = safeSubtract(totalSupply, batVal);
uint256 ethVal = batVal / tokenExchangeRate;
LogRefund(msg.sender, ethVal);
if (!msg.sender.send(ethVal)) throw;
}
}
VaaS工具测试结果:
Mythril工具测试结果:
▷笔者分析,VaaS工具和Mythril工具均能对区块参数依赖作出检测;但Mythril工具存在漏报风险。
Denial of service(拒绝服务)
案例:
contract Auction {
address public highestBidder = 0x0;
uint256 public highestBid;
function Auction(uint256 _highestBid) {
require(_highestBid > 0);
highestBid = _highestBid;
highestBidder = msg.sender;
}
function bid() payable {
require(msg.value > highestBid);
highestBidder.transfer(highestBid);
highestBidder = msg.sender;
highestBid = msg.value;
}
function auction_end() {
}
}
VaaS工具测试结果:
Mythril工具测试结果:
▷笔者分析,VaaS工具和Mythril工具均能针对拒绝服务作出风险检测。但在此案例中,highestBidder可能是恶意攻击合约,而导致transfer恒不成功,从而导致合约拒接服务,此案例VaaS工具能够检测出拒绝服务风险,Mythril工具未检出。
Unchecked Call Or Send Return Values(call和send的返回值检测)
案例:
if (lastTimeOfNewCredit + TWELVE_HOURS < block.timestamp) {
msg.sender.send(amount);
creditorAddresses[creditorAddresses.length - 1].send(profitFromCrash);
corruptElite.send(this.balance);
...
return true;
}
else {
msg.sender.send(amount);
return false;
}
VaaS工具测试结果:
Mythril工具测试结果:
▷笔者分析,VaaS工具和Mythril工具均能对未检查call调用的返回值检测;但Mythril工具存在漏报风险。
Integer Overflow(整数溢出)
案例1:
function distributeBTR(address[] addresses) onlyOwner {
for (uint i = 0; i < addresses.length; i++) {
balances[owner] -= 2000 * 10**8;
alances[addresses[i]] += 2000 * 10**8;
Transfer(owner, addresses[i], 2000 * 10**8);
}
}
▷笔者分析,以上案例没有对balances[owner]的值作检测,可能会产生下溢,但Mythrill工具不会报错,说明Mythrill工具对常数的运算不会作检测。
案例2:
contract A {
uint c;
function add(uint8 a,uint8 b){
uint8 sum = a+b;
c=sum;
}
}
VaaS工具测试结果:
Mythril工具测试结果:
▷笔者分析,Mythrill工具对非uint256数据类型的溢出检测不准确。
案例3:
Mythril工具的一些检测结果:
▷笔者分析,Mythrill工具对一些特定变量未作处理,导致误报。比如数组,msg.value,now等。
02.VaaS工具特有检测项案例
案例1:
...
contract ERC20 is ERC20Basic {
function allowance(address owner, address spender) constant returns (uint);
function transferFrom(address from, address to, uint value);
function approve(address spender, uint value);
event Approval(address indexed owner, address indexed spender, uint value);
}
...
function transfer(address _to, uint _value) onlyPayloadSize(2 * 32) {
balances[msg.sender] = balances[msg.sender].sub(_value);
balances[_to] = balances[_to].add(_value);
Transfer(msg.sender, _to, _value);
}
测试结果:
案例2:
contract A {
B b;
uint c;
function test(uint a){
b = new B(a);
c = b.get(200);
}
}
contract B {
uint b;
function B(uint e){
b=100;
}
function get(uint a)returns(uint){
require(a<100);
return a;
}
}
测试结果:
▷笔者分析,在案例2中关于合约间的调用问题,在拥有源码的情况下,VaaS工具是可以调用成功并进行测试的;而Mythril工具不行。这也是Mythril工具无法进行业务合约验证的原因之一。
通过以上对VaaS工具和Mythril工具逻辑、维度、数据进行简单的对比分析,笔者认为,读者在阅后将能够根据自身业务取向和侧重作出相应的判断和评估。
且毋论智能合约和区块链应用,甚至整个区块链行业的安全性,未来都将需要以一种供(增长率)求(安全性)关系平衡的模式向前发展,我们就更需要清楚地知道,当前现状的痛点所在,以及如何针对该痛点进行改进和革新。
无论是作为前沿科技拥戴者,还是区块链技术极客,但凡具备去中心化思维以及认可智能合约及区块链应用在未来具备深远影响力的有识之士,都能明白笔者针对『形式化验证』作此篇测试报告的用意。
Es cierto que, aunque actualmente se está prestando más atención a cómo promover la implementación de contratos inteligentes y aplicaciones de cadena de bloques y la construcción general del ecosistema de cadena de bloques, aún existen varias lagunas y riesgos en la arquitectura técnica subyacente que no se han resuelto. , sería demasiado ambicioso.
Por lo tanto, el autor sugiere que para garantizar la seguridad de los contratos inteligentes masivos y las aplicaciones de la cadena de bloques, así como mantener el buen funcionamiento y mantenimiento de la ecología de la cadena de bloques, la "verificación formal" se ha convertido en una forma importante de auditoría automatizada.
Es una etapa necesaria para el desarrollo de los contratos inteligentes actuales y las aplicaciones de cadena de bloques para juzgar la viabilidad de una determinada herramienta de verificación y auditoría a través de dimensiones de evaluación como la tasa de falsos negativos, la tasa de falsos positivos, la tasa de aciertos y .el límite
▲Algunas imágenes son de Internet
más información
Matriz de medios Beosin
|
https://www.facebook.com/ BeosinChengdu/ |
|
Gorjeo https://twitter.com/Beosin_com |
|
Telegrama https://t.me/LiananTech_cn (chino) https://t.me/LiananTech_en (inglés) |
|
https://weibo.com/u/6566884467 |
|
Blog de CSDN https://blog.csdn.net/CDLianan |
|
Marte Tecnología de seguridad de la cadena de Chengdu |
|
saber casi Tecnología de seguridad de la cadena de Chengdu |
|
GitHub https://github.com/Lianantech/VCA |
Haga clic en "Leer el texto original"
Visite inmediatamente el sitio web oficial de "Beosin Chengdu Lian'an"