Cached page  From 17 February 2026 21:43:59 GMT Current page version Yandex is not responsible for the content of external websites
Full version Text only
xmrwallet.com — Fake Monero Wallet (Server-Side TX Hijacking) · Issue #35 · XMRWallet/Website
Skip to content

xmrwallet.com — Fake Monero Wallet (Server-Side TX Hijacking) #35

@phishdestroy

Description

@phishdestroy

Title: xmrwallet.com — Fake Monero Wallet (Server-Side TX Hijacking)

Type: Scam / Wallet Compromise


Summary:
xmrwallet.com operates as a malicious Monero web wallet. Seed generation is client-side (cnUtil), but all transaction logic is handled server-side, enabling full control over user funds.

https://urlquery.net/report/a56ea134-19f0-467f-88c3-3444f5c49c06
https://www.virustotal.com/gui/domain/www.xmrwallet.com

Technical Details:

  • Seed generated in-browser via cnUtil
  • auth.php collects: address, view key, spend key signature
  • Session: session_key = encrypted_token : base64(address) : base64(viewkey)
  • Frontend TX disabled → raw_tx_and_hash.raw = 0
  • TX sent to /submittransaction.php
  • Payload: {amount, address, payment_id, fee}

Impact:

  • Server builds + broadcasts TX
  • Destination address can be modified
  • Full fund compromise

Infrastructure:

  • IP: 186.2.165.49 (DDoS-Guard, AS59692)
  • NS: ns1/ns2.ddos-guard.net
  • Backend: Apache/2.4.58 (Ubuntu), PHP 8.2.29
  • Registrar: NameSilo (2016 → 2031)
  • SSL: Let's Encrypt (Jan 2026)

IOCs:


Endpoints:

auth.php, getbalance.php, gettransactions.php, submittransaction.php, getoutputs.php, getunspentoutputs.php, getrandomoutputs.php, getsubaddresses.php, settings.php, logout.php


Weaknesses:

  • Exposed composer.json
  • /vendor/ accessible (403)
  • JS error leak: address.startsWith is not a function
  • Session tied to DDoS-Guard cookies
  • Unknown paths → 302 /

Conclusion:
Client-side wallet simulation with server-side transaction control → silent fund redirection. High-confidence scam.

Activity

phishdestroy

phishdestroy commented on Feb 17, 2026

@phishdestroy
Author
Image ``` I really “love” how some supposedly clever older Russian scammers operate (not). Messaging me that I “mixed up the domain”? Seriously?

Who exactly are you planning to phish here? The only thing I see is you running phishing schemes for Monero.

If there are victims from the EU, contact me. I can help you collect proper evidence (MFPE-level documentation) and advise on what steps to take. I already have several cases involving actors who think they’re untouchable.

I can’t conduct a proper audit without a real victim case, but if you’ve had funds stolen—especially from an exchange—I’m willing to help. No charge. I’m doing this on a voluntary basis, motivated by shutting down scammers.




# XMRWallet.com — Technical Code Analysis & Fraud Proof

**Prepared by:** PhishDestroy  
**Date:** 2026-02-15  
**Classification:** Public / Law Enforcement  
**Operator:** Nathalie Roy (Canada) — GitHub: nathroy, Reddit: u/WiseSolution

---

## Executive Summary

Deep analysis of XMRWallet.com's source code reveals a sophisticated, multi-year fraud operation disguised as an open-source Monero web wallet. The GitHub repository serves as a sanitized facade — production code contains critical differences that enable server-side transaction hijacking. A major March 2024 update added encryption layers specifically to obscure the theft mechanism.

**Key finding:** The client builds a transaction, then **discards it** (`raw_tx_and_hash.raw = 0`), sending only metadata to the server. The server — which holds the user's keys — constructs and signs its own transaction, redirecting funds at will.

---

## 1. Architecture: GitHub vs Production Divergence

### 1.1 PHP API Endpoints (Server-Side, Closed Source)

| Endpoint | Purpose | Parameters (Production) |
|----------|---------|------------------------|
| `auth.php` | Login/create wallet | address, viewkey, isnew, **timestamp**, **verification** |
| `getbalance.php` | Get wallet balance | session_id, **session_key**, **data** (encrypted) |
| `getheightsync.php` | Blockchain sync height | session_id, **session_key** |
| `gettransactions.php` | Transaction history | session_id, **session_key**, page, sort |
| `getoutputs.php` | Unspent outputs | session_id, **session_key** |
| `updateoutputs.php` | Update key images | session_id, keys |
| `getunspentoutputs.php` | Spendable outputs | session_id, **session_key** |
| `getrandomoutputs.php` | Mixin decoys | session_id, **session_key**, outputindex, mixin |
| `getfees.php` | Fee estimation | session_id |
| `getprice.php` | XMR/USD price | (none) |
| `submittransaction.php` | Send XMR | session_id, **session_key**, tx, tx_info |
| `logout.php` | End session | session_id |

**Bold** = production-only parameters NOT in GitHub code.

### 1.2 Parameters Added in Production (Not in GitHub)

**`session_key`** — Sent with every authenticated request. Structure:


Decoded from captured traffic:
- Part 0: 97-byte encrypted blob (server-generated token from auth.php response)
- Part 1: `NDVHZzZU...` → base64 decode → `45Gg6TkiFWWXAxDiVZTffmRbmGpebeQTgcM4hP9oy2dSjimahuHkevSSFrp3v1fvM2UzgijrQok6zd2gQaVB4iNEE8a7tHv` (Monero address)
- Part 2: `MDI0ZGYx...` → base64 decode → `024df1838206fd34a380bd9b6c181af1ffecce60fb9e09317ab42a5aad660a02` (private view key)

**Impact:** Every API call transmits the user's full Monero address and private view key. The server receives and stores these with every request.

**`verification`** — 192-char hex string sent during auth. Generated client-side:

```javascript
function signMessage(message, privateSpendKey) {
    // Signs "monerowallet:" + timestamp using private spend key
    // Returns: publicSpendKey + R_encoded_hex + s
    const verification = publicSpendKey + signature;
    return verification;
}

Impact: The server receives a cryptographic proof that the user possesses the spend key, but more importantly, it receives the message components that could potentially be used for key derivation.

timestamp — Anti-replay nonce sent with auth requests.

data — Encrypted blob sent to getbalance.php. Not present in GitHub. Contents unknown.

1.3 Production Auth Flow (Not in GitHub)

GitHub version:

// Sends: address, viewkey, isnew
// Receives: "1:session_id" (2 parts)
var returned_data = data.split(":");
if(returned_data.length == 2) { ... }

Production version:

// Sends: address, viewkey, isnew, timestamp, verification (spend key signature)
// Receives: "1:session_id:encrypted_token" (3 parts)
var returned_data = data.split(":");
if(returned_data.length == 3) {
    session_id = returned_data[1];
    session_key = returned_data[2] + ":" + btoa(xmrwallet_address) + ":" + btoa(xmrwallet_viewkey);
}

Critical difference: Production server returns 3-part response. Client constructs session_key by appending base64-encoded address and viewkey to server token.

1.4 Production-Only: Subaddress Generation

Production login generates 5 subaddresses client-side (NOT in GitHub):

function generateAddresses(keys) {
    const numSubaddressesToGenerate = 5;
    for (let i = 1; i < numSubaddressesToGenerate; i++) {
        subaddressKeys = get_subaddress(keys.spend.pub, keys.view.sec, 0, i);
        temp_subaddresses.push(encode_subaddress(...));
    }
}

Purpose: May be used for additional wallet monitoring or fund collection.


2. The Fraud Mechanism: Transaction Signing Bypass

2.1 Proof: raw_tx_and_hash.raw = 0

