[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71CK05XHTMNJ1GQ9MMYEDXC":3,"skill-same:01M71CK05XHTMNJ1GQ9MMYEDXC":113},{"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":28,"publishedAt":49,"linkOnly":50,"markdownContent":51,"markdownBody":52,"frontMatter":53,"refName":86,"commitSha":87,"skillDirectory":88,"forksCount":14,"repositoryHtmlUrl":89,"repositoryHomepageUrl":6,"ownerHtmlUrl":90,"ownerBlogUrl":6,"ownerDescription":91,"updatedAt":92,"install":93,"resources":106},"01M71CK05XHTMNJ1GQ9MMYEDXC","incident-forensics-analyze",null,"Perform forensic acquisition and analysis of cloud storage services including Google Drive, OneDrive, Dropbox, and Box by collecting both API-based remote data and local sync client artifacts from endpoint devices.","DCx7C5\u002Fai-marketplace","DCx7C5","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F42419559?v=4","01M71C01G2AZV3NTNGWAWSHJPP","DC","01M71C01GQW6G50S2BYMS7PP3E",0,"MIT","https:\u002F\u002Fgithub.com\u002FDCx7C5\u002Fai-marketplace\u002Fblob\u002Fmain\u002Fskills\u002Fcloud\u002Fincident\u002Fforensics\u002Fanalyze\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48],"analyze","incident forensics analyze","forensics","incident","sync","read","storage","axiom","de","acquisition","api","analysis","Bash","aml","cybersecurity","map","remote","Cloud Storage","local","magnet","2026-11-10 10:12:30",false,"---\nname: incident-forensics-analyze\ndescription: Perform forensic acquisition and analysis of cloud storage services including Google Drive, OneDrive, Dropbox, and Box by collecting both API-based remote data and local sync client artifacts from endpoint devices.\ndomain: cybersecurity\nsubdomain: digital-forensics\ntags:\n- cloud-forensics\n- google-drive\n- onedrive\n- dropbox\n- box\n- cloud-acquisition\n- api-forensics\n- sync-client\n- endpoint-artifacts\n- magnet-axiom\nnist_ai_rmf:\n- MEASURE-2.7\n- MAP-5.1\n- MANAGE-2.4\natlas_techniques:\n- AML.T0070\n- AML.T0066\n- AML.T0082\nnist_csf:\n- RS.AN-01\n- RS.AN-03\n- DE.AE-02\n- RS.MA-01\nmodel: sonnet\nmaxTurns: 20\ntools: [Read, Bash, Glob, Grep]\ncapec: []\n---\n\n# Performing Cloud Storage Forensic Acquisition\n\n## Overview\n\nCloud storage forensic acquisition involves collecting digital evidence from services like Google Drive, OneDrive, Dropbox, and Box through both API-based remote acquisition and local endpoint artifact analysis. Modern investigations must address the challenge that cloud-synced files may exist in multiple states: locally synchronized, cloud-only (on-demand), cached, and deleted. Endpoint devices that have synchronized with cloud storage contain a wealth of metadata about locally synced files, files present only in the cloud, and even deleted items recoverable from cache folders. API-based acquisition using service-specific APIs provides direct access to remote data with valid credentials and proper legal authorization.\n\n\n## When to Use\n\n- When conducting security assessments that involve performing cloud storage forensic acquisition\n- When following incident response procedures for related security events\n- When performing scheduled security testing or auditing activities\n- When validating security controls through hands-on testing\n\n## Prerequisites\n\n- Legal authorization (warrant, consent, or corporate policy) for cloud data access\n- Valid user credentials or administrative access tokens\n- Magnet AXIOM Cloud, Cellebrite Cloud Analyzer, or equivalent tool\n- KAPE with cloud storage target files\n- Python 3.8+ with google-api-python-client, msal, dropbox SDK\n- Network connectivity for API-based acquisition\n\n## Acquisition Methods\n\n### Method 1: API-Based Remote Acquisition\n\n#### Google Drive API Acquisition\n\n```python\nfrom google.oauth2.credentials import Credentials\nfrom googleapiclient.discovery import build\nfrom googleapiclient.http import MediaIoBaseDownload\nimport io\nimport os\nimport json\nfrom datetime import datetime\n\n\nclass GoogleDriveForensicAcquisition:\n    \"\"\"Forensically acquire files and metadata from Google Drive via API.\"\"\"\n\n    def __init__(self, credentials_path: str, output_dir: str):\n        self.creds = Credentials.from_authorized_user_file(credentials_path)\n        self.service = build(\"drive\", \"v3\", credentials=self.creds)\n        self.output_dir = output_dir\n        os.makedirs(output_dir, exist_ok=True)\n        self.acquisition_log = []\n\n    def list_all_files(self, include_trashed: bool = True) -> list:\n        \"\"\"List all files including trashed items.\"\"\"\n        files = []\n        page_token = None\n        query = \"\" if include_trashed else \"trashed = false\"\n\n        while True:\n            results = self.service.files().list(\n                q=query,\n                pageSize=1000,\n                fields=\"nextPageToken, files(id, name, mimeType, size, \"\n                       \"createdTime, modifiedTime, trashed, trashedTime, \"\n                       \"owners, sharingUser, permissions, md5Checksum, \"\n                       \"parents, webViewLink, driveId)\",\n                pageToken=page_token\n            ).execute()\n\n            files.extend(results.get(\"files\", []))\n            page_token = results.get(\"nextPageToken\")\n            if not page_token:\n                break\n\n        return files\n\n    def download_file(self, file_id: str, file_name: str, mime_type: str) -> str:\n        \"\"\"Download a file from Google Drive preserving forensic integrity.\"\"\"\n        output_path = os.path.join(self.output_dir, file_name)\n\n        if mime_type.startswith(\"application\u002Fvnd.google-apps\"):\n            export_formats = {\n                \"application\u002Fvnd.google-apps.document\": \"application\u002Fpdf\",\n                \"application\u002Fvnd.google-apps.spreadsheet\": \"application\u002Fvnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n                \"application\u002Fvnd.google-apps.presentation\": \"application\u002Fpdf\",\n            }\n            export_mime = export_formats.get(mime_type, \"application\u002Fpdf\")\n            request = self.service.files().export_media(fileId=file_id, mimeType=export_mime)\n        else:\n            request = self.service.files().get_media(fileId=file_id)\n\n        with io.FileIO(output_path, \"wb\") as fh:\n            downloader = MediaIoBaseDownload(fh, request)\n            done = False\n            while not done:\n                _, done = downloader.next_chunk()\n\n        self.acquisition_log.append({\n            \"timestamp\": datetime.utcnow().isoformat(),\n            \"file_id\": file_id,\n            \"file_name\": file_name,\n            \"output_path\": output_path,\n            \"action\": \"downloaded\"\n        })\n        return output_path\n\n    def get_activity_log(self, file_id: str) -> list:\n        \"\"\"Retrieve activity\u002Frevision history for a specific file.\"\"\"\n        revisions = self.service.revisions().list(\n            fileId=file_id,\n            fields=\"revisions(id, modifiedTime, lastModifyingUser, size, md5Checksum)\"\n        ).execute()\n        return revisions.get(\"revisions\", [])\n\n    def export_acquisition_report(self) -> str:\n        \"\"\"Export acquisition log for chain of custody documentation.\"\"\"\n        report_path = os.path.join(self.output_dir, \"acquisition_log.json\")\n        with open(report_path, \"w\") as f:\n            json.dump({\n                \"acquisition_start\": self.acquisition_log[0][\"timestamp\"] if self.acquisition_log else None,\n                \"acquisition_end\": datetime.utcnow().isoformat(),\n                \"total_files\": len(self.acquisition_log),\n                \"entries\": self.acquisition_log\n            }, f, indent=2)\n        return report_path\n```\n\n#### OneDrive \u002F Microsoft 365 API Acquisition\n\n```python\nimport msal\nimport requests\nimport os\nimport json\nfrom datetime import datetime\n\n\nclass OneDriveForensicAcquisition:\n    \"\"\"Forensically acquire files and metadata from OneDrive via Microsoft Graph API.\"\"\"\n\n    def __init__(self, client_id: str, tenant_id: str, client_secret: str, output_dir: str):\n        self.output_dir = output_dir\n        os.makedirs(output_dir, exist_ok=True)\n\n        authority = f\"https:\u002F\u002Flogin.microsoftonline.com\u002F{tenant_id}\"\n        self.app = msal.ConfidentialClientApplication(\n            client_id, authority=authority, client_credential=client_secret\n        )\n        token_result = self.app.acquire_token_for_client(\n            scopes=[\"https:\u002F\u002Fgraph.microsoft.com\u002F.default\"]\n        )\n        self.access_token = token_result.get(\"access_token\")\n        self.headers = {\"Authorization\": f\"Bearer {self.access_token}\"}\n        self.base_url = \"https:\u002F\u002Fgraph.microsoft.com\u002Fv1.0\"\n\n    def list_user_files(self, user_id: str) -> list:\n        \"\"\"List all files in user's OneDrive.\"\"\"\n        url = f\"{self.base_url}\u002Fusers\u002F{user_id}\u002Fdrive\u002Froot\u002Fchildren\"\n        files = []\n        while url:\n            response = requests.get(url, headers=self.headers)\n            data = response.json()\n            files.extend(data.get(\"value\", []))\n            url = data.get(\"@odata.nextLink\")\n        return files\n\n    def download_file(self, user_id: str, item_id: str, filename: str) -> str:\n        \"\"\"Download a file from OneDrive.\"\"\"\n        url = f\"{self.base_url}\u002Fusers\u002F{user_id}\u002Fdrive\u002Fitems\u002F{item_id}\u002Fcontent\"\n        response = requests.get(url, headers=self.headers, stream=True)\n        output_path = os.path.join(self.output_dir, filename)\n        with open(output_path, \"wb\") as f:\n            for chunk in response.iter_content(chunk_size=8192):\n                f.write(chunk)\n        return output_path\n\n    def get_deleted_items(self, user_id: str) -> list:\n        \"\"\"Retrieve items from OneDrive recycle bin.\"\"\"\n        url = f\"{self.base_url}\u002Fusers\u002F{user_id}\u002Fdrive\u002Fspecial\u002Frecyclebin\u002Fchildren\"\n        response = requests.get(url, headers=self.headers)\n        return response.json().get(\"value\", [])\n```\n\n### Method 2: Local Endpoint Artifact Collection\n\n#### KAPE Targets for Cloud Storage\n\n```powershell\n# Collect all cloud storage artifacts using KAPE\nkape.exe --tsource C: --tdest C:\\Output\\CloudArtifacts --target GoogleDrive,OneDrive,Dropbox,Box\n\n# OneDrive artifacts\n# %USERPROFILE%\\AppData\\Local\\Microsoft\\OneDrive\\logs\\\n# %USERPROFILE%\\AppData\\Local\\Microsoft\\OneDrive\\settings\\\n# %USERPROFILE%\\OneDrive\\\n\n# Google Drive artifacts\n# %USERPROFILE%\\AppData\\Local\\Google\\DriveFS\\\n# Contains metadata SQLite databases and cached files\n\n# Dropbox artifacts\n# %USERPROFILE%\\AppData\\Local\\Dropbox\\\n# %USERPROFILE%\\Dropbox\\.dropbox.cache\\\n# Contains filecache.dbx (encrypted SQLite), host.dbx, config.dbx\n```\n\n#### OneDrive Local Database Analysis\n\n```python\nimport sqlite3\nimport os\n\ndef analyze_onedrive_sync_engine(db_path: str) -> list:\n    \"\"\"Analyze OneDrive SyncEngineDatabase for file metadata.\"\"\"\n    conn = sqlite3.connect(db_path)\n    cursor = conn.cursor()\n\n    # Query for all tracked files including cloud-only items\n    cursor.execute(\"\"\"\n        SELECT fileName, fileSize, lastChange,\n               resourceID, parentResourceID, eTag\n        FROM od_ClientFile_Records\n        ORDER BY lastChange DESC\n    \"\"\")\n\n    files = []\n    for row in cursor.fetchall():\n        files.append({\n            \"filename\": row[0],\n            \"size\": row[1],\n            \"last_change\": row[2],\n            \"resource_id\": row[3],\n            \"parent_id\": row[4],\n            \"etag\": row[5]\n        })\n\n    conn.close()\n    return files\n```\n\n## Cloud Storage Artifacts Summary\n\n| Service | Local Database | Cache Location | Log Files |\n|---------|---------------|----------------|-----------|\n| OneDrive | SyncEngineDatabase.db | %LOCALAPPDATA%\\Microsoft\\OneDrive\\cache\\ | %LOCALAPPDATA%\\Microsoft\\OneDrive\\logs\\ |\n| Google Drive | metadata_sqlite_db | %LOCALAPPDATA%\\Google\\DriveFS\\{account}\\content_cache\\ | %LOCALAPPDATA%\\Google\\DriveFS\\Logs\\ |\n| Dropbox | filecache.dbx (encrypted) | %APPDATA%\\Dropbox\\.dropbox.cache\\ | %APPDATA%\\Dropbox\\logs\\ |\n| Box | sync_db | %LOCALAPPDATA%\\Box\\Box\\cache\\ | %LOCALAPPDATA%\\Box\\Box\\logs\\ |\n\n## References\n\n- SANS Cloud Storage Acquisition: https:\u002F\u002Fwww.sans.org\u002Fblog\u002Fcloud-storage-acquisition-from-endpoint-devices\n- Magnet AXIOM Cloud: https:\u002F\u002Fwww.magnetforensics.com\u002Fblog\u002Fhow-to-acquire-and-analyze-cloud-data-with-magnet-axiom\u002F\n- AWS Cloud Forensics Framework: https:\u002F\u002Fdocs.aws.amazon.com\u002Fprescriptive-guidance\u002Flatest\u002Fsecurity-reference-architecture\u002Fcyber-forensics.html\n- API-Based Forensic Acquisition of Cloud Drives: https:\u002F\u002Farxiv.org\u002Fabs\u002F1603.06542\n\n## Example Output\n\n```text\n$ python3 cloud_forensic_acquire.py --provider google-drive --auth \u002Ftokens\u002Fgdrive_token.json \\\n    --user jsmith@corporate.com --output \u002Facquisition\u002Fgdrive\n\nCloud Storage Forensic Acquisition Tool v3.2\n==============================================\nProvider:    Google Drive\nAccount:     jsmith@corporate.com\nStart Time:  2024-01-19 08:00:15 UTC\nAuth Method: Admin SDK (domain-wide delegation)\n\n[+] Enumerating files...\n    Total files:        2,345\n    Total folders:      178\n    Shared with me:     456\n    Trashed items:      89 (included in acquisition)\n    Total size:         14.7 GB\n\n[+] Acquiring file contents...\n    Downloaded:    2,345 \u002F 2,345  [████████████████████████████████] 100%\n    Errors:        0\n    Elapsed:       18m 32s\n\n[+] Acquiring metadata...\n    File metadata:      2,345 entries\n    Revision history:   8,912 revisions across 1,234 files\n    Sharing permissions: 3,456 permission entries\n    Activity log:       12,345 events\n\n[+] Acquiring trashed items...\n    Recovered:     89 \u002F 89 items (234 MB)\n\n--- Acquisition Log ---\nTimestamp (UTC)          | Action           | File                                    | Size    | SHA-256\n2024-01-19 08:00:45      | Downloaded       | \u002FMy Drive\u002FFinance\u002FQ4_Report.xlsm        | 245 KB  | 7a3b8c9d...\n2024-01-19 08:00:46      | Downloaded       | \u002FMy Drive\u002FFinance\u002FBudget_2024.xlsx       | 1.2 MB  | 8b4c9d0e...\n...\n2024-01-19 08:02:12      | Trash-Recovered  | \u002FTrash\u002Femployee_list_full.csv            | 4.5 MB  | 9c5d0e1f...\n2024-01-19 08:02:13      | Trash-Recovered  | \u002FTrash\u002Fnetwork_diagram_v3.vsdx          | 2.1 MB  | 0d6e1f2a...\n2024-01-19 08:02:14      | Trash-Recovered  | \u002FTrash\u002Fcredentials_backup.kdbx          | 128 KB  | 1e7f2a3b...\n\n--- Sharing Analysis ---\nFiles Shared Externally:\n  \u002FMy Drive\u002FFinance\u002FQ4_Report.xlsm     → j.smith.personal8842@protonmail.com (2024-01-16 03:10 UTC)\n  \u002FMy Drive\u002FHR\u002Femployee_list_full.csv   → j.smith.personal8842@protonmail.com (2024-01-16 03:12 UTC)\n  \u002FMy Drive\u002FIT\u002Fnetwork_diagram_v3.vsdx  → anonymous (link sharing, 2024-01-16 03:15 UTC)\n\n--- Revision History (Suspicious) ---\nFile: \u002FMy Drive\u002FFinance\u002FQ4_Report.xlsm\n  Rev 1:  2024-01-10 09:00:00 UTC  (245 KB)  - Original\n  Rev 2:  2024-01-15 14:35:00 UTC  (248 KB)  - Modified (macro added)\n  Rev 3:  2024-01-16 03:05:00 UTC  (245 KB)  - Reverted (macro removed - anti-forensics)\n\nAcquisition Summary:\n  Files acquired:       2,345 (14.7 GB)\n  Trashed items:        89 (234 MB)\n  Revisions:            8,912\n  Chain of custody hash (full archive):\n    SHA-256: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2\n  Output directory:     \u002Facquisition\u002Fgdrive\u002F\n  Acquisition log:      \u002Facquisition\u002Fgdrive\u002Facquisition_log.csv\n  Completion Time:      2024-01-19 08:18:47 UTC\n```\n","# Performing Cloud Storage Forensic Acquisition\n\n## Overview\n\nCloud storage forensic acquisition involves collecting digital evidence from services like Google Drive, OneDrive, Dropbox, and Box through both API-based remote acquisition and local endpoint artifact analysis. Modern investigations must address the challenge that cloud-synced files may exist in multiple states: locally synchronized, cloud-only (on-demand), cached, and deleted. Endpoint devices that have synchronized with cloud storage contain a wealth of metadata about locally synced files, files present only in the cloud, and even deleted items recoverable from cache folders. API-based acquisition using service-specific APIs provides direct access to remote data with valid credentials and proper legal authorization.\n\n\n## When to Use\n\n- When conducting security assessments that involve performing cloud storage forensic acquisition\n- When following incident response procedures for related security events\n- When performing scheduled security testing or auditing activities\n- When validating security controls through hands-on testing\n\n## Prerequisites\n\n- Legal authorization (warrant, consent, or corporate policy) for cloud data access\n- Valid user credentials or administrative access tokens\n- Magnet AXIOM Cloud, Cellebrite Cloud Analyzer, or equivalent tool\n- KAPE with cloud storage target files\n- Python 3.8+ with google-api-python-client, msal, dropbox SDK\n- Network connectivity for API-based acquisition\n\n## Acquisition Methods\n\n### Method 1: API-Based Remote Acquisition\n\n#### Google Drive API Acquisition\n\n```python\nfrom google.oauth2.credentials import Credentials\nfrom googleapiclient.discovery import build\nfrom googleapiclient.http import MediaIoBaseDownload\nimport io\nimport os\nimport json\nfrom datetime import datetime\n\n\nclass GoogleDriveForensicAcquisition:\n    \"\"\"Forensically acquire files and metadata from Google Drive via API.\"\"\"\n\n    def __init__(self, credentials_path: str, output_dir: str):\n        self.creds = Credentials.from_authorized_user_file(credentials_path)\n        self.service = build(\"drive\", \"v3\", credentials=self.creds)\n        self.output_dir = output_dir\n        os.makedirs(output_dir, exist_ok=True)\n        self.acquisition_log = []\n\n    def list_all_files(self, include_trashed: bool = True) -> list:\n        \"\"\"List all files including trashed items.\"\"\"\n        files = []\n        page_token = None\n        query = \"\" if include_trashed else \"trashed = false\"\n\n        while True:\n            results = self.service.files().list(\n                q=query,\n                pageSize=1000,\n                fields=\"nextPageToken, files(id, name, mimeType, size, \"\n                       \"createdTime, modifiedTime, trashed, trashedTime, \"\n                       \"owners, sharingUser, permissions, md5Checksum, \"\n                       \"parents, webViewLink, driveId)\",\n                pageToken=page_token\n            ).execute()\n\n            files.extend(results.get(\"files\", []))\n            page_token = results.get(\"nextPageToken\")\n            if not page_token:\n                break\n\n        return files\n\n    def download_file(self, file_id: str, file_name: str, mime_type: str) -> str:\n        \"\"\"Download a file from Google Drive preserving forensic integrity.\"\"\"\n        output_path = os.path.join(self.output_dir, file_name)\n\n        if mime_type.startswith(\"application\u002Fvnd.google-apps\"):\n            export_formats = {\n                \"application\u002Fvnd.google-apps.document\": \"application\u002Fpdf\",\n                \"application\u002Fvnd.google-apps.spreadsheet\": \"application\u002Fvnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n                \"application\u002Fvnd.google-apps.presentation\": \"application\u002Fpdf\",\n            }\n            export_mime = export_formats.get(mime_type, \"application\u002Fpdf\")\n            request = self.service.files().export_media(fileId=file_id, mimeType=export_mime)\n        else:\n            request = self.service.files().get_media(fileId=file_id)\n\n        with io.FileIO(output_path, \"wb\") as fh:\n            downloader = MediaIoBaseDownload(fh, request)\n            done = False\n            while not done:\n                _, done = downloader.next_chunk()\n\n        self.acquisition_log.append({\n            \"timestamp\": datetime.utcnow().isoformat(),\n            \"file_id\": file_id,\n            \"file_name\": file_name,\n            \"output_path\": output_path,\n            \"action\": \"downloaded\"\n        })\n        return output_path\n\n    def get_activity_log(self, file_id: str) -> list:\n        \"\"\"Retrieve activity\u002Frevision history for a specific file.\"\"\"\n        revisions = self.service.revisions().list(\n            fileId=file_id,\n            fields=\"revisions(id, modifiedTime, lastModifyingUser, size, md5Checksum)\"\n        ).execute()\n        return revisions.get(\"revisions\", [])\n\n    def export_acquisition_report(self) -> str:\n        \"\"\"Export acquisition log for chain of custody documentation.\"\"\"\n        report_path = os.path.join(self.output_dir, \"acquisition_log.json\")\n        with open(report_path, \"w\") as f:\n            json.dump({\n                \"acquisition_start\": self.acquisition_log[0][\"timestamp\"] if self.acquisition_log else None,\n                \"acquisition_end\": datetime.utcnow().isoformat(),\n                \"total_files\": len(self.acquisition_log),\n                \"entries\": self.acquisition_log\n            }, f, indent=2)\n        return report_path\n```\n\n#### OneDrive \u002F Microsoft 365 API Acquisition\n\n```python\nimport msal\nimport requests\nimport os\nimport json\nfrom datetime import datetime\n\n\nclass OneDriveForensicAcquisition:\n    \"\"\"Forensically acquire files and metadata from OneDrive via Microsoft Graph API.\"\"\"\n\n    def __init__(self, client_id: str, tenant_id: str, client_secret: str, output_dir: str):\n        self.output_dir = output_dir\n        os.makedirs(output_dir, exist_ok=True)\n\n        authority = f\"https:\u002F\u002Flogin.microsoftonline.com\u002F{tenant_id}\"\n        self.app = msal.ConfidentialClientApplication(\n            client_id, authority=authority, client_credential=client_secret\n        )\n        token_result = self.app.acquire_token_for_client(\n            scopes=[\"https:\u002F\u002Fgraph.microsoft.com\u002F.default\"]\n        )\n        self.access_token = token_result.get(\"access_token\")\n        self.headers = {\"Authorization\": f\"Bearer {self.access_token}\"}\n        self.base_url = \"https:\u002F\u002Fgraph.microsoft.com\u002Fv1.0\"\n\n    def list_user_files(self, user_id: str) -> list:\n        \"\"\"List all files in user's OneDrive.\"\"\"\n        url = f\"{self.base_url}\u002Fusers\u002F{user_id}\u002Fdrive\u002Froot\u002Fchildren\"\n        files = []\n        while url:\n            response = requests.get(url, headers=self.headers)\n            data = response.json()\n            files.extend(data.get(\"value\", []))\n            url = data.get(\"@odata.nextLink\")\n        return files\n\n    def download_file(self, user_id: str, item_id: str, filename: str) -> str:\n        \"\"\"Download a file from OneDrive.\"\"\"\n        url = f\"{self.base_url}\u002Fusers\u002F{user_id}\u002Fdrive\u002Fitems\u002F{item_id}\u002Fcontent\"\n        response = requests.get(url, headers=self.headers, stream=True)\n        output_path = os.path.join(self.output_dir, filename)\n        with open(output_path, \"wb\") as f:\n            for chunk in response.iter_content(chunk_size=8192):\n                f.write(chunk)\n        return output_path\n\n    def get_deleted_items(self, user_id: str) -> list:\n        \"\"\"Retrieve items from OneDrive recycle bin.\"\"\"\n        url = f\"{self.base_url}\u002Fusers\u002F{user_id}\u002Fdrive\u002Fspecial\u002Frecyclebin\u002Fchildren\"\n        response = requests.get(url, headers=self.headers)\n        return response.json().get(\"value\", [])\n```\n\n### Method 2: Local Endpoint Artifact Collection\n\n#### KAPE Targets for Cloud Storage\n\n```powershell\n# Collect all cloud storage artifacts using KAPE\nkape.exe --tsource C: --tdest C:\\Output\\CloudArtifacts --target GoogleDrive,OneDrive,Dropbox,Box\n\n# OneDrive artifacts\n# %USERPROFILE%\\AppData\\Local\\Microsoft\\OneDrive\\logs\\\n# %USERPROFILE%\\AppData\\Local\\Microsoft\\OneDrive\\settings\\\n# %USERPROFILE%\\OneDrive\\\n\n# Google Drive artifacts\n# %USERPROFILE%\\AppData\\Local\\Google\\DriveFS\\\n# Contains metadata SQLite databases and cached files\n\n# Dropbox artifacts\n# %USERPROFILE%\\AppData\\Local\\Dropbox\\\n# %USERPROFILE%\\Dropbox\\.dropbox.cache\\\n# Contains filecache.dbx (encrypted SQLite), host.dbx, config.dbx\n```\n\n#### OneDrive Local Database Analysis\n\n```python\nimport sqlite3\nimport os\n\ndef analyze_onedrive_sync_engine(db_path: str) -> list:\n    \"\"\"Analyze OneDrive SyncEngineDatabase for file metadata.\"\"\"\n    conn = sqlite3.connect(db_path)\n    cursor = conn.cursor()\n\n    # Query for all tracked files including cloud-only items\n    cursor.execute(\"\"\"\n        SELECT fileName, fileSize, lastChange,\n               resourceID, parentResourceID, eTag\n        FROM od_ClientFile_Records\n        ORDER BY lastChange DESC\n    \"\"\")\n\n    files = []\n    for row in cursor.fetchall():\n        files.append({\n            \"filename\": row[0],\n            \"size\": row[1],\n            \"last_change\": row[2],\n            \"resource_id\": row[3],\n            \"parent_id\": row[4],\n            \"etag\": row[5]\n        })\n\n    conn.close()\n    return files\n```\n\n## Cloud Storage Artifacts Summary\n\n| Service | Local Database | Cache Location | Log Files |\n|---------|---------------|----------------|-----------|\n| OneDrive | SyncEngineDatabase.db | %LOCALAPPDATA%\\Microsoft\\OneDrive\\cache\\ | %LOCALAPPDATA%\\Microsoft\\OneDrive\\logs\\ |\n| Google Drive | metadata_sqlite_db | %LOCALAPPDATA%\\Google\\DriveFS\\{account}\\content_cache\\ | %LOCALAPPDATA%\\Google\\DriveFS\\Logs\\ |\n| Dropbox | filecache.dbx (encrypted) | %APPDATA%\\Dropbox\\.dropbox.cache\\ | %APPDATA%\\Dropbox\\logs\\ |\n| Box | sync_db | %LOCALAPPDATA%\\Box\\Box\\cache\\ | %LOCALAPPDATA%\\Box\\Box\\logs\\ |\n\n## References\n\n- SANS Cloud Storage Acquisition: https:\u002F\u002Fwww.sans.org\u002Fblog\u002Fcloud-storage-acquisition-from-endpoint-devices\n- Magnet AXIOM Cloud: https:\u002F\u002Fwww.magnetforensics.com\u002Fblog\u002Fhow-to-acquire-and-analyze-cloud-data-with-magnet-axiom\u002F\n- AWS Cloud Forensics Framework: https:\u002F\u002Fdocs.aws.amazon.com\u002Fprescriptive-guidance\u002Flatest\u002Fsecurity-reference-architecture\u002Fcyber-forensics.html\n- API-Based Forensic Acquisition of Cloud Drives: https:\u002F\u002Farxiv.org\u002Fabs\u002F1603.06542\n\n## Example Output\n\n```text\n$ python3 cloud_forensic_acquire.py --provider google-drive --auth \u002Ftokens\u002Fgdrive_token.json \\\n    --user jsmith@corporate.com --output \u002Facquisition\u002Fgdrive\n\nCloud Storage Forensic Acquisition Tool v3.2\n==============================================\nProvider:    Google Drive\nAccount:     jsmith@corporate.com\nStart Time:  2024-01-19 08:00:15 UTC\nAuth Method: Admin SDK (domain-wide delegation)\n\n[+] Enumerating files...\n    Total files:        2,345\n    Total folders:      178\n    Shared with me:     456\n    Trashed items:      89 (included in acquisition)\n    Total size:         14.7 GB\n\n[+] Acquiring file contents...\n    Downloaded:    2,345 \u002F 2,345  [████████████████████████████████] 100%\n    Errors:        0\n    Elapsed:       18m 32s\n\n[+] Acquiring metadata...\n    File metadata:      2,345 entries\n    Revision history:   8,912 revisions across 1,234 files\n    Sharing permissions: 3,456 permission entries\n    Activity log:       12,345 events\n\n[+] Acquiring trashed items...\n    Recovered:     89 \u002F 89 items (234 MB)\n\n--- Acquisition Log ---\nTimestamp (UTC)          | Action           | File                                    | Size    | SHA-256\n2024-01-19 08:00:45      | Downloaded       | \u002FMy Drive\u002FFinance\u002FQ4_Report.xlsm        | 245 KB  | 7a3b8c9d...\n2024-01-19 08:00:46      | Downloaded       | \u002FMy Drive\u002FFinance\u002FBudget_2024.xlsx       | 1.2 MB  | 8b4c9d0e...\n...\n2024-01-19 08:02:12      | Trash-Recovered  | \u002FTrash\u002Femployee_list_full.csv            | 4.5 MB  | 9c5d0e1f...\n2024-01-19 08:02:13      | Trash-Recovered  | \u002FTrash\u002Fnetwork_diagram_v3.vsdx          | 2.1 MB  | 0d6e1f2a...\n2024-01-19 08:02:14      | Trash-Recovered  | \u002FTrash\u002Fcredentials_backup.kdbx          | 128 KB  | 1e7f2a3b...\n\n--- Sharing Analysis ---\nFiles Shared Externally:\n  \u002FMy Drive\u002FFinance\u002FQ4_Report.xlsm     → j.smith.personal8842@protonmail.com (2024-01-16 03:10 UTC)\n  \u002FMy Drive\u002FHR\u002Femployee_list_full.csv   → j.smith.personal8842@protonmail.com (2024-01-16 03:12 UTC)\n  \u002FMy Drive\u002FIT\u002Fnetwork_diagram_v3.vsdx  → anonymous (link sharing, 2024-01-16 03:15 UTC)\n\n--- Revision History (Suspicious) ---\nFile: \u002FMy Drive\u002FFinance\u002FQ4_Report.xlsm\n  Rev 1:  2024-01-10 09:00:00 UTC  (245 KB)  - Original\n  Rev 2:  2024-01-15 14:35:00 UTC  (248 KB)  - Modified (macro added)\n  Rev 3:  2024-01-16 03:05:00 UTC  (245 KB)  - Reverted (macro removed - anti-forensics)\n\nAcquisition Summary:\n  Files acquired:       2,345 (14.7 GB)\n  Trashed items:        89 (234 MB)\n  Revisions:            8,912\n  Chain of custody hash (full archive):\n    SHA-256: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2\n  Output directory:     \u002Facquisition\u002Fgdrive\u002F\n  Acquisition log:      \u002Facquisition\u002Fgdrive\u002Facquisition_log.csv\n  Completion Time:      2024-01-19 08:18:47 UTC\n```\n",{"name":5,"tags":54,"capec":65,"model":66,"tools":67,"domain":43,"maxTurns":71,"nist_csf":72,"subdomain":77,"description":7,"nist_ai_rmf":78,"atlas_techniques":82},[55,56,57,58,59,60,61,62,63,64],"cloud-forensics","google-drive","onedrive","dropbox","box","cloud-acquisition","api-forensics","sync-client","endpoint-artifacts","magnet-axiom",[],"sonnet",[68,41,69,70],"Read","Glob","Grep",20,[73,74,75,76],"RS.AN-01","RS.AN-03","DE.AE-02","RS.MA-01","digital-forensics",[79,80,81],"MEASURE-2.7","MAP-5.1","MANAGE-2.4",[83,84,85],"AML.T0070","AML.T0066","AML.T0082","main","a91f1293287ffa9f4f1b8f486cd6e835a1568c84","skills\u002Fcloud\u002Fincident\u002Fforensics\u002Fanalyze","https:\u002F\u002Fgithub.com\u002FDCx7C5\u002Fai-marketplace","https:\u002F\u002Fgithub.com\u002FDCx7C5","#Python","2026-09-01 11:21:00",{"source":8,"skillName":5,"commands":94,"prompt":104,"zipAvailable":105},[95,98,101],{"tool":96,"command":97},"npx","npx skills add DCx7C5\u002Fai-marketplace --skill incident-forensics-analyze",{"tool":99,"command":100},"bunx","bunx skills add DCx7C5\u002Fai-marketplace --skill incident-forensics-analyze",{"tool":102,"command":103},"pnpm","pnpm dlx skills add DCx7C5\u002Fai-marketplace --skill incident-forensics-analyze","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FDCx7C5\u002Fai-marketplace\u002Fblob\u002Fmain\u002Fskills\u002Fcloud\u002Fincident\u002Fforensics\u002Fanalyze\u002FSKILL.md",true,[107],{"path":108,"resourceType":109,"resourceTypeDesc":110,"sizeBytes":111,"sourceHtmlUrl":112},"index.json","REFERENCE","参考文档",689,"https:\u002F\u002Fgithub.com\u002FDCx7C5\u002Fai-marketplace\u002Fblob\u002Fmain\u002Fskills\u002Fcloud\u002Fincident\u002Fforensics\u002Fanalyze\u002Findex.json",[114,137,156,175,197,212],{"skillNo":115,"name":116,"nameZh":6,"description":117,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":118,"categories":119,"keywords":120,"publishedAt":49},"01M71HAPZ01KQ30RKTB0FFSQ05","services-wmi-persistence-detect","Detect WMI event subscription persistence by enumerating ActiveScriptEventConsumer, CommandLineEventConsumer, and permanent subscriptions in the WMI repository.","https:\u002F\u002Fgithub.com\u002FDCx7C5\u002Fai-marketplace\u002Fblob\u002Fmain\u002Fskills\u002Fwindows\u002Fservices\u002Fwmi\u002Fpersistence\u002Fdetect\u002FSKILL.md",[],[121,122,123,124,125,37,126,127,128,129,130,131,132,133,134,135,31,43,136],"services","detect","services wmi persistence detect","wmi","persistence","cm","process","activescript","event","subscriptions","commandline-consumer","repository","subscription","event-subscription","t1546.003","process-forensics",{"skillNo":138,"name":139,"nameZh":6,"description":140,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":141,"categories":142,"keywords":143,"publishedAt":49},"01M71HAK6JTTTS229T17WJMMCG","services-wmi-exec-exploit","Perform lateral movement across Windows networks using WMI-based remote execution techniques including Impacket wmiexec.py, CrackMapExec, and native WMI commands for stealthy post-exploitation during red team engagements.","https:\u002F\u002Fgithub.com\u002FDCx7C5\u002Fai-marketplace\u002Fblob\u002Fmain\u002Fskills\u002Fwindows\u002Fservices\u002Fwmi\u002Fexec\u002Fexploit\u002FSKILL.md",[],[144,121,145,124,146,45,147,43,41,40,148,149,150,151,37,152,153,34,154,155],"exploit","services wmi exec exploit","exec","traffic","team","across","crackmapexec","native","command","lateral movement","lateral-movement","Impacket",{"skillNo":157,"name":158,"nameZh":6,"description":159,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":160,"categories":161,"keywords":162,"publishedAt":49},"01M71HAG6MHKNQV8KDZKMT4886","registry-artifact-extract","Extract and analyze Windows Registry hives to uncover user activity, installed software, autostart entries, and evidence of system compromise.","https:\u002F\u002Fgithub.com\u002FDCx7C5\u002Fai-marketplace\u002Fblob\u002Fmain\u002Fskills\u002Fwindows\u002Fregistry\u002Fartifact\u002Fextract\u002FSKILL.md",[],[163,164,165,166,167,168,43,41,169,40,29,170,37,34,171,172,77,173,174,66],"artifact","registry","registry artifact extract","extract","evidence-collection","artifact-analysis","collection","uncover","software","activity","windows-registry","regripper",{"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":15,"licenseFileUrl":6,"sourceHtmlUrl":179,"categories":180,"keywords":181,"publishedAt":49},"01M71HACR4A8XTWTTSXK4124AA","processes-token-impersonate-detect","Detect Windows token impersonation and privilege abuse including SeImpersonatePrivilege exploitation via Potato attacks and token stealing techniques.","https:\u002F\u002Fgithub.com\u002FDCx7C5\u002Fai-marketplace\u002Fblob\u002Fmain\u002Fskills\u002Fwindows\u002Fprocesses\u002Ftoken\u002Fimpersonate\u002Fdetect\u002FSKILL.md",[],[122,182,183,184,185,186,187,126,188,43,136,189,190,191,192,193,194,195,196,37],"processes token impersonate detect","token","processes","attacks","windows","escalation","techniques","privilege-escalation","seimpersonate","token-impersonation","printspoofer","exploitation","potato","impersonation","via",{"skillNo":198,"name":199,"nameZh":6,"description":200,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":201,"categories":202,"keywords":203,"publishedAt":49},"01M71HAABSB4Z6QFSXEG00R4RK","processes-thread-injection-detect","Detect Windows thread injection techniques including CreateRemoteThread, QueueUserAPC, NtCreateThreadEx, and thread hijacking via process memory analysis.","https:\u002F\u002Fgithub.com\u002FDCx7C5\u002Fai-marketplace\u002Fblob\u002Fmain\u002Fskills\u002Fwindows\u002Fprocesses\u002Fthread\u002Finjection\u002Fdetect\u002FSKILL.md",[],[204,205,122,206,184,186,207,126,208,188,43,136,40,39,209,210,211,196,37,127],"thread","processes thread injection detect","injection","memory","process-injection","apc-injection","thread-injection","nt-api",{"skillNo":213,"name":214,"nameZh":6,"description":215,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":216,"categories":217,"keywords":218,"publishedAt":49},"01M71HA7H311V5G14WMX58HQSS","processes-hollow-technique-detect","Detect process hollowing (RunPE) by identifying processes with mismatched image paths between PEB and VAD tree, or unmapped PE headers in memory.","https:\u002F\u002Fgithub.com\u002FDCx7C5\u002Fai-marketplace\u002Fblob\u002Fmain\u002Fskills\u002Fwindows\u002Fprocesses\u002Fhollow\u002Ftechnique\u002Fdetect\u002FSKILL.md",[],[219,122,184,220,207,126,221,222,43,136,223,224,225,226,227,228,37,127,229,230],"processes hollow technique detect","tree","memory-forensics","process-hollow","peb","runpe","image","pe-header","in memory","with","mismatched","headers"]