Home Upgrade Search Memberlist Extras Hacker Tools Award Goals Help Wiki Contact

[Anvilpoint CyberOps] Exogator Engagement Report

Do you have a target you would like us to work on? Start a contract today!
Start Contract

A real-world engagement targeting Exogator. Roughly 22 hours of active work, ~2,300 logged requests, and ~110 individual test verdicts. The engagement is paused. Everything below is banked evidence.

Who the Target Was

Exogator is a crypto wallet drainer. It runs two websites, exogator.org and exogator.com, selling drainer-kit subscriptions. Both sites sat behind Cloudflare, which is why nobody had looked closely at them.

The panel software is a custom-built PHP application using a purchased admin template called Vuexy, a crypto payment processor called Oxapay, Google login, and Telegram for customer support. Finding the real server behind Cloudflare took some work: the panel's own email security record (its SPF entry) listed the true server address, 5.182.209.88, a shared hosting box in the Netherlands. The box runs cPanel and LiteSpeed, hosts dozens of other websites, and had stopped receiving security updates in August 2025.

One detail worth noting: the websites appear to sell subscriptions they cannot deliver (whether the operators hand over access through their Telegram support channel instead, we cannot say from outside). The two sites fail differently. On exogator.org, the buy flow dies at its final step: the checkout chain runs through plan selection and a Telegram contact step, then the last payment page simply does not exist (a 404). There is no payment verification on .org at all, just a browser-side widget that picks a deposit address from a hardcoded list. On exogator.com, the payment pages exist but the verify step returns the same empty error on every request shape we could send, through both the CDN and the server directly. The one working part anywhere is an unauthenticated order form on .com that creates real Oxapay payment invoices. The one path we could not test (the logged-in cart flow on .com) sits behind the invite-gated signup, so a functioning backend may exist behind login. What we can say from outside: the public checkout is broken on both sites, in different ways.

How We Tested

A few ground rules governed the whole engagement: all traffic ran through residential proxy networks so the target never saw our real addresses, every request was logged, pacing avoided tripping defenses, and proof followed strict rules. Roughly 2,300 requests produced about 110 separate verdicts.

We tested every major web vulnerability class against every surface the target exposes. This report covers both what worked and what didn't.

What an Attacker Can Do Today

These are the confirmed, demonstrated vulnerabilities. For each: what it is, and how an attacker would actually use it.

Stealing Passwords Right Off the Login Page

The login page at exogator.com reflects parts of the web address back into the page without encoding them. We injected a form-rebinding payload into that reflection and, in a real browser test, the credentials a user types into the login form were sent directly to a collection server we controlled. The victim sees a normal login page. Their password arrives on our server. No scripts required, no warnings, nothing. This is fully demonstrated with live browser proof.

The payload looks like this. A normal login link is:
Code
https://exogator.com/en/login?return_to=/dashboard

The attacker's link is:

The stray quote closes the attribute the site builds, and the injected form tag overwrites where the login form sends its data. The victim types their email and password into what looks like the real login form, and the browser submits both to webhook.site instead. The victim types their password. The password goes to the attacker instead of the site.

Turning a Reflection Into Account Takeover

The same reflection can carry script code. We proved script execution in a real browser on both reflection zones. Combined with the session problems below, this is the full takeover chain:

1. Victim clicks attacker's link, gets the booby-trapped login page. Example payload, where SESSION123 is a session ID the attacker created earlier:

2. The script quietly sets the victim's session ID to one the attacker chose beforehand.
3. Victim logs in normally. The site authenticates that session without changing the ID: the application never calls the PHP function that would issue a fresh session key at login, so the attacker's chosen ID simply becomes the logged-in one.
4. The attacker now holds the victim's logged-in session and can use it from anywhere in the world.

