top of page

Search Results

496 results found with an empty search

  • Tracking Kerberos & NTLM Authentication Failures and Investigation

    When investigating intrusion attempts or suspicious login activity in Windows environments, one of the most overlooked sources of truth lies in the authentication failure logs  — specifically, Kerberos Event ID 4771  and NTLM Event ID 4776 . These tiny events, often lost in the noise of massive log volumes, can tell a deep story: Was someone trying to guess passwords? Was an attacker using a stolen hash? Or was it just a misconfigured system clock? Kerberos Pre-Authentication Failures (Event ID 4771) Kerberos is the default authentication protocol in modern Windows domains, but when things go wrong, it leaves behind a clear trail. Whenever Kerberos “pre-authentication” fails, Windows logs Event ID 4771  on the authentication server   — usually the domain controller. This event contains the date, time, username, client IP address, and most importantly, an error code  that tells you why authentication failed. There are more than 40 possible Kerberos failure codes, but a few valuable for incident responders. Let’s translate the most common ones into plain language: Error Code Meaning What It Often Means in Real Life 0x6 Invalid or non-existent account Someone tried logging in with an account that doesn’t exist — could be enumeration or stale credentials 0x7 Requested server not found Usually a replication issue, but sometimes points to attempts to reach decommissioned hosts 0xC Policy restriction Account tried to log in outside allowed hours or from a restricted device 0x12 Account locked, disabled, or expired May indicate brute-force or password-guessing attacks 0x17 Password expired User simply needs a reset — or an attacker tried with an old credential dump 0x18 Invalid password The classic — could be typos or password spraying 0x25 Clock skew too large Indicates a mismatch in system time; Kerberos rejects tickets when clocks differ too much If you see a cluster of 0x18 errors  across multiple accounts from a single source IP, it’s not a coincidence — it’s likely someone is testing passwords or performing a brute-force  or password spray  attack. NTLM Authentication Failures (Event ID 4776) Although Kerberos is dominant, NTLM  hasn’t disappeared — it still pops up in remote logins, local account authentications, and pass-the-hash attacks . When NTLM authentication fails, you’ll find Event ID 4776  logged on the system where the authentication was attempted. This event is a goldmine because it records both the username  and the reason  why authentication was denied, using NTSTATUS-style error codes . Here are some of the most useful ones for IR: Error Code Meaning IR Insight 0xC0000064 Account doesn’t exist Enumeration attempt — attacker probing usernames 0xC000006A Wrong password, username valid Password guessing — if repeated from one host, suspect brute-force 0xC000006F Account not allowed to log in now Account policy restriction triggered 0xC0000070 Not allowed from this computer Attempt to access restricted host — possible lateral movement 0xC0000071 Password expired Legit user or old credential reuse 0xC0000072 Account disabled Attackers sometimes test disabled accounts from old dumps 0xC0000193 Account expired Expired service or user account reused 0xC0000234 Account locked Brute-force or repeated login attempts triggered lockout policy Pro Tip:  The same error codes also appear in Event ID 4625 (Failed Logon) . So cross-referencing 4625 with 4776 helps you see where  the login happened and why  it failed. A pattern of multiple 0xC000006A and 0xC0000234 events coming from a single workstation is a clear red flag — it usually means someone (or something) is trying stolen passwords or hashes in bulk. Tracking Account & Group Enumeration (Event IDs 4798 & 4799) Once attackers gain a foothold, they rarely move blind. The next step is reconnaissance  — mapping out what accounts and groups exist, and more importantly, who the Domain Admins are . Windows 10 and Server 2016 introduced new logging capabilities to make this easier to detect: Event ID 4798:  A user’s local group membership  was enumerated. Event ID 4799:  A security-enabled local group membership  was enumerated. Why These Events Matter for Defenders Enumeration happens early  in the attack lifecycle. That means if you spot 4798 or 4799 events tied to suspicious processes, you’ve caught the attacker before  they’ve escalated privileges or exfiltrated data. --------------------------------------------------------------------------------------------------------- When You Log In with a Local Account (NTLMv2 in Action) So imagine this — you’re on your workstation and try to access a shared folder on a remote server using a local account  (not a domain one). Maybe you run: net use S: \\198.30.0.0\Share Boom — that’s a remote access attempt using NTLMv2. Here’s what happens behind the scenes: The client  says to the server: “Hey, I want to log in with this username.” The server  replies: “Cool, prove it. Here’s a random challenge.” The client  encrypts that challenge using the hash of your password and sends it back — this is the NTLM Response . At this point, the server  checks if that encrypted response matches what it expects. If it does — you’re in. Now, from a forensic point of view — here’s what we care about 👇 Event ID Location Meaning 4776 On the server NTLM authentication attempt 4624 On the server Authorization success — user logged in (Type 3 or 10) Type 3 = network login, Type 10 = RDP So if you’re investigating a lateral movement, and you see 4 624 (Type 3)  on a file server using a local account, that’s a huge red flag — someone might be using local creds to hop around. 2. When You Log In with a Domain Account (NTLMv2) Now, let’s change the scene — you’re using a domain account  to connect to that same file share. Here’s where the Domain Controller (DC)  jumps in — because that’s where your account actually lives. The client still sends an authentication request to the server . The server says, “Wait, I don’t store your password hash — let me ask the DC.” The server  forwards that challenge/response to the domain controller . The DC  checks if your response is correct (using the NT hash in the NTDS.dit ). The DC  says “All good,” and the server  logs you in. From a log perspective: Event ID Where it appears What it means 4776 Domain Controller Authentication check (NTLMv2 validation) 4624 (Type 3) Server Authorization success — you got in via SMB 4624 (Type 10) Server Authorization success — you got in via RDP Tip: If you ever see net use \IPaddress\share  — that’s likely NTLMv2 , not Kerberos. Kerberos needs proper Service Principal Names (SPNs) , and those don’t work well with raw IPs unless someone configured it manually (which 99% of orgs don’t). 3. Kerberos — The Smart Guy in the Room Kerberos is the default in modern domains, and it’s way more efficient (and secure) than NTLM. But it’s also a bit more talkative in logs. Let’s picture when someone logs in locally with a domain account. Step 1: The Ticket-Granting Ticket (TGT) — “Let me in the club!” The client  asks the Domain Controller (DC)  for a TGT . The DC logs: 4768 — AS Request / Reply (If it fails, you might see 4771 — Pre-authentication failed) Step 2: The Service Ticket — “Now let me access this service.” Once you have your TGT, the client says to the DC: “Hey, I want to access this specific machine/service.” The DC responds with a TGS (Ticket Granting Service) Ticket  — and logs: 4769 — TGS Request / Reply Now the client can use that service ticket to log in locally or remotely. Step 3: Local Authorization The client  logs: 4624 (Type 2)  → interactive logon (user at keyboard) The DC  also logs: 4624 (Type 3)  → network logon when the ticket is presented back to it. By the end of this process, you’ll see a flurry of 4768, 4769, and 4624 events  across both client and DC. Bonus tip: If you’re ever analyzing logs and see multiple 4769  tied to krbtgt or service accounts, it usually means the client is requesting tickets for various services — like LDAP, CIFS, or even group policy updates. 4. Kerberos in Remote Logons If the logon happens remotely (like accessing a file share or RDP server): The client requests a service ticket  from the DC — 4769  on the DC. The client presents that ticket to the server  — and the server logs 4624 (Type 3)  if it’s successful, or 4625  if it’s denied. So when investigating: 4769 on the DC  tells you who asked  for access. 4624 on the server  tells you who actually got in . That’s gold for tracking lateral movement. ------------------------------------------------------------------------------------------------------------- Putting It All Together Here’s how you can think of it: Scenario Who Logs What Key Events Local Account Logon Target system 4776, 4624 Domain Account (NTLMv2) DC (auth), Server (access) 4776 (DC), 4624 (Server) Domain Account (Kerberos) DC + Client + Server 4768, 4769, 4624 Think of it like this: Authentication  (Who are you?) → DC Authorization  (Can you come in?) → Server or Client ------------------------------------------------------------------------------------------------------------- 5. Why This Matters in Investigations During lateral movement or credential abuse: You’ll often see 4624 (Type 3)  events lighting up on multiple systems. Pair them with 4768/4769  from the DC to map out exactly how the attacker moved. Combine IPs, usernames, and timestamps to build your attack path timeline . And when the logs aren’t centralized — you’ll have to collect from multiple endpoints . Quick DFIR Tip If you’re working offline and can’t access a SIEM, start with: Get-WinEvent -LogName Security | ? {$_.Id -eq 4624 -or $_.Id -eq 4769 -or $_.Id -eq 4776} | Select TimeCreated, Id, Message And then pivot by username and IP address — you’ll quickly map authentication relationships. ------------------------------------------------------------------------------------------------------------- Final Thought Once you understand where each event lives — DC, server, or client — the logs start to tell a story. You can see who authenticated, how, from where, and what access they gained. The fun part? Attackers leave breadcrumbs  across all three — and now you know exactly where to look. -----------------------------------------------Dean---------------------------------------------- Third Part of this series: https://www.cyberengage.org/post/understanding-where-windows-authentication-logs-actually-live-from-ad-to-entra-id

  • Log Analysis – It’s Not About Knowing, It’s About Correlating

    I know, I know — Log Analysis  doesn’t sound like the most exciting topic these days . Everyone in cybersecurity has gone through it at some point, and if you’ve sat in an interview, you’ve probably been asked about it too. There are already tons of articles and videos on this topic out there. But here’s the thing — log analysis isn’t about knowing event IDs by heart . It’s about correlating different events together to tell a story . That’s the part most people miss. And that’s what I’m going to focus on today. ------------------------------------------------------------------------------------------------------------ Why This Topic Still Matters Even with so many amazing tools available now — like Hayabusa : https://www.cyberengage.org/post/hayabusa-a-powerful-log-analysis-tool-for-forensics-and-threat-hunting EvtxECmd : https://www.cyberengage.org/post/unleashing-the-power-of-evtxecmd-a-deep-dive-into-windows-event-log-analysis Chainsaw understanding how  to correlate logs is still essential. These tools automate the process, but they don’t think for you . They can highlight suspicious events, but they can’t explain why something happened , or how one event connects to another . That’s where your analysis skills come in. To help with this, I’ve created a personal Intrusion Detection Cheat Sheet  — it’s available under the Resume page on my website, under Quick Guides . It contains core correlations and scripts I’ve built for my own investigations — things that are hard to remember when you’re in the middle of an IR case. ------------------------------------------------------------------------------------------------------------ Tracking Account Usage: Logon Events One of the most common and powerful ways to start log analysis is by tracking account activity  — basically, who logged in, from where, and when. Relevant Event IDs 4624  → Successful Logon 4625  → Failed Logon 4634 / 4647  → Successful Logoff 4648  → Logon using explicit credentials (like RunAs ) 4672  → Special privileges assigned to a new logon These five are the bread and butter of account tracking. How to Read These Events Every log entry is more than just a timestamp. When you expand an event in the Event Viewer (or parse it with a tool), focus on the following fields: Timestamp:  When the event occurred. Computer:  The hostname — helps correlate across multiple systems. Account Name:  Who logged in or attempted to. Logon Type:   How  they logged in — locally, over the network, via RDP, etc. Event ID:  What kind of logon or logoff this was. Understanding Logon Types Here’s a quick reference to some of the most useful logon types: Logon Type Description 2 Interactive logon via console or KVM 3 Network logon (SMB, PowerShell remoting, etc.) 4 Batch logon (used by Scheduled Tasks) 5 Service logon (Windows service accounts) 7 Session reconnect (unlock, RDP reconnect, etc.) 8 Network logon sending credentials in cleartext 9 Logon using different credentials (RunAs /netonly) 10 Remote interactive logon (RDP) 11-13 Cached or reconnected logons This is where correlation starts to get interesting. If you see Logon Type 10  on a workstation, for example, that means Remote Desktop was used — which might be normal on a jump server, but very suspicious on a regular user laptop. If you see 4625 (failed logons)  with Type 3  repeatedly from different IPs — that’s often a password spray or brute-force attempt. Correlating Logons and Logoffs Let’s say you find this: A 4624 (successful logon)  event at 12:00 PM A 4647 (user-initiated logoff)  event at 12:00 AM the next day Using the Logon ID  (a unique value assigned to each session), you can tie these together and calculate how long the user was active. That’s useful in profiling behavior: Was this an abnormally long session? Was it active during non-business hours? Did any privileged actions happen in between (like a 4672  event)? That’s what log correlation really means — finding connections between time, behavior, and privilege. ------------------------------------------------------------------------------------------------------------ When Logs Don’t Tell the Whole Story It’s important to remember that not every access attempt creates a logon event. If a system is exploited via a backdoor or remote code execution vulnerability, you might not see a normal 4624  event. That’s why correlation must extend beyond Security.evtx — you need to look at: Sysmon events (especially Event ID 1, 3, and 7 ) Prefetch files and ShimCache USN Journal and Amcache PowerShell and WMI logs When combined, these help fill the gaps where the Event Viewer stays silent. ------------------------------------------------------------------------------------------------------------ Pro Tip: Don’t Memorize — Build Your Correlations You don’t have to remember every event ID.Instead, build a mental (or written)  correlation map like this: Scenario Event IDs to Link Description Brute-force attack 4625 + Source IP pattern Repeated failed logons from same IP Lateral movement 4624 + 4672 + Type 3/10 Successful logon with admin privileges Privilege escalation 4672 + 4688 Elevated rights + new process creation RunAs misuse 4648 + 4624 Explicit credential use detected RDP session 4624 (Type 10) + 4634 Remote login session tracking This is exactly what I’ve built in my Intrusion Detection Cheat Sheet , and I can tell you — it makes a huge difference during investigations. ------------------------------------------------------------------------------------------------------------ Understanding Built-In Accounts in Windows Logs When you’re digging through event logs, you’ll often stumble upon strange account names like SYSTEM, LOCAL SERVICE, NETWORK SERVICE, or even things like UMFD-0 and DWM-1. At first glance, these can look suspicious — especially if you’re new to Windows log analysis.But here’s the truth: not every “unknown” account is an attacker. Many of these are built-in service accounts  that Windows uses to run background processes and manage system functions — often before a real user even logs in. Common Built-In Accounts You’ll See Account Description Typical Logon Type Privilege Level SYSTEM The most powerful local account. Has unlimited privileges on the machine. 5 Highest (root-equivalent) LOCAL SERVICE Runs processes that don’t need network access. Uses null sessions for network calls. 5 Low NETWORK SERVICE Similar to LOCAL SERVICE, but can authenticate over the network. 5 Medium $ The computer account for a domain-joined machine. Used for machine-to-domain authentication. 3 System DWM / UMFD Internal Windows components (Desktop Window Manager and Font Driver Host). 2 Low ANONYMOUS LOGON Represents unauthenticated connections (e.g., null sessions, some network access). 3 None 💡 Tip:  Built-in accounts are noisy . Don’t panic if you see multiple 4624 (Logon) events with these accounts — they appear frequently as part of normal Windows operation. Why These Accounts Exist Each service or process in Windows must run under an identity — something that defines its permissions. When Windows boots, dozens of processes start before any user logs in , and these rely on internal accounts like SYSTEM or LOCAL SERVICE. For example: The SYSTEM  account might handle core OS-level operations. LOCAL SERVICE  might manage background maintenance tasks. NETWORK SERVICE  might handle updates or telemetry that require outbound connectivity. The Microsoft Trustworthy Computing Initiative  (post-Windows 2003) actually reduced the power of SYSTEM by introducing these limited accounts, following the principle of least privilege . Filtering Out the Noise When you’re hunting for intrusions, seeing dozens of system account logons can clutter your view. To focus on real user activity , it’s smart to filter out built-in accounts like these: SYSTEM LOCAL SERVICE NETWORK SERVICE DWM-* UMFD-* $ ANONYMOUS LOGON This will leave you with cleaner visibility on human actions — the kind attackers try to mimic. ------------------------------------------------------------------------------------------------------------ Tracking Privileged Account Activity (Event ID 4672) Now let’s talk about one of the most powerful log events  for defenders: Event ID 4672 — “Special privileges assigned to new logon.” Whenever a user logs in and is assigned admin-level privileges (like SeDebugPrivilege or SeTakeOwnershipPrivilege), Windows records Event ID 4672. This event appears immediately after a 4624 (Successful Logon)  event and indicates that the account logging in has administrative capabilities — either local admin, domain admin, or system-equivalent rights. Why 4672 Is a Goldmine Every attacker, at some stage, needs admin-level access  to move laterally, dump credentials, or persist. That means tracking Event ID 4672  can help you: Detect unexpected privilege elevation. Spot service accounts behaving unusually. Identify high-value targets for auditing. Here’s what a typical 4672 looks like: Field Example Meaning Account Name Dean The account that logged in Privileges Assigned SeDebugPrivilege, SeTakeOwnershipPrivilege Indicates admin-level capabilities Correlating Event 4624 (Logon) Shows when and how they logged in If you see a 4624 + 4672  pair on a system where admin logons are rare, your threat-hunting instincts should kick in immediately. Correlation Example Let’s say you see this sequence: 4624 — Successful logon (User: Dean) 4672 — Special privileges assigned 4688 — New process created (possibly with elevated rights) This combination can signal an attacker using stolen credentials or a scheduled task executing under admin privileges. To confirm, look at: Logon Type  (e.g., Type 10 for RDP or Type 3 for network) Source IP  (was it remote?) Timestamp proximity  (did 4672 appear right after 4624?) If yes — that’s a strong indicator of admin-level access. ------------------------------------------------------------------------------------------------------------ Event ID 4648 — Explicit Credential Use Another powerful event in correlation chains is 4648 , which records when a user explicitly provides credentials . This happens when someone: Uses Run As  to launch a program with another account. Connects via PsExec , Enter-PSSession , or net use /user: . Initiates RDP or SMB connections  that prompt for alternate credentials. In short: 4624 = Logon occurred4648 = Credentials explicitly entered 4648 in Action Here are two examples: Example 1 — RDP Connection Source:  dean.cyberengage.org Target:  Server10 Credential Used:  dean@cyberengage.org SPN:  TERMSRV/server10 This means the user on  used admin credentials to open an RDP session to Server10. Example 2 — SMB Share Mapping Command: net use S: \\server10\share /user:cyberengage.og\administrator Network Address:  192.168.0.0 Port:  445 (SMB) SPN:  CIFS/server10 Here, 4648 records that the user explicitly entered alternate credentials to access a network share. Why This Matters When combined, 4624 , 4672 , and 4648  tell a powerful story: 4624:  The account logged in. 4648:  They used a different credential (e.g., administrator). 4672:  That credential had admin-level privileges. This pattern — especially across multiple machines — often signals credential misuse , lateral movement , or privilege escalation . Defensive Takeaway You don’t need fancy tools to spot privilege abuse — just solid log correlation. Start with this simple approach: Search for Event ID 4672  across endpoints. Correlate each one with 4624  and 4648 . Flag logons from: Unusual hosts Non-working hours Service accounts acting interactively These insights often expose attacker behavior long before malware is detected . ------------------------------------------------------------------------------------------------------------ RDP (Remote Desktop Protocol) Why RDP Matters in IR Attackers love RDP : It’s one of the most abused remote access mechanisms. Sophos (2023):  90% of investigated intrusions involved RDP. RDP abuse examples: Lateral movement within internal networks. Persistence via hijacked sessions. Rogue outbound RDP (social engineering or misconfigurations). Credential theft or privilege escalation via RDP sessions. Core Windows Event IDs Event ID Description Notes 4624 Successful Logon Logon Type 3 (network), 7 (unlock/reconnect), 10 (RDP) 4647 Logoff User-initiated logoff 4778 Session Reconnected Captures hostname + IP of client 4779 Session Disconnected Captures client that disconnected 4801 Workstation Unlocked Often seen before Type 7 reconnects Key Forensic Insights 1. Event 4778 (Session Reconnected) Indicates a user reconnected  to an existing session. Contains both Client Name  and Client IP Address  (often the attacker’s system). Often paired with: 4624 (Type 7)  → Unlock / RDP reconnect 4801  → Workstation unlock Important: Not every RDP session logs 4778—only reconnects. 2. Event 4779 (Session Disconnected) Marks when a session was closed or disconnected. Use it with 4778 to “bookend” RDP session activity. 3. Event 4624 (Logon Type) Reference Logon Type Meaning 3 Network (NLA) — pre-authenticated connection 7 Unlock / Reconnect 10 Classic RDP Interactive Logon Many analysts mistakenly only track Logon Type 10 → this can miss modern NLA-based (Type 3) or reconnect-based (Type 7) RDP events. Supporting Logs (Auxiliary Sources) Log Source Event IDs Use RDPCoreTS 131 Outbound RDP connections TerminalServices-RDPClient 1024, 1102 Destination hostname & IP for outbound RDP Prefetch tscon.exe Evidence of RDP hijacking (session switching) Sometimes Mismatched Logon IDs — What It Means You may notice sometimes that the Logon ID  in Event ID 4778 doesn’t match the one in 4624.That’s normal. Here’s why: Event IDs 4778 and 4779 track session reconnect/disconnect  activity. These events inherit the Logon ID of the earliest still-active session  by that user. If there was a prior session (and it was never fully logged off), the reconnect event uses that old session ID — leading to a mismatch. Practical Takeaways for DFIR Analysts Correlate Events Together Combine 4778, 4779, 4624, and 4647 to reconstruct RDP timelines. Look Beyond Logon Type 10 Type 7 and Type 3 can hide RDP reconnects or NLA-based connections. Pay Attention to Client Name & IP These are often your best clues about attacker infrastructure. Check for Persistence via Unclosed Sessions Attackers can hijack old sessions left open by admins to avoid detection. Pivot to Auxiliary Logs Inspect RDPCoreTS  (Event 131) and RDPClient  logs (Events 1024/1102) for outbound connections. Check Prefetch  for tscon.exe (used in RDP hijacking). Additional RDP Logging and Account Logon Events Why This Matters Attackers abuse RDP (Remote Desktop Protocol)  both for initial access  and lateral movement . Unfortunately, traditional Security logs roll over quickly , so responders can lose critical evidence unless they correlate data across custom RDP logs  and authentication logs (Account Logon Events) . 1. Primary RDP Log Sources Target Log Key EIDs Relevant Data Captured Description Security 4624, 4778 Source IP / Hostname / Username Standard logon + RDP reconnects TerminalServices-RDPClient 1024, 1102, 1029 Destination Hostname / Destination IP / Hashed Username Logs outbound RDP connections (source-side) Remote Desktop Services-RDPCoreTS 98, 131 Successful connections / attempts / Source IP / Username Helps identify RDP sessions and connection attempts TerminalServices-RemoteConnectionManager 1149 Source IP / Username Tracks successful RDP authentications TerminalServices-LocalSessionManager 21, 22, 25, 41 Source IP / Username Tracks session creation, connection, and disconnection Tip:  Combine these logs for complete RDP session reconstruction. The Security log  gives general logon evidence, while the custom RDP logs  persist longer and provide IPs, hostnames, and session context that may be missing from Security. 2. Key Log: Microsoft-Windows-TerminalServices-RDPClient/Operational This is the most valuable log  for tracking lateral movement  because: It’s recorded on the source system  (unlike most Windows logs that log activity on the destination). It shows where the attacker moved from the compromised machine. Event IDs Event ID Meaning Example Use in IR 1024 Records the name  of each system accessed Identify lateral movement destination hostnames 1102 Records the IP address  of each system accessed Validate connections or pivot points 1029 Contains a Base64-encoded SHA256 hash of the username  used Useful for detecting reused or suspicious usernames Event ID 1029 – Username Hashing Details Hash = SHA256(username) (case-sensitive, domain ignored). Example: dean@cyberengage.org  → hash based only on administrator. Case matters: Admin ≠ ADMIN ≠ administrator. Helps detect unusual capitalization patterns (e.g., ADMINistrator) used by attackers to bypass detection. Pro Tip:  Always correlate 1029 events with Event ID 4648 (Explicit Credential Use)  in the Security log to see the account actually used for RDP. 3. Account Logon vs Logon Events Event Category Recorded On Purpose Logon Events System where authorization  happens (workstation/server being accessed) Local or remote login tracking Account Logon Events System where authentication  happens (local SAM or Domain Controller) Credential validation tracking Account Logon Events Protocol Event IDs Meaning NTLM 4776 Account authentication success/failure Kerberos 4768 Ticket Granting Ticket (TGT) requested 4769 Service Ticket requested 4771 Pre-authentication failed How They Work Local Accounts:  Authentication logged on the same workstation  (Local SAM). Domain Accounts:  Authentication logged on the Domain Controller  (Kerberos/NTLM handshake). A single logon  can generate: 4624 (Logon Event) on the workstation, and 4768/4769 (Account Logon Events) on the DC. If you see Account Logon events  on a workstation , it often signals a rogue local account  — a potential attacker-created persistence mechanism. We will continue more in next article! ------------------------------------------------------------------------------------------------------------ Closing Thoughts Log analysis might not sound exciting compared to hunting with EDR or sandboxing malware samples — but it’s still the foundation of incident response . The automation tools will help you find the “what,” but your understanding of correlation  helps you find the “why” and “how.” So the next time someone asks you about Event ID 4624 in an interview — don’t just define it. Explain how you’d correlate  it with other events to tell the story of an intrusion. That’s where the real skill lies. -------------------------------------------------Dean---------------------------------------------------- Second Part of this Series: https://www.cyberengage.org/post/tracking-kerberos-ntlm-authentication-failures-and-investigation

  • Understanding Where Windows Authentication Logs Actually Live — From AD to Entra ID

    Okay, let’s get one thing straight — Windows logging is not centralized by default. Each system—your laptop, your DC, your file server—logs its own stuff. That means if you’re doing forensics or threat hunting, you’ve got to know exactly which system has what evidence . If you pull the wrong logs, you might completely miss the attacker’s authentication trail. ------------------------------------------------------------------------------------------------------------- 1. Clients, Domain Controllers, and Member Servers — Who Logs What? Think of these three as different witnesses  in your investigation. Each one saw a different part of the crime. System Type What It Logs Example Event IDs Client Systems Logon events when someone accesses the client, and Account Logon events if local accounts are used. 4624, 4625 (logon), 4776 (local account auth) Domain Controllers (DCs) Account Logon events for all domain accounts  (Kerberos & NTLM). Logon events for when they themselves are accessed. 4768, 4769, 4776, 4624 Member Servers Logon events for access to the server, and Account Logon events if local accounts exist. 4624, 4625, 4776 Now, here’s the simple rule  you should always remember: Authentication happens where the account lives. Authorization happens where the access happens. Let’s decode that in plain language 👇 Authentication = Account Logon Events These tell you who tried to prove their identity  (i.e., “is this password/ticket valid?”).So if it’s: A local account  → it’s stored on that machine → you’ll find 4776  on that system. A domain account  → stored on the Domain Controller → you’ll find 4768/4769/4776  on the DC. Authorization = Logon Events These tell you who actually got access  to the system. So: If someone connects to a file server  using SMB, you’ll see 4624 (Type 3)  on the file server. If someone RDPs into a system, it’s 4624 (Type 10) . If someone logs in locally (keyboard/console), it’s 4624 (Type 2) . Every system generates its own logon events  for whoever touches it. 2. Domain Controllers — The Authentication Powerhouse Every Domain Controller (DC) in the domain is an equal partner . So when a domain account authenticates, the event could appear on any DC  that handled the request. That’s why, during incident response, you often need logs from all DCs , not just one. DCs will be buzzing with: 4768  → Kerberos AS Request (TGT issued) 4769  → TGS Request (Service ticket) 4776  → NTLM authentication 4624 (Type 3)  → Network logon to the DC If you ever wonder “where did this user authenticate?”, start your hunt on the DCs. 3. Member Servers — Your Quiet Evidence Keepers Member servers behave just like clients. If someone accesses them (say, via SMB or RDP), the Logon events (4624/4625)  appear right there. If they have local accounts (which attackers love  creating as backdoors), then you’ll also see: 4776  — Local NTLM authentication 4720 / 4732  — Local account creation or group modification Attackers often create local “shadow” admin accounts, so these logs are pure gold during lateral movement investigations. 4. The Cloud Era — Welcome Entra ID (formerly Azure AD) Now things get interesting.Microsoft’s Modern Authentication  changed the game. We’re no longer bound to traditional AD — you can join your machines directly to Entra ID  (Azure AD). Here’s how it shifts things: What changes: Authentication  moves to the cloud (Entra ID). Logs  for that authentication now live in Entra ID’s portal , not in your local Security event logs. Passwordless login  (Windows Hello / Hello for Business) becomes standard — it uses certificates and key pairs , not NT hashes. What stays the same: Logon events (4624, 4625)  still happen on the local system being accessed. Network logon (Type 3)  → for SMB or remote shares RDP (Type 10)  → for Remote Desktop Local logon (Type 2, 7, or 11)  → for local or interactive access Even in a pure Entra ID world, your endpoints are still the final witnesses. 5. Passwordless Authentication (Windows Hello / Hello for Business) Instead of using passwords or timestamps, Windows Hello uses certificates and keys . But here’s the key takeaway: Even though the authentication method changes, the same event IDs are generated . So: 4768  → Still logged on the DC when a TGT is requested. 4624  → Still recorded on the system granting access. The difference? You’ll see extra certificate details in the log, showing which cert/key pair was used during authentication. 6. Hybrid Entra ID + Active Directory — The Real-World Mix This is where most companies are today — hybrid mode . On-prem AD for internal stuff. Entra ID for cloud apps like Office 365 , SharePoint , or Teams . Here’s how that works under the hood: Authentication may happen in the cloud , but your DCs still issue TGTs  for on-prem access. Service tickets (4769)  still exist. Logon events (4624)  still show up locally. So from an incident response perspective, the log locations don’t change much  — you just add one more layer (Entra ID logs in the cloud). 7. Watching for Account Management Activity Alright, authentication is one thing — but what about account creation or privilege escalation ? Here’s where attackers love to play. Action Event ID Description User account created 4720 New account made (local or domain) User account deleted 4726 Account removed Account enabled/disabled 4722 / 4725 Account activation changes Password reset 4724 Admin reset user password Added to global group 4728 Domain Admins, etc. Added to local group 4732 Local Administrators, etc. Added to universal group 4756 Forest-wide access group Account changed 4738 Username, password, or attribute updated If you ever see 4720 followed by 4732  close together — that’s a dead giveaway. It often means: An attacker created a new user and immediately added it to the Administrators group. Quick Recap for DFIR Analysts 4776 / 4768 / 4769  → Authentication (Account Logon events) 4624 / 4625  → Authorization (Logon events) 4720–4756  → Account and group management DCs = domain accounts , Clients/Servers = local accounts Entra ID  shifts authentication to the cloud but not logon visibility And most importantly — logs are decentralized . Unless you have log forwarding or a SIEM, you’ll need to collect from each endpoint manually. ------------------------------------------------------------------------------------------------------------- Final Word If you’re doing threat hunting or forensics, think of authentication events like breadcrumbs . Each one tells a small part of the story — but together, they paint the attacker’s entire movement. Once you know where each event lives , you’ll never look at “just another 4624” the same way again. ---------------------------------------------Dean--------------------------------------------------

  • Unleashing the Power of EvtxECmd: Windows Event Log Analysis

    If you’ve ever tried digging through Windows event logs, you already know the pain — thousands of entries, confusing structures, and XML data that can make your head spin. Now imagine doing that for dozens or hundreds of systems during an investigation. That’s where EvtxECmd , created by Eric Zimmerman , becomes a real lifesaver. At first glance, EvtxECmd looks like another command-line tool that converts .evtx files into CSV, XML, or JSON formats. But once you start using it, you realize it’s much more than that. It’s a smart, flexible event log parser that helps you extract the right information instead of drowning in all the noise. Why Windows Event Logs Are Tricky Windows event logs are incredibly detailed — sometimes too  detailed. Each event type (like a logon or a process creation) stores information differently. There’s no single consistent structure, which makes it difficult to normalize or compare data across systems. Let’s take Event ID 4624 (a successful logon) as an example. One event might store the username in a particular XML field, another event might bury it in a nested tag. Multiply that inconsistency across hundreds of event IDs, and you quickly see why filtering event logs manually is a nightmare. How EvtxECmd Solves This Problem EvtxECmd fixes this inconsistency by using something called Map files . Think of Map files as small “blueprints” that tell the tool exactly what to extract from each event type. These Maps are crowd-sourced , meaning the community contributes templates for different event types, and each map uses XPath filters  to pull out only the relevant details — usernames, IP addresses, domains, process names, etc. For example: For Event ID 4624, it might extract the TargetUserName  and TargetDomainName . For Event ID 4688, it might extract the command line , parent process , or executable path . Once extracted, EvtxECmd organizes all this information into clean columns in a CSV file. You can now easily filter, search, or group the data without wrestling with XML. It’s like turning chaos into a spreadsheet of clarity. Working Smarter with PayloadData Columns You’ll notice that the tool uses columns named PayloadData1–6 . These are general-purpose slots that can hold different kinds of data depending on the event type. Why not just have separate columns for everything? Because that would result in hundreds  of columns — way too messy. So instead, EvtxECmd lets every event type reuse these six slots for its most important details. That means in one row, PayloadData1 might be a username, and in another, it might be a process name. To know what each means, you can simply refer back to the event’s ID and the corresponding Map file. Once you understand this logic, analyzing large sets of logs becomes surprisingly straightforward. Bringing It All Together with Timeline Explorer Parsing logs is just half the battle — the real magic happens when you start analyzing .Eric Zimmerman’s Timeline Explorer  pairs perfectly with EvtxECmd output. You can open the CSV file in Timeline Explorer and use features like: Filtering by keyword or event ID Grouping by columns  (for example, EventID, Username, LogonType) Counting event occurrences Quick sorting and drilling down Here’s a simple example: If you group by EventID, UserName, and LogonType, you can instantly see how many times each user logged example via RDP (LogonType 10) . You might discover that a user who normally logs in locally suddenly had two RDP sessions from an unknown IP — a quick red flag for possible lateral movement. Scaling It for Real Investigations EvtxECmd isn’t limited to just one system. You can run it on: Live systems  to extract and filter logs on the fly Mounted disk images  or triage collections  during incident response Even older versions of logs through the Volume Shadow Service (VSS) It can also de-duplicate events  across multiple sources, which is super helpful when you’re merging logs from dozens of endpoints. This scalability is what makes it a go-to tool for forensic analysts and threat hunters. Whether you’re investigating a ransomware infection or tracking a suspicious user account, EvtxECmd helps you see patterns that would otherwise stay hidden. unning EvtxEcmd on live system to extract artifacts: COMMAND LINE:  -     EvtxECmd.exe -d C:\windows\system32\winevt\logs --csv C:\Users\user\desktop --csvf eventlogs.csv –vss Breaking Up: -d (directory)  (Path of (directory)logs where it present) --csv \Users\user\desktop (CSV Format where you want store) --csvf eventlogs.csv File name to save CSV formatted results   –vss  Process all Volume Shadow Copies that exist on drive Running EvtxEcmd on collected logs from system: COMMAND LINE:  -     EvtxECmd.exe -d C:\users\user\downloads\logs\ --csv C:\Users\user\desktop --csvf eventlogs.csv -d (Provide path where all logs present)               Running EvtxEcmd on Single log for example security.evtx: COMMAND LINE:  -     EvtxECmd.exe -f C:\users\user\download\security.evtx --csv C:\Users\user\desktop --csvf eventlogs.csv -f (For single evtx file) ------------------------------------------------------------------------------------------------------------- Final Thoughts EvtxECmd takes something notoriously messy — Windows event logs — and turns it into structured, searchable data. It bridges the gap between raw XML chaos and actionable insight. If you’re new to log analysis, this tool will help you focus on what matters: the story the events are trying to tell. And if you’re an experienced investigator, EvtxECmd’s flexibility and map-based approach can dramatically speed up your workflow. -------------------------------------------------------Dean-------------------------------------

  • Part 7 : Secrets Management — The Right Way to Keep Your Secrets Safe

    Hey everyone Let’s talk about one of the most underrated but dangerous  parts of automation and DevOps: secrets management . You might not realize it, but every single system you build — whether it’s an app, CI/CD pipeline, or cloud deployment — has secrets . These are things like API tokens, SSH keys, database passwords, and service credentials that your automation tools, containers, and scripts need to function. ------------------------------------------------------------------------------------------------------------- Why Secrets Management Matters In modern DevOps and cloud environments, everything is automated — provisioning, configuration, deployment, and release pipelines. But automation often requires privileged access to services. That means your infrastructure and code are constantly touching credentials and tokens. So if secrets are hardcoded, exposed in version control, or shared in plain text… well, you’re basically leaving your passwords under the doormat. 🫣 ------------------------------------------------------------------------------------------------------------- How Not  to Keep Secrets Let’s start with what not to do  — because this is where many developers slip up. Keeping Secrets in Code A lot of people hardcode secrets right into their code because it’s quick and easy. But that’s a huge security risk. Why? Anyone with access to your repository can read those secrets. Even if you delete the secret later, it still lives in your version history . In Git, everyone  has a full copy of the repo — including that secret. Rotating secrets means you have to redeploy the code every time. Bottom line: never hardcode credentials . Ever. ------------------------------------------------------------------------------------------------------------- Be Especially Careful with GitHub GitHub is an amazing place for collaboration — but it’s also a goldmine for attackers searching for exposed secrets. Tools to Scan for Secrets in Git Repos Here are some great open-source tools that can help you detect secrets in your repositories: Gitrob 👉 https://github.com/michenriksen/gitrob Scan GitHub repos for sensitive files, credentials, and even things like IPs, domains, and tokens. It maps out all repos under your organization and flags risky content. truffleHog 👉 https://github.com/dxa4481/truffleHog Performs deep searches through the entire commit history  of a repo, looking for high-entropy strings (which often indicate secrets). Git-all-secrets 👉 https://github.com/anshumanbh/git-all-secrets Clones and scans repos using multiple tools (including truffleHog). A great “all-in-one” option. These tools help you catch exposed secrets before they catch you . ------------------------------------------------------------------------------------------------------------- Preventing Secrets from Getting Into Code Detecting secrets is one thing — but wouldn’t it be better if they never made it  into your codebase in the first place? That’s where pre-commit tools come in. They stop you from accidentally committing secrets to your repo. Here are some popular ones: git-secrets  (by AWS Labs) 👉 https://github.com/awslabs/git-secrets Blocks commits that contain secrets. It can be installed locally and even customized with regex patterns. Talisman (ThoughtWorks) 👉 https://github.com/thoughtworks/talisman Hooks into Git’s pre-push process and scans for suspicious content — like private keys or tokens — before allowing a push. SEDATED (OWASP) 👉 https://github.com/OWASP/SEDATED Prevents sensitive data from being pushed to remote Git servers. Git Hound 👉 https://github.com/ezekg/git-hound Uses regular expressions to detect sensitive data in commits and blocks the push if something looks fishy. You can also check out the Pre-commit framework , which has a plugin called detect-secrets  — easy to integrate with your workflow. ------------------------------------------------------------------------------------------------------------- Hands-on with Git-Secrets Let’s look at how to actually use git-secrets , since it’s one of the most popular tools out there. Step 1: Install git-secrets Inside your Git repo, run: git secrets --install This sets up pre-commit hooks automatically. You should see: ✓ Installed commit-msg hook ✓ Installed pre-commit hook ✓ Installed prepare-commit-msg hook Step 2: Register AWS patterns (optional) If you’re using AWS credentials: git secrets --register-aws Step 3: Check what patterns are active git secrets --list This lists all the regex patterns it’s scanning for — like AWS access keys or secret keys. Step 4: Scan your repo git secrets --scan If nothing shows up — awesome! It means your repo is clean. 🎉 ------------------------------------------------------------------------------------------------------------- Ansible — Keep It Simple, Keep It Safe Ansible Vault  ( official docs ) is built right into Ansible (since version 1.5). It allows you to encrypt sensitive data (like passwords, private keys, and tokens) inside special files called vault files . These can be safely stored in your Git repo or shared between teams — no more plain-text secrets! To use it: ansible-vault create secrets.yml You can then edit, view, or decrypt files with: ansible-vault edit secrets.yml ansible-vault view secrets.yml ------------------------------------------------------------------------------------------------------------- Secret Keepers — Centralized Secrets Management At some point, you’ll realize: instead of juggling secrets across multiple tools, you need a central place  to store, rotate, and control access. That’s where Secret Keepers  or Secrets Servers  come in. These are dedicated platforms that: Store and encrypt secrets centrally Allow secure API or CLI access Support rotation, revocation, and auditing Manage authentication and access policies Provide high availability and logging Open-Source Secret Keepers Tool Description Vault OSS (HashiCorp) The most widely used open-source secrets manager. Supports dynamic secrets, key rotation, encryption as a service, and integrates with multiple backends (AWS, databases, etc.). Conjur OSS (CyberArk) Open-source enterprise-grade secrets and identity manager. Handles access control and secret retrieval. Keywhiz (Square) Provides secure access to secrets via REST API or FUSE filesystem. Uses mTLS for authentication. Confidant (Lyft) AWS-native secrets manager that stores encrypted data in DynamoDB. Knox (Pinterest) Lightweight, developer-friendly secrets tool written in Go for key creation and rotation. Commercial Secrets Management Tools Tool Description Amazon KMS Manages encryption keys using dedicated hardware security modules (HSMs). Fully integrated with AWS services. Amazon Secrets Manager Manages secrets like API keys and DB credentials with APIs for rotation and retrieval. CyberArk Secrets Manager Enterprise-grade vaulting solution with AD/LDAP integration and strong auditing. Google KMS / Secret Manager Scalable key and secret management for Google Cloud Platform. Integrated with IAM and audit logging. Microsoft Azure Key Vault Protects keys and secrets using FIPS 140-2 certified HSMs. Integrates with Azure logging and identity services. Vault Enterprise (HashiCorp) Commercial version of Vault with advanced identity management, MFA, replication, and enterprise support. ------------------------------------------------------------------------------------------------------------- Wrapping It Up Secrets management is one of those things that’s boring until it’s not . One small mistake — a single exposed API key — can lead to massive data breaches or unauthorized access. So, remember: Never hardcode secrets. Scan your repos regularly. Use pre-commit hooks  to stop leaks before they happen. Automate responsibly. Your code should be powerful — but your secrets should stay silent . -------------------------------------------------Dean-------------------------------------------------------

  • Managing Vulnerable Dependencies — The Hidden Risk in Open-Source Code

    When we talk about secure coding , we usually think about the code we  write — avoiding insecure functions, preventing injections, or following secure design patterns. But here’s the truth: most of the code running in production today wasn’t even written by us. That’s not necessarily bad — open source drives innovation and saves time. But it also means that we’re inheriting someone else’s vulnerabilities , and in many cases… we don’t even realize it. ------------------------------------------------------------------------------------------------------------- The Open-Source Dependency Problem Here’s the scary part: A single outdated dependency can silently introduce critical security vulnerabilities into your entire application stack. Let’s say you build a web app that depends on 10 libraries. Those libraries might depend on 50 others. And if even one of them has a known vulnerability your system might be at risk without you even touching a line of insecure code. The problem grows when: Developers download old or vulnerable packages  from package managers. Teams don’t update  to newer, patched versions. And sometimes, no one even knows what dependencies  are in the system. That’s why organizations now use dependency analysis tools  — also known as Software Composition Analysis (SCA)  — to automatically detect and monitor these risks. ------------------------------------------------------------------------------------------------------------- How Dependency Scanning Works Dependency analysis tools scan your project’s: Source code Manifest files  (like package.json, requirements.txt, or pom.xml) Or even compiled build artifacts They then identify every open-source component and compare them against known vulnerability databases  — such as the National Vulnerability Database (NVD)  or other proprietary sources. If a component version matches a known vulnerable one, you’ll get an alert — often with details about the CVE ID , severity , and recommended fix . Modern CI/CD pipelines can even fail a build automatically  if a critical vulnerability is detected, preventing risky code from being deployed. ------------------------------------------------------------------------------------------------------------- Popular Open-Source Tools for Managing Vulnerable Dependencies Several open-source tools can help detect and manage vulnerable libraries across different programming ecosystems. Here are some of the most widely used: Tool Language / Features OWASP Dependency-Check Scans Java, .NET, Ruby, Node.js, Python, and limited C/C++ (autoconf/cmake). Compares against CVE databases. Bundler-Audit Checks Ruby Gem dependencies for known vulnerabilities. Retire.js Scans JavaScript libraries (including browser JS) for known security issues. PHP Dependency Checker Detects insecure PHP Composer dependencies. GitHub Dependabot Alerts Automatically detects and reports vulnerable dependencies in Java, JavaScript, .NET, PHP, Python, and Ruby projects. Safety Checks Python dependencies against the Safety DB. Microsoft Application Inspector CLI tool that analyzes dependencies, highlights risks, and flags potential backdoors. Open-source tools include: Ruby:   Bundler-Audit Node.js:   Node Security Project (NSP) JavaScript:   Retire.js PHP:   PHP Dependency Checker Python:   Safety ------------------------------------------------------------------------------------------------------------- Commercial Tools for Dependency Management If you’re working in an enterprise environment, there are several commercial SCA tools  that go beyond open-source scanners. These tools typically: Offer deep integration  into CI/CD pipelines Include license compliance checking Maintain proprietary vulnerability databases  for faster detection Provide governance controls  for managing third-party risk Here are some leading solutions: Tool Features Black Duck (Synopsys) Inventories open-source code for both security and license vulnerabilities. FOSSA Multi-language component analysis with license governance. Sonatype Nexus Lifecycle Integrates into CI/CD pipelines; checks for vulnerable or non-compliant components. Snyk Finds and patches vulnerabilities in Node.js, Ruby, Python, Java, Scala, and more. Free for open-source projects. FlexNet Code Insight Manages and controls downloads of open-source components. SourceClear (CA/Veracode) Detects vulnerabilities not yet public using proprietary analysis. WhiteSource (now Mend) Plugin-based solution that checks both security and licensing issues. JFrog Xray Works with Artifactory; performs deep dependency and license scanning. WhiteHat Security (Sentinel SCA) Adds software composition analysis into the Sentinel Source platform. ------------------------------------------------------------------------------------------------------------- Why This Matters Modern development depends heavily on open-source software — and that’s perfectly fine as long as we manage it responsibly . A single vulnerable dependency can compromise your entire product. That’s why integrating SCA tools (like OWASP Dependency-Check or Snyk) into your CI/CD pipeline  is now considered a best practice. When configured properly, these tools will: Identify outdated or risky components Provide clear remediation paths Automate version updates Help enforce open-source license compliance In short, they give you visibility and control — two things that are often missing when dealing with complex dependency chains. ------------------------------------------------------------------------------------------------------------- Final Thoughts Insecure dependencies are one of the biggest blind spots in modern software development. You might be following every secure coding guideline out there, but if your application uses a vulnerable third-party library, you’re still exposed. By combining SAST tools like Semgrep  with SCA tools like Dependency-Check or Snyk , you get a complete view of your codebase — both your own code and what you’ve inherited. This layered approach is key to building truly secure applications. -------------------------------------------------Dean-------------------------------------------------

  • Remote Execution and Kansa – Still One of the Most Underrated IR Tools

    Whenever I talk about incident response or large-scale data collection, one feature that never fails to amaze me is how PowerShell handles remote execution . It’s built right into Windows, it’s fast, secure, and surprisingly flexible. And trust me — once you understand how powerful remote execution can be, tools like Kansa start to make a lot more sense. Let’s start with the basics. PowerShell Remoting – The Foundation for Scalable Response One of the most useful features of PowerShell is its native support for running commands on remote systems. That’s exactly what makes PowerShell such a gem for incident responders. It uses Windows Remote Management (WinRM) , which in turn relies on WS-Management (WSMAN)  — a protocol that runs over HTTP/S and uses SOAP and XML for communication. If you’ve ever used Enter-PSSession you already know how easy it is to jump into an interactive remote shell. And unlike RDP or PSExec, PowerShell doesn’t leave your credentials lying around on the remote system . That’s a huge win for security. But the real magic happens when you use Invoke-Command With this cmdlet, you can push commands or even entire scripts to one or multiple remote systems — simultaneously. No loops, no complexity. Just one command, and you’re executing across potentially hundreds or even thousands of machines. You might think, “Alright, but won’t that take forever?” Actually, no., WMI loop across 100 systems took six hours, while Invoke-Command did it in just 15 seconds. When scaled up to 1,000 systems, it will finish in just over two minutes. That’s the level of efficiency PowerShell brings to the table. So why am I talking so much about PowerShell remoting? Because that’s exactly what powers Kansa , one of the most beautifully simple yet powerful tools I’ve ever used in my incident response toolkit. ----------------------------------------------------------------------------------------------------------- Let’s Talk About Kansa Now, I’ll be honest — Kansa  isn’t actively maintained by Dave Hull anymore. But even without updates, it’s still one of the most solid, reliable PowerShell-based IR frameworks out there . If you ask me personally, I’d say I prefer KAPE  for many use cases, especially for its modular speed and portability. But when I first saw how simple and effective Kansa  is, I couldn’t help but dive into it. What Makes Kansa Awesome Kansa leverages PowerShell Remoting to run user-defined modules across multiple systems. Whether you’re performing an incident response, threat hunt, or building an environmental baseline — Kansa’s got you covered. Here’s what it does under the hood: If you don’t give it a list of targets, it’ll automatically query Domain Controllers  to find systems. It manages errors and logs  everything neatly to a central file. It runs modules in parallel , up to 32 systems at a time by default. It organizes the output beautifully — one file per host per module. And it uses a Modules.conf  file where you decide which scripts to run and in what order. That last point is really smart. The configuration follows the Order of Volatility , meaning it prioritizes collecting fast-changing data like DNS cache, ARP tables, or Prefetch information first, before moving on to less volatile artifacts. You just move the module names up or down in the file to control the order. Kansa was built for scale — you can gather data from hundreds (or even thousands) of hosts at once, as long as two things are true: WinRM is enabled on your targets, and You’ve got local admin access. That’s it. No fancy setup, no third-party dependencies. ------------------------------------------------------------------------------------------------------------- Setting Up and Using Kansa Getting started is simple — you just grab it from GitHub ( https://github.com/davehull/Kansa ) and extract it anywhere you like. Inside the repository, you’ll find: A Modules  folder — this is where the data collection scripts live, grouped by type. An Analysis  folder — which contains PowerShell scripts for post-collection analysis. If you plan to use the analysis scripts, make sure to drop logparser.exe into your system path (it’s not included by default) . The good part is — Kansa’s output is tab-separated text , so you can load it into Excel, a database, or even feed it into Logparser for custom queries. And here’s what makes it even better: You don’t have to run the full suite  — each of Kansa’s PowerShell scripts can be executed separately. This flexibility means you can use it like a mini collection toolkit. Run just what you need, when you need it.' Honestly, some of the Kansa scripts are among the best-written PowerShell scripts  I’ve seen in the IR space. They’re clean, modular, and incredibly easy to adapt. --------------------------------------------------------------------------------------------------------- Getting Started with Kansa A simple command to kick off data collection using Kansa looks like this: PS C:\tools\Kansa> .\kansa.ps1 -TargetList .\hostlist -Pushbin Here’s what each parameter means: -TargetList .\hostlist  → Specifies the list of systems you want to collect data from. The file should contain one host per line. If you omit this parameter, Kansa automatically queries Active Directory  for all systems. To use AD querying, make sure the Remote Server Administration Tools (RSAT)  module is installed. You can also limit the scope using -TargetCount  to test with a smaller subset before scaling up. -Pushbin  → Tells Kansa to push any required third-party binaries to the target systems before running the collection scripts. Understanding the Kansa Folder Structure Kansa’s folder structure is simple and modular: Kansa │ ├── kansa.ps1 # Main launcher script ├── Modules # Contains PowerShell collectors │ ├── bin # Third-party binaries │ ├── Get-Autorunsc.ps1 │ ├── Get-CertStore.ps1 │ └── ... └── Output # Collection results (auto-created) All collection results are saved in the Output  folder. Each module’s results are written into its own subfolder, and most modules output data in TSV (Tab-Separated Values)  format, making it easy to parse and analyze. Adding Third-Party Binaries While PowerShell is powerful, some modules depend on third-party tools. Kansa supports this through a simple mechanism called a binary dependency directive . For example, the Get-Autorunsc.ps1  module includes the following line: # BINDEP .\Modules\bin\Autorunsc.exe This line tells Kansa to copy Autorunsc.exe to the target machine before running the script. The binaries are copied by default to %SystemRoot% (usually C:\Windows). If you want Kansa to clean up after itself , use the -Rmbin argument to remove these binaries once collection completes. Some modules that rely on third-party binaries include: Get-Autorunsc.ps1 Get-CertStore.ps1 Get-FlsBodyfile.ps1 Get-Handle.ps1 Get-ProcDump.ps1 Get-RekalPslist.ps1 Kansa at Enterprise Scale Originally, Kansa was designed for small to mid-scale collections (150 systems or fewer at a time). However, in 2020, Jon Ketchum transformed it into a truly enterprise-scale tool capable of handling data collection across 150,000+ systems . Why Kansa Matters Kansa bridges the gap between manual data collection  and enterprise-grade visibility . It allows responders to: Gather forensic artifacts quickly from multiple endpoints. Integrate PowerShell and third-party tools into a single workflow. Scale investigations without complex infrastructure. Whether you're running an investigation on 10 systems or 10,000, Kansa adapts to your operational tempo. Real Talk: The Trade-offs Of course, like any live response framework, Kansa isn’t immune to being tricked by rootkits. Since it relies on Windows APIs (just like WMI, .NET, or system commands), a well-built rootkit could theoretically hide its presence . But in the real world, that’s rare. You’re trading off a bit of forensic depth for speed and scale , and that’s usually worth it when you’re dealing with hundreds of endpoints. You can always follow up with a deep dive on a smaller set of systems once you’ve used Kansa to get the bigger picture. Conclusion Kansa remains one of the most underrated tools in incident response. It combines the flexibility of PowerShell with the structure of a modular framework — perfect for both rapid triage and deep forensic collection. If you’re building your own IR toolkit, Kansa deserves a top spot on your list.

  • Understanding Semgrep — A Powerful Open-Source SAST Tool for Developers and Security Teams

    If you’ve ever worked on secure coding or DevSecOps pipelines, you’ve probably come across the term SAST  — Static Application Security Testing. These are the tools that scan your source code for vulnerabilities, misconfigurations, or insecure patterns before  your application even runs. One of the most popular and lightweight tools in this space is Semgrep  — a static analysis tool that’s fast, open-source, and surprisingly easy to customize. Let’s talk about what makes Semgrep stand out and why it’s becoming a go-to for developers and security engineers. -------------------------------------------------------------------------------------------------------- What is Semgrep? Semgrep is an open-source static analysis engine   It’s designed to analyze source code across multiple programming languages, helping you find potential vulnerabilities or risky code patterns. Unlike many bulky enterprise scanners, Semgrep is: Lightweight  – It’s easy to set up and run locally or in CI/CD pipelines. Extensible  – You can easily write your own custom rules. Multi-language  – It supports a wide variety of languages, including: Go, Java, JavaScript, Python, Ruby, TypeScript, C#, and even markup formats like JSON and YAML. That’s pretty rare for an open-source static analysis tool. -------------------------------------------------------------------------------------------------------- How Semgrep Works Semgrep doesn’t just perform simple text searches like grep. Instead, it parses your code into Abstract Syntax Trees (ASTs)  — which basically means it understands  the structure of your code. This allows Semgrep to detect complex issues with a high level of accuracy. Semgrep’s scanning logic is powered by rules , which are written in YAML format. These rules describe specific code patterns or behaviors you want to find. The cool part? You can easily write, test, and publish your own rules using the Semgrep Playground . -------------------------------------------------------------------------------------------------------- The Semgrep Registry If you don’t want to start from scratch, the Semgrep Registry  has you covered. It’s a large community-driven collection of over 1,000 rules , all publicly available at semgrep.dev/explore . Some of the most popular rulesets maintained by r2c are: r2c-ci  – Focused on high-confidence, low-noise rules for CI/CD pipelines. r2c-security-audit  – A more in-depth security audit ruleset for catching subtle vulnerabilities. You can think of these like plug-and-play templates that help you quickly integrate security scanning into your workflow. -------------------------------------------------------------------------------------------------------- Running Semgrep from the Command Line Running a Semgrep scan is incredibly simple. Once you’ve installed it (via CLI or Docker), you can run a full security audit of your codebase with just one command: semgrep --config "p/r2c-security-audit" This command downloads and runs over 200 security-focused rules from the Semgrep registry against your code. By default, results are printed directly to your terminal (stdout). -------------------------------------------------------------------------------------------------------- Semgrep Command-Line Options If you want to customize your scans, Semgrep’s CLI gives you several options. Here are the most useful ones: Option Description -f or -c Specify a YAML configuration file, folder of rule files, or a ruleset from the registry -e Run a custom search pattern directly from the command line -l Restrict scanning to a single language -o Save results to a file or send them to a remote endpoint You can explore all options by running: semgrep --help -------------------------------------------------------------------------------------------------------- Writing Custom Rules One of Semgrep’s biggest strengths is how easy it is to write custom detection rules . You can do this using the Semgrep Playground  ( semgrep.dev/editor ), which lets you test your rules interactively. For example, let’s say you want to identify any AWS policy file that gives full S3 access (s3:*). Here’s a simple rule written in YAML: rules: - id: s3_wildcard_permissions pattern: | { "Effect": "Allow", "Action": "s3:*" } message: Semgrep found a match severity: WARNING This rule will flag any JSON configuration file where Action: "s3:*" appears — a sign of an overly permissive IAM policy. What’s amazing here is that the same rule syntax can be used to scan source code, cloud configs, or even Kubernetes YAML files . So, whether you’re a developer or a cloud engineer, you can use one tool and one query language to identify risky patterns across your entire DevOps pipeline. -------------------------------------------------------------------------------------------------------- CI/CD Integration Semgrep was designed with automation in mind. It fits seamlessly into CI/CD pipelines using: CLI commands Docker containers GitHub Actions This makes it perfect for embedding into your build pipelines , so you can automatically catch vulnerabilities before code is merged — without slowing down developers. -------------------------------------------------------------------------------------------------------- Final Thoughts Semgrep is a great example of how open-source security tools  can compete with — and often outperform — commercial solutions. It’s fast, flexible, and transparent, giving you the power to scan code in your own way. Whether you’re a security engineer trying to enforce secure coding standards or a developer looking to clean up risky code, Semgrep is a tool worth adding to your toolkit. If you want to try it out, here are the official resources: 🔗 GitHub: returntocorp/semgrep 🌐 Semgrep Registry 🧰 Semgrep Playground --------------------------------------------Dean----------------------------------------------------

  • Part 6 : Static Analysis for Configuration and Application Code: Tools and Best Practices

    Configuration code and application code both need to be treated with the same rigor as any other software. Bugs in configuration can be especially dangerous because they can create operational outages, scalability issues, or security vulnerabilities at scale . Unfortunately, reviewing this code often requires specialized knowledge of the underlying platforms and tools, which makes mistakes easier to miss. This is where static analysis  comes in. Static analysis tools help detect common errors, enforce best practices, and highlight potential security issues—before they impact production. Static Analysis for Configuration Management Chef RuboCop  – Ruby style and code quality checks. Cookstyle  – Chef’s official linting tool, powered by RuboCop. Foodcritic (Sunsetted 2019)  – legacy tool, no longer maintained. Puppet Puppet-lint  – syntax and style checks. puppet-lint-security-plugins  – additional security rules. Puppeteer  – automated testing for Puppet code. Ansible Ansible-lint  – ensures playbooks follow best practices. KICS  – infrastructure-as-code security scanner. AWS CloudFormation cfn_nag  – scans templates for insecure patterns. cfripper  – evaluates IAM and security risks. cfn-python-lint  – syntax validation. CloudFormation Guard  – policy-as-code validation. Checkov  – scans IaC for misconfigurations. Static Analysis for Application Code Java Code Quality & Bugs : FindBugs (legacy) , SpotBugs , PMD , Checkstyle . Security : Find Security Bugs , fb-contrib . Advanced Analysis : Error Prone (Google) , Infer (Meta) , SonarSource . .NET / C# FxCop  – legacy, built into Visual Studio. StyleCop  – style enforcement. Puma Scan  – security plugin. Security Code Scan  – Roslyn-based security checks. Roslynator  – analyzers & refactorings. SonarSource . JavaScript Style & Quality : ESLint , JSHint , JSLint . Security : NodeJsScan . Others : Closure Compiler , Flow , SonarSource . PHP Phan  + Taint Check Plugin . PHP CodeSniffer , PHP Mess Detector . Progpilot , Exakat . RIPS (commercial) , SonarSource . Ruby Brakeman  (security), Dawnscanner . RuboCop , RubyCritic . Railroader , SonarSource . Python Bandit , Dlint . Pylint , Pytype . Pyre , Pyright . SonarSource . C / C++ Cppcheck , Clang Analyzer , OCLint . Flawfinder , Infer , SonarSource . Objective-C / Swift Xcode Analyze . SwiftLint , OCLint . Infer , Faux Pas , SonarSource . Android Android Lint , Qark . Custom Lint Rules . Infer . Go Vet , Lint . errcheck , dingo-hunter . Gosec , SafeSQL . SonarSource . Multi-Language Static Analysis For teams working across multiple languages and frameworks: GitHub CodeQL  – semantic code analysis. Semgrep  – fast, rule-based multi-language scanner. Best Practices for Using Static Analysis Integrate Early  – run lightweight checks in CI/CD pipelines to catch issues before deployment. Balance Depth & Speed  – use incremental scans during commits, and schedule deep scans out-of-band. Triage Findings  – security teams should filter false positives and prioritize high-confidence issues. Automate Feedback  – push findings directly into developer workflows (IDE plugins, backlog tickets). Combine Tools  – no single tool covers everything; use a combination for better coverage. Conclusion Static analysis is not just about checking code quality—it’s about catching vulnerabilities early, reducing technical debt, and preventing misconfigurations from becoming large-scale risks . With the right mix of tools and practices, development and security teams can collaborate more effectively, building software that is both reliable and secure. ---------------------------------------------Dean----------------------------------------------------

  • Part 5 : Security in the Commit Phase: Making CI/CD Smarter, Not Slower

    When a developer pushes code, it kicks off the Commit phase  of the DevOps pipeline. This is where the magic of automation happens: builds, tests, scans, and packaging all before the code goes anywhere near production. But here’s the trick: we need to build security into this phase —without slowing developers down. What Security Checks Fit Here? Think of the Commit phase as speed security . We don’t have hours; we have minutes. So our checks need to be lightweight but effective: Unit Tests  → Catch coding mistakes immediately. Incremental SAST (Static Analysis Security Testing)  → Scan only the code that changed. Lightweight Linting & Style Checks  → Make code easier to review and maintain. If all tests pass, we sign the build and store it in a secure artifact repository . This guarantees that what gets deployed later hasn’t been tampered with. -------------------------------------------------------------------------------------------------------- The Goal of SAST in CI/CD Here’s the important mindset shift: Traditional SAST  tries to find all  the vulnerabilities in the codebase. That’s slow and overwhelming. Modern SAST in CI/CD  focuses on catching new vulnerabilities introduced by the latest changes . This way, developers get feedback right away and can fix issues before moving on. -------------------------------------------------------------------------------------------------------- Deep vs. Incremental Scanning Not all scans are created equal: Full scans  → Take hours or even days. Perfect for scheduled jobs (nightly, weekly). Incremental scans  → Only look at the code that changed. Perfect for CI/CD, fast feedback in a few minutes. -------------------------------------------------------------------------------------------------------- Tuning Scanners: Take the Hit for the Team Static analyzers are notorious for false positives . If every scan blocks developers with noise, the pipeline will get ignored—or worse, bypassed. That’s why the security team must “take the false positive hit.” Tune scanners to focus on high-risk, high-confidence findings . Store configuration in version control  so changes are audited. Work with engineers to agree on what’s important enough to block the pipeline. Pro tip: Fail the pipeline if any critical/high findings show up. Save the low-confidence stuff for deeper out-of-band scans. -------------------------------------------------------------------------------------------------------- Writing Your Own Checkers Sometimes tools don’t catch everything. That’s where custom checkers  come in: Simple: grep for dangerous functions or hardcoded secrets. Advanced: write custom plugins for SAST tools like PMD or SonarQube. Examples: Flag eval() or exec() in Python. Detect insecure crypto functions (like MD5, SHA-1). Catch hardcoded AWS keys or passwords. -------------------------------------------------------------------------------------------------------- Different Tools, Different Strengths Not all static analysis tools are equal. Here’s a cheat sheet: Coding style tools  → Checkstyle, PMD, StyleCop, ESLint Not security-focused, but make code easier to read and review. Bug pattern detectors  → FindBugs, FxCop Improve reliability and catch some security issues. Security-focused scanners  → Find Security Bugs, Puma Scan, Fortify, SonarQube Security Rules Look for vulnerabilities using data flow, control flow, and taint analysis. Important: There’s very little overlap between these tools. If you want good coverage, you’ll probably need more than one scanner . To handle duplicates across multiple tools, use aggregators like: OWASP Defect Dojo ThreadFix Code Dx -------------------------------------------------------------------------------------------------------- How to Fit This into CI/CD Here’s a practical Commit phase workflow: Developer pushes code → CI kicks in. Unit tests  + lint checks  run in parallel. Incremental SAST scan  runs in parallel. If time limit breached, send an alert + break scans into smaller chunks. If all checks pass → build is signed & pushed to artifact repo. If critical issues found → block the pipeline until fixed. Meanwhile, schedule nightly full scans  with all checkers enabled. The security team reviews those results, filters out noise, and creates tickets for real issues. -------------------------------------------------------------------------------------------------------- The Bigger Picture Security in the Commit phase isn’t about finding everything . It’s about: Catching mistakes early Giving fast, actionable feedback Building security into the team’s Definition of Done ---------------------------------------------Dean--------------------------------------------------

  • Part 4: Detecting High-Risk Code Changes with Code Owners & Pull Request Security

    Every codebase has certain files that you just don’t want anyone to casually edit. Think about: Authentication and login logic Password handling and crypto libraries Admin panels and backend controls Code that touches private user data Deployment scripts and pipelines If these pieces of code are changed without proper review, the result could be security vulnerabilities, downtime, or even a data breach . That’s why we need a system to detect high-risk code changes and enforce extra approvals. This is where Code Owners files, custom alerts, and pull request templates  come into play. What are Code Owners? A Code Owners file  is a simple text file you place in the root of your repository. It tells GitHub, GitLab, or Bitbucket who “owns” which parts of the code. Think of it like a digital lock: If someone changes a sensitive file, the lock requires approval from the person or group listed as the code owner. Without approval, the change can’t be merged. Rules that appear later override earlier ones. For example: All developers can edit code by default. But if someone touches AccountController.cs, the security team must approve it. Even the   Code Owners file itself is protected (because changing it could bypass the whole system). Why This Matters Let’s say a junior developer accidentally modifies a password hashing function. Without code owners, the change might slip through with just a casual peer review. With code owners, the security team must approve  it before it gets merged. This gives you: Control  – High-risk code can’t be changed by mistake. Visibility  – Security teams see changes that matter. Accountability  – The right people approve sensitive updates. Detecting Risky Code Changes with Alerts One of the security teams took this a step further. Instead of only depending on code owners, they hash sensitive files  and write unit tests to ensure nothing changes silently. Here’s a C# example: [Theory] [InlineData("/Web/AccountController.cs", "2aabf33b66ddb07787f882ceed0718826af897q7")] [InlineData("/Shared/Services/Cryptography/Hash.cs", "87f88d137d37a7ed908737552eed0c524133b6")] public void HighRiskCode_ChecksumTest(string file, string checksum) { bool match = checksum.Equals(Hash.GetChecksum(file)); if(!match) NotificationService.RequestCodeReview(file); Assert.True(match); } What this does: Each high-risk file has a checksum (unique fingerprint). If the file changes, the test fails. When it fails, the system notifies the developer, their manager, and the security team. This runs automatically in Continuous Integration (CI) . So if someone modifies crypto code, you’ll know immediately. Security Checklists with Pull Request Templates What about developer awareness? That’s where pull request templates  come in. A template is just a Markdown file that gets pre-filled when someone opens a pull request. For example: ### Security Checklist - [ ] Have I reviewed this change for security risks? - [ ] Am I touching authentication, crypto, or private data? - [ ] Have I notified the security team if needed? Developers must check these boxes before submitting. It’s not automatic enforcement, but it creates awareness and accountability . Separation of Duties in Approvals The final piece of the puzzle is workflow separation : Developer opens a pull request. Code owners are automatically assigned. Security team (or other owners) review the changes. Once approved, the merge triggers build pipelines and deployments. This ensures no single person can sneak in a risky change. Approvals must come from the right group of people. ------------------------------------------------------------------------------------------------------------ Putting It All Together This combination gives you: Prevention (owners block unapproved changes)0 -- CODEOWNERS   Detection (unit tests catch file modifications) -- Add checksum-based unit tests   Awareness (checklists guide developers) -- Leverage templates   Governance (audit trail of approvals) -- Require approvals By combining these, you create a secure GitFlow workflow  where high-risk code is guarded, reviewed, and deployed with confidence.

  • Part 3 : Version Control Security: Branch Protections

    Branches in Git are like “lanes” of code. Some lanes are safe for experiments (feature branches), but others are critical highways (main, develop, release branches). If someone pushes bad code straight into main, it could break production in seconds. That’s why branch protections  exist: to put guardrails around your most important branches. ------------------------------------------------------------------------------------------------------------- GitHub Branch Protections On GitHub, branch protections are very customizable . Here are the most important options: Require Pull Request Reviews (✅ Always Enable) At least 1–2 people must review before merging. Stops “lone wolf” coding straight into production. Include Administrators (✅ Enable this!) By default, admins can bypass protections. If their account or SSH key is compromised, attackers can push directly into main. Enabling this forces even admins to follow the rules. Require Signed Commits (Optional, but Strong) Developers must sign commits with GPG keys. Prevents impersonation or “mystery commits” from unverified users. Disallow Force Pushes (✅ Keep Disabled) Prevents someone from overwriting history with git push --force. Protects from lost work or sneaky backdoor commits. Disallow Deletions (✅ Keep Disabled) No one should be able to delete main or develop. Period. In short:  On GitHub, always enforce reviews, admin restrictions, no force pushes, no deletions . Signed commits are a bonus layer. ------------------------------------------------------------------------------------------------------------- GitLab Branch Protections GitLab’s rules are simpler but still powerful: Allowed to Merge: Decide which group(s) can merge changes. Typically: “Maintainers” for main, “Developers” for develop. Allowed to Push: Should always be set to No One  for protected branches. This forces Merge Requests only , which means reviews and checks must pass. Require Code Owner Approval (Premium Feature): Lets you require approvals from the owner of a specific file or directory . Example: Only security engineers can approve changes to auth/. Great for granular control, but requires GitLab Premium. In short:  In GitLab, enforce No direct pushes, only MRs, proper role-based merging, and (if available) CodeOwner approvals. ------------------------------------------------------------------------------------------------------------- Azure DevOps Branch Policies Azure DevOps calls them Branch Policies , and they’re pretty flexible: Require Minimum Number of Reviewers: Define how many approvals are needed before merge. Typically 2 reviewers for critical branches. Disallow Self-Approval: Prevents developers from approving their own PRs. Helps enforce “separation of duties.” Block Last Pusher from Approving: The person who made the last commit can’t count as a reviewer. Stops someone from sneaking in changes and approving themselves. Reject if Any Reviewer Votes No: Default: if someone rejects, the PR is blocked. You can override this, but generally safer to block unless explicitly approved. Reset Votes on New Commits: If new code is pushed after a review, approvals reset. Ensures fresh eyes on fresh changes. In short:  Azure DevOps gives you more knobs to tune — use them to enforce real reviews, prevent self-approvals, and reset approvals if new code is added. ------------------------------------------------------------------------------------------------------------- Comparing GitHub vs GitLab vs Azure DevOps Feature GitHub GitLab Azure DevOps Require Reviews ✅ Yes ✅ Yes (via MRs) ✅ Yes Admin Restrictions ✅ Yes ❌ Limited ✅ Yes Signed Commits ✅ Yes ❌ Not built-in ✅ Yes (via policy) Force Push Protection ✅ Yes ✅ Yes ✅ Yes Branch Deletion Protection ✅ Yes ✅ Yes ✅ Yes Code Owner Rules ✅ Yes ✅ Premium only ✅ Yes Advanced Review Rules ⚠️ Basic ⚠️ Limited ✅ Very Flexible ------------------------------------------------------------------------------------------------------------- Best Practices (No Matter the Platform) Protect main and develop (and release branches if used). No direct pushes — all changes via PR/MR . Always require at least 1–2 reviewers , preferably more for sensitive code. Don’t let devs approve their own changes. Restrict admins — they should follow the same rules. Disable force pushes and deletions on critical branches. Use Code Owners  for sensitive areas (auth, payments, infra). Branch protections = “guardrails” for your repo .They don’t just enforce process, they reduce insider threats, mistakes, and even admin account compromises . ---------------------------------------------------Dean---------------------------------------------------

bottom of page