Análise ao Jscrambler

Posted by Miguel Lopes on Tue, Sep 17, 2013
In Na Minha Opinião, Segurança,

A Auditmark é uma empresa de segurança informática, iniciada na UPTEC, com a missão de desenvolver soluções para os problemas de segurança da web. O jscrambler é o ofuscador de código javascript da Auditmark, que permite ofuscar facilmente projetos inteiros (ficheiros html e js).

A auditmark afirma que o seu produto pode ser usado para proteger os algoritmos em aplicações javascript, prevenir a reutilização, modificação e a execução do código não autorizada. Sendo que este “prevenir” não quer dizer evitar ou impedir mas sim mitigar o alcance desses objectivos. O jscrambler tenta tornar o processo tedioso ao ponto de que ninguém tenha paciência para extrair o código. A extração do código é sempre possível porque o javascript é uma linguagem interpretada pelo browser.

Nestes exemplos iniciais irei substituir o conteúdo original pela palavra PAYLOAD já que o código nesta zona está ofuscado.

Para percebermos como funciona o jscrambler vamos começar por analisar um pequeno script, que neste caso será o jsregex.js (do site jsregex.com) que com todas as proteções ficou semelhante á seguinte linha muito menos legivel.

O código está disponível neste gist.

A primeira coisa a fazer é organizar o código de forma a que se torne mais fácil de ler e para isso usei o jsbeautifier, que introduz espaços, mudanças de linha e indentações.

O código está disponível neste gist.

(Neste script estão apenas comentadas as linhas com interesse para ultrapassar o primeiro bloqueio de domínio.)

Depois de passar o código no jsbeautifier já temos algo mais legível, e conseguimos ver que as primeiras linhas são cruciais para o bloqueio de domínio. Agora que sabemos onde vão buscar o domínio podemos alterar a variável para o nome de domínio a que ficou bloqueado o script que neste caso é “jscrambler.com”. Neste momento o código já é extraído mas para o obtermos é necessário intercepta-lo, para isso substituímos o “eval(” por “(var codigo =”  e posteriormente vemos o valor da variável código.

O código está disponível neste gist.

O próximo passo para possibilitar a execução do script é a remoção ou prolongamento do bloqueio de tempo. Na segunda linha a variável W3 têm um valor aparentemente complicado. É utilizado um operador ternário que se for executado na consola mostra que lhe é atribuído o valor 0x1412DEFEB00 (1379455200000) sendo este o tempo máximo de vida que defini para o script. Depois de ultrapassado podemos incrementa-lo para que o script funcione, ou remover completamente o bloqueio, no entanto a sua remoção completa implica a substituição prévia da função F3.y3 (através de uma nova função ou da substituição das referencias pelos respectivos valores).

Agora o script já corre normalmente sem limitações de tempo ou de domínio. Para scripts maiores são introduzidos mais bloqueios de tempo e domínio no entanto ao utilizar o mesmo processo é fácil de remover tudo.

Nesta etapa podemos reutilizar este código, correr localmente se for necessário para compreender melhor o que está acontecer. Em alternativa aos métodos utilizados podemos sempre alterar o ficheiro “hosts” e fazer o browser pensar que está a aceder ao domínio pretendido.

Para perceber-mos o algoritmo basta ler o código, que pode parecer complexo e muito extenso mas têm apenas alguns truques para dissimular o que realmente interessa. Isto pode parecer tedioso por conter muitos operadores ternários mas pode ser resolvido rapidamente com o ajuda de um script.

Um bom auxilio é o closure compiler da google que interpreta e simplifica código javascript.

Este é um exemplo extremamente simples mas demonstra as protecções usadas e algumas maneiras de as neutralizar rapidamente. Já testei a protecção de alguns clientes e embora seja diferente (possivelmente por serem de versões anteriores? ou um plano mais avançado?…) continuam a ser utilizadas técnicas semelhantes.

Futuramente irei publicar o script que uso para auxiliar na limpeza do código.

UPDATE: Já está disponibilizado o script no github



comments powered by Disqus