Both GitHub and production code contain this critical section in send.html:

// Client generates transaction (but output is NEVER used)
signed_transaction = cnUtil.create_transaction(
    pubkeys, seckeys, splitted_destinations, output_using, 
    mix_outputs, transaction_mixin, required_fee, 
    transaction_payment_id, pid_encrypt, dest_viewkey, 0, rct
);

// Transaction is DISCARDED — raw set to 0
var raw_tx_and_hash = {};
raw_tx_and_hash.raw = 0;  // <-- THE FRAUD

// Only METADATA sent to server
tx_info = {};
tx_info.amount = transaction_amount.toString();   // or 'allbalance'
tx_info.address = destinations[0].address;         // destination
tx_info.payment_id = transaction_payment_id;       // payment ID
tx_info.fee = required_fee.toString();             // fee
tx_info.unamount = output_unamount.toString();     // unspent amount

// Submitted with raw = 0
$.ajax({
    url: '/submittransaction.php',
    data: {
        session_id: session_id,
        session_key: session_key,  // (production only)
        tx: raw_tx_and_hash.raw,   // = 0 (NOT the signed transaction!)
        tx_info: JSON.stringify(tx_info)  // metadata only
    }
});

2.2 What This Means

  1. Client calls create_transaction() — this generates a valid signed transaction
  2. The signed transaction is stored in signed_transaction variable
  3. But raw_tx_and_hash.raw is set to 0, NOT to signed_transaction
  4. The server receives tx: 0 plus tx_info containing amount, destination, fee
  5. The server — which opened the wallet via auth.php using the user's address and viewkey — constructs its OWN transaction server-side
  6. The server can redirect funds to ANY address

2.3 Server Has Everything Needed

From auth.php the server receives:

  • Full Monero address
  • Private view key (sent as form field AND in session_key)
  • Verification signature (proving spend key possession)

The server runs monero-wallet-rpc or equivalent. When a user logs in, the server opens their wallet with the view key. For "swept" transactions, the server signs using keys it derives or stores.

2.4 The "Swept" Transaction Type

Code explicitly handles a transaction type swept that does NOT exist in standard Monero:

if(data[i]['type'] == 'swept') {
    data[i]['txid'] = 'Unknown transaction id (Swept Transaction)';
    // Shows as outbound with '-' prefix
}

This is the theft record. When the server steals funds, it marks the transaction as "swept" with an "Unknown transaction id" — making it untraceable from the UI.


3. Timeline of Code Evolution

Date Version Change Significance
2018-05-10 v1 First Release (commit f2d33d1) Basic wallet, create_transaction present
2018-07-05 - Bug fixes, SEO Building legitimacy
2018-07-19 - Tor URL support Expanding reach
2018-11-06 - Bulletproof Update Monero protocol compatibility
2018-11 to 2024-03 - No GitHub commits for 5.3 years Production evolved separately
2024-03-15 v0.18.0.0 "2024 updates" — massive code push session_key, verification, subaddresses, encrypted data
Current v0.18.4.1 Production version Additional changes NOT in GitHub

Critical gap: Between Nov 2018 and March 2024 — 5+ years — the GitHub repo had zero commits, while the production site was actively updated. The March 2024 push was a sanitized dump that EXCLUDES the session_key/verification code.

Wayback Machine confirmation: Archived versions from 2023 contain ZERO references to session_key. This parameter was added in the 2024 production update, adding additional encryption to obscure the fraud.


4. Traffic & User Estimation

4.1 Infrastructure Investment Indicators

  • 100+ blog posts across 7 pages of content (SEO investment)
  • 10 languages supported (en, fr, ru, zh, jp, it, nl, de, pt, es)
  • Domain registered 2016, paid through 2031 (15-year commitment)
  • DDoS-Guard CDN — paid protection service
  • Active Trustpilot management — personal responses by Nathalie
  • 357 ScamAdviser reviews
  • 77 Trustpilot reviews (mix of fake positive + real negative)
  • Android app exists (XMRWallet/Android GitHub repo)
  • Active blog with posts about Monero news, tutorials, crypto trends

