IoC Types and the Pyramid of Pain
Not all IoCs are created equal. Some are easier for attackers to change than others. RFC9424, authored by Kirsty Paine, Ollie Whitehouse, James Sellwood and Andrew Shaw, talks about the Pyramid of Pain to illustrate this.
Hashes of malicious files are low pain for attackers to change. IP addresses and domain names require a little bit more work. Network and endpoint artefacts like traffic patterns or file timestamps take more effort to alter and tools used in attacks are painful to substitute. Finally, an attacker’s tactics, techniques, and procedures (TTPs) require the most effort to change, these are more about human or team habits.
When selecting IoCs, choose indicators across the pyramid to create layered defences. Combine fragile indicators like hashes with more robust TTP-based IoCs. These indicators will have different amounts of value over time, that match up to the pyramid. For example a hash may only be useful for that specific attack, an IP address may be useful for the duration of the incident, but the method of attack, or location of tools may last across several engagements.
Consider this scenario:
An attacker exploits a vulnerability and drops a Webshell, they then use that to connect to the webserver, they escalate privileges on the box and start dropping tools, gaining legitimate credentials and dropping persistence. From here they connect to the VPN using non-MFA credentials (it’s not uncommon), carry out recon activity on the network initially target the Domain Controller where they drop the NTDS.dit, they then use legitimate Domain Admin credentials to attempt to deploy Ransomware.
The IOCs you capture are as follows:
Tool/TTP | Details of Tool | IOC |
Webshell | ASPX/PHP file (either works for this) | SHA256 Hash Folder Location Vulnerability of choice |
Priv Esc Tool | Customised GitHub PoC | SHA256/GitHub Repo |
Persistence Task | Scheduled Task | Task Name Task Location (root task, or in a sub-folder) Task details which are calling a Persistence Binary frpm, |
Persistence Binary | Cobalt Strike Binary connecting to IP. Binary saved to C:\Users\Public\Music | SHA256 of Binary Binary Name Binary Location Attackers C2 IP (from reverse engineering/sandbox of binary) |
VPN/RDP | Attacker connects to the VPN and RDPs from their attack machine | Attacker’s IP Address Attacker’s Hostname Attacker Operating System Any other leaked data from their system RDP Cache may provide insight into TTPs |
Recon Tools | Legitimate network scanning tools | TTPs from tools Output from these tools |
Lateral Movement Tools | Tools such as PSExec or Impacket | TTPs from tools TTPs from how they use these tools, what arguments they use etc |
Dumping NTDS.dit | VSS Exploitation | TTPs from method of exploiting VSS Location of output files from dump Did the attacker clean up, or leave the data Compromised user account details |
Ransomware | Ransomware as a Service (RaaS) tool | TTPs from tool Potential attribution to known attack group/gang Contact details on ransom note Method of Ransom deployment SHA256 of Ransomware binaries |
From the above (very high level, very vague) scenario we have a list of IoCs that range across the pyramid of pain. In terms of how we use them, this will depend massively on the maturity of the security team and their tooling.
Some teams will be able to block based the hash value, or location, others could alert, and some will be blind to this.
Consider all of the IOCs above and think about how your team would see them. Could you do this on 1 host, how about 1,000? Could you do this in near real time for multiple days with the ability to add more?
If you answered ‘no’, you may need to review your technologies and raise this with the business owners.
Managing the IoC Lifecycle
Having hashes for an attack that happened 5 years ago is not helpful, not having the domain name for an active attack is not helpful. Having an AWS IP address blocked by your firewall is not helpful! Consider points like this when thinking about the IoC lifecycle as pointed out in RFC 9424:
- Discovery – Extract IoCs from compromised systems, network traffic, threat feeds, etc.
- Assessment – Evaluate IOC quality and provenance before deployment.
- Sharing – Distribute IOCs with rich context to enable appropriate defences.
- Deployment – Get IOCs to controls like firewalls and EDR for detection/prevention.
- Detection – Monitor for and react appropriately to IOC matches.
- End of life – Retire stale IOCs to avoid false positives.
Automating ingestion, deployment, and retirement is key for managing large volumes. However remember the philosophy of “shit in, shit out”. If you accidentally pick up the hash for explorer.exe because it was a parent process to malware, you are going to be having a bad day.
Adopt a Defence-in-Depth Approach
Because different IoCs work at different layers, utilize IoCs as part of a layered defence-in-depth strategy. Relying solely on endpoint security can be risky if the EDR product is not up to the task, or is not able to provide the blocking functionality. Deploy network-level IoCs to complement endpoint protections.
Why should I care?
This type of work is the bread and butter of defenders, it also helps highlight how defenders operate if you are on the red-team.
Understanding what is useful for looking backwards vs forwards is important. Hashes, IPs and other items at the easy end of the pyramid of pain are typically for looking backwards, seeing what has already happened and responding to that. Things that are near the top of the pyramid help us to look forward. What can we expect the attacker to do in the future? What is common thing that 99% of attackers do? How do we monitor for that?
Asking these questions and understanding where and how to find the answer is why RFCs like RFC9424 are important and why we need to not just read them, but understand them.