diff --git a/.github/coverage/coverage.txt b/.github/coverage/coverage.txt index a9737a5..d0df953 100644 --- a/.github/coverage/coverage.txt +++ b/.github/coverage/coverage.txt @@ -1,13 +1,13 @@ -ok github.com/0xrawsec/whids/agent 33.040s coverage: 51.2% of statements -ok github.com/0xrawsec/whids/agent/config 2.687s coverage: 46.1% of statements -ok github.com/0xrawsec/whids/agent/sysinfo 0.513s coverage: 95.2% of statements -ok github.com/0xrawsec/whids/api/server 177.947s coverage: 67.5% of statements -ok github.com/0xrawsec/whids/event 60.746s coverage: 75.3% of statements -ok github.com/0xrawsec/whids/ioc 19.264s coverage: 73.3% of statements -ok github.com/0xrawsec/whids/logger 51.520s coverage: 76.7% of statements -ok github.com/0xrawsec/whids/sysmon 5.931s coverage: 83.1% of statements -ok github.com/0xrawsec/whids/utils 11.039s coverage: 18.1% of statements -ok github.com/0xrawsec/whids/utils/command 0.795s coverage: 100.0% of statements +ok github.com/0xrawsec/whids/agent 39.337s coverage: 51.0% of statements +ok github.com/0xrawsec/whids/agent/config 2.372s coverage: 46.1% of statements +ok github.com/0xrawsec/whids/agent/sysinfo 0.564s coverage: 95.2% of statements +ok github.com/0xrawsec/whids/api/server 181.937s coverage: 68.0% of statements +ok github.com/0xrawsec/whids/event 61.293s coverage: 75.3% of statements +ok github.com/0xrawsec/whids/ioc 19.730s coverage: 73.3% of statements +ok github.com/0xrawsec/whids/logger 47.841s coverage: 76.7% of statements +ok github.com/0xrawsec/whids/sysmon 6.139s coverage: 83.1% of statements +ok github.com/0xrawsec/whids/utils 11.080s coverage: 17.4% of statements +ok github.com/0xrawsec/whids/utils/command 0.637s coverage: 100.0% of statements github.com/0xrawsec/whids/agent/actions.go:72: NewActionHandler 100.0% github.com/0xrawsec/whids/agent/actions.go:81: dumpname 100.0% github.com/0xrawsec/whids/agent/actions.go:86: prepare 100.0% @@ -17,10 +17,10 @@ github.com/0xrawsec/whids/agent/actions.go:104: dumpAsJson 66.7% github.com/0xrawsec/whids/agent/actions.go:117: dumpBinFile 100.0% github.com/0xrawsec/whids/agent/actions.go:121: dumpFile 77.8% github.com/0xrawsec/whids/agent/actions.go:156: listFilesFromCommandLine 100.0% -github.com/0xrawsec/whids/agent/actions.go:179: filedumpSet 81.5% +github.com/0xrawsec/whids/agent/actions.go:179: filedumpSet 48.1% github.com/0xrawsec/whids/agent/actions.go:232: filedump 80.0% github.com/0xrawsec/whids/agent/actions.go:242: memdump 0.0% -github.com/0xrawsec/whids/agent/actions.go:271: regdump 46.7% +github.com/0xrawsec/whids/agent/actions.go:271: regdump 26.7% github.com/0xrawsec/whids/agent/actions.go:302: suspend_process 0.0% github.com/0xrawsec/whids/agent/actions.go:312: kill_process 0.0% github.com/0xrawsec/whids/agent/actions.go:325: Queue 100.0% @@ -76,10 +76,10 @@ github.com/0xrawsec/whids/agent/config/canary_windows.go:247: Clean 80.0% github.com/0xrawsec/whids/agent/config/config.go:59: RulesPaths 0.0% github.com/0xrawsec/whids/agent/config/config.go:73: Configure 0.0% github.com/0xrawsec/whids/agent/config/config.go:99: Restore 0.0% -github.com/0xrawsec/whids/agent/config/config.go:134: LoadsHIDSConfig 0.0% -github.com/0xrawsec/whids/agent/config/config.go:146: IsForwardingEnabled 0.0% -github.com/0xrawsec/whids/agent/config/config.go:151: Prepare 0.0% -github.com/0xrawsec/whids/agent/config/config.go:170: Verify 0.0% +github.com/0xrawsec/whids/agent/config/config.go:133: LoadsHIDSConfig 0.0% +github.com/0xrawsec/whids/agent/config/config.go:145: IsForwardingEnabled 0.0% +github.com/0xrawsec/whids/agent/config/config.go:150: Prepare 0.0% +github.com/0xrawsec/whids/agent/config/config.go:169: Verify 0.0% github.com/0xrawsec/whids/agent/config/etw_windows.go:36: ConfigureAutologger 62.5% github.com/0xrawsec/whids/agent/config/etw_windows.go:55: UnifiedProviders 75.0% github.com/0xrawsec/whids/agent/config/etw_windows.go:69: UnifiedTraces 0.0% @@ -101,7 +101,7 @@ github.com/0xrawsec/whids/agent/hookdefs.go:39: hookSetImageSize 82.4% github.com/0xrawsec/whids/agent/hookdefs.go:71: hookImageLoad 95.0% github.com/0xrawsec/whids/agent/hookdefs.go:108: trackSysmonProcessCreate 62.7% github.com/0xrawsec/whids/agent/hookdefs.go:229: hookTrack 50.0% -github.com/0xrawsec/whids/agent/hookdefs.go:242: hookStats 90.9% +github.com/0xrawsec/whids/agent/hookdefs.go:242: hookStats 98.2% github.com/0xrawsec/whids/agent/hookdefs.go:353: hookUpdateGeneScore 0.0% github.com/0xrawsec/whids/agent/hookdefs.go:370: hookTerminator 76.9% github.com/0xrawsec/whids/agent/hookdefs.go:398: hookProcTerm 87.5% @@ -131,7 +131,7 @@ github.com/0xrawsec/whids/agent/iocs.go:32: ruleDomainIoC 100.0% github.com/0xrawsec/whids/agent/paths.go:11: EventDataPath 100.0% github.com/0xrawsec/whids/agent/ptrack.go:41: NewProcStats 100.0% github.com/0xrawsec/whids/agent/ptrack.go:52: UpdateNetResolve 100.0% -github.com/0xrawsec/whids/agent/ptrack.go:61: UpdateCon 0.0% +github.com/0xrawsec/whids/agent/ptrack.go:61: UpdateCon 100.0% github.com/0xrawsec/whids/agent/ptrack.go:71: ConStat 100.0% github.com/0xrawsec/whids/agent/ptrack.go:83: NewGeneScore 100.0% github.com/0xrawsec/whids/agent/ptrack.go:87: Update 0.0% @@ -182,10 +182,11 @@ github.com/0xrawsec/whids/agent/stats.go:69: Detections 0.0% github.com/0xrawsec/whids/agent/stats.go:73: EPS 0.0% github.com/0xrawsec/whids/agent/stats.go:81: CriticalEPS 0.0% github.com/0xrawsec/whids/agent/stats.go:85: DynEPS 75.0% -github.com/0xrawsec/whids/agent/stats.go:93: HasPerfIssue 38.5% +github.com/0xrawsec/whids/agent/stats.go:93: HasPerfIssue 30.8% github.com/0xrawsec/whids/agent/stats.go:113: HasCriticalPerfIssue 0.0% github.com/0xrawsec/whids/agent/sysinfo/sysinfo.go:15: RegisterEdrInfo 0.0% github.com/0xrawsec/whids/agent/sysinfo/windows_sysinfo.go:31: NewSystemInfo 100.0% +github.com/0xrawsec/whids/api/server/command.go:18: ToCommand 77.8% github.com/0xrawsec/whids/api/server/log_streamer.go:18: Queue 75.0% github.com/0xrawsec/whids/api/server/log_streamer.go:26: Stream 100.0% github.com/0xrawsec/whids/api/server/log_streamer.go:40: Close 0.0% @@ -221,45 +222,45 @@ github.com/0xrawsec/whids/api/server/manager.go:511: Wait 100.0% github.com/0xrawsec/whids/api/server/manager.go:516: IsDone 0.0% github.com/0xrawsec/whids/api/server/manager.go:521: Shutdown 82.4% github.com/0xrawsec/whids/api/server/manager.go:550: Run 100.0% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:42: admApiParseDuration 71.4% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:55: admApiParseTime 66.7% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:79: NewAdminAPIResponse 100.0% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:84: NewAdminAPIRespError 0.0% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:89: NewAdminAPIRespErrorString 0.0% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:94: UnmarshalData 75.0% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:103: ToJSON 50.0% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:114: Err 66.7% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:121: admErr 0.0% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:125: admJSONResp 100.0% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:135: adminAuthorizationMiddleware 66.7% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:151: admLogHTTPMiddleware 100.0% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:159: adminRespHeaderMiddleware 100.0% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:169: admAPIUsers 54.8% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:237: admAPIUser 59.4% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:298: admAPIEndpoints 81.5% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:349: admAPIEndpoint 76.5% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:430: ToCommand 77.8% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:452: admAPIEndpointCommand 74.1% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:508: admAPIEndpointCommandField 52.9% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:545: admAPIEndpointLogs 70.7% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:685: admAPIEndpointReport 78.9% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:725: admAPIEndpointReportArchive 67.4% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:800: admAPIEndpointsReports 83.3% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:827: listEndpointDumps 80.6% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:894: admAPIArtifacts 61.1% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:925: admAPIEndpointArtifacts 61.1% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:956: admAPIEndpointArtifact 62.9% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:1022: admAPIEndpointSysmonConfig 65.7% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:1095: admAPIEndpointToolMgmt 66.7% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:1182: admAPIEndpointSysmonBinary 100.0% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:1186: admAPIEndpointOSQueryiBinary 100.0% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:1195: admAPIStats 75.0% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:1207: admAPIIocs 62.1% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:1329: admAPIRules 58.8% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:1435: wsHandleControlMessage 100.0% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:1445: admAPIStreamEvents 71.4% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:1468: admAPIStreamDetections 0.0% -github.com/0xrawsec/whids/api/server/manager_admin_api.go:1493: runAdminAPI 87.5% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:43: admApiParseDuration 71.4% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:56: admApiParseTime 66.7% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:80: NewAdminAPIResponse 100.0% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:85: NewAdminAPIRespError 0.0% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:90: NewAdminAPIRespErrorString 0.0% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:95: UnmarshalData 75.0% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:104: ToJSON 50.0% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:115: Err 66.7% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:122: admErr 0.0% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:126: admJSONResp 100.0% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:136: adminAuthorizationMiddleware 66.7% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:152: admLogHTTPMiddleware 100.0% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:160: adminRespHeaderMiddleware 100.0% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:170: admAPIUsers 54.8% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:238: admAPIUser 59.4% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:299: admAPIEndpoints 82.1% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:352: admAPIEndpoint 77.8% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:429: admAPIEndpointConfig 78.8% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:496: admAPIEndpointCommand 74.1% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:552: admAPIEndpointCommandField 52.9% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:589: admAPIEndpointLogs 70.7% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:729: admAPIEndpointReport 78.9% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:769: admAPIEndpointReportArchive 67.4% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:844: admAPIEndpointsReports 83.3% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:871: listEndpointDumps 80.6% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:938: admAPIArtifacts 61.1% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:969: admAPIEndpointArtifacts 61.1% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:1000: admAPIEndpointArtifact 62.9% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:1066: admAPIEndpointSysmonConfig 65.7% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:1139: admAPIEndpointToolMgmt 66.7% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:1226: admAPIEndpointSysmonBinary 100.0% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:1230: admAPIEndpointOSQueryiBinary 100.0% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:1239: admAPIStats 75.0% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:1251: admAPIIocs 62.1% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:1373: admAPIRules 58.8% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:1479: wsHandleControlMessage 100.0% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:1489: admAPIStreamEvents 71.4% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:1512: admAPIStreamDetections 0.0% +github.com/0xrawsec/whids/api/server/manager_admin_api.go:1537: runAdminAPI 87.8% github.com/0xrawsec/whids/api/server/manager_endpoint_api.go:33: eptAPIMutEndpointFromRequest 75.0% github.com/0xrawsec/whids/api/server/manager_endpoint_api.go:43: endpointAuthorizationMiddleware 65.2% github.com/0xrawsec/whids/api/server/manager_endpoint_api.go:86: isVerboseURL 100.0% @@ -273,15 +274,16 @@ github.com/0xrawsec/whids/api/server/manager_endpoint_api.go:200: eptAPIIoCs 5 github.com/0xrawsec/whids/api/server/manager_endpoint_api.go:209: eptAPIIoCsSha256 100.0% github.com/0xrawsec/whids/api/server/manager_endpoint_api.go:214: eptAPIUploadDump 44.4% github.com/0xrawsec/whids/api/server/manager_endpoint_api.go:247: eptAPICollect 86.0% -github.com/0xrawsec/whids/api/server/manager_endpoint_api.go:330: eptAPICommand 75.9% +github.com/0xrawsec/whids/api/server/manager_endpoint_api.go:330: eptAPICommand 79.3% github.com/0xrawsec/whids/api/server/manager_endpoint_api.go:386: eptAPISystemInfo 70.0% github.com/0xrawsec/whids/api/server/manager_endpoint_api.go:405: eptAPISysmonConfig 87.5% github.com/0xrawsec/whids/api/server/manager_endpoint_api.go:422: eptAPISysmonConfigSha256 100.0% github.com/0xrawsec/whids/api/server/manager_endpoint_api.go:435: eptAPITools 0.0% -github.com/0xrawsec/whids/api/server/utils.go:13: muxGetVar 75.0% -github.com/0xrawsec/whids/api/server/utils.go:21: format 100.0% -github.com/0xrawsec/whids/api/server/utils.go:26: readPostAsJSON 80.0% -github.com/0xrawsec/whids/api/server/utils.go:35: readPostAsXML 80.0% +github.com/0xrawsec/whids/api/server/utils.go:14: muxGetVar 75.0% +github.com/0xrawsec/whids/api/server/utils.go:22: format 100.0% +github.com/0xrawsec/whids/api/server/utils.go:27: readPostAsJSON 80.0% +github.com/0xrawsec/whids/api/server/utils.go:36: readPostAsTOML 80.0% +github.com/0xrawsec/whids/api/server/utils.go:45: readPostAsXML 80.0% github.com/0xrawsec/whids/event/event.go:38: NewEdrEvent 100.0% github.com/0xrawsec/whids/event/event.go:42: InitEdrData 100.0% github.com/0xrawsec/whids/event/event.go:46: Hash 100.0% @@ -430,24 +432,26 @@ github.com/0xrawsec/whids/utils/net.go:6: NextIP 0.0% github.com/0xrawsec/whids/utils/net.go:19: PrevIP 0.0% github.com/0xrawsec/whids/utils/rand.go:10: UnsafeUUIDGen 100.0% github.com/0xrawsec/whids/utils/rand.go:19: UnsafeKeyGen 0.0% -github.com/0xrawsec/whids/utils/utils.go:29: IsValidUUID 100.0% -github.com/0xrawsec/whids/utils/utils.go:34: PrettyJson 0.0% -github.com/0xrawsec/whids/utils/utils.go:42: Json 0.0% -github.com/0xrawsec/whids/utils/utils.go:51: JsonString 0.0% -github.com/0xrawsec/whids/utils/utils.go:57: ExpandEnvs 0.0% -github.com/0xrawsec/whids/utils/utils.go:66: Sha256StringArray 0.0% -github.com/0xrawsec/whids/utils/utils.go:76: HashEventBytes 0.0% -github.com/0xrawsec/whids/utils/utils.go:81: HashInterface 0.0% -github.com/0xrawsec/whids/utils/utils.go:91: GetCurFuncName 0.0% -github.com/0xrawsec/whids/utils/utils.go:119: NewWindowsLogger 0.0% -github.com/0xrawsec/whids/utils/utils.go:132: Log 0.0% -github.com/0xrawsec/whids/utils/utils.go:143: Close 0.0% -github.com/0xrawsec/whids/utils/utils.go:152: Round 0.0% -github.com/0xrawsec/whids/utils/utils.go:158: RegQuery 0.0% -github.com/0xrawsec/whids/utils/utils.go:170: Utf16ToUtf8 0.0% -github.com/0xrawsec/whids/utils/utils.go:202: Len 0.0% -github.com/0xrawsec/whids/utils/utils.go:206: Swap 0.0% -github.com/0xrawsec/whids/utils/utils.go:212: Less 0.0% +github.com/0xrawsec/whids/utils/utils.go:30: IsValidUUID 100.0% +github.com/0xrawsec/whids/utils/utils.go:35: PrettyJson 0.0% +github.com/0xrawsec/whids/utils/utils.go:43: Json 0.0% +github.com/0xrawsec/whids/utils/utils.go:52: JsonString 0.0% +github.com/0xrawsec/whids/utils/utils.go:56: Toml 0.0% +github.com/0xrawsec/whids/utils/utils.go:67: TomlString 0.0% +github.com/0xrawsec/whids/utils/utils.go:76: ExpandEnvs 0.0% +github.com/0xrawsec/whids/utils/utils.go:85: Sha256StringArray 0.0% +github.com/0xrawsec/whids/utils/utils.go:95: HashEventBytes 0.0% +github.com/0xrawsec/whids/utils/utils.go:100: HashInterface 0.0% +github.com/0xrawsec/whids/utils/utils.go:110: GetCurFuncName 0.0% +github.com/0xrawsec/whids/utils/utils.go:138: NewWindowsLogger 0.0% +github.com/0xrawsec/whids/utils/utils.go:151: Log 0.0% +github.com/0xrawsec/whids/utils/utils.go:162: Close 0.0% +github.com/0xrawsec/whids/utils/utils.go:171: Round 0.0% +github.com/0xrawsec/whids/utils/utils.go:177: RegQuery 0.0% +github.com/0xrawsec/whids/utils/utils.go:189: Utf16ToUtf8 0.0% +github.com/0xrawsec/whids/utils/utils.go:221: Len 0.0% +github.com/0xrawsec/whids/utils/utils.go:225: Swap 0.0% +github.com/0xrawsec/whids/utils/utils.go:231: Less 0.0% github.com/0xrawsec/whids/utils/windows.go:22: ArgvFromCommandLine 0.0% github.com/0xrawsec/whids/utils/windows.go:41: HideFile 0.0% github.com/0xrawsec/whids/utils/windows.go:53: ResolveCDrive 0.0% diff --git a/agent/agent.go b/agent/agent.go index 41541a5..66a5cd4 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -167,7 +167,7 @@ func NewAgent(c *config.Agent) (h *Agent, err error) { } // loading forwarder config - if h.forwarder, err = client.NewForwarder(h.ctx, h.config.FwdConfig); err != nil { + if h.forwarder, err = client.NewForwarder(h.ctx, &h.config.FwdConfig); err != nil { return } diff --git a/agent/config/canary.go b/agent/config/canary.go index 3135e82..325732d 100644 --- a/agent/config/canary.go +++ b/agent/config/canary.go @@ -6,19 +6,19 @@ import ( // Canary configuration type Canary struct { - HideFiles bool `toml:"hide-files" comment:"Flag to set to hide files"` - HideDirectories bool `toml:"hide-dirs" comment:"Flag to set to hide directories"` - SetAuditACL bool `toml:"set-audit-acl" comment:"Set Audit ACL to the canary directories, sub-directories and files to generate File System audit events\n https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/audit-file-system"` - Directories []string `toml:"directories" comment:"Directories where canary files will be created"` - Files []string `toml:"files" comment:"Canary files to monitor. Files will be created if not existing"` - Delete bool `toml:"delete" comment:"Whether to delete or not the canary files when service stops"` + HideFiles bool `json:"hide-files" toml:"hide-files" comment:"Flag to set to hide files"` + HideDirectories bool `json:"hide-dirs" toml:"hide-dirs" comment:"Flag to set to hide directories"` + SetAuditACL bool `json:"set-audit-acl" toml:"set-audit-acl" comment:"Set Audit ACL to the canary directories, sub-directories and files to generate File System audit events\n https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/audit-file-system"` + Directories []string `json:"directories" toml:"directories" comment:"Directories where canary files will be created"` + Files []string `json:"files" toml:"files" comment:"Canary files to monitor. Files will be created if not existing"` + Delete bool `json:"delete" toml:"delete" comment:"Whether to delete or not the canary files when service stops"` createdDir *datastructs.SyncedSet } // Canaries structure holding canary configuration type Canaries struct { - Enable bool `toml:"enable" comment:"Enable canary files management"` - Actions []string `toml:"actions" comment:"Actions to apply when a canary file is touched"` - Whitelist []string `toml:"whitelist" comment:"Process images being allowed to touch the canaries"` - Canaries []*Canary `toml:"group" comment:"Canary files to create at every run"` + Enable bool `json:"enable" toml:"enable" comment:"Enable canary files management"` + Actions []string `json:"actions" toml:"actions" comment:"Actions to apply when a canary file is touched"` + Whitelist []string `json:"whitelist" toml:"whitelist" comment:"Process images being allowed to touch the canaries"` + Canaries []*Canary `json:"group" toml:"group" comment:"Canary files to create at every run"` } diff --git a/agent/config/config.go b/agent/config/config.go index 9fd4713..8fe5dad 100644 --- a/agent/config/config.go +++ b/agent/config/config.go @@ -27,33 +27,33 @@ var ( ) type Actions struct { - AvailableActions []string `toml:"available-actions" commented:"true" comment:"List of available actions (here as a memo for easier configuration, but it is not used in any way by the engine)"` - Low []string `toml:"low" comment:"Default actions to be taken when event criticality is in [1; 4]"` - Medium []string `toml:"medium" comment:"Default actions to be taken when event criticality is in [5; 7]"` - High []string `toml:"high" comment:"Default actions to be taken when event criticality is in [8; 9]"` - Critical []string `toml:"critical" comment:"Default actions to be taken when event criticality is 10"` + AvailableActions []string `json:"available-actions" toml:"available-actions" commented:"true" comment:"List of available actions (here as a memo for easier configuration, but it is not used in any way by the engine)"` + Low []string `json:"low" toml:"low" comment:"Default actions to be taken when event criticality is in [1; 4]"` + Medium []string `json:"medium" toml:"medium" comment:"Default actions to be taken when event criticality is in [5; 7]"` + High []string `json:"high" toml:"high" comment:"Default actions to be taken when event criticality is in [8; 9]"` + Critical []string `json:"critical" toml:"critical" comment:"Default actions to be taken when event criticality is 10"` } // Dump structure definition type Dump struct { - Dir string `toml:"dir" comment:"Directory used to store dumps"` - MaxDumps int `toml:"max-dumps" comment:"Maximum number of dumps per process"` // maximum number of dump per GUID - Compression bool `toml:"compression" comment:"Enable dumps compression"` - DumpUntracked bool `toml:"dump-untracked" comment:"Dumps untracked process. Untracked processes are missing\n enrichment information and may generate unwanted dumps"` // whether or not we should dump untracked processes, if true it would create many FPs + Dir string `json:"dir" toml:"dir" comment:"Directory used to store dumps"` + MaxDumps int `json:"max-dumps" toml:"max-dumps" comment:"Maximum number of dumps per process"` // maximum number of dump per GUID + Compression bool `json:"compression" toml:"compression" comment:"Enable dumps compression"` + DumpUntracked bool `json:"dump-untracked" toml:"dump-untracked" comment:"Dumps untracked process. Untracked processes are missing\n enrichment information and may generate unwanted dumps"` // whether or not we should dump untracked processes, if true it would create many FPs } // Sysmon holds Sysmon related configuration type Sysmon struct { - Bin string `toml:"bin" comment:"Path to Sysmon binary"` - ArchiveDirectory string `toml:"archive-directory" comment:"Path to Sysmon Archive directory"` - CleanArchived bool `toml:"clean-archived" comment:"Delete files older than 5min archived by Sysmon"` + Bin string `json:"bin" toml:"bin" comment:"Path to Sysmon binary"` + ArchiveDirectory string `json:"archive-directory" toml:"archive-directory" comment:"Path to Sysmon Archive directory"` + CleanArchived bool `json:"clean-archived" toml:"clean-archived" comment:"Delete files older than 5min archived by Sysmon"` } // Rules holds rules configuration type Rules struct { - RulesDB string `toml:"rules-db" comment:"Path to Gene rules database"` - ContainersDB string `toml:"containers-db" comment:"Path to Gene rules containers\n (c.f. Gene documentation)"` - UpdateInterval time.Duration `toml:"update-interval" comment:"Update interval at which rules should be pulled from manager\n NB: only applies if a manager server is configured"` + RulesDB string `json:"rules-db" toml:"rules-db" comment:"Path to Gene rules database"` + ContainersDB string `json:"containers-db" toml:"containers-db" comment:"Path to Gene rules containers\n (c.f. Gene documentation)"` + UpdateInterval time.Duration `json:"update-interval" toml:"update-interval" comment:"Update interval at which rules should be pulled from manager\n NB: only applies if a manager server is configured"` } func (c *Rules) RulesPaths() (path, sha256Path string) { @@ -64,9 +64,9 @@ func (c *Rules) RulesPaths() (path, sha256Path string) { // Audit holds Windows audit configuration type Audit struct { - Enable bool `toml:"enable" comment:"Enable following Audit Policies or not"` - AuditPolicies []string `toml:"audit-policies" comment:"Audit Policies to enable (c.f. auditpol /get /category:* /r)"` - AuditDirs []string `toml:"audit-dirs" comment:"Set Audit ACL to directories, sub-directories and files to generate File System audit events\n https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/audit-file-system)"` + Enable bool `json:"enable" toml:"enable" comment:"Enable following Audit Policies or not"` + AuditPolicies []string `json:"audit-policies" toml:"audit-policies" comment:"Audit Policies to enable (c.f. auditpol /get /category:* /r)"` + AuditDirs []string `json:"audit-dirs" toml:"audit-dirs" comment:"Set Audit ACL to directories, sub-directories and files to generate File System audit events\n https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/audit-file-system)"` } // Configure configures the desired audit policies @@ -111,23 +111,22 @@ func (c *Audit) Restore() { // Agent structure type Agent struct { - //Channels []string `toml:"channels" comment:"Windows log channels to listen to. Either channel names\n can be used (i.e. Microsoft-Windows-Sysmon/Operational) or aliases"` - DatabasePath string `toml:"db-path" comment:"Path to local database root directory"` - CritTresh int `toml:"criticality-treshold" comment:"Dumps/forward only events above criticality threshold\n or filtered events (i.e. Gene filtering rules)"` - EnableHooks bool `toml:"en-hooks" comment:"Enable enrichment hooks and dump hooks"` - EnableFiltering bool `toml:"en-filters" comment:"Enable event filtering (log filtered events, not only alerts)\n See documentation: https://github.com/0xrawsec/gene"` - Logfile string `toml:"logfile" comment:"Logfile used to log messages generated by the engine"` // for WHIDS log messages (not alerts) - LogAll bool `toml:"log-all" comment:"Log any incoming event passing through the engine"` // log all events to logfile (used for debugging) - Endpoint bool `toml:"endpoint" comment:"True if current host is the endpoint on which logs are generated\n Example: turn this off if running on a WEC"` - EtwConfig *Etw `toml:"etw" comment:"ETW configuration"` - FwdConfig *config.Forwarder `toml:"forwarder" comment:"Forwarder configuration"` - Sysmon *Sysmon `toml:"sysmon" comment:"Sysmon related settings"` - Actions *Actions `toml:"actions" comment:"Default actions to apply to events, depending on their criticality"` - Dump *Dump `toml:"dump" comment:"Dump related settings"` - Report *Report `toml:"reporting" comment:"Reporting related settings"` - RulesConfig *Rules `toml:"rules" comment:"Gene rules related settings\n Gene repo: https://github.com/0xrawsec/gene\n Gene rules repo: https://github.com/0xrawsec/gene-rules"` - AuditConfig *Audit `toml:"audit" comment:"Windows auditing configuration"` - CanariesConfig *Canaries `toml:"canaries" comment:"Canary files configuration"` + DatabasePath string `json:"db-path" toml:"db-path" comment:"Path to local database root directory"` + CritTresh int `json:"criticality-treshold" toml:"criticality-treshold" comment:"Dumps/forward only events above criticality threshold\n or filtered events (i.e. Gene filtering rules)" ` + EnableHooks bool `json:"en-hooks" toml:"en-hooks" comment:"Enable enrichment hooks and dump hooks"` + EnableFiltering bool `json:"en-filters" toml:"en-filters" comment:"Enable event filtering (log filtered events, not only alerts)\n See documentation: https://github.com/0xrawsec/gene" ` + Logfile string `json:"logfile" toml:"logfile" comment:"Logfile used to log messages generated by the engine"` // for WHIDS log messages (not alerts) + LogAll bool `json:"log-all" toml:"log-all" comment:"Log any incoming event passing through the engine" ` // log all events to logfile (used for debugging) + Endpoint bool `json:"endpoint" toml:"endpoint" comment:"True if current host is the endpoint on which logs are generated\n Example: turn this off if running on a WEC"` + EtwConfig Etw `json:"etw" toml:"etw" comment:"ETW configuration"` + FwdConfig config.Forwarder `json:"forwarder" toml:"forwarder" comment:"Forwarder configuration"` + Sysmon Sysmon `json:"sysmon" toml:"sysmon" comment:"Sysmon related settings"` + Actions Actions `json:"actions" toml:"actions" comment:"Default actions to apply to events, depending on their criticality"` + Dump Dump `json:"dump" toml:"dump" comment:"Dump related settings"` + Report Report `json:"report" toml:"reporting" comment:"Reporting related settings"` + RulesConfig Rules `json:"rules" toml:"rules" comment:"Gene rules related settings\n Gene repo: https://github.com/0xrawsec/gene\n Gene rules repo: https://github.com/0xrawsec/gene-rules"` + AuditConfig Audit `json:"audit" toml:"audit" comment:"Windows auditing configuration"` + CanariesConfig Canaries `json:"canaries" toml:"canaries" comment:"Canary files configuration"` } // LoadsHIDSConfig loads a HIDS configuration from a file @@ -144,7 +143,7 @@ func LoadsHIDSConfig(path string) (c Agent, err error) { // IsForwardingEnabled returns true if a forwarder is actually configured to forward logs func (c *Agent) IsForwardingEnabled() bool { - return *c.FwdConfig != emptyForwarderConfig && !c.FwdConfig.Local + return c.FwdConfig != emptyForwarderConfig && !c.FwdConfig.Local } // Prepare creates directory used in the config if not existing diff --git a/agent/config/etw.go b/agent/config/etw.go index 0854eb9..f08337a 100644 --- a/agent/config/etw.go +++ b/agent/config/etw.go @@ -2,7 +2,7 @@ package config type Etw struct { // set as private not to support it officially as Microsoft-Windows-Kernel-File generates too many events - enTraceFile bool `toml:"trace-files" comment:"Enable file read/write events via an optimized Microsoft-Windows-Kernel-File provider"` - Providers []string `toml:"providers" comment:"ETW providers to enable in the EDR autologger setting"` - Traces []string `toml:"traces" comment:"Additional ETW traces to retrieve events"` + enTraceFile bool `json:"trace-files" toml:"trace-files" comment:"Enable file read/write events via an optimized Microsoft-Windows-Kernel-File provider"` + Providers []string `json:"providers" toml:"providers" comment:"ETW providers to enable in the EDR autologger setting"` + Traces []string `json:"traces" toml:"traces" comment:"Additional ETW traces to retrieve events"` } diff --git a/agent/config/reports.go b/agent/config/reports.go index 2d86c3f..d606d13 100644 --- a/agent/config/reports.go +++ b/agent/config/reports.go @@ -63,7 +63,7 @@ var ( // OSQuery holds configuration about OSQuery tool type OSQuery struct { - Tables []string `toml:"tables" comment:"OSQuery tables to add to the report"` + Tables []string `json:"tables" toml:"tables" comment:"OSQuery tables to add to the report"` } // PrepareCommands builds up osquery commands @@ -84,10 +84,10 @@ func (c *OSQuery) PrepareCommands() (cmds []ReportCommand) { // Report holds report configuration type Report struct { - EnableReporting bool `toml:"en-reporting" comment:"Enables IR reporting"` - OSQuery OSQuery `toml:"osquery" comment:"OSQuery configuration"` - Commands []ReportCommand `toml:"commands" comment:"Commands to execute in addition to the OSQuery ones" commented:"true"` - CommandTimeout time.Duration `toml:"timeout" comment:"Timeout after which every command expires (to prevent too long commands)"` + EnableReporting bool `json:"en-reporting" toml:"en-reporting" comment:"Enables IR reporting"` + OSQuery OSQuery `json:"osquery" toml:"osquery" comment:"OSQuery configuration"` + Commands []ReportCommand `json:"commands" toml:"commands" comment:"Commands to execute in addition to the OSQuery ones" commented:"true"` + CommandTimeout time.Duration `json:"timeout" toml:"timeout" comment:"Timeout after which every command expires (to prevent too long commands)"` } // PrepareCommands builds up all commands to run diff --git a/agent/defaults.go b/agent/defaults.go index 975c4d9..bcceaf0 100644 --- a/agent/defaults.go +++ b/agent/defaults.go @@ -14,13 +14,13 @@ func BuildDefaultConfig(root string) *config.Agent { logDir := filepath.Join(root, "Logs") return &config.Agent{ - RulesConfig: &config.Rules{ + RulesConfig: config.Rules{ RulesDB: filepath.Join(root, "Database", "Rules"), ContainersDB: filepath.Join(root, "Database", "Containers"), UpdateInterval: 60 * time.Second, }, - FwdConfig: &clientConfig.Forwarder{ + FwdConfig: clientConfig.Forwarder{ Local: true, Client: clientConfig.Client{ MaxUploadSize: api.DefaultMaxUploadSize, @@ -30,7 +30,7 @@ func BuildDefaultConfig(root string) *config.Agent { RotationInterval: time.Hour * 5, }, }, - EtwConfig: &config.Etw{ + EtwConfig: config.Etw{ Providers: []string{ "Microsoft-Windows-Sysmon", "Microsoft-Windows-Windows Defender", @@ -39,25 +39,25 @@ func BuildDefaultConfig(root string) *config.Agent { }, Traces: []string{"Eventlog-Security"}, }, - Sysmon: &config.Sysmon{ + Sysmon: config.Sysmon{ Bin: "C:\\Windows\\Sysmon64.exe", ArchiveDirectory: "C:\\Sysmon\\", CleanArchived: true, }, - Actions: &config.Actions{ + Actions: config.Actions{ AvailableActions: AvailableActions, Low: []string{}, Medium: []string{"brief", "filedump", "regdump"}, High: []string{"report", "filedump", "regdump"}, Critical: []string{"report", "filedump", "regdump", "memdump"}, }, - Dump: &config.Dump{ + Dump: config.Dump{ Dir: filepath.Join(root, "Dumps"), Compression: true, MaxDumps: 4, DumpUntracked: false, }, - Report: &config.Report{ + Report: config.Report{ EnableReporting: false, OSQuery: config.OSQuery{ Tables: []string{"processes", "services", "scheduled_tasks", "drivers", "startup_items", "process_open_sockets"}}, @@ -69,10 +69,10 @@ func BuildDefaultConfig(root string) *config.Agent { }}, CommandTimeout: 60 * time.Second, }, - AuditConfig: &config.Audit{ + AuditConfig: config.Audit{ AuditPolicies: []string{"File System"}, }, - CanariesConfig: &config.Canaries{ + CanariesConfig: config.Canaries{ Enable: false, Canaries: []*config.Canary{ { diff --git a/agent/hook_test.go b/agent/hook_test.go index c0049eb..b0167d7 100644 --- a/agent/hook_test.go +++ b/agent/hook_test.go @@ -138,7 +138,7 @@ func TestHooks(t *testing.T) { defer os.RemoveAll(tmp) c := BuildDefaultConfig(tmp) - c.Actions = &config.Actions{ + c.Actions = config.Actions{ AvailableActions: AvailableActions, Low: []string{}, Medium: []string{}, diff --git a/api/client/config/client.go b/api/client/config/client.go index da7df3a..74fa213 100644 --- a/api/client/config/client.go +++ b/api/client/config/client.go @@ -14,15 +14,15 @@ import ( // Client structure definition type Client struct { - Proto string `toml:"proto" comment:"Protocol to use to connect to manager (http or https)"` - Host string `toml:"host" comment:"Hostname or IP of the manager"` - Port int `toml:"port" comment:"Port at which endpoint API is running on manager server"` - UUID string `toml:"endpoint-uuid" comment:"Endpoint UUID configured on manager used to authenticate this endpoint"` - Key string `toml:"endpoint-key" comment:"Endpoint key configured on manager used to authenticate this endpoint"` - ServerKey string `toml:"server-key" comment:"Key configured on manager, used to authenticate server on this endpoint\n This settings does not protect from MITM, so configuring server\n certificate pinning is recommended."` - ServerFingerprint string `toml:"server-fingerprint" comment:"Configure manager certificate pinning\n Put here the manager's certificate fingerprint"` - Unsafe bool `toml:"unsafe" comment:"Allow unsafe HTTPS connection"` - MaxUploadSize int64 `toml:"max-upload-size" comment:"Maximum allowed upload size"` + Proto string `json:"proto" toml:"proto" comment:"Protocol to use to connect to manager (http or https)"` + Host string `json:"host" toml:"host" comment:"Hostname or IP of the manager"` + Port int `json:"port" toml:"port" comment:"Port at which endpoint API is running on manager server"` + UUID string `json:"endpoint-uuid" toml:"endpoint-uuid" comment:"Endpoint UUID configured on manager used to authenticate this endpoint"` + Key string `json:"endpoint-key" toml:"endpoint-key" comment:"Endpoint key configured on manager used to authenticate this endpoint"` + ServerKey string `json:"server-key" toml:"server-key" comment:"Key configured on manager, used to authenticate server on this endpoint\n This settings does not protect from MITM, so configuring server\n certificate pinning is recommended."` + ServerFingerprint string `json:"server-fingerprint" toml:"server-fingerprint" comment:"Configure manager certificate pinning\n Put here the manager's certificate fingerprint"` + Unsafe bool `json:"unsafe" toml:"unsafe" comment:"Allow unsafe HTTPS connection"` + MaxUploadSize int64 `json:"max-upload-size" toml:"max-upload-size" comment:"Maximum allowed upload size"` localAddr string } diff --git a/api/client/config/forwarder.go b/api/client/config/forwarder.go index a0f95f9..7c465f9 100644 --- a/api/client/config/forwarder.go +++ b/api/client/config/forwarder.go @@ -6,13 +6,13 @@ import ( // ForwarderLogging structure to encode Logging configuration of the forwarder type ForwarderLogging struct { - Dir string `toml:"dir" comment:"Directory used to store logs"` - RotationInterval time.Duration `toml:"rotation-interval" comment:"Logfile rotation interval"` + Dir string `json:"dir" toml:"dir" comment:"Directory used to store logs"` + RotationInterval time.Duration `json:"rotation-interval" toml:"rotation-interval" comment:"Logfile rotation interval"` } // Forwarder config structure definition type Forwarder struct { - Local bool `toml:"local" comment:"If forwarder is local (this setting equals true)\n neither alerts nor dumps will be forwarded to manager"` - Client Client `toml:"manager" comment:"Configure connection to the manager"` - Logging ForwarderLogging `toml:"logging" comment:"Forwarder's logging configuration"` + Local bool `json:"local" toml:"local" comment:"If forwarder is local (this setting equals true)\n neither alerts nor dumps will be forwarded to manager"` + Client Client `json:"manager" toml:"manager" comment:"Configure connection to the manager"` + Logging ForwarderLogging `json:"logging" toml:"logging" comment:"Forwarder's logging configuration"` } diff --git a/api/endpoint.go b/api/endpoint.go index 219e73c..dd8ff55 100644 --- a/api/endpoint.go +++ b/api/endpoint.go @@ -22,10 +22,10 @@ type Endpoint struct { Score float64 `json:"score"` Status string `json:"status"` SystemInfo *sysinfo.SystemInfo `json:"system-info,omitempty"` - Config *config.Agent - LastEvent time.Time `json:"last-event"` - LastDetection time.Time `json:"last-detection"` - LastConnection time.Time `json:"last-connection"` + Config *config.Agent `json:"config,omitempty"` + LastEvent time.Time `json:"last-event"` + LastDetection time.Time `json:"last-detection"` + LastConnection time.Time `json:"last-connection"` } // NewEndpoint returns a new Endpoint structure diff --git a/api/openapi/openapi.go b/api/openapi/openapi.go index 54b58ad..601b39c 100644 --- a/api/openapi/openapi.go +++ b/api/openapi/openapi.go @@ -167,8 +167,9 @@ func (oa *OpenAPI) docPath(path PathItem, op Operation) { } } -func (oa *OpenAPI) Do(base PathItem, op Operation) { - var err error +func (oa *OpenAPI) do(base *PathItem, op *Operation) (err error) { + var req *http.Request + var resp *http.Response var data []byte body := new(bytes.Buffer) @@ -180,7 +181,7 @@ func (oa *OpenAPI) Do(base PathItem, op Operation) { if op.RequestBody != nil { if data, err = op.RequestBody.ContentBytes(); err != nil { - panic(err) + return } } @@ -215,9 +216,9 @@ func (oa *OpenAPI) Do(base PathItem, op Operation) { } } - req, err := http.NewRequest(op.Method, URL, body) + req, err = http.NewRequest(op.Method, URL, body) if err != nil { - panic(err) + return } // Set authentication header @@ -225,9 +226,27 @@ func (oa *OpenAPI) Do(base PathItem, op Operation) { req.Header.Add(oa.ApiKey.Name, oa.ApiKey.Value) } - if resp, err := oa.Client.Do(req); err != nil { - panic(err) - } else if err := op.ParseResponse(resp); err != nil { + if resp, err = oa.Client.Do(req); err != nil { + return + } + + if err = op.ParseResponse(resp); err != nil { + return + } + + return +} + +// Test does exactly what Do does except that it does not document Operation +// the other difference is that this method returns any error encountered instead +// of panicing +func (oa *OpenAPI) Test(base PathItem, op Operation) error { + return oa.do(&base, &op) +} + +func (oa *OpenAPI) Do(base PathItem, op Operation) { + + if err := oa.do(&base, &op); err != nil { panic(err) } @@ -391,6 +410,42 @@ func (o *Operation) softInit() { } } +func (o *Operation) GET(params ...*Parameter) Operation { + new := o.SetParams(params...) + return new.SetMethod("GET") +} + +func (o *Operation) DELETE(params ...*Parameter) Operation { + new := o.SetParams(params...) + return new.SetMethod("DELETE") +} + +func (o *Operation) POST(b *RequestBody, params ...*Parameter) Operation { + new := o.SetMethod("POST") + if b != nil { + new = new.SetRequestBody(b) + } + return new.SetParams(params...) +} + +func (o *Operation) SetMethod(method string) Operation { + new := *o + new.Method = method + return new +} + +func (o *Operation) SetParams(params ...*Parameter) Operation { + new := *o + new.Parameters = append(new.Parameters, params...) + return new +} + +func (o *Operation) SetRequestBody(b *RequestBody) Operation { + new := *o + new.RequestBody = b + return new +} + func (o *Operation) ParseResponse(r *http.Response) (err error) { var data []byte @@ -403,7 +458,9 @@ func (o *Operation) ParseResponse(r *http.Response) (err error) { switch ct { case ContentTypeJson: - json.Unmarshal(data, &o.Output) + if err = json.Unmarshal(data, &o.Output); err != nil { + return err + } case "": break default: diff --git a/api/routes.go b/api/routes.go index 0867086..41cb048 100644 --- a/api/routes.go +++ b/api/routes.go @@ -69,7 +69,11 @@ const ( AdmAPIEndpointsOSQueryiPath = AdmAPIEndpointsOSPath + `/osqueryi` AdmAPIEndpointsOSQueryiBinary = AdmAPIEndpointsOSQueryiPath + `/binary` + // Endpoint by UUID AdmAPIEndpointsByIDPath = AdmAPIEndpointsPath + "/{euuid:" + uuidRe + "}" + // Config related + AdmAPIConfigSuffix = "/config" + AdmAPIEndpointConfigPath = AdmAPIEndpointsByIDPath + AdmAPIConfigSuffix // Command related AdmAPICommandSuffix = "/command" AdmAPIEndpointCommandPath = AdmAPIEndpointsByIDPath + AdmAPICommandSuffix diff --git a/api/server/command.go b/api/server/command.go new file mode 100644 index 0000000..919a8b0 --- /dev/null +++ b/api/server/command.go @@ -0,0 +1,38 @@ +package server + +import ( + "time" + + "github.com/0xrawsec/whids/api" +) + +// CommandAPI structure used by Admin API clients to POST commands +type CommandAPI struct { + CommandLine string `json:"command-line"` + FetchFiles []string `json:"fetch-files"` + DropFiles []string `json:"drop-files"` + Timeout time.Duration `json:"timeout"` +} + +// ToCommand converts a CommandAPI to an EndpointCommand +func (c *CommandAPI) ToCommand() (*api.EndpointCommand, error) { + cmd := api.NewEndpointCommand() + // adding command line + if err := cmd.SetCommandLine(c.CommandLine); err != nil { + return cmd, err + } + + // adding files to fetch + for _, ff := range c.FetchFiles { + cmd.AddFetchFile(ff) + } + + // adding files to drop on the endpoint + for _, df := range c.DropFiles { + cmd.AddDropFileFromPath(df) + } + + cmd.Timeout = c.Timeout + + return cmd, nil +} diff --git a/api/server/manager_admin_api.go b/api/server/manager_admin_api.go index 367b7bd..5848204 100644 --- a/api/server/manager_admin_api.go +++ b/api/server/manager_admin_api.go @@ -18,6 +18,7 @@ import ( "github.com/0xrawsec/gene/v2/engine" "github.com/0xrawsec/gene/v2/reducer" "github.com/0xrawsec/sod" + "github.com/0xrawsec/whids/agent/config" "github.com/0xrawsec/whids/api" "github.com/0xrawsec/whids/event" "github.com/0xrawsec/whids/ioc" @@ -321,6 +322,8 @@ func (m *Manager) admAPIEndpoints(wt http.ResponseWriter, rq *http.Request) { if endpt.Criticality < int(criticality) { continue } + // never show config + endpt.Config = nil // never show command endpt.Command = nil if !showKey { @@ -395,6 +398,11 @@ func (m *Manager) admAPIEndpoint(wt http.ResponseWriter, rq *http.Request) { } } + // never show command + endpt.Command = nil + // never show config + endpt.Config = nil + // score is updated at every call as it depends on all the other endpoints endpt.Score = m.gene.reducer.BoundedScore(endpt.Uuid) @@ -418,35 +426,71 @@ func (m *Manager) admAPIEndpoint(wt http.ResponseWriter, rq *http.Request) { } } -// CommandAPI structure used by Admin API clients to POST commands -type CommandAPI struct { - CommandLine string `json:"command-line"` - FetchFiles []string `json:"fetch-files"` - DropFiles []string `json:"drop-files"` - Timeout time.Duration `json:"timeout"` -} +func (m *Manager) admAPIEndpointConfig(wt http.ResponseWriter, rq *http.Request) { + var euuid string + var err error -// ToCommand converts a CommandAPI to a Command -func (c *CommandAPI) ToCommand() (*api.EndpointCommand, error) { - cmd := api.NewEndpointCommand() - // adding command line - if err := cmd.SetCommandLine(c.CommandLine); err != nil { - return cmd, err - } + qpfmt := rq.URL.Query().Get(api.QpFormat) - // adding files to fetch - for _, ff := range c.FetchFiles { - cmd.AddFetchFile(ff) - } + if euuid, err = muxGetVar(rq, "euuid"); err == nil { + if endpt, ok := m.Endpoint(euuid); ok { + var err error - // adding files to drop on the endpoint - for _, df := range c.DropFiles { - cmd.AddDropFileFromPath(df) - } + switch rq.Method { + + case "POST": + c := config.Agent{} + log.Info("format=", qpfmt) + switch qpfmt { + case "toml": + log.Info("reading toml") + err = readPostAsTOML(rq, &c) + default: + err = readPostAsJSON(rq, &c) + } + + if err != nil && rq.ContentLength > 0 { + wt.Write(admErr(err.Error())) + return + } + + endpt.Config = &c + + if err = m.db.InsertOrUpdate(endpt); err != nil { + m.logAPIErrorf("failed to save updated endpoint UUID=%s", euuid) + } + + case "DELETE": + + // delete configuration + endpt.Config = nil + + if err = m.db.InsertOrUpdate(endpt); err != nil { + m.logAPIErrorf("failed to save updated endpoint UUID=%s", euuid) + } + } - cmd.Timeout = c.Timeout + var respData any + respData = endpt.Config + + if qpfmt == "toml" { + if endpt.Config != nil { + respData, err = utils.TomlString(endpt.Config) + } + } - return cmd, nil + apiResp := NewAdminAPIResponse(respData) + if err != nil { + apiResp.Error = err.Error() + } + + wt.Write(apiResp.ToJSON()) + } else { + wt.Write(admErr(format("Unknown endpoint: %s", euuid))) + } + } else { + wt.Write(admErr(format("Failed to parse URL: %s", err))) + } } func (m *Manager) admAPIEndpointCommand(wt http.ResponseWriter, rq *http.Request) { @@ -1517,6 +1561,7 @@ func (m *Manager) runAdminAPI() { rt.HandleFunc(api.AdmAPIUserByID, m.admAPIUser).Methods("GET", "POST", "DELETE") rt.HandleFunc(api.AdmAPIEndpointsPath, m.admAPIEndpoints).Methods("GET", "PUT") rt.HandleFunc(api.AdmAPIEndpointsByIDPath, m.admAPIEndpoint).Methods("GET", "POST", "DELETE") + rt.HandleFunc(api.AdmAPIEndpointConfigPath, m.admAPIEndpointConfig).Methods("GET", "POST", "DELETE") rt.HandleFunc(api.AdmAPIEndpointCommandPath, m.admAPIEndpointCommand).Methods("GET", "POST") rt.HandleFunc(api.AdmAPIEndpointCommandFieldPath, m.admAPIEndpointCommandField).Methods("GET") rt.HandleFunc(api.AdmAPIEndpointsReportsPath, m.admAPIEndpointsReports).Methods("GET") diff --git a/api/server/openapi_def.go b/api/server/openapi_def.go index da48db6..07a4f33 100644 --- a/api/server/openapi_def.go +++ b/api/server/openapi_def.go @@ -70,87 +70,14 @@ var OpenAPIDefinition = ` "example": { "data": [ { - "Config": { - "Actions": { - "AvailableActions": [], - "Critical": [], - "High": [], - "Low": [], - "Medium": [] - }, - "AuditConfig": { - "AuditDirs": [], - "AuditPolicies": [], - "Enable": false - }, - "CanariesConfig": { - "Actions": [], - "Canaries": [], - "Enable": false, - "Whitelist": [] - }, - "CritTresh": 0, - "DatabasePath": "", - "Dump": { - "Compression": false, - "Dir": "", - "DumpUntracked": false, - "MaxDumps": 0 - }, - "EnableFiltering": false, - "EnableHooks": false, - "Endpoint": false, - "EtwConfig": { - "Providers": [], - "Traces": [] - }, - "FwdConfig": { - "Client": { - "Host": "", - "Key": "", - "MaxUploadSize": 0, - "Port": 0, - "Proto": "", - "ServerFingerprint": "", - "ServerKey": "", - "UUID": "", - "Unsafe": false - }, - "Local": false, - "Logging": { - "Dir": "", - "RotationInterval": 0 - } - }, - "LogAll": false, - "Logfile": "", - "Report": { - "CommandTimeout": 0, - "Commands": [], - "EnableReporting": false, - "OSQuery": { - "Tables": [] - } - }, - "RulesConfig": { - "ContainersDB": "", - "RulesDB": "", - "UpdateInterval": 0 - }, - "Sysmon": { - "ArchiveDirectory": "", - "Bin": "", - "CleanArchived": false - } - }, "criticality": 0, "group": "", "hostname": "OpenHappy", "ip": "127.0.0.1", - "key": "1dBTeTTbXc5OE3qU8XW8WwkHfpGxHPn7eRyVoXmgQLQ7T7vqapOEVCPd3Cqx6MEE", - "last-connection": "2022-07-26T10:16:09.409830822Z", - "last-detection": "2022-07-26T12:16:08.351197299+02:00", - "last-event": "2022-07-26T12:16:08.351197299+02:00", + "key": "LMOwHSiGhg1MNG57lJnlm1Pl9VuEL2nPhLg37D1M4L0DCJgnEgqQHGCYNwySoOcm", + "last-connection": "2022-07-27T16:16:22.005202458Z", + "last-detection": "2022-07-27T18:16:20.951172026+02:00", + "last-event": "2022-07-27T18:16:20.951172026+02:00", "score": 0, "status": "", "system-info": { @@ -223,18 +150,17 @@ var OpenAPIDefinition = ` "application/json": { "example": { "data": { - "Config": null, "criticality": 0, "group": "", "hostname": "", "ip": "", - "key": "NknjFBuHmm83cfLMIyYBOGTaH6zYovgBxkaD5NNbgaBUKrlvIJYBHgTvm4N0sSxn", + "key": "T1CvqgGOawX0upc0RJP6544JfjJP0Sj38D4t8fYM1IXtbNaOKV5TUYwPeyMzkBKa", "last-connection": "0001-01-01T00:00:00Z", "last-detection": "0001-01-01T00:00:00Z", "last-event": "0001-01-01T00:00:00Z", "score": 0, "status": "", - "uuid": "9bad456e-ab68-06ee-3242-6f0425951686" + "uuid": "f5911ff9-704d-4b50-4a6b-f5f58bbe1a84" }, "error": "", "message": "OK" @@ -274,21 +200,21 @@ var OpenAPIDefinition = ` "5a92baeb-9384-47d3-92b4-a0db6f9b8c6d": [ { "base-url": "/endpoints/5a92baeb-9384-47d3-92b4-a0db6f9b8c6d/artifacts/5a92baeb-9384-47d3-92b4-a0db6f9b8c6d/3d8441643c204ba9b9dcb5c414b25a3129f66f6c/", - "creation": "2022-07-26T10:16:13.747105168Z", + "creation": "2022-07-27T16:16:27.50137352Z", "event-hash": "3d8441643c204ba9b9dcb5c414b25a3129f66f6c", "files": [ { "name": "bar.txt", "size": 4, - "timestamp": "2022-07-26T10:16:13.747105168Z" + "timestamp": "2022-07-27T16:16:27.50137352Z" }, { "name": "foo.txt", "size": 4, - "timestamp": "2022-07-26T10:16:13.747105168Z" + "timestamp": "2022-07-27T16:16:27.50137352Z" } ], - "modification": "2022-07-26T10:16:13.747105168Z", + "modification": "2022-07-27T16:16:27.50137352Z", "process-guid": "5a92baeb-9384-47d3-92b4-a0db6f9b8c6d" } ] @@ -322,30 +248,30 @@ var OpenAPIDefinition = ` "avg-signature-criticality": 0, "bounded-score": 0, "count-by-signature": { - "DefenderConfigChanged": 6, - "NewAutorun": 27, + "DefenderConfigChanged": 4, + "NewAutorun": 21, "SuspiciousService": 4, - "UnknownServices": 7, - "UntrustedDriverLoaded": 6 + "UnknownServices": 9, + "UntrustedDriverLoaded": 12 }, "count-uniq-signatures": 5, "identifier": "5a92baeb-9384-47d3-92b4-a0db6f9b8c6d", - "median-time": "2022-07-26T12:16:11.570582416+02:00", + "median-time": "2022-07-27T18:16:25.263455529+02:00", "score": 0, "signature-count": 50, "signature-criticality-metric": 0, "signature-diversity": 100, "signatures": [ "NewAutorun", + "UntrustedDriverLoaded", "UnknownServices", "SuspiciousService", - "DefenderConfigChanged", - "UntrustedDriverLoaded" + "DefenderConfigChanged" ], - "start-time": "2022-07-26T12:16:11.5690665+02:00", + "start-time": "2022-07-27T18:16:25.261859405+02:00", "std-dev-alert-criticality": 0, "std-dev-signature-criticality": -92233720368547760, - "stop-time": "2022-07-26T12:16:11.572098332+02:00", + "stop-time": "2022-07-27T18:16:25.265051653+02:00", "sum-alert-criticality": 0, "sum-rule-criticality": 0, "tactics": null, @@ -406,7 +332,7 @@ var OpenAPIDefinition = ` }, "name": "osqueryi", "os": "windows", - "uuid": "661564ba-e14c-639e-437b-537abb656bc6" + "uuid": "c94bde56-2a28-cc0a-9f87-5ceda92b49b1" }, "error": "", "message": "OK" @@ -473,7 +399,7 @@ var OpenAPIDefinition = ` }, "name": "osqueryi", "os": "windows", - "uuid": "661564ba-e14c-639e-437b-537abb656bc6" + "uuid": "c94bde56-2a28-cc0a-9f87-5ceda92b49b1" }, "error": "", "message": "OK" @@ -527,7 +453,7 @@ var OpenAPIDefinition = ` }, "name": "osqueryi", "os": "windows", - "uuid": "661564ba-e14c-639e-437b-537abb656bc6" + "uuid": "c94bde56-2a28-cc0a-9f87-5ceda92b49b1" }, "error": "", "message": "OK" @@ -583,7 +509,7 @@ var OpenAPIDefinition = ` }, "name": "sysmon", "os": "windows", - "uuid": "1e4dff28-8d71-34cf-22ef-5ed6d057aef7" + "uuid": "57937591-b3f4-489a-608f-24d6b5d49923" }, "error": "", "message": "OK" @@ -650,7 +576,7 @@ var OpenAPIDefinition = ` }, "name": "sysmon", "os": "windows", - "uuid": "1e4dff28-8d71-34cf-22ef-5ed6d057aef7" + "uuid": "57937591-b3f4-489a-608f-24d6b5d49923" }, "error": "", "message": "OK" @@ -704,7 +630,7 @@ var OpenAPIDefinition = ` }, "name": "sysmon", "os": "windows", - "uuid": "1e4dff28-8d71-34cf-22ef-5ed6d057aef7" + "uuid": "57937591-b3f4-489a-608f-24d6b5d49923" }, "error": "", "message": "OK" @@ -1967,103 +1893,13 @@ var OpenAPIDefinition = ` "application/json": { "example": { "data": { - "Config": { - "Actions": { - "AvailableActions": [], - "Critical": [], - "High": [], - "Low": [], - "Medium": [] - }, - "AuditConfig": { - "AuditDirs": [], - "AuditPolicies": [], - "Enable": false - }, - "CanariesConfig": { - "Actions": [], - "Canaries": [], - "Enable": false, - "Whitelist": [] - }, - "CritTresh": 0, - "DatabasePath": "", - "Dump": { - "Compression": false, - "Dir": "", - "DumpUntracked": false, - "MaxDumps": 0 - }, - "EnableFiltering": false, - "EnableHooks": false, - "Endpoint": false, - "EtwConfig": { - "Providers": [], - "Traces": [] - }, - "FwdConfig": { - "Client": { - "Host": "", - "Key": "", - "MaxUploadSize": 0, - "Port": 0, - "Proto": "", - "ServerFingerprint": "", - "ServerKey": "", - "UUID": "", - "Unsafe": false - }, - "Local": false, - "Logging": { - "Dir": "", - "RotationInterval": 0 - } - }, - "LogAll": false, - "Logfile": "", - "Report": { - "CommandTimeout": 0, - "Commands": [], - "EnableReporting": false, - "OSQuery": { - "Tables": [] - } - }, - "RulesConfig": { - "ContainersDB": "", - "RulesDB": "", - "UpdateInterval": 0 - }, - "Sysmon": { - "ArchiveDirectory": "", - "Bin": "", - "CleanArchived": false - } - }, - "command": { - "args": [], - "background": false, - "completed": true, - "drop": [], - "error": "", - "expect-json": false, - "fetch": {}, - "json": null, - "name": "", - "sent": true, - "sent-time": "2022-07-26T12:16:09.408987389+02:00", - "stderr": "", - "stdout": "", - "timeout": 0, - "uuid": "" - }, "criticality": 0, "group": "", "hostname": "OpenHappy", "ip": "127.0.0.1", - "last-connection": "2022-07-26T10:16:09.409830822Z", - "last-detection": "2022-07-26T12:16:08.351197299+02:00", - "last-event": "2022-07-26T12:16:08.351197299+02:00", + "last-connection": "2022-07-27T16:16:22.005202458Z", + "last-detection": "2022-07-27T18:16:20.951172026+02:00", + "last-event": "2022-07-27T18:16:20.951172026+02:00", "score": 0, "status": "", "system-info": { @@ -2167,37 +2003,134 @@ var OpenAPIDefinition = ` "schema": { "type": "object", "properties": { - "Config": { + "Item": { + "type": "object" + }, + "command": { + "type": "object", + "properties": { + "args": { + "type": "array", + "items": { + "type": "string" + } + }, + "background": { + "type": "boolean" + }, + "completed": { + "type": "boolean" + }, + "drop": { + "type": "array", + "items": { + "type": "object", + "properties": { + "data": { + "type": "string", + "format": "binary" + }, + "error": { + "type": "string" + }, + "name": { + "type": "string" + }, + "uuid": { + "type": "string" + } + } + } + }, + "error": { + "type": "string" + }, + "expect-json": { + "type": "boolean" + }, + "fetch": { + "type": "object", + "properties": { + "key(string)": { + "type": "object", + "properties": { + "data": { + "type": "string", + "format": "binary" + }, + "error": { + "type": "string" + }, + "name": { + "type": "string" + }, + "uuid": { + "type": "string" + } + } + } + } + }, + "json": { + "type": "object" + }, + "name": { + "type": "string" + }, + "sent": { + "type": "boolean" + }, + "sent-time": { + "type": "string", + "format": "date" + }, + "stderr": { + "type": "string", + "format": "binary" + }, + "stdout": { + "type": "string", + "format": "binary" + }, + "timeout": { + "type": "object" + }, + "uuid": { + "type": "string" + } + } + }, + "config": { "type": "object", "properties": { - "Actions": { + "actions": { "type": "object", "properties": { - "AvailableActions": { + "available-actions": { "type": "array", "items": { "type": "string" } }, - "Critical": { + "critical": { "type": "array", "items": { "type": "string" } }, - "High": { + "high": { "type": "array", "items": { "type": "string" } }, - "Low": { + "low": { "type": "array", "items": { "type": "string" } }, - "Medium": { + "medium": { "type": "array", "items": { "type": "string" @@ -2205,71 +2138,71 @@ var OpenAPIDefinition = ` } } }, - "AuditConfig": { + "audit": { "type": "object", "properties": { - "AuditDirs": { + "audit-dirs": { "type": "array", "items": { "type": "string" } }, - "AuditPolicies": { + "audit-policies": { "type": "array", "items": { "type": "string" } }, - "Enable": { + "enable": { "type": "boolean" } } }, - "CanariesConfig": { + "canaries": { "type": "object", "properties": { - "Actions": { + "actions": { "type": "array", "items": { "type": "string" } }, - "Canaries": { + "enable": { + "type": "boolean" + }, + "group": { "type": "array", "items": { "type": "object", "properties": { - "Delete": { + "delete": { "type": "boolean" }, - "Directories": { + "directories": { "type": "array", "items": { "type": "string" } }, - "Files": { + "files": { "type": "array", "items": { "type": "string" } }, - "HideDirectories": { + "hide-dirs": { "type": "boolean" }, - "HideFiles": { + "hide-files": { "type": "boolean" }, - "SetAuditACL": { + "set-audit-acl": { "type": "boolean" } } } }, - "Enable": { - "type": "boolean" - }, - "Whitelist": { + "whitelist": { "type": "array", "items": { "type": "string" @@ -2277,50 +2210,50 @@ var OpenAPIDefinition = ` } } }, - "CritTresh": { + "criticality-treshold": { "type": "integer", "format": "int64" }, - "DatabasePath": { + "db-path": { "type": "string" }, - "Dump": { + "dump": { "type": "object", "properties": { - "Compression": { + "compression": { "type": "boolean" }, - "Dir": { + "dir": { "type": "string" }, - "DumpUntracked": { + "dump-untracked": { "type": "boolean" }, - "MaxDumps": { + "max-dumps": { "type": "integer", "format": "int64" } } }, - "EnableFiltering": { + "en-filters": { "type": "boolean" }, - "EnableHooks": { + "en-hooks": { "type": "boolean" }, - "Endpoint": { + "endpoint": { "type": "boolean" }, - "EtwConfig": { + "etw": { "type": "object", "properties": { - "Providers": { + "providers": { "type": "array", "items": { "type": "string" } }, - "Traces": { + "traces": { "type": "array", "items": { "type": "string" @@ -2328,72 +2261,69 @@ var OpenAPIDefinition = ` } } }, - "FwdConfig": { + "forwarder": { "type": "object", "properties": { - "Client": { + "local": { + "type": "boolean" + }, + "logging": { + "type": "object", + "properties": { + "dir": { + "type": "string" + }, + "rotation-interval": { + "type": "object" + } + } + }, + "manager": { "type": "object", "properties": { - "Host": { + "endpoint-key": { "type": "string" }, - "Key": { + "endpoint-uuid": { "type": "string" }, - "MaxUploadSize": { + "host": { + "type": "string" + }, + "max-upload-size": { "type": "integer", "format": "int64" }, - "Port": { + "port": { "type": "integer", "format": "int64" }, - "Proto": { - "type": "string" - }, - "ServerFingerprint": { + "proto": { "type": "string" }, - "ServerKey": { + "server-fingerprint": { "type": "string" }, - "UUID": { + "server-key": { "type": "string" }, - "Unsafe": { + "unsafe": { "type": "boolean" } } - }, - "Local": { - "type": "boolean" - }, - "Logging": { - "type": "object", - "properties": { - "Dir": { - "type": "string" - }, - "RotationInterval": { - "type": "object" - } - } } } }, - "LogAll": { + "log-all": { "type": "boolean" }, - "Logfile": { + "logfile": { "type": "string" }, - "Report": { + "report": { "type": "object", "properties": { - "CommandTimeout": { - "type": "object" - }, - "Commands": { + "commands": { "type": "array", "items": { "type": "object", @@ -2433,199 +2363,105 @@ var OpenAPIDefinition = ` } } }, - "EnableReporting": { + "en-reporting": { "type": "boolean" }, - "OSQuery": { + "osquery": { "type": "object", "properties": { - "Tables": { + "tables": { "type": "array", "items": { "type": "string" } } } + }, + "timeout": { + "type": "object" } } }, - "RulesConfig": { + "rules": { "type": "object", "properties": { - "ContainersDB": { + "containers-db": { "type": "string" }, - "RulesDB": { + "rules-db": { "type": "string" }, - "UpdateInterval": { + "update-interval": { "type": "object" } } }, - "Sysmon": { + "sysmon": { "type": "object", "properties": { - "ArchiveDirectory": { + "archive-directory": { "type": "string" }, - "Bin": { + "bin": { "type": "string" }, - "CleanArchived": { + "clean-archived": { "type": "boolean" } } } } }, - "Item": { - "type": "object" + "criticality": { + "type": "integer", + "format": "int64" }, - "command": { + "group": { + "type": "string" + }, + "hostname": { + "type": "string" + }, + "ip": { + "type": "string" + }, + "key": { + "type": "string" + }, + "last-connection": { + "type": "string", + "format": "date" + }, + "last-detection": { + "type": "string", + "format": "date" + }, + "last-event": { + "type": "string", + "format": "date" + }, + "score": { + "type": "number", + "format": "double" + }, + "status": { + "type": "string" + }, + "system-info": { "type": "object", "properties": { - "args": { - "type": "array", - "items": { - "type": "string" - } - }, - "background": { - "type": "boolean" - }, - "completed": { - "type": "boolean" - }, - "drop": { - "type": "array", - "items": { - "type": "object", - "properties": { - "data": { - "type": "string", - "format": "binary" - }, - "error": { - "type": "string" - }, - "name": { - "type": "string" - }, - "uuid": { - "type": "string" - } + "bios": { + "type": "object", + "properties": { + "date": { + "type": "string" + }, + "version": { + "type": "string" } } }, - "error": { - "type": "string" - }, - "expect-json": { - "type": "boolean" - }, - "fetch": { - "type": "object", - "properties": { - "key(string)": { - "type": "object", - "properties": { - "data": { - "type": "string", - "format": "binary" - }, - "error": { - "type": "string" - }, - "name": { - "type": "string" - }, - "uuid": { - "type": "string" - } - } - } - } - }, - "json": { - "type": "object" - }, - "name": { - "type": "string" - }, - "sent": { - "type": "boolean" - }, - "sent-time": { - "type": "string", - "format": "date" - }, - "stderr": { - "type": "string", - "format": "binary" - }, - "stdout": { - "type": "string", - "format": "binary" - }, - "timeout": { - "type": "object" - }, - "uuid": { - "type": "string" - } - } - }, - "criticality": { - "type": "integer", - "format": "int64" - }, - "group": { - "type": "string" - }, - "hostname": { - "type": "string" - }, - "ip": { - "type": "string" - }, - "key": { - "type": "string" - }, - "last-connection": { - "type": "string", - "format": "date" - }, - "last-detection": { - "type": "string", - "format": "date" - }, - "last-event": { - "type": "string", - "format": "date" - }, - "score": { - "type": "number", - "format": "double" - }, - "status": { - "type": "string" - }, - "system-info": { - "type": "object", - "properties": { - "bios": { - "type": "object", - "properties": { - "date": { - "type": "string" - }, - "version": { - "type": "string" - } - } - }, - "cpu": { + "cpu": { "type": "object", "properties": { "count": { @@ -2756,7 +2592,6 @@ var OpenAPIDefinition = ` "key": "New Key", "score": 0, "status": "New Status", - "Config": null, "last-event": "0001-01-01T00:00:00Z", "last-detection": "0001-01-01T00:00:00Z", "last-connection": "0001-01-01T00:00:00Z" @@ -2772,103 +2607,13 @@ var OpenAPIDefinition = ` "application/json": { "example": { "data": { - "Config": { - "Actions": { - "AvailableActions": [], - "Critical": [], - "High": [], - "Low": [], - "Medium": [] - }, - "AuditConfig": { - "AuditDirs": [], - "AuditPolicies": [], - "Enable": false - }, - "CanariesConfig": { - "Actions": [], - "Canaries": [], - "Enable": false, - "Whitelist": [] - }, - "CritTresh": 0, - "DatabasePath": "", - "Dump": { - "Compression": false, - "Dir": "", - "DumpUntracked": false, - "MaxDumps": 0 - }, - "EnableFiltering": false, - "EnableHooks": false, - "Endpoint": false, - "EtwConfig": { - "Providers": [], - "Traces": [] - }, - "FwdConfig": { - "Client": { - "Host": "", - "Key": "", - "MaxUploadSize": 0, - "Port": 0, - "Proto": "", - "ServerFingerprint": "", - "ServerKey": "", - "UUID": "", - "Unsafe": false - }, - "Local": false, - "Logging": { - "Dir": "", - "RotationInterval": 0 - } - }, - "LogAll": false, - "Logfile": "", - "Report": { - "CommandTimeout": 0, - "Commands": [], - "EnableReporting": false, - "OSQuery": { - "Tables": [] - } - }, - "RulesConfig": { - "ContainersDB": "", - "RulesDB": "", - "UpdateInterval": 0 - }, - "Sysmon": { - "ArchiveDirectory": "", - "Bin": "", - "CleanArchived": false - } - }, - "command": { - "args": [], - "background": false, - "completed": true, - "drop": [], - "error": "", - "expect-json": false, - "fetch": {}, - "json": null, - "name": "", - "sent": true, - "sent-time": "2022-07-26T12:16:09.408987389+02:00", - "stderr": "", - "stdout": "", - "timeout": 0, - "uuid": "" - }, "criticality": 0, "group": "New Group", "hostname": "OpenHappy", "ip": "127.0.0.1", - "last-connection": "2022-07-26T10:16:09.409830822Z", - "last-detection": "2022-07-26T12:16:08.351197299+02:00", - "last-event": "2022-07-26T12:16:08.351197299+02:00", + "last-connection": "2022-07-27T16:16:22.005202458Z", + "last-detection": "2022-07-27T18:16:20.951172026+02:00", + "last-event": "2022-07-27T18:16:20.951172026+02:00", "score": 0, "status": "New Status", "system-info": { @@ -2952,103 +2697,13 @@ var OpenAPIDefinition = ` "application/json": { "example": { "data": { - "Config": { - "Actions": { - "AvailableActions": [], - "Critical": [], - "High": [], - "Low": [], - "Medium": [] - }, - "AuditConfig": { - "AuditDirs": [], - "AuditPolicies": [], - "Enable": false - }, - "CanariesConfig": { - "Actions": [], - "Canaries": [], - "Enable": false, - "Whitelist": [] - }, - "CritTresh": 0, - "DatabasePath": "", - "Dump": { - "Compression": false, - "Dir": "", - "DumpUntracked": false, - "MaxDumps": 0 - }, - "EnableFiltering": false, - "EnableHooks": false, - "Endpoint": false, - "EtwConfig": { - "Providers": [], - "Traces": [] - }, - "FwdConfig": { - "Client": { - "Host": "", - "Key": "", - "MaxUploadSize": 0, - "Port": 0, - "Proto": "", - "ServerFingerprint": "", - "ServerKey": "", - "UUID": "", - "Unsafe": false - }, - "Local": false, - "Logging": { - "Dir": "", - "RotationInterval": 0 - } - }, - "LogAll": false, - "Logfile": "", - "Report": { - "CommandTimeout": 0, - "Commands": [], - "EnableReporting": false, - "OSQuery": { - "Tables": [] - } - }, - "RulesConfig": { - "ContainersDB": "", - "RulesDB": "", - "UpdateInterval": 0 - }, - "Sysmon": { - "ArchiveDirectory": "", - "Bin": "", - "CleanArchived": false - } - }, - "command": { - "args": [], - "background": false, - "completed": true, - "drop": [], - "error": "", - "expect-json": false, - "fetch": {}, - "json": null, - "name": "", - "sent": true, - "sent-time": "2022-07-26T12:16:09.408987389+02:00", - "stderr": "", - "stdout": "", - "timeout": 0, - "uuid": "" - }, "criticality": 0, "group": "New Group", "hostname": "OpenHappy", "ip": "127.0.0.1", - "last-connection": "2022-07-26T10:16:09.409830822Z", - "last-detection": "2022-07-26T12:16:08.351197299+02:00", - "last-event": "2022-07-26T12:16:08.351197299+02:00", + "last-connection": "2022-07-27T16:16:22.005202458Z", + "last-detection": "2022-07-27T18:16:20.951172026+02:00", + "last-event": "2022-07-27T18:16:20.951172026+02:00", "score": 0, "status": "New Status", "system-info": { @@ -3147,21 +2802,21 @@ var OpenAPIDefinition = ` "data": [ { "base-url": "/endpoints/5a92baeb-9384-47d3-92b4-a0db6f9b8c6d/artifacts/5a92baeb-9384-47d3-92b4-a0db6f9b8c6d/3d8441643c204ba9b9dcb5c414b25a3129f66f6c/", - "creation": "2022-07-26T10:16:13.747105168Z", + "creation": "2022-07-27T16:16:27.50137352Z", "event-hash": "3d8441643c204ba9b9dcb5c414b25a3129f66f6c", "files": [ { "name": "bar.txt", "size": 4, - "timestamp": "2022-07-26T10:16:13.747105168Z" + "timestamp": "2022-07-27T16:16:27.50137352Z" }, { "name": "foo.txt", "size": 4, - "timestamp": "2022-07-26T10:16:13.747105168Z" + "timestamp": "2022-07-27T16:16:27.50137352Z" } ], - "modification": "2022-07-26T10:16:13.747105168Z", + "modification": "2022-07-27T16:16:27.50137352Z", "process-guid": "5a92baeb-9384-47d3-92b4-a0db6f9b8c6d" } ], @@ -3306,11 +2961,11 @@ var OpenAPIDefinition = ` "json": null, "name": "/usr/bin/printf", "sent": true, - "sent-time": "2022-07-26T12:16:11.484199786+02:00", - "stderr": "", + "sent-time": "2022-07-27T18:16:25.182782394+02:00", + "stderr": null, "stdout": "SGVsbG8gV29ybGQ=", "timeout": 0, - "uuid": "a11af54b-60cb-ce0d-c869-daa4c97d1521" + "uuid": "01bef0d3-40d1-381c-4bd6-763a54b05e8c" }, "error": "", "message": "OK" @@ -3381,79 +3036,6 @@ var OpenAPIDefinition = ` "application/json": { "example": { "data": { - "Config": { - "Actions": { - "AvailableActions": [], - "Critical": [], - "High": [], - "Low": [], - "Medium": [] - }, - "AuditConfig": { - "AuditDirs": [], - "AuditPolicies": [], - "Enable": false - }, - "CanariesConfig": { - "Actions": [], - "Canaries": [], - "Enable": false, - "Whitelist": [] - }, - "CritTresh": 0, - "DatabasePath": "", - "Dump": { - "Compression": false, - "Dir": "", - "DumpUntracked": false, - "MaxDumps": 0 - }, - "EnableFiltering": false, - "EnableHooks": false, - "Endpoint": false, - "EtwConfig": { - "Providers": [], - "Traces": [] - }, - "FwdConfig": { - "Client": { - "Host": "", - "Key": "", - "MaxUploadSize": 0, - "Port": 0, - "Proto": "", - "ServerFingerprint": "", - "ServerKey": "", - "UUID": "", - "Unsafe": false - }, - "Local": false, - "Logging": { - "Dir": "", - "RotationInterval": 0 - } - }, - "LogAll": false, - "Logfile": "", - "Report": { - "CommandTimeout": 0, - "Commands": [], - "EnableReporting": false, - "OSQuery": { - "Tables": [] - } - }, - "RulesConfig": { - "ContainersDB": "", - "RulesDB": "", - "UpdateInterval": 0 - }, - "Sysmon": { - "ArchiveDirectory": "", - "Bin": "", - "CleanArchived": false - } - }, "command": { "args": [ "Hello World" @@ -3471,16 +3053,16 @@ var OpenAPIDefinition = ` "stderr": null, "stdout": null, "timeout": 0, - "uuid": "a11af54b-60cb-ce0d-c869-daa4c97d1521" + "uuid": "01bef0d3-40d1-381c-4bd6-763a54b05e8c" }, "criticality": 0, "group": "", "hostname": "OpenHappy", "ip": "127.0.0.1", - "key": "rG1txTFPuFk22sMEHMelMgNtOqszf7BRw8fIN0BvQpn5VCo8ahXs2dyk7zQNgpRb", - "last-connection": "2022-07-26T10:16:10.480698644Z", - "last-detection": "2022-07-26T12:16:09.452094893+02:00", - "last-event": "2022-07-26T12:16:09.452094893+02:00", + "key": "NxIkjKFUuLsPw2TYN2hLkXoWy0hxwpxxkUsmklvMSWgJbjyqdNfgV4Y2G821HzXE", + "last-connection": "2022-07-27T16:16:24.179437494Z", + "last-detection": "2022-07-27T18:16:23.151266867+02:00", + "last-event": "2022-07-27T18:16:23.151266867+02:00", "score": 0, "status": "", "system-info": { @@ -3595,88 +3177,13 @@ var OpenAPIDefinition = ` } } }, - "/endpoints/{uuid}/detections": { + "/endpoints/{uuid}/config": { "get": { "tags": [ - "Endpoint Log Retrieval" + "Endpoint Configuration" ], - "summary": "Retrieve detections logs", + "summary": "Get endpoint configuration", "parameters": [ - { - "name": "since", - "in": "query", - "description": "Retrieve logs since date (RFC3339)", - "required": false, - "allowEmptyValue": true, - "schema": { - "type": "string", - "format": "date" - } - }, - { - "name": "until", - "in": "query", - "description": "Retrieve logs until date (RFC3339)", - "required": false, - "allowEmptyValue": true, - "schema": { - "type": "string", - "format": "date" - } - }, - { - "name": "last", - "in": "query", - "description": "Return last logs from duration (ex: '1d' for last day)", - "required": false, - "allowEmptyValue": true, - "schema": { - "type": "string" - } - }, - { - "name": "pivot", - "in": "query", - "description": "Timestamp to pivot around (RFC3339)", - "required": false, - "allowEmptyValue": true, - "schema": { - "type": "string", - "format": "date" - } - }, - { - "name": "delta", - "in": "query", - "description": "Delta duration used to pivot (ex: '5m' to get logs 5min around pivot) ", - "required": false, - "allowEmptyValue": true, - "schema": { - "type": "string" - } - }, - { - "name": "limit", - "in": "query", - "description": "Maximum number of reports to return", - "required": false, - "allowEmptyValue": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "skip", - "in": "query", - "description": "Skip number of events", - "required": false, - "allowEmptyValue": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, { "name": "uuid", "in": "path", @@ -3694,72 +3201,772 @@ var OpenAPIDefinition = ` "content": { "application/json": { "example": { - "data": [ - { - "Event": { - "Detection": { - "Actions": [], - "Criticality": 10, - "Signature": [ - "UnknownServices" - ] - }, - "EdrData": { - "Endpoint": { - "Group": "", - "Hostname": "OpenHappy", - "IP": "127.0.0.1", - "UUID": "5a92baeb-9384-47d3-92b4-a0db6f9b8c6d" - }, - "Event": { - "Detection": true, - "Hash": "0f0d61843edd1cdeddb710ecd38c4813d406e8bc", - "ReceiptTime": "2022-07-25T13:42:46.388637264Z" - } - }, - "EventData": { - "Ancestors": "System|C:\\Windows\\System32\\smss.exe|C:\\Windows\\System32\\smss.exe|C:\\Windows\\System32\\wininit.exe|C:\\Windows\\System32\\services.exe", - "CommandLine": "C:\\Windows\\System32\\VBoxService.exe", - "Company": "Oracle Corporation", - "CurrentDirectory": "C:\\Windows\\system32\\", - "Description": "VirtualBox Guest Additions Service", - "FileVersion": "6.0.8.130520", - "Hashes": "SHA1=AE49D900887E95D7B3040BFD2C888D3439F94035,MD5=3001126B78719A1189A0A5270DA316A0,SHA256=9A66844E7ADA8E2D1D454136D68413CE74D90004BAD754D79DAA1A020A27E86C,IMPHASH=6A98677D1BE25D4274AAA7C9C37E832F", - "Image": "C:\\Windows\\System32\\VBoxService.exe", - "ImageSize": "2732048", - "IntegrityLevel": "System", - "LogonGuid": "{515cd0d1-7667-6123-e703-000000000000}", - "LogonId": "0x3E7", - "OriginalFileName": "VBoxService.exe", - "ParentCommandLine": "C:\\Windows\\system32\\services.exe", - "ParentImage": "C:\\Windows\\System32\\services.exe", - "ParentIntegrityLevel": "System", - "ParentProcessGuid": "{515cd0d1-7666-6123-0b00-000000007300}", - "ParentProcessId": "692", - "ParentServices": "N/A", - "ParentUser": "NT AUTHORITY\\SYSTEM", - "ProcessGuid": "{515cd0d1-7668-6123-2300-000000007300}", - "ProcessId": "1592", - "Product": "Oracle VM VirtualBox Guest Additions", - "RuleName": "-", - "Services": "VBoxService", - "TerminalSessionId": "0", - "User": "NT AUTHORITY\\SYSTEM", - "UtcTime": "2021-08-23 10:20:24.054" - }, - "System": { - "Channel": "Microsoft-Windows-Sysmon/Operational", - "Computer": "DESKTOP-LJRVE06", - "Correlation": { - "ActivityID": "", - "RelatedActivityID": "" - }, - "EventID": 1, - "Execution": { - "ProcessID": 3220, - "ThreadID": 3848 - }, - "Keywords": { + "data": { + "actions": { + "available-actions": null, + "critical": [], + "high": [], + "low": [], + "medium": [] + }, + "audit": { + "audit-dirs": [], + "audit-policies": [], + "enable": false + }, + "canaries": { + "actions": [], + "enable": false, + "group": null, + "whitelist": [] + }, + "criticality-treshold": 0, + "db-path": "somerandompath", + "dump": { + "compression": false, + "dir": "", + "dump-untracked": false, + "max-dumps": 0 + }, + "en-filters": false, + "en-hooks": false, + "endpoint": false, + "etw": { + "providers": [], + "traces": [] + }, + "forwarder": { + "local": false, + "logging": { + "dir": "", + "rotation-interval": 0 + }, + "manager": { + "endpoint-key": "", + "endpoint-uuid": "", + "host": "", + "max-upload-size": 0, + "port": 0, + "proto": "", + "server-fingerprint": "", + "server-key": "", + "unsafe": false + } + }, + "log-all": false, + "logfile": "", + "report": { + "commands": null, + "en-reporting": false, + "osquery": { + "tables": [] + }, + "timeout": 0 + }, + "rules": { + "containers-db": "", + "rules-db": "", + "update-interval": 0 + }, + "sysmon": { + "archive-directory": "", + "bin": "", + "clean-archived": false + } + }, + "error": "", + "message": "OK" + } + } + } + } + } + }, + "post": { + "tags": [ + "Endpoint Configuration" + ], + "summary": "Change endpoint configuration", + "parameters": [ + { + "name": "uuid", + "in": "path", + "description": "uuid path parameter", + "required": true, + "allowEmptyValue": false, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "Configuration content", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "actions": { + "type": "object", + "properties": { + "available-actions": { + "type": "array", + "items": { + "type": "string" + } + }, + "critical": { + "type": "array", + "items": { + "type": "string" + } + }, + "high": { + "type": "array", + "items": { + "type": "string" + } + }, + "low": { + "type": "array", + "items": { + "type": "string" + } + }, + "medium": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "audit": { + "type": "object", + "properties": { + "audit-dirs": { + "type": "array", + "items": { + "type": "string" + } + }, + "audit-policies": { + "type": "array", + "items": { + "type": "string" + } + }, + "enable": { + "type": "boolean" + } + } + }, + "canaries": { + "type": "object", + "properties": { + "actions": { + "type": "array", + "items": { + "type": "string" + } + }, + "enable": { + "type": "boolean" + }, + "group": { + "type": "array", + "items": { + "type": "object", + "properties": { + "delete": { + "type": "boolean" + }, + "directories": { + "type": "array", + "items": { + "type": "string" + } + }, + "files": { + "type": "array", + "items": { + "type": "string" + } + }, + "hide-dirs": { + "type": "boolean" + }, + "hide-files": { + "type": "boolean" + }, + "set-audit-acl": { + "type": "boolean" + } + } + } + }, + "whitelist": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "criticality-treshold": { + "type": "integer", + "format": "int64" + }, + "db-path": { + "type": "string" + }, + "dump": { + "type": "object", + "properties": { + "compression": { + "type": "boolean" + }, + "dir": { + "type": "string" + }, + "dump-untracked": { + "type": "boolean" + }, + "max-dumps": { + "type": "integer", + "format": "int64" + } + } + }, + "en-filters": { + "type": "boolean" + }, + "en-hooks": { + "type": "boolean" + }, + "endpoint": { + "type": "boolean" + }, + "etw": { + "type": "object", + "properties": { + "providers": { + "type": "array", + "items": { + "type": "string" + } + }, + "traces": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "forwarder": { + "type": "object", + "properties": { + "local": { + "type": "boolean" + }, + "logging": { + "type": "object", + "properties": { + "dir": { + "type": "string" + }, + "rotation-interval": { + "type": "object" + } + } + }, + "manager": { + "type": "object", + "properties": { + "endpoint-key": { + "type": "string" + }, + "endpoint-uuid": { + "type": "string" + }, + "host": { + "type": "string" + }, + "max-upload-size": { + "type": "integer", + "format": "int64" + }, + "port": { + "type": "integer", + "format": "int64" + }, + "proto": { + "type": "string" + }, + "server-fingerprint": { + "type": "string" + }, + "server-key": { + "type": "string" + }, + "unsafe": { + "type": "boolean" + } + } + } + } + }, + "log-all": { + "type": "boolean" + }, + "logfile": { + "type": "string" + }, + "report": { + "type": "object", + "properties": { + "commands": { + "type": "array", + "items": { + "type": "object", + "properties": { + "args": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": { + "type": "string" + }, + "error": { + "type": "string" + }, + "expect-json": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "stderr": { + "type": "string", + "format": "binary" + }, + "stdout": { + "type": "object" + }, + "timeout": { + "type": "object" + }, + "timestamp": { + "type": "string", + "format": "date" + } + } + } + }, + "en-reporting": { + "type": "boolean" + }, + "osquery": { + "type": "object", + "properties": { + "tables": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "timeout": { + "type": "object" + } + } + }, + "rules": { + "type": "object", + "properties": { + "containers-db": { + "type": "string" + }, + "rules-db": { + "type": "string" + }, + "update-interval": { + "type": "object" + } + } + }, + "sysmon": { + "type": "object", + "properties": { + "archive-directory": { + "type": "string" + }, + "bin": { + "type": "string" + }, + "clean-archived": { + "type": "boolean" + } + } + } + } + }, + "example": { + "db-path": "somerandompath", + "criticality-treshold": 0, + "en-hooks": false, + "en-filters": false, + "logfile": "", + "log-all": false, + "endpoint": false, + "etw": { + "providers": null, + "traces": null + }, + "forwarder": { + "local": false, + "manager": { + "proto": "", + "host": "", + "port": 0, + "endpoint-uuid": "", + "endpoint-key": "", + "server-key": "", + "server-fingerprint": "", + "unsafe": false, + "max-upload-size": 0 + }, + "logging": { + "dir": "", + "rotation-interval": 0 + } + }, + "sysmon": { + "bin": "", + "archive-directory": "", + "clean-archived": false + }, + "actions": { + "available-actions": null, + "low": null, + "medium": null, + "high": null, + "critical": null + }, + "dump": { + "dir": "", + "max-dumps": 0, + "compression": false, + "dump-untracked": false + }, + "report": { + "en-reporting": false, + "osquery": { + "tables": null + }, + "commands": null, + "timeout": 0 + }, + "rules": { + "rules-db": "", + "containers-db": "", + "update-interval": 0 + }, + "audit": { + "enable": false, + "audit-policies": null, + "audit-dirs": null + }, + "canaries": { + "enable": false, + "actions": null, + "whitelist": null, + "group": null + } + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "HTTP 200 response", + "content": { + "application/json": { + "example": { + "data": { + "actions": { + "available-actions": null, + "critical": null, + "high": null, + "low": null, + "medium": null + }, + "audit": { + "audit-dirs": null, + "audit-policies": null, + "enable": false + }, + "canaries": { + "actions": null, + "enable": false, + "group": null, + "whitelist": null + }, + "criticality-treshold": 0, + "db-path": "somerandompath", + "dump": { + "compression": false, + "dir": "", + "dump-untracked": false, + "max-dumps": 0 + }, + "en-filters": false, + "en-hooks": false, + "endpoint": false, + "etw": { + "providers": null, + "traces": null + }, + "forwarder": { + "local": false, + "logging": { + "dir": "", + "rotation-interval": 0 + }, + "manager": { + "endpoint-key": "", + "endpoint-uuid": "", + "host": "", + "max-upload-size": 0, + "port": 0, + "proto": "", + "server-fingerprint": "", + "server-key": "", + "unsafe": false + } + }, + "log-all": false, + "logfile": "", + "report": { + "commands": null, + "en-reporting": false, + "osquery": { + "tables": null + }, + "timeout": 0 + }, + "rules": { + "containers-db": "", + "rules-db": "", + "update-interval": 0 + }, + "sysmon": { + "archive-directory": "", + "bin": "", + "clean-archived": false + } + }, + "error": "", + "message": "OK" + } + } + } + } + } + }, + "delete": { + "tags": [ + "Endpoint Configuration" + ], + "summary": "Delete endpoint configuration (this causes the endpoint to sync again its current configuration)", + "parameters": [ + { + "name": "uuid", + "in": "path", + "description": "uuid path parameter", + "required": true, + "allowEmptyValue": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "HTTP 200 response", + "content": { + "application/json": { + "example": { + "data": null, + "error": "", + "message": "OK" + } + } + } + } + } + } + }, + "/endpoints/{uuid}/detections": { + "get": { + "tags": [ + "Endpoint Log Retrieval" + ], + "summary": "Retrieve detections logs", + "parameters": [ + { + "name": "since", + "in": "query", + "description": "Retrieve logs since date (RFC3339)", + "required": false, + "allowEmptyValue": true, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "until", + "in": "query", + "description": "Retrieve logs until date (RFC3339)", + "required": false, + "allowEmptyValue": true, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "last", + "in": "query", + "description": "Return last logs from duration (ex: '1d' for last day)", + "required": false, + "allowEmptyValue": true, + "schema": { + "type": "string" + } + }, + { + "name": "pivot", + "in": "query", + "description": "Timestamp to pivot around (RFC3339)", + "required": false, + "allowEmptyValue": true, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "delta", + "in": "query", + "description": "Delta duration used to pivot (ex: '5m' to get logs 5min around pivot) ", + "required": false, + "allowEmptyValue": true, + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "description": "Maximum number of reports to return", + "required": false, + "allowEmptyValue": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "skip", + "in": "query", + "description": "Skip number of events", + "required": false, + "allowEmptyValue": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "uuid", + "in": "path", + "description": "uuid path parameter", + "required": true, + "allowEmptyValue": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "HTTP 200 response", + "content": { + "application/json": { + "example": { + "data": [ + { + "Event": { + "Detection": { + "Actions": [], + "Criticality": 8, + "Signature": [ + "NewAutorun" + ] + }, + "EdrData": { + "Endpoint": { + "Group": "", + "Hostname": "OpenHappy", + "IP": "127.0.0.1", + "UUID": "5a92baeb-9384-47d3-92b4-a0db6f9b8c6d" + }, + "Event": { + "Detection": true, + "Hash": "6edf48b18b3eefb73facc7376e8b9606de63933f", + "ReceiptTime": "2022-07-27T08:25:52.162327775Z" + } + }, + "EventData": { + "CommandLine": "\"C:\\ProgramData\\Microsoft\\Windows Defender\\Platform\\4.18.2106.6-0\\MsMpEng.exe\"", + "CurrentDirectory": "C:\\Windows\\system32\\", + "Details": "\"%%ProgramFiles%%\\Windows Defender\\MSASCuiL.exe\"", + "EventType": "SetValue", + "Image": "C:\\ProgramData\\Microsoft\\Windows Defender\\Platform\\4.18.2106.6-0\\MsMpEng.exe", + "ImageHashes": "SHA1=FBF03B5D6DC1A7EDAB0BA8D4DD27291C739E5813,MD5=B1C15F9DB942B373B2FC468B7048E63F,SHA256=1DC05B6DD6281840CEB822604B0E403E499180D636D02EC08AD77B4EB56F1B9C,IMPHASH=8AA2B8727E6858A3557A4C09970B9A5D", + "ImageSignature": "?", + "ImageSignatureStatus": "?", + "ImageSigned": "false", + "IntegrityLevel": "System", + "ProcessGuid": "{515cd0d1-7669-6123-4e00-000000007300}", + "ProcessId": "3276", + "ProcessThreatScore": "56", + "RuleName": "-", + "Services": "WinDefend", + "TargetObject": "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\WindowsDefender", + "User": "NT AUTHORITY\\SYSTEM", + "UtcTime": "2021-08-23 10:20:26.175" + }, + "System": { + "Channel": "Microsoft-Windows-Sysmon/Operational", + "Computer": "DESKTOP-LJRVE06", + "Correlation": { + "ActivityID": "", + "RelatedActivityID": "" + }, + "EventID": 13, + "Execution": { + "ProcessID": 3220, + "ThreadID": 3848 + }, + "Keywords": { "Name": "", "Value": 9223372036854776000 }, @@ -3780,7 +3987,7 @@ var OpenAPIDefinition = ` "Value": 0 }, "TimeCreated": { - "SystemTime": "2022-07-25T15:42:45.373142764+02:00" + "SystemTime": "2022-07-27T10:25:51.115761302+02:00" } } } @@ -3789,9 +3996,9 @@ var OpenAPIDefinition = ` "Event": { "Detection": { "Actions": [], - "Criticality": 4, + "Criticality": 8, "Signature": [ - "SuspiciousService" + "DefenderConfigChanged" ] }, "EdrData": { @@ -3803,51 +4010,27 @@ var OpenAPIDefinition = ` }, "Event": { "Detection": true, - "Hash": "f4d21ac421927aacd195af9018463ac6e8affeb0", - "ReceiptTime": "2022-07-25T13:42:46.389008991Z" + "Hash": "20cd85ba5456e676316c46907efde7b71faf7706", + "ReceiptTime": "2022-07-27T08:25:52.162950825Z" } }, "EventData": { - "Ancestors": "System|C:\\Windows\\System32\\smss.exe|C:\\Windows\\System32\\smss.exe|C:\\Windows\\System32\\wininit.exe|C:\\Windows\\System32\\services.exe", - "CommandLine": "\"C:\\ProgramData\\Microsoft\\Windows Defender\\Platform\\4.18.2106.6-0\\NisSrv.exe\"", - "Company": "Microsoft Corporation", - "CurrentDirectory": "C:\\Windows\\system32\\", - "Description": "Microsoft Network Realtime Inspection Service", - "FileVersion": "4.18.2106.6 (WinBuild.160101.0800)", - "Hashes": "SHA1=924E8FFFA0578AD8C9C902148F93AA08088B1870,MD5=3E373AF37BB6A15EBC5C42EB741B1965,SHA256=3E60923E4690397EF38D5C97CF578E6E3D136D7977B8C58C26C2DE0A8552F30F,IMPHASH=22CB254211A4B914EE99372F003D561A", - "Image": "C:\\ProgramData\\Microsoft\\Windows Defender\\Platform\\4.18.2106.6-0\\NisSrv.exe", - "ImageSize": "2665432", - "IntegrityLevel": "System", - "LogonGuid": "{515cd0d1-7667-6123-e503-000000000000}", - "LogonId": "0x3E5", - "OriginalFileName": "NisSrv.exe", - "ParentCommandLine": "C:\\Windows\\system32\\services.exe", - "ParentImage": "C:\\Windows\\System32\\services.exe", - "ParentIntegrityLevel": "System", - "ParentProcessGuid": "{515cd0d1-7666-6123-0b00-000000007300}", - "ParentProcessId": "692", - "ParentServices": "N/A", - "ParentUser": "NT AUTHORITY\\SYSTEM", - "ProcessGuid": "{515cd0d1-7670-6123-7100-000000007300}", - "ProcessId": "5628", - "Product": "Microsoft® Windows® Operating System", - "RuleName": "-", - "Services": "WdNisSvc", - "TerminalSessionId": "0", - "User": "NT AUTHORITY\\LOCAL SERVICE", - "UtcTime": "2021-08-23 10:20:32.460" + "New Value": "HKLM\\SOFTWARE\\Microsoft\\Windows Defender\\IsServiceRunning = 0x1", + "Old Value": "Default\\IsServiceRunning = 0x0", + "Product Name": "Windows Defender Antivirus", + "Product Version": "4.18.2106.6" }, "System": { - "Channel": "Microsoft-Windows-Sysmon/Operational", + "Channel": "Microsoft-Windows-Windows Defender/Operational", "Computer": "DESKTOP-LJRVE06", "Correlation": { "ActivityID": "", "RelatedActivityID": "" }, - "EventID": 1, + "EventID": 5007, "Execution": { - "ProcessID": 3220, - "ThreadID": 3848 + "ProcessID": 3276, + "ThreadID": 3592 }, "Keywords": { "Name": "", @@ -3858,19 +4041,19 @@ var OpenAPIDefinition = ` "Value": 4 }, "Opcode": { - "Name": "Info", + "Name": "", "Value": 0 }, "Provider": { - "Guid": "{5770385F-C22A-43E0-BF4C-06F5698FFBD9}", - "Name": "Microsoft-Windows-Sysmon" + "Guid": "{11CD958A-C507-4EF3-B3F2-5FD9DFBD2C78}", + "Name": "Microsoft-Windows-Windows Defender" }, "Task": { "Name": "", "Value": 0 }, "TimeCreated": { - "SystemTime": "2022-07-25T15:42:45.373158064+02:00" + "SystemTime": "2022-07-27T10:25:51.115825869+02:00" } } } @@ -3996,14 +4179,14 @@ var OpenAPIDefinition = ` }, "Event": { "Detection": false, - "Hash": "5f8b190da254450eb36d535c8ebfa519284df7c8", - "ReceiptTime": "2022-07-25T13:42:46.385362731Z" + "Hash": "c5a8e92135fbecbbfb6d631acf35be2e579450dc", + "ReceiptTime": "2022-07-27T08:25:52.156504719Z" } }, "EventData": { "CommandLine": "C:\\Windows\\system32\\svchost.exe -k appmodel -p -s StateRepository", "CurrentDirectory": "C:\\Windows\\system32\\", - "Details": "AppResolverUX.App", + "Details": "Binary Data", "EventType": "SetValue", "Image": "C:\\Windows\\system32\\svchost.exe", "ImageHashes": "SHA1=75C5A97F521F760E32A4A9639A653EED862E9C61,MD5=9520A99E77D6196D0D09833146424113,SHA256=DD191A5B23DF92E12A8852291F9FB5ED594B76A28A5A464418442584AFD1E048,IMPHASH=247B9220E5D9B720A82B2C8B5069AD69", @@ -4016,9 +4199,9 @@ var OpenAPIDefinition = ` "ProcessThreatScore": "0", "RuleName": "-", "Services": "StateRepository", - "TargetObject": "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModel\\StateRepository\\Cache\\Application\\Data\\3\\Entrypoint", + "TargetObject": "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModel\\StateRepository\\Cache\\Package\\Data\\1fa\\MutableLocation", "User": "NT AUTHORITY\\SYSTEM", - "UtcTime": "2021-08-23 10:20:30.123" + "UtcTime": "2021-08-23 10:20:29.943" }, "System": { "Channel": "Microsoft-Windows-Sysmon/Operational", @@ -4053,7 +4236,7 @@ var OpenAPIDefinition = ` "Value": 0 }, "TimeCreated": { - "SystemTime": "2022-07-25T15:42:45.372403048+02:00" + "SystemTime": "2022-07-27T10:25:51.114803973+02:00" } } } @@ -4069,29 +4252,29 @@ var OpenAPIDefinition = ` }, "Event": { "Detection": false, - "Hash": "15c800b58e6f2460cb82e157ce5e30465cba2e3c", - "ReceiptTime": "2022-07-25T13:42:46.385713163Z" + "Hash": "c0badd553bf8e9b2e8827392c42a3d5c4852b24f", + "ReceiptTime": "2022-07-27T08:25:52.156933046Z" } }, "EventData": { - "CommandLine": "C:\\Windows\\system32\\svchost.exe -k appmodel -p -s StateRepository", + "CommandLine": "%%SystemRoot%%\\system32\\csrss.exe ObjectDirectory=\\Windows SharedSection=1024,20480,768 Windows=On SubSystemType=Windows ServerDll=basesrv,1 ServerDll=winsrv:UserServerDllInitialization,3 ServerDll=sxssrv,4 ProfileControl=Off MaxRequestThreads=16", "CurrentDirectory": "C:\\Windows\\system32\\", - "Details": "DWORD (0x00000001)", + "Details": "DWORD (0x00000000)", "EventType": "SetValue", - "Image": "C:\\Windows\\system32\\svchost.exe", - "ImageHashes": "SHA1=75C5A97F521F760E32A4A9639A653EED862E9C61,MD5=9520A99E77D6196D0D09833146424113,SHA256=DD191A5B23DF92E12A8852291F9FB5ED594B76A28A5A464418442584AFD1E048,IMPHASH=247B9220E5D9B720A82B2C8B5069AD69", + "Image": "C:\\Windows\\system32\\csrss.exe", + "ImageHashes": "SHA1=2038501676866B87CEE4514CEFF77DAEA9729F30,MD5=23019322FFECB179746210BE52D6DE60,SHA256=F2C7D894ABE8AC0B4C2A597CAA6B3EFE7AD2BDB4226845798D954C5AB9C9BF15,IMPHASH=A96FA9912E09E361274AD77F1A4B252C", "ImageSignature": "?", "ImageSignatureStatus": "?", "ImageSigned": "false", "IntegrityLevel": "System", - "ProcessGuid": "{515cd0d1-7668-6123-3c00-000000007300}", - "ProcessId": "2556", + "ProcessGuid": "{515cd0d1-7665-6123-0900-000000007300}", + "ProcessId": "556", "ProcessThreatScore": "0", "RuleName": "-", - "Services": "StateRepository", - "TargetObject": "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModel\\StateRepository\\Cache\\Package\\Data\\1d2\\Volume", + "Services": "N/A", + "TargetObject": "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AutoRotation\\LastOrientation", "User": "NT AUTHORITY\\SYSTEM", - "UtcTime": "2021-08-23 10:20:29.865" + "UtcTime": "2021-08-23 10:20:21.951" }, "System": { "Channel": "Microsoft-Windows-Sysmon/Operational", @@ -4126,7 +4309,7 @@ var OpenAPIDefinition = ` "Value": 0 }, "TimeCreated": { - "SystemTime": "2022-07-25T15:42:45.372403541+02:00" + "SystemTime": "2022-07-27T10:25:51.114804471+02:00" } } } @@ -4172,30 +4355,30 @@ var OpenAPIDefinition = ` "avg-signature-criticality": 0, "bounded-score": 0, "count-by-signature": { - "DefenderConfigChanged": 6, - "NewAutorun": 27, + "DefenderConfigChanged": 4, + "NewAutorun": 21, "SuspiciousService": 4, - "UnknownServices": 7, - "UntrustedDriverLoaded": 6 + "UnknownServices": 9, + "UntrustedDriverLoaded": 12 }, "count-uniq-signatures": 5, "identifier": "5a92baeb-9384-47d3-92b4-a0db6f9b8c6d", - "median-time": "2022-07-26T12:16:11.570582416+02:00", + "median-time": "2022-07-27T18:16:25.263455529+02:00", "score": 0, "signature-count": 50, "signature-criticality-metric": 0, "signature-diversity": 100, "signatures": [ - "NewAutorun", "UnknownServices", "SuspiciousService", "DefenderConfigChanged", + "NewAutorun", "UntrustedDriverLoaded" ], - "start-time": "2022-07-26T12:16:11.5690665+02:00", + "start-time": "2022-07-27T18:16:25.261859405+02:00", "std-dev-alert-criticality": 0, "std-dev-signature-criticality": -92233720368547760, - "stop-time": "2022-07-26T12:16:11.572098332+02:00", + "stop-time": "2022-07-27T18:16:25.265051653+02:00", "sum-alert-criticality": 0, "sum-rule-criticality": 0, "tactics": null, @@ -4239,30 +4422,30 @@ var OpenAPIDefinition = ` "avg-signature-criticality": 0, "bounded-score": 0, "count-by-signature": { - "DefenderConfigChanged": 6, - "NewAutorun": 27, + "DefenderConfigChanged": 4, + "NewAutorun": 21, "SuspiciousService": 4, - "UnknownServices": 7, - "UntrustedDriverLoaded": 6 + "UnknownServices": 9, + "UntrustedDriverLoaded": 12 }, "count-uniq-signatures": 5, "identifier": "5a92baeb-9384-47d3-92b4-a0db6f9b8c6d", - "median-time": "2022-07-26T12:16:11.570582416+02:00", + "median-time": "2022-07-27T18:16:25.263455529+02:00", "score": 0, "signature-count": 50, "signature-criticality-metric": 0, "signature-diversity": 100, "signatures": [ "NewAutorun", + "UntrustedDriverLoaded", "UnknownServices", "SuspiciousService", - "DefenderConfigChanged", - "UntrustedDriverLoaded" + "DefenderConfigChanged" ], - "start-time": "2022-07-26T12:16:11.5690665+02:00", + "start-time": "2022-07-27T18:16:25.261859405+02:00", "std-dev-alert-criticality": 0, "std-dev-signature-criticality": -92233720368547760, - "stop-time": "2022-07-26T12:16:11.572098332+02:00", + "stop-time": "2022-07-27T18:16:25.265051653+02:00", "sum-alert-criticality": 0, "sum-rule-criticality": 0, "tactics": null, @@ -4348,35 +4531,35 @@ var OpenAPIDefinition = ` { "alert-count": 50, "alert-criticality-metric": 0, - "archived-time": "2022-07-26T12:16:12.611066041+02:00", + "archived-time": "2022-07-27T18:16:26.338676919+02:00", "avg-alert-criticality": 0, "avg-signature-criticality": 0, "bounded-score": 0, "count-by-signature": { - "DefenderConfigChanged": 6, - "NewAutorun": 27, + "DefenderConfigChanged": 4, + "NewAutorun": 21, "SuspiciousService": 4, - "UnknownServices": 7, - "UntrustedDriverLoaded": 6 + "UnknownServices": 9, + "UntrustedDriverLoaded": 12 }, "count-uniq-signatures": 5, "identifier": "5a92baeb-9384-47d3-92b4-a0db6f9b8c6d", - "median-time": "2022-07-26T12:16:11.570582416+02:00", + "median-time": "2022-07-27T18:16:25.263455529+02:00", "score": 0, "signature-count": 50, "signature-criticality-metric": 0, "signature-diversity": 100, "signatures": [ "NewAutorun", + "UntrustedDriverLoaded", "UnknownServices", "SuspiciousService", - "DefenderConfigChanged", - "UntrustedDriverLoaded" + "DefenderConfigChanged" ], - "start-time": "2022-07-26T12:16:11.5690665+02:00", + "start-time": "2022-07-27T18:16:25.261859405+02:00", "std-dev-alert-criticality": 0, "std-dev-signature-criticality": -92233720368547760, - "stop-time": "2022-07-26T12:16:11.572098332+02:00", + "stop-time": "2022-07-27T18:16:25.265051653+02:00", "sum-alert-criticality": 0, "sum-rule-criticality": 0, "tactics": null, @@ -4458,10 +4641,10 @@ var OpenAPIDefinition = ` "example": { "data": [ { - "guuid": "d89f8c3e-731a-3da1-13bf-be45605f8ae3", + "guuid": "051252a8-8a81-e2ed-0244-9c691b39a457", "source": "XyzTIProvider", "type": "domain", - "uuid": "df040f2a-6720-c709-7230-3ee5da9f05ce", + "uuid": "3cb28ad5-0dea-60be-ee0f-a4780ad6cdf9", "value": "some.random.domain" } ], @@ -4509,8 +4692,8 @@ var OpenAPIDefinition = ` }, "example": [ { - "uuid": "df040f2a-6720-c709-7230-3ee5da9f05ce", - "guuid": "d89f8c3e-731a-3da1-13bf-be45605f8ae3", + "uuid": "3cb28ad5-0dea-60be-ee0f-a4780ad6cdf9", + "guuid": "051252a8-8a81-e2ed-0244-9c691b39a457", "source": "XyzTIProvider", "value": "some.random.domain", "type": "domain" @@ -4528,10 +4711,10 @@ var OpenAPIDefinition = ` "example": { "data": [ { - "guuid": "d89f8c3e-731a-3da1-13bf-be45605f8ae3", + "guuid": "051252a8-8a81-e2ed-0244-9c691b39a457", "source": "XyzTIProvider", "type": "domain", - "uuid": "df040f2a-6720-c709-7230-3ee5da9f05ce", + "uuid": "3cb28ad5-0dea-60be-ee0f-a4780ad6cdf9", "value": "some.random.domain" } ], @@ -5028,8 +5211,8 @@ var OpenAPIDefinition = ` "description": "", "group": "", "identifier": "TestAdminUser", - "key": "XvObbqUrV9FQIJDpKSEmUPzgzPhzPEucwF8tV8bGgU9ev5VL7gblj47rzqoNfg08", - "uuid": "888cb092-a409-5ff4-4312-b30cfa1c0862" + "key": "xMcwCEYVJXnRohnXOUn4MEl0N3PWI2o1TwF8PK4TPyktkVK8h600SKSBWBt6lkle", + "uuid": "fdf82040-77ea-a86b-a3fc-278d434d9ca6" }, "error": "", "message": "OK" @@ -5072,7 +5255,7 @@ var OpenAPIDefinition = ` } }, "example": { - "uuid": "0421fb00-28e4-b36f-2068-abe5201ecdce", + "uuid": "774d4102-5671-bf6f-7e5e-73afad8ce299", "identifier": "SecondTestAdmin", "key": "ChangeMe", "group": "CSIRT", @@ -5093,7 +5276,7 @@ var OpenAPIDefinition = ` "group": "CSIRT", "identifier": "SecondTestAdmin", "key": "ChangeMe", - "uuid": "0421fb00-28e4-b36f-2068-abe5201ecdce" + "uuid": "774d4102-5671-bf6f-7e5e-73afad8ce299" }, "error": "", "message": "OK" @@ -5181,7 +5364,7 @@ var OpenAPIDefinition = ` "group": "SOC", "identifier": "SecondTestAdmin", "key": "NewWeakKey", - "uuid": "0421fb00-28e4-b36f-2068-abe5201ecdce" + "uuid": "774d4102-5671-bf6f-7e5e-73afad8ce299" }, "error": "", "message": "OK" @@ -5219,7 +5402,7 @@ var OpenAPIDefinition = ` "group": "SOC", "identifier": "SecondTestAdmin", "key": "NewWeakKey", - "uuid": "0421fb00-28e4-b36f-2068-abe5201ecdce" + "uuid": "774d4102-5671-bf6f-7e5e-73afad8ce299" }, "error": "", "message": "OK" diff --git a/api/server/openapi_test.go b/api/server/openapi_test.go index 3d708af..b5a07e8 100644 --- a/api/server/openapi_test.go +++ b/api/server/openapi_test.go @@ -7,12 +7,14 @@ import ( "fmt" "net/http" "os" + "reflect" "testing" "time" "github.com/0xrawsec/gene/v2/engine" "github.com/0xrawsec/golang-utils/code/builder" "github.com/0xrawsec/toast" + "github.com/0xrawsec/whids/agent/config" "github.com/0xrawsec/whids/agent/sysinfo" "github.com/0xrawsec/whids/api" "github.com/0xrawsec/whids/api/client" @@ -154,7 +156,10 @@ var ( URL: defaultServerConfig.AdminAPIUrl(), }) - systemInfo = &sysinfo.SystemInfo{} + systemInfo = &sysinfo.SystemInfo{} + agentConfig = config.Agent{ + DatabasePath: "somerandompath", + } ) func init() { @@ -302,7 +307,7 @@ func writeConfig(filename string, data []byte) { f.Write(data) } -func TestOpenApi(t *testing.T) { +func TestOpenApiUserManagement(t *testing.T) { f := func(t *testing.T) { // User Management usersPath := openapi.PathItem{ @@ -445,6 +450,84 @@ func TestOpenApiEndpointManagement(t *testing.T) { runAdminApiTest(t, f) } +func TestOpenApiEndpointConfiguration(t *testing.T) { + f := func(t *testing.T) { + tt := toast.FromT(t) + + c := &config.Agent{} + out := &AdminAPIResponse{Data: c} + qptoml := openapi.QueryParameter(api.QpFormat, "toml", "Select output format (allowed toml, json)") + qpjson := openapi.QueryParameter(api.QpFormat, "json", "Select output format (allowed toml, json)") + agentConfigStr, err := utils.TomlString(agentConfig) + tt.CheckErr(err) + tomlBody := openapi.BinaryRequestBody("Configuration content", []byte(agentConfigStr), true) + configAPI := openapi.Operation{ + Parameters: []*openapi.Parameter{ + openapi.PathParameter("uuid", cconf.UUID).Suffix(api.AdmAPIConfigSuffix), + }, + Output: out, + } + + // Endpoint Management + endpointPath := openapi.PathItem{ + Summary: "Endpoint Configuration", + Value: api.AdmAPIEndpointsPath, + } + + openAPI.Do(endpointPath, openapi.Operation{ + Method: "POST", + Summary: "Change endpoint configuration", + Parameters: []*openapi.Parameter{ + openapi.PathParameter("uuid", cconf.UUID).Suffix(api.AdmAPIConfigSuffix), + }, + //RequestBody: openapi.BinaryRequestBody("Configuration content", []byte(agentConfigStr), true), + RequestBody: openapi.JsonRequestBody("Configuration content", agentConfig, true), + Output: AdminAPIResponse{Data: config.Agent{}}, + }) + + // cannot parse toml string into config.Agent + tt.Assert(openAPI.Test(endpointPath, configAPI.GET(qptoml)) != nil) + tt.CheckErr(openAPI.Test(endpointPath, configAPI.GET())) + tt.CheckErr(openAPI.Test(endpointPath, configAPI.GET(qpjson))) + // checking that POST method worked as intented + tt.Assert(reflect.DeepEqual(*c, agentConfig)) + + tt.CheckErr(openAPI.Test(endpointPath, configAPI.DELETE())) + tt.CheckErr(openAPI.Test(endpointPath, configAPI.POST(tomlBody, qptoml))) + c = &config.Agent{} + out.Data = c + tt.CheckErr(openAPI.Test(endpointPath, configAPI.GET())) + tt.Assert(c.DatabasePath == agentConfig.DatabasePath) + + openAPI.Do(endpointPath, openapi.Operation{ + Method: "GET", + Summary: "Get endpoint configuration", + Parameters: []*openapi.Parameter{ + openapi.PathParameter("uuid", cconf.UUID).Suffix(api.AdmAPIConfigSuffix), + }, + Output: AdminAPIResponse{Data: config.Agent{}}, + }) + + // deleting configuration + + tt.CheckErr(openAPI.Test(endpointPath, configAPI.DELETE())) + tt.CheckErr(openAPI.Test(endpointPath, configAPI.GET(qpjson))) + tt.Assert(out.Data == nil) + + openAPI.Do(endpointPath, openapi.Operation{ + Method: "DELETE", + Summary: "Delete endpoint configuration (this causes the endpoint to sync again its current configuration)", + Parameters: []*openapi.Parameter{ + openapi.PathParameter("uuid", cconf.UUID).Suffix(api.AdmAPIConfigSuffix), + }, + Output: AdminAPIResponse{Data: config.Agent{}}, + }) + + } + + runAdminApiTest(t, f) +} + func TestOpenApiEndpointCommands(t *testing.T) { f := func(t *testing.T) { diff --git a/api/server/utils.go b/api/server/utils.go index 51b8ca1..4f616fc 100644 --- a/api/server/utils.go +++ b/api/server/utils.go @@ -8,6 +8,7 @@ import ( "net/http" "github.com/gorilla/mux" + "github.com/pelletier/go-toml" ) func muxGetVar(rq *http.Request, name string) (string, error) { @@ -32,6 +33,15 @@ func readPostAsJSON(rq *http.Request, i interface{}) error { return json.Unmarshal(b, i) } +func readPostAsTOML(rq *http.Request, i interface{}) error { + defer rq.Body.Close() + b, err := ioutil.ReadAll(rq.Body) + if err != nil { + return fmt.Errorf("failed to read POST body: %w", err) + } + return toml.Unmarshal(b, i) +} + func readPostAsXML(rq *http.Request, i interface{}) error { defer rq.Body.Close() b, err := ioutil.ReadAll(rq.Body) diff --git a/doc/admin.openapi.json b/doc/admin.openapi.json index 3dbf535..6a91973 100644 --- a/doc/admin.openapi.json +++ b/doc/admin.openapi.json @@ -68,87 +68,14 @@ "example": { "data": [ { - "Config": { - "Actions": { - "AvailableActions": [], - "Critical": [], - "High": [], - "Low": [], - "Medium": [] - }, - "AuditConfig": { - "AuditDirs": [], - "AuditPolicies": [], - "Enable": false - }, - "CanariesConfig": { - "Actions": [], - "Canaries": [], - "Enable": false, - "Whitelist": [] - }, - "CritTresh": 0, - "DatabasePath": "", - "Dump": { - "Compression": false, - "Dir": "", - "DumpUntracked": false, - "MaxDumps": 0 - }, - "EnableFiltering": false, - "EnableHooks": false, - "Endpoint": false, - "EtwConfig": { - "Providers": [], - "Traces": [] - }, - "FwdConfig": { - "Client": { - "Host": "", - "Key": "", - "MaxUploadSize": 0, - "Port": 0, - "Proto": "", - "ServerFingerprint": "", - "ServerKey": "", - "UUID": "", - "Unsafe": false - }, - "Local": false, - "Logging": { - "Dir": "", - "RotationInterval": 0 - } - }, - "LogAll": false, - "Logfile": "", - "Report": { - "CommandTimeout": 0, - "Commands": [], - "EnableReporting": false, - "OSQuery": { - "Tables": [] - } - }, - "RulesConfig": { - "ContainersDB": "", - "RulesDB": "", - "UpdateInterval": 0 - }, - "Sysmon": { - "ArchiveDirectory": "", - "Bin": "", - "CleanArchived": false - } - }, "criticality": 0, "group": "", "hostname": "OpenHappy", "ip": "127.0.0.1", - "key": "1dBTeTTbXc5OE3qU8XW8WwkHfpGxHPn7eRyVoXmgQLQ7T7vqapOEVCPd3Cqx6MEE", - "last-connection": "2022-07-26T10:16:09.409830822Z", - "last-detection": "2022-07-26T12:16:08.351197299+02:00", - "last-event": "2022-07-26T12:16:08.351197299+02:00", + "key": "LMOwHSiGhg1MNG57lJnlm1Pl9VuEL2nPhLg37D1M4L0DCJgnEgqQHGCYNwySoOcm", + "last-connection": "2022-07-27T16:16:22.005202458Z", + "last-detection": "2022-07-27T18:16:20.951172026+02:00", + "last-event": "2022-07-27T18:16:20.951172026+02:00", "score": 0, "status": "", "system-info": { @@ -221,18 +148,17 @@ "application/json": { "example": { "data": { - "Config": null, "criticality": 0, "group": "", "hostname": "", "ip": "", - "key": "NknjFBuHmm83cfLMIyYBOGTaH6zYovgBxkaD5NNbgaBUKrlvIJYBHgTvm4N0sSxn", + "key": "T1CvqgGOawX0upc0RJP6544JfjJP0Sj38D4t8fYM1IXtbNaOKV5TUYwPeyMzkBKa", "last-connection": "0001-01-01T00:00:00Z", "last-detection": "0001-01-01T00:00:00Z", "last-event": "0001-01-01T00:00:00Z", "score": 0, "status": "", - "uuid": "9bad456e-ab68-06ee-3242-6f0425951686" + "uuid": "f5911ff9-704d-4b50-4a6b-f5f58bbe1a84" }, "error": "", "message": "OK" @@ -272,21 +198,21 @@ "5a92baeb-9384-47d3-92b4-a0db6f9b8c6d": [ { "base-url": "/endpoints/5a92baeb-9384-47d3-92b4-a0db6f9b8c6d/artifacts/5a92baeb-9384-47d3-92b4-a0db6f9b8c6d/3d8441643c204ba9b9dcb5c414b25a3129f66f6c/", - "creation": "2022-07-26T10:16:13.747105168Z", + "creation": "2022-07-27T16:16:27.50137352Z", "event-hash": "3d8441643c204ba9b9dcb5c414b25a3129f66f6c", "files": [ { "name": "bar.txt", "size": 4, - "timestamp": "2022-07-26T10:16:13.747105168Z" + "timestamp": "2022-07-27T16:16:27.50137352Z" }, { "name": "foo.txt", "size": 4, - "timestamp": "2022-07-26T10:16:13.747105168Z" + "timestamp": "2022-07-27T16:16:27.50137352Z" } ], - "modification": "2022-07-26T10:16:13.747105168Z", + "modification": "2022-07-27T16:16:27.50137352Z", "process-guid": "5a92baeb-9384-47d3-92b4-a0db6f9b8c6d" } ] @@ -320,30 +246,30 @@ "avg-signature-criticality": 0, "bounded-score": 0, "count-by-signature": { - "DefenderConfigChanged": 6, - "NewAutorun": 27, + "DefenderConfigChanged": 4, + "NewAutorun": 21, "SuspiciousService": 4, - "UnknownServices": 7, - "UntrustedDriverLoaded": 6 + "UnknownServices": 9, + "UntrustedDriverLoaded": 12 }, "count-uniq-signatures": 5, "identifier": "5a92baeb-9384-47d3-92b4-a0db6f9b8c6d", - "median-time": "2022-07-26T12:16:11.570582416+02:00", + "median-time": "2022-07-27T18:16:25.263455529+02:00", "score": 0, "signature-count": 50, "signature-criticality-metric": 0, "signature-diversity": 100, "signatures": [ "NewAutorun", + "UntrustedDriverLoaded", "UnknownServices", "SuspiciousService", - "DefenderConfigChanged", - "UntrustedDriverLoaded" + "DefenderConfigChanged" ], - "start-time": "2022-07-26T12:16:11.5690665+02:00", + "start-time": "2022-07-27T18:16:25.261859405+02:00", "std-dev-alert-criticality": 0, "std-dev-signature-criticality": -92233720368547760, - "stop-time": "2022-07-26T12:16:11.572098332+02:00", + "stop-time": "2022-07-27T18:16:25.265051653+02:00", "sum-alert-criticality": 0, "sum-rule-criticality": 0, "tactics": null, @@ -404,7 +330,7 @@ }, "name": "osqueryi", "os": "windows", - "uuid": "661564ba-e14c-639e-437b-537abb656bc6" + "uuid": "c94bde56-2a28-cc0a-9f87-5ceda92b49b1" }, "error": "", "message": "OK" @@ -471,7 +397,7 @@ }, "name": "osqueryi", "os": "windows", - "uuid": "661564ba-e14c-639e-437b-537abb656bc6" + "uuid": "c94bde56-2a28-cc0a-9f87-5ceda92b49b1" }, "error": "", "message": "OK" @@ -525,7 +451,7 @@ }, "name": "osqueryi", "os": "windows", - "uuid": "661564ba-e14c-639e-437b-537abb656bc6" + "uuid": "c94bde56-2a28-cc0a-9f87-5ceda92b49b1" }, "error": "", "message": "OK" @@ -581,7 +507,7 @@ }, "name": "sysmon", "os": "windows", - "uuid": "1e4dff28-8d71-34cf-22ef-5ed6d057aef7" + "uuid": "57937591-b3f4-489a-608f-24d6b5d49923" }, "error": "", "message": "OK" @@ -648,7 +574,7 @@ }, "name": "sysmon", "os": "windows", - "uuid": "1e4dff28-8d71-34cf-22ef-5ed6d057aef7" + "uuid": "57937591-b3f4-489a-608f-24d6b5d49923" }, "error": "", "message": "OK" @@ -702,7 +628,7 @@ }, "name": "sysmon", "os": "windows", - "uuid": "1e4dff28-8d71-34cf-22ef-5ed6d057aef7" + "uuid": "57937591-b3f4-489a-608f-24d6b5d49923" }, "error": "", "message": "OK" @@ -1965,103 +1891,13 @@ "application/json": { "example": { "data": { - "Config": { - "Actions": { - "AvailableActions": [], - "Critical": [], - "High": [], - "Low": [], - "Medium": [] - }, - "AuditConfig": { - "AuditDirs": [], - "AuditPolicies": [], - "Enable": false - }, - "CanariesConfig": { - "Actions": [], - "Canaries": [], - "Enable": false, - "Whitelist": [] - }, - "CritTresh": 0, - "DatabasePath": "", - "Dump": { - "Compression": false, - "Dir": "", - "DumpUntracked": false, - "MaxDumps": 0 - }, - "EnableFiltering": false, - "EnableHooks": false, - "Endpoint": false, - "EtwConfig": { - "Providers": [], - "Traces": [] - }, - "FwdConfig": { - "Client": { - "Host": "", - "Key": "", - "MaxUploadSize": 0, - "Port": 0, - "Proto": "", - "ServerFingerprint": "", - "ServerKey": "", - "UUID": "", - "Unsafe": false - }, - "Local": false, - "Logging": { - "Dir": "", - "RotationInterval": 0 - } - }, - "LogAll": false, - "Logfile": "", - "Report": { - "CommandTimeout": 0, - "Commands": [], - "EnableReporting": false, - "OSQuery": { - "Tables": [] - } - }, - "RulesConfig": { - "ContainersDB": "", - "RulesDB": "", - "UpdateInterval": 0 - }, - "Sysmon": { - "ArchiveDirectory": "", - "Bin": "", - "CleanArchived": false - } - }, - "command": { - "args": [], - "background": false, - "completed": true, - "drop": [], - "error": "", - "expect-json": false, - "fetch": {}, - "json": null, - "name": "", - "sent": true, - "sent-time": "2022-07-26T12:16:09.408987389+02:00", - "stderr": "", - "stdout": "", - "timeout": 0, - "uuid": "" - }, "criticality": 0, "group": "", "hostname": "OpenHappy", "ip": "127.0.0.1", - "last-connection": "2022-07-26T10:16:09.409830822Z", - "last-detection": "2022-07-26T12:16:08.351197299+02:00", - "last-event": "2022-07-26T12:16:08.351197299+02:00", + "last-connection": "2022-07-27T16:16:22.005202458Z", + "last-detection": "2022-07-27T18:16:20.951172026+02:00", + "last-event": "2022-07-27T18:16:20.951172026+02:00", "score": 0, "status": "", "system-info": { @@ -2165,37 +2001,134 @@ "schema": { "type": "object", "properties": { - "Config": { + "Item": { + "type": "object" + }, + "command": { + "type": "object", + "properties": { + "args": { + "type": "array", + "items": { + "type": "string" + } + }, + "background": { + "type": "boolean" + }, + "completed": { + "type": "boolean" + }, + "drop": { + "type": "array", + "items": { + "type": "object", + "properties": { + "data": { + "type": "string", + "format": "binary" + }, + "error": { + "type": "string" + }, + "name": { + "type": "string" + }, + "uuid": { + "type": "string" + } + } + } + }, + "error": { + "type": "string" + }, + "expect-json": { + "type": "boolean" + }, + "fetch": { + "type": "object", + "properties": { + "key(string)": { + "type": "object", + "properties": { + "data": { + "type": "string", + "format": "binary" + }, + "error": { + "type": "string" + }, + "name": { + "type": "string" + }, + "uuid": { + "type": "string" + } + } + } + } + }, + "json": { + "type": "object" + }, + "name": { + "type": "string" + }, + "sent": { + "type": "boolean" + }, + "sent-time": { + "type": "string", + "format": "date" + }, + "stderr": { + "type": "string", + "format": "binary" + }, + "stdout": { + "type": "string", + "format": "binary" + }, + "timeout": { + "type": "object" + }, + "uuid": { + "type": "string" + } + } + }, + "config": { "type": "object", "properties": { - "Actions": { + "actions": { "type": "object", "properties": { - "AvailableActions": { + "available-actions": { "type": "array", "items": { "type": "string" } }, - "Critical": { + "critical": { "type": "array", "items": { "type": "string" } }, - "High": { + "high": { "type": "array", "items": { "type": "string" } }, - "Low": { + "low": { "type": "array", "items": { "type": "string" } }, - "Medium": { + "medium": { "type": "array", "items": { "type": "string" @@ -2203,71 +2136,71 @@ } } }, - "AuditConfig": { + "audit": { "type": "object", "properties": { - "AuditDirs": { + "audit-dirs": { "type": "array", "items": { "type": "string" } }, - "AuditPolicies": { + "audit-policies": { "type": "array", "items": { "type": "string" } }, - "Enable": { + "enable": { "type": "boolean" } } }, - "CanariesConfig": { + "canaries": { "type": "object", "properties": { - "Actions": { + "actions": { "type": "array", "items": { "type": "string" } }, - "Canaries": { + "enable": { + "type": "boolean" + }, + "group": { "type": "array", "items": { "type": "object", "properties": { - "Delete": { + "delete": { "type": "boolean" }, - "Directories": { + "directories": { "type": "array", "items": { "type": "string" } }, - "Files": { + "files": { "type": "array", "items": { "type": "string" } }, - "HideDirectories": { + "hide-dirs": { "type": "boolean" }, - "HideFiles": { + "hide-files": { "type": "boolean" }, - "SetAuditACL": { + "set-audit-acl": { "type": "boolean" } } } }, - "Enable": { - "type": "boolean" - }, - "Whitelist": { + "whitelist": { "type": "array", "items": { "type": "string" @@ -2275,50 +2208,50 @@ } } }, - "CritTresh": { + "criticality-treshold": { "type": "integer", "format": "int64" }, - "DatabasePath": { + "db-path": { "type": "string" }, - "Dump": { + "dump": { "type": "object", "properties": { - "Compression": { + "compression": { "type": "boolean" }, - "Dir": { + "dir": { "type": "string" }, - "DumpUntracked": { + "dump-untracked": { "type": "boolean" }, - "MaxDumps": { + "max-dumps": { "type": "integer", "format": "int64" } } }, - "EnableFiltering": { + "en-filters": { "type": "boolean" }, - "EnableHooks": { + "en-hooks": { "type": "boolean" }, - "Endpoint": { + "endpoint": { "type": "boolean" }, - "EtwConfig": { + "etw": { "type": "object", "properties": { - "Providers": { + "providers": { "type": "array", "items": { "type": "string" } }, - "Traces": { + "traces": { "type": "array", "items": { "type": "string" @@ -2326,72 +2259,69 @@ } } }, - "FwdConfig": { + "forwarder": { "type": "object", "properties": { - "Client": { + "local": { + "type": "boolean" + }, + "logging": { + "type": "object", + "properties": { + "dir": { + "type": "string" + }, + "rotation-interval": { + "type": "object" + } + } + }, + "manager": { "type": "object", "properties": { - "Host": { + "endpoint-key": { "type": "string" }, - "Key": { + "endpoint-uuid": { "type": "string" }, - "MaxUploadSize": { + "host": { + "type": "string" + }, + "max-upload-size": { "type": "integer", "format": "int64" }, - "Port": { + "port": { "type": "integer", "format": "int64" }, - "Proto": { - "type": "string" - }, - "ServerFingerprint": { + "proto": { "type": "string" }, - "ServerKey": { + "server-fingerprint": { "type": "string" }, - "UUID": { + "server-key": { "type": "string" }, - "Unsafe": { + "unsafe": { "type": "boolean" } } - }, - "Local": { - "type": "boolean" - }, - "Logging": { - "type": "object", - "properties": { - "Dir": { - "type": "string" - }, - "RotationInterval": { - "type": "object" - } - } } } }, - "LogAll": { + "log-all": { "type": "boolean" }, - "Logfile": { + "logfile": { "type": "string" }, - "Report": { + "report": { "type": "object", "properties": { - "CommandTimeout": { - "type": "object" - }, - "Commands": { + "commands": { "type": "array", "items": { "type": "object", @@ -2431,199 +2361,105 @@ } } }, - "EnableReporting": { + "en-reporting": { "type": "boolean" }, - "OSQuery": { + "osquery": { "type": "object", "properties": { - "Tables": { + "tables": { "type": "array", "items": { "type": "string" } } } + }, + "timeout": { + "type": "object" } } }, - "RulesConfig": { + "rules": { "type": "object", "properties": { - "ContainersDB": { + "containers-db": { "type": "string" }, - "RulesDB": { + "rules-db": { "type": "string" }, - "UpdateInterval": { + "update-interval": { "type": "object" } } }, - "Sysmon": { + "sysmon": { "type": "object", "properties": { - "ArchiveDirectory": { + "archive-directory": { "type": "string" }, - "Bin": { + "bin": { "type": "string" }, - "CleanArchived": { + "clean-archived": { "type": "boolean" } } } } }, - "Item": { - "type": "object" + "criticality": { + "type": "integer", + "format": "int64" }, - "command": { + "group": { + "type": "string" + }, + "hostname": { + "type": "string" + }, + "ip": { + "type": "string" + }, + "key": { + "type": "string" + }, + "last-connection": { + "type": "string", + "format": "date" + }, + "last-detection": { + "type": "string", + "format": "date" + }, + "last-event": { + "type": "string", + "format": "date" + }, + "score": { + "type": "number", + "format": "double" + }, + "status": { + "type": "string" + }, + "system-info": { "type": "object", "properties": { - "args": { - "type": "array", - "items": { - "type": "string" - } - }, - "background": { - "type": "boolean" - }, - "completed": { - "type": "boolean" - }, - "drop": { - "type": "array", - "items": { - "type": "object", - "properties": { - "data": { - "type": "string", - "format": "binary" - }, - "error": { - "type": "string" - }, - "name": { - "type": "string" - }, - "uuid": { - "type": "string" - } + "bios": { + "type": "object", + "properties": { + "date": { + "type": "string" + }, + "version": { + "type": "string" } } }, - "error": { - "type": "string" - }, - "expect-json": { - "type": "boolean" - }, - "fetch": { - "type": "object", - "properties": { - "key(string)": { - "type": "object", - "properties": { - "data": { - "type": "string", - "format": "binary" - }, - "error": { - "type": "string" - }, - "name": { - "type": "string" - }, - "uuid": { - "type": "string" - } - } - } - } - }, - "json": { - "type": "object" - }, - "name": { - "type": "string" - }, - "sent": { - "type": "boolean" - }, - "sent-time": { - "type": "string", - "format": "date" - }, - "stderr": { - "type": "string", - "format": "binary" - }, - "stdout": { - "type": "string", - "format": "binary" - }, - "timeout": { - "type": "object" - }, - "uuid": { - "type": "string" - } - } - }, - "criticality": { - "type": "integer", - "format": "int64" - }, - "group": { - "type": "string" - }, - "hostname": { - "type": "string" - }, - "ip": { - "type": "string" - }, - "key": { - "type": "string" - }, - "last-connection": { - "type": "string", - "format": "date" - }, - "last-detection": { - "type": "string", - "format": "date" - }, - "last-event": { - "type": "string", - "format": "date" - }, - "score": { - "type": "number", - "format": "double" - }, - "status": { - "type": "string" - }, - "system-info": { - "type": "object", - "properties": { - "bios": { - "type": "object", - "properties": { - "date": { - "type": "string" - }, - "version": { - "type": "string" - } - } - }, - "cpu": { + "cpu": { "type": "object", "properties": { "count": { @@ -2754,7 +2590,6 @@ "key": "New Key", "score": 0, "status": "New Status", - "Config": null, "last-event": "0001-01-01T00:00:00Z", "last-detection": "0001-01-01T00:00:00Z", "last-connection": "0001-01-01T00:00:00Z" @@ -2770,103 +2605,13 @@ "application/json": { "example": { "data": { - "Config": { - "Actions": { - "AvailableActions": [], - "Critical": [], - "High": [], - "Low": [], - "Medium": [] - }, - "AuditConfig": { - "AuditDirs": [], - "AuditPolicies": [], - "Enable": false - }, - "CanariesConfig": { - "Actions": [], - "Canaries": [], - "Enable": false, - "Whitelist": [] - }, - "CritTresh": 0, - "DatabasePath": "", - "Dump": { - "Compression": false, - "Dir": "", - "DumpUntracked": false, - "MaxDumps": 0 - }, - "EnableFiltering": false, - "EnableHooks": false, - "Endpoint": false, - "EtwConfig": { - "Providers": [], - "Traces": [] - }, - "FwdConfig": { - "Client": { - "Host": "", - "Key": "", - "MaxUploadSize": 0, - "Port": 0, - "Proto": "", - "ServerFingerprint": "", - "ServerKey": "", - "UUID": "", - "Unsafe": false - }, - "Local": false, - "Logging": { - "Dir": "", - "RotationInterval": 0 - } - }, - "LogAll": false, - "Logfile": "", - "Report": { - "CommandTimeout": 0, - "Commands": [], - "EnableReporting": false, - "OSQuery": { - "Tables": [] - } - }, - "RulesConfig": { - "ContainersDB": "", - "RulesDB": "", - "UpdateInterval": 0 - }, - "Sysmon": { - "ArchiveDirectory": "", - "Bin": "", - "CleanArchived": false - } - }, - "command": { - "args": [], - "background": false, - "completed": true, - "drop": [], - "error": "", - "expect-json": false, - "fetch": {}, - "json": null, - "name": "", - "sent": true, - "sent-time": "2022-07-26T12:16:09.408987389+02:00", - "stderr": "", - "stdout": "", - "timeout": 0, - "uuid": "" - }, "criticality": 0, "group": "New Group", "hostname": "OpenHappy", "ip": "127.0.0.1", - "last-connection": "2022-07-26T10:16:09.409830822Z", - "last-detection": "2022-07-26T12:16:08.351197299+02:00", - "last-event": "2022-07-26T12:16:08.351197299+02:00", + "last-connection": "2022-07-27T16:16:22.005202458Z", + "last-detection": "2022-07-27T18:16:20.951172026+02:00", + "last-event": "2022-07-27T18:16:20.951172026+02:00", "score": 0, "status": "New Status", "system-info": { @@ -2950,103 +2695,13 @@ "application/json": { "example": { "data": { - "Config": { - "Actions": { - "AvailableActions": [], - "Critical": [], - "High": [], - "Low": [], - "Medium": [] - }, - "AuditConfig": { - "AuditDirs": [], - "AuditPolicies": [], - "Enable": false - }, - "CanariesConfig": { - "Actions": [], - "Canaries": [], - "Enable": false, - "Whitelist": [] - }, - "CritTresh": 0, - "DatabasePath": "", - "Dump": { - "Compression": false, - "Dir": "", - "DumpUntracked": false, - "MaxDumps": 0 - }, - "EnableFiltering": false, - "EnableHooks": false, - "Endpoint": false, - "EtwConfig": { - "Providers": [], - "Traces": [] - }, - "FwdConfig": { - "Client": { - "Host": "", - "Key": "", - "MaxUploadSize": 0, - "Port": 0, - "Proto": "", - "ServerFingerprint": "", - "ServerKey": "", - "UUID": "", - "Unsafe": false - }, - "Local": false, - "Logging": { - "Dir": "", - "RotationInterval": 0 - } - }, - "LogAll": false, - "Logfile": "", - "Report": { - "CommandTimeout": 0, - "Commands": [], - "EnableReporting": false, - "OSQuery": { - "Tables": [] - } - }, - "RulesConfig": { - "ContainersDB": "", - "RulesDB": "", - "UpdateInterval": 0 - }, - "Sysmon": { - "ArchiveDirectory": "", - "Bin": "", - "CleanArchived": false - } - }, - "command": { - "args": [], - "background": false, - "completed": true, - "drop": [], - "error": "", - "expect-json": false, - "fetch": {}, - "json": null, - "name": "", - "sent": true, - "sent-time": "2022-07-26T12:16:09.408987389+02:00", - "stderr": "", - "stdout": "", - "timeout": 0, - "uuid": "" - }, "criticality": 0, "group": "New Group", "hostname": "OpenHappy", "ip": "127.0.0.1", - "last-connection": "2022-07-26T10:16:09.409830822Z", - "last-detection": "2022-07-26T12:16:08.351197299+02:00", - "last-event": "2022-07-26T12:16:08.351197299+02:00", + "last-connection": "2022-07-27T16:16:22.005202458Z", + "last-detection": "2022-07-27T18:16:20.951172026+02:00", + "last-event": "2022-07-27T18:16:20.951172026+02:00", "score": 0, "status": "New Status", "system-info": { @@ -3145,21 +2800,21 @@ "data": [ { "base-url": "/endpoints/5a92baeb-9384-47d3-92b4-a0db6f9b8c6d/artifacts/5a92baeb-9384-47d3-92b4-a0db6f9b8c6d/3d8441643c204ba9b9dcb5c414b25a3129f66f6c/", - "creation": "2022-07-26T10:16:13.747105168Z", + "creation": "2022-07-27T16:16:27.50137352Z", "event-hash": "3d8441643c204ba9b9dcb5c414b25a3129f66f6c", "files": [ { "name": "bar.txt", "size": 4, - "timestamp": "2022-07-26T10:16:13.747105168Z" + "timestamp": "2022-07-27T16:16:27.50137352Z" }, { "name": "foo.txt", "size": 4, - "timestamp": "2022-07-26T10:16:13.747105168Z" + "timestamp": "2022-07-27T16:16:27.50137352Z" } ], - "modification": "2022-07-26T10:16:13.747105168Z", + "modification": "2022-07-27T16:16:27.50137352Z", "process-guid": "5a92baeb-9384-47d3-92b4-a0db6f9b8c6d" } ], @@ -3304,11 +2959,11 @@ "json": null, "name": "/usr/bin/printf", "sent": true, - "sent-time": "2022-07-26T12:16:11.484199786+02:00", - "stderr": "", + "sent-time": "2022-07-27T18:16:25.182782394+02:00", + "stderr": null, "stdout": "SGVsbG8gV29ybGQ=", "timeout": 0, - "uuid": "a11af54b-60cb-ce0d-c869-daa4c97d1521" + "uuid": "01bef0d3-40d1-381c-4bd6-763a54b05e8c" }, "error": "", "message": "OK" @@ -3379,79 +3034,6 @@ "application/json": { "example": { "data": { - "Config": { - "Actions": { - "AvailableActions": [], - "Critical": [], - "High": [], - "Low": [], - "Medium": [] - }, - "AuditConfig": { - "AuditDirs": [], - "AuditPolicies": [], - "Enable": false - }, - "CanariesConfig": { - "Actions": [], - "Canaries": [], - "Enable": false, - "Whitelist": [] - }, - "CritTresh": 0, - "DatabasePath": "", - "Dump": { - "Compression": false, - "Dir": "", - "DumpUntracked": false, - "MaxDumps": 0 - }, - "EnableFiltering": false, - "EnableHooks": false, - "Endpoint": false, - "EtwConfig": { - "Providers": [], - "Traces": [] - }, - "FwdConfig": { - "Client": { - "Host": "", - "Key": "", - "MaxUploadSize": 0, - "Port": 0, - "Proto": "", - "ServerFingerprint": "", - "ServerKey": "", - "UUID": "", - "Unsafe": false - }, - "Local": false, - "Logging": { - "Dir": "", - "RotationInterval": 0 - } - }, - "LogAll": false, - "Logfile": "", - "Report": { - "CommandTimeout": 0, - "Commands": [], - "EnableReporting": false, - "OSQuery": { - "Tables": [] - } - }, - "RulesConfig": { - "ContainersDB": "", - "RulesDB": "", - "UpdateInterval": 0 - }, - "Sysmon": { - "ArchiveDirectory": "", - "Bin": "", - "CleanArchived": false - } - }, "command": { "args": [ "Hello World" @@ -3469,16 +3051,16 @@ "stderr": null, "stdout": null, "timeout": 0, - "uuid": "a11af54b-60cb-ce0d-c869-daa4c97d1521" + "uuid": "01bef0d3-40d1-381c-4bd6-763a54b05e8c" }, "criticality": 0, "group": "", "hostname": "OpenHappy", "ip": "127.0.0.1", - "key": "rG1txTFPuFk22sMEHMelMgNtOqszf7BRw8fIN0BvQpn5VCo8ahXs2dyk7zQNgpRb", - "last-connection": "2022-07-26T10:16:10.480698644Z", - "last-detection": "2022-07-26T12:16:09.452094893+02:00", - "last-event": "2022-07-26T12:16:09.452094893+02:00", + "key": "NxIkjKFUuLsPw2TYN2hLkXoWy0hxwpxxkUsmklvMSWgJbjyqdNfgV4Y2G821HzXE", + "last-connection": "2022-07-27T16:16:24.179437494Z", + "last-detection": "2022-07-27T18:16:23.151266867+02:00", + "last-event": "2022-07-27T18:16:23.151266867+02:00", "score": 0, "status": "", "system-info": { @@ -3593,88 +3175,13 @@ } } }, - "/endpoints/{uuid}/detections": { + "/endpoints/{uuid}/config": { "get": { "tags": [ - "Endpoint Log Retrieval" + "Endpoint Configuration" ], - "summary": "Retrieve detections logs", + "summary": "Get endpoint configuration", "parameters": [ - { - "name": "since", - "in": "query", - "description": "Retrieve logs since date (RFC3339)", - "required": false, - "allowEmptyValue": true, - "schema": { - "type": "string", - "format": "date" - } - }, - { - "name": "until", - "in": "query", - "description": "Retrieve logs until date (RFC3339)", - "required": false, - "allowEmptyValue": true, - "schema": { - "type": "string", - "format": "date" - } - }, - { - "name": "last", - "in": "query", - "description": "Return last logs from duration (ex: '1d' for last day)", - "required": false, - "allowEmptyValue": true, - "schema": { - "type": "string" - } - }, - { - "name": "pivot", - "in": "query", - "description": "Timestamp to pivot around (RFC3339)", - "required": false, - "allowEmptyValue": true, - "schema": { - "type": "string", - "format": "date" - } - }, - { - "name": "delta", - "in": "query", - "description": "Delta duration used to pivot (ex: '5m' to get logs 5min around pivot) ", - "required": false, - "allowEmptyValue": true, - "schema": { - "type": "string" - } - }, - { - "name": "limit", - "in": "query", - "description": "Maximum number of reports to return", - "required": false, - "allowEmptyValue": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "skip", - "in": "query", - "description": "Skip number of events", - "required": false, - "allowEmptyValue": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, { "name": "uuid", "in": "path", @@ -3692,72 +3199,772 @@ "content": { "application/json": { "example": { - "data": [ - { - "Event": { - "Detection": { - "Actions": [], - "Criticality": 10, - "Signature": [ - "UnknownServices" - ] - }, - "EdrData": { - "Endpoint": { - "Group": "", - "Hostname": "OpenHappy", - "IP": "127.0.0.1", - "UUID": "5a92baeb-9384-47d3-92b4-a0db6f9b8c6d" - }, - "Event": { - "Detection": true, - "Hash": "0f0d61843edd1cdeddb710ecd38c4813d406e8bc", - "ReceiptTime": "2022-07-25T13:42:46.388637264Z" - } - }, - "EventData": { - "Ancestors": "System|C:\\Windows\\System32\\smss.exe|C:\\Windows\\System32\\smss.exe|C:\\Windows\\System32\\wininit.exe|C:\\Windows\\System32\\services.exe", - "CommandLine": "C:\\Windows\\System32\\VBoxService.exe", - "Company": "Oracle Corporation", - "CurrentDirectory": "C:\\Windows\\system32\\", - "Description": "VirtualBox Guest Additions Service", - "FileVersion": "6.0.8.130520", - "Hashes": "SHA1=AE49D900887E95D7B3040BFD2C888D3439F94035,MD5=3001126B78719A1189A0A5270DA316A0,SHA256=9A66844E7ADA8E2D1D454136D68413CE74D90004BAD754D79DAA1A020A27E86C,IMPHASH=6A98677D1BE25D4274AAA7C9C37E832F", - "Image": "C:\\Windows\\System32\\VBoxService.exe", - "ImageSize": "2732048", - "IntegrityLevel": "System", - "LogonGuid": "{515cd0d1-7667-6123-e703-000000000000}", - "LogonId": "0x3E7", - "OriginalFileName": "VBoxService.exe", - "ParentCommandLine": "C:\\Windows\\system32\\services.exe", - "ParentImage": "C:\\Windows\\System32\\services.exe", - "ParentIntegrityLevel": "System", - "ParentProcessGuid": "{515cd0d1-7666-6123-0b00-000000007300}", - "ParentProcessId": "692", - "ParentServices": "N/A", - "ParentUser": "NT AUTHORITY\\SYSTEM", - "ProcessGuid": "{515cd0d1-7668-6123-2300-000000007300}", - "ProcessId": "1592", - "Product": "Oracle VM VirtualBox Guest Additions", - "RuleName": "-", - "Services": "VBoxService", - "TerminalSessionId": "0", - "User": "NT AUTHORITY\\SYSTEM", - "UtcTime": "2021-08-23 10:20:24.054" - }, - "System": { - "Channel": "Microsoft-Windows-Sysmon/Operational", - "Computer": "DESKTOP-LJRVE06", - "Correlation": { - "ActivityID": "", - "RelatedActivityID": "" - }, - "EventID": 1, - "Execution": { - "ProcessID": 3220, - "ThreadID": 3848 - }, - "Keywords": { + "data": { + "actions": { + "available-actions": null, + "critical": [], + "high": [], + "low": [], + "medium": [] + }, + "audit": { + "audit-dirs": [], + "audit-policies": [], + "enable": false + }, + "canaries": { + "actions": [], + "enable": false, + "group": null, + "whitelist": [] + }, + "criticality-treshold": 0, + "db-path": "somerandompath", + "dump": { + "compression": false, + "dir": "", + "dump-untracked": false, + "max-dumps": 0 + }, + "en-filters": false, + "en-hooks": false, + "endpoint": false, + "etw": { + "providers": [], + "traces": [] + }, + "forwarder": { + "local": false, + "logging": { + "dir": "", + "rotation-interval": 0 + }, + "manager": { + "endpoint-key": "", + "endpoint-uuid": "", + "host": "", + "max-upload-size": 0, + "port": 0, + "proto": "", + "server-fingerprint": "", + "server-key": "", + "unsafe": false + } + }, + "log-all": false, + "logfile": "", + "report": { + "commands": null, + "en-reporting": false, + "osquery": { + "tables": [] + }, + "timeout": 0 + }, + "rules": { + "containers-db": "", + "rules-db": "", + "update-interval": 0 + }, + "sysmon": { + "archive-directory": "", + "bin": "", + "clean-archived": false + } + }, + "error": "", + "message": "OK" + } + } + } + } + } + }, + "post": { + "tags": [ + "Endpoint Configuration" + ], + "summary": "Change endpoint configuration", + "parameters": [ + { + "name": "uuid", + "in": "path", + "description": "uuid path parameter", + "required": true, + "allowEmptyValue": false, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "Configuration content", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "actions": { + "type": "object", + "properties": { + "available-actions": { + "type": "array", + "items": { + "type": "string" + } + }, + "critical": { + "type": "array", + "items": { + "type": "string" + } + }, + "high": { + "type": "array", + "items": { + "type": "string" + } + }, + "low": { + "type": "array", + "items": { + "type": "string" + } + }, + "medium": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "audit": { + "type": "object", + "properties": { + "audit-dirs": { + "type": "array", + "items": { + "type": "string" + } + }, + "audit-policies": { + "type": "array", + "items": { + "type": "string" + } + }, + "enable": { + "type": "boolean" + } + } + }, + "canaries": { + "type": "object", + "properties": { + "actions": { + "type": "array", + "items": { + "type": "string" + } + }, + "enable": { + "type": "boolean" + }, + "group": { + "type": "array", + "items": { + "type": "object", + "properties": { + "delete": { + "type": "boolean" + }, + "directories": { + "type": "array", + "items": { + "type": "string" + } + }, + "files": { + "type": "array", + "items": { + "type": "string" + } + }, + "hide-dirs": { + "type": "boolean" + }, + "hide-files": { + "type": "boolean" + }, + "set-audit-acl": { + "type": "boolean" + } + } + } + }, + "whitelist": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "criticality-treshold": { + "type": "integer", + "format": "int64" + }, + "db-path": { + "type": "string" + }, + "dump": { + "type": "object", + "properties": { + "compression": { + "type": "boolean" + }, + "dir": { + "type": "string" + }, + "dump-untracked": { + "type": "boolean" + }, + "max-dumps": { + "type": "integer", + "format": "int64" + } + } + }, + "en-filters": { + "type": "boolean" + }, + "en-hooks": { + "type": "boolean" + }, + "endpoint": { + "type": "boolean" + }, + "etw": { + "type": "object", + "properties": { + "providers": { + "type": "array", + "items": { + "type": "string" + } + }, + "traces": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "forwarder": { + "type": "object", + "properties": { + "local": { + "type": "boolean" + }, + "logging": { + "type": "object", + "properties": { + "dir": { + "type": "string" + }, + "rotation-interval": { + "type": "object" + } + } + }, + "manager": { + "type": "object", + "properties": { + "endpoint-key": { + "type": "string" + }, + "endpoint-uuid": { + "type": "string" + }, + "host": { + "type": "string" + }, + "max-upload-size": { + "type": "integer", + "format": "int64" + }, + "port": { + "type": "integer", + "format": "int64" + }, + "proto": { + "type": "string" + }, + "server-fingerprint": { + "type": "string" + }, + "server-key": { + "type": "string" + }, + "unsafe": { + "type": "boolean" + } + } + } + } + }, + "log-all": { + "type": "boolean" + }, + "logfile": { + "type": "string" + }, + "report": { + "type": "object", + "properties": { + "commands": { + "type": "array", + "items": { + "type": "object", + "properties": { + "args": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": { + "type": "string" + }, + "error": { + "type": "string" + }, + "expect-json": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "stderr": { + "type": "string", + "format": "binary" + }, + "stdout": { + "type": "object" + }, + "timeout": { + "type": "object" + }, + "timestamp": { + "type": "string", + "format": "date" + } + } + } + }, + "en-reporting": { + "type": "boolean" + }, + "osquery": { + "type": "object", + "properties": { + "tables": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "timeout": { + "type": "object" + } + } + }, + "rules": { + "type": "object", + "properties": { + "containers-db": { + "type": "string" + }, + "rules-db": { + "type": "string" + }, + "update-interval": { + "type": "object" + } + } + }, + "sysmon": { + "type": "object", + "properties": { + "archive-directory": { + "type": "string" + }, + "bin": { + "type": "string" + }, + "clean-archived": { + "type": "boolean" + } + } + } + } + }, + "example": { + "db-path": "somerandompath", + "criticality-treshold": 0, + "en-hooks": false, + "en-filters": false, + "logfile": "", + "log-all": false, + "endpoint": false, + "etw": { + "providers": null, + "traces": null + }, + "forwarder": { + "local": false, + "manager": { + "proto": "", + "host": "", + "port": 0, + "endpoint-uuid": "", + "endpoint-key": "", + "server-key": "", + "server-fingerprint": "", + "unsafe": false, + "max-upload-size": 0 + }, + "logging": { + "dir": "", + "rotation-interval": 0 + } + }, + "sysmon": { + "bin": "", + "archive-directory": "", + "clean-archived": false + }, + "actions": { + "available-actions": null, + "low": null, + "medium": null, + "high": null, + "critical": null + }, + "dump": { + "dir": "", + "max-dumps": 0, + "compression": false, + "dump-untracked": false + }, + "report": { + "en-reporting": false, + "osquery": { + "tables": null + }, + "commands": null, + "timeout": 0 + }, + "rules": { + "rules-db": "", + "containers-db": "", + "update-interval": 0 + }, + "audit": { + "enable": false, + "audit-policies": null, + "audit-dirs": null + }, + "canaries": { + "enable": false, + "actions": null, + "whitelist": null, + "group": null + } + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "HTTP 200 response", + "content": { + "application/json": { + "example": { + "data": { + "actions": { + "available-actions": null, + "critical": null, + "high": null, + "low": null, + "medium": null + }, + "audit": { + "audit-dirs": null, + "audit-policies": null, + "enable": false + }, + "canaries": { + "actions": null, + "enable": false, + "group": null, + "whitelist": null + }, + "criticality-treshold": 0, + "db-path": "somerandompath", + "dump": { + "compression": false, + "dir": "", + "dump-untracked": false, + "max-dumps": 0 + }, + "en-filters": false, + "en-hooks": false, + "endpoint": false, + "etw": { + "providers": null, + "traces": null + }, + "forwarder": { + "local": false, + "logging": { + "dir": "", + "rotation-interval": 0 + }, + "manager": { + "endpoint-key": "", + "endpoint-uuid": "", + "host": "", + "max-upload-size": 0, + "port": 0, + "proto": "", + "server-fingerprint": "", + "server-key": "", + "unsafe": false + } + }, + "log-all": false, + "logfile": "", + "report": { + "commands": null, + "en-reporting": false, + "osquery": { + "tables": null + }, + "timeout": 0 + }, + "rules": { + "containers-db": "", + "rules-db": "", + "update-interval": 0 + }, + "sysmon": { + "archive-directory": "", + "bin": "", + "clean-archived": false + } + }, + "error": "", + "message": "OK" + } + } + } + } + } + }, + "delete": { + "tags": [ + "Endpoint Configuration" + ], + "summary": "Delete endpoint configuration (this causes the endpoint to sync again its current configuration)", + "parameters": [ + { + "name": "uuid", + "in": "path", + "description": "uuid path parameter", + "required": true, + "allowEmptyValue": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "HTTP 200 response", + "content": { + "application/json": { + "example": { + "data": null, + "error": "", + "message": "OK" + } + } + } + } + } + } + }, + "/endpoints/{uuid}/detections": { + "get": { + "tags": [ + "Endpoint Log Retrieval" + ], + "summary": "Retrieve detections logs", + "parameters": [ + { + "name": "since", + "in": "query", + "description": "Retrieve logs since date (RFC3339)", + "required": false, + "allowEmptyValue": true, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "until", + "in": "query", + "description": "Retrieve logs until date (RFC3339)", + "required": false, + "allowEmptyValue": true, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "last", + "in": "query", + "description": "Return last logs from duration (ex: '1d' for last day)", + "required": false, + "allowEmptyValue": true, + "schema": { + "type": "string" + } + }, + { + "name": "pivot", + "in": "query", + "description": "Timestamp to pivot around (RFC3339)", + "required": false, + "allowEmptyValue": true, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "delta", + "in": "query", + "description": "Delta duration used to pivot (ex: '5m' to get logs 5min around pivot) ", + "required": false, + "allowEmptyValue": true, + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "description": "Maximum number of reports to return", + "required": false, + "allowEmptyValue": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "skip", + "in": "query", + "description": "Skip number of events", + "required": false, + "allowEmptyValue": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "uuid", + "in": "path", + "description": "uuid path parameter", + "required": true, + "allowEmptyValue": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "HTTP 200 response", + "content": { + "application/json": { + "example": { + "data": [ + { + "Event": { + "Detection": { + "Actions": [], + "Criticality": 8, + "Signature": [ + "NewAutorun" + ] + }, + "EdrData": { + "Endpoint": { + "Group": "", + "Hostname": "OpenHappy", + "IP": "127.0.0.1", + "UUID": "5a92baeb-9384-47d3-92b4-a0db6f9b8c6d" + }, + "Event": { + "Detection": true, + "Hash": "6edf48b18b3eefb73facc7376e8b9606de63933f", + "ReceiptTime": "2022-07-27T08:25:52.162327775Z" + } + }, + "EventData": { + "CommandLine": "\"C:\\ProgramData\\Microsoft\\Windows Defender\\Platform\\4.18.2106.6-0\\MsMpEng.exe\"", + "CurrentDirectory": "C:\\Windows\\system32\\", + "Details": "\"%%ProgramFiles%%\\Windows Defender\\MSASCuiL.exe\"", + "EventType": "SetValue", + "Image": "C:\\ProgramData\\Microsoft\\Windows Defender\\Platform\\4.18.2106.6-0\\MsMpEng.exe", + "ImageHashes": "SHA1=FBF03B5D6DC1A7EDAB0BA8D4DD27291C739E5813,MD5=B1C15F9DB942B373B2FC468B7048E63F,SHA256=1DC05B6DD6281840CEB822604B0E403E499180D636D02EC08AD77B4EB56F1B9C,IMPHASH=8AA2B8727E6858A3557A4C09970B9A5D", + "ImageSignature": "?", + "ImageSignatureStatus": "?", + "ImageSigned": "false", + "IntegrityLevel": "System", + "ProcessGuid": "{515cd0d1-7669-6123-4e00-000000007300}", + "ProcessId": "3276", + "ProcessThreatScore": "56", + "RuleName": "-", + "Services": "WinDefend", + "TargetObject": "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\WindowsDefender", + "User": "NT AUTHORITY\\SYSTEM", + "UtcTime": "2021-08-23 10:20:26.175" + }, + "System": { + "Channel": "Microsoft-Windows-Sysmon/Operational", + "Computer": "DESKTOP-LJRVE06", + "Correlation": { + "ActivityID": "", + "RelatedActivityID": "" + }, + "EventID": 13, + "Execution": { + "ProcessID": 3220, + "ThreadID": 3848 + }, + "Keywords": { "Name": "", "Value": 9223372036854776000 }, @@ -3778,7 +3985,7 @@ "Value": 0 }, "TimeCreated": { - "SystemTime": "2022-07-25T15:42:45.373142764+02:00" + "SystemTime": "2022-07-27T10:25:51.115761302+02:00" } } } @@ -3787,9 +3994,9 @@ "Event": { "Detection": { "Actions": [], - "Criticality": 4, + "Criticality": 8, "Signature": [ - "SuspiciousService" + "DefenderConfigChanged" ] }, "EdrData": { @@ -3801,51 +4008,27 @@ }, "Event": { "Detection": true, - "Hash": "f4d21ac421927aacd195af9018463ac6e8affeb0", - "ReceiptTime": "2022-07-25T13:42:46.389008991Z" + "Hash": "20cd85ba5456e676316c46907efde7b71faf7706", + "ReceiptTime": "2022-07-27T08:25:52.162950825Z" } }, "EventData": { - "Ancestors": "System|C:\\Windows\\System32\\smss.exe|C:\\Windows\\System32\\smss.exe|C:\\Windows\\System32\\wininit.exe|C:\\Windows\\System32\\services.exe", - "CommandLine": "\"C:\\ProgramData\\Microsoft\\Windows Defender\\Platform\\4.18.2106.6-0\\NisSrv.exe\"", - "Company": "Microsoft Corporation", - "CurrentDirectory": "C:\\Windows\\system32\\", - "Description": "Microsoft Network Realtime Inspection Service", - "FileVersion": "4.18.2106.6 (WinBuild.160101.0800)", - "Hashes": "SHA1=924E8FFFA0578AD8C9C902148F93AA08088B1870,MD5=3E373AF37BB6A15EBC5C42EB741B1965,SHA256=3E60923E4690397EF38D5C97CF578E6E3D136D7977B8C58C26C2DE0A8552F30F,IMPHASH=22CB254211A4B914EE99372F003D561A", - "Image": "C:\\ProgramData\\Microsoft\\Windows Defender\\Platform\\4.18.2106.6-0\\NisSrv.exe", - "ImageSize": "2665432", - "IntegrityLevel": "System", - "LogonGuid": "{515cd0d1-7667-6123-e503-000000000000}", - "LogonId": "0x3E5", - "OriginalFileName": "NisSrv.exe", - "ParentCommandLine": "C:\\Windows\\system32\\services.exe", - "ParentImage": "C:\\Windows\\System32\\services.exe", - "ParentIntegrityLevel": "System", - "ParentProcessGuid": "{515cd0d1-7666-6123-0b00-000000007300}", - "ParentProcessId": "692", - "ParentServices": "N/A", - "ParentUser": "NT AUTHORITY\\SYSTEM", - "ProcessGuid": "{515cd0d1-7670-6123-7100-000000007300}", - "ProcessId": "5628", - "Product": "Microsoft® Windows® Operating System", - "RuleName": "-", - "Services": "WdNisSvc", - "TerminalSessionId": "0", - "User": "NT AUTHORITY\\LOCAL SERVICE", - "UtcTime": "2021-08-23 10:20:32.460" + "New Value": "HKLM\\SOFTWARE\\Microsoft\\Windows Defender\\IsServiceRunning = 0x1", + "Old Value": "Default\\IsServiceRunning = 0x0", + "Product Name": "Windows Defender Antivirus", + "Product Version": "4.18.2106.6" }, "System": { - "Channel": "Microsoft-Windows-Sysmon/Operational", + "Channel": "Microsoft-Windows-Windows Defender/Operational", "Computer": "DESKTOP-LJRVE06", "Correlation": { "ActivityID": "", "RelatedActivityID": "" }, - "EventID": 1, + "EventID": 5007, "Execution": { - "ProcessID": 3220, - "ThreadID": 3848 + "ProcessID": 3276, + "ThreadID": 3592 }, "Keywords": { "Name": "", @@ -3856,19 +4039,19 @@ "Value": 4 }, "Opcode": { - "Name": "Info", + "Name": "", "Value": 0 }, "Provider": { - "Guid": "{5770385F-C22A-43E0-BF4C-06F5698FFBD9}", - "Name": "Microsoft-Windows-Sysmon" + "Guid": "{11CD958A-C507-4EF3-B3F2-5FD9DFBD2C78}", + "Name": "Microsoft-Windows-Windows Defender" }, "Task": { "Name": "", "Value": 0 }, "TimeCreated": { - "SystemTime": "2022-07-25T15:42:45.373158064+02:00" + "SystemTime": "2022-07-27T10:25:51.115825869+02:00" } } } @@ -3994,14 +4177,14 @@ }, "Event": { "Detection": false, - "Hash": "5f8b190da254450eb36d535c8ebfa519284df7c8", - "ReceiptTime": "2022-07-25T13:42:46.385362731Z" + "Hash": "c5a8e92135fbecbbfb6d631acf35be2e579450dc", + "ReceiptTime": "2022-07-27T08:25:52.156504719Z" } }, "EventData": { "CommandLine": "C:\\Windows\\system32\\svchost.exe -k appmodel -p -s StateRepository", "CurrentDirectory": "C:\\Windows\\system32\\", - "Details": "AppResolverUX.App", + "Details": "Binary Data", "EventType": "SetValue", "Image": "C:\\Windows\\system32\\svchost.exe", "ImageHashes": "SHA1=75C5A97F521F760E32A4A9639A653EED862E9C61,MD5=9520A99E77D6196D0D09833146424113,SHA256=DD191A5B23DF92E12A8852291F9FB5ED594B76A28A5A464418442584AFD1E048,IMPHASH=247B9220E5D9B720A82B2C8B5069AD69", @@ -4014,9 +4197,9 @@ "ProcessThreatScore": "0", "RuleName": "-", "Services": "StateRepository", - "TargetObject": "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModel\\StateRepository\\Cache\\Application\\Data\\3\\Entrypoint", + "TargetObject": "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModel\\StateRepository\\Cache\\Package\\Data\\1fa\\MutableLocation", "User": "NT AUTHORITY\\SYSTEM", - "UtcTime": "2021-08-23 10:20:30.123" + "UtcTime": "2021-08-23 10:20:29.943" }, "System": { "Channel": "Microsoft-Windows-Sysmon/Operational", @@ -4051,7 +4234,7 @@ "Value": 0 }, "TimeCreated": { - "SystemTime": "2022-07-25T15:42:45.372403048+02:00" + "SystemTime": "2022-07-27T10:25:51.114803973+02:00" } } } @@ -4067,29 +4250,29 @@ }, "Event": { "Detection": false, - "Hash": "15c800b58e6f2460cb82e157ce5e30465cba2e3c", - "ReceiptTime": "2022-07-25T13:42:46.385713163Z" + "Hash": "c0badd553bf8e9b2e8827392c42a3d5c4852b24f", + "ReceiptTime": "2022-07-27T08:25:52.156933046Z" } }, "EventData": { - "CommandLine": "C:\\Windows\\system32\\svchost.exe -k appmodel -p -s StateRepository", + "CommandLine": "%%SystemRoot%%\\system32\\csrss.exe ObjectDirectory=\\Windows SharedSection=1024,20480,768 Windows=On SubSystemType=Windows ServerDll=basesrv,1 ServerDll=winsrv:UserServerDllInitialization,3 ServerDll=sxssrv,4 ProfileControl=Off MaxRequestThreads=16", "CurrentDirectory": "C:\\Windows\\system32\\", - "Details": "DWORD (0x00000001)", + "Details": "DWORD (0x00000000)", "EventType": "SetValue", - "Image": "C:\\Windows\\system32\\svchost.exe", - "ImageHashes": "SHA1=75C5A97F521F760E32A4A9639A653EED862E9C61,MD5=9520A99E77D6196D0D09833146424113,SHA256=DD191A5B23DF92E12A8852291F9FB5ED594B76A28A5A464418442584AFD1E048,IMPHASH=247B9220E5D9B720A82B2C8B5069AD69", + "Image": "C:\\Windows\\system32\\csrss.exe", + "ImageHashes": "SHA1=2038501676866B87CEE4514CEFF77DAEA9729F30,MD5=23019322FFECB179746210BE52D6DE60,SHA256=F2C7D894ABE8AC0B4C2A597CAA6B3EFE7AD2BDB4226845798D954C5AB9C9BF15,IMPHASH=A96FA9912E09E361274AD77F1A4B252C", "ImageSignature": "?", "ImageSignatureStatus": "?", "ImageSigned": "false", "IntegrityLevel": "System", - "ProcessGuid": "{515cd0d1-7668-6123-3c00-000000007300}", - "ProcessId": "2556", + "ProcessGuid": "{515cd0d1-7665-6123-0900-000000007300}", + "ProcessId": "556", "ProcessThreatScore": "0", "RuleName": "-", - "Services": "StateRepository", - "TargetObject": "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModel\\StateRepository\\Cache\\Package\\Data\\1d2\\Volume", + "Services": "N/A", + "TargetObject": "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AutoRotation\\LastOrientation", "User": "NT AUTHORITY\\SYSTEM", - "UtcTime": "2021-08-23 10:20:29.865" + "UtcTime": "2021-08-23 10:20:21.951" }, "System": { "Channel": "Microsoft-Windows-Sysmon/Operational", @@ -4124,7 +4307,7 @@ "Value": 0 }, "TimeCreated": { - "SystemTime": "2022-07-25T15:42:45.372403541+02:00" + "SystemTime": "2022-07-27T10:25:51.114804471+02:00" } } } @@ -4170,30 +4353,30 @@ "avg-signature-criticality": 0, "bounded-score": 0, "count-by-signature": { - "DefenderConfigChanged": 6, - "NewAutorun": 27, + "DefenderConfigChanged": 4, + "NewAutorun": 21, "SuspiciousService": 4, - "UnknownServices": 7, - "UntrustedDriverLoaded": 6 + "UnknownServices": 9, + "UntrustedDriverLoaded": 12 }, "count-uniq-signatures": 5, "identifier": "5a92baeb-9384-47d3-92b4-a0db6f9b8c6d", - "median-time": "2022-07-26T12:16:11.570582416+02:00", + "median-time": "2022-07-27T18:16:25.263455529+02:00", "score": 0, "signature-count": 50, "signature-criticality-metric": 0, "signature-diversity": 100, "signatures": [ - "NewAutorun", "UnknownServices", "SuspiciousService", "DefenderConfigChanged", + "NewAutorun", "UntrustedDriverLoaded" ], - "start-time": "2022-07-26T12:16:11.5690665+02:00", + "start-time": "2022-07-27T18:16:25.261859405+02:00", "std-dev-alert-criticality": 0, "std-dev-signature-criticality": -92233720368547760, - "stop-time": "2022-07-26T12:16:11.572098332+02:00", + "stop-time": "2022-07-27T18:16:25.265051653+02:00", "sum-alert-criticality": 0, "sum-rule-criticality": 0, "tactics": null, @@ -4237,30 +4420,30 @@ "avg-signature-criticality": 0, "bounded-score": 0, "count-by-signature": { - "DefenderConfigChanged": 6, - "NewAutorun": 27, + "DefenderConfigChanged": 4, + "NewAutorun": 21, "SuspiciousService": 4, - "UnknownServices": 7, - "UntrustedDriverLoaded": 6 + "UnknownServices": 9, + "UntrustedDriverLoaded": 12 }, "count-uniq-signatures": 5, "identifier": "5a92baeb-9384-47d3-92b4-a0db6f9b8c6d", - "median-time": "2022-07-26T12:16:11.570582416+02:00", + "median-time": "2022-07-27T18:16:25.263455529+02:00", "score": 0, "signature-count": 50, "signature-criticality-metric": 0, "signature-diversity": 100, "signatures": [ "NewAutorun", + "UntrustedDriverLoaded", "UnknownServices", "SuspiciousService", - "DefenderConfigChanged", - "UntrustedDriverLoaded" + "DefenderConfigChanged" ], - "start-time": "2022-07-26T12:16:11.5690665+02:00", + "start-time": "2022-07-27T18:16:25.261859405+02:00", "std-dev-alert-criticality": 0, "std-dev-signature-criticality": -92233720368547760, - "stop-time": "2022-07-26T12:16:11.572098332+02:00", + "stop-time": "2022-07-27T18:16:25.265051653+02:00", "sum-alert-criticality": 0, "sum-rule-criticality": 0, "tactics": null, @@ -4346,35 +4529,35 @@ { "alert-count": 50, "alert-criticality-metric": 0, - "archived-time": "2022-07-26T12:16:12.611066041+02:00", + "archived-time": "2022-07-27T18:16:26.338676919+02:00", "avg-alert-criticality": 0, "avg-signature-criticality": 0, "bounded-score": 0, "count-by-signature": { - "DefenderConfigChanged": 6, - "NewAutorun": 27, + "DefenderConfigChanged": 4, + "NewAutorun": 21, "SuspiciousService": 4, - "UnknownServices": 7, - "UntrustedDriverLoaded": 6 + "UnknownServices": 9, + "UntrustedDriverLoaded": 12 }, "count-uniq-signatures": 5, "identifier": "5a92baeb-9384-47d3-92b4-a0db6f9b8c6d", - "median-time": "2022-07-26T12:16:11.570582416+02:00", + "median-time": "2022-07-27T18:16:25.263455529+02:00", "score": 0, "signature-count": 50, "signature-criticality-metric": 0, "signature-diversity": 100, "signatures": [ "NewAutorun", + "UntrustedDriverLoaded", "UnknownServices", "SuspiciousService", - "DefenderConfigChanged", - "UntrustedDriverLoaded" + "DefenderConfigChanged" ], - "start-time": "2022-07-26T12:16:11.5690665+02:00", + "start-time": "2022-07-27T18:16:25.261859405+02:00", "std-dev-alert-criticality": 0, "std-dev-signature-criticality": -92233720368547760, - "stop-time": "2022-07-26T12:16:11.572098332+02:00", + "stop-time": "2022-07-27T18:16:25.265051653+02:00", "sum-alert-criticality": 0, "sum-rule-criticality": 0, "tactics": null, @@ -4456,10 +4639,10 @@ "example": { "data": [ { - "guuid": "d89f8c3e-731a-3da1-13bf-be45605f8ae3", + "guuid": "051252a8-8a81-e2ed-0244-9c691b39a457", "source": "XyzTIProvider", "type": "domain", - "uuid": "df040f2a-6720-c709-7230-3ee5da9f05ce", + "uuid": "3cb28ad5-0dea-60be-ee0f-a4780ad6cdf9", "value": "some.random.domain" } ], @@ -4507,8 +4690,8 @@ }, "example": [ { - "uuid": "df040f2a-6720-c709-7230-3ee5da9f05ce", - "guuid": "d89f8c3e-731a-3da1-13bf-be45605f8ae3", + "uuid": "3cb28ad5-0dea-60be-ee0f-a4780ad6cdf9", + "guuid": "051252a8-8a81-e2ed-0244-9c691b39a457", "source": "XyzTIProvider", "value": "some.random.domain", "type": "domain" @@ -4526,10 +4709,10 @@ "example": { "data": [ { - "guuid": "d89f8c3e-731a-3da1-13bf-be45605f8ae3", + "guuid": "051252a8-8a81-e2ed-0244-9c691b39a457", "source": "XyzTIProvider", "type": "domain", - "uuid": "df040f2a-6720-c709-7230-3ee5da9f05ce", + "uuid": "3cb28ad5-0dea-60be-ee0f-a4780ad6cdf9", "value": "some.random.domain" } ], @@ -5026,8 +5209,8 @@ "description": "", "group": "", "identifier": "TestAdminUser", - "key": "XvObbqUrV9FQIJDpKSEmUPzgzPhzPEucwF8tV8bGgU9ev5VL7gblj47rzqoNfg08", - "uuid": "888cb092-a409-5ff4-4312-b30cfa1c0862" + "key": "xMcwCEYVJXnRohnXOUn4MEl0N3PWI2o1TwF8PK4TPyktkVK8h600SKSBWBt6lkle", + "uuid": "fdf82040-77ea-a86b-a3fc-278d434d9ca6" }, "error": "", "message": "OK" @@ -5070,7 +5253,7 @@ } }, "example": { - "uuid": "0421fb00-28e4-b36f-2068-abe5201ecdce", + "uuid": "774d4102-5671-bf6f-7e5e-73afad8ce299", "identifier": "SecondTestAdmin", "key": "ChangeMe", "group": "CSIRT", @@ -5091,7 +5274,7 @@ "group": "CSIRT", "identifier": "SecondTestAdmin", "key": "ChangeMe", - "uuid": "0421fb00-28e4-b36f-2068-abe5201ecdce" + "uuid": "774d4102-5671-bf6f-7e5e-73afad8ce299" }, "error": "", "message": "OK" @@ -5179,7 +5362,7 @@ "group": "SOC", "identifier": "SecondTestAdmin", "key": "NewWeakKey", - "uuid": "0421fb00-28e4-b36f-2068-abe5201ecdce" + "uuid": "774d4102-5671-bf6f-7e5e-73afad8ce299" }, "error": "", "message": "OK" @@ -5217,7 +5400,7 @@ "group": "SOC", "identifier": "SecondTestAdmin", "key": "NewWeakKey", - "uuid": "0421fb00-28e4-b36f-2068-abe5201ecdce" + "uuid": "774d4102-5671-bf6f-7e5e-73afad8ce299" }, "error": "", "message": "OK" diff --git a/utils/utils.go b/utils/utils.go index 4bc8496..4c546ff 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -20,6 +20,7 @@ import ( "github.com/0xrawsec/golang-utils/datastructs" "github.com/0xrawsec/golang-utils/log" "github.com/0xrawsec/whids/utils/powershell" + "github.com/pelletier/go-toml" ) var ( @@ -52,6 +53,24 @@ func JsonString(i interface{}) string { return string(Json(i)) } +func Toml(i interface{}) (b []byte, err error) { + buf := new(bytes.Buffer) + enc := toml.NewEncoder(buf) + enc.Order(toml.OrderPreserve) + if err = enc.Encode(i); err != nil { + return + } + b = buf.Bytes() + return +} + +func TomlString(i any) (s string, err error) { + var b []byte + b, err = Toml(i) + s = string(b) + return +} + // ExpandEnvs expands several strings with environment variable // it is just a loop calling os.ExpandEnv for every element func ExpandEnvs(s ...string) (o []string) {