Skip to content

Commit 78877fb

Browse files
committed
Merge remote-tracking branch 'origin/bugfix/10.8.0/macos' into bugfix/10.8.0/macos
2 parents 2027f04 + 4a7c819 commit 78877fb

File tree

34 files changed

+1759
-14
lines changed

34 files changed

+1759
-14
lines changed

.github/workflows/principal-multi-env.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ jobs:
8888
strategy:
8989
fail-fast: false
9090
matrix:
91-
service: ['aws', 'backend', 'correlation', 'frontend', 'bitdefender', 'mutate', 'office365', 'log-auth-proxy', 'sophos', 'user-auditor', 'web-pdf']
91+
service: ['aws', 'backend', 'correlation', 'frontend', 'bitdefender', 'mutate', 'office365', 'log-auth-proxy', 'soc-ai', 'sophos', 'user-auditor', 'web-pdf']
9292
uses: ./.github/workflows/used-runner.yml
9393
with:
9494
microservice: ${{ matrix.service }}

.github/workflows/used-runner.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
id: get_tech
2323
run: |
2424
folder_changed="${{inputs.microservice}}"
25-
if [[ "$folder_changed" == "aws" || "$folder_changed" == "correlation" || "$folder_changed" == "bitdefender" || "$folder_changed" == "office365" || "$folder_changed" == "sophos" || "$folder_changed" == "log-auth-proxy" ]]; then
25+
if [[ "$folder_changed" == "aws" || "$folder_changed" == "correlation" || "$folder_changed" == "bitdefender" || "$folder_changed" == "office365" || "$folder_changed" == "soc-ai" || "$folder_changed" == "sophos" || "$folder_changed" == "log-auth-proxy" ]]; then
2626
tech="golang"
2727
elif [[ "$folder_changed" == "backend" ]]; then
2828
tech="java-11"

CHANGELOG.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# UTMStack 10.7.3 Release Notes
2-
-- Implemented backend support for filtering compliance reports based on active integrations, optimizing query performance and data retrieval.
3-
-- Introduced new compliance reports aligned with the PCI DSS standard to expand auditing capabilities.
4-
-- Added support for creating and updating tag-based rules with dynamic conditions.
5-
6-
### Bug Fixes
7-
-- Improved exception handling in `automaticReview` to prevent the process from stopping due to errors, ensuring the system continues evaluating alerts even if a specific rule fails.
8-
-- Improved operator selection for more accurate and consistent filtering.
1+
# UTMStack 10.8.0 Release Notes
2+
- Updated Soc-AI models and released the code as open source.
3+
- Added the ability for users to choose which model to use with Soc-AI.
4+
- Enhanced the prompt sent to OpenAI by including additional contextual details.
5+
- Added support for RedHat; UTMStack can now be installed on both Ubuntu and RedHat.
6+
- Improved log delivery from ARM-based agents on Windows, now sending native system logs.
7+
- Added support for macOS ARM64; agents can now be installed on that platform.
8+
- Improved agent information displayed in the Sources panel, providing more accurate OS details and agent versions.

correlation/cache/operators.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ func compare(operator, val1, val2 string) bool {
8888
return !lowerEqual(val1, val2)
8989
case "contains":
9090
return contain(val1, val2)
91-
case "not contain":
91+
case "not contain", "not contains":
9292
return !contain(val1, val2)
9393
case "in":
9494
return in(val1, val2)

frontend/src/app/shared/components/utm/util/utm-agent-detail/utm-agent-detail.component.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,13 @@
5656
<app-assets-apply-note *ngIf="asset" [asset]="asset" class="ml-2"></app-assets-apply-note>
5757
</div>
5858
<div class="agent-details w-100 d-flex justify-content-start mb-2" *ngIf="agent.version">
59-
<span class="text-blue-800 font-weight-light has-minimum-width">OS Version:</span>&nbsp;
59+
<span class="text-blue-800 font-weight-light has-minimum-width">Agent Version:</span>&nbsp;
6060
{{agent.version}}
6161
</div>
62+
<div class="agent-details w-100 d-flex justify-content-start mb-2" *ngIf="agent.osMajorVersion && agent.osMinorVersion">
63+
<span class="text-blue-800 font-weight-light has-minimum-width">OS Version:</span>&nbsp;
64+
{{agent.osMajorVersion + '.' + agent.osMinorVersion}}
65+
</div>
6266
<div class="agent-details w-100 d-flex justify-content-start mb-2" *ngIf="agent.lastSeen">
6367
<span class="text-blue-800 font-weight-light has-minimum-width">Last seen:</span>&nbsp;
6468
{{agent.lastSeen}}

installer/types/compose.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ func (c *Compose) Populate(conf *Config, stack *StackConfig) *Compose {
507507

508508
socAIMem := stack.ServiceResources["socai"].AssignedMemory
509509
c.Services["socai"] = Service{
510-
Image: utils.Str("ghcr.io/utmstack/soc-ai/soc-ai:" + conf.Branch),
510+
Image: utils.Str("ghcr.io/utmstack/utmstack/soc-ai:" + conf.Branch),
511511
DependsOn: []string{
512512
"node1",
513513
"backend",

installer/utils/os.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ func CreatePathIfNotExist(path string) error {
4949
}
5050

5151
func WriteToFile(fileName string, body string) error {
52+
filePath := filepath.Dir(fileName)
53+
if err := CreatePathIfNotExist(filePath); err != nil {
54+
return fmt.Errorf("error creating directory for file %s: %v", fileName, err)
55+
}
56+
5257
file, err := os.OpenFile(fileName, os.O_CREATE|os.O_RDWR|os.O_TRUNC, os.ModePerm)
5358

5459
if err != nil {

soc-ai/Dockerfile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
FROM ubuntu:24.04
2+
3+
COPY soc-ai /app/
4+
5+
RUN apt-get update && \
6+
apt-get install -y ca-certificates jq wget && \
7+
update-ca-certificates && \
8+
apt-get clean && \
9+
rm -rf /var/lib/apt/lists/*
10+
11+
EXPOSE 8080
12+
13+
CMD ["/app/soc-ai"]

soc-ai/configurations/config.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package configurations
2+
3+
import (
4+
"time"
5+
6+
UTMStackConfigurationClient "github.com/utmstack/config-client-go"
7+
"github.com/utmstack/config-client-go/enum"
8+
"github.com/utmstack/soc-ai/utils"
9+
)
10+
11+
var (
12+
gptConfig GPTConfig
13+
)
14+
15+
type GPTConfig struct {
16+
APIKey string
17+
ChangeAlertStatus bool
18+
AutomaticIncidentCreation bool
19+
Model string
20+
ModuleActive bool
21+
}
22+
23+
func GetGPTConfig() *GPTConfig {
24+
return &gptConfig
25+
}
26+
27+
func UpdateGPTConfigurations() {
28+
intKey := GetInternalKey()
29+
panelServ := GetPanelServiceName()
30+
client := UTMStackConfigurationClient.NewUTMClient(intKey, panelServ)
31+
32+
for {
33+
if err := utils.ConnectionChecker(GPT_API_ENDPOINT); err != nil {
34+
utils.Logger.ErrorF("Failed to establish internet connection: %v", err)
35+
}
36+
37+
tempModuleConfig, err := client.GetUTMConfig(enum.SOCAI)
38+
if err != nil && err.Error() != "" && err.Error() != " " {
39+
utils.Logger.LogF(100, "Error while getting GPT configuration: %v", err)
40+
time.Sleep(TIME_FOR_GET_CONFIG * time.Second)
41+
continue
42+
}
43+
44+
gptConfig.ModuleActive = tempModuleConfig.ModuleActive
45+
46+
if gptConfig.ModuleActive && tempModuleConfig != nil && len(tempModuleConfig.ConfigurationGroups) > 0 {
47+
for _, config := range tempModuleConfig.ConfigurationGroups[0].Configurations {
48+
switch config.ConfKey {
49+
case "utmstack.socai.key":
50+
if config.ConfValue != "" && config.ConfValue != " " {
51+
gptConfig.APIKey = config.ConfValue
52+
}
53+
case "utmstack.socai.incidentCreation":
54+
if config.ConfValue != "" && config.ConfValue != " " {
55+
gptConfig.AutomaticIncidentCreation = config.ConfValue == "true"
56+
}
57+
case "utmstack.socai.changeAlertStatus":
58+
if config.ConfValue != "" && config.ConfValue != " " {
59+
gptConfig.ChangeAlertStatus = config.ConfValue == "true"
60+
}
61+
case "utmstack.socai.model":
62+
if config.ConfValue != "" && config.ConfValue != " " {
63+
gptConfig.Model = config.ConfValue
64+
}
65+
}
66+
}
67+
}
68+
69+
time.Sleep(TIME_FOR_GET_CONFIG * time.Second)
70+
}
71+
}

soc-ai/configurations/const.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package configurations
2+
3+
import (
4+
"path/filepath"
5+
6+
"github.com/utmstack/soc-ai/utils"
7+
)
8+
9+
const (
10+
SOC_AI_SERVER_PORT = "8080"
11+
SOC_AI_SERVER_ENDPOINT = "/process"
12+
API_ALERT_ENDPOINT = "/api/elasticsearch/search"
13+
API_ALERT_STATUS_ENDPOINT = "/api/utm-alerts/status"
14+
API_INCIDENT_ENDPOINT = "/api/utm-incidents"
15+
API_INCIDENT_ADD_NEW_ALERT_ENDPOINT = "/api/utm-incidents/add-alerts"
16+
API_ALERT_COMPLETED_STATUS_CODE = 5
17+
API_ALERT_INFO_PARAMS = "?page=0&size=25&top=10000&indexPattern="
18+
ELASTIC_DOC_ENDPOINT = "/_doc/"
19+
ELASTIC_UPDATE_BY_QUERY_ENDPOINT = "/_update_by_query"
20+
ALERT_INDEX_PATTERN = "alert-*"
21+
LOGS_INDEX_PATTERN = "log-*"
22+
SOC_AI_INDEX = "soc-ai"
23+
GPT_API_ENDPOINT = "https://api.openai.com/v1/chat/completions"
24+
TIME_FOR_GET_CONFIG = 10
25+
CLEANER_DELAY = 10
26+
MAX_ATTEMPS_TO_GPT = 3
27+
GPT_RESPONSE_TOKENS = 10
28+
HTTP_GPT_TIMEOUT = 90
29+
HTTP_TIMEOUT = 30
30+
LOGS_SEPARATOR = "[utm-logs-separator]"
31+
)
32+
33+
var (
34+
AllowedGPTModels = map[string]int{
35+
"gpt-4.1": 1047576,
36+
"gpt-4.1-mini": 1047576,
37+
"gpt-4.1-nano": 1047576,
38+
"gpt-4o": 128000,
39+
"gpt-4o-mini": 128000,
40+
"gpt-4-turbo": 128000,
41+
"gpt-4-0614": 8192,
42+
"gpt-4-0125-preview": 128000,
43+
"gpt-3.5-turbo": 16385,
44+
"gpt-3.5-turbo-instruct": 4096,
45+
"gpt-3.5-turbo-1106": 16385,
46+
"o1": 200000,
47+
"o1-pro": 200000,
48+
"o3": 200000,
49+
"o3-mini": 200000,
50+
"o4-mini": 200000,
51+
// "gpt-4-0314": 8192, // Removed 2024-06-13
52+
// "gpt-4-1106-preview": 128000, // Removed 2024-12-06
53+
}
54+
)
55+
56+
type SensitivePattern struct {
57+
Regexp string
58+
FakeValue string
59+
}
60+
61+
var (
62+
SensitivePatterns = map[string]SensitivePattern{
63+
"email": {Regexp: `([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})`, FakeValue: "[email protected]"},
64+
//"ipv4": `(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)`,
65+
}
66+
GPT_INSTRUCTION = "You are an expert security engineer. Perform a deep analysis of an alert created by a SIEM and the logs related to it. Determine if the alert could be an actual potential threat or not and explain why. Provide a description that shows a deep understanding of the alert based on a deep analysis of its logs and estimate the risk to the systems affected. Classify the alert in the following manner: if the alert information is sufficient to determine that the security, availability, confidentiality, or integrity of the systems has being compromised, then classify it as \"possible incident\". If the alert does not pose a security risk to the organization or has no security relevance, classify it as \"possible false positive\". If the alert does not pose an imminent risk to the systems, requires no urgent action from an administrator, or requires not urgent review by an administrator, it should be classified as a \"standard alert\". You will also provide context-specific instructions for remediation, mitigation, or further investigation, related to the alert and logs analyzed. Your answer should be provided using the following JSON format and the total number of characters in your answer must not exceed 1500 words. Your entire answer must be inside this json format. {\"activity_id\":\"<activity_id>\",\"classification\":\"<classification>\",\"reasoning\":[\"<deep_reasoning>\"],\"nextSteps\":[{\"step\":1,\"action\":\"<action_1>\",\"details\":\"<action_1_details>\"},{\"step\":2,\"action\":\"<action_2>\",\"details\":\"<action_2_details>\"},{\"step\":3,\"action\":\"<action_3>\"]}Ensure that your entire answer adheres to the provided JSON format. The response should be valid JSON syntax and schema."
67+
GPT_FALSE_POSITIVE = "This alert is categorized as a potential false positive due to two key factors. Firstly, it originates from an automated system, which may occasionally produce alerts without direct human validation. Additionally, the absence of any correlated logs further raises suspicion, as a genuine incident typically leaves a trail of relevant log entries. Hence, the combination of its system-generated nature and the lack of associated logs suggests a likelihood of being a false positive rather than a genuine security incident."
68+
)
69+
70+
func GetInternalKey() string {
71+
return utils.Getenv("INTERNAL_KEY", true)
72+
}
73+
74+
func GetPanelServiceName() string {
75+
return utils.Getenv("PANEL_SERV_NAME", true)
76+
}
77+
78+
func GetOpenSearchHost() string {
79+
return "http://" + utils.Getenv("OPENSEARCH_HOST", true)
80+
}
81+
82+
func GetOpenSearchPort() string {
83+
return utils.Getenv("OPENSEARCH_PORT", true)
84+
}
85+
86+
func GetAlertsDBPath() string {
87+
path, _ := utils.GetMyPath()
88+
return filepath.Join(path, "database", "alerts.sqlite3")
89+
}

0 commit comments

Comments
 (0)