Ir para conteúdo

Minha tentativa do exercicio do AMO


unc4nny

Posts Recomendados

Entao, tentei fazer o exercicio que o Fernando deixou pra gente na aula 0 do AMO. Acabou que eu nao cheguei exatamente em um resultado, mas eu acho que cheguei perto. Entao aqui vai minha 'nao-solucao' (O sistema que eu uso eh Manjaro Linux, soh por via das duvidas):
A primeira coisa que eu fiz, foi voltar pra VM e abrir o arquivo com o pestudio mais uma vez, soh pra dar mais uma olhada na tabela de strings que o pestudio formou. Nela eu achei algumas coisas interessantes: Uma sequencia de caracteres que representa os caracteres da base64 (A-Z, a-z, 0-9, + e /) e duas "stringonas". Uma delas eh aquela que ele mostrou no video, de tamando 1128, e outra de tamanho 368.  Alem de strings em russo e alguns sites.

Okay, fiquem com essa informacao da string de caracteres em base64 em mente, vai ser importante (talvez) la pra frente.

image.png.12b29533a8a658e061ab8f70a333688b.png

Mas como o desafio era entender a stringona, eu foquei nisso. A primeira coisa que eu tentei fazer foi decodificar a string:image.png.ceead8e6b154f42c99d42b65b003abb5.png

Esse foi o resultado. Nao ajudou muita coisa entao eu tentei ver que tipo de arquivo ele eh:

image.png.b94cc248ae91e2d585bf39355671c782.png

Okay, aparentemente eh uma stream de bytes, dumpando esse arquivo eu obtive:
image.thumb.png.a576582735068f99c7d8a428dc38fcfa.png

Isso tambem nao ajudou em nada. Entao eu peguei a outra "stringona" e fiz a mesma coisa, pulando pra parte do dump, ela ficou desse jeito:

image.png.21353795890de24a929209969429927a.png

Tambem nao ajudou em muita coisa, mas nessa a gnt ve uma sequencia de caracter conhecida: 'RSA1', um criptosystem bem conhecido. Mas o objetivo eh a outra stringona.

Entao ele tem duas strings (que eu saiba) codificadas em base64, e uma outra string com caracteres de base64, me parece razoavel pensar que ele vai decriptar essas strings dentro do programa, usando uma implementacao de decriptador caseira. Com essas informacoes e suposicoes, eu pulei pro ghidra pra tentar ver onde essas strings sao usadas:

Procurei strings com no minimo tamanho 63, para ver se encontrava onde os caracteres base64 sao usados, que provavelmente seria o decoder dele:image.png.95203c128625f8acb838fd1b46bb5180.png

Infelizmente, ghidra nao conseguiu achar a string dos caracteres base64, mas achou as outras 2 stringonas. Entao, peguei a maior e fui ver onde ela era usada:image.png.380d0ba8e9dfb2ea89714da4505a0c0a.png

Vemos que o ghidra identificou que a string eh utilizada em 6 ocasioes diferentes, vamos ver entao.

image.thumb.png.60432317669cbc48ac44147b31d7d353.png

Todas as 6 vezes sao na mesma funcao, apelidade pelo ghidra de FUN_004013F2. Essa eh uma das vezes que ele usa ela:

  1. Ele pega o tamanho da string, faz um calculo maluco que eu nao entendi o motivo com ele, cujo resultado deu 846. image.png.994b497ef97a7b0f9dedd93c31627107.png
  2. Pega o HANDLE para a heap do processo. Que chamou a funcao, que no caso eu imagino que seja o proprio ransomware.
  3. Aloca um bloco de tamanho 846 na heap do processo.

A seguir, ele de novo faz o calculo do tamanho da stringona, mas usa ele com outro proposito:

image.thumb.png.24a70326409ef0cc356775f0a51be24f.png

Ele chama a funcao que o ghidra apelidou de FUN_0040133e, passando como primeiro argumento a stringona, e como segundo o tamanho da string, entrando na funcao:

image.thumb.png.1d3f358b8699c409e908cc4c0d8b7961.png

Esse eh o resultado do decompiler do ghira. Nao entendi muita coisa dessa funcao, pra ser sincero, quando tem muita manipulacao de bit na funcao eu geralmente soh ignoro kkkkk.
Mas algumas coisas nessa funcao chamaram minha atencao. Primeiro que eu ja estava esperando que essa stringona fosse chamada em uma funcao desse estilo. Pois como ja foi dito, eu esperava que ele decodificasse ela dentro do codigo. Entao eu fui na internet procurar por algumas implementacoes de um decoder base64:

