Back to Blog

Revisitando o Incidente de Segurança do CashioApp

Code Auditing
May 16, 2022
5 min read

Iniciado em 23 de março de 2022 às 16:20:08 UTC+8, o CashioApp foi explorado para drenar a conta de tokens de garantia, com perdas de aproximadamente 52 milhões. O ataque foi possível devido à verificação insuficiente das contas de entrada, o que permitiu ao atacante cunhar 20 bilhões de tokens $CASH sem nenhum depósito. A seguir, apresentamos os detalhes técnicos.

Resumo

O incidente foi causado por um bug no programa Brrr, projetado para gerenciar a cunhagem e a queima de tokens $CASH com a garantia de Saber LP Arrows. Especificamente, os usuários podem imprimir $CASH, ou seja, cunhar CASH,depositandotokensLPdoArrow.NotequeotokenArrowLPrecebeo[tokenLPdoSaber](https://app.saber.so/swap)comotokenssubjacentes.Ainstruc\ca~oprintcash,quepodecunharCASH, depositando tokens LP do `Arrow`. Note que o token Arrow LP recebe o [token LP do Saber](https://app.saber.so/swap) como tokens subjacentes. A instrução `print_cash`, que pode cunhar `CASH, recebe uma lista de contas incluindo a conta Banke a contaCollateral. Elas são usadas para registrar e rastrear a garantia (isto é, tokens LP do Arrow) que pode ser utilizada para cunhar CASH.Pordesign,essasduascontasdeveriamserinicializadaseautorizadasapenaspeloadministrador.Noentanto,oprogramafalhaemverificaravalidadedacontaBank.Comoresultado,oatacantepodecriarumaseˊriedecontasfalsas(incluindoacontaBank)paraalimentarainstruc\ca~oprintcasheimprimirCASH`. Por design, essas duas contas deveriam ser inicializadas e autorizadas apenas pelo administrador. No entanto, o programa falha em verificar a validade da conta `Bank`. Como resultado, o atacante pode criar uma série de contas falsas (incluindo a conta `Bank`) para alimentar a instrução `print_cash` e imprimir `CASH` praticamente de graça (o único custo são as taxas de transação).

Detalhes

Vamos começar a análise pelas contas utilizadas na instrução print_cash abaixo.

O atributo common (linha 75) é uma struct cujo tipo é BrrrCommon no programa. Em BrrrCommon, a conta bank e a conta collateral são inicializadas e autorizadas pelo administrador. O crate_token é a conta do token $CASH, que armazena informações sobre o $CASH, como a chave pública do crate_mint (linha 107), as chaves públicas dos papéis de administrador e mais. O crate_collateral_tokens é uma conta cofre que mantém os tokens de garantia transferidos pelos usuários. Como a garantia deve ser tokens LP do Arrow, que recebem os tokens LP do Saber, os usuários precisam inserir as contas relacionadas ao saber_swap. Os últimos dois atributos na struct BrrrCommon são os IDs de programa dos programas-alvo utilizados na instrução. Note que os últimos quatro atributos na struct PrintCash são a conta de sistema do usuário (também o assinante da transação), a conta de garantia do usuário, a conta de token $CASH do usuário que recebe o $CASH cunhado, e a chave pública da conta com autoridade para cunhar o $CASH.

A Transação do Ataque

Após entender a funcionalidade das contas acima, passamos a analisar a transação do ataque: 0x4fgL…z2K5. Este ataque foi iniciado a partir do endereço do atacante (localizado em 0x6D7f) e a lista de contas de entrada na instrução PrintCash é mostrada abaixo.

A Account #1 (0x5aha) acima corresponde à conta Bank. Observamos que ela é diferente do endereço fornecido no site oficial do CashioApp (0xEm1P), o que significa que a validação da conta Bank é insuficiente!

Validação

Vamos analisar mais de perto a validação da struct BrrrCommon no código para entender como o bypass funciona.

A única verificação da conta Bank de entrada é garantir que a conta Collateral de entrada esteja associada à conta Bank (linha 12). No entanto, isso pode ser facilmente contornado fornecendo também uma conta Collateral falsa. Além disso, para evitar o pagamento de ativos de garantia reais, o atacante também forneceu contas saber_swap falsas. Note que o atacante visa depositar ativos de garantia sem valor para imprimir tokens $CASH valiosos, portanto o crate_token e o crate_mint fornecidos pelo atacante devem ser endereços verdadeiros. Em outras palavras, a verificação insuficiente da conta Bank permite ao atacante criar uma série de contas falsas para imprimir $CASH com garantias sem valor.

A Correção

A correção consiste em adicionar a instrução assert_keys_eq!(self.bank.crate_mint, self.crate_mint). Essa instrução garante que o crate_mint da conta Bank seja o crate_mint correto para o $CASH. Mas como isso garante que a conta Bank seja válida? Vamos analisar a struct NewBank (no programa bankman) e a struct NewCrate (no programa crate_token) para encontrar a resposta.

Na verdade, a conta Bank é um PDA cujas sementes contêm o endereço do crate_token. Ao mesmo tempo, o crate_token também é um PDA cujas sementes contêm o endereço do crate_mint. Isso garante que a conta Bank seja válida se o crate_mint de entrada for válido. Sem um crate_mint correto, os atacantes não podem cunhar o $CASH e não podem lançar os ataques.

Sobre a BlockSec

A BlockSec é uma empresa pioneira em segurança blockchain, fundada em 2021 por um grupo de especialistas em segurança de renome mundial. A empresa está comprometida em aprimorar a segurança e a usabilidade para o emergente mundo Web3, a fim de facilitar sua adoção em massa. Para isso, a BlockSec oferece serviços de auditoria de segurança de contratos inteligentes e chains EVM, a plataforma Phalcon para desenvolvimento seguro e bloqueio proativo de ameaças, a plataforma MetaSleuth para rastreamento e investigação de fundos, e a extensão MetaSuites para construtores web3 navegarem com eficiência no mundo cripto.

Até o momento, a empresa atendeu mais de 300 clientes ilustres, como MetaMask, Uniswap Foundation, Compound, Forta e PancakeSwap, e recebeu dezenas de milhões de dólares americanos em duas rodadas de financiamento de investidores proeminentes, incluindo Matrix Partners, Vitalbridge Capital e Fenbushi Capital.

Site oficial: https://blocksec.com/

Conta oficial no Twitter: https://twitter.com/BlockSecTeam

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit