<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Qimin Zhao</title>
    <description>The latest articles on DEV Community by Qimin Zhao (@sec123).</description>
    <link>https://dev.to/sec123</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3958231%2Fa63aa5ef-babb-400a-b7df-44cec38af7b6.jpeg</url>
      <title>DEV Community: Qimin Zhao</title>
      <link>https://dev.to/sec123</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sec123"/>
    <language>en</language>
    <item>
      <title>Turning first-pass host evidence into a DFIR handoff report</title>
      <dc:creator>Qimin Zhao</dc:creator>
      <pubDate>Fri, 29 May 2026 15:03:48 +0000</pubDate>
      <link>https://dev.to/sec123/turning-first-pass-host-evidence-into-a-dfir-handoff-report-3aem</link>
      <guid>https://dev.to/sec123/turning-first-pass-host-evidence-into-a-dfir-handoff-report-3aem</guid>
      <description>&lt;p&gt;Most incident-response writeups focus on the detection moment: a suspicious IP, a strange login, a web-root file, a Java service behaving oddly, or a process listening on a port it should not expose.&lt;/p&gt;

&lt;p&gt;That first clue matters, but the next problem is usually more operational:&lt;/p&gt;

&lt;p&gt;How do you turn the first 15-30 minutes of host triage into something another responder can trust, review, and continue?&lt;/p&gt;

&lt;p&gt;A useful first-pass handoff is not just a paragraph that says "probably compromised." It should preserve the evidence trail, the commands or collectors used, the confidence level, the gaps, and the next manual checks.&lt;/p&gt;

&lt;p&gt;Here is the handoff shape I like for AI-assisted host investigation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with a bounded question
&lt;/h2&gt;

&lt;p&gt;Instead of giving an AI agent a production shell, start with a narrow investigation question and a time window.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;oi ask &lt;span class="s2"&gt;"Investigate this server for suspicious login, web, process, network, persistence, and recent-file clues over the last 7 days. Do not remediate."&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; 7d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or if the alert starts from one external address:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;oi ip 203.0.113.77 &lt;span class="nt"&gt;-s&lt;/span&gt; 7d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important part is not the exact command. The important part is the boundary: collect and correlate host evidence, but do not mutate the host.&lt;/p&gt;

&lt;h2&gt;
  
  
  Collect evidence by category, not by vibes
&lt;/h2&gt;

&lt;p&gt;For a server case, a first pass should usually cover at least these areas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;authentication events and failed/successful login patterns&lt;/li&gt;
&lt;li&gt;local accounts, groups, sudoers, and authorized keys summaries&lt;/li&gt;
&lt;li&gt;process snapshots and suspicious command lines&lt;/li&gt;
&lt;li&gt;listening sockets and active network connections&lt;/li&gt;
&lt;li&gt;systemd, cron, startup items, and other persistence points&lt;/li&gt;
&lt;li&gt;web logs and recent web-root file changes where relevant&lt;/li&gt;
&lt;li&gt;Java process and memory-shell perimeter clues where relevant&lt;/li&gt;
&lt;li&gt;recent files, packages, containers, and shell history clues&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not to prove the whole incident in one pass. The goal is to avoid handing off a vague summary with no supporting trail.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep the case directory as the handoff object
&lt;/h2&gt;

&lt;p&gt;Open Investigator writes every run into a case folder like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.oi/cases/&amp;lt;case-id&amp;gt;/
  case.json       # investigation input and mode
  evidence.jsonl  # evidence records with evidence_id
  commands.log    # allowed/denied command audit
  report.json     # structured report
  report.md       # human-readable report
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That structure is useful because different responders need different artifacts.&lt;/p&gt;

&lt;p&gt;The analyst reading quickly wants &lt;code&gt;report.md&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The person validating claims wants &lt;code&gt;evidence.jsonl&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The reviewer checking what the tool did wants &lt;code&gt;commands.log&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The team integrating the result into a ticket, case system, or downstream tool wants &lt;code&gt;report.json&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should go into report.md
&lt;/h2&gt;

&lt;p&gt;A good first-pass report should separate conclusions from evidence. I would expect sections like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;executive summary&lt;/li&gt;
&lt;li&gt;observed signals&lt;/li&gt;
&lt;li&gt;timeline or chain of suspicious activity&lt;/li&gt;
&lt;li&gt;key evidence IDs&lt;/li&gt;
&lt;li&gt;confidence and risk level&lt;/li&gt;
&lt;li&gt;evidence gaps&lt;/li&gt;
&lt;li&gt;recommended manual follow-up&lt;/li&gt;
&lt;li&gt;explicit non-actions taken by the tool&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The phrase "explicit non-actions" matters. If the tool did not block an IP, kill a process, delete a file, disable an account, restart a service, change firewall state, or isolate the host, the report should make that clear.&lt;/p&gt;

&lt;p&gt;That is not just legal caution. It helps the next responder understand that the system was used for investigation, not remediation.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should go into commands.log
&lt;/h2&gt;

&lt;p&gt;If an AI system can ask for host checks, the audit trail should show what was allowed and what was denied.&lt;/p&gt;

&lt;p&gt;For example, I want to know whether the run used only sealed read-only collectors, whether a policy-filtered read-only command fallback was used, and whether anything was denied because it looked destructive or outside scope.&lt;/p&gt;

&lt;p&gt;A useful command audit answers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which collector or command ran?&lt;/li&gt;
&lt;li&gt;Why was it allowed?&lt;/li&gt;
&lt;li&gt;Was anything denied?&lt;/li&gt;
&lt;li&gt;Which case did the action belong to?&lt;/li&gt;
&lt;li&gt;Did it write only to the case directory?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is one of the places where AI incident tooling should be boring on purpose.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do not let the summary outrun the evidence
&lt;/h2&gt;

&lt;p&gt;The report should not pretend to know what it did not inspect.&lt;/p&gt;

