{"id":13773775,"url":"https://github.com/cgosec/Blauhaunt","last_synced_at":"2025-05-11T06:30:43.119Z","repository":{"id":200058999,"uuid":"704668508","full_name":"cgosec/Blauhaunt","owner":"cgosec","description":"A tool collection for filtering and visualizing logon events. Designed to help answering the \"Cotton Eye Joe\" question (Where did you come from where did you go) in Security Incidents and Threat Hunts","archived":false,"fork":false,"pushed_at":"2024-04-16T22:34:21.000Z","size":312,"stargazers_count":152,"open_issues_count":1,"forks_count":10,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-08-03T17:10:46.782Z","etag":null,"topics":["analysis","cyber-crime","dfir","forensics","graph","incident-response","investigation","security","velociraptor"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cgosec.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-10-13T19:21:40.000Z","updated_at":"2024-07-28T13:54:57.000Z","dependencies_parsed_at":"2024-01-05T22:23:40.292Z","dependency_job_id":"5888b0da-0790-45df-8d9f-f7cc281acd0c","html_url":"https://github.com/cgosec/Blauhaunt","commit_stats":null,"previous_names":["cgosec/blauhaunt"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cgosec%2FBlauhaunt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cgosec%2FBlauhaunt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cgosec%2FBlauhaunt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cgosec%2FBlauhaunt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cgosec","download_url":"https://codeload.github.com/cgosec/Blauhaunt/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225017841,"owners_count":17407838,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["analysis","cyber-crime","dfir","forensics","graph","incident-response","investigation","security","velociraptor"],"created_at":"2024-08-03T17:01:20.032Z","updated_at":"2025-05-11T06:30:43.111Z","avatar_url":"https://github.com/cgosec.png","language":"JavaScript","funding_links":[],"categories":["Tools"],"sub_categories":["Windows Artifacts"],"readme":"**Basic Worflow: Set Filters -\u003e click Apply Filters -\u003e click Render**\n\n# Blauhaunt\nA tool collection for filtering and visualizing logon events. Designed to help answering the \"Cotton Eye Joe\" question (Where did you come from where did you go) in Security Incidents and Threat Hunts.\n\n***This tool is designed for experienced DFIR specialists. You may have little to none usage from it without experience in Threat Hunting*** \n![image](https://github.com/cgosec/Blauhaunt/assets/147876916/5b5c7ddb-1a89-479d-9f61-2dd34edc3e6e)\n\n\n## Table of Contents  \n- [Get started](#get-started)\n- [Integration in investigation](#integration-in-investigation)\n- [Architecture](#architekture)\n- [PowerShell Script](#powershell-script)\n- [Velociraptor Artifact](#velociraptor-artifact)\n- [Defender 365 KUSTO Query](#defender)\n- [Acknowledgements](#acknowledgements)\n\n### Interactive User Graph\n![image](https://github.com/cgosec/Blauhaunt/assets/147876916/3e15114d-6413-4a4c-9c7b-51b3903f7c71)\n### Heatmap of User activities\n![image](https://github.com/cgosec/Blauhaunt/assets/147876916/af2eb726-5621-4c2d-bd2b-0720100f6d9a)\n### Timeline\n![image](https://github.com/cgosec/Blauhaunt/assets/147876916/db54d02c-b315-42dc-9f8a-498b3e3f8bd7)\n\n## Get started\nRunning Blauhaunt is as simple as that:\n\nopen https://cgosec.github.io/Blauhaunt/app/ since there is no backend no data will leave your local system. *(third party libraries integrated and I do not take any responsibilities of their communication behavior. Imports are in the index.html file on top)*\n\nrun a cmd or bash or what ever you like...\n\nThen:\n\n     git clone https://github.com/cgosec/Blauhaunt\n     cd Blauhaunt/app\n     python -m http.server\n\nNow you can navigate to http://localhost:8000/ in your browser and start blau haunting the baddies.\n\nSome random test data is in the directory test_data to get started. However this is just randomly generated and nothing to start investigate with.\n\n## Integrate into Velociraptor\n\nYou can use Velociraptors reverse proxy capability to host Blauhaunt directly within your instance. Blauhaunt is Velo Aware. If You do so, Blauhaunt will get the Data automaticall from Velociraptor and you do not have to upload data.\n\nYou need to start a Hunt with the Velo Artifact. You can use the Monitoring Artifact too to get real time data form Velo.\n\n### Velo Settings:\n\n![image](https://github.com/cgosec/Blauhaunt/assets/147876916/7f4d2b98-cc47-4da8-9931-0d08155a61d3)\n\nsee: [Velo Docs](https://docs.velociraptor.app/docs/deployment/references/#GUI.reverse_proxy)\n\n*hint* I did not get this running having the GUI hosted on windows. But you can use the URI to a hosted instance on a https server there too\n\n**UPDATE** Since you can set Tags for Hunts now you need to add the Tag \"Blauhaunt\" to your Hunt to be processed. Otherwise Blauhaunt will not find it!\n\nThats basically all you have to do.... :)\n\nbig big thanks to Mike Cohen who helped me with the workflow for CSRF-Tokens and the not documented REST-API of Velo.\n\n### Upload Data\n![image](https://github.com/cgosec/Blauhaunt/assets/147876916/ae87f5f5-f95b-4c8b-88fc-2845a334030f)\nKlick \"Upload Data\" (surprising isn't it :-P)\n\n![image](https://github.com/cgosec/Blauhaunt/assets/147876916/23d391c9-af24-44b2-853e-cf064eb2bcb2)\nUpload the json export of the velo artifact or the result(s) of the powershell script here.\n*Do not upload the client_info.json or anything in here!*\n\n![image](https://github.com/cgosec/Blauhaunt/assets/147876916/68aa031e-6563-4531-9a5f-f7d14af41db4)\nThis is optional and just needed for having system tags and their os info.\nUpload your client_info.json extract here. This is just an export of the Velociraptor clients() function.\nJust use this query:\n\n     SELECT * FROM clients()\n\nand export the json\n\n![image](https://github.com/cgosec/Blauhaunt/assets/147876916/61edef0d-96b2-40cc-ac81-2f38ada4077b)\nThis is optional too.\nUpload a mapping for having IP-Addresses resolved to their hostnames. You need to have a file where there is one col for Hostnames and a col for IP-Addresses.\nIf a System has multiple IP-Addresses you can have them in this one col separated by an arbitrarily symbol e.G. \"/\".\n\nExample:\n| Hostname    | IP-Addresses | MaybeSomeNotNeededStuff |\n| -------- | ------- | ------- |\n| System_A  | 10.10.10.100    | bonjour |\n| System_B | 10.10.10.100 / 10.10.20.100 | hello |\n| System_C    | 10.10.10.100 | hola |\n\n![image](https://github.com/cgosec/Blauhaunt/assets/147876916/5abba586-b386-4af6-8085-4b1d5eb85301)\n\nOnce a proper file is selected a delimiter (if non is specified a comma is expected). And click Load Map.\n\n![image](https://github.com/cgosec/Blauhaunt/assets/147876916/086ead34-6448-48d0-8f52-7758f13cd778)\n1. Choose the name of the col where the hostname is in\n2. OPTIONAL: Specify if there are any entries you want to exclude from parsing e.g. lines having an \"UNKNOWN\" in the Hostname Ip Mapping.\n3. Choose the name of the col where the IP-Address is in\n4. Specify the delimiter for multiple IP-Addresses in this line\nWhen everything is correct click ![image](https://github.com/cgosec/Blauhaunt/assets/147876916/79d13f20-8aa2-42c7-bbe6-fbfdeea8be79)\n\nWhen done click ![image](https://github.com/cgosec/Blauhaunt/assets/147876916/014b2359-02ec-44b5-943b-28d8c5f61025)\n\n![image](https://github.com/cgosec/Blauhaunt/assets/147876916/a56c1b26-c949-4e3d-b9c3-a8828bb2af6d)\nIf everything was processed as intended you should now see the number of total nodes and edges\n\n### Filtering\n\nClick ![image](https://github.com/cgosec/Blauhaunt/assets/147876916/2df6081e-6041-46b6-b905-53e2fc5955d2) to open the sidebar.\n\n![image](https://github.com/cgosec/Blauhaunt/assets/147876916/a28f4794-f30e-4d12-8fd7-4a4d57e15743)\n\nThe Filter Sidepar shows up\n\n**MOST FILTERS HAVE TOOLTIPS SO I WILL NOT EXPLAIN EVERY FILTER IN DETAIL**\n\n![image](https://github.com/cgosec/Blauhaunt/assets/147876916/76cd7b27-e476-4bb5-8fe6-45d8983bb7e0)\n\nFilter for a time span for activities.\n\n![image](https://github.com/cgosec/Blauhaunt/assets/147876916/71048d37-f979-4006-bcf9-f240d90ece02)\n\nThe Daily times filter specifies from what time we are interested in the events. This is useful if nightly user logons are not common in your environment. This is regardless of the date - that means in your timespan only events that occurred during that hourly timespan are in the set. (Works over night like in the example picture too)\n\n![image](https://github.com/cgosec/Blauhaunt/assets/147876916/406cdc5a-799f-4aa6-8315-3c8391cb2907)\n\n**Highlighted**: You can permanently highlight edges by holding CTRL and clicking on them. This also works for every element where temporary highlighting is actice - just hold CRL and click on the element to highlight edges permanently. (Elements are e.g. Timeline on the left; Stats on mouse over; when clicking the destination host) \n\n**ToSelf**: By default events where source and destination are the same node are not displayed. If you want to display them active it by clicking.\n\n![image](https://github.com/cgosec/Blauhaunt/assets/147876916/c6cbe668-e6c8-4f54-b1a4-41e1085dc26b)\n\nFiltering for EventIDs is a good idea to reduce the data. There is no difference in choosing all or none.\n\n![image](https://github.com/cgosec/Blauhaunt/assets/147876916/17da2925-65e7-4e47-8690-fff918199d5c)\n\nLogon Types are only relevant for 4624 or 4625 events. I assume you know them already when you are using this tool.\n\n![image](https://github.com/cgosec/Blauhaunt/assets/147876916/0988ee19-1ec5-4fa5-b165-eb8f85c59e3a)\n\nFiltering for Tags only is available when client infos are uploaded. Those are your tags specified in Velociraptor for the Systems. It does not have an effect if all on none are chosen.\nThose apply only for the source not for the destination system.\n\n### Source: System or User\nUsually I am rather focused on system -\u003e system activity in favour of identifying the initial access. Since there are a lot of situations you want to focus on user behavior you can choose what your source should be: System or User. \n\n![image](https://github.com/cgosec/Blauhaunt/assets/147876916/f14a564f-5747-4887-aa33-5b747a5a2336)\n\n### Render Graph, Timeline or Heatmap\nWhen your filters are set you need to press render to display the results.\n![image](https://github.com/cgosec/Blauhaunt/assets/147876916/c35535fa-4a23-4437-8abd-15c630b57050)\n\n#### Graph\nThe default Graph calculates the position of systems according to their activitie median time (Y-Axis) and their total number of connections (X-Axis). \n\n**Y-Axis**: Calculated Activitie time early-top to latest-down\n\n**X-Axis**: The more centered a system is, the more connections have this system either as source or destination. Left to right is randomly distributed. (The more outside the less active a system has been)\n\n**Size**: The Size of the nodes indicates their outgoing activities\n\nThe Graph is calculated every time before rendering. Position and size is always relative according to the filters set.\n\n![image](https://github.com/cgosec/Blauhaunt/assets/147876916/691043c5-e218-4ea7-8df9-8ec1de6d7caf)\n\nWhen clicking on a Node you can get further systems information. (Some need the clients() output like OS or Tags.\n\nIPs can be more than one. When data is loaded every Event that has the hostname and an IP in it, will create a list that is presented here. (Multiple entries can be e.g. because of NAT-Devices or Multiple Network Adapters / IP Changes)\n\n![image](https://github.com/cgosec/Blauhaunt/assets/147876916/95cc3271-4eb3-447d-beb9-c5935431589d)\n\nWhen clicking on an edge you get further information about the connection. You can open up a list of Timestamps that shows you when this event has occured.\n\n\n#### Timeline\n\nThe Timeline is the timeline...\n\n#### Heatmap\n\nThe heatmap gives you a quick overview of the usual day by day behavior of users. You can click on a day to quickly switch to the graph of the day and the users connections.\n\nThe color indicator is not per user but in total. It takes account of your filters.\n\n\nIf you want to change from one view to another: choose the view you need and then click render.\n'Be careful with Timeline! Few nodes and edges can still have a huge timeline!* Checking the Stats ![image](https://github.com/cgosec/Blauhaunt/assets/147876916/29429607-9a31-4633-a86e-70a9b70fa5ee) is a good idea before rendering a timeline.\n\n### Graph Style\n\nYou can choose between some variations...\n\n### Tag vizualisation\n\nYou can choose a color for a Tag. The number to specify indicates the priorities when multiple Tags match. The highest number wins.\n\n### Exports\n\nYou can Export:\n\n- Timeline as CSV\n- Graph as PNG / JPEG\n- GraphJSON (from the library cytoscape)\n\n### Stats\n\nStats give you a good indication for what to filter out or to pivot for when starting the investigation.\nStats take account of your filters.\n\n![image](https://github.com/cgosec/Blauhaunt/assets/147876916/aa01e14e-3ecd-4ef8-97e3-ef4cce2182c0)\n\nSystem Stats:\n- To Systems = Number of Systems connected to followed by (Sum of connections to systems in total)\n- From Systems = Number of Systems that connected to this System followed by (Sum of connections to this systems in total)\n- Users out = Number of Users that were observed connection to other systems from this System\n- Users in = Number of Users that were observed connecting to this System\n\n![image](https://github.com/cgosec/Blauhaunt/assets/147876916/eb8c4131-7bd4-4d1e-8d24-a8d4ce6f7aec)\n\nUser Stats:\n- To Systems = Number of Systems the User connected to followed by (Sum of connections in total)\n\n\n## Integration in investigation\nI recommend using Blauhaunt with [Velociraptor](https://github.com/Velocidex/velociraptor) since it is the fastest way to get data from multiple systems. The Blauhaunt import format for event data and client info is the one that can be exported from Velo.\nThe blauhaunt_script.ps1 works well if you prefer working with e.g. [KAPE](https://www.kroll.com/en/insights/publications/cyber/kroll-artifact-parser-extractor-kape) triage data.\n\nBlauhaunt really gets useful if you have multiple systems to identify your next pivot system or sus users. Blauhaunt standalone will not magically bring you to the compromised systems and users. But if you have hundreds of systems to check it really speeds up your game.\n\n### Example workflow\n\n#### Known compromised system\n(e.g. from a Velo hunt) -\u003e Check in Blauhaunt what users connected to this system -\u003e sus user -\u003e sus systems -\u003e further sus users -\u003e the story goes on. You have good chances identifying the systems where deeper forensics will speed you up in your hunt.\nIf you e.g. identify compromised users on that system again you can go back to Blauhaunt and repeat the game.\n\n#### No idea where to start\nWith several filters Blauhaunt gives you statistical and visual possibilities identifying unusual connections. You can e.g. check for user activities occurring at night. Or simply see a logon fire coming form a system where an attacker is enumerating the AD-Infrastructure.\n\n#### Lucky shot\nIf you are really lucky and have a noisy attacker + solid administration in the network, Blauhaunt can potentially deliver you an optical attack map with the timeline of compromised systems along the y-axis in the center.\n\n## Architecture\nBlauhaunt is designed to run entirely without a backend system.\nI suggest simply starting a python http server on the local system from a shell in the directory where the index.html is in with this command:\n\n     python -m http.server\n     \nif you are using linux likely you have to type python3 instead of python - but if you are using this tool you should be technical skilled enough to figure that out yourself ;)\n\n*Some day I will create a backend in Django with an API to get realtime data to display for better threat hunting*\n\n### Default Layout\nThe layout of the graph is calculated according to the set filters. \nThe icon size of a node is calculated by its activities within the set filters.\nThe x-axis position of a node is calculated by its outgoing connections. Nodes having many outgoing connections are rather in the center of the graph. Nodes with fewer outgoing connections are at the left and the right of the graph.\nThe y-axis is calculated by the first quatile of the nodes activity time.\n\nTo not have too many nodes at the same spot there is some movement when there are too many on the same spot.\n\nThe other layouts are defaults from the cytoscape universe that can be chosen as well.\n\n\n### Displays\ndescription comming soon\n\n### General Data Schema\nThere are three types of data - only the event data is mandatory\n\n#### Event Data\nThis is the input Schema for the Event data that is needed by Blauhaunt to process it:\n\n     {\n        \"LogonTimes\":[\n            \"2023-07-28T20:30:19Z\",\n            \"2023-07-27T21:12:12Z\",\n            \"2023-07-27T21:10:49Z\"\n            ],\n        \"UserName\":\"Dumdidum\",\n        \"SID\":\"-\",\n        \"Destination\":\"Desti-LAPTOP\",\n        \"Description\":\"using explicit credentials\",\n        \"Distinction\": \"SomeCustomFieldToDistionctEdgesAndFilterFor\"\n        \"EventID\":4648,\n        \"LogonType\":\"-\",\n        \"SourceIP\":\"-\",\n        \"SourceHostname\":\"Sourci-LAPTOP\",\n        \"LogonCount\":3\n        }\n***To correctly process the files each dataset starting with { and ending with } must be in a new line***\n\n#### Client Info\n     {\n        \"os_info\": {\n             \"hostname\": \"Desti-LAPTOP\"\n             \"release\": \"Windows 10\"\n        },\n        \"labels\": [\n             \"Touched\",\n             \"C2\",\n             \"CredDumped\"\n             ]\n        }\n***To correctly process the files each dataset starting with { and ending with } must be in a new line***\n\n\n#### Host IP Mapping\nCan be any CSV File. Delimiter can be specified and cols for Hostname and IP can be choosen\n\n\n## PowerShell Script (deprectated - use the quick velo instead)\nblauhaunt_script.ps1\nIf you face any issues with execution policy the easiest thing to do is to spawn a powershell with execution policy bypass like this:\n\n     PowerShell.exe -ExecutionPolicy Bypass powershell\n\nTo get information about usage and parameters use Get-Help\n\n     Get-Help blauhaunt_script.ps1 -Detailed\n\n### Usage\n![image](https://github.com/cgosec/Blauhaunt/assets/147876916/3cbe2fc9-ccb3-411d-bccb-d46dc2a69484)\n\nDepending on the size, StartDate and EndDate this can take quiet some time so be a little patient \n\n## Velociraptor Artifact\nThis speeds up collecting the relevant data on scale. \nI recommend creating a notebook (template may be provided soon here too) where all the results are listed.\nYou can simply take the json export from this artefact to import it into Blauhaunt\n\nThe client_info import is designed to work directly with the client_info from Velociraptor too. You can simply export the json file and upload it into Blauhaunt.\n\n### Usage\n\nIf you want to parse event logs collected from a system offline using velociraptor, you can do so like this:\n\n     .\\velociraptor*.exe artifacts --definitions Blauhaunt\\parser\\velociraptor\\ collect --format=jsonl Custom.Windows.EventLogs.Blauhaunt --args Security='C:\\my\\awesome\\storage\\path\\Security.evtx' --args System='C:\\my\\awesome\\storage\\path\\System.evtx' --args LocalSessionManager='C:\\my\\awesome\\storage\\path\\Microsoft-Windows-TerminalServices-LocalSessionManager%4Operational.evtx' --args RemoteConnectionManager='C:\\my\\awesome\\storage\\path\\Microsoft-Windows-TerminalServices-RemoteConnectionManager%4Operational.evtx' --args RDPClientOperational='C:\\my\\awesome\\storage\\path\\Microsoft-Windows-TerminalServices-RDPClient%4Operational.evtx'\n\nIf you dislike typing long paths, feel free to use the provided quick script:\n \n     .\\quick_velo.ps1 -EventLogDirectory C:\\my\\awesome\\storage\\path \n\n## Defender\n\nYou can import Data from Defender365 into Blauhaunt by using this Hunting Query:\n\n[Defender 365 Query](https://github.com/cgosec/Blauhaunt/blob/main/parser/Defender365_Query.md)\n\nrun the query, export the csv and direktly load it into Blauhaunt...\n\n\n## Acknowledgements\n - [SEC Consult](https://sec-consult.com/de/) This work was massively motivated by my work in and with the SEC Defence team\n - [Velociraptor](https://github.com/Velocidex/velociraptor/) is the game changer making it possible to collect the data to display at scale (tested with \u003e 8000 systems already!)\n - [Cytoscape.js](https://js.cytoscape.org/) is the library making the interactive graph visualisation possible\n - [LogonTracer](https://github.com/JPCERTCC/LogonTracer) inspired the layout and part of the techstack of this project\n - [CyberChef](https://gchq.github.io/CyberChef/) inspired the idea of creating a version of Blauhaunt running without backend system all browser based\n\n\n(The icon is intentionally shitty - this is how I actually look while hunting... just the look in the face not the big arms though :-P )\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcgosec%2FBlauhaunt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcgosec%2FBlauhaunt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcgosec%2FBlauhaunt/lists"}