iflow-mcp_developermode-korea_reversecore-mcp 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- iflow_mcp_developermode_korea_reversecore_mcp-1.0.0.dist-info/METADATA +543 -0
- iflow_mcp_developermode_korea_reversecore_mcp-1.0.0.dist-info/RECORD +79 -0
- iflow_mcp_developermode_korea_reversecore_mcp-1.0.0.dist-info/WHEEL +5 -0
- iflow_mcp_developermode_korea_reversecore_mcp-1.0.0.dist-info/entry_points.txt +2 -0
- iflow_mcp_developermode_korea_reversecore_mcp-1.0.0.dist-info/licenses/LICENSE +21 -0
- iflow_mcp_developermode_korea_reversecore_mcp-1.0.0.dist-info/top_level.txt +1 -0
- reversecore_mcp/__init__.py +9 -0
- reversecore_mcp/core/__init__.py +78 -0
- reversecore_mcp/core/audit.py +101 -0
- reversecore_mcp/core/binary_cache.py +138 -0
- reversecore_mcp/core/command_spec.py +357 -0
- reversecore_mcp/core/config.py +432 -0
- reversecore_mcp/core/container.py +288 -0
- reversecore_mcp/core/decorators.py +152 -0
- reversecore_mcp/core/error_formatting.py +93 -0
- reversecore_mcp/core/error_handling.py +142 -0
- reversecore_mcp/core/evidence.py +229 -0
- reversecore_mcp/core/exceptions.py +296 -0
- reversecore_mcp/core/execution.py +240 -0
- reversecore_mcp/core/ghidra.py +642 -0
- reversecore_mcp/core/ghidra_helper.py +481 -0
- reversecore_mcp/core/ghidra_manager.py +234 -0
- reversecore_mcp/core/json_utils.py +131 -0
- reversecore_mcp/core/loader.py +73 -0
- reversecore_mcp/core/logging_config.py +206 -0
- reversecore_mcp/core/memory.py +721 -0
- reversecore_mcp/core/metrics.py +198 -0
- reversecore_mcp/core/mitre_mapper.py +365 -0
- reversecore_mcp/core/plugin.py +45 -0
- reversecore_mcp/core/r2_helpers.py +404 -0
- reversecore_mcp/core/r2_pool.py +403 -0
- reversecore_mcp/core/report_generator.py +268 -0
- reversecore_mcp/core/resilience.py +252 -0
- reversecore_mcp/core/resource_manager.py +169 -0
- reversecore_mcp/core/result.py +132 -0
- reversecore_mcp/core/security.py +213 -0
- reversecore_mcp/core/validators.py +238 -0
- reversecore_mcp/dashboard/__init__.py +221 -0
- reversecore_mcp/prompts/__init__.py +56 -0
- reversecore_mcp/prompts/common.py +24 -0
- reversecore_mcp/prompts/game.py +280 -0
- reversecore_mcp/prompts/malware.py +1219 -0
- reversecore_mcp/prompts/report.py +150 -0
- reversecore_mcp/prompts/security.py +136 -0
- reversecore_mcp/resources.py +329 -0
- reversecore_mcp/server.py +727 -0
- reversecore_mcp/tools/__init__.py +49 -0
- reversecore_mcp/tools/analysis/__init__.py +74 -0
- reversecore_mcp/tools/analysis/capa_tools.py +215 -0
- reversecore_mcp/tools/analysis/die_tools.py +180 -0
- reversecore_mcp/tools/analysis/diff_tools.py +643 -0
- reversecore_mcp/tools/analysis/lief_tools.py +272 -0
- reversecore_mcp/tools/analysis/signature_tools.py +591 -0
- reversecore_mcp/tools/analysis/static_analysis.py +479 -0
- reversecore_mcp/tools/common/__init__.py +58 -0
- reversecore_mcp/tools/common/file_operations.py +352 -0
- reversecore_mcp/tools/common/memory_tools.py +516 -0
- reversecore_mcp/tools/common/patch_explainer.py +230 -0
- reversecore_mcp/tools/common/server_tools.py +115 -0
- reversecore_mcp/tools/ghidra/__init__.py +19 -0
- reversecore_mcp/tools/ghidra/decompilation.py +975 -0
- reversecore_mcp/tools/ghidra/ghidra_tools.py +1052 -0
- reversecore_mcp/tools/malware/__init__.py +61 -0
- reversecore_mcp/tools/malware/adaptive_vaccine.py +579 -0
- reversecore_mcp/tools/malware/dormant_detector.py +756 -0
- reversecore_mcp/tools/malware/ioc_tools.py +228 -0
- reversecore_mcp/tools/malware/vulnerability_hunter.py +519 -0
- reversecore_mcp/tools/malware/yara_tools.py +214 -0
- reversecore_mcp/tools/patch_explainer.py +19 -0
- reversecore_mcp/tools/radare2/__init__.py +13 -0
- reversecore_mcp/tools/radare2/r2_analysis.py +972 -0
- reversecore_mcp/tools/radare2/r2_session.py +376 -0
- reversecore_mcp/tools/radare2/radare2_mcp_tools.py +1183 -0
- reversecore_mcp/tools/report/__init__.py +4 -0
- reversecore_mcp/tools/report/email.py +82 -0
- reversecore_mcp/tools/report/report_mcp_tools.py +344 -0
- reversecore_mcp/tools/report/report_tools.py +1076 -0
- reversecore_mcp/tools/report/session.py +194 -0
- reversecore_mcp/tools/report_tools.py +11 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Session management for malware analysis reports.
|
|
3
|
+
|
|
4
|
+
Provides AnalysisSession dataclass and timezone utilities.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import asdict, dataclass, field
|
|
8
|
+
from datetime import datetime, timedelta, timezone
|
|
9
|
+
from enum import Enum
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class TimezonePreset(Enum):
|
|
14
|
+
"""Frequently used timezone presets"""
|
|
15
|
+
|
|
16
|
+
UTC = "UTC"
|
|
17
|
+
KST = "Asia/Seoul" # UTC+9
|
|
18
|
+
JST = "Asia/Tokyo" # UTC+9
|
|
19
|
+
CST = "Asia/Shanghai" # UTC+8
|
|
20
|
+
EST = "America/New_York" # UTC-5/-4
|
|
21
|
+
PST = "America/Los_Angeles" # UTC-8/-7
|
|
22
|
+
CET = "Europe/Paris" # UTC+1/+2
|
|
23
|
+
GMT = "Europe/London" # UTC+0/+1
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# Timezone handling using standard library zoneinfo (Python 3.9+)
|
|
27
|
+
try:
|
|
28
|
+
from zoneinfo import ZoneInfo
|
|
29
|
+
except ImportError:
|
|
30
|
+
# Fallback for older python versions if backports.zoneinfo not installed
|
|
31
|
+
from datetime import timedelta, timezone
|
|
32
|
+
|
|
33
|
+
class ZoneInfo:
|
|
34
|
+
def __init__(self, key: str):
|
|
35
|
+
self.key = key
|
|
36
|
+
|
|
37
|
+
def utcoffset(self, dt):
|
|
38
|
+
# Very basic fallback - DOES NOT HANDLE DST
|
|
39
|
+
# This is just to prevent crashes if zoneinfo missing
|
|
40
|
+
offsets = {
|
|
41
|
+
"Asia/Seoul": 9,
|
|
42
|
+
"Asia/Tokyo": 9,
|
|
43
|
+
"Asia/Shanghai": 8,
|
|
44
|
+
"America/New_York": -5,
|
|
45
|
+
"America/Los_Angeles": -8,
|
|
46
|
+
"Europe/Paris": 1,
|
|
47
|
+
"Europe/London": 0,
|
|
48
|
+
"UTC": 0,
|
|
49
|
+
}
|
|
50
|
+
return timedelta(hours=offsets.get(self.key, 0))
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def get_timezone(tz_name: str):
|
|
54
|
+
"""Get timezone object by name with DST support."""
|
|
55
|
+
try:
|
|
56
|
+
return ZoneInfo(tz_name)
|
|
57
|
+
except Exception:
|
|
58
|
+
return ZoneInfo("UTC")
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
# Timezone offsets (standard time)
|
|
62
|
+
TIMEZONE_OFFSETS: dict[str, int] = {
|
|
63
|
+
"UTC": 0,
|
|
64
|
+
"Asia/Seoul": 9,
|
|
65
|
+
"Asia/Tokyo": 9,
|
|
66
|
+
"Asia/Shanghai": 8,
|
|
67
|
+
"America/New_York": -5,
|
|
68
|
+
"America/Los_Angeles": -8,
|
|
69
|
+
"Europe/Paris": 1,
|
|
70
|
+
"Europe/London": 0,
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
# Timezone abbreviation mapping (kept for display purposes)
|
|
74
|
+
TIMEZONE_ABBRS: dict[str, str] = {
|
|
75
|
+
"UTC": "UTC",
|
|
76
|
+
"Asia/Seoul": "KST",
|
|
77
|
+
"Asia/Tokyo": "JST",
|
|
78
|
+
"Asia/Shanghai": "CST",
|
|
79
|
+
"America/New_York": "ET",
|
|
80
|
+
"America/Los_Angeles": "PT",
|
|
81
|
+
"Europe/Paris": "CET",
|
|
82
|
+
"Europe/London": "GMT",
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@dataclass
|
|
87
|
+
class AnalysisSession:
|
|
88
|
+
"""Data class for tracking analysis session information"""
|
|
89
|
+
|
|
90
|
+
session_id: str
|
|
91
|
+
sample_path: str | None = None
|
|
92
|
+
sample_name: str | None = None
|
|
93
|
+
analyst: str = "Security Researcher"
|
|
94
|
+
|
|
95
|
+
# Timestamps (stored in UTC)
|
|
96
|
+
started_at: datetime | None = None
|
|
97
|
+
ended_at: datetime | None = None
|
|
98
|
+
|
|
99
|
+
# Session status
|
|
100
|
+
status: str = "initialized" # initialized, in_progress, completed, aborted
|
|
101
|
+
|
|
102
|
+
# Data collected during analysis
|
|
103
|
+
findings: dict[str, Any] = field(default_factory=dict)
|
|
104
|
+
iocs: dict[str, list[str]] = field(
|
|
105
|
+
default_factory=lambda: {
|
|
106
|
+
"hashes": [],
|
|
107
|
+
"ips": [],
|
|
108
|
+
"domains": [],
|
|
109
|
+
"urls": [],
|
|
110
|
+
"files": [],
|
|
111
|
+
"registry": [],
|
|
112
|
+
"mutexes": [],
|
|
113
|
+
"emails": [],
|
|
114
|
+
"bitcoin_addresses": [], # For ransomware BTC wallets
|
|
115
|
+
"crypto_wallets": [], # ETH, XMR, etc.
|
|
116
|
+
}
|
|
117
|
+
)
|
|
118
|
+
mitre_techniques: list[dict[str, str]] = field(default_factory=list)
|
|
119
|
+
notes: list[dict[str, str]] = field(default_factory=list)
|
|
120
|
+
|
|
121
|
+
# Additional metadata
|
|
122
|
+
tags: list[str] = field(default_factory=list)
|
|
123
|
+
severity: str = "medium" # low, medium, high, critical
|
|
124
|
+
malware_family: str | None = None
|
|
125
|
+
|
|
126
|
+
def start(self):
|
|
127
|
+
"""Start session"""
|
|
128
|
+
self.started_at = datetime.now(timezone.utc)
|
|
129
|
+
self.status = "in_progress"
|
|
130
|
+
|
|
131
|
+
def end(self, status: str = "completed"):
|
|
132
|
+
"""End session"""
|
|
133
|
+
self.ended_at = datetime.now(timezone.utc)
|
|
134
|
+
self.status = status
|
|
135
|
+
|
|
136
|
+
def get_duration(self) -> timedelta | None:
|
|
137
|
+
"""Calculate analysis duration"""
|
|
138
|
+
if not self.started_at:
|
|
139
|
+
return None
|
|
140
|
+
end = self.ended_at or datetime.now(timezone.utc)
|
|
141
|
+
return end - self.started_at
|
|
142
|
+
|
|
143
|
+
def get_duration_str(self) -> str:
|
|
144
|
+
"""Human-readable duration string"""
|
|
145
|
+
duration = self.get_duration()
|
|
146
|
+
if duration is None:
|
|
147
|
+
return "N/A"
|
|
148
|
+
|
|
149
|
+
total_seconds = int(duration.total_seconds())
|
|
150
|
+
hours, remainder = divmod(total_seconds, 3600)
|
|
151
|
+
minutes, seconds = divmod(remainder, 60)
|
|
152
|
+
|
|
153
|
+
parts = []
|
|
154
|
+
if hours > 0:
|
|
155
|
+
parts.append(f"{hours}h")
|
|
156
|
+
if minutes > 0:
|
|
157
|
+
parts.append(f"{minutes}m")
|
|
158
|
+
parts.append(f"{seconds}s")
|
|
159
|
+
|
|
160
|
+
return " ".join(parts)
|
|
161
|
+
|
|
162
|
+
def add_ioc(self, ioc_type: str, value: str) -> bool:
|
|
163
|
+
"""Add IOC"""
|
|
164
|
+
if ioc_type in self.iocs and value not in self.iocs[ioc_type]:
|
|
165
|
+
self.iocs[ioc_type].append(value)
|
|
166
|
+
return True
|
|
167
|
+
return False
|
|
168
|
+
|
|
169
|
+
def add_note(self, note: str, category: str = "general"):
|
|
170
|
+
"""Add analysis note"""
|
|
171
|
+
timestamp = datetime.now(timezone.utc).isoformat()
|
|
172
|
+
self.notes.append({"timestamp": timestamp, "note": note, "category": category})
|
|
173
|
+
|
|
174
|
+
def add_mitre(self, technique_id: str, technique_name: str, tactic: str):
|
|
175
|
+
"""Add MITRE ATT&CK technique"""
|
|
176
|
+
entry = {"id": technique_id, "name": technique_name, "tactic": tactic}
|
|
177
|
+
if entry not in self.mitre_techniques:
|
|
178
|
+
self.mitre_techniques.append(entry)
|
|
179
|
+
|
|
180
|
+
def add_tag(self, tag: str):
|
|
181
|
+
"""Add tag"""
|
|
182
|
+
if tag not in self.tags:
|
|
183
|
+
self.tags.append(tag)
|
|
184
|
+
|
|
185
|
+
def to_dict(self) -> dict:
|
|
186
|
+
"""Serialize to dictionary"""
|
|
187
|
+
data = asdict(self)
|
|
188
|
+
# Convert datetime objects to ISO format
|
|
189
|
+
if self.started_at:
|
|
190
|
+
data["started_at"] = self.started_at.isoformat()
|
|
191
|
+
if self.ended_at:
|
|
192
|
+
data["ended_at"] = self.ended_at.isoformat()
|
|
193
|
+
data["duration"] = self.get_duration_str()
|
|
194
|
+
return data
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Report Tools module - Backward compatibility alias.
|
|
3
|
+
|
|
4
|
+
This module was moved to report/report_tools.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
# Re-export everything from report.report_tools
|
|
8
|
+
from reversecore_mcp.tools.report.report_tools import *
|
|
9
|
+
from reversecore_mcp.tools.report.report_tools import ReportTools
|
|
10
|
+
|
|
11
|
+
__all__ = ["ReportTools"]
|