&lt;p&gt;Examples of honest gaps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;outbound traffic was not proven&lt;/li&gt;
&lt;li&gt;EDR telemetry was not correlated yet&lt;/li&gt;
&lt;li&gt;cloud control-plane logs were not reviewed&lt;/li&gt;
&lt;li&gt;packet captures were not available&lt;/li&gt;
&lt;li&gt;application-level impact was not validated&lt;/li&gt;
&lt;li&gt;Java deep diagnostics were not enabled&lt;/li&gt;
&lt;li&gt;heap or JFR artifacts were intentionally not collected&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those gaps are not failures. They are the checklist for the next responder.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why read-only matters for handoff
&lt;/h2&gt;

&lt;p&gt;In an incident, the first tool that touches the host can accidentally change the evidence story.&lt;/p&gt;

&lt;p&gt;For a first-pass AI investigator, I want the default boundary to be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;read logs, metadata, process snapshots, network state, persistence config, and relevant file metadata&lt;/li&gt;
&lt;li&gt;write only case artifacts and audit records&lt;/li&gt;
&lt;li&gt;avoid remediation authority by default&lt;/li&gt;
&lt;li&gt;require explicit flags for heavier diagnostics&lt;/li&gt;
&lt;li&gt;preserve enough raw evidence for a human to challenge the summary&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That boundary makes the result more useful to a real DFIR/SOC workflow because another person can pick up the case without guessing what the AI changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical handoff checklist
&lt;/h2&gt;

&lt;p&gt;Before sending the case to a teammate, I would check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the original question and time window clear in &lt;code&gt;case.json&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;Does &lt;code&gt;report.md&lt;/code&gt; cite evidence IDs instead of unsupported claims?&lt;/li&gt;
&lt;li&gt;Does &lt;code&gt;evidence.jsonl&lt;/code&gt; include the raw or summarized observations needed to challenge the conclusion?&lt;/li&gt;
&lt;li&gt;Does &lt;code&gt;commands.log&lt;/code&gt; show allowed and denied actions?&lt;/li&gt;
&lt;li&gt;Are gaps written as follow-up tasks?&lt;/li&gt;
&lt;li&gt;Are heavy artifacts, if any, explicitly requested and stored under the case directory?&lt;/li&gt;
&lt;li&gt;Is the report clear that investigation happened but remediation did not?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the difference between "AI wrote a summary" and "the team received a case they can work."&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Open Investigator fits
&lt;/h2&gt;

&lt;p&gt;I maintain Open Investigator at Arvanta Cyber. It is an Apache-2.0 local AI server investigator for Linux and Windows incident response.&lt;/p&gt;

&lt;p&gt;The design goal is narrow: let AI collect and correlate host evidence through sealed read-only tools, then produce reviewable case artifacts. It is not an EDR replacement, not a SIEM/SOAR replacement, and not an automated remediation system.&lt;/p&gt;

&lt;p&gt;Useful starting points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Product overview: &lt;a href="https://www.arvantacyber.com/open-investigator/" rel="noopener noreferrer"&gt;https://www.arvantacyber.com/open-investigator/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;AI DFIR report page: &lt;a href="https://www.arvantacyber.com/open-investigator/ai-dfir-reporting-tool/" rel="noopener noreferrer"&gt;https://www.arvantacyber.com/open-investigator/ai-dfir-reporting-tool/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Open-source repo: &lt;a href="https://github.com/SEc-123/open-investigator" rel="noopener noreferrer"&gt;https://github.com/SEc-123/open-investigator&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I would be interested in how other DFIR, SOC, SRE, and security engineering teams structure first-pass handoff reports. The report format is often where tooling either becomes operationally useful or turns into one more summary to distrust.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>opensource</category>
      <category>incidentresponse</category>
    </item>
    <item>
      <title>How to triage Java memory-shell clues without unsafe default heap dumps</title>
      <dc:creator>Qimin Zhao</dc:creator>
      <pubDate>Fri, 29 May 2026 13:05:06 +0000</pubDate>
      <link>https://dev.to/sec123/how-to-triage-java-memory-shell-clues-without-unsafe-default-heap-dumps-4ch6</link>
      <guid>https://dev.to/sec123/how-to-triage-java-memory-shell-clues-without-unsafe-default-heap-dumps-4ch6</guid>
      <description>&lt;p&gt;Disclosure: I maintain Open Investigator at Arvanta Cyber.&lt;/p&gt;

&lt;p&gt;A suspected Java memory shell is an awkward incident-response starting point. You may not have a clean IOC. You may only have a strange request path, a servlet that should not exist, a web process that opened an unexpected connection, or a Java service that suddenly behaves differently after a deploy window.&lt;/p&gt;

&lt;p&gt;The risky move is to jump straight to heavy production diagnostics. Heap dumps and flight recordings can be useful, but they can also be large, sensitive, and disruptive if a team treats them as the first button to press.&lt;/p&gt;

&lt;p&gt;For a first pass, I want a safer question:&lt;/p&gt;

&lt;p&gt;What read-only evidence can I collect before asking for heavier JVM inspection?&lt;/p&gt;

&lt;h2&gt;
  
  
  The first-pass Java triage loop
&lt;/h2&gt;

&lt;p&gt;I would start with low-impact context:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Identify Java processes and service owners.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Look at process command lines, working directories, users, service managers, and how the JVM was launched.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Review JVM flags and attach-style clues.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Useful clues include unexpected &lt;code&gt;-javaagent&lt;/code&gt;, &lt;code&gt;-agentlib&lt;/code&gt;, JDWP, &lt;code&gt;Xbootclasspath&lt;/code&gt;, suspicious classpaths, unusual temp directories, and command lines that do not match the expected service unit.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Correlate with web and app evidence.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A memory shell often matters because it is reachable through a web surface. I want nearby web logs, request paths, status codes, user agents, reverse proxy logs, app logs, and recent changes under web roots or application directories.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Expand to process and network context.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Which ports are listening? Are there new outbound connections from the Java user? Are there child processes that should not exist? Did the Java service touch files or directories at the same time as the suspicious request?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check persistence around the same window.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Systemd units, cron entries, startup scripts, modified service files, package changes, and recently changed files can explain whether this looks transient or durable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where AI can help safely
&lt;/h2&gt;

&lt;p&gt;AI is useful here when it correlates many small pieces of evidence. It is less useful, and more dangerous, when it gets broad production-changing authority.&lt;/p&gt;

