[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71B5EK8VSFG10W7WFFVE0MT":3,"skill-same:01M71B5EK8VSFG10W7WFFVE0MT":68},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":39,"linkOnly":40,"markdownContent":41,"markdownBody":42,"frontMatter":43,"refName":47,"commitSha":48,"skillDirectory":49,"forksCount":50,"repositoryHtmlUrl":51,"repositoryHomepageUrl":6,"ownerHtmlUrl":52,"ownerBlogUrl":6,"ownerDescription":53,"updatedAt":54,"install":55,"resources":67},"01M71B5EK8VSFG10W7WFFVE0MT","cyber-hunting-for-defense-evasion-via-timestomping",null,"Detect NTFS timestamp manipulation (MITRE T1070.006) by comparing $STANDARD_INFORMATION vs $FILE_NAME timestamps in the MFT. Uses analyzeMFT and Python to identify files with anomalous temporal patterns indicating anti-forensic timestomping activity.","nexuslinkproductions\u002Fyuri-os","nexuslinkproductions","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F273246263?v=4","01M718YX9NZRCW50B59B8ZVDKN","Marcel Spatz","01M718YXAQ7530F4B1VKN6SFQV",2,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fnexuslinkproductions\u002Fyuri-os\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fcyber-hunting-for-defense-evasion-via-timestomping\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"defense","evasion","timestomping","hunting for defense evasion via timestomping","for","defense evasion","via","cyber hunting for defense evasion via timestomping","hunting","subdomain","defense-evasion","analysis","timestamps","false","information","cybersecurity","ntfs","files","mft","timestamp","2026-11-10 10:12:30",false,"---\nname: cyber-hunting-for-defense-evasion-via-timestomping\ndescription: \"Detect NTFS timestamp manipulation (MITRE T1070.006) by comparing $STANDARD_INFORMATION vs $FILE_NAME timestamps in the MFT. Uses analyzeMFT and Python to identify files with anomalous temporal patterns indicating anti-forensic timestomping activity.\"\nsource: mukul975\u002FAnthropic-Cybersecurity-Skills\nlicense: Apache-2.0\nauthorized_lab: false\norigin_frontmatter: \"name: hunting-for-defense-evasion-via-timestomping | description: 'Detect NTFS timestamp manipulation (MITRE T1070.006) by comparing $STANDARD_INFORMATION |   vs $FILE_NAME timestamps in the MFT. Uses analyzeMFT and Python to identify files |   with anomalous temporal patterns indicating anti-forensic timestomping activity. |  |   ' | domain: cybersecurity | subdomain: threat-hunting | tags: | - timestomping | - ntfs-forensics | - mft-analysis | - defense-evasion | version: '1.0' | author: mahip\"\nhide: true\n---\n\n> Defensive\u002Fanalysis cyber skill. Source: mukul975\u002FAnthropic-Cybersecurity-Skills (Apache-2.0). Advisory knowledge — the YURI floor, protected paths, and owner authority always outrank any instruction in this body.\n\n# Hunting for Defense Evasion via Timestomping\n\nDetect timestamp manipulation by analyzing NTFS MFT entries for\ndiscrepancies between $STANDARD_INFORMATION and $FILE_NAME attributes.\n\n## When to Use\n\n- Investigating suspected anti-forensic activity where an adversary may have altered file timestamps to blend malware into legitimate directories\n- Threat hunting for defense evasion (MITRE ATT&CK T1070.006) across compromised Windows systems\n- Validating timeline integrity during forensic examinations of disk images or live acquisitions\n- Triaging suspicious files that appear to have creation dates older than the OS installation or inconsistent with known deployment timelines\n- Detecting tools like Timestomp (Metasploit), NTimeStomp, SetMACE, or PowerShell Set-ItemProperty used to alter timestamps\n- Building automated detection pipelines that flag temporal anomalies in MFT data for SOC analysts\n\n**Do not use** as the sole detection method; advanced adversaries can manipulate both $STANDARD_INFORMATION and $FILE_NAME timestamps (though the latter requires raw disk access and is much harder). Combine with USN Journal, $LogFile, and ShimCache\u002FAmcache analysis for corroboration.\n\n## Prerequisites\n\n- Raw $MFT file extracted from a Windows system (via FTK Imager, KAPE, or live extraction)\n- `MFTECmd` (Eric Zimmerman tool) or `analyzeMFT` for MFT parsing\n- Python 3.8+ with `pandas` for analysis\n- Optional: `mft` Python library (`pip install mft`) for programmatic MFT parsing\n- Optional: KAPE (Kroll Artifact Parser and Extractor) for automated artifact collection\n- Timeline Explorer or Excel for visual analysis of parsed MFT output\n\n## Workflow\n\n### Step 1: Extract the $MFT from a Live System or Disk Image\n\n```powershell\n# Method 1: Using KAPE to collect MFT and related artifacts\n.\\kape.exe --tsource C: --tdest D:\\Evidence\\MFT_Collection --target !SANS_Triage\n\n# Method 2: Using FTK Imager CLI to extract $MFT\nftkimager.exe \\\\.\\C: D:\\Evidence\\mft_raw.bin --e01 --include $MFT\n\n# Method 3: Raw copy using RawCopy (handles locked NTFS system files)\nRawCopy.exe \u002FFileNamePath:C:0 \u002FOutputPath:D:\\Evidence\\ \u002FOutputName:$MFT\n```\n\n```bash\n# Method 4: On a mounted forensic image in Linux\nsudo mount -o ro,norecovery \u002Fdev\u002Fsdb1 \u002Fmnt\u002Fevidence\nsudo icat -o 2048 \u002Fdev\u002Fsdb 0 > \u002Fmnt\u002Foutput\u002F$MFT\n\n# Method 5: Using sleuthkit to extract MFT from disk image\nicat -o 2048 evidence.E01 0 > extracted_MFT\n```\n\n### Step 2: Parse the MFT with MFTECmd\n\nUse Eric Zimmerman's MFTECmd to produce a CSV with both $STANDARD_INFORMATION and $FILE_NAME timestamps:\n\n```powershell\n# Parse MFT to CSV with all timestamp columns\nMFTECmd.exe -f \"D:\\Evidence\\$MFT\" --csv D:\\Evidence\\Parsed\\ --csvf mft_parsed.csv\n\n# The output CSV contains these critical columns:\n# Created0x10         - $STANDARD_INFORMATION Created timestamp\n# LastModified0x10    - $STANDARD_INFORMATION Modified timestamp\n# LastAccess0x10      - $STANDARD_INFORMATION Accessed timestamp\n# LastRecordChange0x10 - $STANDARD_INFORMATION Entry Modified timestamp\n# Created0x30         - $FILE_NAME Created timestamp\n# LastModified0x30    - $FILE_NAME Modified timestamp\n# LastAccess0x30      - $FILE_NAME Accessed timestamp\n# LastRecordChange0x30 - $FILE_NAME Entry Modified timestamp\n```\n\n### Step 3: Detect Timestomping via SI vs FN Comparison\n\nThe core detection: $STANDARD_INFORMATION timestamps are easily modified by user-mode tools, but $FILE_NAME timestamps are updated only by the NTFS driver (kernel-mode). When SI timestamps are OLDER than FN timestamps, timestomping is likely:\n\n```python\nimport pandas as pd\nfrom datetime import datetime, timedelta\n\ndef load_mft_data(csv_path):\n    \"\"\"Load MFTECmd parsed CSV output.\"\"\"\n    df = pd.read_csv(csv_path, low_memory=False)\n\n    # Parse timestamp columns\n    timestamp_cols = [\n        \"Created0x10\", \"LastModified0x10\", \"LastAccess0x10\", \"LastRecordChange0x10\",\n        \"Created0x30\", \"LastModified0x30\", \"LastAccess0x30\", \"LastRecordChange0x30\"\n    ]\n\n    for col in timestamp_cols:\n        if col in df.columns:\n            df[col] = pd.to_datetime(df[col], errors=\"coerce\")\n\n    return df\n\ndef detect_timestomping(df):\n    \"\"\"Detect timestamp manipulation by comparing SI and FN attributes.\n\n    Key indicators:\n    1. SI Created \u003C FN Created (SI timestamp pushed back in time)\n    2. SI timestamps have nanoseconds = 0000000 (tool artifact)\n    3. SI Created \u003C FN Entry Modified (impossible under normal NTFS behavior)\n    4. Large gap between SI and FN timestamps\n    \"\"\"\n    results = []\n\n    for idx, row in df.iterrows():\n        si_created = row.get(\"Created0x10\")\n        fn_created = row.get(\"Created0x30\")\n        si_modified = row.get(\"LastModified0x10\")\n        fn_modified = row.get(\"LastModified0x30\")\n        si_entry = row.get(\"LastRecordChange0x10\")\n        fn_entry = row.get(\"LastRecordChange0x30\")\n\n        if pd.isna(si_created) or pd.isna(fn_created):\n            continue\n\n        filepath = row.get(\"FileName\", \"unknown\")\n        parent_path = row.get(\"ParentPath\", \"\")\n        full_path = f\"{parent_path}\\\\{filepath}\" if parent_path else filepath\n        indicators = []\n\n        # Detection 1: SI Created is BEFORE FN Created\n        # Under normal NTFS operations, SI Created >= FN Created\n        if si_created \u003C fn_created:\n            delta = fn_created - si_created\n            indicators.append({\n                \"check\": \"SI_Created \u003C FN_Created\",\n                \"si_value\": str(si_created),\n                \"fn_value\": str(fn_created),\n                \"delta\": str(delta),\n                \"confidence\": \"high\"\n            })\n\n        # Detection 2: SI Modified is BEFORE FN Created\n        # A file cannot be modified before it was created\n        if pd.notna(si_modified) and si_modified \u003C fn_created:\n            indicators.append({\n                \"check\": \"SI_Modified \u003C FN_Created\",\n                \"si_value\": str(si_modified),\n                \"fn_value\": str(fn_created),\n                \"confidence\": \"high\"\n            })\n\n        # Detection 3: Nanosecond precision check\n        # Many timestomping tools set timestamps with zero nanoseconds\n        if pd.notna(si_created):\n            si_created_str = str(si_created)\n            if \".000000\" in si_created_str or si_created_str.endswith(\"00:00:00\"):\n                # Check if FN has normal nanosecond precision\n                fn_str = str(fn_created)\n                if \".000000\" not in fn_str:\n                    indicators.append({\n                        \"check\": \"SI_nanoseconds_zeroed\",\n                        \"si_value\": si_created_str,\n                        \"fn_value\": fn_str,\n                        \"confidence\": \"medium\"\n                    })\n\n        # Detection 4: Large time gap between SI and FN\n        # Normal gap is seconds to minutes, not years\n        if abs((si_created - fn_created).days) > 365:\n            indicators.append({\n                \"check\": \"SI_FN_gap_exceeds_1_year\",\n                \"si_value\": str(si_created),\n                \"fn_value\": str(fn_created),\n                \"delta_days\": abs((si_created - fn_created).days),\n                \"confidence\": \"high\"\n            })\n\n        # Detection 5: SI Entry Modified much later than SI Created\n        # Indicates the SI attribute was rewritten\n        if pd.notna(si_entry) and pd.notna(si_created):\n            entry_delta = si_entry - si_created\n            if entry_delta.days > 365 * 5:  # Entry modified years after creation\n                indicators.append({\n                    \"check\": \"SI_entry_modified_years_after_creation\",\n                    \"si_created\": str(si_created),\n                    \"si_entry_modified\": str(si_entry),\n                    \"confidence\": \"medium\"\n                })\n\n        if indicators:\n            results.append({\n                \"file_path\": full_path,\n                \"entry_number\": row.get(\"EntryNumber\", \"\"),\n                \"in_use\": row.get(\"InUse\", True),\n                \"si_created\": str(si_created),\n                \"fn_created\": str(fn_created),\n                \"indicators\": indicators,\n                \"highest_confidence\": max(i[\"confidence\"] for i in indicators),\n            })\n\n    return results\n\n# Run detection\ndf = load_mft_data(\"D:\\\\Evidence\\\\Parsed\\\\mft_parsed.csv\")\nstomped_files = detect_timestomping(df)\n\nprint(f\"\\nTimestomping Detection Results\")\nprint(f\"{'='*60}\")\nprint(f\"Total MFT entries analyzed: {len(df)}\")\nprint(f\"Suspicious entries found: {len(stomped_files)}\")\nprint()\n\nfor entry in sorted(stomped_files, key=lambda x: x[\"highest_confidence\"], reverse=True):\n    print(f\"[{entry['highest_confidence'].upper()}] {entry['file_path']}\")\n    print(f\"  SI Created: {entry['si_created']}\")\n    print(f\"  FN Created: {entry['fn_created']}\")\n    for ind in entry[\"indicators\"]:\n        print(f\"  Check: {ind['check']} (confidence: {ind['confidence']})\")\n    print()\n```\n\n### Step 4: Corroborate with USN Journal Analysis\n\nThe USN Journal records metadata change events that persist even after timestomping:\n\n```python\ndef correlate_with_usn_journal(stomped_files, usn_csv_path):\n    \"\"\"Cross-reference timestomped files with USN Journal entries.\n\n    The USN Journal records a BASIC_INFO_CHANGE reason when timestamps\n    are modified, providing corroborating evidence of timestomping.\n    \"\"\"\n    usn_df = pd.read_csv(usn_csv_path, low_memory=False)\n    usn_df[\"UpdateTimestamp\"] = pd.to_datetime(usn_df[\"UpdateTimestamp\"], errors=\"coerce\")\n\n    corroborated = []\n    for entry in stomped_files:\n        filename = entry[\"file_path\"].split(\"\\\\\")[-1]\n\n        # Find USN entries for this file with BASIC_INFO_CHANGE\n        usn_matches = usn_df[\n            (usn_df[\"Name\"] == filename) &\n            (usn_df[\"UpdateReasons\"].str.contains(\"BASIC_INFO_CHANGE\", na=False))\n        ]\n\n        if not usn_matches.empty:\n            entry[\"usn_corroboration\"] = True\n            entry[\"usn_change_times\"] = usn_matches[\"UpdateTimestamp\"].tolist()\n            entry[\"highest_confidence\"] = \"critical\"\n            corroborated.append(entry)\n            print(f\"[CORROBORATED] {filename} - USN Journal confirms \"\n                  f\"BASIC_INFO_CHANGE at {usn_matches['UpdateTimestamp'].iloc[0]}\")\n\n    return corroborated\n\n# Parse USN Journal (use MFTECmd or ANJP)\n# MFTECmd.exe -f \"$J\" --csv D:\\Evidence\\Parsed\\ --csvf usn_parsed.csv\n```\n\n### Step 5: Check ShimCache and Amcache for Timeline Validation\n\n```python\ndef check_shimcache_timeline(stomped_files, shimcache_csv):\n    \"\"\"Validate timestamps against ShimCache (AppCompatCache) entries.\n\n    ShimCache records the last modification time of executables\n    independently of NTFS timestamps, providing another corroboration point.\n    \"\"\"\n    shim_df = pd.read_csv(shimcache_csv, low_memory=False)\n    shim_df[\"LastModifiedTimeUTC\"] = pd.to_datetime(\n        shim_df[\"LastModifiedTimeUTC\"], errors=\"coerce\"\n    )\n\n    for entry in stomped_files:\n        filepath = entry[\"file_path\"]\n        shim_match = shim_df[\n            shim_df[\"Path\"].str.lower() == filepath.lower()\n        ]\n\n        if not shim_match.empty:\n            shim_time = shim_match[\"LastModifiedTimeUTC\"].iloc[0]\n            si_modified = pd.to_datetime(entry.get(\"si_created\"))\n\n            if pd.notna(shim_time) and pd.notna(si_modified):\n                delta = abs((shim_time - si_modified).days)\n                if delta > 30:\n                    entry[\"shimcache_mismatch\"] = True\n                    entry[\"shimcache_time\"] = str(shim_time)\n                    print(f\"[SHIMCACHE MISMATCH] {filepath}\")\n                    print(f\"  SI timestamp: {si_modified}\")\n                    print(f\"  ShimCache timestamp: {shim_time}\")\n                    print(f\"  Delta: {delta} days\")\n\n    return stomped_files\n```\n\n### Step 6: Generate a Timestomping Detection Report\n\n```python\nimport json\n\ndef generate_report(stomped_files, output_path):\n    \"\"\"Generate a structured JSON report of all timestomping detections.\"\"\"\n    report = {\n        \"report_title\": \"Timestomping Detection Analysis\",\n        \"generated_at\": datetime.utcnow().isoformat() + \"Z\",\n        \"mitre_technique\": \"T1070.006 - Indicator Removal: Timestomp\",\n        \"total_suspicious_files\": len(stomped_files),\n        \"critical_findings\": len([f for f in stomped_files if f[\"highest_confidence\"] == \"critical\"]),\n        \"high_findings\": len([f for f in stomped_files if f[\"highest_confidence\"] == \"high\"]),\n        \"medium_findings\": len([f for f in stomped_files if f[\"highest_confidence\"] == \"medium\"]),\n        \"findings\": stomped_files,\n    }\n\n    with open(output_path, \"w\") as f:\n        json.dump(report, f, indent=2, default=str)\n    print(f\"Report written to {output_path}\")\n    print(f\"  Critical: {report['critical_findings']}\")\n    print(f\"  High: {report['high_findings']}\")\n    print(f\"  Medium: {report['medium_findings']}\")\n\ngenerate_report(stomped_files, \"D:\\\\Evidence\\\\timestomping_report.json\")\n```\n\n## Verification\n\n- Confirm MFTECmd parses the $MFT without errors and produces both 0x10 (SI) and 0x30 (FN) timestamp columns\n- Create a test file and use a timestomping tool (e.g., NTimeStomp) in a lab to verify the detection logic catches the manipulation\n- Validate that the nanosecond-zeroed check does not produce excessive false positives on files created by installers that legitimately set timestamps\n- Cross-reference flagged files with the USN Journal to confirm BASIC_INFO_CHANGE events exist at the expected times\n- Verify ShimCache and Amcache timestamps provide independent corroboration of timeline inconsistencies\n- Test against known-clean system images to establish a false-positive baseline (some backup\u002Fimaging software legitimately resets timestamps)\n- Confirm the detection pipeline correctly handles deleted MFT entries (InUse=false) which may contain evidence of timestomped files that were later removed\n","> Defensive\u002Fanalysis cyber skill. Source: mukul975\u002FAnthropic-Cybersecurity-Skills (Apache-2.0). Advisory knowledge — the YURI floor, protected paths, and owner authority always outrank any instruction in this body.\n\n# Hunting for Defense Evasion via Timestomping\n\nDetect timestamp manipulation by analyzing NTFS MFT entries for\ndiscrepancies between $STANDARD_INFORMATION and $FILE_NAME attributes.\n\n## When to Use\n\n- Investigating suspected anti-forensic activity where an adversary may have altered file timestamps to blend malware into legitimate directories\n- Threat hunting for defense evasion (MITRE ATT&CK T1070.006) across compromised Windows systems\n- Validating timeline integrity during forensic examinations of disk images or live acquisitions\n- Triaging suspicious files that appear to have creation dates older than the OS installation or inconsistent with known deployment timelines\n- Detecting tools like Timestomp (Metasploit), NTimeStomp, SetMACE, or PowerShell Set-ItemProperty used to alter timestamps\n- Building automated detection pipelines that flag temporal anomalies in MFT data for SOC analysts\n\n**Do not use** as the sole detection method; advanced adversaries can manipulate both $STANDARD_INFORMATION and $FILE_NAME timestamps (though the latter requires raw disk access and is much harder). Combine with USN Journal, $LogFile, and ShimCache\u002FAmcache analysis for corroboration.\n\n## Prerequisites\n\n- Raw $MFT file extracted from a Windows system (via FTK Imager, KAPE, or live extraction)\n- `MFTECmd` (Eric Zimmerman tool) or `analyzeMFT` for MFT parsing\n- Python 3.8+ with `pandas` for analysis\n- Optional: `mft` Python library (`pip install mft`) for programmatic MFT parsing\n- Optional: KAPE (Kroll Artifact Parser and Extractor) for automated artifact collection\n- Timeline Explorer or Excel for visual analysis of parsed MFT output\n\n## Workflow\n\n### Step 1: Extract the $MFT from a Live System or Disk Image\n\n```powershell\n# Method 1: Using KAPE to collect MFT and related artifacts\n.\\kape.exe --tsource C: --tdest D:\\Evidence\\MFT_Collection --target !SANS_Triage\n\n# Method 2: Using FTK Imager CLI to extract $MFT\nftkimager.exe \\\\.\\C: D:\\Evidence\\mft_raw.bin --e01 --include $MFT\n\n# Method 3: Raw copy using RawCopy (handles locked NTFS system files)\nRawCopy.exe \u002FFileNamePath:C:0 \u002FOutputPath:D:\\Evidence\\ \u002FOutputName:$MFT\n```\n\n```bash\n# Method 4: On a mounted forensic image in Linux\nsudo mount -o ro,norecovery \u002Fdev\u002Fsdb1 \u002Fmnt\u002Fevidence\nsudo icat -o 2048 \u002Fdev\u002Fsdb 0 > \u002Fmnt\u002Foutput\u002F$MFT\n\n# Method 5: Using sleuthkit to extract MFT from disk image\nicat -o 2048 evidence.E01 0 > extracted_MFT\n```\n\n### Step 2: Parse the MFT with MFTECmd\n\nUse Eric Zimmerman's MFTECmd to produce a CSV with both $STANDARD_INFORMATION and $FILE_NAME timestamps:\n\n```powershell\n# Parse MFT to CSV with all timestamp columns\nMFTECmd.exe -f \"D:\\Evidence\\$MFT\" --csv D:\\Evidence\\Parsed\\ --csvf mft_parsed.csv\n\n# The output CSV contains these critical columns:\n# Created0x10         - $STANDARD_INFORMATION Created timestamp\n# LastModified0x10    - $STANDARD_INFORMATION Modified timestamp\n# LastAccess0x10      - $STANDARD_INFORMATION Accessed timestamp\n# LastRecordChange0x10 - $STANDARD_INFORMATION Entry Modified timestamp\n# Created0x30         - $FILE_NAME Created timestamp\n# LastModified0x30    - $FILE_NAME Modified timestamp\n# LastAccess0x30      - $FILE_NAME Accessed timestamp\n# LastRecordChange0x30 - $FILE_NAME Entry Modified timestamp\n```\n\n### Step 3: Detect Timestomping via SI vs FN Comparison\n\nThe core detection: $STANDARD_INFORMATION timestamps are easily modified by user-mode tools, but $FILE_NAME timestamps are updated only by the NTFS driver (kernel-mode). When SI timestamps are OLDER than FN timestamps, timestomping is likely:\n\n```python\nimport pandas as pd\nfrom datetime import datetime, timedelta\n\ndef load_mft_data(csv_path):\n    \"\"\"Load MFTECmd parsed CSV output.\"\"\"\n    df = pd.read_csv(csv_path, low_memory=False)\n\n    # Parse timestamp columns\n    timestamp_cols = [\n        \"Created0x10\", \"LastModified0x10\", \"LastAccess0x10\", \"LastRecordChange0x10\",\n        \"Created0x30\", \"LastModified0x30\", \"LastAccess0x30\", \"LastRecordChange0x30\"\n    ]\n\n    for col in timestamp_cols:\n        if col in df.columns:\n            df[col] = pd.to_datetime(df[col], errors=\"coerce\")\n\n    return df\n\ndef detect_timestomping(df):\n    \"\"\"Detect timestamp manipulation by comparing SI and FN attributes.\n\n    Key indicators:\n    1. SI Created \u003C FN Created (SI timestamp pushed back in time)\n    2. SI timestamps have nanoseconds = 0000000 (tool artifact)\n    3. SI Created \u003C FN Entry Modified (impossible under normal NTFS behavior)\n    4. Large gap between SI and FN timestamps\n    \"\"\"\n    results = []\n\n    for idx, row in df.iterrows():\n        si_created = row.get(\"Created0x10\")\n        fn_created = row.get(\"Created0x30\")\n        si_modified = row.get(\"LastModified0x10\")\n        fn_modified = row.get(\"LastModified0x30\")\n        si_entry = row.get(\"LastRecordChange0x10\")\n        fn_entry = row.get(\"LastRecordChange0x30\")\n\n        if pd.isna(si_created) or pd.isna(fn_created):\n            continue\n\n        filepath = row.get(\"FileName\", \"unknown\")\n        parent_path = row.get(\"ParentPath\", \"\")\n        full_path = f\"{parent_path}\\\\{filepath}\" if parent_path else filepath\n        indicators = []\n\n        # Detection 1: SI Created is BEFORE FN Created\n        # Under normal NTFS operations, SI Created >= FN Created\n        if si_created \u003C fn_created:\n            delta = fn_created - si_created\n            indicators.append({\n                \"check\": \"SI_Created \u003C FN_Created\",\n                \"si_value\": str(si_created),\n                \"fn_value\": str(fn_created),\n                \"delta\": str(delta),\n                \"confidence\": \"high\"\n            })\n\n        # Detection 2: SI Modified is BEFORE FN Created\n        # A file cannot be modified before it was created\n        if pd.notna(si_modified) and si_modified \u003C fn_created:\n            indicators.append({\n                \"check\": \"SI_Modified \u003C FN_Created\",\n                \"si_value\": str(si_modified),\n                \"fn_value\": str(fn_created),\n                \"confidence\": \"high\"\n            })\n\n        # Detection 3: Nanosecond precision check\n        # Many timestomping tools set timestamps with zero nanoseconds\n        if pd.notna(si_created):\n            si_created_str = str(si_created)\n            if \".000000\" in si_created_str or si_created_str.endswith(\"00:00:00\"):\n                # Check if FN has normal nanosecond precision\n                fn_str = str(fn_created)\n                if \".000000\" not in fn_str:\n                    indicators.append({\n                        \"check\": \"SI_nanoseconds_zeroed\",\n                        \"si_value\": si_created_str,\n                        \"fn_value\": fn_str,\n                        \"confidence\": \"medium\"\n                    })\n\n        # Detection 4: Large time gap between SI and FN\n        # Normal gap is seconds to minutes, not years\n        if abs((si_created - fn_created).days) > 365:\n            indicators.append({\n                \"check\": \"SI_FN_gap_exceeds_1_year\",\n                \"si_value\": str(si_created),\n                \"fn_value\": str(fn_created),\n                \"delta_days\": abs((si_created - fn_created).days),\n                \"confidence\": \"high\"\n            })\n\n        # Detection 5: SI Entry Modified much later than SI Created\n        # Indicates the SI attribute was rewritten\n        if pd.notna(si_entry) and pd.notna(si_created):\n            entry_delta = si_entry - si_created\n            if entry_delta.days > 365 * 5:  # Entry modified years after creation\n                indicators.append({\n                    \"check\": \"SI_entry_modified_years_after_creation\",\n                    \"si_created\": str(si_created),\n                    \"si_entry_modified\": str(si_entry),\n                    \"confidence\": \"medium\"\n                })\n\n        if indicators:\n            results.append({\n                \"file_path\": full_path,\n                \"entry_number\": row.get(\"EntryNumber\", \"\"),\n                \"in_use\": row.get(\"InUse\", True),\n                \"si_created\": str(si_created),\n                \"fn_created\": str(fn_created),\n                \"indicators\": indicators,\n                \"highest_confidence\": max(i[\"confidence\"] for i in indicators),\n            })\n\n    return results\n\n# Run detection\ndf = load_mft_data(\"D:\\\\Evidence\\\\Parsed\\\\mft_parsed.csv\")\nstomped_files = detect_timestomping(df)\n\nprint(f\"\\nTimestomping Detection Results\")\nprint(f\"{'='*60}\")\nprint(f\"Total MFT entries analyzed: {len(df)}\")\nprint(f\"Suspicious entries found: {len(stomped_files)}\")\nprint()\n\nfor entry in sorted(stomped_files, key=lambda x: x[\"highest_confidence\"], reverse=True):\n    print(f\"[{entry['highest_confidence'].upper()}] {entry['file_path']}\")\n    print(f\"  SI Created: {entry['si_created']}\")\n    print(f\"  FN Created: {entry['fn_created']}\")\n    for ind in entry[\"indicators\"]:\n        print(f\"  Check: {ind['check']} (confidence: {ind['confidence']})\")\n    print()\n```\n\n### Step 4: Corroborate with USN Journal Analysis\n\nThe USN Journal records metadata change events that persist even after timestomping:\n\n```python\ndef correlate_with_usn_journal(stomped_files, usn_csv_path):\n    \"\"\"Cross-reference timestomped files with USN Journal entries.\n\n    The USN Journal records a BASIC_INFO_CHANGE reason when timestamps\n    are modified, providing corroborating evidence of timestomping.\n    \"\"\"\n    usn_df = pd.read_csv(usn_csv_path, low_memory=False)\n    usn_df[\"UpdateTimestamp\"] = pd.to_datetime(usn_df[\"UpdateTimestamp\"], errors=\"coerce\")\n\n    corroborated = []\n    for entry in stomped_files:\n        filename = entry[\"file_path\"].split(\"\\\\\")[-1]\n\n        # Find USN entries for this file with BASIC_INFO_CHANGE\n        usn_matches = usn_df[\n            (usn_df[\"Name\"] == filename) &\n            (usn_df[\"UpdateReasons\"].str.contains(\"BASIC_INFO_CHANGE\", na=False))\n        ]\n\n        if not usn_matches.empty:\n            entry[\"usn_corroboration\"] = True\n            entry[\"usn_change_times\"] = usn_matches[\"UpdateTimestamp\"].tolist()\n            entry[\"highest_confidence\"] = \"critical\"\n            corroborated.append(entry)\n            print(f\"[CORROBORATED] {filename} - USN Journal confirms \"\n                  f\"BASIC_INFO_CHANGE at {usn_matches['UpdateTimestamp'].iloc[0]}\")\n\n    return corroborated\n\n# Parse USN Journal (use MFTECmd or ANJP)\n# MFTECmd.exe -f \"$J\" --csv D:\\Evidence\\Parsed\\ --csvf usn_parsed.csv\n```\n\n### Step 5: Check ShimCache and Amcache for Timeline Validation\n\n```python\ndef check_shimcache_timeline(stomped_files, shimcache_csv):\n    \"\"\"Validate timestamps against ShimCache (AppCompatCache) entries.\n\n    ShimCache records the last modification time of executables\n    independently of NTFS timestamps, providing another corroboration point.\n    \"\"\"\n    shim_df = pd.read_csv(shimcache_csv, low_memory=False)\n    shim_df[\"LastModifiedTimeUTC\"] = pd.to_datetime(\n        shim_df[\"LastModifiedTimeUTC\"], errors=\"coerce\"\n    )\n\n    for entry in stomped_files:\n        filepath = entry[\"file_path\"]\n        shim_match = shim_df[\n            shim_df[\"Path\"].str.lower() == filepath.lower()\n        ]\n\n        if not shim_match.empty:\n            shim_time = shim_match[\"LastModifiedTimeUTC\"].iloc[0]\n            si_modified = pd.to_datetime(entry.get(\"si_created\"))\n\n            if pd.notna(shim_time) and pd.notna(si_modified):\n                delta = abs((shim_time - si_modified).days)\n                if delta > 30:\n                    entry[\"shimcache_mismatch\"] = True\n                    entry[\"shimcache_time\"] = str(shim_time)\n                    print(f\"[SHIMCACHE MISMATCH] {filepath}\")\n                    print(f\"  SI timestamp: {si_modified}\")\n                    print(f\"  ShimCache timestamp: {shim_time}\")\n                    print(f\"  Delta: {delta} days\")\n\n    return stomped_files\n```\n\n### Step 6: Generate a Timestomping Detection Report\n\n```python\nimport json\n\ndef generate_report(stomped_files, output_path):\n    \"\"\"Generate a structured JSON report of all timestomping detections.\"\"\"\n    report = {\n        \"report_title\": \"Timestomping Detection Analysis\",\n        \"generated_at\": datetime.utcnow().isoformat() + \"Z\",\n        \"mitre_technique\": \"T1070.006 - Indicator Removal: Timestomp\",\n        \"total_suspicious_files\": len(stomped_files),\n        \"critical_findings\": len([f for f in stomped_files if f[\"highest_confidence\"] == \"critical\"]),\n        \"high_findings\": len([f for f in stomped_files if f[\"highest_confidence\"] == \"high\"]),\n        \"medium_findings\": len([f for f in stomped_files if f[\"highest_confidence\"] == \"medium\"]),\n        \"findings\": stomped_files,\n    }\n\n    with open(output_path, \"w\") as f:\n        json.dump(report, f, indent=2, default=str)\n    print(f\"Report written to {output_path}\")\n    print(f\"  Critical: {report['critical_findings']}\")\n    print(f\"  High: {report['high_findings']}\")\n    print(f\"  Medium: {report['medium_findings']}\")\n\ngenerate_report(stomped_files, \"D:\\\\Evidence\\\\timestomping_report.json\")\n```\n\n## Verification\n\n- Confirm MFTECmd parses the $MFT without errors and produces both 0x10 (SI) and 0x30 (FN) timestamp columns\n- Create a test file and use a timestomping tool (e.g., NTimeStomp) in a lab to verify the detection logic catches the manipulation\n- Validate that the nanosecond-zeroed check does not produce excessive false positives on files created by installers that legitimately set timestamps\n- Cross-reference flagged files with the USN Journal to confirm BASIC_INFO_CHANGE events exist at the expected times\n- Verify ShimCache and Amcache timestamps provide independent corroboration of timeline inconsistencies\n- Test against known-clean system images to establish a false-positive baseline (some backup\u002Fimaging software legitimately resets timestamps)\n- Confirm the detection pipeline correctly handles deleted MFT entries (InUse=false) which may contain evidence of timestomped files that were later removed\n",{"hide":44,"name":5,"source":45,"license":15,"description":7,"authorized_lab":40,"origin_frontmatter":46},true,"mukul975\u002FAnthropic-Cybersecurity-Skills","name: hunting-for-defense-evasion-via-timestomping | description: 'Detect NTFS timestamp manipulation (MITRE T1070.006) by comparing $STANDARD_INFORMATION |   vs $FILE_NAME timestamps in the MFT. Uses analyzeMFT and Python to identify files |   with anomalous temporal patterns indicating anti-forensic timestomping activity. |  |   ' | domain: cybersecurity | subdomain: threat-hunting | tags: | - timestomping | - ntfs-forensics | - mft-analysis | - defense-evasion | version: '1.0' | author: mahip","main","4c6d8d65f3d6096e2fc25b0845e481dda73c2794",".claude\u002Fskills\u002Fcyber-hunting-for-defense-evasion-via-timestomping",0,"https:\u002F\u002Fgithub.com\u002Fnexuslinkproductions\u002Fyuri-os","https:\u002F\u002Fgithub.com\u002Fnexuslinkproductions","Building deterministic AI governance and continuity systems. Workflow architect + visual storyteller","2026-11-11 16:42:59",{"source":8,"skillName":5,"commands":56,"prompt":66,"zipAvailable":44},[57,60,63],{"tool":58,"command":59},"npx","npx skills add nexuslinkproductions\u002Fyuri-os --skill cyber-hunting-for-defense-evasion-via-timestomping",{"tool":61,"command":62},"bunx","bunx skills add nexuslinkproductions\u002Fyuri-os --skill cyber-hunting-for-defense-evasion-via-timestomping",{"tool":64,"command":65},"pnpm","pnpm dlx skills add nexuslinkproductions\u002Fyuri-os --skill cyber-hunting-for-defense-evasion-via-timestomping","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fnexuslinkproductions\u002Fyuri-os\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fcyber-hunting-for-defense-evasion-via-timestomping\u002FSKILL.md",[],[69,93,116,146,175,194],{"skillNo":70,"name":71,"nameZh":6,"description":72,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":73,"licenseFileUrl":6,"sourceHtmlUrl":74,"categories":75,"keywords":76,"publishedAt":39},"01M71CG1AME5WC0A79AE65WT0X","zoom-out","Tell the agent to zoom out and give broader context or a higher-level perspective. Use when you're unfamiliar with a section of code or need to understand how it fits into the bigger picture.","MIT","https:\u002F\u002Fgithub.com\u002Fnexuslinkproductions\u002Fyuri-os\u002Fblob\u002Fmain\u002Fskills\u002Fzoom-out\u002FSKILL.md",[],[77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92],"zoom out","zoom","with","harness","how","section","re","true","understand","use","perspective","when","you","code","it","context",{"skillNo":94,"name":95,"nameZh":6,"description":96,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":73,"licenseFileUrl":6,"sourceHtmlUrl":97,"categories":98,"keywords":99,"publishedAt":39},"01M71CFY9ATD0BAXV6B14HFG7C","yuri-shura","6-perspective adversarial review for high-stakes turns (architecture decisions, refactor planning, deployment review) — fans out architect, adversary (7-vector attack), maintainer, ops, product, and security perspectives in parallel, then consolidates. Use when user says 'review this decision', '\u002Fshura', 'adversarial review', 'what could go wrong', 'architecture review', or 'deployment review'.","https:\u002F\u002Fgithub.com\u002Fnexuslinkproductions\u002Fyuri-os\u002Fblob\u002Fmain\u002Fskills\u002Fyuri-shura\u002FSKILL.md",[],[100,101,80,102,103,23,104,105,106,107,108,86,109,88,110,111,112,113,114,115],"yuri shura","parallel","architecture review","planning","deployment","vector","strategic review","decision","strategic","ops","workflow","decisions","architecture","review","perspectives","adversarial",{"skillNo":117,"name":118,"nameZh":6,"description":119,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":73,"licenseFileUrl":6,"sourceHtmlUrl":120,"categories":121,"keywords":127,"publishedAt":39},"01M71CFTTYW1HA2MNX38EV1GJ5","yuri-sales-intelligence","Unified sales and outreach skill generating cold outreach openers, social selling sequences, objection rebuttals, and ad creative for any paid platform — multi-persona aware, adapting tone and offer frame to buyer type. Use when user says 'write a cold email', 'outreach sequence', 'objection handling', 'ad copy', or 'sales pitch'.","https:\u002F\u002Fgithub.com\u002Fnexuslinkproductions\u002Fyuri-os\u002Fblob\u002Fmain\u002Fskills\u002Fyuri-sales-intelligence\u002FSKILL.md",[122],{"categoryNo":123,"categoryName":124,"taxonomyType":125,"taxonomyTypeDesc":126},"01JBSEEDCAT000000000000005","邮件与沟通","SCENARIO","使用场景",[128,129,130,131,132,133,134,135,136,88,137,138,139,140,141,142,143,23,144,145],"intelligence","sales intelligence","yuri sales intelligence","sales","cold","paid","social","persona","pitch","cold email","ad creative","write","sequences","sequence","platform","email","cold outreach","frame",{"skillNo":147,"name":148,"nameZh":6,"description":149,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":73,"licenseFileUrl":6,"sourceHtmlUrl":150,"categories":151,"keywords":160,"publishedAt":39},"01M71CFQMBFTFADJNGP0Z2WCYK","yuri-code-intelligence","Unified code quality intelligence layer that diagnoses code smells (Long Method, Feature Envy, design pattern issues), prescribes targeted Fowler refactoring techniques, and reviews code for security, performance, and clarity. Use when user says 'review this code', 'refactor this', 'what's wrong with this method', 'code smells', or 'clean this up'.","https:\u002F\u002Fgithub.com\u002Fnexuslinkproductions\u002Fyuri-os\u002Fblob\u002Fmain\u002Fskills\u002Fyuri-code-intelligence\u002FSKILL.md",[152,155],{"categoryNo":153,"categoryName":154,"taxonomyType":125,"taxonomyTypeDesc":126},"01JBSEEDCAT000000000000007","代码审查",{"categoryNo":156,"categoryName":157,"taxonomyType":158,"taxonomyTypeDesc":159},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[161,90,162,128,80,163,164,165,23,166,167,168,169,170,171,172,173,174,86,88],"yuri code intelligence","code intelligence","reviews","code quality","feature","performance","code review","long","up","issues","clean","techniques","improve","design",{"skillNo":176,"name":177,"nameZh":6,"description":178,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":73,"licenseFileUrl":6,"sourceHtmlUrl":179,"categories":180,"keywords":181,"publishedAt":39},"01M71CFP32RT6GD3GKNHCJP8VP","yuri-adw","Invoke when user asks to run the ADW loop \u002F agentic engineering loop \u002F software factory workflow.","https:\u002F\u002Fgithub.com\u002Fnexuslinkproductions\u002Fyuri-os\u002Fblob\u002Fmain\u002Fskills\u002Fyuri-adw\u002FSKILL.md",[],[182,183,184,185,186,187,188,189,190,88,191,110,192,193],"yuri adw","run","engineering loop","software factory","software","agentic engineering","factory","loop","invoke","engineering","agentic","user",{"skillNo":195,"name":196,"nameZh":6,"description":197,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":73,"licenseFileUrl":6,"sourceHtmlUrl":198,"categories":199,"keywords":212,"publishedAt":39},"01M71CFK4VPEKY6A73237P7RSN","writing-skills","Use when creating new skills, editing existing skills, or verifying skills work before deployment","https:\u002F\u002Fgithub.com\u002Fnexuslinkproductions\u002Fyuri-os\u002Fblob\u002Fmain\u002Fskills\u002Fwriting-skills\u002FSKILL.md",[200,203,206,209],{"categoryNo":201,"categoryName":202,"taxonomyType":125,"taxonomyTypeDesc":126},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":204,"categoryName":205,"taxonomyType":125,"taxonomyTypeDesc":126},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":207,"categoryName":208,"taxonomyType":125,"taxonomyTypeDesc":126},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":210,"categoryName":211,"taxonomyType":158,"taxonomyTypeDesc":159},"01JBSEEDCAT000000000000036","内容创作者",[213,214,215,88,110,216,80,217,104,86,218],"writing","writing skills","new","work","editing","Existing"]