Back to Blog

#9: Bot MEV 0xd61492: De Predador a Presa em um Exploit Engenhoso

Phalcon Security
February 21, 2024
6 min read

Em 3 de agosto de 2023, um MEV Bot na Arbitrum foi atacado, resultando em uma perda de $800K. A causa raiz desse ataque foi a Verificação Insuficiente de Entradas do Usuário.

Considerando as interações intrincadas entre os MEV Bots e seus contratos não verificados, fica evidente que não ser de código aberto não garante segurança, especialmente para protocolos DeFi.

Contexto

MEV Bot

MEV Bot (Bot de Valor Máximo Extraível) é projetado para identificar e executar oportunidades lucrativas na blockchain. Ele opera analisando transações pendentes (ou seja, aquelas no mempool) ou estados on-chain para gerar lucros por meio de arbitragem.

Ao contrário dos MEV Bots típicos de front-running e ataque sanduíche, o MEV Bot visado neste ataque focava na execução de estratégias como arbitragem triangular e liquidação de dívidas. Esses bots ajudam a estabilizar os preços para AMMs e auxiliam os protocolos de empréstimo com liquidações para garantir uma operação tranquila, constituindo uma parte essencial do funcionamento saudável do ecossistema DeFi.

Flashloan

O Flashloan representa uma inovação única no ecossistema DeFi – uma forma de empréstimo sem garantia. Você pode tomar emprestado até um bilhão de dólares por meio de Flashloan sem qualquer garantia, desde que o empréstimo seja reembolsado na mesma transação. Se o empréstimo não for reembolsado dentro dessa transação, ele será revertido, como se a transação nunca tivesse acontecido.

Esse mecanismo é comumente usado para arbitragem ou para alavancar outras estratégias DeFi a fim de explorar ineficiências temporárias do mercado.

A Vulnerabilidade

Versão Resumida

A validação insuficiente dos parâmetros inseridos pelo usuário permitiu que o atacante introduzisse um FakeFlashloanProvider. O contrato vault utilizou esse provedor para iniciar um flashloan. Posteriormente, talvez para liquidar o flashloan, o contrato vault aprovou tokens para o FakeFlashloanProvider, levando à transferência não autorizada de ativos para fora do vault.

Versão Detalhada

O contrato explorado é:

  • Vault: O contrato vítima 0xd614927acfb9744441180c2525faf4cedb70207f serve como um "Vault", fornecendo reservas e facilitando flashloans de outros protocolos como AAVE e Balancer.
  • Arbitrage Bot: O contrato vulnerável 0x8db0efee6a7622cd9f46a2cf1aedc8505341a1a7, funcionando como um "Arbitrage Bot", ocupa o papel de tomador de empréstimo no contrato "Vault".

A função 0x0582f20f() no "Arbitrage Bot" é o principal ponto de entrada para iniciar arbitragens. Ela primeiro invoca o borrow() no "Vault" para adquirir o principal original, depois executa a lógica de arbitragem por meio de um delegatecall para um contrato externo especificado no calldata e sem nenhuma validação.

function 0x0582f20f(...) {
  ...
  v67, /* uint256 */ v68 = address(0xd614927acfb9744441180c2525faf4cedb70207f).borrow(address(v39), address(v9[0]), v29).gas(msg.gas);
  ...
  // 0x4da91757 = swap(address,address,address,uint256,uint256,uint256,address)
  MEM[MEM[64] + 32] = uint224(address(MEM[0 + v4[v69]])) | 0x4da9175700000000000000000000000000000000000000000000000000000000;
  v82 = address(v76 >> 96).delegatecall(MEM[(MEM[64]) len 228], MEM[(MEM[64]) len 0]).gas(msg.gas);
  ...
  v189 = v170.refund(0x410085df, address(v9[0]), address(v39), v68, address(v9[0]), v29, v186, 4 + MEM[64] + (varg2.length << 5) - (4 + MEM[64]) + 192).gas(msg.gas);
  ...
}

Em seguida, ele invoca o 0x512b7351() no "Vault", iniciando um flashloan para o contrato FakeFlashloanProvider do atacante.

A função 0x512b7351() exige que msg.sender esteja na lista de permissões, mas foi contornada com sucesso pelo delegatecall anterior, burlando a verificação. Este é um passo muito crítico

function 0x512b7351(...) public nonPayable { 
    ...
    if (_borrow[msg.sender] >= 1) {
        v0 = !_refund;
    }
    require(v0, Error('BBVault: FORBIDDEN'));
    ...
    v38 = v23.length;
    v39 = v23.data;
    _refund = keccak256(v23);
    ...
    <FakeFalshloanProvider>.flashloan(...);
    ...
}

Durante o callback do flashloan, o executeOperation() no "Vault" primeiro transfere os ativos emprestados para o MEVBot "Arbitrage Bot" 0x8db0ef, depois chama seu 0x7fe3ba8b().

function executeOperation(...) {
  ...
  require(_refund == keccak256(v3.data), Error('BBVault: STATUS'));

  Token.transfer(ArbitrageBot, amountBorrowed);
  <ArbitrageBot>.call(0x7fe3ba8b...);
  
}

O "Arbitrage Bot", confiando nessa chamada externa, transfere os ativos recebidos de volta para o FakeFlashloanProvider. No entanto, o "Vault" não reconhece isso e ainda concede aprovação ao FakeFlashloanProvider para reembolsar o flashloan ao final do executeOperation().

O Processo de Ataque

Tx do Ataque: 0x864c8cfb8c54d3439613e6bd0d81a5ea2c5d0ad25c9af11afd190e5ea4dcfc1f

O atacante invoca o 0x0582f20f() do "Arbitrage Bot", que por sua vez realiza uma chamada delegate para o contrato do atacante.

O hack_contract_2 então chama a função 0x512b7351() da vítima. O 0x512b7351() exige que msg.sender esteja na lista de permissões, mas foi contornado com sucesso pelo delegatecall anterior, burlando a verificação.

A vítima então chama o contrato FakeFlashloanProvider do atacante, transferindo todos os ativos do flashloan para a vítima e chamando o executeOperation() da vítima.

O 0x7fe3ba8b() do Arbitrage Bot novamente realiza um delegatecall para o contrato do atacante, desta vez transferindo todos os ativos de volta para o atacante. **Neste ponto, os ativos emprestados pelo Flashloan Provider do atacante foram reembolsados. **

A vítima ("Vault") aprova tokens para o FakeFlashloanProvider, possivelmente com a intenção de reembolsar o flashloan.

O atacante explora essa aprovação para obter lucro, usando transferFrom para drenar fundos da vítima.

Recomendações de Segurança

Código não aberto não garante segurança

Acreditar que código não aberto e ofuscado garante segurança é um equívoco. Este incidente com o MEV Bot revela que o sigilo não protege contra exploits e pode dar aos desenvolvedores uma falsa sensação de segurança.

Validação Rigorosa de Entradas

É fundamental validar meticulosamente todas as interações de contratos e calldata, especialmente ao lidar com interfaces padrão como callbacks de flashloan e swap. Garantir a integridade e a segurança dos dados deve ser uma prioridade no design e na implementação de contratos.

Leia outros artigos desta série:

Get Real-Time Protection with Phalcon Security

Audits alone are not enough. Phalcon Security detects attacks in real time and blocks threats mid-flight.

phalcon security