image.thumb.png.fa736e9abfce4d8649409379c8280d8f.png

image.thumb.png.e9f7d9f86cc8b45c0fa24925c9cdecb3.png

image.thumb.png.a328949275b2b6a9962aec8e70dde6c8.png

Nao vou falar que eh 100% igual, mas existem semelhancas muito grandes. Entao eu continuei a explorar com a suposicao que aquele era o decoder dele. Mas soh tem um problema, ele nao usa nenhum tipo de retorno, e o ghidra nao especifica se ele esta usando de fato um literal de string ou um endereco de memoria. Entao eu parti pra analisar as instrucoes e ver o que elas me dizem

 Antes de passar pras  instrucoes, notem que depois que ele chama o 'decoder' ele faz faz mais uma vez aquele calculo doido com o tamanho da stringona e chama uma funcao da API do windows, CryptDecrypt:

image.thumb.png.7bcb4405d056ab5d2fef04675d5b5669.png

Eu poderia ver o que eh este DAT_0040F968. Mas isso vai alem do escopo do exercicio. Eu ate tentei, mas assim como esse exercicio, eu cheguei numa resposta mais ou menos hehehe

 

Aqui esta a sequencia de instrucoes ate o CryptDecrypt:

image.png.091560d22f7065c619f3d7d55d4a7b89.png

Aqui, percebi que realmente, aparentemente ele nao utiliza o resultado da funcao que eu estava chamando de decoder, e que ate agora ainda acredito que seja, pois ela eh usada mais uma vez em um contexto similar, no que eu acredito que seja a outra stringona, mas isso vai alem do escopo do exercicio. Voltando para CryptDecrypt, os argumentos passado para ela sao:

image.png.f632bc9dba2dcc18a280a25667502893.png

Segundo a API do windows, essa funcao decripta dados que foram previamente encriptados usando a funcao CryptEncrypt, que inclusive eh o contexto que eu me referi onde a outra stringona eh usada, com a funcao que eu acredito que seja o decoder.

image.png.9a8df51b02898f252997993d0978acab.png

Essa eh a assinatura da funcao, entao, fazendo a cross-reference com a assinatura e com os parametros que foram passados pra chamar a funcao, da esquerda pra direita:

  • DAT_0040F968 = hKey (Um HANDLE para a chave que sera usada para decriptacao, esse HANDLE foi gerado pela funcao CryptImportKey, pelo que eu pude perceber a outra stringona tambem sera usada nessa funcao. Acredito que a outra stringona na verdade seja usada para encriptar, e essa para decriptar.)
  • 0 = hHash (Um HANDLE para um objeto hash, o valor eh zero entao provavelmente eh um ponteiro nulo)
  • 1 = Final (Um valor booleano que indica se esta eh a ultima secao de blocos a ser decriptada, o valor eh 1 entao ela eh a ultima ou a unica)
  • 0 = dwFlags (Nao ha flags, entao nao precisamos nos preocupar, mas isso seria imagino que algumas opcoes adicionais para a decriptacao)
  • pbData = pbData (Na verdade, como podemos ver la em cima, esse eh o valor do bloco alocado de heap do processo. Segundo a API do windows, esse valor deve ser um ponteiro para o buffer que contem os dados a serem decriptados. Depois que a decriptacao eh realizada, o plain text eh colocado nesse buffer )
  • pbwDataLen = pbwDataLen (Eh o valor daquele calculo doido que eu nao entendi direito com o tamanho da stringona maior. Segundo a API, isso eh o tamanho do buffer a ser decriptado, que no caso ja vimos que eh 846).

Entao eh isso. Essa eh a minha "nao-solucao". Nao cheguei a entender completamente (na vdd acho que n entendi foi nada kkkk) o motivo dessa stringona, seria ela apenas uma tecnica de defense-evasion ou ela tem mais algum outro motivo que eu nao consegui captar? Ajuda o maluco que ta doente aki kkkkk

Atualizacao: Aparentemente 846 eh o tamando da stream de bytes que representa a stringona decodada. Entao parece justo eu assumir que esse calcula na verdade eh uma otimizacao do compilador ou o ghidra nao conseguiu interpretar isso como uma chamada de funcao? Ou talvez realmente seja algum tipo de calculo que ja existe, vou dar uma pesquisada sobre

image.png.79fe7bbdb539c0b63c6cf4604deec4ce.png

 

 

 

 

 

 

image.png

Link para o comentário
Compartilhar em outros sites

  • 7 meses depois...

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

  • Quem Está Navegando   0 membros estão online

    • Nenhum usuário registrado visualizando esta página.
×
×
  • Criar Novo...