diff --git a/CHANGELOG.md b/CHANGELOG.md index 69eb6385d..13f938a5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,44 +1,4 @@ -# UTMStack 11.0.0 Release Notes - -This is the release notes for **UTMStack v11**, a major update from v10. This version introduces significant improvements and new features aimed at enhancing performance, scalability, and security. - -## ⚠️ BREAKING CHANGE - Migration Required - -**IMPORTANT:** UTMStack v11 introduces fundamental architectural changes that make it **incompatible with v10**. - -- **Direct upgrades from v10 to v11 are NOT supported** -- A **complete migration** is required to move from v10 to v11 -- We are currently developing a **migration tool** to facilitate this process -- **Do not attempt to upgrade** your v10 installation to v11 until the migration tool is available - -Please contact our support team for guidance on migration planning and timeline. - -## Key Highlights - -### Performance and Resource Optimization -- **EventProcessor Integration:** Replaced the resource-intensive Logstash with the new **EventProcessor** from Threatwinds, drastically reducing resource usage for data processing. -- **Plugin Architecture:** Introduced a new **plugin system** for official integrations, improving scalability and maintainability. -- **Scalable Processing:** Previous versions required one container per data input. Now, v11 uses two EventProcessor containers—a manager and a worker—allowing each to run its plugins and process logs in parallel. Additional workers can be added as needed to avoid bottlenecks. - -### Security Enhancements -- **TLS Improvements:** Strengthened TLS handling across all components. -- **Mandatory Multi-Factor Authentication (MFA):** Added as a required security measure to protect access. - -### SOC-AI Enhancements -- **Custom Models Support:** Users can now utilize their own models in SOC-AI integrations, in addition to officially supported models. - -### User Interface and Usability -- **UI Overhaul:** Major improvements to visual interfaces for enhanced user experience. -- **SOAR (formerly Incident Response):** Renamed and upgraded to provide automated alert response workflows. -- **Rule Creation Improvements:** Simplified graphical interface for rule creation while maintaining YAML-based configuration options. -- **Log Filter Format Update:** Simplified from complex Logstash syntax to easy-to-use YAML format. - -### Centralization and Deployment -- **Central Server:** All instances can now connect to a central server for improved support, enabling remote log submission. -- **Cross-Platform Installation:** Added support for **Red Hat** installations in addition to Ubuntu. -- **Offline On-Premise Installation:** Supported with guided assistance from our engineers for more complex setups. -- **Automatic Updates:** Updates can now be automatically applied from the central server. Users can schedule updates to run at convenient times, ensuring the system remains current without manual checks. - -## Summary -UTMStack v11 represents a major leap forward in performance, scalability, security, and usability. The new architecture, plugin system, and central server support ensure that deployments can grow with your organization's needs while simplifying management and operations. +# UTMStack 11.0.1 Release Notes +- Enriched the TIMEZONES constant to include additional IANA zones for broader coverage. +- Support for additional syslog framing methods (RFC 5424 octet counting). \ No newline at end of file diff --git a/frontend/src/app/app-module/shared/components/app-module-card/app-module-card.component.html b/frontend/src/app/app-module/shared/components/app-module-card/app-module-card.component.html index 8cf7e65b1..9a086b794 100644 --- a/frontend/src/app/app-module/shared/components/app-module-card/app-module-card.component.html +++ b/frontend/src/app/app-module/shared/components/app-module-card/app-module-card.component.html @@ -1,8 +1,8 @@
-
+
{{module.prettyName}}

- - + -->
diff --git a/frontend/src/app/incident-response/playbooks/playbooks.component.html b/frontend/src/app/incident-response/playbooks/playbooks.component.html index a69c4c939..5eab287a4 100644 --- a/frontend/src/app/incident-response/playbooks/playbooks.component.html +++ b/frontend/src/app/incident-response/playbooks/playbooks.component.html @@ -102,20 +102,20 @@
FLOWS
- -
- -

Start building

-

Begin with a template, or start from scratch.

- - - New Flow - +
+ +

Start building

+

Begin with a template, or start from scratch.

