diff --git a/monkey/common/data/post_breach_consts.py b/monkey/common/data/post_breach_consts.py index c3bba9950..1dc739a7d 100644 --- a/monkey/common/data/post_breach_consts.py +++ b/monkey/common/data/post_breach_consts.py @@ -6,3 +6,4 @@ POST_BREACH_HIDDEN_FILES = "Hide files and directories" POST_BREACH_TRAP_COMMAND = "Execute command when a particular signal is received" POST_BREACH_SETUID_SETGID = "Setuid and Setgid" POST_BREACH_JOB_SCHEDULING = "Schedule jobs" +POST_BREACH_TIMESTOMPPING = "Modify files' timestamps" diff --git a/monkey/infection_monkey/post_breach/actions/timestomping.py b/monkey/infection_monkey/post_breach/actions/timestomping.py new file mode 100644 index 000000000..3d0564b0d --- /dev/null +++ b/monkey/infection_monkey/post_breach/actions/timestomping.py @@ -0,0 +1,12 @@ +from common.data.post_breach_consts import POST_BREACH_TIMESTOMPPING +from infection_monkey.post_breach.pba import PBA +from infection_monkey.post_breach.timestomping.timestomping import \ + get_timestomping_commands + + +class Timestomping(PBA): + def __init__(self): + linux_cmds, windows_cmds = get_timestomping_commands() + super().__init__(POST_BREACH_TIMESTOMPPING, + linux_cmd=linux_cmds, + windows_cmd=windows_cmds) diff --git a/monkey/infection_monkey/post_breach/timestomping/linux/timestomping.py b/monkey/infection_monkey/post_breach/timestomping/linux/timestomping.py new file mode 100644 index 000000000..ea608b85d --- /dev/null +++ b/monkey/infection_monkey/post_breach/timestomping/linux/timestomping.py @@ -0,0 +1,11 @@ +TEMP_FILE = 'monkey-timestomping-file.txt' +TIMESTAMP_EPOCH = '197001010000.00' + + +def get_linux_timestomping_commands(): + return [ + f'echo "Successfully changed a file\'s modification timestamp" > {TEMP_FILE} && ' + f'touch -m -t {TIMESTAMP_EPOCH} {TEMP_FILE} && ' + f'cat {TEMP_FILE} ; ' + f'rm {TEMP_FILE} -f' + ] diff --git a/monkey/infection_monkey/post_breach/timestomping/timestomping.py b/monkey/infection_monkey/post_breach/timestomping/timestomping.py new file mode 100644 index 000000000..04ed5cb6d --- /dev/null +++ b/monkey/infection_monkey/post_breach/timestomping/timestomping.py @@ -0,0 +1,10 @@ +from infection_monkey.post_breach.timestomping.linux.timestomping import \ + get_linux_timestomping_commands +from infection_monkey.post_breach.timestomping.windows.timestomping import \ + get_windows_timestomping_commands + + +def get_timestomping_commands(): + linux_cmds = get_linux_timestomping_commands() + windows_cmds = get_windows_timestomping_commands() + return linux_cmds, windows_cmds diff --git a/monkey/infection_monkey/post_breach/timestomping/windows/timestomping.ps1 b/monkey/infection_monkey/post_breach/timestomping/windows/timestomping.ps1 new file mode 100644 index 000000000..8965a149a --- /dev/null +++ b/monkey/infection_monkey/post_breach/timestomping/windows/timestomping.ps1 @@ -0,0 +1,13 @@ +$TEMP_FILE = 'monkey-timestomping-file.txt' +$TIMESTAMP_EPOCH = '01/01/1970 00:00:00' + +# create temporary file +New-Item -Path $TEMP_FILE -Force | Out-Null +Set-Content $TEMP_FILE -Value "Successfully changed a file\'s modification timestamp" -Force | Out-Null + +# attempt to change modification timestamp +Get-ChildItem $TEMP_FILE | % { $_.LastWriteTime = $TIMESTAMP_EPOCH } +Get-Content $TEMP_FILE + +# remove temporary file +Remove-Item $TEMP_FILE -Force -ErrorAction Ignore diff --git a/monkey/infection_monkey/post_breach/timestomping/windows/timestomping.py b/monkey/infection_monkey/post_breach/timestomping/windows/timestomping.py new file mode 100644 index 000000000..c18baabfc --- /dev/null +++ b/monkey/infection_monkey/post_breach/timestomping/windows/timestomping.py @@ -0,0 +1,5 @@ +TEMP_FILE = 'monkey-timestomping-file.txt' + + +def get_windows_timestomping_commands(): + return 'powershell.exe infection_monkey/post_breach/timestomping/windows/timestomping.ps1' diff --git a/monkey/monkey_island/cc/services/attack/attack_report.py b/monkey/monkey_island/cc/services/attack/attack_report.py index 6d4bac9ed..6485fc5b5 100644 --- a/monkey/monkey_island/cc/services/attack/attack_report.py +++ b/monkey/monkey_island/cc/services/attack/attack_report.py @@ -10,15 +10,16 @@ from monkey_island.cc.services.attack.technique_reports import (T1003, T1005, T1059, T1064, T1065, T1075, T1082, T1086, - T1090, T1105, - T1106, T1107, - T1110, T1129, - T1136, T1145, - T1154, T1156, - T1158, T1166, - T1168, T1188, - T1197, T1210, - T1222, T1504) + T1090, T1099, + T1105, T1106, + T1107, T1110, + T1129, T1136, + T1145, T1154, + T1156, T1158, + T1166, T1168, + T1188, T1197, + T1210, T1222, + T1504) from monkey_island.cc.services.reporting.report_generation_synchronisation import \ safe_generate_attack_report @@ -57,7 +58,8 @@ TECHNIQUES = {'T1210': T1210.T1210, 'T1154': T1154.T1154, 'T1166': T1166.T1166, 'T1168': T1168.T1168, - 'T1053': T1053.T1053 + 'T1053': T1053.T1053, + 'T1099': T1099.T1099 } REPORT_NAME = 'new_report' diff --git a/monkey/monkey_island/cc/services/attack/attack_schema.py b/monkey/monkey_island/cc/services/attack/attack_schema.py index 30d33ca3e..ae0dbd2bc 100644 --- a/monkey/monkey_island/cc/services/attack/attack_schema.py +++ b/monkey/monkey_island/cc/services/attack/attack_schema.py @@ -185,6 +185,15 @@ SCHEMA = { "necessary": True, "link": "https://attack.mitre.org/techniques/T1222", "description": "Adversaries may modify file permissions/attributes to evade intended DACLs." + }, + "T1099": { + "title": "Timestomping", + "type": "bool", + "value": True, + "necessary": False, + "link": "https://attack.mitre.org/techniques/T1099", + "description": "Adversaries may modify file time attributes to hide new/changes to existing " + "files to avoid attention from forensic investigators or file analysis tools." } } }, diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1099.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1099.py new file mode 100644 index 000000000..3ca46408d --- /dev/null +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1099.py @@ -0,0 +1,13 @@ +from common.data.post_breach_consts import POST_BREACH_TIMESTOMPPING +from monkey_island.cc.services.attack.technique_reports.pba_technique import \ + PostBreachTechnique + +__author__ = "shreyamalviya" + + +class T1099(PostBreachTechnique): + tech_id = "T1099" + unscanned_msg = "Monkey didn't try changing any file's time attributes." + scanned_msg = "Monkey tried changing a file's time attributes but failed." + used_msg = "Monkey successfully changed a file's time attributes." + pba_names = [POST_BREACH_TIMESTOMPPING] diff --git a/monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py b/monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py index f3e2a9bfa..ab4356850 100644 --- a/monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py +++ b/monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py @@ -70,6 +70,15 @@ POST_BREACH_ACTIONS = { "title": "Job scheduling", "info": "Attempts to create a scheduled job on the system and remove it.", "attack_techniques": ["T1168", "T1053"] + }, + { + "type": "string", + "enum": [ + "Timestomping" + ], + "title": "Timestomping", + "info": "Creates a temporary file and attempts to modify its file time attributes. Removes temporary file.", + "attack_techniques": ["T1099"] } ] } diff --git a/monkey/monkey_island/cc/services/config_schema/monkey.py b/monkey/monkey_island/cc/services/config_schema/monkey.py index dd10cb35b..e58ac7c79 100644 --- a/monkey/monkey_island/cc/services/config_schema/monkey.py +++ b/monkey/monkey_island/cc/services/config_schema/monkey.py @@ -67,7 +67,8 @@ MONKEY = { "HiddenFiles", "TrapCommand", "ChangeSetuidSetgid", - "ScheduleJobs" + "ScheduleJobs", + "Timestomping" ] }, } diff --git a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1099.js b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1099.js new file mode 100644 index 000000000..2c95cdba9 --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1099.js @@ -0,0 +1,45 @@ +import React from 'react'; +import ReactTable from 'react-table'; +import {renderMachineFromSystemData, ScanStatus} from './Helpers'; +import MitigationsComponent from './MitigationsComponent'; + +class T1099 extends React.Component { + + constructor(props) { + super(props); + } + + static getColumns() { + return ([{ + columns: [ + { Header: 'Machine', + id: 'machine', + accessor: x => renderMachineFromSystemData(x.machine), + style: {'whiteSpace': 'unset'}}, + { Header: 'Result', + id: 'result', + accessor: x => x.result, + style: {'whiteSpace': 'unset'}} + ] + }]) + } + + render() { + return ( +