From 0b666625257154a6db256e30b710ba94eb78681b Mon Sep 17 00:00:00 2001 From: funman300 Date: Tue, 11 Aug 2026 18:33:59 +0000 Subject: [PATCH] utas: first real corpus, and two sanitiser gaps the audit caught 24 transactions across 11 connections from a retail session: login, hub, one pack open, two squad saves, a quick-sell, with before/after state manifests. Raw .ofcap stays gitignored at 0600; the sanitized corpus is committed as adapter fixtures. TWO GAPS FOUND BY AUDITING THE OUTPUT, NOT BY TRUSTING THE SANITISER. 1. `POST /ut/auth` carries `macAddress` and `deviceId`. Session tokens were being redacted correctly and these were not. A committed fixture is a published fixture. 2. Then, with those fixed, the audit fired AGAIN on the file about to be committed: `GET .../phishing/trusteddevice?deviceId=...` puts the id in the QUERY STRING. Three input surfaces carry identifiers -- headers, JSON bodies, and query strings -- and the sanitiser knew about two. Both fixed in the tool rather than by editing the file, with a regression test and a mutation for the query path. AND A THIRD ARTEFACT MIX-UP, in the mutation harness itself. It reported the query-redaction mutation as SURVIVED while a hand-run of the same mutation killed it. Cause: the harness pointed at a stale scratchpad copy of the test that pre-dated the query assertion, so it was faithfully testing the mutated tool against a test that could not detect the mutation. That is the same class as the build guard checking the wrong binary and cargo reusing a binary compiled from mutated source -- the third instance today of measuring the wrong artifact. The harness now resolves ROOT from its own location and runs the COMMITTED test; the stale copy is deleted. Harness committed as scripts/mutate-utas-observe.py so this is repeatable rather than a thing that happened once in a scratch directory. 6/6 killed. Co-Authored-By: Claude Opus 5 --- .../fixtures/utas/session-001.jsonl | 24 +++ .../fixtures/utas/state-after.json | 84 +++++++++ .../fixtures/utas/state-before.json | 84 +++++++++ scripts/mutate-utas-observe.py | 75 ++++++++ scripts/openfut-utas-observe.py | 174 +++++++++++++----- scripts/test-utas-observe.py | 14 +- 6 files changed, 405 insertions(+), 50 deletions(-) create mode 100644 openfut-adapter-fifa17/fixtures/utas/session-001.jsonl create mode 100644 openfut-adapter-fifa17/fixtures/utas/state-after.json create mode 100644 openfut-adapter-fifa17/fixtures/utas/state-before.json create mode 100755 scripts/mutate-utas-observe.py diff --git a/openfut-adapter-fifa17/fixtures/utas/session-001.jsonl b/openfut-adapter-fifa17/fixtures/utas/session-001.jsonl new file mode 100644 index 0000000..9c85f25 --- /dev/null +++ b/openfut-adapter-fifa17/fixtures/utas/session-001.jsonl @@ -0,0 +1,24 @@ +{"conn": 1, "connection": {"keepalive_observed": false, "requests_on_this_connection": 1}, "elapsed_ms": 33.177, "request": {"body_b64": "eyJwZXJzb25hSWQiOjMzMDY4MTc5LCJwZXJzb25hTmFtZSI6IkNBR0UiLCJsZXZlbCI6MSwiZXhwZXJpZW5jZSI6MCwiZXhwZXJpZW5jZU1heCI6MTAwMCwiYWNjb3VudEZ1bmRzIjowLCJhY2NvdW50RnVuZHNDYXAiOjEwMDAwMH0=", "body_len": 131, "headers": [["Host", "10.10.0.120:8099"], ["Content-Type", "application/json"], ["Content-Length", "131"], ["Connection", "close"]], "method": "POST", "path": "/openfut/account/sync", "query": "", "version": "HTTP/1.1"}, "response": {"body_b64": "eyJhY2NvdW50IjogeyJwZXJzb25hSWQiOiAzMzA2ODE3OSwgInBlcnNvbmFOYW1lIjogIkNBR0UiLCAiY2x1Yk5hbWUiOiAiT3BlbkZVVCIsICJjbHViQWJiciI6ICJPRkMiLCAibGV2ZWwiOiAxLCAiZXhwZXJpZW5jZSI6IDAsICJleHBlcmllbmNlTWF4IjogMTAwMCwgImFjY291bnRGdW5kcyI6IDAsICJhY2NvdW50RnVuZHNDYXAiOiAxMDAwMDAsICJwcm9maWxlUGF0aCI6ICJhY2NvdW50cy8zMzA2ODE3OS9maWZhMTdfcHJvZmlsZS5qc29uIiwgImNvaW5zIjogMjgwMjA2NTYsICJ1bm9wZW5lZFBhY2tzIjogMH0sICJzdGF0dXMiOiAiT0sifQ==", "body_len": 310, "headers": [["Server", "BaseHTTP/0.6 Python/3.12.13"], ["Date", "Tue, 11 Aug 2026 18:17:25 GMT"], ["Content-Type", "application/json"], ["Content-Length", "310"]], "status": 200, "status_line": "HTTP/1.1 200 OK"}, "seq": 1, "t_request": 49.859722, "t_response": 49.892899, "unix_request": 1786472245.6425924} +{"conn": 2, "connection": {"keepalive_observed": false, "requests_on_this_connection": 1}, "elapsed_ms": 0.837, "redacted": ["request.Easw-Session-Data-Nucleus-Id"], "request": {"body_b64": "", "body_len": 0, "headers": [["Host", "10.10.0.120:8099"], ["Connection", "Close"], ["User-Agent", "ProtoHttp 1.3/DS 15.1.2.1.0 (Windows)"], ["Accept", "application/json"], ["Content-Type", "application/json"], ["Accept-Encoding", "gzip"], ["Easw-Session-Data-Nucleus-Id", ""], ["Accept-Encoding", "gzip"]], "method": "GET", "path": "/ut/game/fifa17/user/accountinfo", "query": "", "version": "HTTP/1.1"}, "response": {"body_b64": "e30=", "body_len": 2, "headers": [["Server", "BaseHTTP/0.6 Python/3.12.13"], ["Date", "Tue, 11 Aug 2026 18:17:47 GMT"], ["Content-Type", "application/json"], ["Content-Length", "2"]], "status": 200, "status_line": "HTTP/1.1 200 OK"}, "seq": 1, "t_request": 71.24207, "t_response": 71.242907, "unix_request": 1786472267.0249455} +{"conn": 3, "connection": {"keepalive_observed": false, "requests_on_this_connection": 1}, "elapsed_ms": 1.086, "redacted": ["request.body.authCode", "request.body.deviceId", "request.body.macAddress", "response.body.sid"], "request": {"body_b64": "eyJjbGllbnRWZXJzaW9uIjogMywgImRldmljZUlkIjogIjxSRURBQ1RFRD4iLCAiaWRlbnRpZmljYXRpb24iOiB7ImF1dGhDb2RlIjogIjxSRURBQ1RFRD4ifSwgImlzUmVhZE9ubHkiOiBmYWxzZSwgImxvY2FsZSI6ICJlbi1VUyIsICJtYWNBZGRyZXNzIjogIjxSRURBQ1RFRD4iLCAibWV0aG9kIjogImF1dGhjb2RlIiwgIm51YyI6IDMzMDY4MTc5LCAibnVjbGV1c1BlcnNvbmFEaXNwbGF5TmFtZSI6ICJDQUdFIiwgIm51Y2xldXNQZXJzb25hSWQiOiAzMzA2ODE3OSwgIm51Y2xldXNQZXJzb25hUGxhdGZvcm0iOiAicGMiLCAicHJpb3JpdHlMZXZlbCI6IDYsICJyZWdpb25Db2RlIjogIlVTIiwgInNrdSI6ICJGRkExN1BDQyJ9", "body_len": 380, "body_len_original": 380, "headers": [["Host", "10.10.0.120:8099"], ["Content-Length", "380"], ["Connection", "Close"], ["User-Agent", "ProtoHttp 1.3/DS 15.1.2.1.0 (Windows)"], ["Accept", "application/json"], ["Content-Type", "application/json"], ["Hash", "a1578680859e872fa65f1e0c67274b4a3239af524d8f11acec6b30e74bb22ca4"]], "method": "POST", "path": "/ut/auth", "query": "", "version": "HTTP/1.1"}, "response": {"body_b64": "eyJsYXN0T25saW5lVGltZSI6ICIyMDI2LTA4LTExIDE4OjE4OjAyIiwgInByb3RvY29sIjogMSwgInNlcnZlclRpbWUiOiAiMjAyNi0wOC0xMSAxODoxODowMiIsICJzaWQiOiAiPFJFREFDVEVEPiJ9", "body_len": 132, "body_len_original": 132, "headers": [["Server", "BaseHTTP/0.6 Python/3.12.13"], ["Date", "Tue, 11 Aug 2026 18:18:02 GMT"], ["Content-Type", "application/json"], ["Content-Length", "132"]], "status": 200, "status_line": "HTTP/1.1 200 OK"}, "seq": 1, "t_request": 86.646358, "t_response": 86.647444, "unix_request": 1786472282.4292276} +{"conn": 4, "connection": {"keepalive_observed": true, "requests_on_this_connection": 2}, "elapsed_ms": 0.832, "redacted": ["request.X-UT-SID"], "request": {"body_b64": "", "body_len": 0, "headers": [["Host", "10.10.0.120:8099"], ["User-Agent", "ProtoHttp 1.3/DS 15.1.2.1.0 (Windows)"], ["Accept", "application/json"], ["Content-Type", "application/json"], ["X-UT-SID", ""], ["Accept-Encoding", "gzip"]], "method": "GET", "path": "/ut/game/fifa17/settings", "query": "", "version": "HTTP/1.1"}, "response": {"body_b64": "eyJjb25maWdzIjogW119", "body_len": 15, "headers": [["Server", "BaseHTTP/0.6 Python/3.12.13"], ["Date", "Tue, 11 Aug 2026 18:18:02 GMT"], ["Content-Type", "application/json"], ["Content-Length", "15"]], "status": 200, "status_line": "HTTP/1.1 200 OK"}, "seq": 1, "t_request": 86.687919, "t_response": 86.688751, "unix_request": 1786472282.4707916} +{"conn": 4, "connection": {"keepalive_observed": true, "requests_on_this_connection": 2}, "elapsed_ms": 1.039, "redacted": ["request.X-UT-SID", "request.query.deviceId"], "request": {"body_b64": "", "body_len": 0, "headers": [["Host", "10.10.0.120:8099"], ["User-Agent", "ProtoHttp 1.3/DS 15.1.2.1.0 (Windows)"], ["Accept", "application/json"], ["Content-Type", "application/json"], ["X-UT-SID", ""], ["Accept-Encoding", "gzip"]], "method": "GET", "path": "/ut/game/fifa17/phishing/trusteddevice", "query": "deviceId=", "version": "HTTP/1.1"}, "response": {"body_b64": "eyJjaGFuZ2VkIjogZmFsc2UsICJleGlzdHMiOiB0cnVlLCAibG9ja2VkIjogZmFsc2UsICJ0cnVzdGVkIjogdHJ1ZX0=", "body_len": 68, "headers": [["Server", "BaseHTTP/0.6 Python/3.12.13"], ["Date", "Tue, 11 Aug 2026 18:18:03 GMT"], ["Content-Type", "application/json"], ["Content-Length", "68"]], "status": 200, "status_line": "HTTP/1.1 200 OK"}, "seq": 2, "t_request": 87.637419, "t_response": 87.638458, "unix_request": 1786472283.4202926} +{"conn": 5, "connection": {"keepalive_observed": true, "requests_on_this_connection": 2}, "elapsed_ms": 0.955, "redacted": ["request.X-UT-SID"], "request": {"body_b64": "", "body_len": 0, "headers": [["Host", "10.10.0.120:8099"], ["Content-Length", "0"], ["User-Agent", "ProtoHttp 1.3/DS 15.1.2.1.0 (Windows)"], ["Accept", "application/json"], ["Content-Type", "application/json"], ["X-UT-SID", ""]], "method": "PUT", "path": "/ut/game/fifa17/match/reset", "query": "", "version": "HTTP/1.1"}, "response": {"body_b64": "e30=", "body_len": 2, "headers": [["Server", "BaseHTTP/0.6 Python/3.12.13"], ["Date", "Tue, 11 Aug 2026 18:18:03 GMT"], ["Content-Type", "application/json"], ["Content-Length", "2"]], "status": 200, "status_line": "HTTP/1.1 200 OK"}, "seq": 1, "t_request": 87.68812, "t_response": 87.689075, "unix_request": 1786472283.4709938} +{"conn": 5, "connection": {"keepalive_observed": true, "requests_on_this_connection": 2}, "elapsed_ms": 7.337, "redacted": ["request.X-UT-SID"], "request": {"body_b64": "", "body_len": 0, "headers": [["Host", "10.10.0.120:8099"], ["User-Agent", "ProtoHttp 1.3/DS 15.1.2.1.0 (Windows)"], ["Accept", "application/json"], ["Content-Type", "application/json"], ["X-UT-SID", ""], ["Accept-Encoding", "gzip"]], "method": "GET", "path": "/ut/game/fifa17/userMassInfo", "query": "", "version": "HTTP/1.1"}, "response": {"body_b64": "eyJ1c2VySW5mbyI6IHsicGVyc29uYUlkIjogMzMwNjgxNzksICJjbHViTmFtZSI6ICJPcGVuRlVUIiwgImNsdWJBYmJyIjogIk9GQyIsICJlc3RhYmxpc2hlZCI6ICIyMDI2IiwgImFjY291bnRDcmVhdGVkUGxhdGZvcm1OYW1lIjogInBjIiwgImN1cnJlbmNpZXMiOiBbeyJuYW1lIjogImNvaW5zIiwgImZ1bmRzIjogMjgwMjA2NTYsICJmaW5hbEZ1bmRzIjogMjgwMjA2NTYsICJhY3RpdmUiOiB0cnVlfSwgeyJuYW1lIjogInBvaW50cyIsICJmdW5kcyI6IDAsICJmaW5hbEZ1bmRzIjogMCwgImFjdGl2ZSI6IHRydWV9XSwgIndvbiI6IDAsICJkcmF3IjogMCwgImxvc3MiOiAwLCAiY2x1Yk5hbWVDaGFuZ2VBbGxvd2VkIjogZmFsc2UsICJkaXZpc2lvbk9mZmxpbmUiOiAxMCwgImRpdmlzaW9uT25saW5lIjogMTAsICJwdXJjaGFzZWQiOiBmYWxzZSwgImZlYXR1cmUiOiB7fSwgInJlbGlhYmlsaXR5IjogeyJyZWxpYWJpbGl0eSI6IDEwMCwgIm1hdGNoVW5maW5pc2hlZFRpbWUiOiAwfSwgImJpZFRva2VucyI6IHsiY291bnQiOiAwLCAidXBkYXRlVGltZSI6IDB9LCAidHJvcGhpZXMiOiAwLCAic2Vzc2lvbkNvaW5zQmFua0JhbGFuY2UiOiAwLCAiYWN0aXZlcyI6IFtdLCAic3F1YWRMaXN0IjogeyJzcXVhZCI6IFt7InJhdGluZyI6IDg5LCAiY2hlbWlzdHJ5IjogMjUsICJmb3JtYXRpb24iOiAiZjQ0MiIsICJpZCI6IDAsICJzcXVhZE5hbWUiOiAiT3BlbkZVVCIsICJzcXVhZFR5cGUiOiAiUkVHVUxBUl9TUVVBRCJ9XX19LCAic3F1YWQiOiB7ImlkIjogMCwgInBlcnNvbmFJZCI6IDMzMDY4MTc5LCAic3F1YWROYW1lIjogIk9wZW5GVVQiLCAiZm9ybWF0aW9uIjogImY0NDIiLCAic3F1YWRUeXBlIjogIlJFR1VMQVJfU1FVQUQiLCAiY2hlbWlzdHJ5IjogMjUsICJzdGFyUmF0aW5nIjogODgsICJjYXB0YWluIjogMTAwMDAwMDAxLCAiY2hhbmdlZCI6IDAsICJtYW5hZ2VyIjogW3siaWQiOiAxMDAwMDA0MjcsICJkcmVhbSI6IGZhbHNlfV0sICJhY3RpdmVzIjogW10sICJjdXN0b20iOiAiWzAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsNTAsNTAsMCw1MCw0MCw2NSwwLDY1LDUwLDUwLDFdIiwgInBsYXllcnMiOiBbeyJpbmRleCI6IDAsICJpdGVtRGF0YSI6IHsiaWQiOiAxMDAwMDAwMDMsICJyZXNvdXJjZUlkIjogMjAwMzg5LCAiYXNzZXRJZCI6IDIwMDM4OSwgImNhcmRhc3NldGlkIjogMjAwMzg5LCAiZGVmaW5pdGlvbklkIjogMjAwMzg5LCAiY2FyZHN1YnR5cGVpZCI6IDAsICJpdGVtVHlwZSI6ICJwbGF5ZXIiLCAicmFyZWZsYWciOiAxLCAicmF0aW5nIjogODcsICJwcmVmZXJyZWRQb3NpdGlvbiI6ICJHSyIsICJuYXRpb24iOiA0NCwgInRlYW1pZCI6IDI0MCwgImxlYWd1ZUlkIjogNTMsICJwbGF5U3R5bGUiOiAyNTAsICJhdHRyaWJ1dGVMaXN0IjogW3siaW5kZXgiOiAwLCAidmFsdWUiOiA4M30sIHsiaW5kZXgiOiAxLCAidmFsdWUiOiA5MH0sIHsiaW5kZXgiOiAyLCAidmFsdWUiOiA3N30sIHsiaW5kZXgiOiAzLCAidmFsdWUiOiA4Mn0sIHsiaW5kZXgiOiA0LCAidmFsdWUiOiA1MH0sIHsiaW5kZXgiOiA1LCAidmFsdWUiOiA4N31dLCAiaXRlbVN0YXRlIjogImZyZWUiLCAib3duZXJzIjogMSwgInVudHJhZGVhYmxlIjogZmFsc2UsICJjb250cmFjdCI6IDcsICJmaXRuZXNzIjogOTksICJkaXNjYXJkVmFsdWUiOiA2OTZ9LCAia2l0TnVtYmVyIjogMX0sIHsiaW5kZXgiOiAxLCAiaXRlbURhdGEiOiB7ImlkIjogMTAwMDAwMDEwLCAicmVzb3VyY2VJZCI6IDE3NjU4MCwgImFzc2V0SWQiOiAxNzY1ODAsICJjYXJkYXNzZXRpZCI6IDE3NjU4MCwgImRlZmluaXRpb25JZCI6IDE3NjU4MCwgImNhcmRzdWJ0eXBlaWQiOiAwLCAiaXRlbVR5cGUiOiAicGxheWVyIiwgInJhcmVmbGFnIjogMSwgInJhdGluZyI6IDkyLCAicHJlZmVycmVkUG9zaXRpb24iOiAiU1QiLCAibmF0aW9uIjogNjAsICJ0ZWFtaWQiOiAyNDEsICJsZWFndWVJZCI6IDUzLCAicGxheVN0eWxlIjogMjUwLCAiYXR0cmlidXRlTGlzdCI6IFt7ImluZGV4IjogMCwgInZhbHVlIjogODJ9LCB7ImluZGV4IjogMSwgInZhbHVlIjogOTB9LCB7ImluZGV4IjogMiwgInZhbHVlIjogNzl9LCB7ImluZGV4IjogMywgInZhbHVlIjogODd9LCB7ImluZGV4IjogNCwgInZhbHVlIjogNDJ9LCB7ImluZGV4IjogNSwgInZhbHVlIjogNzl9XSwgIml0ZW1TdGF0ZSI6ICJmcmVlIiwgIm93bmVycyI6IDEsICJ1bnRyYWRlYWJsZSI6IGZhbHNlLCAiY29udHJhY3QiOiA3LCAiZml0bmVzcyI6IDk5LCAiZGlzY2FyZFZhbHVlIjogNzM2fSwgImtpdE51bWJlciI6IDEwfSwgeyJpbmRleCI6IDIsICJpdGVtRGF0YSI6IHsiaWQiOiAxMDAwMDAwMDksICJyZXNvdXJjZUlkIjogMTgzMjc3LCAiYXNzZXRJZCI6IDE4MzI3NywgImNhcmRhc3NldGlkIjogMTgzMjc3LCAiZGVmaW5pdGlvbklkIjogMTgzMjc3LCAiY2FyZHN1YnR5cGVpZCI6IDAsICJpdGVtVHlwZSI6ICJwbGF5ZXIiLCAicmFyZWZsYWciOiAxLCAicmF0aW5nIjogODgsICJwcmVmZXJyZWRQb3NpdGlvbiI6ICJMTSIsICJuYXRpb24iOiA3LCAidGVhbWlkIjogNSwgImxlYWd1ZUlkIjogMTMsICJwbGF5U3R5bGUiOiAyNTAsICJhdHRyaWJ1dGVMaXN0IjogW3siaW5kZXgiOiAwLCAidmFsdWUiOiA5MH0sIHsiaW5kZXgiOiAxLCAidmFsdWUiOiA4MX0sIHsiaW5kZXgiOiAyLCAidmFsdWUiOiA4Mn0sIHsiaW5kZXgiOiAzLCAidmFsdWUiOiA5MX0sIHsiaW5kZXgiOiA0LCAidmFsdWUiOiAzMn0sIHsiaW5kZXgiOiA1LCAidmFsdWUiOiA2NH1dLCAiaXRlbVN0YXRlIjogImZyZWUiLCAib3duZXJzIjogMSwgInVudHJhZGVhYmxlIjogZmFsc2UsICJjb250cmFjdCI6IDcsICJmaXRuZXNzIjogOTksICJkaXNjYXJkVmFsdWUiOiA3MDR9LCAia2l0TnVtYmVyIjogN30sIHsiaW5kZXgiOiAzLCAiaXRlbURhdGEiOiB7ImlkIjogMTAwMDAwMDA4LCAicmVzb3VyY2VJZCI6IDE4MjUyMSwgImFzc2V0SWQiOiAxODI1MjEsICJjYXJkYXNzZXRpZCI6IDE4MjUyMSwgImRlZmluaXRpb25JZCI6IDE4MjUyMSwgImNhcmRzdWJ0eXBlaWQiOiAwLCAiaXRlbVR5cGUiOiAicGxheWVyIiwgInJhcmVmbGFnIjogMSwgInJhdGluZyI6IDg4LCAicHJlZmVycmVkUG9zaXRpb24iOiAiQ00iLCAibmF0aW9uIjogMjEsICJ0ZWFtaWQiOiAyNDMsICJsZWFndWVJZCI6IDUzLCAicGxheVN0eWxlIjogMjUwLCAiYXR0cmlidXRlTGlzdCI6IFt7ImluZGV4IjogMCwgInZhbHVlIjogNDV9LCB7ImluZGV4IjogMSwgInZhbHVlIjogODB9LCB7ImluZGV4IjogMiwgInZhbHVlIjogODh9LCB7ImluZGV4IjogMywgInZhbHVlIjogNzl9LCB7ImluZGV4IjogNCwgInZhbHVlIjogNjl9LCB7ImluZGV4IjogNSwgInZhbHVlIjogNzB9XSwgIml0ZW1TdGF0ZSI6ICJmcmVlIiwgIm93bmVycyI6IDEsICJ1bnRyYWRlYWJsZSI6IGZhbHNlLCAiY29udHJhY3QiOiA3LCAiZml0bmVzcyI6IDk5LCAiZGlzY2FyZFZhbHVlIjogNzA0fSwgImtpdE51bWJlciI6IDZ9LCB7ImluZGV4IjogNCwgIml0ZW1EYXRhIjogeyJpZCI6IDEwMDAwMDAwNywgInJlc291cmNlSWQiOiAxODkzMzIsICJhc3NldElkIjogMTg5MzMyLCAiY2FyZGFzc2V0aWQiOiAxODkzMzIsICJkZWZpbml0aW9uSWQiOiAxODkzMzIsICJjYXJkc3VidHlwZWlkIjogMCwgIml0ZW1UeXBlIjogInBsYXllciIsICJyYXJlZmxhZyI6IDEsICJyYXRpbmciOiA4NiwgInByZWZlcnJlZFBvc2l0aW9uIjogIkxCIiwgIm5hdGlvbiI6IDQ1LCAidGVhbWlkIjogMjQxLCAibGVhZ3VlSWQiOiA1MywgInBsYXlTdHlsZSI6IDI1MCwgImF0dHJpYnV0ZUxpc3QiOiBbeyJpbmRleCI6IDAsICJ2YWx1ZSI6IDkzfSwgeyJpbmRleCI6IDEsICJ2YWx1ZSI6IDY5fSwgeyJpbmRleCI6IDIsICJ2YWx1ZSI6IDc1fSwgeyJpbmRleCI6IDMsICJ2YWx1ZSI6IDgzfSwgeyJpbmRleCI6IDQsICJ2YWx1ZSI6IDgxfSwgeyJpbmRleCI6IDUsICJ2YWx1ZSI6IDc1fV0sICJpdGVtU3RhdGUiOiAiZnJlZSIsICJvd25lcnMiOiAxLCAidW50cmFkZWFibGUiOiBmYWxzZSwgImNvbnRyYWN0IjogNywgImZpdG5lc3MiOiA5OSwgImRpc2NhcmRWYWx1ZSI6IDY4OH0sICJraXROdW1iZXIiOiA1fSwgeyJpbmRleCI6IDUsICJpdGVtRGF0YSI6IHsiaWQiOiAxMDAwMDAwMDYsICJyZXNvdXJjZUlkIjogMTk3NDQ1LCAiYXNzZXRJZCI6IDE5NzQ0NSwgImNhcmRhc3NldGlkIjogMTk3NDQ1LCAiZGVmaW5pdGlvbklkIjogMTk3NDQ1LCAiY2FyZHN1YnR5cGVpZCI6IDAsICJpdGVtVHlwZSI6ICJwbGF5ZXIiLCAicmFyZWZsYWciOiAxLCAicmF0aW5nIjogODcsICJwcmVmZXJyZWRQb3NpdGlvbiI6ICJMQiIsICJuYXRpb24iOiA0LCAidGVhbWlkIjogMjEsICJsZWFndWVJZCI6IDE5LCAicGxheVN0eWxlIjogMjUwLCAiYXR0cmlidXRlTGlzdCI6IFt7ImluZGV4IjogMCwgInZhbHVlIjogODZ9LCB7ImluZGV4IjogMSwgInZhbHVlIjogNzN9LCB7ImluZGV4IjogMiwgInZhbHVlIjogODF9LCB7ImluZGV4IjogMywgInZhbHVlIjogODN9LCB7ImluZGV4IjogNCwgInZhbHVlIjogODN9LCB7ImluZGV4IjogNSwgInZhbHVlIjogNzN9XSwgIml0ZW1TdGF0ZSI6ICJmcmVlIiwgIm93bmVycyI6IDEsICJ1bnRyYWRlYWJsZSI6IGZhbHNlLCAiY29udHJhY3QiOiA3LCAiZml0bmVzcyI6IDk5LCAiZGlzY2FyZFZhbHVlIjogNjk2fSwgImtpdE51bWJlciI6IDR9LCB7ImluZGV4IjogNiwgIml0ZW1EYXRhIjogeyJpZCI6IDEwMDAwMDAwNSwgInJlc291cmNlSWQiOiAxNTU4NjIsICJhc3NldElkIjogMTU1ODYyLCAiY2FyZGFzc2V0aWQiOiAxNTU4NjIsICJkZWZpbml0aW9uSWQiOiAxNTU4NjIsICJjYXJkc3VidHlwZWlkIjogMCwgIml0ZW1UeXBlIjogInBsYXllciIsICJyYXJlZmxhZyI6IDEsICJyYXRpbmciOiA4OSwgInByZWZlcnJlZFBvc2l0aW9uIjogIkNCIiwgIm5hdGlvbiI6IDQ1LCAidGVhbWlkIjogMjQzLCAibGVhZ3VlSWQiOiA1MywgInBsYXlTdHlsZSI6IDI1MCwgImF0dHJpYnV0ZUxpc3QiOiBbeyJpbmRleCI6IDAsICJ2YWx1ZSI6IDc4fSwgeyJpbmRleCI6IDEsICJ2YWx1ZSI6IDYzfSwgeyJpbmRleCI6IDIsICJ2YWx1ZSI6IDcwfSwgeyJpbmRleCI6IDMsICJ2YWx1ZSI6IDcwfSwgeyJpbmRleCI6IDQsICJ2YWx1ZSI6IDg3fSwgeyJpbmRleCI6IDUsICJ2YWx1ZSI6IDgzfV0sICJpdGVtU3RhdGUiOiAiZnJlZSIsICJvd25lcnMiOiAxLCAidW50cmFkZWFibGUiOiBmYWxzZSwgImNvbnRyYWN0IjogNywgImZpdG5lc3MiOiA5OSwgImRpc2NhcmRWYWx1ZSI6IDcxMn0sICJraXROdW1iZXIiOiAzfSwgeyJpbmRleCI6IDcsICJpdGVtRGF0YSI6IHsiaWQiOiAxMDAwMDAwMDQsICJyZXNvdXJjZUlkIjogMTgzOTA3LCAiYXNzZXRJZCI6IDE4MzkwNywgImNhcmRhc3NldGlkIjogMTgzOTA3LCAiZGVmaW5pdGlvbklkIjogMTgzOTA3LCAiY2FyZHN1YnR5cGVpZCI6IDAsICJpdGVtVHlwZSI6ICJwbGF5ZXIiLCAicmFyZWZsYWciOiAxLCAicmF0aW5nIjogOTAsICJwcmVmZXJyZWRQb3NpdGlvbiI6ICJDQiIsICJuYXRpb24iOiAyMSwgInRlYW1pZCI6IDIxLCAibGVhZ3VlSWQiOiAxOSwgInBsYXlTdHlsZSI6IDI1MCwgImF0dHJpYnV0ZUxpc3QiOiBbeyJpbmRleCI6IDAsICJ2YWx1ZSI6IDc5fSwgeyJpbmRleCI6IDEsICJ2YWx1ZSI6IDUwfSwgeyJpbmRleCI6IDIsICJ2YWx1ZSI6IDcyfSwgeyJpbmRleCI6IDMsICJ2YWx1ZSI6IDY4fSwgeyJpbmRleCI6IDQsICJ2YWx1ZSI6IDkwfSwgeyJpbmRleCI6IDUsICJ2YWx1ZSI6IDg1fV0sICJpdGVtU3RhdGUiOiAiZnJlZSIsICJvd25lcnMiOiAxLCAidW50cmFkZWFibGUiOiBmYWxzZSwgImNvbnRyYWN0IjogNywgImZpdG5lc3MiOiA5OSwgImRpc2NhcmRWYWx1ZSI6IDcyMH0sICJraXROdW1iZXIiOiAyfSwgeyJpbmRleCI6IDgsICJpdGVtRGF0YSI6IHsiaWQiOiAxMDAwMDAwMjUsICJyZXNvdXJjZUlkIjogMTg4NTQ1LCAiYXNzZXRJZCI6IDE4ODU0NSwgImNhcmRhc3NldGlkIjogMTg4NTQ1LCAiZGVmaW5pdGlvbklkIjogMTg4NTQ1LCAiY2FyZHN1YnR5cGVpZCI6IDAsICJpdGVtVHlwZSI6ICJwbGF5ZXIiLCAicmFyZWZsYWciOiAxLCAicmF0aW5nIjogOTAsICJwcmVmZXJyZWRQb3NpdGlvbiI6ICJTVCIsICJuYXRpb24iOiAzNywgInRlYW1pZCI6IDIxLCAibGVhZ3VlSWQiOiAxOSwgInBsYXlTdHlsZSI6IDI1MCwgImF0dHJpYnV0ZUxpc3QiOiBbeyJpbmRleCI6IDAsICJ2YWx1ZSI6IDgxfSwgeyJpbmRleCI6IDEsICJ2YWx1ZSI6IDg3fSwgeyJpbmRleCI6IDIsICJ2YWx1ZSI6IDc0fSwgeyJpbmRleCI6IDMsICJ2YWx1ZSI6IDg1fSwgeyJpbmRleCI6IDQsICJ2YWx1ZSI6IDM4fSwgeyJpbmRleCI6IDUsICJ2YWx1ZSI6IDgyfV0sICJpdGVtU3RhdGUiOiAiZnJlZSIsICJvd25lcnMiOiAxLCAidW50cmFkZWFibGUiOiBmYWxzZSwgImNvbnRyYWN0IjogNywgImZpdG5lc3MiOiA5OSwgInBpbGUiOiAiY2x1YiIsICJkaXNjYXJkVmFsdWUiOiA3MjB9LCAia2l0TnVtYmVyIjogMTF9LCB7ImluZGV4IjogOSwgIml0ZW1EYXRhIjogeyJpZCI6IDAsICJkcmVhbSI6IGZhbHNlfSwgImtpdE51bWJlciI6IDB9LCB7ImluZGV4IjogMTAsICJpdGVtRGF0YSI6IHsiaWQiOiAxMDAwMDAwMDEsICJyZXNvdXJjZUlkIjogMjA4MDEsICJhc3NldElkIjogMjA4MDEsICJjYXJkYXNzZXRpZCI6IDIwODAxLCAiZGVmaW5pdGlvbklkIjogMjA4MDEsICJjYXJkc3VidHlwZWlkIjogMCwgIml0ZW1UeXBlIjogInBsYXllciIsICJyYXJlZmxhZyI6IDEsICJyYXRpbmciOiA5NCwgInByZWZlcnJlZFBvc2l0aW9uIjogIkxXIiwgIm5hdGlvbiI6IDM4LCAidGVhbWlkIjogMjQzLCAibGVhZ3VlSWQiOiA1MywgInBsYXlTdHlsZSI6IDI1MCwgImF0dHJpYnV0ZUxpc3QiOiBbeyJpbmRleCI6IDAsICJ2YWx1ZSI6IDkyfSwgeyJpbmRleCI6IDEsICJ2YWx1ZSI6IDkyfSwgeyJpbmRleCI6IDIsICJ2YWx1ZSI6IDgxfSwgeyJpbmRleCI6IDMsICJ2YWx1ZSI6IDkxfSwgeyJpbmRleCI6IDQsICJ2YWx1ZSI6IDMzfSwgeyJpbmRleCI6IDUsICJ2YWx1ZSI6IDgwfV0sICJpdGVtU3RhdGUiOiAiZnJlZSIsICJvd25lcnMiOiAxLCAidW50cmFkZWFibGUiOiBmYWxzZSwgImNvbnRyYWN0IjogNywgImZpdG5lc3MiOiA5OSwgImRpc2NhcmRWYWx1ZSI6IDc1Mn0sICJraXROdW1iZXIiOiA4fSwgeyJpbmRleCI6IDExLCAiaXRlbURhdGEiOiB7ImlkIjogMTAwMDAwMDAyLCAicmVzb3VyY2VJZCI6IDE1ODAyMywgImFzc2V0SWQiOiAxNTgwMjMsICJjYXJkYXNzZXRpZCI6IDE1ODAyMywgImRlZmluaXRpb25JZCI6IDE1ODAyMywgImNhcmRzdWJ0eXBlaWQiOiAwLCAiaXRlbVR5cGUiOiAicGxheWVyIiwgInJhcmVmbGFnIjogMSwgInJhdGluZyI6IDkzLCAicHJlZmVycmVkUG9zaXRpb24iOiAiUlciLCAibmF0aW9uIjogNTIsICJ0ZWFtaWQiOiAyNDEsICJsZWFndWVJZCI6IDUzLCAicGxheVN0eWxlIjogMjUwLCAiYXR0cmlidXRlTGlzdCI6IFt7ImluZGV4IjogMCwgInZhbHVlIjogODl9LCB7ImluZGV4IjogMSwgInZhbHVlIjogOTB9LCB7ImluZGV4IjogMiwgInZhbHVlIjogODZ9LCB7ImluZGV4IjogMywgInZhbHVlIjogOTZ9LCB7ImluZGV4IjogNCwgInZhbHVlIjogMjZ9LCB7ImluZGV4IjogNSwgInZhbHVlIjogNjF9XSwgIml0ZW1TdGF0ZSI6ICJmcmVlIiwgIm93bmVycyI6IDEsICJ1bnRyYWRlYWJsZSI6IGZhbHNlLCAiY29udHJhY3QiOiA3LCAiZml0bmVzcyI6IDk5LCAiZGlzY2FyZFZhbHVlIjogNzQ0fSwgImtpdE51bWJlciI6IDl9LCB7ImluZGV4IjogMTIsICJpdGVtRGF0YSI6IHsiaWQiOiAwLCAiZHJlYW0iOiBmYWxzZX0sICJraXROdW1iZXIiOiAwfSwgeyJpbmRleCI6IDEzLCAiaXRlbURhdGEiOiB7ImlkIjogMCwgImRyZWFtIjogZmFsc2V9LCAia2l0TnVtYmVyIjogMH0sIHsiaW5kZXgiOiAxNCwgIml0ZW1EYXRhIjogeyJpZCI6IDAsICJkcmVhbSI6IGZhbHNlfSwgImtpdE51bWJlciI6IDB9LCB7ImluZGV4IjogMTUsICJpdGVtRGF0YSI6IHsiaWQiOiAwLCAiZHJlYW0iOiBmYWxzZX0sICJraXROdW1iZXIiOiAwfSwgeyJpbmRleCI6IDE2LCAiaXRlbURhdGEiOiB7ImlkIjogMCwgImRyZWFtIjogZmFsc2V9LCAia2l0TnVtYmVyIjogMH0sIHsiaW5kZXgiOiAxNywgIml0ZW1EYXRhIjogeyJpZCI6IDAsICJkcmVhbSI6IGZhbHNlfSwgImtpdE51bWJlciI6IDB9LCB7ImluZGV4IjogMTgsICJpdGVtRGF0YSI6IHsiaWQiOiAwLCAiZHJlYW0iOiBmYWxzZX0sICJraXROdW1iZXIiOiAwfSwgeyJpbmRleCI6IDE5LCAiaXRlbURhdGEiOiB7ImlkIjogMCwgImRyZWFtIjogZmFsc2V9LCAia2l0TnVtYmVyIjogMH0sIHsiaW5kZXgiOiAyMCwgIml0ZW1EYXRhIjogeyJpZCI6IDAsICJkcmVhbSI6IGZhbHNlfSwgImtpdE51bWJlciI6IDB9LCB7ImluZGV4IjogMjEsICJpdGVtRGF0YSI6IHsiaWQiOiAwLCAiZHJlYW0iOiBmYWxzZX0sICJraXROdW1iZXIiOiAwfSwgeyJpbmRleCI6IDIyLCAiaXRlbURhdGEiOiB7ImlkIjogMCwgImRyZWFtIjogZmFsc2V9LCAia2l0TnVtYmVyIjogMH1dLCAia2lja3Rha2VycyI6IFt7ImluZGV4IjogMCwgImlkIjogMTAwMDAwMDAxLCAiZHJlYW0iOiBmYWxzZX0sIHsiaW5kZXgiOiAxLCAiaWQiOiAxMDAwMDAwMDEsICJkcmVhbSI6IGZhbHNlfSwgeyJpbmRleCI6IDIsICJpZCI6IDEwMDAwMDAwMSwgImRyZWFtIjogZmFsc2V9LCB7ImluZGV4IjogMywgImlkIjogMTAwMDAwMDAxLCAiZHJlYW0iOiBmYWxzZX0sIHsiaW5kZXgiOiA0LCAiaWQiOiAxMDAwMDAwMDEsICJkcmVhbSI6IGZhbHNlfV0sICJyYXRpbmciOiA4OH0sICJzZXR0aW5ncyI6IHsiY29uZmlncyI6IFtdfSwgInVzZXJEYXRhIjoge30sICJwaWxlU2l6ZUNsaWVudERhdGEiOiB7ImVudHJpZXMiOiBbeyJrZXkiOiAyLCAidmFsdWUiOiAxMDB9LCB7ImtleSI6IDQsICJ2YWx1ZSI6IDUwfV19fQ==", "body_len": 8929, "headers": [["Server", "BaseHTTP/0.6 Python/3.12.13"], ["Date", "Tue, 11 Aug 2026 18:18:03 GMT"], ["Content-Type", "application/json"], ["Content-Length", "8929"]], "status": 200, "status_line": "HTTP/1.1 200 OK"}, "seq": 2, "t_request": 87.735745, "t_response": 87.743082, "unix_request": 1786472283.5186143} +{"conn": 6, "connection": {"keepalive_observed": true, "requests_on_this_connection": 2}, "elapsed_ms": 0.885, "redacted": ["request.X-UT-SID"], "request": {"body_b64": "eyJzdGF0ZSI6IlRSQU5TQUNUSU9OQ0FOQ0VMIn0=", "body_len": 29, "headers": [["Host", "10.10.0.120:8099"], ["Content-Length", "29"], ["User-Agent", "ProtoHttp 1.3/DS 15.1.2.1.0 (Windows)"], ["Accept", "application/json"], ["Content-Type", "application/json"], ["X-UT-SID", ""]], "method": "PUT", "path": "/ut/v2/game/fifa17/store/transaction/0", "query": "", "version": "HTTP/1.1"}, "response": {"body_b64": "e30=", "body_len": 2, "headers": [["Server", "BaseHTTP/0.6 Python/3.12.13"], ["Date", "Tue, 11 Aug 2026 18:18:03 GMT"], ["Content-Type", "application/json"], ["Content-Length", "2"]], "status": 200, "status_line": "HTTP/1.1 200 OK"}, "seq": 1, "t_request": 87.820951, "t_response": 87.821836, "unix_request": 1786472283.6038213} +{"conn": 6, "connection": {"keepalive_observed": true, "requests_on_this_connection": 2}, "elapsed_ms": 3.609, "redacted": ["request.X-UT-SID"], "request": {"body_b64": "", "body_len": 0, "headers": [["Host", "10.10.0.120:8099"], ["User-Agent", "ProtoHttp 1.3/DS 15.1.2.1.0 (Windows)"], ["Accept", "application/json"], ["Content-Type", "application/json"], ["X-UT-SID", ""], ["Accept-Encoding", "gzip"]], "method": "GET", "path": "/ut/game/fifa17/hub", "query": "", "version": "HTTP/1.1"}, "response": {"body_b64": "eyJjbHViUGxheWVycyI6IDE5NjIsICJhdWN0aW9uQ291bnQiOiAxLCAidHJhZGVQaWxlIjogeyJjb3VudCI6IDEsICJzZWxsaW5nIjogMSwgInNvbGQiOiAwfSwgIm9mZmxpbmVTZWFzb24iOiB7ImRpdmlzaW9uSWQiOiAiMTAiLCAiZ2FtZXNQbGF5ZWQiOiAiMCIsICJwb2ludHMiOiAiMCIsICJ0b3RhbEdhbWVzIjogIjEwIiwgInByb2dyZXNzRGF0YVZlcnNpb24iOiAiMCJ9fQ==", "body_len": 214, "headers": [["Server", "BaseHTTP/0.6 Python/3.12.13"], ["Date", "Tue, 11 Aug 2026 18:18:03 GMT"], ["Content-Type", "application/json"], ["Content-Length", "214"]], "status": 200, "status_line": "HTTP/1.1 200 OK"}, "seq": 2, "t_request": 88.12058, "t_response": 88.124189, "unix_request": 1786472283.9034576} +{"conn": 7, "connection": {"keepalive_observed": true, "requests_on_this_connection": 3}, "elapsed_ms": 78.146, "redacted": ["request.X-UT-SID"], "request": {"body_b64": "eyJlbnRyaWVzIjpbeyJrZXkiOjAsInZhbHVlIjowfSx7ImtleSI6MSwidmFsdWUiOjF9XX0=", "body_len": 53, "headers": [["Host", "10.10.0.120:8099"], ["Content-Length", "53"], ["User-Agent", "ProtoHttp 1.3/DS 15.1.2.1.0 (Windows)"], ["Accept", "application/json"], ["Content-Type", "application/json"], ["X-UT-SID", ""]], "method": "PUT", "path": "/ut/game/fifa17/clientdata/userHubData", "query": "", "version": "HTTP/1.1"}, "response": {"body_b64": "e30=", "body_len": 2, "headers": [["Server", "BaseHTTP/0.6 Python/3.12.13"], ["Date", "Tue, 11 Aug 2026 18:18:07 GMT"], ["Content-Type", "application/json"], ["Content-Length", "2"]], "status": 200, "status_line": "HTTP/1.1 200 OK"}, "seq": 1, "t_request": 91.171212, "t_response": 91.249358, "unix_request": 1786472286.954086} +{"conn": 7, "connection": {"keepalive_observed": true, "requests_on_this_connection": 3}, "elapsed_ms": 41.316, "redacted": ["request.X-UT-SID"], "request": {"body_b64": "", "body_len": 0, "headers": [["Host", "10.10.0.120:8099"], ["User-Agent", "ProtoHttp 1.3/DS 15.1.2.1.0 (Windows)"], ["Accept", "application/json"], ["Content-Type", "application/json"], ["X-UT-SID", ""], ["Accept-Encoding", "gzip"]], "method": "GET", "path": "/ut/game/fifa17/user/credits", "query": "", "version": "HTTP/1.1"}, "response": {"body_b64": "eyJjcmVkaXRzIjogMjgwMjA2NTYsICJjdXJyZW5jaWVzIjogW3sibmFtZSI6ICJjb2lucyIsICJmdW5kcyI6IDI4MDIwNjU2LCAiZmluYWxGdW5kcyI6IDI4MDIwNjU2fSwgeyJuYW1lIjogInBvaW50cyIsICJmdW5kcyI6IDAsICJmaW5hbEZ1bmRzIjogMH1dfQ==", "body_len": 148, "headers": [["Server", "BaseHTTP/0.6 Python/3.12.13"], ["Date", "Tue, 11 Aug 2026 18:18:07 GMT"], ["Content-Type", "application/json"], ["Content-Length", "148"]], "status": 200, "status_line": "HTTP/1.1 200 OK"}, "seq": 2, "t_request": 91.286239, "t_response": 91.327555, "unix_request": 1786472287.0691159} +{"conn": 7, "connection": {"keepalive_observed": true, "requests_on_this_connection": 3}, "elapsed_ms": 0.871, "redacted": ["request.X-UT-SID"], "request": {"body_b64": "", "body_len": 0, "headers": [["Host", "10.10.0.120:8099"], ["User-Agent", "ProtoHttp 1.3/DS 15.1.2.1.0 (Windows)"], ["Accept", "application/json"], ["Content-Type", "application/json"], ["X-UT-SID", ""], ["Accept-Encoding", "gzip"]], "method": "GET", "path": "/ut/game/fifa17/store/purchasegroup/all", "query": "ppInfo=true", "version": "HTTP/1.1"}, "response": {"body_b64": "eyJwdXJjaGFzZSI6IFt7ImFzc2V0SWQiOiAxLCAiaWQiOiAxLCAicGFja1R5cGUiOiAiQlJPTlpFIiwgImRlc2NyaXB0aW9uIjogIkJyb256ZSBQYWNrIiwgInN0YXRlIjogImFjdGl2ZSIsICJzYWxlVHlwZSI6ICJwcm9tbyIsICJsaW1pdFR5cGUiOiAiTk9ORSIsICJxdWFudGl0eSI6IDAsICJwdXJjaGFzZUxpbWl0IjogMCwgInB1cmNoYXNlQ291bnQiOiAwLCAiaXNQcmVtaXVtIjogZmFsc2UsICJzb3J0UHJpb3JpdHkiOiAxLCAiY3VycmVuY2llcyI6IFt7Im5hbWUiOiAiY29pbnMiLCAiZnVuZHMiOiA0MDAsICJmaW5hbEZ1bmRzIjogNDAwfV0sICJleHRQcmljZSI6IHsiZmluYWxQcmljZSI6IHsiYW1vdW50IjogNCwgImN1cnJlbmN5IjogIm10eCJ9LCAib3JpZ2luYWxQcmljZSI6IHsiYW1vdW50IjogNCwgImN1cnJlbmN5IjogIm10eCJ9fSwgInBhY2tDb250ZW50SW5mbyI6IHsiYnJvbnplUXVhbnRpdHkiOiA1LCAic2lsdmVyUXVhbnRpdHkiOiAwLCAiZ29sZFF1YW50aXR5IjogMCwgInJhcmVRdWFudGl0eSI6IDAsICJpdGVtUXVhbnRpdHkiOiA1fSwgInVub3BlbmVkIjogZmFsc2UsICJkaXNwbGF5R3JvdXAiOiB7InZhbHVlIjogImJyb256ZSJ9fSwgeyJhc3NldElkIjogNSwgImlkIjogNSwgInBhY2tUeXBlIjogIkdPTEQiLCAiZGVzY3JpcHRpb24iOiAiR29sZCBQYWNrIiwgInN0YXRlIjogImFjdGl2ZSIsICJzYWxlVHlwZSI6ICJwcm9tbyIsICJsaW1pdFR5cGUiOiAiTk9ORSIsICJxdWFudGl0eSI6IDAsICJwdXJjaGFzZUxpbWl0IjogMCwgInB1cmNoYXNlQ291bnQiOiAwLCAiaXNQcmVtaXVtIjogZmFsc2UsICJzb3J0UHJpb3JpdHkiOiAyLCAiY3VycmVuY2llcyI6IFt7Im5hbWUiOiAiY29pbnMiLCAiZnVuZHMiOiA1MDAwLCAiZmluYWxGdW5kcyI6IDUwMDB9XSwgImV4dFByaWNlIjogeyJmaW5hbFByaWNlIjogeyJhbW91bnQiOiA1MCwgImN1cnJlbmN5IjogIm10eCJ9LCAib3JpZ2luYWxQcmljZSI6IHsiYW1vdW50IjogNTAsICJjdXJyZW5jeSI6ICJtdHgifX0sICJwYWNrQ29udGVudEluZm8iOiB7ImJyb256ZVF1YW50aXR5IjogMCwgInNpbHZlclF1YW50aXR5IjogMCwgImdvbGRRdWFudGl0eSI6IDcsICJyYXJlUXVhbnRpdHkiOiA3LCAiaXRlbVF1YW50aXR5IjogN30sICJ1bm9wZW5lZCI6IGZhbHNlLCAiZGlzcGxheUdyb3VwIjogeyJ2YWx1ZSI6ICJnb2xkIn19LCB7ImFzc2V0SWQiOiA2LCAiaWQiOiA2LCAicGFja1R5cGUiOiAiR09MRCIsICJkZXNjcmlwdGlvbiI6ICJQcmVtaXVtIEdvbGQiLCAic3RhdGUiOiAiYWN0aXZlIiwgInNhbGVUeXBlIjogInByb21vIiwgImxpbWl0VHlwZSI6ICJOT05FIiwgInF1YW50aXR5IjogMCwgInB1cmNoYXNlTGltaXQiOiAwLCAicHVyY2hhc2VDb3VudCI6IDAsICJpc1ByZW1pdW0iOiBmYWxzZSwgInNvcnRQcmlvcml0eSI6IDMsICJjdXJyZW5jaWVzIjogW3sibmFtZSI6ICJjb2lucyIsICJmdW5kcyI6IDE1MDAwLCAiZmluYWxGdW5kcyI6IDE1MDAwfV0sICJleHRQcmljZSI6IHsiZmluYWxQcmljZSI6IHsiYW1vdW50IjogMTUwLCAiY3VycmVuY3kiOiAibXR4In0sICJvcmlnaW5hbFByaWNlIjogeyJhbW91bnQiOiAxNTAsICJjdXJyZW5jeSI6ICJtdHgifX0sICJwYWNrQ29udGVudEluZm8iOiB7ImJyb256ZVF1YW50aXR5IjogMCwgInNpbHZlclF1YW50aXR5IjogMCwgImdvbGRRdWFudGl0eSI6IDExLCAicmFyZVF1YW50aXR5IjogMTEsICJpdGVtUXVhbnRpdHkiOiAxMX0sICJ1bm9wZW5lZCI6IGZhbHNlLCAiZGlzcGxheUdyb3VwIjogeyJ2YWx1ZSI6ICJnb2xkIn19LCB7ImFzc2V0SWQiOiA3LCAiaWQiOiA3LCAicGFja1R5cGUiOiAiR09MRCIsICJkZXNjcmlwdGlvbiI6ICJTcGVjaWFsIFBsYXllcnMgUGFjayIsICJzdGF0ZSI6ICJhY3RpdmUiLCAic2FsZVR5cGUiOiAicHJvbW8iLCAibGltaXRUeXBlIjogIk5PTkUiLCAicXVhbnRpdHkiOiAwLCAicHVyY2hhc2VMaW1pdCI6IDAsICJwdXJjaGFzZUNvdW50IjogMCwgImlzUHJlbWl1bSI6IGZhbHNlLCAic29ydFByaW9yaXR5IjogNCwgImN1cnJlbmNpZXMiOiBbeyJuYW1lIjogImNvaW5zIiwgImZ1bmRzIjogMjUwMDAsICJmaW5hbEZ1bmRzIjogMjUwMDB9XSwgImV4dFByaWNlIjogeyJmaW5hbFByaWNlIjogeyJhbW91bnQiOiAyNTAsICJjdXJyZW5jeSI6ICJtdHgifSwgIm9yaWdpbmFsUHJpY2UiOiB7ImFtb3VudCI6IDI1MCwgImN1cnJlbmN5IjogIm10eCJ9fSwgInBhY2tDb250ZW50SW5mbyI6IHsiYnJvbnplUXVhbnRpdHkiOiAwLCAic2lsdmVyUXVhbnRpdHkiOiAwLCAiZ29sZFF1YW50aXR5IjogMTEsICJyYXJlUXVhbnRpdHkiOiAxMSwgIml0ZW1RdWFudGl0eSI6IDExfSwgInVub3BlbmVkIjogZmFsc2UsICJkaXNwbGF5R3JvdXAiOiB7InZhbHVlIjogInNwZWNpYWwifX0sIHsiYXNzZXRJZCI6IDY1NTM0LCAiaWQiOiA2NTUzNCwgInBhY2tUeXBlIjogIkdPTEQiLCAiZGVzY3JpcHRpb24iOiAiIiwgInN0YXRlIjogImluYWN0aXZlIiwgInNhbGVUeXBlIjogInByb21vIiwgImxpbWl0VHlwZSI6ICJOT05FIiwgInF1YW50aXR5IjogMCwgInB1cmNoYXNlTGltaXQiOiAwLCAicHVyY2hhc2VDb3VudCI6IDAsICJpc1ByZW1pdW0iOiBmYWxzZSwgInNvcnRQcmlvcml0eSI6IDEsICJwYWNrQ29udGVudEluZm8iOiB7ImJyb256ZVF1YW50aXR5IjogMCwgInNpbHZlclF1YW50aXR5IjogMCwgImdvbGRRdWFudGl0eSI6IDAsICJyYXJlUXVhbnRpdHkiOiAwLCAiaXRlbVF1YW50aXR5IjogMH0sICJ1bm9wZW5lZCI6IGZhbHNlLCAiZGlzcGxheUdyb3VwIjogeyJ2YWx1ZSI6ICJteXBhY2tzIiwgInByaW9yaXR5IjogMX19XSwgInRpbWVzdGFtcCI6IDE1OTYzMjY0MDB9", "body_len": 2841, "headers": [["Server", "BaseHTTP/0.6 Python/3.12.13"], ["Date", "Tue, 11 Aug 2026 18:18:07 GMT"], ["Content-Type", "application/json"], ["Content-Length", "2841"]], "status": 200, "status_line": "HTTP/1.1 200 OK"}, "seq": 3, "t_request": 91.368892, "t_response": 91.369763, "unix_request": 1786472287.1517632} +{"conn": 8, "connection": {"keepalive_observed": true, "requests_on_this_connection": 4}, "elapsed_ms": 1032.662, "redacted": ["request.X-UT-SID"], "request": {"body_b64": "eyJwYWNrSWQiOjcsInVzZUNyZWRpdHMiOjEsInVzZVByZU9yZGVyIjowLCJjdXJyZW5jeSI6IkNPSU5TIn0=", "body_len": 62, "headers": [["Host", "10.10.0.120:8099"], ["Content-Length", "62"], ["User-Agent", "ProtoHttp 1.3/DS 15.1.2.1.0 (Windows)"], ["Accept", "application/json"], ["Content-Type", "application/json"], ["X-UT-SID", ""]], "method": "POST", "path": "/ut/game/fifa17/purchased/items", "query": "", "version": "HTTP/1.1"}, "response": {"body_b64": "eyJwYWNrSWQiOiA3LCAiZmlyc3RQYXJ0eVN0b3JlSWQiOiAwLCAiZ3JvdXBOYW1lIjogImZpZmExNyIsICJwcm9kdWN0SWQiOiAiNyIsICJwdXJjaGFzZVBhY2tUeXBlIjogIkdPTEQifQ==", "body_len": 106, "headers": [["Server", "BaseHTTP/0.6 Python/3.12.13"], ["Date", "Tue, 11 Aug 2026 18:18:11 GMT"], ["Content-Type", "application/json"], ["Content-Length", "106"]], "status": 200, "status_line": "HTTP/1.1 200 OK"}, "seq": 1, "t_request": 94.786972, "t_response": 95.819634, "unix_request": 1786472290.5698442} +{"conn": 8, "connection": {"keepalive_observed": true, "requests_on_this_connection": 4}, "elapsed_ms": 4.374, "redacted": ["request.X-UT-SID"], "request": {"body_b64": "", "body_len": 0, "headers": [["Host", "10.10.0.120:8099"], ["User-Agent", "ProtoHttp 1.3/DS 15.1.2.1.0 (Windows)"], ["Accept", "application/json"], ["Content-Type", "application/json"], ["X-UT-SID", ""], ["Accept-Encoding", "gzip"]], "method": "GET", "path": "/ut/game/fifa17/squad/active", "query": "active=true", "version": "HTTP/1.1"}, "response": {"body_b64": "eyJpZCI6IDAsICJwZXJzb25hSWQiOiAzMzA2ODE3OSwgInNxdWFkTmFtZSI6ICJPcGVuRlVUIiwgImZvcm1hdGlvbiI6ICJmNDQyIiwgInNxdWFkVHlwZSI6ICJSRUdVTEFSX1NRVUFEIiwgImNoZW1pc3RyeSI6IDI1LCAic3RhclJhdGluZyI6IDg4LCAiY2FwdGFpbiI6IDEwMDAwMDAwMSwgImNoYW5nZWQiOiAwLCAibWFuYWdlciI6IFt7ImlkIjogMTAwMDAwNDI3LCAiZHJlYW0iOiBmYWxzZX1dLCAiYWN0aXZlcyI6IFtdLCAiY3VzdG9tIjogIlswLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDUwLDUwLDAsNTAsNDAsNjUsMCw2NSw1MCw1MCwxXSIsICJwbGF5ZXJzIjogW3siaW5kZXgiOiAwLCAiaXRlbURhdGEiOiB7ImlkIjogMTAwMDAwMDAzLCAicmVzb3VyY2VJZCI6IDIwMDM4OSwgImFzc2V0SWQiOiAyMDAzODksICJjYXJkYXNzZXRpZCI6IDIwMDM4OSwgImRlZmluaXRpb25JZCI6IDIwMDM4OSwgImNhcmRzdWJ0eXBlaWQiOiAwLCAiaXRlbVR5cGUiOiAicGxheWVyIiwgInJhcmVmbGFnIjogMSwgInJhdGluZyI6IDg3LCAicHJlZmVycmVkUG9zaXRpb24iOiAiR0siLCAibmF0aW9uIjogNDQsICJ0ZWFtaWQiOiAyNDAsICJsZWFndWVJZCI6IDUzLCAicGxheVN0eWxlIjogMjUwLCAiYXR0cmlidXRlTGlzdCI6IFt7ImluZGV4IjogMCwgInZhbHVlIjogODN9LCB7ImluZGV4IjogMSwgInZhbHVlIjogOTB9LCB7ImluZGV4IjogMiwgInZhbHVlIjogNzd9LCB7ImluZGV4IjogMywgInZhbHVlIjogODJ9LCB7ImluZGV4IjogNCwgInZhbHVlIjogNTB9LCB7ImluZGV4IjogNSwgInZhbHVlIjogODd9XSwgIml0ZW1TdGF0ZSI6ICJmcmVlIiwgIm93bmVycyI6IDEsICJ1bnRyYWRlYWJsZSI6IGZhbHNlLCAiY29udHJhY3QiOiA3LCAiZml0bmVzcyI6IDk5LCAiZGlzY2FyZFZhbHVlIjogNjk2fSwgImtpdE51bWJlciI6IDF9LCB7ImluZGV4IjogMSwgIml0ZW1EYXRhIjogeyJpZCI6IDEwMDAwMDAxMCwgInJlc291cmNlSWQiOiAxNzY1ODAsICJhc3NldElkIjogMTc2NTgwLCAiY2FyZGFzc2V0aWQiOiAxNzY1ODAsICJkZWZpbml0aW9uSWQiOiAxNzY1ODAsICJjYXJkc3VidHlwZWlkIjogMCwgIml0ZW1UeXBlIjogInBsYXllciIsICJyYXJlZmxhZyI6IDEsICJyYXRpbmciOiA5MiwgInByZWZlcnJlZFBvc2l0aW9uIjogIlNUIiwgIm5hdGlvbiI6IDYwLCAidGVhbWlkIjogMjQxLCAibGVhZ3VlSWQiOiA1MywgInBsYXlTdHlsZSI6IDI1MCwgImF0dHJpYnV0ZUxpc3QiOiBbeyJpbmRleCI6IDAsICJ2YWx1ZSI6IDgyfSwgeyJpbmRleCI6IDEsICJ2YWx1ZSI6IDkwfSwgeyJpbmRleCI6IDIsICJ2YWx1ZSI6IDc5fSwgeyJpbmRleCI6IDMsICJ2YWx1ZSI6IDg3fSwgeyJpbmRleCI6IDQsICJ2YWx1ZSI6IDQyfSwgeyJpbmRleCI6IDUsICJ2YWx1ZSI6IDc5fV0sICJpdGVtU3RhdGUiOiAiZnJlZSIsICJvd25lcnMiOiAxLCAidW50cmFkZWFibGUiOiBmYWxzZSwgImNvbnRyYWN0IjogNywgImZpdG5lc3MiOiA5OSwgImRpc2NhcmRWYWx1ZSI6IDczNn0sICJraXROdW1iZXIiOiAxMH0sIHsiaW5kZXgiOiAyLCAiaXRlbURhdGEiOiB7ImlkIjogMTAwMDAwMDA5LCAicmVzb3VyY2VJZCI6IDE4MzI3NywgImFzc2V0SWQiOiAxODMyNzcsICJjYXJkYXNzZXRpZCI6IDE4MzI3NywgImRlZmluaXRpb25JZCI6IDE4MzI3NywgImNhcmRzdWJ0eXBlaWQiOiAwLCAiaXRlbVR5cGUiOiAicGxheWVyIiwgInJhcmVmbGFnIjogMSwgInJhdGluZyI6IDg4LCAicHJlZmVycmVkUG9zaXRpb24iOiAiTE0iLCAibmF0aW9uIjogNywgInRlYW1pZCI6IDUsICJsZWFndWVJZCI6IDEzLCAicGxheVN0eWxlIjogMjUwLCAiYXR0cmlidXRlTGlzdCI6IFt7ImluZGV4IjogMCwgInZhbHVlIjogOTB9LCB7ImluZGV4IjogMSwgInZhbHVlIjogODF9LCB7ImluZGV4IjogMiwgInZhbHVlIjogODJ9LCB7ImluZGV4IjogMywgInZhbHVlIjogOTF9LCB7ImluZGV4IjogNCwgInZhbHVlIjogMzJ9LCB7ImluZGV4IjogNSwgInZhbHVlIjogNjR9XSwgIml0ZW1TdGF0ZSI6ICJmcmVlIiwgIm93bmVycyI6IDEsICJ1bnRyYWRlYWJsZSI6IGZhbHNlLCAiY29udHJhY3QiOiA3LCAiZml0bmVzcyI6IDk5LCAiZGlzY2FyZFZhbHVlIjogNzA0fSwgImtpdE51bWJlciI6IDd9LCB7ImluZGV4IjogMywgIml0ZW1EYXRhIjogeyJpZCI6IDEwMDAwMDAwOCwgInJlc291cmNlSWQiOiAxODI1MjEsICJhc3NldElkIjogMTgyNTIxLCAiY2FyZGFzc2V0aWQiOiAxODI1MjEsICJkZWZpbml0aW9uSWQiOiAxODI1MjEsICJjYXJkc3VidHlwZWlkIjogMCwgIml0ZW1UeXBlIjogInBsYXllciIsICJyYXJlZmxhZyI6IDEsICJyYXRpbmciOiA4OCwgInByZWZlcnJlZFBvc2l0aW9uIjogIkNNIiwgIm5hdGlvbiI6IDIxLCAidGVhbWlkIjogMjQzLCAibGVhZ3VlSWQiOiA1MywgInBsYXlTdHlsZSI6IDI1MCwgImF0dHJpYnV0ZUxpc3QiOiBbeyJpbmRleCI6IDAsICJ2YWx1ZSI6IDQ1fSwgeyJpbmRleCI6IDEsICJ2YWx1ZSI6IDgwfSwgeyJpbmRleCI6IDIsICJ2YWx1ZSI6IDg4fSwgeyJpbmRleCI6IDMsICJ2YWx1ZSI6IDc5fSwgeyJpbmRleCI6IDQsICJ2YWx1ZSI6IDY5fSwgeyJpbmRleCI6IDUsICJ2YWx1ZSI6IDcwfV0sICJpdGVtU3RhdGUiOiAiZnJlZSIsICJvd25lcnMiOiAxLCAidW50cmFkZWFibGUiOiBmYWxzZSwgImNvbnRyYWN0IjogNywgImZpdG5lc3MiOiA5OSwgImRpc2NhcmRWYWx1ZSI6IDcwNH0sICJraXROdW1iZXIiOiA2fSwgeyJpbmRleCI6IDQsICJpdGVtRGF0YSI6IHsiaWQiOiAxMDAwMDAwMDcsICJyZXNvdXJjZUlkIjogMTg5MzMyLCAiYXNzZXRJZCI6IDE4OTMzMiwgImNhcmRhc3NldGlkIjogMTg5MzMyLCAiZGVmaW5pdGlvbklkIjogMTg5MzMyLCAiY2FyZHN1YnR5cGVpZCI6IDAsICJpdGVtVHlwZSI6ICJwbGF5ZXIiLCAicmFyZWZsYWciOiAxLCAicmF0aW5nIjogODYsICJwcmVmZXJyZWRQb3NpdGlvbiI6ICJMQiIsICJuYXRpb24iOiA0NSwgInRlYW1pZCI6IDI0MSwgImxlYWd1ZUlkIjogNTMsICJwbGF5U3R5bGUiOiAyNTAsICJhdHRyaWJ1dGVMaXN0IjogW3siaW5kZXgiOiAwLCAidmFsdWUiOiA5M30sIHsiaW5kZXgiOiAxLCAidmFsdWUiOiA2OX0sIHsiaW5kZXgiOiAyLCAidmFsdWUiOiA3NX0sIHsiaW5kZXgiOiAzLCAidmFsdWUiOiA4M30sIHsiaW5kZXgiOiA0LCAidmFsdWUiOiA4MX0sIHsiaW5kZXgiOiA1LCAidmFsdWUiOiA3NX1dLCAiaXRlbVN0YXRlIjogImZyZWUiLCAib3duZXJzIjogMSwgInVudHJhZGVhYmxlIjogZmFsc2UsICJjb250cmFjdCI6IDcsICJmaXRuZXNzIjogOTksICJkaXNjYXJkVmFsdWUiOiA2ODh9LCAia2l0TnVtYmVyIjogNX0sIHsiaW5kZXgiOiA1LCAiaXRlbURhdGEiOiB7ImlkIjogMTAwMDAwMDA2LCAicmVzb3VyY2VJZCI6IDE5NzQ0NSwgImFzc2V0SWQiOiAxOTc0NDUsICJjYXJkYXNzZXRpZCI6IDE5NzQ0NSwgImRlZmluaXRpb25JZCI6IDE5NzQ0NSwgImNhcmRzdWJ0eXBlaWQiOiAwLCAiaXRlbVR5cGUiOiAicGxheWVyIiwgInJhcmVmbGFnIjogMSwgInJhdGluZyI6IDg3LCAicHJlZmVycmVkUG9zaXRpb24iOiAiTEIiLCAibmF0aW9uIjogNCwgInRlYW1pZCI6IDIxLCAibGVhZ3VlSWQiOiAxOSwgInBsYXlTdHlsZSI6IDI1MCwgImF0dHJpYnV0ZUxpc3QiOiBbeyJpbmRleCI6IDAsICJ2YWx1ZSI6IDg2fSwgeyJpbmRleCI6IDEsICJ2YWx1ZSI6IDczfSwgeyJpbmRleCI6IDIsICJ2YWx1ZSI6IDgxfSwgeyJpbmRleCI6IDMsICJ2YWx1ZSI6IDgzfSwgeyJpbmRleCI6IDQsICJ2YWx1ZSI6IDgzfSwgeyJpbmRleCI6IDUsICJ2YWx1ZSI6IDczfV0sICJpdGVtU3RhdGUiOiAiZnJlZSIsICJvd25lcnMiOiAxLCAidW50cmFkZWFibGUiOiBmYWxzZSwgImNvbnRyYWN0IjogNywgImZpdG5lc3MiOiA5OSwgImRpc2NhcmRWYWx1ZSI6IDY5Nn0sICJraXROdW1iZXIiOiA0fSwgeyJpbmRleCI6IDYsICJpdGVtRGF0YSI6IHsiaWQiOiAxMDAwMDAwMDUsICJyZXNvdXJjZUlkIjogMTU1ODYyLCAiYXNzZXRJZCI6IDE1NTg2MiwgImNhcmRhc3NldGlkIjogMTU1ODYyLCAiZGVmaW5pdGlvbklkIjogMTU1ODYyLCAiY2FyZHN1YnR5cGVpZCI6IDAsICJpdGVtVHlwZSI6ICJwbGF5ZXIiLCAicmFyZWZsYWciOiAxLCAicmF0aW5nIjogODksICJwcmVmZXJyZWRQb3NpdGlvbiI6ICJDQiIsICJuYXRpb24iOiA0NSwgInRlYW1pZCI6IDI0MywgImxlYWd1ZUlkIjogNTMsICJwbGF5U3R5bGUiOiAyNTAsICJhdHRyaWJ1dGVMaXN0IjogW3siaW5kZXgiOiAwLCAidmFsdWUiOiA3OH0sIHsiaW5kZXgiOiAxLCAidmFsdWUiOiA2M30sIHsiaW5kZXgiOiAyLCAidmFsdWUiOiA3MH0sIHsiaW5kZXgiOiAzLCAidmFsdWUiOiA3MH0sIHsiaW5kZXgiOiA0LCAidmFsdWUiOiA4N30sIHsiaW5kZXgiOiA1LCAidmFsdWUiOiA4M31dLCAiaXRlbVN0YXRlIjogImZyZWUiLCAib3duZXJzIjogMSwgInVudHJhZGVhYmxlIjogZmFsc2UsICJjb250cmFjdCI6IDcsICJmaXRuZXNzIjogOTksICJkaXNjYXJkVmFsdWUiOiA3MTJ9LCAia2l0TnVtYmVyIjogM30sIHsiaW5kZXgiOiA3LCAiaXRlbURhdGEiOiB7ImlkIjogMTAwMDAwMDA0LCAicmVzb3VyY2VJZCI6IDE4MzkwNywgImFzc2V0SWQiOiAxODM5MDcsICJjYXJkYXNzZXRpZCI6IDE4MzkwNywgImRlZmluaXRpb25JZCI6IDE4MzkwNywgImNhcmRzdWJ0eXBlaWQiOiAwLCAiaXRlbVR5cGUiOiAicGxheWVyIiwgInJhcmVmbGFnIjogMSwgInJhdGluZyI6IDkwLCAicHJlZmVycmVkUG9zaXRpb24iOiAiQ0IiLCAibmF0aW9uIjogMjEsICJ0ZWFtaWQiOiAyMSwgImxlYWd1ZUlkIjogMTksICJwbGF5U3R5bGUiOiAyNTAsICJhdHRyaWJ1dGVMaXN0IjogW3siaW5kZXgiOiAwLCAidmFsdWUiOiA3OX0sIHsiaW5kZXgiOiAxLCAidmFsdWUiOiA1MH0sIHsiaW5kZXgiOiAyLCAidmFsdWUiOiA3Mn0sIHsiaW5kZXgiOiAzLCAidmFsdWUiOiA2OH0sIHsiaW5kZXgiOiA0LCAidmFsdWUiOiA5MH0sIHsiaW5kZXgiOiA1LCAidmFsdWUiOiA4NX1dLCAiaXRlbVN0YXRlIjogImZyZWUiLCAib3duZXJzIjogMSwgInVudHJhZGVhYmxlIjogZmFsc2UsICJjb250cmFjdCI6IDcsICJmaXRuZXNzIjogOTksICJkaXNjYXJkVmFsdWUiOiA3MjB9LCAia2l0TnVtYmVyIjogMn0sIHsiaW5kZXgiOiA4LCAiaXRlbURhdGEiOiB7ImlkIjogMTAwMDAwMDI1LCAicmVzb3VyY2VJZCI6IDE4ODU0NSwgImFzc2V0SWQiOiAxODg1NDUsICJjYXJkYXNzZXRpZCI6IDE4ODU0NSwgImRlZmluaXRpb25JZCI6IDE4ODU0NSwgImNhcmRzdWJ0eXBlaWQiOiAwLCAiaXRlbVR5cGUiOiAicGxheWVyIiwgInJhcmVmbGFnIjogMSwgInJhdGluZyI6IDkwLCAicHJlZmVycmVkUG9zaXRpb24iOiAiU1QiLCAibmF0aW9uIjogMzcsICJ0ZWFtaWQiOiAyMSwgImxlYWd1ZUlkIjogMTksICJwbGF5U3R5bGUiOiAyNTAsICJhdHRyaWJ1dGVMaXN0IjogW3siaW5kZXgiOiAwLCAidmFsdWUiOiA4MX0sIHsiaW5kZXgiOiAxLCAidmFsdWUiOiA4N30sIHsiaW5kZXgiOiAyLCAidmFsdWUiOiA3NH0sIHsiaW5kZXgiOiAzLCAidmFsdWUiOiA4NX0sIHsiaW5kZXgiOiA0LCAidmFsdWUiOiAzOH0sIHsiaW5kZXgiOiA1LCAidmFsdWUiOiA4Mn1dLCAiaXRlbVN0YXRlIjogImZyZWUiLCAib3duZXJzIjogMSwgInVudHJhZGVhYmxlIjogZmFsc2UsICJjb250cmFjdCI6IDcsICJmaXRuZXNzIjogOTksICJwaWxlIjogImNsdWIiLCAiZGlzY2FyZFZhbHVlIjogNzIwfSwgImtpdE51bWJlciI6IDExfSwgeyJpbmRleCI6IDksICJpdGVtRGF0YSI6IHsiaWQiOiAwLCAiZHJlYW0iOiBmYWxzZX0sICJraXROdW1iZXIiOiAwfSwgeyJpbmRleCI6IDEwLCAiaXRlbURhdGEiOiB7ImlkIjogMTAwMDAwMDAxLCAicmVzb3VyY2VJZCI6IDIwODAxLCAiYXNzZXRJZCI6IDIwODAxLCAiY2FyZGFzc2V0aWQiOiAyMDgwMSwgImRlZmluaXRpb25JZCI6IDIwODAxLCAiY2FyZHN1YnR5cGVpZCI6IDAsICJpdGVtVHlwZSI6ICJwbGF5ZXIiLCAicmFyZWZsYWciOiAxLCAicmF0aW5nIjogOTQsICJwcmVmZXJyZWRQb3NpdGlvbiI6ICJMVyIsICJuYXRpb24iOiAzOCwgInRlYW1pZCI6IDI0MywgImxlYWd1ZUlkIjogNTMsICJwbGF5U3R5bGUiOiAyNTAsICJhdHRyaWJ1dGVMaXN0IjogW3siaW5kZXgiOiAwLCAidmFsdWUiOiA5Mn0sIHsiaW5kZXgiOiAxLCAidmFsdWUiOiA5Mn0sIHsiaW5kZXgiOiAyLCAidmFsdWUiOiA4MX0sIHsiaW5kZXgiOiAzLCAidmFsdWUiOiA5MX0sIHsiaW5kZXgiOiA0LCAidmFsdWUiOiAzM30sIHsiaW5kZXgiOiA1LCAidmFsdWUiOiA4MH1dLCAiaXRlbVN0YXRlIjogImZyZWUiLCAib3duZXJzIjogMSwgInVudHJhZGVhYmxlIjogZmFsc2UsICJjb250cmFjdCI6IDcsICJmaXRuZXNzIjogOTksICJkaXNjYXJkVmFsdWUiOiA3NTJ9LCAia2l0TnVtYmVyIjogOH0sIHsiaW5kZXgiOiAxMSwgIml0ZW1EYXRhIjogeyJpZCI6IDEwMDAwMDAwMiwgInJlc291cmNlSWQiOiAxNTgwMjMsICJhc3NldElkIjogMTU4MDIzLCAiY2FyZGFzc2V0aWQiOiAxNTgwMjMsICJkZWZpbml0aW9uSWQiOiAxNTgwMjMsICJjYXJkc3VidHlwZWlkIjogMCwgIml0ZW1UeXBlIjogInBsYXllciIsICJyYXJlZmxhZyI6IDEsICJyYXRpbmciOiA5MywgInByZWZlcnJlZFBvc2l0aW9uIjogIlJXIiwgIm5hdGlvbiI6IDUyLCAidGVhbWlkIjogMjQxLCAibGVhZ3VlSWQiOiA1MywgInBsYXlTdHlsZSI6IDI1MCwgImF0dHJpYnV0ZUxpc3QiOiBbeyJpbmRleCI6IDAsICJ2YWx1ZSI6IDg5fSwgeyJpbmRleCI6IDEsICJ2YWx1ZSI6IDkwfSwgeyJpbmRleCI6IDIsICJ2YWx1ZSI6IDg2fSwgeyJpbmRleCI6IDMsICJ2YWx1ZSI6IDk2fSwgeyJpbmRleCI6IDQsICJ2YWx1ZSI6IDI2fSwgeyJpbmRleCI6IDUsICJ2YWx1ZSI6IDYxfV0sICJpdGVtU3RhdGUiOiAiZnJlZSIsICJvd25lcnMiOiAxLCAidW50cmFkZWFibGUiOiBmYWxzZSwgImNvbnRyYWN0IjogNywgImZpdG5lc3MiOiA5OSwgImRpc2NhcmRWYWx1ZSI6IDc0NH0sICJraXROdW1iZXIiOiA5fSwgeyJpbmRleCI6IDEyLCAiaXRlbURhdGEiOiB7ImlkIjogMCwgImRyZWFtIjogZmFsc2V9LCAia2l0TnVtYmVyIjogMH0sIHsiaW5kZXgiOiAxMywgIml0ZW1EYXRhIjogeyJpZCI6IDAsICJkcmVhbSI6IGZhbHNlfSwgImtpdE51bWJlciI6IDB9LCB7ImluZGV4IjogMTQsICJpdGVtRGF0YSI6IHsiaWQiOiAwLCAiZHJlYW0iOiBmYWxzZX0sICJraXROdW1iZXIiOiAwfSwgeyJpbmRleCI6IDE1LCAiaXRlbURhdGEiOiB7ImlkIjogMCwgImRyZWFtIjogZmFsc2V9LCAia2l0TnVtYmVyIjogMH0sIHsiaW5kZXgiOiAxNiwgIml0ZW1EYXRhIjogeyJpZCI6IDAsICJkcmVhbSI6IGZhbHNlfSwgImtpdE51bWJlciI6IDB9LCB7ImluZGV4IjogMTcsICJpdGVtRGF0YSI6IHsiaWQiOiAwLCAiZHJlYW0iOiBmYWxzZX0sICJraXROdW1iZXIiOiAwfSwgeyJpbmRleCI6IDE4LCAiaXRlbURhdGEiOiB7ImlkIjogMCwgImRyZWFtIjogZmFsc2V9LCAia2l0TnVtYmVyIjogMH0sIHsiaW5kZXgiOiAxOSwgIml0ZW1EYXRhIjogeyJpZCI6IDAsICJkcmVhbSI6IGZhbHNlfSwgImtpdE51bWJlciI6IDB9LCB7ImluZGV4IjogMjAsICJpdGVtRGF0YSI6IHsiaWQiOiAwLCAiZHJlYW0iOiBmYWxzZX0sICJraXROdW1iZXIiOiAwfSwgeyJpbmRleCI6IDIxLCAiaXRlbURhdGEiOiB7ImlkIjogMCwgImRyZWFtIjogZmFsc2V9LCAia2l0TnVtYmVyIjogMH0sIHsiaW5kZXgiOiAyMiwgIml0ZW1EYXRhIjogeyJpZCI6IDAsICJkcmVhbSI6IGZhbHNlfSwgImtpdE51bWJlciI6IDB9XSwgImtpY2t0YWtlcnMiOiBbeyJpbmRleCI6IDAsICJpZCI6IDEwMDAwMDAwMSwgImRyZWFtIjogZmFsc2V9LCB7ImluZGV4IjogMSwgImlkIjogMTAwMDAwMDAxLCAiZHJlYW0iOiBmYWxzZX0sIHsiaW5kZXgiOiAyLCAiaWQiOiAxMDAwMDAwMDEsICJkcmVhbSI6IGZhbHNlfSwgeyJpbmRleCI6IDMsICJpZCI6IDEwMDAwMDAwMSwgImRyZWFtIjogZmFsc2V9LCB7ImluZGV4IjogNCwgImlkIjogMTAwMDAwMDAxLCAiZHJlYW0iOiBmYWxzZX1dLCAicmF0aW5nIjogODh9", "body_len": 8034, "headers": [["Server", "BaseHTTP/0.6 Python/3.12.13"], ["Date", "Tue, 11 Aug 2026 18:18:12 GMT"], ["Content-Type", "application/json"], ["Content-Length", "8034"]], "status": 200, "status_line": "HTTP/1.1 200 OK"}, "seq": 2, "t_request": 96.69037, "t_response": 96.694744, "unix_request": 1786472292.4732482} +{"conn": 8, "connection": {"keepalive_observed": true, "requests_on_this_connection": 4}, "elapsed_ms": 3.328, "redacted": ["request.X-UT-SID"], "request": {"body_b64": "", "body_len": 0, "headers": [["Host", "10.10.0.120:8099"], ["User-Agent", "ProtoHttp 1.3/DS 15.1.2.1.0 (Windows)"], ["Accept", "application/json"], ["Content-Type", "application/json"], ["X-UT-SID", ""], ["Accept-Encoding", "gzip"]], "method": "GET", "path": "/ut/game/fifa17/tradePile", "query": "", "version": "HTTP/1.1"}, "response": {"body_b64": "eyJhdWN0aW9uSW5mbyI6IFt7InRyYWRlSWQiOiA5MDA1MDAwMDAsICJpdGVtRGF0YSI6IHsiaWQiOiAxMDAwMDAzMTEsICJyZXNvdXJjZUlkIjogMjA4MDEsICJhc3NldElkIjogMjA4MDEsICJjYXJkYXNzZXRpZCI6IDIwODAxLCAiZGVmaW5pdGlvbklkIjogMjA4MDEsICJjYXJkc3VidHlwZWlkIjogMCwgIml0ZW1UeXBlIjogInBsYXllciIsICJyYXJlZmxhZyI6IDEsICJyYXRpbmciOiA5NCwgInByZWZlcnJlZFBvc2l0aW9uIjogIkxXIiwgIm5hdGlvbiI6IDM4LCAidGVhbWlkIjogMjQzLCAibGVhZ3VlSWQiOiA1MywgInBsYXlTdHlsZSI6IDI1MCwgImF0dHJpYnV0ZUxpc3QiOiBbeyJpbmRleCI6IDAsICJ2YWx1ZSI6IDkyfSwgeyJpbmRleCI6IDEsICJ2YWx1ZSI6IDkyfSwgeyJpbmRleCI6IDIsICJ2YWx1ZSI6IDgxfSwgeyJpbmRleCI6IDMsICJ2YWx1ZSI6IDkxfSwgeyJpbmRleCI6IDQsICJ2YWx1ZSI6IDMzfSwgeyJpbmRleCI6IDUsICJ2YWx1ZSI6IDgwfV0sICJpdGVtU3RhdGUiOiAibGlzdEZTIiwgIm93bmVycyI6IDEsICJ1bnRyYWRlYWJsZSI6IGZhbHNlLCAiY29udHJhY3QiOiA3LCAiZml0bmVzcyI6IDk5LCAiZGlzY2FyZFZhbHVlIjogNzUyLCAicGlsZSI6ICJ0cmFkZSJ9LCAidHJhZGVTdGF0ZSI6ICJhY3RpdmUiLCAiYnV5Tm93UHJpY2UiOiAxNTAwMCwgInN0YXJ0aW5nQmlkIjogMTUwLCAiY3VycmVudEJpZCI6IDAsICJiaWRTdGF0ZSI6ICJub25lIiwgImV4cGlyZXMiOiAzNjAwLCAic2VsbGVyTmFtZSI6ICJDQUdFIiwgInNlbGxlckVzdGFibGlzaGVkIjogMSwgIndhdGNoZWQiOiBmYWxzZSwgImNvaW5zUHJvY2Vzc2VkIjogMH1dLCAiY3JlZGl0cyI6IDI3OTk1NjU2LCAidG90YWwiOiAxfQ==", "body_len": 862, "headers": [["Server", "BaseHTTP/0.6 Python/3.12.13"], ["Date", "Tue, 11 Aug 2026 18:18:12 GMT"], ["Content-Type", "application/json"], ["Content-Length", "862"]], "status": 200, "status_line": "HTTP/1.1 200 OK"}, "seq": 3, "t_request": 96.751829, "t_response": 96.755157, "unix_request": 1786472292.5347033} +{"conn": 8, "connection": {"keepalive_observed": true, "requests_on_this_connection": 4}, "elapsed_ms": 0.835, "redacted": ["request.X-UT-SID"], "request": {"body_b64": "", "body_len": 0, "headers": [["Host", "10.10.0.120:8099"], ["User-Agent", "ProtoHttp 1.3/DS 15.1.2.1.0 (Windows)"], ["Accept", "application/json"], ["Content-Type", "application/json"], ["X-UT-SID", ""], ["Accept-Encoding", "gzip"]], "method": "GET", "path": "/ut/game/fifa17/purchased/items", "query": "", "version": "HTTP/1.1"}, "response": {"body_b64": "eyJpdGVtRGF0YSI6IFt7ImlkIjogMTAwMDA0NjA2LCAicmVzb3VyY2VJZCI6IDEzNDQyMjkyMiwgImFzc2V0SWQiOiAyMDUxOTQsICJjYXJkYXNzZXRpZCI6IDIwNTE5NCwgImRlZmluaXRpb25JZCI6IDEzNDQyMjkyMiwgImNhcmRzdWJ0eXBlaWQiOiAwLCAiaXRlbVR5cGUiOiAicGxheWVyIiwgInJhcmVmbGFnIjogMjMsICJyYXRpbmciOiA3OCwgInByZWZlcnJlZFBvc2l0aW9uIjogIkNCIiwgIm5hdGlvbiI6IDU0LCAidGVhbWlkIjogMjM3LCAibGVhZ3VlSWQiOiAzMDgsICJwbGF5U3R5bGUiOiAyNTAsICJhdHRyaWJ1dGVMaXN0IjogW3siaW5kZXgiOiAwLCAidmFsdWUiOiA2Mn0sIHsiaW5kZXgiOiAxLCAidmFsdWUiOiA0MH0sIHsiaW5kZXgiOiAyLCAidmFsdWUiOiA1OX0sIHsiaW5kZXgiOiAzLCAidmFsdWUiOiA2M30sIHsiaW5kZXgiOiA0LCAidmFsdWUiOiA3OX0sIHsiaW5kZXgiOiA1LCAidmFsdWUiOiA3N31dLCAiaXRlbVN0YXRlIjogImZyZWUiLCAib3duZXJzIjogMSwgInVudHJhZGVhYmxlIjogZmFsc2UsICJjb250cmFjdCI6IDcsICJmaXRuZXNzIjogOTksICJkaXNjYXJkVmFsdWUiOiA5NTE2fSwgeyJpZCI6IDEwMDAwNDYxNCwgInJlc291cmNlSWQiOiAxNTExNzgwNTIsICJhc3NldElkIjogMTgzMTA4LCAiY2FyZGFzc2V0aWQiOiAxODMxMDgsICJkZWZpbml0aW9uSWQiOiAxNTExNzgwNTIsICJjYXJkc3VidHlwZWlkIjogMCwgIml0ZW1UeXBlIjogInBsYXllciIsICJyYXJlZmxhZyI6IDI0LCAicmF0aW5nIjogODMsICJwcmVmZXJyZWRQb3NpdGlvbiI6ICJTVCIsICJuYXRpb24iOiAxMjksICJ0ZWFtaWQiOiAxNzk1LCAibGVhZ3VlSWQiOiAxMywgInBsYXlTdHlsZSI6IDI1MCwgImF0dHJpYnV0ZUxpc3QiOiBbeyJpbmRleCI6IDAsICJ2YWx1ZSI6IDkwfSwgeyJpbmRleCI6IDEsICJ2YWx1ZSI6IDgwfSwgeyJpbmRleCI6IDIsICJ2YWx1ZSI6IDgyfSwgeyJpbmRleCI6IDMsICJ2YWx1ZSI6IDg4fSwgeyJpbmRleCI6IDQsICJ2YWx1ZSI6IDQyfSwgeyJpbmRleCI6IDUsICJ2YWx1ZSI6IDc2fV0sICJpdGVtU3RhdGUiOiAiZnJlZSIsICJvd25lcnMiOiAxLCAidW50cmFkZWFibGUiOiBmYWxzZSwgImNvbnRyYWN0IjogNywgImZpdG5lc3MiOiA5OSwgImRpc2NhcmRWYWx1ZSI6IDEwMTI2fSwgeyJpZCI6IDEwMDAwNDYxMSwgInJlc291cmNlSWQiOiAxNjk4OTM2NiwgImFzc2V0SWQiOiAyMTIxNTAsICJjYXJkYXNzZXRpZCI6IDIxMjE1MCwgImRlZmluaXRpb25JZCI6IDE2OTg5MzY2LCAiY2FyZHN1YnR5cGVpZCI6IDAsICJpdGVtVHlwZSI6ICJwbGF5ZXIiLCAicmFyZWZsYWciOiAzLCAicmF0aW5nIjogODIsICJwcmVmZXJyZWRQb3NpdGlvbiI6ICJDQU0iLCAibmF0aW9uIjogMjEsICJ0ZWFtaWQiOiAzNCwgImxlYWd1ZUlkIjogMTksICJwbGF5U3R5bGUiOiAyNTAsICJhdHRyaWJ1dGVMaXN0IjogW3siaW5kZXgiOiAwLCAidmFsdWUiOiA3N30sIHsiaW5kZXgiOiAxLCAidmFsdWUiOiA2Nn0sIHsiaW5kZXgiOiAyLCAidmFsdWUiOiA4MH0sIHsiaW5kZXgiOiAzLCAidmFsdWUiOiA4N30sIHsiaW5kZXgiOiA0LCAidmFsdWUiOiAzN30sIHsiaW5kZXgiOiA1LCAidmFsdWUiOiA1Nn1dLCAiaXRlbVN0YXRlIjogImZyZWUiLCAib3duZXJzIjogMSwgInVudHJhZGVhYmxlIjogZmFsc2UsICJjb250cmFjdCI6IDcsICJmaXRuZXNzIjogOTksICJkaXNjYXJkVmFsdWUiOiAxMDAwNH0sIHsiaWQiOiAxMDAwMDQ2MDksICJyZXNvdXJjZUlkIjogMTAwODc3OTAxLCAiYXNzZXRJZCI6IDIxNDYwNSwgImNhcmRhc3NldGlkIjogMjE0NjA1LCAiZGVmaW5pdGlvbklkIjogMTAwODc3OTAxLCAiY2FyZHN1YnR5cGVpZCI6IDAsICJpdGVtVHlwZSI6ICJwbGF5ZXIiLCAicmFyZWZsYWciOiAyMSwgInJhdGluZyI6IDc5LCAicHJlZmVycmVkUG9zaXRpb24iOiAiQ0RNIiwgIm5hdGlvbiI6IDU2LCAidGVhbWlkIjogMTEwNzgxLCAibGVhZ3VlSWQiOiAzNDEsICJwbGF5U3R5bGUiOiAyNTAsICJhdHRyaWJ1dGVMaXN0IjogW3siaW5kZXgiOiAwLCAidmFsdWUiOiA2Nn0sIHsiaW5kZXgiOiAxLCAidmFsdWUiOiA0OH0sIHsiaW5kZXgiOiAyLCAidmFsdWUiOiA2OH0sIHsiaW5kZXgiOiAzLCAidmFsdWUiOiA2Mn0sIHsiaW5kZXgiOiA0LCAidmFsdWUiOiA3NX0sIHsiaW5kZXgiOiA1LCAidmFsdWUiOiA4Nn1dLCAiaXRlbVN0YXRlIjogImZyZWUiLCAib3duZXJzIjogMSwgInVudHJhZGVhYmxlIjogZmFsc2UsICJjb250cmFjdCI6IDcsICJmaXRuZXNzIjogOTksICJkaXNjYXJkVmFsdWUiOiA5NjM4fSwgeyJpZCI6IDEwMDAwNDYxMywgInJlc291cmNlSWQiOiAxMTc2MzE1NjUsICJhc3NldElkIjogMTkxMDUzLCAiY2FyZGFzc2V0aWQiOiAxOTEwNTMsICJkZWZpbml0aW9uSWQiOiAxMTc2MzE1NjUsICJjYXJkc3VidHlwZWlkIjogMCwgIml0ZW1UeXBlIjogInBsYXllciIsICJyYXJlZmxhZyI6IDIyLCAicmF0aW5nIjogNzksICJwcmVmZXJyZWRQb3NpdGlvbiI6ICJDTSIsICJuYXRpb24iOiA2MSwgInRlYW1pZCI6IDExMDU1NiwgImxlYWd1ZUlkIjogMzEsICJwbGF5U3R5bGUiOiAyNTAsICJhdHRyaWJ1dGVMaXN0IjogW3siaW5kZXgiOiAwLCAidmFsdWUiOiA3NX0sIHsiaW5kZXgiOiAxLCAidmFsdWUiOiA2N30sIHsiaW5kZXgiOiAyLCAidmFsdWUiOiA3Nn0sIHsiaW5kZXgiOiAzLCAidmFsdWUiOiA3Nn0sIHsiaW5kZXgiOiA0LCAidmFsdWUiOiA3N30sIHsiaW5kZXgiOiA1LCAidmFsdWUiOiA4MX1dLCAiaXRlbVN0YXRlIjogImZyZWUiLCAib3duZXJzIjogMSwgInVudHJhZGVhYmxlIjogZmFsc2UsICJjb250cmFjdCI6IDcsICJmaXRuZXNzIjogOTksICJkaXNjYXJkVmFsdWUiOiA5NjM4fSwgeyJpZCI6IDEwMDAwNDYwOCwgInJlc291cmNlSWQiOiAxMTc2MjQ5ODQsICJhc3NldElkIjogMTg0NDcyLCAiY2FyZGFzc2V0aWQiOiAxODQ0NzIsICJkZWZpbml0aW9uSWQiOiAxMTc2MjQ5ODQsICJjYXJkc3VidHlwZWlkIjogMCwgIml0ZW1UeXBlIjogInBsYXllciIsICJyYXJlZmxhZyI6IDIyLCAicmF0aW5nIjogNzgsICJwcmVmZXJyZWRQb3NpdGlvbiI6ICJMQiIsICJuYXRpb24iOiA0NiwgInRlYW1pZCI6IDE3OTIsICJsZWFndWVJZCI6IDE0LCAicGxheVN0eWxlIjogMjUwLCAiYXR0cmlidXRlTGlzdCI6IFt7ImluZGV4IjogMCwgInZhbHVlIjogODZ9LCB7ImluZGV4IjogMSwgInZhbHVlIjogNjV9LCB7ImluZGV4IjogMiwgInZhbHVlIjogNzB9LCB7ImluZGV4IjogMywgInZhbHVlIjogNzR9LCB7ImluZGV4IjogNCwgInZhbHVlIjogNzV9LCB7ImluZGV4IjogNSwgInZhbHVlIjogNzl9XSwgIml0ZW1TdGF0ZSI6ICJmcmVlIiwgIm93bmVycyI6IDEsICJ1bnRyYWRlYWJsZSI6IGZhbHNlLCAiY29udHJhY3QiOiA3LCAiZml0bmVzcyI6IDk5LCAiZGlzY2FyZFZhbHVlIjogOTUxNn0sIHsiaWQiOiAxMDAwMDQ2MTUsICJyZXNvdXJjZUlkIjogMTAwODQ3NzI3LCAiYXNzZXRJZCI6IDE4NDQzMSwgImNhcmRhc3NldGlkIjogMTg0NDMxLCAiZGVmaW5pdGlvbklkIjogMTAwODQ3NzI3LCAiY2FyZHN1YnR5cGVpZCI6IDAsICJpdGVtVHlwZSI6ICJwbGF5ZXIiLCAicmFyZWZsYWciOiAyMSwgInJhdGluZyI6IDg1LCAicHJlZmVycmVkUG9zaXRpb24iOiAiQ0YiLCAibmF0aW9uIjogMjcsICJ0ZWFtaWQiOiAxMTE2NTEsICJsZWFndWVJZCI6IDM5LCAicGxheVN0eWxlIjogMjUwLCAiYXR0cmlidXRlTGlzdCI6IFt7ImluZGV4IjogMCwgInZhbHVlIjogOTF9LCB7ImluZGV4IjogMSwgInZhbHVlIjogODF9LCB7ImluZGV4IjogMiwgInZhbHVlIjogODB9LCB7ImluZGV4IjogMywgInZhbHVlIjogODl9LCB7ImluZGV4IjogNCwgInZhbHVlIjogMjh9LCB7ImluZGV4IjogNSwgInZhbHVlIjogNjJ9XSwgIml0ZW1TdGF0ZSI6ICJmcmVlIiwgIm93bmVycyI6IDEsICJ1bnRyYWRlYWJsZSI6IGZhbHNlLCAiY29udHJhY3QiOiA3LCAiZml0bmVzcyI6IDk5LCAiZGlzY2FyZFZhbHVlIjogMTAzNzB9LCB7ImlkIjogMTAwMDA0NjEwLCAicmVzb3VyY2VJZCI6IDg0MDc1MTY0LCAiYXNzZXRJZCI6IDE4OTA4NCwgImNhcmRhc3NldGlkIjogMTg5MDg0LCAiZGVmaW5pdGlvbklkIjogODQwNzUxNjQsICJjYXJkc3VidHlwZWlkIjogMCwgIml0ZW1UeXBlIjogInBsYXllciIsICJyYXJlZmxhZyI6IDExLCAicmF0aW5nIjogODAsICJwcmVmZXJyZWRQb3NpdGlvbiI6ICJHSyIsICJuYXRpb24iOiA4NSwgInRlYW1pZCI6IDE5MDksICJsZWFndWVJZCI6IDEwLCAicGxheVN0eWxlIjogMjUwLCAiYXR0cmlidXRlTGlzdCI6IFt7ImluZGV4IjogMCwgInZhbHVlIjogODN9LCB7ImluZGV4IjogMSwgInZhbHVlIjogODJ9LCB7ImluZGV4IjogMiwgInZhbHVlIjogNzd9LCB7ImluZGV4IjogMywgInZhbHVlIjogNzd9LCB7ImluZGV4IjogNCwgInZhbHVlIjogNTB9LCB7ImluZGV4IjogNSwgInZhbHVlIjogNzd9XSwgIml0ZW1TdGF0ZSI6ICJmcmVlIiwgIm93bmVycyI6IDEsICJ1bnRyYWRlYWJsZSI6IGZhbHNlLCAiY29udHJhY3QiOiA3LCAiZml0bmVzcyI6IDk5LCAiZGlzY2FyZFZhbHVlIjogMTkyMDB9LCB7ImlkIjogMTAwMDA0NjEyLCAicmVzb3VyY2VJZCI6IDE3MDAwMjA0LCAiYXNzZXRJZCI6IDIyMjk4OCwgImNhcmRhc3NldGlkIjogMjIyOTg4LCAiZGVmaW5pdGlvbklkIjogMTcwMDAyMDQsICJjYXJkc3VidHlwZWlkIjogMCwgIml0ZW1UeXBlIjogInBsYXllciIsICJyYXJlZmxhZyI6IDMsICJyYXRpbmciOiA3NywgInByZWZlcnJlZFBvc2l0aW9uIjogIkNNIiwgIm5hdGlvbiI6IDE2MywgInRlYW1pZCI6IDExMzE1NywgImxlYWd1ZUlkIjogMzQ5LCAicGxheVN0eWxlIjogMjUwLCAiYXR0cmlidXRlTGlzdCI6IFt7ImluZGV4IjogMCwgInZhbHVlIjogNjF9LCB7ImluZGV4IjogMSwgInZhbHVlIjogNjV9LCB7ImluZGV4IjogMiwgInZhbHVlIjogNzV9LCB7ImluZGV4IjogMywgInZhbHVlIjogNzN9LCB7ImluZGV4IjogNCwgInZhbHVlIjogNjl9LCB7ImluZGV4IjogNSwgInZhbHVlIjogNzh9XSwgIml0ZW1TdGF0ZSI6ICJmcmVlIiwgIm93bmVycyI6IDEsICJ1bnRyYWRlYWJsZSI6IGZhbHNlLCAiY29udHJhY3QiOiA3LCAiZml0bmVzcyI6IDk5LCAiZGlzY2FyZFZhbHVlIjogOTM5NH0sIHsiaWQiOiAxMDAwMDQ2MTYsICJyZXNvdXJjZUlkIjogMTM0NDA4NDQ1LCAiYXNzZXRJZCI6IDE5MDcxNywgImNhcmRhc3NldGlkIjogMTkwNzE3LCAiZGVmaW5pdGlvbklkIjogMTM0NDA4NDQ1LCAiY2FyZHN1YnR5cGVpZCI6IDAsICJpdGVtVHlwZSI6ICJwbGF5ZXIiLCAicmFyZWZsYWciOiAyMywgInJhdGluZyI6IDc5LCAicHJlZmVycmVkUG9zaXRpb24iOiAiUk0iLCAibmF0aW9uIjogMTQsICJ0ZWFtaWQiOiAxOSwgImxlYWd1ZUlkIjogMTMsICJwbGF5U3R5bGUiOiAyNTAsICJhdHRyaWJ1dGVMaXN0IjogW3siaW5kZXgiOiAwLCAidmFsdWUiOiA5MH0sIHsiaW5kZXgiOiAxLCAidmFsdWUiOiA3Nn0sIHsiaW5kZXgiOiAyLCAidmFsdWUiOiA3MH0sIHsiaW5kZXgiOiAzLCAidmFsdWUiOiA4Mn0sIHsiaW5kZXgiOiA0LCAidmFsdWUiOiA1NX0sIHsiaW5kZXgiOiA1LCAidmFsdWUiOiA4M31dLCAiaXRlbVN0YXRlIjogImZyZWUiLCAib3duZXJzIjogMSwgInVudHJhZGVhYmxlIjogZmFsc2UsICJjb250cmFjdCI6IDcsICJmaXRuZXNzIjogOTksICJkaXNjYXJkVmFsdWUiOiA5NjM4fSwgeyJpZCI6IDEwMDAwNDYwNywgInJlc291cmNlSWQiOiAxNTExNjgyNTAsICJhc3NldElkIjogMTczMzA2LCAiY2FyZGFzc2V0aWQiOiAxNzMzMDYsICJkZWZpbml0aW9uSWQiOiAxNTExNjgyNTAsICJjYXJkc3VidHlwZWlkIjogMCwgIml0ZW1UeXBlIjogInBsYXllciIsICJyYXJlZmxhZyI6IDI0LCAicmF0aW5nIjogODQsICJwcmVmZXJyZWRQb3NpdGlvbiI6ICJMQiIsICJuYXRpb24iOiA1MiwgInRlYW1pZCI6IDQ0LCAibGVhZ3VlSWQiOiAzMSwgInBsYXlTdHlsZSI6IDI1MCwgImF0dHJpYnV0ZUxpc3QiOiBbeyJpbmRleCI6IDAsICJ2YWx1ZSI6IDg1fSwgeyJpbmRleCI6IDEsICJ2YWx1ZSI6IDYzfSwgeyJpbmRleCI6IDIsICJ2YWx1ZSI6IDc2fSwgeyJpbmRleCI6IDMsICJ2YWx1ZSI6IDc3fSwgeyJpbmRleCI6IDQsICJ2YWx1ZSI6IDgxfSwgeyJpbmRleCI6IDUsICJ2YWx1ZSI6IDc1fV0sICJpdGVtU3RhdGUiOiAiZnJlZSIsICJvd25lcnMiOiAxLCAidW50cmFkZWFibGUiOiBmYWxzZSwgImNvbnRyYWN0IjogNywgImZpdG5lc3MiOiA5OSwgImRpc2NhcmRWYWx1ZSI6IDEwMjQ4fV19", "body_len": 6234, "headers": [["Server", "BaseHTTP/0.6 Python/3.12.13"], ["Date", "Tue, 11 Aug 2026 18:18:12 GMT"], ["Content-Type", "application/json"], ["Content-Length", "6234"]], "status": 200, "status_line": "HTTP/1.1 200 OK"}, "seq": 4, "t_request": 96.803651, "t_response": 96.804486, "unix_request": 1786472292.5865254} +{"conn": 9, "connection": {"keepalive_observed": true, "requests_on_this_connection": 4}, "elapsed_ms": 79.094, "redacted": ["request.X-UT-SID"], "request": {"body_b64": "eyJpdGVtSWQiOlsxMDAwMDQ2MTAsMTAwMDA0NjE1LDEwMDAwNDYwNywxMDAwMDQ2MTQsMTAwMDA0NjExLDEwMDAwNDYxNiwxMDAwMDQ2MTMsMTAwMDA0NjA5LDEwMDAwNDYwOCwxMDAwMDQ2MDYsMTAwMDA0NjEyXX0=", "body_len": 122, "headers": [["Host", "10.10.0.120:8099"], ["Content-Length", "122"], ["User-Agent", "ProtoHttp 1.3/DS 15.1.2.1.0 (Windows)"], ["Accept", "application/json"], ["Content-Type", "application/json"], ["X-UT-SID", ""]], "method": "POST", "path": "/ut/delete/game/fifa17/item", "query": "", "version": "HTTP/1.1"}, "response": {"body_b64": "eyJpdGVtcyI6IFt7ImlkIjogMTAwMDA0NjEwfSwgeyJpZCI6IDEwMDAwNDYxNX0sIHsiaWQiOiAxMDAwMDQ2MDd9LCB7ImlkIjogMTAwMDA0NjE0fSwgeyJpZCI6IDEwMDAwNDYxMX0sIHsiaWQiOiAxMDAwMDQ2MTZ9LCB7ImlkIjogMTAwMDA0NjEzfSwgeyJpZCI6IDEwMDAwNDYwOX0sIHsiaWQiOiAxMDAwMDQ2MDh9LCB7ImlkIjogMTAwMDA0NjA2fSwgeyJpZCI6IDEwMDAwNDYxMn1dLCAidG90YWxDcmVkaXRzIjogMjgxMTI5NDR9", "body_len": 246, "headers": [["Server", "BaseHTTP/0.6 Python/3.12.13"], ["Date", "Tue, 11 Aug 2026 18:18:16 GMT"], ["Content-Type", "application/json"], ["Content-Length", "246"]], "status": 200, "status_line": "HTTP/1.1 200 OK"}, "seq": 1, "t_request": 101.123351, "t_response": 101.202445, "unix_request": 1786472296.906225} +{"conn": 9, "connection": {"keepalive_observed": true, "requests_on_this_connection": 4}, "elapsed_ms": 0.866, "redacted": ["request.X-UT-SID"], "request": {"body_b64": "", "body_len": 0, "headers": [["Host", "10.10.0.120:8099"], ["User-Agent", "ProtoHttp 1.3/DS 15.1.2.1.0 (Windows)"], ["Accept", "application/json"], ["Content-Type", "application/json"], ["X-UT-SID", ""], ["Accept-Encoding", "gzip"]], "method": "GET", "path": "/ut/game/fifa17/user/credits", "query": "", "version": "HTTP/1.1"}, "response": {"body_b64": "eyJjcmVkaXRzIjogMjgxMTI5NDQsICJjdXJyZW5jaWVzIjogW3sibmFtZSI6ICJjb2lucyIsICJmdW5kcyI6IDI4MTEyOTQ0LCAiZmluYWxGdW5kcyI6IDI4MTEyOTQ0fSwgeyJuYW1lIjogInBvaW50cyIsICJmdW5kcyI6IDAsICJmaW5hbEZ1bmRzIjogMH1dfQ==", "body_len": 148, "headers": [["Server", "BaseHTTP/0.6 Python/3.12.13"], ["Date", "Tue, 11 Aug 2026 18:18:17 GMT"], ["Content-Type", "application/json"], ["Content-Length", "148"]], "status": 200, "status_line": "HTTP/1.1 200 OK"}, "seq": 2, "t_request": 101.921631, "t_response": 101.922497, "unix_request": 1786472297.7045069} +{"conn": 9, "connection": {"keepalive_observed": true, "requests_on_this_connection": 4}, "elapsed_ms": 0.664, "redacted": ["request.X-UT-SID"], "request": {"body_b64": "", "body_len": 0, "headers": [["Host", "10.10.0.120:8099"], ["User-Agent", "ProtoHttp 1.3/DS 15.1.2.1.0 (Windows)"], ["Accept", "application/json"], ["Content-Type", "application/json"], ["X-UT-SID", ""], ["Accept-Encoding", "gzip"]], "method": "GET", "path": "/ut/game/fifa17/store/purchasegroup/all", "query": "ppInfo=true", "version": "HTTP/1.1"}, "response": {"body_b64": "eyJwdXJjaGFzZSI6IFt7ImFzc2V0SWQiOiAxLCAiaWQiOiAxLCAicGFja1R5cGUiOiAiQlJPTlpFIiwgImRlc2NyaXB0aW9uIjogIkJyb256ZSBQYWNrIiwgInN0YXRlIjogImFjdGl2ZSIsICJzYWxlVHlwZSI6ICJwcm9tbyIsICJsaW1pdFR5cGUiOiAiTk9ORSIsICJxdWFudGl0eSI6IDAsICJwdXJjaGFzZUxpbWl0IjogMCwgInB1cmNoYXNlQ291bnQiOiAwLCAiaXNQcmVtaXVtIjogZmFsc2UsICJzb3J0UHJpb3JpdHkiOiAxLCAiY3VycmVuY2llcyI6IFt7Im5hbWUiOiAiY29pbnMiLCAiZnVuZHMiOiA0MDAsICJmaW5hbEZ1bmRzIjogNDAwfV0sICJleHRQcmljZSI6IHsiZmluYWxQcmljZSI6IHsiYW1vdW50IjogNCwgImN1cnJlbmN5IjogIm10eCJ9LCAib3JpZ2luYWxQcmljZSI6IHsiYW1vdW50IjogNCwgImN1cnJlbmN5IjogIm10eCJ9fSwgInBhY2tDb250ZW50SW5mbyI6IHsiYnJvbnplUXVhbnRpdHkiOiA1LCAic2lsdmVyUXVhbnRpdHkiOiAwLCAiZ29sZFF1YW50aXR5IjogMCwgInJhcmVRdWFudGl0eSI6IDAsICJpdGVtUXVhbnRpdHkiOiA1fSwgInVub3BlbmVkIjogZmFsc2UsICJkaXNwbGF5R3JvdXAiOiB7InZhbHVlIjogImJyb256ZSJ9fSwgeyJhc3NldElkIjogNSwgImlkIjogNSwgInBhY2tUeXBlIjogIkdPTEQiLCAiZGVzY3JpcHRpb24iOiAiR29sZCBQYWNrIiwgInN0YXRlIjogImFjdGl2ZSIsICJzYWxlVHlwZSI6ICJwcm9tbyIsICJsaW1pdFR5cGUiOiAiTk9ORSIsICJxdWFudGl0eSI6IDAsICJwdXJjaGFzZUxpbWl0IjogMCwgInB1cmNoYXNlQ291bnQiOiAwLCAiaXNQcmVtaXVtIjogZmFsc2UsICJzb3J0UHJpb3JpdHkiOiAyLCAiY3VycmVuY2llcyI6IFt7Im5hbWUiOiAiY29pbnMiLCAiZnVuZHMiOiA1MDAwLCAiZmluYWxGdW5kcyI6IDUwMDB9XSwgImV4dFByaWNlIjogeyJmaW5hbFByaWNlIjogeyJhbW91bnQiOiA1MCwgImN1cnJlbmN5IjogIm10eCJ9LCAib3JpZ2luYWxQcmljZSI6IHsiYW1vdW50IjogNTAsICJjdXJyZW5jeSI6ICJtdHgifX0sICJwYWNrQ29udGVudEluZm8iOiB7ImJyb256ZVF1YW50aXR5IjogMCwgInNpbHZlclF1YW50aXR5IjogMCwgImdvbGRRdWFudGl0eSI6IDcsICJyYXJlUXVhbnRpdHkiOiA3LCAiaXRlbVF1YW50aXR5IjogN30sICJ1bm9wZW5lZCI6IGZhbHNlLCAiZGlzcGxheUdyb3VwIjogeyJ2YWx1ZSI6ICJnb2xkIn19LCB7ImFzc2V0SWQiOiA2LCAiaWQiOiA2LCAicGFja1R5cGUiOiAiR09MRCIsICJkZXNjcmlwdGlvbiI6ICJQcmVtaXVtIEdvbGQiLCAic3RhdGUiOiAiYWN0aXZlIiwgInNhbGVUeXBlIjogInByb21vIiwgImxpbWl0VHlwZSI6ICJOT05FIiwgInF1YW50aXR5IjogMCwgInB1cmNoYXNlTGltaXQiOiAwLCAicHVyY2hhc2VDb3VudCI6IDAsICJpc1ByZW1pdW0iOiBmYWxzZSwgInNvcnRQcmlvcml0eSI6IDMsICJjdXJyZW5jaWVzIjogW3sibmFtZSI6ICJjb2lucyIsICJmdW5kcyI6IDE1MDAwLCAiZmluYWxGdW5kcyI6IDE1MDAwfV0sICJleHRQcmljZSI6IHsiZmluYWxQcmljZSI6IHsiYW1vdW50IjogMTUwLCAiY3VycmVuY3kiOiAibXR4In0sICJvcmlnaW5hbFByaWNlIjogeyJhbW91bnQiOiAxNTAsICJjdXJyZW5jeSI6ICJtdHgifX0sICJwYWNrQ29udGVudEluZm8iOiB7ImJyb256ZVF1YW50aXR5IjogMCwgInNpbHZlclF1YW50aXR5IjogMCwgImdvbGRRdWFudGl0eSI6IDExLCAicmFyZVF1YW50aXR5IjogMTEsICJpdGVtUXVhbnRpdHkiOiAxMX0sICJ1bm9wZW5lZCI6IGZhbHNlLCAiZGlzcGxheUdyb3VwIjogeyJ2YWx1ZSI6ICJnb2xkIn19LCB7ImFzc2V0SWQiOiA3LCAiaWQiOiA3LCAicGFja1R5cGUiOiAiR09MRCIsICJkZXNjcmlwdGlvbiI6ICJTcGVjaWFsIFBsYXllcnMgUGFjayIsICJzdGF0ZSI6ICJhY3RpdmUiLCAic2FsZVR5cGUiOiAicHJvbW8iLCAibGltaXRUeXBlIjogIk5PTkUiLCAicXVhbnRpdHkiOiAwLCAicHVyY2hhc2VMaW1pdCI6IDAsICJwdXJjaGFzZUNvdW50IjogMCwgImlzUHJlbWl1bSI6IGZhbHNlLCAic29ydFByaW9yaXR5IjogNCwgImN1cnJlbmNpZXMiOiBbeyJuYW1lIjogImNvaW5zIiwgImZ1bmRzIjogMjUwMDAsICJmaW5hbEZ1bmRzIjogMjUwMDB9XSwgImV4dFByaWNlIjogeyJmaW5hbFByaWNlIjogeyJhbW91bnQiOiAyNTAsICJjdXJyZW5jeSI6ICJtdHgifSwgIm9yaWdpbmFsUHJpY2UiOiB7ImFtb3VudCI6IDI1MCwgImN1cnJlbmN5IjogIm10eCJ9fSwgInBhY2tDb250ZW50SW5mbyI6IHsiYnJvbnplUXVhbnRpdHkiOiAwLCAic2lsdmVyUXVhbnRpdHkiOiAwLCAiZ29sZFF1YW50aXR5IjogMTEsICJyYXJlUXVhbnRpdHkiOiAxMSwgIml0ZW1RdWFudGl0eSI6IDExfSwgInVub3BlbmVkIjogZmFsc2UsICJkaXNwbGF5R3JvdXAiOiB7InZhbHVlIjogInNwZWNpYWwifX0sIHsiYXNzZXRJZCI6IDcsICJpZCI6IDcsICJwYWNrVHlwZSI6ICJHT0xEIiwgImRlc2NyaXB0aW9uIjogIlNwZWNpYWwgUGxheWVycyBQYWNrIiwgInN0YXRlIjogImFjdGl2ZSIsICJzYWxlVHlwZSI6ICJwcm9tbyIsICJsaW1pdFR5cGUiOiAiTk9ORSIsICJxdWFudGl0eSI6IDAsICJwdXJjaGFzZUxpbWl0IjogMCwgInB1cmNoYXNlQ291bnQiOiAwLCAiaXNQcmVtaXVtIjogZmFsc2UsICJzb3J0UHJpb3JpdHkiOiAxLCAicGFja0NvbnRlbnRJbmZvIjogeyJicm9uemVRdWFudGl0eSI6IDAsICJzaWx2ZXJRdWFudGl0eSI6IDAsICJnb2xkUXVhbnRpdHkiOiAxMSwgInJhcmVRdWFudGl0eSI6IDExLCAiaXRlbVF1YW50aXR5IjogMTF9LCAidW5vcGVuZWQiOiB0cnVlLCAiZGlzcGxheUdyb3VwIjogeyJ2YWx1ZSI6ICJteXBhY2tzIiwgInByaW9yaXR5IjogMX19XSwgInRpbWVzdGFtcCI6IDE1OTYzMjY0MDB9", "body_len": 2853, "headers": [["Server", "BaseHTTP/0.6 Python/3.12.13"], ["Date", "Tue, 11 Aug 2026 18:18:17 GMT"], ["Content-Type", "application/json"], ["Content-Length", "2853"]], "status": 200, "status_line": "HTTP/1.1 200 OK"}, "seq": 3, "t_request": 101.968864, "t_response": 101.969528, "unix_request": 1786472297.751733} +{"conn": 9, "connection": {"keepalive_observed": true, "requests_on_this_connection": 4}, "elapsed_ms": 3.826, "redacted": ["request.X-UT-SID"], "request": {"body_b64": "", "body_len": 0, "headers": [["Host", "10.10.0.120:8099"], ["User-Agent", "ProtoHttp 1.3/DS 15.1.2.1.0 (Windows)"], ["Accept", "application/json"], ["Content-Type", "application/json"], ["X-UT-SID", ""], ["Accept-Encoding", "gzip"]], "method": "GET", "path": "/ut/game/fifa17/hub", "query": "", "version": "HTTP/1.1"}, "response": {"body_b64": "eyJjbHViUGxheWVycyI6IDE5NjIsICJhdWN0aW9uQ291bnQiOiAxLCAidHJhZGVQaWxlIjogeyJjb3VudCI6IDEsICJzZWxsaW5nIjogMSwgInNvbGQiOiAwfSwgIm9mZmxpbmVTZWFzb24iOiB7ImRpdmlzaW9uSWQiOiAiMTAiLCAiZ2FtZXNQbGF5ZWQiOiAiMCIsICJwb2ludHMiOiAiMCIsICJ0b3RhbEdhbWVzIjogIjEwIiwgInByb2dyZXNzRGF0YVZlcnNpb24iOiAiMCJ9fQ==", "body_len": 214, "headers": [["Server", "BaseHTTP/0.6 Python/3.12.13"], ["Date", "Tue, 11 Aug 2026 18:18:19 GMT"], ["Content-Type", "application/json"], ["Content-Length", "214"]], "status": 200, "status_line": "HTTP/1.1 200 OK"}, "seq": 4, "t_request": 103.387746, "t_response": 103.391572, "unix_request": 1786472299.1706216} +{"conn": 10, "connection": {"keepalive_observed": true, "requests_on_this_connection": 2}, "elapsed_ms": 76.617, "redacted": ["request.X-UT-SID"], "request": {"body_b64": "eyJpZCI6MCwiY3VzdG9tIjoiWzAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsNTAsNTAsMCw1MCw0MCw2NSwwLDY1LDUwLDUwLDFdIiwic3F1YWROYW1lIjoiT3BlbkZVVCIsImNoZW1pc3RyeSI6NTIsInN0YXJSYXRpbmciOjkwLCJyYXRpbmciOjkwLCJmb3JtYXRpb24iOiJmNDQyIiwic3F1YWRUeXBlIjoiUkVHVUxBUl9TUVVBRCIsIm1hbmFnZXIiOlt7ImlkIjoxMDAwMDA0MjcsImRyZWFtIjpmYWxzZX1dLCJwbGF5ZXJzIjpbeyJpbmRleCI6MCwiaXRlbURhdGEiOnsiaWQiOjEwMDAwMDAwMywiZHJlYW0iOmZhbHNlfSwia2l0TnVtYmVyIjoxfSx7ImluZGV4IjoxLCJpdGVtRGF0YSI6eyJpZCI6MTAwMDAwMDEwLCJkcmVhbSI6ZmFsc2V9LCJraXROdW1iZXIiOjEwfSx7ImluZGV4IjoyLCJpdGVtRGF0YSI6eyJpZCI6MTAwMDAwMDA1LCJkcmVhbSI6ZmFsc2V9LCJraXROdW1iZXIiOjN9LHsiaW5kZXgiOjMsIml0ZW1EYXRhIjp7ImlkIjoxMDAwMDAwMDgsImRyZWFtIjpmYWxzZX0sImtpdE51bWJlciI6Nn0seyJpbmRleCI6NCwiaXRlbURhdGEiOnsiaWQiOjEwMDAwMDAwNywiZHJlYW0iOmZhbHNlfSwia2l0TnVtYmVyIjo1fSx7ImluZGV4Ijo1LCJpdGVtRGF0YSI6eyJpZCI6MTAwMDAwMDA2LCJkcmVhbSI6ZmFsc2V9LCJraXROdW1iZXIiOjR9LHsiaW5kZXgiOjYsIml0ZW1EYXRhIjp7ImlkIjoxMDAwMDAwMDQsImRyZWFtIjpmYWxzZX0sImtpdE51bWJlciI6Mn0seyJpbmRleCI6NywiaXRlbURhdGEiOnsiaWQiOjEwMDAwMDAwOSwiZHJlYW0iOmZhbHNlfSwia2l0TnVtYmVyIjo3fSx7ImluZGV4Ijo4LCJpdGVtRGF0YSI6eyJpZCI6MTAwMDAwMDAxLCJkcmVhbSI6ZmFsc2V9LCJraXROdW1iZXIiOjh9LHsiaW5kZXgiOjksIml0ZW1EYXRhIjp7ImlkIjoxMDAwMDAwMDIsImRyZWFtIjpmYWxzZX0sImtpdE51bWJlciI6OX0seyJpbmRleCI6MTAsIml0ZW1EYXRhIjp7ImlkIjoxMDAwMDAwMjUsImRyZWFtIjpmYWxzZX0sImtpdE51bWJlciI6MTF9LHsiaW5kZXgiOjExLCJpdGVtRGF0YSI6eyJpZCI6MCwiZHJlYW0iOmZhbHNlfSwia2l0TnVtYmVyIjowfSx7ImluZGV4IjoxMiwiaXRlbURhdGEiOnsiaWQiOjAsImRyZWFtIjpmYWxzZX0sImtpdE51bWJlciI6MH0seyJpbmRleCI6MTMsIml0ZW1EYXRhIjp7ImlkIjowLCJkcmVhbSI6ZmFsc2V9LCJraXROdW1iZXIiOjB9LHsiaW5kZXgiOjE0LCJpdGVtRGF0YSI6eyJpZCI6MCwiZHJlYW0iOmZhbHNlfSwia2l0TnVtYmVyIjowfSx7ImluZGV4IjoxNSwiaXRlbURhdGEiOnsiaWQiOjAsImRyZWFtIjpmYWxzZX0sImtpdE51bWJlciI6MH0seyJpbmRleCI6MTYsIml0ZW1EYXRhIjp7ImlkIjowLCJkcmVhbSI6ZmFsc2V9LCJraXROdW1iZXIiOjB9LHsiaW5kZXgiOjE3LCJpdGVtRGF0YSI6eyJpZCI6MCwiZHJlYW0iOmZhbHNlfSwia2l0TnVtYmVyIjowfSx7ImluZGV4IjoxOCwiaXRlbURhdGEiOnsiaWQiOjAsImRyZWFtIjpmYWxzZX0sImtpdE51bWJlciI6MH0seyJpbmRleCI6MTksIml0ZW1EYXRhIjp7ImlkIjowLCJkcmVhbSI6ZmFsc2V9LCJraXROdW1iZXIiOjB9LHsiaW5kZXgiOjIwLCJpdGVtRGF0YSI6eyJpZCI6MCwiZHJlYW0iOmZhbHNlfSwia2l0TnVtYmVyIjowfSx7ImluZGV4IjoyMSwiaXRlbURhdGEiOnsiaWQiOjAsImRyZWFtIjpmYWxzZX0sImtpdE51bWJlciI6MH0seyJpbmRleCI6MjIsIml0ZW1EYXRhIjp7ImlkIjowLCJkcmVhbSI6ZmFsc2V9LCJraXROdW1iZXIiOjB9XSwiY2FwdGFpbiI6MTAwMDAwMDAxLCJraWNrdGFrZXJzIjpbeyJpbmRleCI6MCwiaWQiOjEwMDAwMDAwMSwiZHJlYW0iOmZhbHNlfSx7ImluZGV4IjoxLCJpZCI6MTAwMDAwMDAxLCJkcmVhbSI6ZmFsc2V9LHsiaW5kZXgiOjIsImlkIjoxMDAwMDAwMDEsImRyZWFtIjpmYWxzZX0seyJpbmRleCI6MywiaWQiOjEwMDAwMDAwMSwiZHJlYW0iOmZhbHNlfSx7ImluZGV4Ijo0LCJpZCI6MTAwMDAwMDAxLCJkcmVhbSI6ZmFsc2V9XX0=", "body_len": 1985, "headers": [["Host", "10.10.0.120:8099"], ["Content-Length", "1985"], ["User-Agent", "ProtoHttp 1.3/DS 15.1.2.1.0 (Windows)"], ["Accept", "application/json"], ["Content-Type", "application/json"], ["X-UT-SID", ""]], "method": "PUT", "path": "/ut/game/fifa17/squad/0", "query": "", "version": "HTTP/1.1"}, "response": {"body_b64": "eyJpZCI6IDB9", "body_len": 9, "headers": [["Server", "BaseHTTP/0.6 Python/3.12.13"], ["Date", "Tue, 11 Aug 2026 18:19:56 GMT"], ["Content-Type", "application/json"], ["Content-Length", "9"]], "status": 200, "status_line": "HTTP/1.1 200 OK"}, "seq": 1, "t_request": 200.387247, "t_response": 200.463864, "unix_request": 1786472396.170115} +{"conn": 10, "connection": {"keepalive_observed": true, "requests_on_this_connection": 2}, "elapsed_ms": 3.618, "redacted": ["request.X-UT-SID"], "request": {"body_b64": "", "body_len": 0, "headers": [["Host", "10.10.0.120:8099"], ["User-Agent", "ProtoHttp 1.3/DS 15.1.2.1.0 (Windows)"], ["Accept", "application/json"], ["Content-Type", "application/json"], ["X-UT-SID", ""], ["Accept-Encoding", "gzip"]], "method": "GET", "path": "/ut/game/fifa17/hub", "query": "", "version": "HTTP/1.1"}, "response": {"body_b64": "eyJjbHViUGxheWVycyI6IDE5NjIsICJhdWN0aW9uQ291bnQiOiAxLCAidHJhZGVQaWxlIjogeyJjb3VudCI6IDEsICJzZWxsaW5nIjogMSwgInNvbGQiOiAwfSwgIm9mZmxpbmVTZWFzb24iOiB7ImRpdmlzaW9uSWQiOiAiMTAiLCAiZ2FtZXNQbGF5ZWQiOiAiMCIsICJwb2ludHMiOiAiMCIsICJ0b3RhbEdhbWVzIjogIjEwIiwgInByb2dyZXNzRGF0YVZlcnNpb24iOiAiMCJ9fQ==", "body_len": 214, "headers": [["Server", "BaseHTTP/0.6 Python/3.12.13"], ["Date", "Tue, 11 Aug 2026 18:19:56 GMT"], ["Content-Type", "application/json"], ["Content-Length", "214"]], "status": 200, "status_line": "HTTP/1.1 200 OK"}, "seq": 2, "t_request": 200.935413, "t_response": 200.939031, "unix_request": 1786472396.718291} +{"conn": 11, "connection": {"keepalive_observed": true, "requests_on_this_connection": 2}, "elapsed_ms": 75.804, "redacted": ["request.X-UT-SID"], "request": {"body_b64": "eyJpZCI6MCwiY3VzdG9tIjoiWzAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsNTAsNTAsMCw1MCw0MCw2NSwwLDY1LDUwLDUwLDFdIiwic3F1YWROYW1lIjoiT3BlbkZVVCIsImNoZW1pc3RyeSI6NTksInN0YXJSYXRpbmciOjkwLCJyYXRpbmciOjkwLCJmb3JtYXRpb24iOiJmNDQyIiwic3F1YWRUeXBlIjoiUkVHVUxBUl9TUVVBRCIsIm1hbmFnZXIiOlt7ImlkIjoxMDAwMDA0MjcsImRyZWFtIjpmYWxzZX1dLCJwbGF5ZXJzIjpbeyJpbmRleCI6MCwiaXRlbURhdGEiOnsiaWQiOjEwMDAwMDAwMywiZHJlYW0iOmZhbHNlfSwia2l0TnVtYmVyIjoxfSx7ImluZGV4IjoxLCJpdGVtRGF0YSI6eyJpZCI6MTAwMDAwMDA2LCJkcmVhbSI6ZmFsc2V9LCJraXROdW1iZXIiOjR9LHsiaW5kZXgiOjIsIml0ZW1EYXRhIjp7ImlkIjoxMDAwMDAwMDUsImRyZWFtIjpmYWxzZX0sImtpdE51bWJlciI6M30seyJpbmRleCI6MywiaXRlbURhdGEiOnsiaWQiOjEwMDAwMDAwOCwiZHJlYW0iOmZhbHNlfSwia2l0TnVtYmVyIjo2fSx7ImluZGV4Ijo0LCJpdGVtRGF0YSI6eyJpZCI6MTAwMDAwMDA3LCJkcmVhbSI6ZmFsc2V9LCJraXROdW1iZXIiOjV9LHsiaW5kZXgiOjUsIml0ZW1EYXRhIjp7ImlkIjoxMDAwMDAwMDIsImRyZWFtIjpmYWxzZX0sImtpdE51bWJlciI6OX0seyJpbmRleCI6NiwiaXRlbURhdGEiOnsiaWQiOjEwMDAwMDAwNCwiZHJlYW0iOmZhbHNlfSwia2l0TnVtYmVyIjoyfSx7ImluZGV4Ijo3LCJpdGVtRGF0YSI6eyJpZCI6MTAwMDAwMDA5LCJkcmVhbSI6ZmFsc2V9LCJraXROdW1iZXIiOjd9LHsiaW5kZXgiOjgsIml0ZW1EYXRhIjp7ImlkIjoxMDAwMDAwMDEsImRyZWFtIjpmYWxzZX0sImtpdE51bWJlciI6OH0seyJpbmRleCI6OSwiaXRlbURhdGEiOnsiaWQiOjEwMDAwMDAyNSwiZHJlYW0iOmZhbHNlfSwia2l0TnVtYmVyIjoxMX0seyJpbmRleCI6MTAsIml0ZW1EYXRhIjp7ImlkIjoxMDAwMDAwMTAsImRyZWFtIjpmYWxzZX0sImtpdE51bWJlciI6MTB9LHsiaW5kZXgiOjExLCJpdGVtRGF0YSI6eyJpZCI6MCwiZHJlYW0iOmZhbHNlfSwia2l0TnVtYmVyIjowfSx7ImluZGV4IjoxMiwiaXRlbURhdGEiOnsiaWQiOjAsImRyZWFtIjpmYWxzZX0sImtpdE51bWJlciI6MH0seyJpbmRleCI6MTMsIml0ZW1EYXRhIjp7ImlkIjowLCJkcmVhbSI6ZmFsc2V9LCJraXROdW1iZXIiOjB9LHsiaW5kZXgiOjE0LCJpdGVtRGF0YSI6eyJpZCI6MCwiZHJlYW0iOmZhbHNlfSwia2l0TnVtYmVyIjowfSx7ImluZGV4IjoxNSwiaXRlbURhdGEiOnsiaWQiOjAsImRyZWFtIjpmYWxzZX0sImtpdE51bWJlciI6MH0seyJpbmRleCI6MTYsIml0ZW1EYXRhIjp7ImlkIjowLCJkcmVhbSI6ZmFsc2V9LCJraXROdW1iZXIiOjB9LHsiaW5kZXgiOjE3LCJpdGVtRGF0YSI6eyJpZCI6MCwiZHJlYW0iOmZhbHNlfSwia2l0TnVtYmVyIjowfSx7ImluZGV4IjoxOCwiaXRlbURhdGEiOnsiaWQiOjAsImRyZWFtIjpmYWxzZX0sImtpdE51bWJlciI6MH0seyJpbmRleCI6MTksIml0ZW1EYXRhIjp7ImlkIjowLCJkcmVhbSI6ZmFsc2V9LCJraXROdW1iZXIiOjB9LHsiaW5kZXgiOjIwLCJpdGVtRGF0YSI6eyJpZCI6MCwiZHJlYW0iOmZhbHNlfSwia2l0TnVtYmVyIjowfSx7ImluZGV4IjoyMSwiaXRlbURhdGEiOnsiaWQiOjAsImRyZWFtIjpmYWxzZX0sImtpdE51bWJlciI6MH0seyJpbmRleCI6MjIsIml0ZW1EYXRhIjp7ImlkIjowLCJkcmVhbSI6ZmFsc2V9LCJraXROdW1iZXIiOjB9XSwiY2FwdGFpbiI6MTAwMDAwMDAxLCJraWNrdGFrZXJzIjpbeyJpbmRleCI6MCwiaWQiOjEwMDAwMDAwMSwiZHJlYW0iOmZhbHNlfSx7ImluZGV4IjoxLCJpZCI6MTAwMDAwMDAxLCJkcmVhbSI6ZmFsc2V9LHsiaW5kZXgiOjIsImlkIjoxMDAwMDAwMDEsImRyZWFtIjpmYWxzZX0seyJpbmRleCI6MywiaWQiOjEwMDAwMDAwMSwiZHJlYW0iOmZhbHNlfSx7ImluZGV4Ijo0LCJpZCI6MTAwMDAwMDAxLCJkcmVhbSI6ZmFsc2V9XX0=", "body_len": 1985, "headers": [["Host", "10.10.0.120:8099"], ["Content-Length", "1985"], ["User-Agent", "ProtoHttp 1.3/DS 15.1.2.1.0 (Windows)"], ["Accept", "application/json"], ["Content-Type", "application/json"], ["X-UT-SID", ""]], "method": "PUT", "path": "/ut/game/fifa17/squad/0", "query": "", "version": "HTTP/1.1"}, "response": {"body_b64": "eyJpZCI6IDB9", "body_len": 9, "headers": [["Server", "BaseHTTP/0.6 Python/3.12.13"], ["Date", "Tue, 11 Aug 2026 18:20:36 GMT"], ["Content-Type", "application/json"], ["Content-Length", "9"]], "status": 200, "status_line": "HTTP/1.1 200 OK"}, "seq": 1, "t_request": 240.987206, "t_response": 241.06301, "unix_request": 1786472436.7700737} +{"conn": 11, "connection": {"keepalive_observed": true, "requests_on_this_connection": 2}, "elapsed_ms": 3.533, "redacted": ["request.X-UT-SID"], "request": {"body_b64": "", "body_len": 0, "headers": [["Host", "10.10.0.120:8099"], ["User-Agent", "ProtoHttp 1.3/DS 15.1.2.1.0 (Windows)"], ["Accept", "application/json"], ["Content-Type", "application/json"], ["X-UT-SID", ""], ["Accept-Encoding", "gzip"]], "method": "GET", "path": "/ut/game/fifa17/hub", "query": "", "version": "HTTP/1.1"}, "response": {"body_b64": "eyJjbHViUGxheWVycyI6IDE5NjIsICJhdWN0aW9uQ291bnQiOiAxLCAidHJhZGVQaWxlIjogeyJjb3VudCI6IDEsICJzZWxsaW5nIjogMSwgInNvbGQiOiAwfSwgIm9mZmxpbmVTZWFzb24iOiB7ImRpdmlzaW9uSWQiOiAiMTAiLCAiZ2FtZXNQbGF5ZWQiOiAiMCIsICJwb2ludHMiOiAiMCIsICJ0b3RhbEdhbWVzIjogIjEwIiwgInByb2dyZXNzRGF0YVZlcnNpb24iOiAiMCJ9fQ==", "body_len": 214, "headers": [["Server", "BaseHTTP/0.6 Python/3.12.13"], ["Date", "Tue, 11 Aug 2026 18:20:37 GMT"], ["Content-Type", "application/json"], ["Content-Length", "214"]], "status": 200, "status_line": "HTTP/1.1 200 OK"}, "seq": 2, "t_request": 241.53566, "t_response": 241.539193, "unix_request": 1786472437.3185353} diff --git a/openfut-adapter-fifa17/fixtures/utas/state-after.json b/openfut-adapter-fifa17/fixtures/utas/state-after.json new file mode 100644 index 0000000..f16dabc --- /dev/null +++ b/openfut-adapter-fifa17/fixtures/utas/state-after.json @@ -0,0 +1,84 @@ +{ + "routes": { + "accountInfo": { + "body_len": 2, + "fields": { + "keys": [] + }, + "sha256": "44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a", + "status": 200 + }, + "activeSquad": { + "body_len": 8034, + "fields": { + "formation": "f442", + "id": 0, + "players.count": 23, + "slots": { + "0": 100000003, + "1": 100000006, + "10": 100000010, + "11": 0, + "12": 0, + "13": 0, + "14": 0, + "15": 0, + "16": 0, + "17": 0, + "18": 0, + "19": 0, + "2": 100000005, + "20": 0, + "21": 0, + "22": 0, + "3": 100000008, + "4": 100000007, + "5": 100000002, + "6": 100000004, + "7": 100000009, + "8": 100000001, + "9": 100000025 + } + }, + "sha256": "07e330ed358fbefe31379cd2462aaac4bdc9c85ee28b7500dd2d963e5ea565bd", + "status": 200 + }, + "credits": { + "body_len": 148, + "fields": { + "credits": 28112944 + }, + "sha256": "0a5f3bac80c3a8ee6f088ccf180f5fdcbcbe8a2ef19c7026e4f21876016d7786", + "status": 200 + }, + "tradePile": { + "body_len": 862, + "fields": { + "auctionInfo.count": 1 + }, + "sha256": "b42bab98202209bd8309beb0eca73dba471688e69fef3e014b59901fbc21fe04", + "status": 200 + }, + "unassigned": { + "body_len": 16, + "fields": { + "itemData.count": 0 + }, + "sha256": "873f8bba8baf9c573fc51b54d100c357b3bf0caeb2ccd104245c295e073cf342", + "status": 200 + }, + "userMassInfo": { + "body_len": 8929, + "fields": { + "clubAbbr": "OFC", + "clubName": "OpenFUT", + "personaId": 33068179, + "trophies": 0 + }, + "sha256": "a616aca1742263c47ade9409693e66ec13b50114e608d88bb94141ce80237b66", + "status": 200 + } + }, + "unix": 1786472465.339646, + "upstream": "127.0.0.1:8099" +} \ No newline at end of file diff --git a/openfut-adapter-fifa17/fixtures/utas/state-before.json b/openfut-adapter-fifa17/fixtures/utas/state-before.json new file mode 100644 index 0000000..22477cd --- /dev/null +++ b/openfut-adapter-fifa17/fixtures/utas/state-before.json @@ -0,0 +1,84 @@ +{ + "routes": { + "accountInfo": { + "body_len": 2, + "fields": { + "keys": [] + }, + "sha256": "44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a", + "status": 200 + }, + "activeSquad": { + "body_len": 8034, + "fields": { + "formation": "f442", + "id": 0, + "players.count": 23, + "slots": { + "0": 100000003, + "1": 100000010, + "10": 100000001, + "11": 100000002, + "12": 0, + "13": 0, + "14": 0, + "15": 0, + "16": 0, + "17": 0, + "18": 0, + "19": 0, + "2": 100000009, + "20": 0, + "21": 0, + "22": 0, + "3": 100000008, + "4": 100000007, + "5": 100000006, + "6": 100000005, + "7": 100000004, + "8": 100000025, + "9": 0 + } + }, + "sha256": "768bb0584ad953ac5f088ad029f161d302ee1be3a63826eb186405acaf1b6232", + "status": 200 + }, + "credits": { + "body_len": 148, + "fields": { + "credits": 28020656 + }, + "sha256": "8d39fee51c24ddee9f12d98d7833af6cd3d3399a0e7567ab7062945a1180e30f", + "status": 200 + }, + "tradePile": { + "body_len": 862, + "fields": { + "auctionInfo.count": 1 + }, + "sha256": "1575046afb8ca60c76de64427ee0c70e1d4ca2da032819a60db95d72d272d11d", + "status": 200 + }, + "unassigned": { + "body_len": 16, + "fields": { + "itemData.count": 0 + }, + "sha256": "873f8bba8baf9c573fc51b54d100c357b3bf0caeb2ccd104245c295e073cf342", + "status": 200 + }, + "userMassInfo": { + "body_len": 8929, + "fields": { + "clubAbbr": "OFC", + "clubName": "OpenFUT", + "personaId": 33068179, + "trophies": 0 + }, + "sha256": "3d89d0497661fc62f107081208a14c4fa5753ee4e6482eeda825fe4b622f871f", + "status": 200 + } + }, + "unix": 1786472102.908128, + "upstream": "127.0.0.1:8099" +} \ No newline at end of file diff --git a/scripts/mutate-utas-observe.py b/scripts/mutate-utas-observe.py new file mode 100755 index 0000000..05d921a --- /dev/null +++ b/scripts/mutate-utas-observe.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 +"""Mutation-test the UTAS recorder. A no-op replacement exits 3 rather than +counting as a survivor -- a sed that silently does nothing is how a mutation run +lies about coverage.""" +import os, shutil, subprocess, sys + +import os as _os +ROOT = _os.path.dirname(_os.path.dirname(_os.path.abspath(__file__))) +# The COMMITTED test, not a scratchpad copy. Pointing this at a stale +# duplicate made a live mutation look survivable: the old copy had no +# query-string assertion, so disabling query redaction passed. +TEST = ROOT + "/scripts/test-utas-observe.py" + +MUTATIONS = [ + ("U1 tee: record but do not forward", + "scripts/openfut-utas-observe.py", + " try:\n dst.sendall(data)", + " try:\n pass"), + ("U2 tee: drop the last byte of every chunk", + "scripts/openfut-utas-observe.py", + " dst.sendall(data)", + " dst.sendall(data[:-1])"), + ("U3 sanitiser: stop redacting secrets", + "scripts/openfut-utas-observe.py", + " if any(s in k.lower() for s in SECRET_BODY_KEYS) and isinstance(o[k], str):", + " if False:"), + ("U4 parser: ignore chunked framing", + "scripts/openfut-utas-observe.py", + ' if te and "chunked" in te.group(1).lower():', + " if False:"), + ("U6 sanitiser: stop redacting query parameters", + "scripts/openfut-utas-observe.py", + " if eq and any(x in k.lower() for x in SECRET_BODY_KEYS):", + " if False:"), + ("U5 parser: reverse header order", + "scripts/openfut-utas-observe.py", + " out.append([k, v.strip()])", + " out.insert(0, [k, v.strip()])"), +] + +LAST = {} +def run(): + r = subprocess.run([sys.executable, TEST], cwd=ROOT, capture_output=True, text=True) + LAST["rc"] = r.returncode + LAST["out"] = r.stdout + return r.returncode == 0 + +def main(): + if not run(): + print("BASELINE FAILS"); return 2 + survivors = [] + for name, rel, old, new in MUTATIONS: + path = os.path.join(ROOT, rel); bak = path + ".mutbak" + shutil.copy2(path, bak) + try: + src = open(path).read() + mutated = src.replace(old, new, 1) + if mutated == src: + print("!! MUTATION DID NOT APPLY: %s" % name); return 3 + open(path, "w").write(mutated) + killed = not run() + print(("KILLED " if killed else "SURVIVED ") + name + " [rc=%s]" % LAST.get("rc")) + if not killed: + for l in LAST.get("out","").splitlines(): + if "query" in l or "FAIL" in l or "all checks" in l: + print(" " + l) + if not killed: survivors.append(name) + finally: + shutil.move(bak, path); os.utime(path, None) + print() + print("all %d mutations killed" % len(MUTATIONS) if not survivors + else "%d SURVIVED: %s" % (len(survivors), survivors)) + return 1 if survivors else 0 + +sys.exit(main()) diff --git a/scripts/openfut-utas-observe.py b/scripts/openfut-utas-observe.py index 2ead781..e018833 100755 --- a/scripts/openfut-utas-observe.py +++ b/scripts/openfut-utas-observe.py @@ -350,18 +350,48 @@ def header_list(head): SECRET_HEADERS = {"authorization", "cookie", "set-cookie", "x-ut-sid", "easw-session-data-nucleus-id"} -SECRET_BODY_KEYS = ("sid", "token", "password", "answer", "secret") +# Substring-matched against lowercased JSON keys. Extended after auditing the +# first real corpus: session tokens were being redacted correctly, but the +# client also sends hardware and device identifiers in `POST /ut/auth`, and a +# committed fixture is a published fixture. Audit the output before publishing, +# every time -- "the sanitiser handles it" is a belief until it is checked. +SECRET_BODY_KEYS = ( + "sid", "token", "password", "answer", "secret", + "macaddress", "deviceid", "authcode", +) def sanitize(rec): """Repository-safe form. Bodies are preserved EXACTLY; only credentials go. + THREE input surfaces carry identifiers, not two. The first version handled + headers and JSON bodies and was still about to publish a device id, because + `GET /ut/game/fifa17/phishing/trusteddevice?deviceId=...` puts it in the + QUERY STRING. Caught by auditing the output rather than by trusting the + sanitiser -- which is the only reason it is a comment and not a leak. + Exact bodies first, sanitise second: the corpus is worthless if response payloads are reshaped, so nothing here touches structure -- it replaces known-secret header values and known-secret JSON keys, and records that it did so. """ redacted = [] + + # Query string: same key rules as bodies. + q = rec["request"].get("query") or "" + if q: + parts, hit = [], False + for kv in q.split("&"): + k, eq, v = kv.partition("=") + if eq and any(x in k.lower() for x in SECRET_BODY_KEYS): + parts.append(k + "=") + redacted.append("request.query." + k) + hit = True + else: + parts.append(kv) + if hit: + rec["request"]["query"] = "&".join(parts) + for side in ("request", "response"): hs = rec[side]["headers"] for pair in hs: @@ -407,73 +437,121 @@ def redact_json(body): # ────────────────────────────────────────────────────────────── snapshot ──── +# Read-only GETs only. `/openfut/account/sync` is deliberately NOT here: it is a +# POST that selects and writes an account, so using it as a snapshot would +# mutate the state the snapshot exists to observe. +# +# All six were confirmed to answer 200 without a session token. SNAPSHOT_ROUTES = [ - ("account", "/openfut/account/sync"), + ("credits", "/ut/game/fifa17/user/credits"), + ("userMassInfo", "/ut/game/fifa17/userMassInfo"), + ("unassigned", "/ut/game/fifa17/purchased/items"), + ("activeSquad", "/ut/game/fifa17/squad/active"), + ("tradePile", "/ut/game/fifa17/tradePile"), + ("accountInfo", "/ut/game/fifa17/user/accountinfo"), ] -def cmd_snapshot(args): - """A light state manifest, for before/after pairing around a session. +def http_get(host, port, path): + s = socket.create_connection((host, int(port)), timeout=10) + s.sendall(("GET %s HTTP/1.1\r\nHost: %s:%s\r\nConnection: close\r\n\r\n" + % (path, host, port)).encode()) + buf = b"" + while True: + d = s.recv(65536) + if not d: + break + buf += d + s.close() + head, _, body = buf.partition(b"\r\n\r\n") + line = head.split(b"\r\n")[0].decode("latin1") + status = int(line.split()[1]) if len(line.split()) > 1 else None + return status, body - Deliberately a summary, not a database dump: the point is to say what - changed, and a committed copy of the save would be both huge and full of - things that are not evidence. + +def cmd_snapshot(args): + """A state manifest for pairing before/after around a capture session. + + A summary plus a hash, not a database dump. The named fields are what a + human reads; the sha256 of each full body is the safety net, because a + summary can only report changes in fields somebody thought to list. If the + hash moves and no field does, the summary is incomplete -- and that is + itself a finding rather than a silent miss. + + Raw bodies are written alongside at mode 0600 so a real diff is possible + later without re-running the session. """ + import hashlib uh, up = args.upstream.rsplit(":", 1) + out_path = os.path.abspath(args.out) + raw_dir = os.path.join(os.path.dirname(out_path), "bodies") + os.makedirs(raw_dir, exist_ok=True) + man = {"unix": time.time(), "upstream": args.upstream, "routes": {}} for name, path in SNAPSHOT_ROUTES: try: - s = socket.create_connection((uh, int(up)), timeout=5) - body = b'{"personaId":0}' - req = ("POST %s HTTP/1.1\r\nHost: %s:%s\r\nContent-Type: application/json\r\n" - "Content-Length: %d\r\nConnection: close\r\n\r\n" % (path, uh, up, len(body))) - s.sendall(req.encode() + body) - buf = b"" - while True: - d = s.recv(4096) - if not d: - break - buf += d - s.close() - _, _, payload = buf.partition(b"\r\n\r\n") - man["routes"][name] = summarize(payload) + status, body = http_get(uh, up, path) except Exception as e: - # Recorded as an error rather than omitted: a manifest missing a - # section must not look like a section that was empty. + # Recorded as an error, never omitted: a missing section must not + # be mistakable for an empty one. man["routes"][name] = {"error": str(e)} - os.makedirs(os.path.dirname(os.path.abspath(args.out)), exist_ok=True) - with open(args.out, "w") as f: + continue + bp = os.path.join(raw_dir, name + ".json") + fd = os.open(bp, os.O_CREAT | os.O_WRONLY | os.O_TRUNC, 0o600) + with os.fdopen(fd, "wb") as f: + f.write(body) + man["routes"][name] = { + "status": status, + "body_len": len(body), + "sha256": hashlib.sha256(body).hexdigest(), + "fields": extract(name, body), + } + + os.makedirs(os.path.dirname(out_path), exist_ok=True) + with open(out_path, "w") as f: json.dump(man, f, indent=2, sort_keys=True) f.write("\n") - print("wrote %s" % args.out) + print("wrote %s" % out_path) for k, v in man["routes"].items(): - print(" %s: %s" % (k, v)) + print(" %-13s %s" % (k, v.get("fields", v))) return 0 -INTERESTING = ("coins", "unopenedPacks", "personaId", "personaName", "clubName", - "level", "experience", "accountFunds", "itemCount", "squadId") - - -def summarize(payload): +def extract(name, body): + """Named fields per route. Unknown shapes report what they can rather than + raising -- the hash still covers everything.""" try: - doc = json.loads(payload) + d = json.loads(body) except Exception: - return {"raw_len": len(payload)} - out = {} - - def walk(o, prefix=""): - if isinstance(o, dict): - for k, v in o.items(): - if k in INTERESTING and not isinstance(v, (dict, list)): - out[k] = v - else: - walk(v, prefix + k + ".") - elif isinstance(o, list): - out.setdefault(prefix.rstrip(".") + ".count", len(o)) - - walk(doc) - return out + return {"unparsed_len": len(body)} + f = {} + if name == "credits": + f["credits"] = d.get("credits") + elif name == "userMassInfo": + ui = d.get("userInfo", {}) + for k in ("personaId", "clubName", "clubAbbr", "trophies"): + if k in ui: + f[k] = ui[k] + for k, v in d.items(): + if isinstance(v, list): + f[k + ".count"] = len(v) + elif name == "unassigned": + f["itemData.count"] = len(d.get("itemData", [])) + elif name == "activeSquad": + f["id"] = d.get("id") + f["formation"] = d.get("formation") + players = d.get("players", []) + f["players.count"] = len(players) + # Slot -> item id, so a two-player swap is visible in the diff. + f["slots"] = { + str(p.get("index", i)): (p.get("itemData") or {}).get("id") + for i, p in enumerate(players) + } + elif name == "tradePile": + f["auctionInfo.count"] = len(d.get("auctionInfo", [])) + elif name == "accountInfo": + f["keys"] = sorted(d.keys()) if isinstance(d, dict) else None + return f def main(): diff --git a/scripts/test-utas-observe.py b/scripts/test-utas-observe.py index 07b9557..943e893 100755 --- a/scripts/test-utas-observe.py +++ b/scripts/test-utas-observe.py @@ -50,7 +50,7 @@ class H(http.server.BaseHTTPRequestHandler): return self.rfile.read(n) if n else b"" def do_GET(self): - if self.path == "/chunked": + if self.path.split("?")[0] == "/chunked": self.send_response(200) self.send_header("Content-Type", "application/json") self.send_header("Transfer-Encoding", "chunked") @@ -126,7 +126,7 @@ def main(): b"GET /ut/game/fifa17/userMassInfo HTTP/1.1\r\nHost: t\r\n\r\n", b"POST /ut/game/fifa17/purchased/items HTTP/1.1\r\nHost: t\r\n" b"Content-Type: application/json\r\nContent-Length: %d\r\n\r\n" % len(body) + body, - b"GET /chunked HTTP/1.1\r\nHost: t\r\n\r\n", + b"GET /chunked?deviceId=DEADBEEFCAFE&keep=yes HTTP/1.1\r\nHost: t\r\n\r\n", b"GET /ut/game/fifa17/hub HTTP/1.1\r\nHost: t\r\nConnection: close\r\n\r\n", ] @@ -199,6 +199,16 @@ def main(): check("secret JSON value redacted", echoed.get("sid") == "") check("non-secret payload preserved exactly", echoed.get("echo_len") == len(body)) check("redaction is recorded, not silent", "redacted" in txs[1]) + # Regression: the sanitiser handled headers and JSON bodies but not the + # QUERY STRING, and was one audit away from publishing a device id from + # `?deviceId=...`. Three surfaces carry identifiers, not two. + qtx = next((t for t in txs if t["request"]["query"]), None) + check("a secret query parameter is redacted", + qtx is not None and "deviceId=" in qtx["request"]["query"], + qtx["request"]["query"] if qtx else "no query captured") + check("a non-secret query parameter is preserved", + qtx is not None and "keep=yes" in qtx["request"]["query"], + qtx["request"]["query"] if qtx else "") srv.shutdown() print()