&lt;p&gt;For this type of investigation, I want the AI to ask for bounded read-only checks and produce a report a human can challenge. I do not want it to kill the Java process, delete files, restart the service, block IPs, disable accounts, or start dumping memory without approval.&lt;/p&gt;

&lt;p&gt;With Open Investigator, the low-impact starting point looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;oi java &lt;span class="nt"&gt;-s&lt;/span&gt; 14d
oi mem &lt;span class="nt"&gt;-s&lt;/span&gt; 14d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those checks focus on Java process metadata, JVM launch clues, related web/app evidence, process context, network context, recent files, and persistence evidence.&lt;/p&gt;

&lt;p&gt;If the production owner approves deeper JVM inspection, the deeper path is explicit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;oi mem &lt;span class="nt"&gt;-s&lt;/span&gt; 14d &lt;span class="nt"&gt;-m&lt;/span&gt; inv &lt;span class="nt"&gt;--java-deep&lt;/span&gt;
oi java &lt;span class="nt"&gt;-s&lt;/span&gt; 14d &lt;span class="nt"&gt;-m&lt;/span&gt; inv &lt;span class="nt"&gt;--java-deep&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And heavy artifacts are separate decisions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;oi mem &lt;span class="nt"&gt;-s&lt;/span&gt; 14d &lt;span class="nt"&gt;-m&lt;/span&gt; inv &lt;span class="nt"&gt;--java-deep&lt;/span&gt; &lt;span class="nt"&gt;--heap-dump&lt;/span&gt;
oi mem &lt;span class="nt"&gt;-s&lt;/span&gt; 14d &lt;span class="nt"&gt;-m&lt;/span&gt; inv &lt;span class="nt"&gt;--java-deep&lt;/span&gt; &lt;span class="nt"&gt;--jfr-dump&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That separation matters. A first-pass report should not quietly turn into a heap dump workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the output should achieve
&lt;/h2&gt;

&lt;p&gt;The goal is not AI says this is a memory shell. The useful output is a case folder with evidence and uncertainty preserved:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;evidence.jsonl&lt;/code&gt; for individual evidence records&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;commands.log&lt;/code&gt; for commands and denials&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;report.json&lt;/code&gt; for structured handoff&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;report.md&lt;/code&gt; for responder review&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A good report should say what was observed, what is suspicious, what looks normal, what evidence is missing, and what needs manual confirmation.&lt;/p&gt;

&lt;p&gt;That is the practical value: faster first-pass triage without pretending the tool has finished the incident.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Open Investigator fits
&lt;/h2&gt;

&lt;p&gt;Open Investigator is an Apache-2.0 local AI server investigator. It runs on Linux and Windows hosts and gives the model sealed read-only tools for auth, accounts, processes, network, persistence, services, web logs, Java clues, recent files, packages, containers, and history.&lt;/p&gt;

&lt;p&gt;The boundary is deliberate: it investigates, but it does not remediate.&lt;/p&gt;

&lt;p&gt;Related Arvanta page on Java memory-shell investigation:&lt;br&gt;
&lt;a href="https://www.arvantacyber.com/open-investigator/java-memory-shell-investigation/" rel="noopener noreferrer"&gt;https://www.arvantacyber.com/open-investigator/java-memory-shell-investigation/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open Investigator overview:&lt;br&gt;
&lt;a href="https://www.arvantacyber.com/open-investigator/" rel="noopener noreferrer"&gt;https://www.arvantacyber.com/open-investigator/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open-source repo:&lt;br&gt;
&lt;a href="https://github.com/SEc-123/open-investigator" rel="noopener noreferrer"&gt;https://github.com/SEc-123/open-investigator&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I would be interested in feedback from Java operators, SREs, DFIR teams, and blue-team engineers: what evidence would you require before approving deeper JVM inspection on a production service?&lt;/p&gt;

</description>
      <category>security</category>
      <category>java</category>
      <category>incidentresponse</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How to investigate suspicious SSH logins without giving AI a shell</title>
      <dc:creator>Qimin Zhao</dc:creator>
      <pubDate>Fri, 29 May 2026 12:37:46 +0000</pubDate>
      <link>https://dev.to/sec123/how-to-investigate-suspicious-ssh-logins-without-giving-ai-a-shell-407n</link>
      <guid>https://dev.to/sec123/how-to-investigate-suspicious-ssh-logins-without-giving-ai-a-shell-407n</guid>
      <description>&lt;p&gt;A lot of Linux incident response starts with a login question, not a malware sample.&lt;/p&gt;

&lt;p&gt;Someone sees a spike of failed SSH attempts. A root login appears in the wrong time window. A service account logs in from an address nobody recognizes. A helpdesk ticket says "the server looks weird" and the only concrete clue is a username or IP address.&lt;/p&gt;

&lt;p&gt;At that point, the useful question is not "is this host compromised?" It is more boring and more important:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Did anyone actually authenticate?&lt;/li&gt;
&lt;li&gt;Which account was involved?&lt;/li&gt;
&lt;li&gt;Was it password, key, sudo, su, or a scheduled task?&lt;/li&gt;
&lt;li&gt;Was the same IP seen in web logs, current sockets, process context, or command history?&lt;/li&gt;
&lt;li&gt;Did persistence, services, packages, or recent files change near the same time?&lt;/li&gt;
&lt;li&gt;Can another responder review exactly what evidence was collected?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last point matters. If you let an AI assistant freely run shell commands during the first pass, you can get speed, but you also create a new risk: the model may over-collect, mutate the host, or produce a confident answer that nobody can audit later.&lt;/p&gt;

&lt;p&gt;For a login anomaly, I prefer a read-only evidence loop.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical first pass
&lt;/h2&gt;

&lt;p&gt;Start with the narrow clue if you have one.&lt;/p&gt;

&lt;p&gt;If the alert names a user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;oi login &lt;span class="nt"&gt;--user&lt;/span&gt; root &lt;span class="nt"&gt;-s&lt;/span&gt; 7d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the alert names an IP address:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;oi login &lt;span class="nt"&gt;--ip&lt;/span&gt; 203.0.113.44 &lt;span class="nt"&gt;-s&lt;/span&gt; 7d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the alert is vague, start wider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;oi login &lt;span class="nt"&gt;-s&lt;/span&gt; 7d
oi scan &lt;span class="nt"&gt;-s&lt;/span&gt; 7d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal of the first pass is not to prove every detail. The goal is to build a timeline that a human responder can challenge.&lt;/p&gt;

&lt;p&gt;For a suspicious SSH login, I want the initial report to answer five things.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Authentication pattern
&lt;/h2&gt;

&lt;p&gt;Look for the difference between noise and access.&lt;/p&gt;

&lt;p&gt;A server can receive thousands of failed SSH attempts from the internet. That is useful background, but it is not the same as a successful session. The first split should be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;failed attempts only&lt;/li&gt;
&lt;li&gt;successful login after many failures&lt;/li&gt;
&lt;li&gt;accepted key from an unusual source&lt;/li&gt;
&lt;li&gt;login by an account that normally should not be interactive&lt;/li&gt;
&lt;li&gt;root login where root SSH should be disabled&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A good report should show the exact log lines or normalized evidence behind that assessment, not just say "suspicious login observed."&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Account context
&lt;/h2&gt;

&lt;p&gt;The username is only one part of the story.&lt;/p&gt;

&lt;p&gt;For the involved account, collect read-only account facts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UID and groups&lt;/li&gt;
&lt;li&gt;shell&lt;/li&gt;
&lt;li&gt;home directory&lt;/li&gt;
&lt;li&gt;recent password or account metadata if available&lt;/li&gt;
&lt;li&gt;sudo-related context&lt;/li&gt;
&lt;li&gt;whether the account looks like a human, service, or automation identity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This helps separate a noisy brute-force event from a potentially meaningful access event.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Session and process context
&lt;/h2&gt;

&lt;p&gt;If the login was successful, ask what was active around the same time.&lt;/p&gt;

&lt;p&gt;Useful read-only checks include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;current sessions&lt;/li&gt;
&lt;li&gt;process snapshot&lt;/li&gt;
&lt;li&gt;parent/child process hints&lt;/li&gt;
&lt;li&gt;network sockets&lt;/li&gt;
&lt;li&gt;command history if available and appropriate&lt;/li&gt;
&lt;li&gt;recent files in likely working directories&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these alone prove compromise. Together, they can show whether the login became a shell, touched a web root, started a process, connected outbound, or did nothing observable.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Persistence and service changes
&lt;/h2&gt;

&lt;p&gt;Login anomalies often matter because of what follows.&lt;/p&gt;

&lt;p&gt;For the same time window, check persistence surfaces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cron and timer entries&lt;/li&gt;
&lt;li&gt;systemd services&lt;/li&gt;
&lt;li&gt;shell startup files&lt;/li&gt;
&lt;li&gt;recently modified files&lt;/li&gt;
&lt;li&gt;unusual listeners&lt;/li&gt;
&lt;li&gt;package changes&lt;/li&gt;
&lt;li&gt;container changes if the host runs containers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first pass should be explicit about gaps. For example: "auth logs show a successful login, but no matching persistence change was found in the collected window" is much more useful than a dramatic conclusion.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Reviewable output
&lt;/h2&gt;

&lt;p&gt;The output should not be an opaque chat answer.&lt;/p&gt;

&lt;p&gt;For a real handoff, I want a case folder that contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;evidence.jsonl&lt;/code&gt; for normalized observations&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;commands.log&lt;/code&gt; for what was collected&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;report.json&lt;/code&gt; for structured findings&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;report.md&lt;/code&gt; for the human-readable narrative&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This lets a second responder inspect the evidence, rerun missing checks, disagree with the conclusion, or attach the report to a ticket.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the AI boundary matters
&lt;/h2&gt;

&lt;p&gt;An AI assistant is useful for correlation. It can connect login times, accounts, IPs, files, services, and network state faster than a tired human staring at separate terminals.&lt;/p&gt;

&lt;p&gt;But during first-pass incident response, the assistant should not have authority to remediate by default.&lt;/p&gt;

&lt;p&gt;It should not:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;kill processes&lt;/li&gt;
&lt;li&gt;delete files&lt;/li&gt;
&lt;li&gt;disable accounts&lt;/li&gt;
&lt;li&gt;restart services&lt;/li&gt;
&lt;li&gt;block IPs&lt;/li&gt;
&lt;li&gt;change firewall rules&lt;/li&gt;
&lt;li&gt;install packages&lt;/li&gt;
&lt;li&gt;upload or download tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those actions may be appropriate later, but they belong in an approved response step, not in evidence collection.&lt;/p&gt;

&lt;p&gt;The safer pattern is: collect bounded evidence, write an auditable report, then let the responder decide what to do next.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Open Investigator fits
&lt;/h2&gt;

&lt;p&gt;I maintain Open Investigator at Arvanta Cyber. It is an Apache-2.0 local AI incident investigation CLI for Linux and Windows hosts. The project is built around this read-only first-pass model: AI gets sealed investigation tools, not arbitrary remediation authority.&lt;/p&gt;

&lt;p&gt;For login anomalies, WebShell clues, suspicious IPs, Java service issues, and vague server alerts, the point is to turn a loose signal into a reviewable case folder.&lt;/p&gt;

&lt;p&gt;Project:&lt;br&gt;
&lt;a href="https://github.com/SEc-123/open-investigator" rel="noopener noreferrer"&gt;https://github.com/SEc-123/open-investigator&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Overview:&lt;br&gt;
&lt;a href="https://www.arvantacyber.com/open-investigator/" rel="noopener noreferrer"&gt;https://www.arvantacyber.com/open-investigator/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Related read-only AI incident response guide:&lt;br&gt;
&lt;a href="https://www.arvantacyber.com/open-investigator/articles/local-ai-server-incident-response/" rel="noopener noreferrer"&gt;https://www.arvantacyber.com/open-investigator/articles/local-ai-server-incident-response/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>incidentresponse</category>
      <category>linux</category>
      <category>security</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How to triage a suspected WebShell without giving AI a shell</title>
      <dc:creator>Qimin Zhao</dc:creator>
      <pubDate>Fri, 29 May 2026 12:03:23 +0000</pubDate>
      <link>https://dev.to/sec123/how-to-triage-a-suspected-webshell-without-giving-ai-a-shell-3jp5</link>
      <guid>https://dev.to/sec123/how-to-triage-a-suspected-webshell-without-giving-ai-a-shell-3jp5</guid>
      <description>&lt;p&gt;A suspected WebShell is awkward because the first clue is often weak.&lt;/p&gt;