+ + + New Flow + +
Start building + +
!!request), switchMap(request => { - this.loading.next(true); + setTimeout(() => this.loading.next(true), 300); return this.incidentResponseRuleService.query(request).pipe( map(response => { this.totalItems.next(Number(response.headers.get('X-Total-Count'))); @@ -30,7 +30,7 @@ export class PlaybookService { this.utmToastService.showError('Error', 'An error occurred while fetching playbooks.'); return of([]); }), - finalize(() => this.loading.next(false)) + finalize(() => setTimeout(() => this.loading.next(false), 200)) ); }) ); diff --git a/frontend/src/app/shared/components/layout/header/shared/components/utm-version-info/utm-version-info.component.html b/frontend/src/app/shared/components/layout/header/shared/components/utm-version-info/utm-version-info.component.html index b5a59b113..34805073f 100644 --- a/frontend/src/app/shared/components/layout/header/shared/components/utm-version-info/utm-version-info.component.html +++ b/frontend/src/app/shared/components/layout/header/shared/components/utm-version-info/utm-version-info.component.html @@ -1,4 +1,4 @@ - + diff --git a/frontend/src/app/shared/components/layout/header/shared/components/utm-version-info/utm-version-info.component.ts b/frontend/src/app/shared/components/layout/header/shared/components/utm-version-info/utm-version-info.component.ts index 161e85940..cb2b72aa3 100644 --- a/frontend/src/app/shared/components/layout/header/shared/components/utm-version-info/utm-version-info.component.ts +++ b/frontend/src/app/shared/components/layout/header/shared/components/utm-version-info/utm-version-info.component.ts @@ -12,8 +12,7 @@ import {VersionInfo} from '../../../../../../types/updates/updates.type'; styleUrls: ['./utm-version-info.component.css'] }) export class UtmVersionInfoComponent implements OnInit { - currentVersion$: Observable = EMPTY; - destroy$ = new Subject(); + versionInfo: VersionInfo; constructor(private checkForUpdatesService: CheckForUpdatesService, private utmToastService: UtmToastService, @@ -21,26 +20,30 @@ export class UtmVersionInfoComponent implements OnInit { } ngOnInit() { - this.getVersionInfo(); - } - - getVersionInfo() { - this.currentVersion$ = this.checkForUpdatesService.getVersion() + this.checkForUpdatesService.getVersion() .pipe( map(response => response.body || null), tap((versionInfo: VersionInfo) => { - console.log('versionInfo', versionInfo); const version = versionInfo && versionInfo.build && versionInfo.build.version || ''; - const versionType = version.includes('community') || version === '' ? VersionType.COMMUNITY : VersionType.ENTERPRISE; + const versionType = version.includes('community') || version === '' + ? VersionType.COMMUNITY + : VersionType.ENTERPRISE; if (versionType !== this.versionTypeService.versionType()) { this.versionTypeService.changeVersionType(versionType); } }), catchError(() => { - this.utmToastService.showError('Error fetching version info', 'An error occurred while fetching version info.'); + this.utmToastService.showError( + 'Error fetching version info', + 'An error occurred while fetching version info.' + ); return EMPTY; }) - ); + ) + .subscribe(versionInfo => { + this.versionInfo = versionInfo; + }); } + } diff --git a/frontend/src/app/shared/constants/alert/alert-field.constant.ts b/frontend/src/app/shared/constants/alert/alert-field.constant.ts index 19e33b1ea..ebeba9da2 100644 --- a/frontend/src/app/shared/constants/alert/alert-field.constant.ts +++ b/frontend/src/app/shared/constants/alert/alert-field.constant.ts @@ -488,6 +488,36 @@ export const ALERT_FILTERS_FIELDS: UtmFieldType[] = [ type: ElasticDataTypesEnum.STRING, visible: false, }, + { + label: 'Category', + field: ALERT_CATEGORY_FIELD, + type: ElasticDataTypesEnum.STRING, + visible: true, + }, + { + label: 'Sensor', + field: ALERT_SENSOR_FIELD, + type: ElasticDataTypesEnum.STRING, + visible: true, + }, + { + label: 'Time', + field: ALERT_TIMESTAMP_FIELD, + type: ElasticDataTypesEnum.DATE, + visible: false, + }, + { + label: 'Incident Name', + field: ALERT_INCIDENT_NAME_FIELD, + type: ElasticDataTypesEnum.STRING, + visible: true, + }, + { + label: 'Tags', + field: ALERT_TAGS_FIELD, + type: ElasticDataTypesEnum.STRING, + visible: true, + }, { label: 'Adversary IP', field: ALERT_ADVERSARY_IP_FIELD, @@ -583,36 +613,6 @@ export const ALERT_FILTERS_FIELDS: UtmFieldType[] = [ field: ALERT_TARGET_GEOLOCATION_LONGITUDE_FIELD, type: ElasticDataTypesEnum.STRING, visible: false, - }, - { - label: 'Category', - field: ALERT_CATEGORY_FIELD, - type: ElasticDataTypesEnum.STRING, - visible: true, - }, - { - label: 'Sensor', - field: ALERT_SENSOR_FIELD, - type: ElasticDataTypesEnum.STRING, - visible: true, - }, - { - label: 'Time', - field: ALERT_TIMESTAMP_FIELD, - type: ElasticDataTypesEnum.DATE, - visible: false, - }, - { - label: 'Incident Name', - field: ALERT_INCIDENT_NAME_FIELD, - type: ElasticDataTypesEnum.STRING, - visible: true, - }, - { - label: 'Tags', - field: ALERT_TAGS_FIELD, - type: ElasticDataTypesEnum.STRING, - visible: true, } ]; diff --git a/frontend/src/app/shared/constants/date-timezone-date.const.ts b/frontend/src/app/shared/constants/date-timezone-date.const.ts index ebb65546d..503bf2b64 100644 --- a/frontend/src/app/shared/constants/date-timezone-date.const.ts +++ b/frontend/src/app/shared/constants/date-timezone-date.const.ts @@ -1,3 +1,5 @@ +import moment from 'moment-timezone'; + export const DATE_SECTION_ID = 5; export const DEFAULT_DATE_SETTING_TIMEZONE = 'UTC'; @@ -6,7 +8,19 @@ export const DEFAULT_DATE_SETTING_DATE = 'medium'; export const DATE_SETTING_TIMEZONE_SHORT = 'utmstack.time.zone'; export const DATE_SETTING_FORMAT_SHORT = 'utmstack.time.dateformat'; -export const TIMEZONES: Array<{ label: string; timezone: string, zone: string }> = [ +export const TIMEZONES: Array<{ label: string; timezone: string; zone: string }> = + moment.tz.names().map((tz) => { + const parts = tz.split('/'); + const zone = parts[0] || 'Other'; + const label = tz.replace(/_/g, ' '); + return { + label, + timezone: tz, + zone + }; + }); + +/*export const TIMEZONES: Array<{ label: string; timezone: string, zone: string }> = [ {label: 'UTC', timezone: 'UTC', zone: 'UTC'}, {label: 'Eastern Standard Time (New York)', timezone: 'America/New_York', zone: 'America'}, {label: 'Pacific Standard Time (Los Angeles)', timezone: 'America/Los_Angeles', zone: 'America'}, @@ -38,7 +52,8 @@ export const TIMEZONES: Array<{ label: string; timezone: string, zone: string }> {label: 'Jerusalem (IST)', timezone: 'Asia/Jerusalem', zone: 'Asia'}, {label: 'Buenos Aires (ART)', timezone: 'America/Argentina/Buenos_Aires', zone: 'America'}, {label: 'São Paulo (BRT)', timezone: 'America/Sao_Paulo', zone: 'America'}, -]; +];*/ + export const DATE_FORMATS: Array<{ label: string; format: string; equivalentTo: string }> = [ {label: 'Short', format: 'short', equivalentTo: 'M/d/yy, h:mm a'}, {label: 'Medium', format: 'medium', equivalentTo: 'MMM d, y, h:mm:ss a'}, diff --git a/plugins/modules-config/config/config.go b/plugins/modules-config/config/config.go index 28780d84b..0a1576896 100644 --- a/plugins/modules-config/config/config.go +++ b/plugins/modules-config/config/config.go @@ -128,6 +128,8 @@ func (s *ConfigServer) NotifyUpdate(moduleName string, section *ConfigurationSec pluginType = PluginType_SOC_AI case "SOPHOS": pluginType = PluginType_SOPHOS + case "CROWDSTRIKE": + pluginType = PluginType_CROWDSTRIKE default: _ = catcher.Error("unknown module name", fmt.Errorf("module: %s", moduleName), nil) return @@ -165,6 +167,7 @@ func (s *ConfigServer) SyncConfigs(backend string, internalKey string) { "O365": PluginType_O365, "SOC_AI": PluginType_SOC_AI, "SOPHOS": PluginType_SOPHOS, + "CROWDSTRIKE": PluginType_CROWDSTRIKE, } for name, t := range AllModules { diff --git a/plugins/modules-config/config/config.pb.go b/plugins/modules-config/config/config.pb.go index 8f1713887..5c33be8d8 100644 --- a/plugins/modules-config/config/config.pb.go +++ b/plugins/modules-config/config/config.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.6 -// protoc v5.29.3 +// protoc-gen-go v1.36.2 +// protoc v3.21.12 // source: config.proto package config @@ -11,7 +11,6 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" - unsafe "unsafe" ) const ( @@ -32,6 +31,7 @@ const ( PluginType_O365 PluginType = 5 PluginType_SOC_AI PluginType = 6 PluginType_SOPHOS PluginType = 7 + PluginType_CROWDSTRIKE PluginType = 8 ) // Enum value maps for PluginType. @@ -45,6 +45,7 @@ var ( 5: "O365", 6: "SOC_AI", 7: "SOPHOS", + 8: "CROWDSTRIKE", } PluginType_value = map[string]int32{ "UNKNOWN": 0, @@ -55,6 +56,7 @@ var ( "O365": 5, "SOC_AI": 6, "SOPHOS": 7, + "CROWDSTRIKE": 8, } ) @@ -529,76 +531,110 @@ func (x *ConfigurationSection) GetActivatable() bool { var File_config_proto protoreflect.FileDescriptor -const file_config_proto_rawDesc = "" + - "\n" + - "\fconfig.proto\x12\x06config\"\x90\x01\n" + - "\x14BiDirectionalMessage\x125\n" + - "\vplugin_init\x18\x01 \x01(\v2\x12.config.PluginInitH\x00R\n" + - "pluginInit\x126\n" + - "\x06config\x18\x02 \x01(\v2\x1c.config.ConfigurationSectionH\x00R\x06configB\t\n" + - "\apayload\"4\n" + - "\n" + - "PluginInit\x12&\n" + - "\x04type\x18\x01 \x01(\x0e2\x12.config.PluginTypeR\x04type\"\xff\x01\n" + - "\rConfiguration\x12\x0e\n" + - "\x02id\x18\x01 \x01(\x05R\x02id\x12\x18\n" + - "\agroupId\x18\x02 \x01(\x05R\agroupId\x12\x18\n" + - "\aconfKey\x18\x03 \x01(\tR\aconfKey\x12\x1c\n" + - "\tconfValue\x18\x04 \x01(\tR\tconfValue\x12\x1a\n" + - "\bconfName\x18\x05 \x01(\tR\bconfName\x12(\n" + - "\x0fconfDescription\x18\x06 \x01(\tR\x0fconfDescription\x12\"\n" + - "\fconfDataType\x18\a \x01(\tR\fconfDataType\x12\"\n" + - "\fconfRequired\x18\b \x01(\bR\fconfRequired\"\xf6\x01\n" + - "\vModuleGroup\x12\x0e\n" + - "\x02id\x18\x01 \x01(\x05R\x02id\x12\x1a\n" + - "\bmoduleId\x18\x02 \x01(\x05R\bmoduleId\x12\x1c\n" + - "\tgroupName\x18\x03 \x01(\tR\tgroupName\x12*\n" + - "\x10groupDescription\x18\x04 \x01(\tR\x10groupDescription\x12S\n" + - "\x19moduleGroupConfigurations\x18\x05 \x03(\v2\x15.config.ConfigurationR\x19moduleGroupConfigurations\x12\x1c\n" + - "\tcollector\x18\x06 \x01(\tR\tcollector\"\xbd\x03\n" + - "\x14ConfigurationSection\x12\x0e\n" + - "\x02id\x18\x01 \x01(\x05R\x02id\x12\x1a\n" + - "\bserverId\x18\x02 \x01(\x05R\bserverId\x12\x1e\n" + - "\n" + - "prettyName\x18\x03 \x01(\tR\n" + - "prettyName\x12\x1e\n" + - "\n" + - "moduleName\x18\x04 \x01(\tR\n" + - "moduleName\x12,\n" + - "\x11moduleDescription\x18\x05 \x01(\tR\x11moduleDescription\x12\"\n" + - "\fmoduleActive\x18\x06 \x01(\bR\fmoduleActive\x12\x1e\n" + - "\n" + - "moduleIcon\x18\a \x01(\tR\n" + - "moduleIcon\x12&\n" + - "\x0emoduleCategory\x18\b \x01(\tR\x0emoduleCategory\x12 \n" + - "\vliteVersion\x18\t \x01(\bR\vliteVersion\x12\"\n" + - "\fneedsRestart\x18\n" + - " \x01(\bR\fneedsRestart\x127\n" + - "\fmoduleGroups\x18\v \x03(\v2\x13.config.ModuleGroupR\fmoduleGroups\x12 \n" + - "\vactivatable\x18\f \x01(\bR\vactivatable*r\n" + - "\n" + - "PluginType\x12\v\n" + - "\aUNKNOWN\x10\x00\x12\x10\n" + - "\fAWS_IAM_USER\x10\x01\x12\t\n" + - "\x05AZURE\x10\x02\x12\x0f\n" + - "\vBITDEFENDER\x10\x03\x12\a\n" + - "\x03GCP\x10\x04\x12\b\n" + - "\x04O365\x10\x05\x12\n" + - "\n" + - "\x06SOC_AI\x10\x06\x12\n" + - "\n" + - "\x06SOPHOS\x10\a2_\n" + - "\rConfigService\x12N\n" + - "\fStreamConfig\x12\x1c.config.BiDirectionalMessage\x1a\x1c.config.BiDirectionalMessage(\x010\x01B