-
Notifications
You must be signed in to change notification settings - Fork 431
sesameop #3827
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
sesameop #3827
Changes from all commits
f704724
10440c8
7b01655
3002e2e
254e7a5
080769f
e33bae1
56bc52d
e265b21
3f0da71
5003ee5
3a1c68d
91eb95a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| name: Windows Potential AppDomainManager Hijack Artifacts Creation | ||
| id: be19b369-fd0c-42be-ae97-c10b6c01638f | ||
| version: 1 | ||
| date: '2025-12-10' | ||
| author: Teoderick Contreras, Splunk | ||
| status: production | ||
| type: Anomaly | ||
| description: The following analytic detects the creation of an .exe file along with its corresponding .exe.config and a .dll in the same directory, which is a common pattern indicative of potential AppDomain hijacking or CLR code injection attempts. This behavior may signal that a malicious actor is attempting to load a rogue assembly into a legitimate application's AppDomain, allowing code execution under the context of a trusted process. | ||
| data_source: | ||
| - Sysmon EventID 11 | ||
| search: | | ||
| | tstats `security_content_summariesonly` count min(_time) AS firstTime max(_time) AS lastTime from datamodel=Endpoint.Filesystem | ||
| where Filesystem.file_name IN ("*.exe", "*.exe.config", "*.dll") AND Filesystem.file_path IN | ||
| ("*\\windows\\fonts\\*", "*\\temp\\*", "*\\users\\public\\*", "*\\windows\\debug\\*","*\\Users\\Administrator\\Music\\*", "*\\Windows\\servicing\\*", "*\\Users\\Default\\*", "*Recycle.bin*", "*\\Windows\\Media\\*", "*\\Windows\\repair\\*", "*\\PerfLogs\\*") | ||
| AND Filesystem.action = "created" | ||
| by Filesystem.action Filesystem.dest Filesystem.file_access_time Filesystem.file_create_time Filesystem.file_hash Filesystem.file_modify_time Filesystem.file_name Filesystem.file_path Filesystem.file_acl Filesystem.file_size Filesystem.process_guid Filesystem.process_id Filesystem.user Filesystem.vendor_product | ||
| | `drop_dm_object_name("Filesystem")` | ||
| | stats values(file_name) AS file_names | ||
| values(file_path) AS file_paths | ||
| values(user) AS users | ||
| min(firstTime) AS firstTime max(lastTime) AS lastTime | ||
| BY dest process_guid | ||
| | eval exe_present = if(mvcount(mvfilter(match(file_names, "\.exe$"))) > 0, 1, 0) | ||
| | eval config_present = if(mvcount(mvfilter(match(file_names, "\.exe\.config$"))) > 0, 1, 0) | ||
| | eval dll_present = if(mvcount(mvfilter(match(file_names, "\.dll$"))) > 0, 1, 0) | ||
|
|
||
| | eval exe_files = mvfilter(match(file_names, "\.exe$") AND NOT match(file_names, "\.exe\.config$")) | ||
| | eval config_files = mvfilter(match(file_names, "\.exe\.config$")) | ||
| | eval exe_base_names = mvmap(exe_files, replace(exe_files, "\.exe$", "")) | ||
| | eval config_base_names = mvmap(config_files, replace(config_files, "\.exe\.config$", "")) | ||
|
|
||
| | mvexpand exe_base_names | ||
| | mvexpand config_base_names | ||
|
|
||
| | eval file_count = mvcount(file_names) | ||
|
|
||
| | where file_count >= 3 AND exe_present = 1 AND config_present = 1 AND dll_present = 1 AND exe_base_names = config_base_names | ||
| | `security_content_ctime(firstTime)` | ||
| | `security_content_ctime(lastTime)` | ||
| | `windows_potential_appdomainmanager_hijack_artifacts_creation_filter` | ||
| how_to_implement: To successfully implement this search you need to be ingesting information | ||
| on process that include the name of the process responsible for the changes from | ||
| your endpoints into the `Endpoint` datamodel in the `Filesystem` node. In addition, | ||
| confirm the latest CIM App 4.20 or higher is installed and the latest TA for the | ||
| endpoint product. | ||
| known_false_positives: This detection may still produce false positives, so additional filtering is recommended. To validate potential alerts, verify that the executable’s original file name matches its current file name, and also review the associated .config file to confirm which DLLs are expected to load during execution. This helps distinguish legitimate activity from suspicious behavior. | ||
| references: | ||
| - https://www.microsoft.com/en-us/security/blog/2025/11/03/sesameop-novel-backdoor-uses-openai-assistants-api-for-command-and-control/ | ||
| - https://attack.mitre.org/techniques/T1574/014/ | ||
tccontre marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| - https://gist.github.com/djhohnstein/afb93a114b848e16facf0b98cd7cb57b | ||
| - https://www.scworld.com/brief/appdomain-manager-injection-exploited-for-cobalt-strike-beacon-delivery | ||
| - https://jp.security.ntt/insights_resources/tech_blog/appdomainmanager-injection-en/ | ||
| drilldown_searches: | ||
| - name: View the detection results for - "$dest$" | ||
| search: '%original_detection_search% | search dest = "$dest$"' | ||
| earliest_offset: $info_min_time$ | ||
| latest_offset: $info_max_time$ | ||
| - name: View risk events for the last 7 days for - "$dest$" | ||
| search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$dest$") | ||
| starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime | ||
| values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) | ||
| as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) | ||
| as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | ||
| | `security_content_ctime(lastTime)`' | ||
| earliest_offset: $info_min_time$ | ||
| latest_offset: $info_max_time$ | ||
| rba: | ||
| message: A file $file_name$ is created in $file_path$ on $dest$ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ljstella same question here. If the condition is grouping the file name into MVs. What's best to use here? Should we perhaps use |
||
| risk_objects: | ||
| - field: dest | ||
| type: system | ||
| score: 20 | ||
| threat_objects: | ||
| - field: file_names | ||
| type: file_name | ||
|
Comment on lines
+74
to
+75
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ljstella question for you. How do multi value threat objects show up? |
||
| - field: file_paths | ||
| type: file_path | ||
| tags: | ||
| analytic_story: | ||
| - SesameOp | ||
| asset_type: Endpoint | ||
| mitre_attack_id: | ||
| - T1574.014 | ||
| product: | ||
| - Splunk Enterprise | ||
| - Splunk Enterprise Security | ||
| - Splunk Cloud | ||
| security_domain: endpoint | ||
| tests: | ||
| - name: True Positive Test | ||
| attack_data: | ||
| - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1574.014/appdomain_hijack_artifacts/appdomain_hijack.log | ||
| source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational | ||
| sourcetype: XmlWinEventLog | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| name: SesameOp | ||
| id: 26b6c7c5-351b-489f-8053-da6cbaa74479 | ||
| version: 1 | ||
| date: '2025-12-10' | ||
| author: Teoderick Contreras, Splunk | ||
| status: production | ||
| description: SesameOp is a Backdoor that abuses the OpenAI Assistants API as its command-and-control (C2) channel. Instead of using a traditional malicious server infrastructure, the malware loads a heavily obfuscated .NET DLL (Netapi64.dll / OpenAIAgent.Netapi64) which reaches out to the Assistants API to fetch encrypted, compressed commands and then executes them on the infected host. Results from these commands are likewise compressed, encrypted and sent back via the same legitimate API channel — effectively hiding malicious traffic in seemingly normal API calls. To evade detection, it injects into the host using .NET AppDomainManager injection, maintains persistence over time, and obfuscates communications via symmetric and asymmetric encryption plus compression. | ||
| narrative: SesameOp is a stealthy backdoor discovered in July 2025 that abuses the OpenAI Assistants API as a covert command-and-control channel. It comprises two components, a heavily obfuscated loader (Netapi64.dll) and a .NET-based backdoor (OpenAIAgent.Netapi64). The loader uses .NET AppDomainManager injection to persist within otherwise legitimate host processes such as developer tools. Once active, the backdoor fetches encrypted, compressed commands hidden in AI-assistant metadata from the OpenAI API, executes them locally, and returns results using the same legitimate HTTPS traffic. Because the traffic resembles normal AI API usage, it easily evades standard network detection methods. | ||
| references: | ||
| - https://www.microsoft.com/en-us/security/blog/2025/11/03/sesameop-novel-backdoor-uses-openai-assistants-api-for-command-and-control/ | ||
| tags: | ||
| category: | ||
| - Data Destruction | ||
| - Malware | ||
| - Adversary Tactics | ||
| product: | ||
| - Splunk Enterprise | ||
| - Splunk Enterprise Security | ||
| - Splunk Cloud | ||
| usecase: Advanced Threat Detection |
Uh oh!
There was an error while loading. Please reload this page.