&lt;p&gt;You may have one odd request in an access log, one newly modified file under a web root, a process running as the web user, or an outbound connection that does not fit the service.&lt;/p&gt;

&lt;p&gt;The dangerous move is to jump straight into cleanup. Before deleting files or restarting services, a responder needs a small evidence map:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what request or path started the suspicion&lt;/li&gt;
&lt;li&gt;whether related files changed recently&lt;/li&gt;
&lt;li&gt;whether the web user has unusual processes&lt;/li&gt;
&lt;li&gt;whether those processes have network connections&lt;/li&gt;
&lt;li&gt;whether persistence or scheduled tasks changed nearby&lt;/li&gt;
&lt;li&gt;whether auth logs show a related login or privilege event&lt;/li&gt;
&lt;li&gt;what evidence is still missing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the point where local, read-only AI can be useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start from the web root, not a verdict
&lt;/h2&gt;

&lt;p&gt;A practical first pass can start with the web root and recent time window:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;oi web &lt;span class="nt"&gt;--root&lt;/span&gt; /var/www &lt;span class="nt"&gt;-s&lt;/span&gt; 7d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal is not to ask AI to decide whether the host is compromised. The goal is to collect enough context that a human can challenge the next step.&lt;/p&gt;

&lt;p&gt;For a suspected WebShell, I would want the first-pass collector to look at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;recently changed files under the web root&lt;/li&gt;
&lt;li&gt;suspicious script extensions or unexpected upload locations&lt;/li&gt;
&lt;li&gt;web access/error log entries around those paths&lt;/li&gt;
&lt;li&gt;requests with unusual parameters, encodings, or user agents&lt;/li&gt;
&lt;li&gt;processes owned by the web service user&lt;/li&gt;
&lt;li&gt;listening sockets and outbound connections&lt;/li&gt;
&lt;li&gt;persistence files, services, cron entries, and recent auth activity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of those require remediation authority.&lt;/p&gt;

&lt;h2&gt;
  
  
  Correlate weak clues
&lt;/h2&gt;

&lt;p&gt;A single clue is noisy. A PHP file changed yesterday may be a normal deploy. A POST request to an upload directory may be normal application behavior. An outbound connection may belong to a legitimate integration.&lt;/p&gt;

&lt;p&gt;The value comes from correlation.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A new file appears in an upload directory.&lt;/li&gt;
&lt;li&gt;Web logs show a POST to that file shortly after creation.&lt;/li&gt;
&lt;li&gt;A process owned by the web user opens an outbound connection.&lt;/li&gt;
&lt;li&gt;The same time window shows a service or cron change.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That chain is not a final incident report, but it is much more useful than a vague alert.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep the AI boundary boring
&lt;/h2&gt;

&lt;p&gt;If an AI investigation tool can run arbitrary shell on a production host, it is too easy for the model to cross from investigation into response.&lt;/p&gt;

&lt;p&gt;For this workflow, I want the model to request sealed read-only checks instead of improvising commands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;web log checks&lt;/li&gt;
&lt;li&gt;recent file checks&lt;/li&gt;
&lt;li&gt;process snapshots&lt;/li&gt;
&lt;li&gt;network snapshots&lt;/li&gt;
&lt;li&gt;persistence snapshots&lt;/li&gt;
&lt;li&gt;auth/account context&lt;/li&gt;
&lt;li&gt;package and container context when relevant&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The tool should log every command and every denial. It should write evidence separately from the summary, so a responder can reproduce or reject the conclusion.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a useful output looks like
&lt;/h2&gt;

&lt;p&gt;A useful first pass should produce a case folder, not just a paragraph.&lt;/p&gt;

&lt;p&gt;The artifacts I want are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;evidence.jsonl&lt;/code&gt; for structured observations&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;commands.log&lt;/code&gt; for the audit trail&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;report.json&lt;/code&gt; for machine-readable handoff&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;report.md&lt;/code&gt; for human review&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The report should say what was found, why it matters, what is missing, and what a human responder should verify next. It should not delete the suspected file, block the IP, kill the process, or restart the web service.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Open Investigator fits
&lt;/h2&gt;

&lt;p&gt;I maintain Open Investigator at Arvanta Cyber. It is an Apache-2.0 local AI server investigation CLI for Linux and Windows hosts.&lt;/p&gt;

&lt;p&gt;The WebShell use case is one of the scenarios it is designed for: start from a weak web clue, collect read-only host evidence, and produce a reviewable evidence bundle.&lt;/p&gt;

&lt;p&gt;WebShell investigation page:&lt;br&gt;
&lt;a href="https://www.arvantacyber.com/open-investigator/webshell-investigation-tool/" rel="noopener noreferrer"&gt;https://www.arvantacyber.com/open-investigator/webshell-investigation-tool/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Project overview:&lt;br&gt;
&lt;a href="https://www.arvantacyber.com/open-investigator/" rel="noopener noreferrer"&gt;https://www.arvantacyber.com/open-investigator/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub:&lt;br&gt;
&lt;a href="https://github.com/SEc-123/open-investigator" rel="noopener noreferrer"&gt;https://github.com/SEc-123/open-investigator&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you do incident response, blue-team work, web operations, or SRE on Linux servers, the design question I care about is this: what evidence would you require before trusting an AI-assisted first pass on a suspected WebShell?&lt;/p&gt;

