Threat Overview
JPCERT/CC published alert JPCERT-AT-2026-0030 on 8 October 2026 and expanded it on 9 October following multiple recent unauthorized-access incidents and personal-data leaks in Japan. It describes **separate observed attack patterns, not one proven common campaign**: probing known vulnerabilities and exposed backup/configuration files; misuse of mobile and internal APIs to create accounts, change privileges, test malformed tokens and use stolen API keys; exploitation of Metabase CVE-2026-72898 (a previously disclosed, confirmed exploited SQL injection); and newly added reports of WAR archives containing JSP command-execution webshells on application servers accessible through public web servers. JPCERT published historical source IPs and User-Agent strings but warned that the IPs may now serve legitimate traffic. The Metabase vulnerability itself dates to August, but the October 9 advisory adds fresh observed indicators and the WAR/JSP case. The hunt combines behavior with dated indicators and does not equate every hit to compromise.
References
- JPCERT/CC Alert JPCERT-AT-2026-0030 — 2026-10-08; updated 2026-10-09
- JPCERT/CC Metabase CVE-2026-72898 advisory — 2026-08-14
- Metabase security update — 2026-08-06
- The Hacker News — Japan API abuse and Metabase attacks — 2026-10-08
Impacted Systems
- Generic API abuse: Internet-accessible consumer/mobile API backends, employee/admin APIs and business-intelligence or management applications; no single affected vendor, operating system, version or fixed build was identified for the generic incidents.
- Metabase self-hosted (including public-facing BI application/API role): CVE-2026-72898 affects branches x.63 before x.63.5, x.62 before x.62.9, x.61 before x.61.11, x.60 before x.60.17, x.59 before x.59.21, and x.58 before x.58.24. Versions before the 58 branch are stated by Metabase to be unaffected. Metabase Cloud was already remediated by the vendor.
- Metabase exposure: unauthenticated HTTP requests to `/api/session/reset_password`; confirmed attack sequence includes POST to that endpoint (400) followed by GET `/api/user/current` (200). An Internet-exposed endpoint materially increases risk. Fixed versions are the listed branch thresholds or newer vendor releases.
- WAR/JSP webshell case: a publicly reachable web server can reach a Java application server accepting or loading `.war` deployments; specific Java application product, version, deployment path, OS and exploit vector were not confirmed. This is an observed post-compromise artifact, not a disclosed product-specific CVE.
- Historical source IPs and user agents are supporting pivots only; do not treat them as exclusive or currently malicious.
Why this matters
JPCERT reports real data-loss incidents spanning mobile APIs, BI platforms and Java application servers. The shared risk is poorly protected Internet-reachable application functionality rather than a single product.
Exploitation Status
Confirmed: JPCERT incident reports of unauthorized API activity, Metabase exploitation, and WAR/JSP webshell placement; Metabase independently confirmed exploitation of CVE-2026-72898. JPCERT caveat: cases are fragmentary and need not share a single actor or exploit chain. Historical IP associations do not prove current malicious use.
What this hunt looks for
Prepared Sentinel hunts for the confirmed Metabase endpoint sequence, reported source addresses/User-Agent, unusual API access and enumeration, WAR/JSP file creation, Java-to-shell execution, Linux deployment messages, and post-compromise Java egress. No customer workspace was queried.
Required logs
Microsoft Sentinel tables, where ingested: AzureDiagnostics, CommonSecurityLog, DeviceFileEvents, DeviceNetworkEvents, DeviceProcessEvents, Syslog. Query results depend on appropriate collection, schema and retention.
1. First pass — Metabase exploit-sequence HTTP requests
AzureDiagnostics
| where TimeGenerated >= ago(30d)
| extend URI=tostring(column_ifexists("requestUri_s","")), ClientIP=tostring(column_ifexists("clientIP_s","")), Method=tostring(column_ifexists("httpMethod_s",column_ifexists("requestMethod_s",""))), Status=tostring(column_ifexists("httpStatus_d",""))
| where URI contains "/api/session/reset_password" or URI contains "/api/user/current"
| summarize Reset400=countif(URI contains "/api/session/reset_password" and Method =~ "POST" and Status == "400"), Current200=countif(URI contains "/api/user/current" and Method =~ "GET" and Status == "200"), Examples=make_set(strcat(Method," ",URI," ",Status),8) by Resource, ClientIP, bin(TimeGenerated,1h)
| where Reset400 > 0 and Current200 > 0
| order by Reset400 desc
2. Metabase endpoint access where HTTP status is unavailable
CommonSecurityLog
| where TimeGenerated >= ago(30d)
| extend URI=tostring(column_ifexists("RequestURL",""))
| where URI contains "/api/session/reset_password" or URI contains "/api/user/current"
| summarize ResetRequests=countif(URI contains "/api/session/reset_password"), CurrentRequests=countif(URI contains "/api/user/current"), SampleURLs=make_set(URI,5) by SourceIP, DestinationIP, bin(TimeGenerated,1h)
| where ResetRequests > 0 and CurrentRequests > 0
| order by ResetRequests desc
3. JPCERT reported historical source IPs in perimeter telemetry
let HistoricalIPs=dynamic(["20.210.128.125","3.112.252.14","54.95.112.6","69.10.51.162","172.86.91.7","210.149.87.120","31.76.91.2","136.117.40.140","136.85.58.5","141.11.187.186","207.241.172.54","213.163.202.171","221.216.140.49","221.216.140.129","124.133.237.18"]);
CommonSecurityLog
| where TimeGenerated >= ago(30d)
| where SourceIP in (HistoricalIPs)
| project TimeGenerated, SourceIP, DestinationIP, DestinationPort, RequestURL, DeviceAction, DeviceVendor, DeviceProduct
| order by TimeGenerated desc
4. API endpoint probing, privilege and account-management activity
AzureDiagnostics
| where TimeGenerated >= ago(14d)
| extend URI=tostring(column_ifexists("requestUri_s","")), ClientIP=tostring(column_ifexists("clientIP_s","")), Status=tostring(column_ifexists("httpStatus_d",""))
| where URI contains "/api/" and (URI has_any ("admin","user","role","permission","token","account") or URI contains "reset_password")
| summarize Requests=count(), Paths=dcount(URI), Failures=countif(Status startswith "4" or Status startswith "5"), Examples=make_set(URI,8) by Resource, ClientIP, bin(TimeGenerated,30m)
| where Requests >= 40 and (Paths >= 5 or Failures >= 20)
| order by Requests desc
5. Repeated API requests and endpoint diversity from one source
CommonSecurityLog
| where TimeGenerated >= ago(14d)
| extend URI=tostring(column_ifexists("RequestURL",""))
| where URI contains "/api/"
| summarize Requests=count(), Paths=dcount(URI), Targets=dcount(DestinationIP), Samples=make_set(URI,8) by SourceIP, bin(TimeGenerated,15m)
| where Requests >= 100 and (Paths >= 10 or Targets >= 3)
| order by Requests desc
6. Unexpected WAR/JSP artifacts on Java application hosts
DeviceFileEvents
| where TimeGenerated >= ago(30d)
| where FileName endswith ".war" or FileName endswith ".jsp"
| where FolderPath has_any ("webapps","tomcat","deploy","www","tmp") or InitiatingProcessFileName in~ ("java","java.exe","tomcat","bash","sh")
| project TimeGenerated, DeviceName, ActionType, FileName, FolderPath, InitiatingProcessFileName, InitiatingProcessCommandLine, SHA256
| order by TimeGenerated desc
7. Java or Tomcat spawning shells and network utilities
DeviceProcessEvents
| where TimeGenerated >= ago(30d)
| where InitiatingProcessFileName in~ ("java","java.exe","tomcat","catalina.sh")
| where FileName in~ ("sh","bash","dash","cmd.exe","powershell.exe","curl","wget","python","python3","nc","ncat")
| project TimeGenerated, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine, FolderPath
| order by TimeGenerated desc
8. Linux Syslog webshell deployment and WAR/JSP messages
Syslog
| where TimeGenerated >= ago(30d)
| where SyslogMessage has_any (".war",".jsp","webshell","web shell")
| where SyslogMessage has_any ("tomcat","deploy","java","webapps","uploaded","manager","shell")
| project TimeGenerated, Computer, ProcessName, SeverityLevel, SyslogMessage
| order by TimeGenerated desc
9. Metabase-specific User-Agent and reported historical sources
CommonSecurityLog
| where TimeGenerated >= ago(30d)
| extend UA=strcat(tostring(column_ifexists("RequestClientApplication",""))," ",tostring(column_ifexists("DeviceCustomString1","")))
| where UA contains "Metabase-GHSA-vwf4/2.0" or (SourceIP in ("213.163.202.171","221.216.140.49","221.216.140.129") and RequestURL contains "/api/")
| project TimeGenerated, SourceIP, DestinationIP, DestinationPort, RequestURL, UA, DeviceAction
| order by TimeGenerated desc
10. New outbound destinations initiated by Java server processes
let Seen=DeviceNetworkEvents
| where TimeGenerated between (ago(30d) .. ago(3d))
| where InitiatingProcessFileName in~ ("java","java.exe") and isnotempty(RemoteIP)
| summarize by DeviceId, RemoteIP;
DeviceNetworkEvents
| where TimeGenerated >= ago(3d)
| where InitiatingProcessFileName in~ ("java","java.exe") and isnotempty(RemoteIP)
| join kind=leftanti Seen on DeviceId, RemoteIP
| project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, RemoteIP, RemoteUrl, RemotePort, ActionType
| order by TimeGenerated desc
Detection Notes
- Highest signal: POST `/api/session/reset_password` with 400 followed by GET `/api/user/current` with 200 from the same source to the same Metabase service; an unexpected WAR containing JSP command execution or Java spawning shells is also high signal.
- HTTP request method, URI, status, and client IP require WAF/access logs with those fields populated. `CommonSecurityLog` typically lacks HTTP status and may omit URL; the corresponding query is a weaker pivot.
- The IPs in the JPCERT advisory were observed in August–October and may now have legitimate use. Do not auto-block solely on these indicators. The User-Agent strings `curl` and `python-requests` are common.
- A `.war` file or `java` spawning a shell can be normal during CI/CD, administrative scripts, and Tomcat maintenance; correlate with deployment accounts, paths and access logs.
- Metabase affected-version information is vendor-confirmed for CVE-2026-72898. Do not extrapolate those versions to the generic API or WAR/JSP cases.