> ## Content Index
> Fetch the complete content index at: https://f4n6.co.uk/llms.txt
> Use this file to discover other available public pages before exploring further.

# Obfuscating IP Addresses as Hostnames, (Tue, Aug 25th)
- URL: https://f4n6.co.uk/security-feed/obfuscating-ip-addresses-as-hostnames-tue-aug-25th/
- Published: 2026-08-25T21:45:08.000Z
- Updated: 2026-08-25T21:45:08.000Z
- Author: Jeff Davies
- Tags: #security-feed

## 1\. Executive summary

SANS ISC reports SSRF scanning in which attacker-supplied hostnames resolve to the link-local cloud metadata address `169.254.169.254`, bypassing controls that inspect only literal IP strings. Reported hostnames used `nip.io`, `sslip.io` and `1u.ms`; the latter can change DNS answers after a configured time or number of lookups. A related GitHub advisory demonstrates the same control failure in `praisonaiagents <= 1.6.52`, where LLM-callable web tools can retrieve an internal service through `127.0.0.1.nip.io`. EMEA financial institutions are exposed where applications or agents fetch untrusted URLs while retaining network access to metadata or internal services; the supplied material confirms an internal-response proof of concept, not victim compromise or data theft. No verified CVSS score, severity or CISA KEV exploitation state was resolved for this item, and the observed hostname set is single-sourced and unattributed.

## 2\. Regulatory framing

No specific DORA/NIS2 article is directly engaged by this item.

## 3\. Technical analysis & attack chain

### Confirmed attack chain

1. **Attacker-controlled URL reaches a server-side fetcher.** SANS reports attacker use of hostnames such as `169.254.169.254.nip.io` and `169-254-169-254.sslip.io` in SSRF scanning. Separately, the GitHub advisory confirms that `scrape_page("http://127.0.0.1.nip.io:PORT/secret")` reaches a local service in affected PraisonAI Agents deployments.
2. **Literal-only validation accepts the hostname.** In `praisonaiagents/tools/spider_tools.py`, `_host_is_blocked()` lowercases the hostname, removes a trailing dot and rejects selected literals and suffixes:
- `localhost`, `0.0.0.0`, `::1`
- `169.254.169.254`, `metadata.google.internal`
- `.local`, `.internal`, `.localdomain`

It then tries `ipaddress.ip_address(host)` and `socket.inet_aton(host)`. A real hostname such as `127.0.0.1.nip.io` is not an IP literal, so both parsing paths fail and the function returns `False`, meaning “not blocked.”

1. **DNS converts the accepted hostname into a prohibited destination.** Wildcard DNS resolves the PraisonAI proof-of-concept hostname to `127.0.0.1`. The SANS examples resolve to or are intended to transition to `169.254.169.254`. SANS states that `1u.ms` can change answers after a configured number of lookups or elapsed time and can support custom domains and alternative IP encodings.
2. **The server initiates the internal request.** The URL-fetching process connects using the DNS result rather than the hostname value previously evaluated by the filter. In PraisonAI Agents, `scrape_page`, `extract_links`, `crawl` and `extract_text` are registered as LLM-callable tools in `praisonaiagents/tools/__init__.py`, making the path reachable when an agent is instructed to fetch an attacker-controlled URL.
3. **An internal response can be returned to the caller.** The GitHub advisory reports a live proof of concept in which `scrape_page()` returns the response from a loopback service. SANS reports scanning directed at the cloud metadata service, but provides no evidence that metadata, credentials or other data were successfully obtained from a victim.

### Affected implementation

The supplied GitHub advisory identifies `praisonaiagents <= 1.6.52` on Python 3.x. Its filter-only test produces:

```text
_host_is_blocked("127.0.0.1.nip.io")                   -> False
SpiderTools()._validate_url("http://127.0.0.1.nip.io/") -> True
_host_is_blocked("127.0.0.1")                          -> True

```

A prior fix, commit `004dcfef` for `GHSA-q9pw-vmhh-384g`, addressed IP-literal encodings such as hexadecimal, octal and backslash forms. According to the advisory, DNS-resolution checks added to `web_crawl_tools.py` were not ported to `spider_tools.py`.

The contrasting implementation in `web_crawl_tools.py` calls `socket.gethostbyname(hostname)`, classifies the result with `ipaddress.ip_address()` and rejects loopback, private, link-local and multicast addresses. It also fails closed on `socket.gaierror`, unless `ALLOW_LOCAL_CRAWL` is set to `true`.

No evidence connects the PraisonAI vulnerability to the scanning reported by SANS; the two sources corroborate the underlying hostname-to-IP validation failure, not a common campaign.

### Capability and impact boundaries

| Area                 | Finding                                                                                                          |
| -------------------- | ---------------------------------------------------------------------------------------------------------------- |
| Initial vector       | Attacker-controlled URL supplied to a server-side URL fetcher or LLM-callable browsing tool                      |
| Exploited component  | Generic literal-only SSRF filters; specifically spider\_tools.\_host\_is\_blocked() in praisonaiagents <= 1.6.52 |
| Authentication       | Not specified                                                                                                    |
| Malware/payload      | None reported                                                                                                    |
| Persistence          | None reported                                                                                                    |
| Privilege escalation | None reported                                                                                                    |
| Command-and-control  | None reported                                                                                                    |
| Lateral movement     | No confirmed activity; internal HTTP access is possible where routing permits                                    |
| Data access          | Internal service response returned in the PraisonAI proof of concept; metadata extraction not confirmed          |
| Observed impact      | Scanning and control bypass; no identified victim impact supplied                                                |
| Attribution          | No actor named; attribution is unconfirmed                                                                       |
| Reference status     | No verified CVSS score, severity or CISA KEV exploitation state is available                                     |

The exact scanning observations and `1u.ms` capabilities are single-sourced to [SANS ISC](https://isc.sans.edu/diary/rss/33280?ref=f4n6.co.uk). The PraisonAI exploit result is single-sourced to the [GitHub advisory](https://github.com/advisories/GHSA-x44h-65qv-cw74?ref=f4n6.co.uk); verify before enforcement.

## 4\. Mitigation & containment

### P1 — within 24 hours

1. **Identify exposed PraisonAI deployments.** Check every relevant Python environment:

`bash python -m pip show praisonaiagents`

Treat versions `<= 1.6.52` as affected based on the supplied advisory.

1. **Disable the vulnerable fetch path.** Remove or disable `scrape_page`, `extract_links`, `crawl` and `extract_text` for agents that can receive untrusted prompts or URLs. Do not rely on system prompts to prevent hostile URL submission.
2. **Restrict server-side egress.** Deny affected workloads direct access to `169.254.169.254`, loopback services and unnecessary private address ranges at the host, workload, proxy or network layer. Controls must apply to the resolved destination, not only the URL text.
3. **Deploy temporary DNS/proxy controls for the §5 hostnames.** Treat these as compensating controls only: `1u.ms` supports custom domains, and equivalent wildcard DNS services can evade domain-specific blocks.
4. **Hunt DNS and URL-fetch telemetry.** Search for the reported hostnames, queries whose answers contained `169.254.169.254`, and subsequent requests from application or agent workloads. SANS states that the last 100 requests received by `1u.ms` are exposed at `http://1u.ms/last`; use this only as supplementary evidence because the available history is limited.

### P2 — within 72 hours

1. **Correct `spider_tools.py`.** Port equivalent resolution and address-classification logic from `web_crawl_tools.py` into `_host_is_blocked()`. At minimum:
- Resolve hostnames before allowing a request.
- Reject loopback, private, link-local and multicast results.
- Fail closed when DNS resolution fails.
- Ensure `ALLOW_LOCAL_CRAWL` is not `true` in workloads processing untrusted URLs.
1. **Close the DNS-rebinding gap.** Because DNS answers can change between validation and connection, validate the address actually used for the connection or bind the connection to a previously validated result. Revalidate each new hostname encountered by the fetch workflow.
2. **Do not claim upgrade remediation without confirmation.** The supplied material identifies affected versions through `1.6.52` but does not state a fixed release. Obtain a supplier-confirmed unaffected version before re-enabling the tools.

### P3 — within seven days

1. Add regression tests requiring these values to be rejected:

`text 127.0.0.1.nip.io 169.254.169.254.nip.io 169-254-169-254.sslip.io make-1.1.1.1-rebind-169.254.169.254-rr.1u.ms`

1. Test both static wildcard DNS and answers that change between lookups. Confirm that direct IP literals and DNS aliases receive identical address-class enforcement.
2. Retain DNS, proxy and application fetch logs with sufficient correlation to connect the submitted URL, DNS answer, destination and returned response.
3. Where telemetry confirms successful metadata or internal-service retrieval, identify exactly what was returned and rotate only credentials or secrets shown to have been exposed.

## 5\. Indicators of compromise

The following are SANS-reported probe hostnames. They use legitimate dual-use DNS services and are single-sourced; verify before enforcement.

| type   | value                                                                        | confidence                                | source                                                          |
| ------ | ---------------------------------------------------------------------------- | ----------------------------------------- | --------------------------------------------------------------- |
| domain | 169\[.\]254\[.\]169\[.\]254\[.\]nip\[.\]io                                   | Medium — single-sourced, dual use         | [SANS ISC](https://isc.sans.edu/diary/rss/33280?ref=f4n6.co.uk) |
| domain | 169-254-169-254\[.\]sslip\[.\]io                                             | Medium — single-sourced, dual use         | [SANS ISC](https://isc.sans.edu/diary/rss/33280?ref=f4n6.co.uk) |
| domain | test\[.\]169\[.\]254\[.\]169\[.\]254\[.\]nip\[.\]io                          | Medium — single-sourced example, dual use | [SANS ISC](https://isc.sans.edu/diary/rss/33280?ref=f4n6.co.uk) |
| domain | make-1\[.\]1\[.\]1\[.\]1-rebind-169\[.\]254\[.\]169\[.\]254-rr\[.\]1u\[.\]ms | Medium — single-sourced, dual use         | [SANS ISC](https://isc.sans.edu/diary/rss/33280?ref=f4n6.co.uk) |

```iocs
domain  169[.]254[.]169[.]254[.]nip[.]io
domain  169-254-169-254[.]sslip[.]io
domain  test[.]169[.]254[.]169[.]254[.]nip[.]io
domain  make-1[.]1[.]1[.]1-rebind-169[.]254[.]169[.]254-rr[.]1u[.]ms

```

`127[.]0[.]0[.]1[.]nip[.]io` is excluded from the IOC block because the supplied material identifies it as a proof-of-concept value rather than an observed compromise indicator.

### Behavioural indicators

| behaviour                                                                                       | where to observe                                       | confidence                                                   |
| ----------------------------------------------------------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------ |
| Application or agent DNS query returns 169.254.169.254 for a non-literal hostname               | Recursive resolver, endpoint DNS or workload telemetry | High for the mechanism; context required                     |
| URL-fetch tool connects to loopback or an internal address after accepting a public hostname    | Application, proxy, firewall and flow logs             | High for the PraisonAI proof of concept; single-sourced      |
| Repeated resolution of an 1u.ms hostname produces changing answers before a server-side request | DNS and application correlation                        | Low as an intrusion indicator; reported tool capability only |

## 6\. Detection

Apply the YARA rule to captured request, prompt or proxy-log content. Scanning general document repositories will also match reporting that reproduces the hostnames.

```yara
rule AT_2026_08_25_SSRF_Hostname_Obfuscation
{
    meta:
        author = "Adverse Trace"
        date = "2026-08-25"
        reference = "https://isc.sans.edu/diary/rss/33280"
        description = "Detects SANS-reported hostnames used to bypass literal-IP SSRF controls"

    strings:
        $host1 = "169.254.169.254.nip.io" ascii nocase
        $host2 = "169-254-169-254.sslip.io" ascii nocase
        $host3 = "test.169.254.169.254.nip.io" ascii nocase
        $host4 = "make-1.1.1.1-rebind-169.254.169.254-rr.1u.ms" ascii nocase

    condition:
        any of ($host*)
}

```

Map `query` and `answer` to the equivalent fields in the deployed DNS schema.

```yaml
title: SSRF Hostname Resolution to Cloud Metadata Address
status: experimental
description: Detects reported SSRF hostnames or DNS answers containing the cloud metadata address.
author: Adverse Trace
date: 2026-08-25
references:

  - https://isc.sans.edu/diary/rss/33280
logsource:
  category: dns
detection:
  selection_query:
    query|endswith:

      - '169.254.169.254.nip.io'
      - '169-254-169-254.sslip.io'
      - 'make-1.1.1.1-rebind-169.254.169.254-rr.1u.ms'
  selection_answer:
    answer|contains: '169.254.169.254'
  condition: selection_query or selection_answer
falsepositives:

  - Authorised SSRF testing using nip.io, sslip.io or 1u.ms
level: medium

```

## 7\. Sources

- SANS Internet Storm Center, “Obfuscating IP Addresses as Hostnames,” 2026-08-25: https://isc.sans.edu/diary/rss/33280
- GitHub Security Advisories, “praisonaiagents has an SSRF protection bypass in `spider_tools._host_is_blocked()` via DNS-resolved hostnames,” date not stated in supplied material: https://github.com/advisories/GHSA-x44h-65qv-cw74

## 8\. Adverse Trace position

Adverse Trace leaves this item unscored because no verified CVSS score, severity or CISA KEV exploitation state was resolved. The control failure is actionable for clients exposing server-side URL fetchers or LLM agents to untrusted input, particularly where those workloads can reach metadata or internal services; however, the supplied evidence establishes scanning and a separate product proof of concept, not a confirmed client compromise. No actor is named, so attribution is unconfirmed. The reported hostname set and tooling claims are single-sourced; verify before enforcement. Adverse Trace will monitor for independent campaign corroboration and a supplier-confirmed fixed PraisonAI Agents release.

---

[Read the original source →](https://isc.sans.edu/diary/rss/33280?ref=f4n6.co.uk)

*Published via PulseTrace — Adverse Trace threat intelligence.*