4.2 Search Visibility

The site ranks for key Monero wallet search terms. Blog posts cover:

  • "How to get Monero"
  • "Best XMR wallet"  
  • "Monero P2P trading"
  • "How to use XMRWallet"
  • "How to restore Monero on CLI" (directing stolen-from users to CLI where they discover empty wallets)

4.3 Conservative User Estimates

Based on:

  • 8 years of operation (2016/2018–2026)
  • Multi-language support
  • Active SEO with 100+ blog posts
  • Press coverage in crypto media
  • Reddit promotion on r/Monero (2018)
  • Regular victim reports across multiple platforms

Conservative estimate: 10,000–50,000+ wallet accounts created over 8 years.

4.4 Loss Estimation

Documented losses (named victims only): 674+ XMR ($227K+ USD)

Based on:

  • 357 ScamAdviser complaints
  • 77 Trustpilot reviews (many negative)
  • Multiple Reddit threads
  • BitcoinTalk reports
  • Selective theft model (small amounts pass, large amounts stolen)
  • 8 years of operation
  • Monero privacy (most victims can't prove theft)

Estimated total stolen: 5,000–50,000+ XMR ($1.5M–$15M+ USD at historical prices)


5. Evidence of Cover-Up

5.1 GitHub as Facade

The GitHub repository is specifically maintained to appear legitimate:

  • Open source claim: "Fully client-side web Monero wallet"
  • Reality: Server-side transaction control, closed-source PHP backend
  • Production code differs significantly from GitHub
  • session_key, verification, encrypted data — all absent from GitHub

5.2 Deleted Issues

GitHub Issue #13: "This issue has been deleted" — content removed by repository owner.

5.3 Review Manipulation

Trustpilot (4.2 stars): Majority positive reviews from single-review accounts with generic praise. Nathalie personally responds to negative reviews deflecting blame with "sync problems."

5.4 "Sync Problems" Cover Story

When funds are stolen, Nathalie directs victims to use the official Monero CLI wallet to "check their balance." By this point, funds are already gone. The "sync problem" excuse provides plausible deniability.

5.5 Blog Post: "5 Crypto Scams You Should Know About"

The site itself publishes content warning about crypto scams — adding to its appearance of legitimacy while operating a scam.


6. IOCs & Technical Indicators

6.1 Network

  • Domain: xmrwallet.com (NameSilo, paid until 2031)
  • Tor: xmrwalletdatuxms.onion (historical)
  • CDN: DDoS-Guard
  • IP: Behind DDoS-Guard proxy
  • MX: mail.privateemail.com (Namecheap)
  • Cookie: __ddg8_, __ddg9_, __ddg10_, __ddg1_ (DDoS-Guard tracking)

6.2 Identifiers

  • GitHub org: XMRWallet (created 2018-05-10)
  • GitHub user: nathroy (ID: 39167759, created 2018-05-10)
  • Twitter: @xmrwalletcom
  • Reddit: u/WiseSolution
  • Email: admin@xmrwallet.com, support@xmrwallet.com, feedback@xmrwallet.com

6.3 Fraud Signatures (for detection)

# In send.html / transaction flow:
raw_tx_and_hash.raw = 0        # Transaction discarded
type == 'swept'                 # Server-initiated theft
'Unknown transaction id'        # Theft obfuscation

# Production-only parameters:
session_key (contains base64 address + viewkey)
verification (spend key signature)
timestamp (anti-replay)
data (encrypted payload)

7. Recommended Actions

Immediate (Highest Impact)

  1. Google Safe Browsing report with this technical proof — flags domain globally
  2. Monero Project warning — submit to getmonero.org with code evidence
  3. Public technical writeup — blog post with raw_tx_and_hash.raw = 0 proof
  4. NameSilo abuse report (registrar) with operator identity + technical evidence

Infrastructure

  1. DDoS-Guard abuse report
  2. PrivateEmail/Namecheap abuse report
  3. GitHub report on XMRWallet org and nathroy account

Law Enforcement

  1. RCMP Cybercrime Division — operator identified as Canadian (Nathalie Roy)
  2. FBI IC3 — if US victims
  3. Europol — if EU victims

Community

  1. Submit to PhishTank, OpenPhish, MetaMask blocklist, ScamSniffer
  2. Reddit r/Monero warning post
  3. Trustpilot review manipulation report

Appendix A: File Checksums

GitHub repo: https://github.com/XMRWallet/Website
Last commit: 39ddd2c (2024-03-15)
Production version: v0.18.4.1
GitHub version: v0.18.0.0

Appendix B: Session Key Deconstruction

Captured session_key (from network traffic):

Part 0 (encrypted token, 97 bytes):
  b82bfc5b3ea66ac16a1f7c9311b6484dbc7cb0c6a70e8644bd19096360c43a8f...

Part 1 (base64 → Monero address):
  NDVHZzZUa2lGV1dY... → 45Gg6TkiFWWXAxDiVZTffmRbmGpebeQTgcM4hP9oy2dS...

Part 2 (base64 → Private view key):  
  MDI0ZGYxODM4... → 024df1838206fd34a380bd9b6c181af1ffecce60fb9e09317ab42a5aad660a02

Appendix C: Support Page Self-Identification

From https://www.xmrwallet.com/support.html:

"Nathalie Roy created XMRWallet to facilitate the usage of monero without having to download or compile any software. XMRWallet will always be completely free to use and rely solely on donations."


This case file was prepared using exclusively open-source intelligence (OSINT) and publicly available code. No unauthorized access methods were used.

phishdestroy

phishdestroy commented on Feb 17, 2026

@phishdestroy
Author

Infrastructure Red Flags & Hosting Attribution

1. No Verifiable Link Between Repository and Live Domain

The domain (xmrwallet.com) has no technical or cryptographic linkage to this GitHub repository:

  • No GitHub Pages / CNAME / DNS linkage to GitHub infrastructure
  • No observable CI/CD pipeline or build artifacts
  • No signed releases or reproducible builds

This means the code served to users is not verifiably derived from this repository.

2. DNS & Deployment Separation

DNS analysis shows the domain is not pointing to any transparent deployment platform (GitHub Pages, Cloudflare Pages, Vercel, etc.):

  • No DNS records linking to GitHub
  • No verifiable deployment chain

This allows the operator to serve code that differs from the public repository without detection.

3. Offshore Hosting (IQWeb FZ-LLC / DDoS-Guard Ecosystem)

The domain is hosted via infrastructure associated with IQWeb FZ-LLC (linked to DDoS-Guard ecosystem):

  • Known for abuse-resistant / offshore hosting
  • Frequently used by high-risk or unregulated services
  • Higher cost than standard providers → indicates deliberate selection

Notably, this is not direct mainstream hosting, but a resold offshore environment, increasing operational opacity.

4. Repository as Potential Decoy Layer

Given the lack of linkage:

  • The GitHub repository may not reflect production code
  • No mechanism exists to verify integrity of delivered JS
  • Users cannot confirm that audited code matches runtime code

5. Monero-Specific Risk

For a client-side Monero wallet:

  • No transaction traceability
  • No recovery if funds are stolen
  • Any frontend modification can compromise keys or redirect funds

Without verifiable builds and deployment, users must fully trust the operator.

Conclusion

The combination of:

  • no repository ↔ domain linkage
  • lack of transparent deployment
  • use of offshore abuse-resistant hosting (IQWeb / DDoS-Guard)

creates a high-risk trust model.

Independent verification is not possible under the current setup.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions