From 96610ccb167c4a467faccba0e13cca6b2d0438af Mon Sep 17 00:00:00 2001 From: funman300 Date: Mon, 24 Aug 2026 16:36:56 +0000 Subject: [PATCH] tools(re): remove the port-8081 DNAT that breaks FIFA 17's roster TLS A client-local nat rule redirecting dport 8081 to the plain-HTTP staging UTAS host captures the roster/squad-update TLS connection, which is https://winter15.gosredirector.ea.com:8081/fifa17/fut/rosterupdate.xml. The staging host completes the TCP handshake then closes on the ClientHello, so the client retries and shows "An error occurred downloading the FUT squad update." Proven by capturing on the server while probing from the client: a connection addressed to :8081 arrives as dport 8299, while an :8443 control in the same capture yields 75 packets and a clean handshake. The script deletes only nat rules whose destination port is 8299, then verifies the endpoint presents CN = winter15.gosredirector.ea.com. --- fifa17-recon/tools/live/fix-roster-dnat.sh | 58 ++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100755 fifa17-recon/tools/live/fix-roster-dnat.sh diff --git a/fifa17-recon/tools/live/fix-roster-dnat.sh b/fifa17-recon/tools/live/fix-roster-dnat.sh new file mode 100755 index 0000000..9b80cd5 --- /dev/null +++ b/fifa17-recon/tools/live/fix-roster-dnat.sh @@ -0,0 +1,58 @@ +#!/bin/sh +# Remove the port-8081 DNAT rule that hijacks FIFA 17's roster/squad-update TLS. +# +# Why: the FUT squad update is https://winter15.gosredirector.ea.com:8081/fifa17/fut/rosterupdate.xml +# (TLS on port 8081). A DNAT rule rewriting dport 8081 -> 8299 sends that TLS +# handshake to the plain-HTTP staging UTAS host, which closes the connection. +# Proven: a probe to 10.10.0.120:8081 from this box arrives at the server as +# dport 8299. Result: "An error occurred downloading the FUT squad update." +# +# The rule also never redirected UTAS, which lives on :8443, not :8081. +# +# Read-only until it deletes; deletes only nat rules whose target port is 8299. +set -u + +echo "== nat OUTPUT rules mentioning 8081 or 8299 ==" +iptables -t nat -S OUTPUT 2>/dev/null | grep -E '8081|8299' || echo " (none)" + +echo +echo "== deleting DNAT rules that redirect to port 8299 ==" +removed=0 +# Delete by spec, repeatedly, until no matching rule remains. +while :; do + rule=$(iptables -t nat -S OUTPUT 2>/dev/null | grep -m1 -E '\-\-dport 8081 .*8299|to-destination [0-9.]+:8299') + [ -z "$rule" ] && break + spec=$(printf '%s' "$rule" | sed 's/^-A /-D /') + # shellcheck disable=SC2086 + if iptables -t nat $spec 2>/dev/null; then + echo " removed: $rule" + removed=$((removed + 1)) + else + echo " FAILED to remove: $rule" >&2 + break + fi +done +[ "$removed" -eq 0 ] && echo " (no matching rule found)" + +echo +echo "== remaining nat OUTPUT rules mentioning 8081 or 8299 ==" +iptables -t nat -S OUTPUT 2>/dev/null | grep -E '8081|8299' || echo " (none)" + +echo +echo "== verifying the roster endpoint now presents the correct certificate ==" +python3 - <<'PY' +import socket, ssl +host, port, sni = "10.10.0.120", 8081, "winter15.gosredirector.ea.com" +try: + ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + ctx.check_hostname = False + ctx.verify_mode = ssl.CERT_NONE + with socket.create_connection((host, port), 8) as s: + with ctx.wrap_socket(s, server_hostname=sni) as t: + der = t.getpeercert(True) + cn = dict(x[0] for x in t.getpeercert().get("subject", ())) + print(f" PASS {host}:{port} sni={sni} {t.version()} der={len(der)}B subject={cn}") +except Exception as e: + print(f" FAIL {host}:{port} sni={sni} -> {type(e).__name__}: {e}") + print(" The roster path is still broken; do not relaunch yet.") +PY