</description>
      <category>incidentresponse</category>
      <category>security</category>
      <category>linux</category>
      <category>opensource</category>
    </item>
    <item>
      <title>What safety boundary should an AI incident investigation tool have?</title>
      <dc:creator>Qimin Zhao</dc:creator>
      <pubDate>Fri, 29 May 2026 11:01:16 +0000</pubDate>
      <link>https://dev.to/sec123/what-safety-boundary-should-an-ai-incident-investigation-tool-have-391k</link>
      <guid>https://dev.to/sec123/what-safety-boundary-should-an-ai-incident-investigation-tool-have-391k</guid>
      <description>&lt;p&gt;Disclosure: I maintain Open Investigator at Arvanta Cyber. Open Investigator is Apache-2.0 open source.&lt;/p&gt;

&lt;p&gt;AI can help incident responders move from a weak clue to a concrete evidence&lt;br&gt;
plan. It can also become dangerous quickly if it is allowed to improvise on a&lt;br&gt;
production host.&lt;/p&gt;

&lt;p&gt;Open Investigator takes a narrow position: AI should start as a local,&lt;br&gt;
read-only investigator.&lt;/p&gt;

&lt;p&gt;Repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://github.com/SEc-123/open-investigator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Relevant page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://www.arvantacyber.com/open-investigator/read-only-ai-server-investigation/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;Incident response starts under uncertainty:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a suspicious IP appears in logs&lt;/li&gt;
&lt;li&gt;a Java service looks strange&lt;/li&gt;
&lt;li&gt;a WebShell may exist&lt;/li&gt;
&lt;li&gt;root logged in at an unusual time&lt;/li&gt;
&lt;li&gt;a server "looks wrong" but nobody has a full hypothesis&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is exactly where AI planning can help. The model can decide that the next&lt;br&gt;
useful evidence is auth context, process context, recent files, web logs,&lt;br&gt;
network state, persistence, or Java process metadata.&lt;/p&gt;

&lt;p&gt;But the same uncertainty makes mutation risky. Before the team understands the&lt;br&gt;
case, the AI should not delete files, restart services, kill processes, disable&lt;br&gt;
accounts, or block IPs.&lt;/p&gt;
&lt;h2&gt;
  
  
  The boundary
&lt;/h2&gt;

&lt;p&gt;Open Investigator gives the model sealed investigation tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;oi_ioc_find
oi_auth_check
oi_acct_snap
oi_proc_snap
oi_net_snap
oi_per_snap
oi_svc_snap
oi_web_check
oi_java_check
oi_mem_check
oi_file_recent
oi_container_check
oi_hist_check
oi_linux_deep
oi_windows_deep
oi_pkg_check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In safe mode, the AI cannot call raw OS commands.&lt;/p&gt;

&lt;p&gt;In investigator mode, it can request &lt;code&gt;oi_ro_run&lt;/code&gt;, but that command path is&lt;br&gt;
filtered by a read-only policy and logged. Commands that mutate the host are&lt;br&gt;
blocked.&lt;/p&gt;
&lt;h2&gt;
  
  
  What this enables
&lt;/h2&gt;

&lt;p&gt;The model can still do useful work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;start from an IP, user, path, process, web root, Java service, or vague clue&lt;/li&gt;
&lt;li&gt;collect evidence across multiple host surfaces&lt;/li&gt;
&lt;li&gt;branch based on observations&lt;/li&gt;
&lt;li&gt;record evidence IDs and command audit entries&lt;/li&gt;
&lt;li&gt;produce &lt;code&gt;report.md&lt;/code&gt; and &lt;code&gt;report.json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;explain which evidence is missing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The point is not to replace a responder. The point is to shorten the first-pass&lt;br&gt;
evidence collection loop while keeping every action reviewable.&lt;/p&gt;
&lt;h2&gt;
  
  
  What this refuses to do
&lt;/h2&gt;

&lt;p&gt;Open Investigator does not:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;isolate hosts&lt;/li&gt;
&lt;li&gt;block IPs&lt;/li&gt;
&lt;li&gt;kill suspicious processes&lt;/li&gt;
&lt;li&gt;delete WebShells&lt;/li&gt;
&lt;li&gt;disable users&lt;/li&gt;
&lt;li&gt;restart services&lt;/li&gt;
&lt;li&gt;change firewall rules&lt;/li&gt;
&lt;li&gt;edit the registry&lt;/li&gt;
&lt;li&gt;install agents&lt;/li&gt;
&lt;li&gt;replace EDR, SIEM, or SOAR&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are response actions, not first-pass investigation actions.&lt;/p&gt;
&lt;h2&gt;
  
  
  Java memory-shell example
&lt;/h2&gt;

&lt;p&gt;Java investigations show why the boundary matters.&lt;/p&gt;

&lt;p&gt;Default Java checks are low impact:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;oi java &lt;span class="nt"&gt;-s&lt;/span&gt; 14d
oi mem &lt;span class="nt"&gt;-s&lt;/span&gt; 14d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They inspect process command lines, JVM options, &lt;code&gt;-javaagent&lt;/code&gt;, &lt;code&gt;-agentlib&lt;/code&gt;,&lt;br&gt;
JDWP, &lt;code&gt;Xbootclasspath&lt;/code&gt;, &lt;code&gt;jps&lt;/code&gt;, &lt;code&gt;jcmd VM.command_line&lt;/code&gt;, web logs, recent&lt;br&gt;
Java/web file changes, and related process or network context.&lt;/p&gt;

&lt;p&gt;Deeper JVM inspection is explicit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;oi mem &lt;span class="nt"&gt;-s&lt;/span&gt; 14d &lt;span class="nt"&gt;-m&lt;/span&gt; inv &lt;span class="nt"&gt;--java-deep&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Heavy artifacts are separate approvals:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;oi mem &lt;span class="nt"&gt;-s&lt;/span&gt; 14d &lt;span class="nt"&gt;-m&lt;/span&gt; inv &lt;span class="nt"&gt;--java-deep&lt;/span&gt; &lt;span class="nt"&gt;--heap-dump&lt;/span&gt;
oi mem &lt;span class="nt"&gt;-s&lt;/span&gt; 14d &lt;span class="nt"&gt;-m&lt;/span&gt; inv &lt;span class="nt"&gt;--java-deep&lt;/span&gt; &lt;span class="nt"&gt;--jfr-dump&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ordinary &lt;code&gt;oi sh&lt;/code&gt; and AI &lt;code&gt;oi_ro_run&lt;/code&gt; cannot bypass those gates to create heap or&lt;br&gt;
JFR dumps.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical trust checklist
&lt;/h2&gt;