Each link in that chain is individually proven on the wire. The final step needs a real victim's login, which is part of why it works: the victim does the last piece themselves, thinking they're just logging in. That evidence shape (every link demonstrated separately on controlled accounts, the victim's own login completing the chain) matches a published, triaged, and paid bug-bounty report, so the industry treats it as report-grade, not theoretical.

And the prize is concrete. From public teardowns of identical panels, an attacker holding an operator account can edit the receiving-wallet configuration so that new victim funds route to the attacker's own wallets, read the full victim log (every wallet that connected and what was drained), mint their own victim links through the panel's link-generation features, and manipulate the earnings and payout ledger. One documented drainer operation lost a single victim to a wallet-redirection attack for $55 million. The session chain above is the front door to all of it.

The Password Reset That Hands Over the Token

Ask the .com site to reset the password for any email address, registered or not, and it creates a valid reset token and puts the whole token in the redirect header of the response. The token never needs a mailbox. Whoever asks for it gets it.

The attacker sends one request:
Code
POST https://exogator.com/en/recovery
[email protected]

and the server answers:
Code
HTTP/1.1 302 Found
Location: /en/resetpass?token=eyJhbGciOiJIUzI1NiJ9...

The full token is sitting in that Location header. The attacker copies it, visits the reset page with it, and owns the account's password. The one step we couldn't complete is submitting the new password, because that needs a live .com account to test against (registration requires an invite code). The token-theft half is confirmed, and the final submission sits one account away.

Creating a Duplicate of Any Victim's Account

On exogator.org, the signup form accepts email tricks like adding dots or +1 to an existing user's address and creates a second account that the system treats as the same identity. There's no email verification at all. If a victim is registered as [email protected], the attacker registers:
Code
POST https://exogator.org/process.php?register=true
[email protected]
password=attackerpassword

The form accepts it, the account is created, and the attacker now holds an account the system treats as the same address. Confirmed live: we created duplicate accounts this way for an address we already controlled, watched the site log both into the same dashboard, and the reset flow mints tokens against the confused address too.

Reading Files From the Server

The .com site loads language files based on a URL parameter without cleaning it. The application runs require("lang/" . $lang . ".php"), and the ?lang= parameter accepts path traversal:
Code
https://exogator.com/en/?lang=../../etc/hostname

Each ../ steps out of the language folder. We walked out and mapped what the server will and won't include, using the server's own error behavior as a map: a missing file returns an instant error, an existing file returns a different signature, and a file that hangs returns a third. Confirmed we can make the server load files it shouldn't, with the exploitation research done. The follow-up attempts are ranked and ready for the next phase: an argument-injection technique against a PHP utility file on the server, poisoned-file includes, and the hang itself is a reportable denial-of-service right now (a handful of concurrent requests can exhaust the PHP worker pool that all sites on the box share).

Unprotected Admin Ports on the Real Server

The origin box exposes its entire cPanel family to the internet: the admin consoles (WHM on port 2087, LiteSpeed WebAdmin on 7080), webmail, file-disk access, calendar services, and a mail-filtering service (ManageSieve on port 4190) that is running a manually-installed version with three known vulnerabilities, one rated capable of remote code execution. Anyone can connect:
Code
nc 5.182.209.88 4190
"IMPLEMENTATION" "Dovecot Pigeonhole"   <- the service answers, no login needed

The mail-filter service crashes on malformed pre-login commands (a denial-of-service we could trigger without any credentials), and the code-execution flaw needs one mail password to unlock.

Cookie Flags That Don't Exist

Every one of the 104 login cookies we observed, on both sites, ships without HttpOnly and without SameSite. The site sends:
Code
Set-Cookie: PHPSESSID=a1b2c3d4...; path=/; secure

A hardened site sends:
Code
Set-Cookie: PHPSESSID=a1b2c3d4...; path=/; secure; HttpOnly; SameSite=Strict

The missing flags mean any successful script injection can read the session cookie (document.cookie returns it, which is exactly what the XSS chain above does), and cross-site requests ride along freely. This isn't exotic: it's a one-line server configuration fix, and it's missing.


What We Tried That Failed, and Why That Matters

A report that only lists wins is lying to you by omission. Here's the full account of what we attacked and what held, because the negatives are how you know the positives are real.

SQL injection and command injection, everywhere they could exist: Manual payload batteries against every live form on both sites, then sqlmap and commix tool passes behind our WAF-testing proxy. All negative: ~230 manual rows plus tool passes, no injection oracles anywhere. The parameter layer of this panel is clean. One crash artifact looked like a hit and was root-caused to a parsing bug in our own driver. We refired it deterministically and closed it honestly.

Cross-origin resource sharing (CORS): No CORS policy exists at all on 24 probe combinations across both sites. An attacker can't read authenticated data cross-origin because there's nothing to misuse: the app never grants cross-origin reads.

Server-side request forgery (SSRF): No URL parameter we tested triggers the server to fetch anything. The one page-cloning feature that would obviously do server-side fetching doesn't fetch.

XML attacks (XXE and content-type confusion): PHP's standard form handling simply ignores XML bodies, and we confirmed the target follows that default. The classic "send XML where JSON is expected" trick has nothing to land on here.

Hidden parameters: The full 120-name dictionary sweep across all live endpoints, then a second pass with 252 more probes. The application reads a couple of dispatch flags and ignores everything else. If there were secret admin or debug parameters, we'd have found them.

Request smuggling through Cloudflare: The edge rejects malformed framing strictly (clean 400s, connection closed). We also poisoned the connection pool and it held. An attacker cannot desync the CDN from the origin through the front door.

Default credentials: This is a complete story worth telling: we built a master table of every default username/password pair that exists for every technology this target runs (cPanel, WHM, RoundCube, phpMyAdmin, the databases, LiteSpeed, Exim, Dovecot, the payment processor). It turns out almost nothing on this stack ships with a default password at all, and the two pairs that do exist were tested and rejected.

Brute-forcing the mail login: We ran a short, bounded credential attack against the real mail server: 102 attempts, three plausible operator usernames, zero hits. The valuable output is what the failed attack measured: the server has no per-account lockout whatsoever (any leaked password is verifiable in one try), blocks by IP address after about 34 rapid attempts, and rotating proxy addresses defeats that.

Cache poisoning, IDOR on order IDs, mass assignment, CSRF on the checkout, invite-gate bypass, session IDs in URLs: All tested, all closed negative.

Order-by injection a first sweep missed: Data tables in the admin template ship with a documented flaw class: the column-sorting parameter can smuggle SQL into the ORDER BY clause, and no probe in the original battery had ever sent a column name. We fired the full correction battery (the out-of-range error oracle, the boolean blind, two limit shapes) across the four unauthenticated table surfaces. All negative: the unauthenticated pages ignore the sorting parameters entirely. The open leg is the logged-in pages, where real sorting happens, and that test waits on the same account everything else waits on.

Database files in the web root: Panels in this family often leave their SQLite database sitting in a public folder, where anyone can just download it. We checked every candidate path on both sites. All 404: no exposed database file exists.

Telegram bot tokens: These panels ship with an operator Telegram bot for notifications, and a leaked bot token means full control of the bot's identity. We swept the entire captured artifact corpus (3,250 indexed files plus a 1.5 GB traffic log) for the token pattern. Zero hits: whatever bot integration this operation uses, its token appears nowhere we can see. The live ammunition would be the per-victim pages, which sit outside our corpus by design.

The Landscape Behind the Sites

The operation is small and its engineering is copy-paste. Demo JWT tokens still in the JavaScript bundle from the admin template. A misspelled cookie (main_curency) set to live for 900 days. The two sites run as separate PHP installations with different session formats. The admin gate uses a placeholder two-factor code. The .com signup is locked behind invite codes.

The infrastructure tells the real story. The cPanel stack froze in August 2025, which means it missed every 2026 security wave: a LiteSpeed bug that lets any hosting customer become root, a cPanel bug that lets a low-privilege account execute commands as root, another cPanel mail-tracking flaw that ends in arbitrary file creation as root, and the mail-filter service flaws above. None of those are directly usable without a foothold on the box, and that's the recurring theme of the whole engagement: this server is soft, and everything soft about it sits behind one credential that nobody has yet.

The operators' own email would be the crown jewel. Incoming mail lands on the origin with no Cloudflare protection. The catch-all mailbox shares the panel password. The domain's SPF record authorizes the origin server, and there's no DMARC record at all. So mail sent from the box impersonating the operators would pass spam filters at every receiver, and nobody would receive a report saying their domain was abused. We mapped all of this, including how a leaked credential converts: stealer-log markets sell exactly this credential type, indexed by victim email, and one hit would open the mail, the panel, the hosting account, and the whole ladder to root.

We checked those markets directly. The operators themselves do not appear in the leaked-credential dumps we could search (their handles, their mailboxes, all the role addresses). But the panel's own customers do: thirteen of the operation's buyers appear in the dumps, with credentials captured by infostealer malware at the panel's own signup and login pages. The drainer's customers were being robbed by unrelated malware while shopping for robbery tools. We recorded the finding, and the next phase includes retrieving and testing those passwords against the server. Any accepted login is the invite-gate unlock, and a reused password that also works on the server's mail login opens the whole box.

The .com domain expires 2026-11-12. If renewal lapses, anyone can catch it in the drop window (roughly mid-December through end of January), inherit its residual traffic, re-issue valid TLS certificates in minutes, and receive the operators' mail.

The Security Posture in Plain Terms

The application fails at the basics. Session handling is stock PHP with every security setting left at its insecure default. Output encoding doesn't exist on the reflection points, and there's no content security policy anywhere. The reset flow hands its secret to whoever asks. Registration doesn't check email ownership.

The infrastructure is a frozen, unpatched management plane sitting on the open internet behind a CDN that hides it from casual view but can't protect it origin-direct. Its one saving grace is that the worst bug on it (the cPanel authentication bypass that hit 1.5 million servers this spring) doesn't fully compose on this particular deployment, and everything else needs the application to give up a foothold first.

The CDN itself does genuine work (we couldn't smuggle, desync, or poison through it) while passing literally every exploitation payload class through untouched. We measured this with a WAF posture scan: structural tricks get blocked, actual attack payloads pass 90-100% of the time on both sites. A CDN is a performance and availability product that happens to stop the easy stuff. It is not a security boundary, and this engagement is a standing proof of that distinction. One routing fact from the same scan is worth keeping: every extensionless path on the .com site (no file extension, single segment) falls into one catch-all handler that dies with the same empty error page. That one misconfiguration swallows every "does this endpoint exist" probe and looks like nine different scanner findings if you don't recognize it. We mapped the boundary and the .org site doesn't share it: the same paths there return clean 404s.


What's Next, If the Work Resumes

Every finished result from the engagement is in the sections above. What remains here is genuinely untested work, in order of what unlocks the most:

1. Escalating the file-inclusion finding: The ?lang= flaw is confirmed but currently read-limited: the response echoes nothing, so we can prove which files exist but can't yet read their contents. Three escalation paths are researched and ranked. First, argument injection into a PHP utility file (pearcmd.php) that ships on cPanel servers: if one server setting (register_argc_argv) is on, as it commonly is, a single crafted URL writes attacker-controlled PHP to a file and includes it, turning the read into remote code execution. One request settles whether the setting is on. Second, poisoning a file the server will include (a session file or a log file carrying attacker text), which requires the same file-write leg. Third, the hang behavior itself: we measured that a request for a slow-loading file pins a PHP worker for tens of seconds, and the PHP worker pool is small and shared by every site on the box, so a handful of concurrent requests would take every website on that server offline. That denial-of-service finding is reportable today with the measurements we already have.

2. The session-poisoning chain: PHP lets an attacker write chosen content into a session file through a file-upload header, with no upload feature required. We proved that request survives Cloudflare and lands on the origin untouched. What's missing is a way to make the server read that poisoned file back. The file-inclusion finding is exactly that missing read. If the two connect, the session file becomes either a stored-XSS delivery or a route to running code on the server, and on this server the session directory is shared between tenants, so the read reaches other websites' session data too. One missing piece, three payoffs.

3. The credential gates: Four separate questions on the origin (the exact RoundCube version, the exact mail-filter version, the authenticated webmail attack paths, and the reset-confirmation step) all unlock with the same single thing: one account or one mail password. The cheapest untried source is the credential-leak market: these hosting credentials are sold in bulk, indexed by victim email, and one hit converts directly into the mail, the panel, and the hosting account. A bounded lookup against the operator identities is a desk task.

4. Trying the thirteen leaked customer passwords: The credential dumps listed above hold thirteen panel customers whose logins were captured by infostealer malware at the panel's own signup and login pages. The credentials themselves sit behind the leak service's key-gated tier. The next phase retrieves all thirteen and tries each against the panel login (these are panel accounts, so an accepted password is the invite-gate unlock and an account of our own) and, for password reuse, against the server's mail login. The odds are not nothing: the box has no per-account lockout, so each guess costs one attempt and carries no risk of locking anything. Any hit opens the account gates in items 3, 5, and 6 at once.

5. The full source-code pivot: One credential into the hosting panel means the panel application's source code, its database, the payment processor's secret key, the admin two-factor implementation, and every remaining version question answered in a single step. It also answers the two questions we could not resolve from outside at all: what the 3.5-second signup delay actually does (our timing analysis narrows it to the signup and password-recovery files), and where the victim-facing drainer code lives (if any). We proved it is not in the panel's own JavaScript. It is generated per-victim and served from pages we cannot see without an account.

6. The logged-in cart flow on .com: The invite-gated signup hid the only responding order-creation handler from us. With an account, the cart flow can be exercised end to end: create a cart, walk the checkout, and see whether the verify step that errors empty for everyone else actually processes for a logged-in session. That single test settles whether the operation can really take money, and it feeds directly into the payment-forgery question (whether a faked "paid" callback can flip an order, which is structurally impossible while the backend is dead but goes live the moment a real order exists).

7. The formality work: Completing two single-request checks left in the session-mapping path (does the .com login page hand out a session before sign-in, and how does the .org login page treat sessions), and a browser test for the frame-timing leak candidate. Small, mechanical, ready when the engagement resumes.

Do you have a target you would like us to work on? Start a contract today!
Start Contract


Possibly Related Threads...
Thread / Author Replies Views Last Post
by V_TECOct 22, 2012 03:52 PM 9 361 Oct 22, 2012 03:52 PM
Last Post: Cyb3r_0pTic