&lt;p&gt;Before using any AI incident investigation tool on a real host, ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can the AI mutate the host?&lt;/li&gt;
&lt;li&gt;Can it run arbitrary shell?&lt;/li&gt;
&lt;li&gt;Are commands and denials logged?&lt;/li&gt;
&lt;li&gt;Are evidence records preserved separately from the summary?&lt;/li&gt;
&lt;li&gt;Are heavy diagnostics explicit?&lt;/li&gt;
&lt;li&gt;Does the report show evidence gaps?&lt;/li&gt;
&lt;li&gt;Can another responder reproduce or challenge the findings?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the answer is unclear, the tool is not ready for production triage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;AI incident response tooling should earn trust from the boundary inward. Start&lt;br&gt;
with local evidence collection, sealed tools, audit logs, and explicit&lt;br&gt;
non-goals. Add broader capabilities only when the team can reason about the&lt;br&gt;
risk.&lt;/p&gt;

</description>
      <category>incidentresponse</category>
      <category>security</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How to investigate a suspicious IP on a Linux server with read-only evidence</title>
      <dc:creator>Qimin Zhao</dc:creator>
      <pubDate>Fri, 29 May 2026 10:40:11 +0000</pubDate>
      <link>https://dev.to/sec123/how-to-investigate-a-suspicious-ip-on-a-linux-server-with-read-only-evidence-16eh</link>
      <guid>https://dev.to/sec123/how-to-investigate-a-suspicious-ip-on-a-linux-server-with-read-only-evidence-16eh</guid>
      <description>&lt;p&gt;Disclosure: I maintain Open Investigator at Arvanta Cyber. Open Investigator is Apache-2.0 open source.&lt;/p&gt;

&lt;p&gt;When an alert starts with only an IP address, the first response question is not&lt;br&gt;
"is the host compromised?" It is narrower:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Where did this IP appear, what changed around that time, and what evidence is
still missing?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open Investigator is built for this first-pass loop. It runs locally on the&lt;br&gt;
host, lets AI call sealed read-only investigation tools, and writes an auditable&lt;br&gt;
case folder instead of giving the model raw shell access.&lt;/p&gt;

&lt;p&gt;Repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://github.com/SEc-123/open-investigator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Relevant page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://www.arvantacyber.com/open-investigator/local-ai-incident-response/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Start with the IP
&lt;/h2&gt;

&lt;p&gt;Build the tool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/SEc-123/open-investigator.git
&lt;span class="nb"&gt;cd &lt;/span&gt;open-investigator
cargo build &lt;span class="nt"&gt;--release&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run an IP-focused investigation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./target/release/oi ip 1.2.3.4 &lt;span class="nt"&gt;-s&lt;/span&gt; 7d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This asks a practical set of questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Did the IP appear in auth logs?&lt;/li&gt;
&lt;li&gt;Did it hit web access logs?&lt;/li&gt;
&lt;li&gt;Is it connected now?&lt;/li&gt;
&lt;li&gt;Is it tied to a listening service or process?&lt;/li&gt;
&lt;li&gt;Did suspicious files, persistence entries, or account activity appear nearby?&lt;/li&gt;
&lt;li&gt;Which evidence categories were unavailable because of permissions or platform
differences?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why this should be read-only
&lt;/h2&gt;

&lt;p&gt;Early in triage, the responder often does not know whether the IP is an&lt;br&gt;
attacker, scanner, customer, proxy, admin VPN, monitoring system, or false&lt;br&gt;
positive.&lt;/p&gt;

&lt;p&gt;That is why Open Investigator keeps the default boundary narrow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no raw shell for the AI in safe mode&lt;/li&gt;
&lt;li&gt;no host isolation&lt;/li&gt;
&lt;li&gt;no IP blocking&lt;/li&gt;
&lt;li&gt;no process killing&lt;/li&gt;
&lt;li&gt;no file deletion&lt;/li&gt;
&lt;li&gt;no account disabling&lt;/li&gt;
&lt;li&gt;no firewall or registry changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The output is evidence and a report. Remediation belongs in separate,&lt;br&gt;
human-approved response systems.&lt;/p&gt;
&lt;h2&gt;
  
  
  What gets collected
&lt;/h2&gt;

&lt;p&gt;For an IP investigation, useful evidence usually spans more than one log file:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;IOC search across readable logs and text surfaces&lt;/li&gt;
&lt;li&gt;authentication events and login anomalies&lt;/li&gt;
&lt;li&gt;process and network context&lt;/li&gt;
&lt;li&gt;services and persistence entries&lt;/li&gt;
&lt;li&gt;web logs and recent web-root changes&lt;/li&gt;
&lt;li&gt;package and container context when available&lt;/li&gt;
&lt;li&gt;recent files and command history signals&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Open Investigator records observations into:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.oi/cases/&amp;lt;case-id&amp;gt;/
  case.json
  evidence.jsonl
  commands.log
  report.json
  report.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The report is not the source of truth by itself. The important property is that&lt;br&gt;
the report can point back to evidence records and command audit entries.&lt;/p&gt;
&lt;h2&gt;
  
  
  Follow-up with a natural-language question
&lt;/h2&gt;

&lt;p&gt;If the IP appears in web logs or auth logs, ask a focused follow-up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./target/release/oi ask &lt;span class="s2"&gt;"Investigate 1.2.3.4 on this host. Focus on auth logs, nginx access logs, related processes, outbound connections, recent web-root changes, and persistence over the last 7 days."&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; 7d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI investigator can branch from observations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;web hit -&amp;gt; suspicious paths -&amp;gt; recent files -&amp;gt; process context&lt;/li&gt;
&lt;li&gt;failed login burst -&amp;gt; successful login -&amp;gt; account context -&amp;gt; shell history&lt;/li&gt;
&lt;li&gt;active connection -&amp;gt; process owner -&amp;gt; service context -&amp;gt; persistence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That loop is the reason to use AI here. It can decide the next bounded evidence&lt;br&gt;
request while staying inside the read-only tool catalog.&lt;/p&gt;
&lt;h2&gt;
  
  
  What a useful result looks like
&lt;/h2&gt;

&lt;p&gt;A useful first-pass report should include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;where the IP appeared&lt;/li&gt;
&lt;li&gt;timestamps and source files where possible&lt;/li&gt;
&lt;li&gt;related users, processes, services, files, and network connections&lt;/li&gt;
&lt;li&gt;severity and confidence for findings&lt;/li&gt;
&lt;li&gt;evidence gaps and permission issues&lt;/li&gt;
&lt;li&gt;recommended manual confirmation steps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It should not pretend that one scan proves absence of compromise.&lt;/p&gt;
&lt;h2&gt;
  
  
  When to use deeper mode
&lt;/h2&gt;

&lt;p&gt;Open Investigator has an investigator mode for controlled read-only command&lt;br&gt;
fallback:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./target/release/oi ask &lt;span class="s2"&gt;"Investigate 1.2.3.4 and explain any remaining evidence gaps."&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; 7d &lt;span class="nt"&gt;-m&lt;/span&gt; inv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even then, &lt;code&gt;oi_ro_run&lt;/code&gt; is policy-filtered and audited. It blocks commands that&lt;br&gt;
delete, modify, kill, restart, install, download, upload, edit registry, change&lt;br&gt;
firewall state, change accounts, or execute interactive shells.&lt;/p&gt;

&lt;p&gt;Use this only when the team accepts the broader read-only command surface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;A suspicious IP is a starting point, not a verdict. The useful first step is to&lt;br&gt;
collect linked host evidence, preserve the audit trail, and produce a report&lt;br&gt;
another responder can challenge.&lt;/p&gt;

&lt;p&gt;Open Investigator tries to make that first step faster while keeping the AI&lt;br&gt;
inside a local, read-only investigation boundary.&lt;/p&gt;

</description>
      <category>incidentresponse</category>
      <category>linux</category>
      <category>security</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How I would use local read-only AI for first-pass server incident response</title>
      <dc:creator>Qimin Zhao</dc:creator>
      <pubDate>Fri, 29 May 2026 10:05:52 +0000</pubDate>
      <link>https://dev.to/sec123/how-i-would-use-local-read-only-ai-for-first-pass-server-incident-response-b96</link>
      <guid>https://dev.to/sec123/how-i-would-use-local-read-only-ai-for-first-pass-server-incident-response-b96</guid>
      <description>&lt;p&gt;Disclosure: I maintain Open Investigator at Arvanta Cyber.&lt;/p&gt;

&lt;p&gt;Most server incident response does not start with a clean incident narrative. It starts with a weak clue:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one suspicious IP&lt;/li&gt;
&lt;li&gt;a weird login&lt;/li&gt;
&lt;li&gt;a possible WebShell&lt;/li&gt;
&lt;li&gt;a Java service behaving strangely&lt;/li&gt;
&lt;li&gt;a host that simply "looks wrong"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The risky part is jumping from that clue straight to remediation. Before killing processes, blocking IPs, deleting files, or restarting services, I want a local, reviewable evidence package.&lt;/p&gt;

&lt;h2&gt;
  
  
  The first-pass workflow I like
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Search for the clue across local evidence
&lt;/h3&gt;

&lt;p&gt;For an IP, that means auth logs, web access logs, reverse proxy logs, application logs, current network connections, and nearby timestamps.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Expand from evidence, not guesses
&lt;/h3&gt;

&lt;p&gt;If the IP appears in web logs, look at paths, status codes, user agents, recent web-root changes, web-user processes, and outbound connections. If it appears in auth logs, look at failed and successful logins, account state, sudo activity, and shell history.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Keep the model inside a bounded tool catalog
&lt;/h3&gt;

&lt;p&gt;The AI should not get raw production-changing authority. It can ask for investigation tools, but those tools should be read-only and audited.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Write artifacts a human can review
&lt;/h3&gt;

&lt;p&gt;The output should not just be "the AI says this is compromised." I want:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;evidence.jsonl&lt;/li&gt;
&lt;li&gt;commands.log&lt;/li&gt;
&lt;li&gt;report.json&lt;/li&gt;
&lt;li&gt;report.md&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That lets another responder challenge the conclusion, inspect evidence IDs, and continue the case.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Open Investigator fits
&lt;/h2&gt;

&lt;p&gt;Open Investigator is my Apache-2.0 implementation of this pattern. It runs locally on Linux and Windows hosts, exposes sealed read-only investigation tools for auth, process, network, persistence, services, web logs, Java clues, recent files, containers, packages, and history, and then writes a case report.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;oi ip 1.2.3.4 &lt;span class="nt"&gt;-s&lt;/span&gt; 7d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or a broader first pass:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;oi scan &lt;span class="nt"&gt;-s&lt;/span&gt; 7d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The boundary is deliberate. It investigates, but it does not isolate hosts, block IPs, kill processes, delete files, disable accounts, restart services, or change firewall/registry state.&lt;/p&gt;

&lt;p&gt;Practical walkthrough:&lt;br&gt;
&lt;a href="https://www.arvantacyber.com/open-investigator/articles/local-ai-server-incident-response/" rel="noopener noreferrer"&gt;https://www.arvantacyber.com/open-investigator/articles/local-ai-server-incident-response/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open-source repo:&lt;br&gt;
&lt;a href="https://github.com/SEc-123/open-investigator" rel="noopener noreferrer"&gt;https://github.com/SEc-123/open-investigator&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Product page:&lt;br&gt;
&lt;a href="https://www.arvantacyber.com/open-investigator/" rel="noopener noreferrer"&gt;https://www.arvantacyber.com/open-investigator/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I would be interested in feedback from incident responders, Linux admins, SREs, and blue-team engineers: what evidence would you require before trusting a first-pass AI-assisted investigation report?&lt;/p&gt;

</description>
      <category>incidentresponse</category>
      <category>security</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
