Back to blog

Google Sues Chinese Phishing Group Selling Kits: How to Protect Your Infrastructure and Users

Hey HaWkers, significant news broke recently: Google filed a lawsuit against an organized Chinese group that is selling sophisticated phishing kits through the dark web and clandestine platforms.

This isn't an isolated crime — it's the operation of a highly organized cartel selling infrastructure-as-a-service for phishing attacks, with hundreds of active customers paying for access to templates, servers, and automation tools.

For us developers and DevOps engineers, this news is a critical alert about current infrastructure risks. Let's break down how these attacks work, how to detect them, and implement real defenses in our applications.

What Is the Group and How Does It Operate

Scale of Operation

Data revealed by Google:

  • Operational period: 2018-2025 (7 years active)
  • Paying customers: 800+ registered criminal groups
  • Attacks executed: ~50,000+ per month
  • Targets: Fortune 500 companies, government, academia
  • Estimated revenue: $2-5 million/month

Criminal Business Model

It operates like a legitimate Phishing-as-a-Service (PaaS):

Services offered:

  1. Ready-made templates:

    • Exact clones of Gmail, Outlook, AWS, GitHub pages
    • Automatically updated whenever real services change
    • Landing pages with detection evasion
  2. Infrastructure:

    • Hosting on compromised servers
    • CDN for global distribution
    • Automatic URL rotation to avoid detection
  3. Automation tools:

    • Mass email dispatchers
    • SMS phishing (smishing)
    • Voice phishing (vishing) with AI
    • QR code phishing
  4. Security evasion:

    • 2FA bypass
    • Advanced credential harvesters
    • Session hijacking tools
  5. Real-time analytics:

    • Dashboard showing click-through rate
    • Captured credentials collection
    • Victim geolocation

Pricing:

Phishing service à la carte:

Starter Pack: $50
- 10,000 emails
- 1 custom template
- 30 days hosting

Professional: $200
- 100,000 emails
- 5 templates
- 2FA evasion
- 90 days hosting

Enterprise: $500/month
- Unlimited emails
- Access to 50+ templates
- 24/7 technical support
- Custom infrastructure

How Attacks Work

Typical Attack Flow

1. Reconnaissance (Information gathering)

Stage 1: Identify target

1. Collect employee names (LinkedIn, GitHub)
2. Map company domains
3. Identify tools used (AWS, GitHub, Slack)
4. Find email patterns
5. Detect authentication systems (2FA, SSO)

Result: List of 500+ employees + metadata

2. Crafting (Attack preparation)

Stage 2: Create convincing email

Used template: Clone of "AWS Security Alert"
Email body:

From: aws-security@amazon-verify.com ❌
Subject: "⚠️ URGENT: Suspicious Activity Detected"

Dear Customer,

We detected suspicious login to your AWS account:
- IP: 203.0.113.5 (China)
- Time: 2025-11-16 14:32 UTC
- Resource: S3 access

👉 Verify Activity: [PHISHING_LINK]

If this wasn't you, reset password now!

---
AWS Security Team

Why it's convincing:

  • Email appears from Amazon domain (typosquatting)
  • Artificial urgency ("suspicious activity")
  • False authority ("AWS Security Team")
  • Immediate call-to-action ("click now")
  • Social proof ("we detected...")

3. Delivery (Mass sending)

Stage 3: Send to 100,000 employees

Evasion techniques:

✓ Spaced emails (1 per minute, not in burst)
✓ Rotating IPs (different servers per email)
✓ Custom headers (forged SPF/DKIM)
✓ Image-only content (avoids spam filters)
✓ JavaScript in body (checks if human)

Expected rates:
- Delivered: 60-70%
- Opened: 20-30%
- Clicked link: 8-15%
- Entered credentials: 3-5%

For 100,000 emails = ~3,000-5,000 stolen credentials

4. Harvesting (Data collection)

Stage 4: Steal credentials

User clicks → Fake landing page → Entered email + password

Page captures:
- Email/username
- Password
- 2FA code (if typed)
- Session cookies
- User's IP
- User agent
- Timezone
- Browser language

Result: Active credentials in real-time

5. Access (Account compromise)

Stage 5: Use stolen credentials

Time elapsed: 15 minutes from sending

1. Login with stolen credentials
2. If 2FA is enabled:
   - Use captured code (valid for 30 seconds)
   - OR login before victim notices
3. Once inside:
   - Disable 2FA
   - Create backdoor/SSH key
   - Access sensitive data
   - Move laterally in network

Technical Detection and Prevention

1. Email Level Detection

// Advanced phishing detection system for Node.js
import emailValidator from 'email-validator';
import dns from 'dns';
import Anthropic from '@anthropic-ai/sdk';

class PhishingDetector {
  constructor() {
    this.client = new Anthropic();
    this.suspiciousPatterns = [
      /verify.*account/i,
      /urgent.*action/i,
      /confirm.*identity/i,
      /update.*payment/i,
      /security.*alert/i,
      /unusual.*activity/i,
      /click.*link.*now/i,
      /reset.*password/i
    ];
  }

  // Validate sender domain vs SPF/DKIM
  async validateEmailAuthentication(sender, domain) {
    return new Promise((resolve, reject) => {
      dns.resolveMx(domain, (err, addresses) => {
        if (err) {
          resolve({
            valid: false,
            reason: 'SPF failed - invalid domain'
          });
          return;
        }

        // Check SPF records
        dns.resolveTxt(domain, (err, records) => {
          if (!records) {
            resolve({
              valid: false,
              reason: 'No SPF record found'
            });
            return;
          }

          const hasSpf = records.some(r => r.join('').includes('v=spf1'));
          resolve({
            valid: hasSpf,
            reason: hasSpf ? 'SPF verified' : 'SPF missing'
          });
        });
      });
    });
  }

  // Analyze email body with Claude AI
  async analyzeEmailContent(subject, body, sender) {
    const suspiciousKeywords = this.suspiciousPatterns.filter(p =>
      p.test(subject) || p.test(body)
    ).length;

    const response = await this.client.messages.create({
      model: 'claude-3-5-sonnet-20241022',
      max_tokens: 256,
      system: `You are a phishing detection expert. Analyze the email and determine:
1. Legitimacy score (0-100, 0=definitely phishing, 100=definitely legitimate)
2. Threat level (low, medium, high, critical)
3. Key suspicious indicators
4. Recommended action

Respond as JSON.`,
      messages: [{
        role: 'user',
        content: `Analyze this email:
From: ${sender}
Subject: ${subject}

Body:
${body}

Is this phishing?`
      }]
    });

    let analysis;
    try {
      analysis = JSON.parse(
        response.content[0].type === 'text'
          ? response.content[0].text
          : '{}'
      );
    } catch (e) {
      analysis = { legitimacy_score: 50, threat_level: 'medium' };
    }

    return {
      suspiciousKeywords,
      aiAnalysis: analysis,
      shouldBlock: (analysis.legitimacy_score || 100) < 40
    };
  }

  // Check links in email
  async analyzeLinks(body) {
    const urlRegex = /https?:\/\/[^\s<>]+/g;
    const links = body.match(urlRegex) || [];

    const analyzed = await Promise.all(
      links.map(async (link) => {
        try {
          const url = new URL(link);

          // Check if domain is similar to expected
          const isSuspicious =
            url.hostname !== 'aws.amazon.com' &&
            url.hostname.includes('amazon') &&
            url.hostname !== url.origin; // Typosquatting

          return {
            url,
            suspicious: isSuspicious,
            reason: isSuspicious
              ? 'Domain typosquatting detected'
              : 'Domain looks legitimate'
          };
        } catch (e) {
          return {
            url: link,
            suspicious: true,
            reason: 'Invalid URL format'
          };
        }
      })
    );

    return analyzed.filter(l => l.suspicious);
  }

  // Main detection function
  async detect(email) {
    const {
      sender,
      subject,
      body,
      replyTo
    } = email;

    const [authCheck, contentAnalysis, linkAnalysis] = await Promise.all([
      this.validateEmailAuthentication(sender, new URL(`mailto:${sender}`).hostname),
      this.analyzeEmailContent(subject, body, sender),
      this.analyzeLinks(body)
    ]);

    const riskScore =
      (authCheck.valid ? 0 : 30) +
      (contentAnalysis.suspiciousKeywords * 5) +
      (contentAnalysis.aiAnalysis.legitimacy_score < 40 ? 40 : 0) +
      (linkAnalysis.length > 0 ? 30 : 0);

    return {
      isPhishing: riskScore > 60,
      riskScore,
      threats: {
        authenticationFailed: !authCheck.valid,
        suspiciousContent: contentAnalysis.shouldBlock,
        phishingLinks: linkAnalysis.length > 0
      },
      recommendation: riskScore > 80
        ? 'BLOCK - High confidence phishing'
        : riskScore > 60
          ? 'QUARANTINE - Suspicious email'
          : 'ALLOW - Low risk'
    };
  }
}

// Usage in security API
const detector = new PhishingDetector();

// In your email server
app.post('/api/security/email-check', async (req, res) => {
  const email = req.body;
  const result = await detector.detect(email);

  if (result.isPhishing) {
    // Quarantine email
    await quarantineEmail(email.id);
    // Notify user
    await notifyUser(email.recipient, 'Phishing attempt blocked');
  }

  res.json(result);
});

2. Application Level Protection

// Middleware to protect against credential harvesting
import rateLimit from 'express-rate-limit';
import helmet from 'helmet';

// Rate limiting for login
const loginAttempts = new Map();

const protectLogin = rateLimit({
  store: new Map(),
  windowMs: 5 * 60 * 1000, // 5 minutes
  max: 5, // 5 attempts max
  message: 'Too many login attempts. Try again in 5 minutes.',
  standardHeaders: true,
  legacyHeaders: false,
  skip: (req) => {
    // Don't apply rate limit to known IPs (office, VPN)
    const whitelistedIPs = process.env.WHITELIST_IPS?.split(',') || [];
    return whitelistedIPs.includes(req.ip);
  }
});

// Validate credentials
const validateLoginAttempt = async (req, res, next) => {
  const { email, password } = req.body;

  // Check if using HTTPS
  if (req.protocol !== 'https') {
    return res.status(403).json({
      error: 'HTTPS required',
      message: 'For security reasons, login must be via HTTPS'
    });
  }

  // Check if email exists (slowly, to not reveal)
  const user = await User.findByEmail(email);
  if (!user) {
    // Simulate delay to prevent user enumeration
    await new Promise(resolve => setTimeout(resolve, Math.random() * 2000));
    return res.status(401).json({ error: 'Invalid credentials' });
  }

  // Verify password
  const isValid = await user.verifyPassword(password);
  if (!isValid) {
    // Log attempt
    await LogSuspiciousActivity.create({
      userId: user.id,
      type: 'FAILED_LOGIN',
      ip: req.ip,
      userAgent: req.get('user-agent'),
      timestamp: new Date()
    });

    return res.status(401).json({ error: 'Invalid credentials' });
  }

  // Successful login
  next();
};

// Login routes
app.post('/auth/login', protectLogin, validateLoginAttempt, async (req, res) => {
  const { email } = req.body;
  const user = await User.findByEmail(email);

  // Create secure session
  const session = await createSecureSession(user, {
    ipAddress: req.ip,
    userAgent: req.get('user-agent'),
    timestamp: new Date(),
    expiresIn: 30 * 60 * 1000 // 30 minutes
  });

  // Use secure, httpOnly cookies
  res.cookie('sessionId', session.id, {
    secure: true,
    httpOnly: true,
    sameSite: 'strict',
    maxAge: 30 * 60 * 1000
  });

  res.json({
    success: true,
    requiresMFA: user.mfaEnabled,
    user: {
      id: user.id,
      email: user.email
    }
  });
});

3. Infrastructure-Level Anomaly Detection

// Anomaly detection system with machine learning
import tf from '@tensorflow/tfjs';

class AnomalyDetector {
  constructor() {
    this.model = null;
    this.normalBehavior = {
      avgLoginTime: 9, // 9 AM
      avgDayOfWeek: 3, // Wednesday
      commonCountries: ['BR', 'US'],
      commonDevices: [],
      avgSessionLength: 2400 // 40 minutes
    };
  }

  // Train model with login history
  async train(historicalLogins) {
    const features = historicalLogins.map(login => [
      login.hour,
      login.dayOfWeek,
      this.countryToNumber(login.country),
      login.deviceAge,
      login.sessionLength
    ]);

    const xs = tf.tensor2d(features);
    const ys = tf.ones([features.length, 1]);

    this.model = tf.sequential({
      layers: [
        tf.layers.dense({
          inputShape: [5],
          units: 16,
          activation: 'relu'
        }),
        tf.layers.dense({
          units: 8,
          activation: 'relu'
        }),
        tf.layers.dense({
          units: 1,
          activation: 'sigmoid'
        })
      ]
    });

    this.model.compile({
      optimizer: 'adam',
      loss: 'meanSquaredError'
    });

    await this.model.fit(xs, ys, {
      epochs: 50,
      batchSize: 32,
      verbose: 0
    });
  }

  // Detect anomalous login
  async detectAnomaly(loginAttempt) {
    const features = tf.tensor2d([[
      loginAttempt.hour,
      loginAttempt.dayOfWeek,
      this.countryToNumber(loginAttempt.country),
      loginAttempt.deviceAge,
      loginAttempt.sessionLength
    ]]);

    const prediction = this.model.predict(features);
    const anomalyScore = 1 - (await prediction.data())[0];

    features.dispose();
    prediction.dispose();

    return {
      isAnomaly: anomalyScore > 0.7,
      anomalyScore: (anomalyScore * 100).toFixed(2) + '%',
      factors: this.explainAnomaly(loginAttempt)
    };
  }

  // Explain what is anomalous
  explainAnomaly(login) {
    const factors = [];

    // Unusual time
    if (Math.abs(login.hour - this.normalBehavior.avgLoginTime) > 6) {
      factors.push({
        factor: 'Unusual time',
        detail: `Login at ${login.hour}:00, usual: ${this.normalBehavior.avgLoginTime}:00`
      });
    }

    // Unusual country
    if (!this.normalBehavior.commonCountries.includes(login.country)) {
      factors.push({
        factor: 'New country',
        detail: `Login from ${login.country}, common locations: ${this.normalBehavior.commonCountries.join(', ')}`
      });
    }

    // New device
    if (login.deviceAge < 7) { // Less than 7 days
      factors.push({
        factor: 'New device',
        detail: 'Device never seen before'
      });
    }

    return factors;
  }

  countryToNumber(country) {
    const countryMap = {
      'BR': 1,
      'US': 2,
      'CN': 3,
      'RU': 4
    };
    return countryMap[country] || 0;
  }
}

// Use in middleware
app.post('/auth/login', async (req, res, next) => {
  const loginAttempt = {
    hour: new Date().getHours(),
    dayOfWeek: new Date().getDay(),
    country: req.geoip.country,
    deviceAge: await getDeviceAgeInDays(req.headers['user-agent']),
    sessionLength: 0 // Will be filled later
  };

  const anomalyDetector = new AnomalyDetector();
  const anomaly = await anomalyDetector.detectAnomaly(loginAttempt);

  if (anomaly.isAnomaly) {
    // Require additional verification
    return res.status(403).json({
      error: 'Suspicious activity detected',
      message: 'We will send a verification code to your email',
      requiresVerification: true,
      anomalyFactors: anomaly.factors
    });
  }

  next();
});

Organizational Strategies

1. Security Education

Recommended program:

Frequency: Monthly

Modules:
1. Phishing recognition (30 min)
   - Real examples
   - How to verify domains
   - Common red flags

2. Credential management (20 min)
   - Use password managers
   - Never share passwords
   - 2FA everywhere

3. Reporting suspicious emails (15 min)
   - How to report
   - Don't delete suspicious emails
   - Who to contact

Evaluation: Monthly fake phishing test
Goal: Company with 0% clicks on fake phishing

2. Implement Zero Trust Architecture

Principles:

- Verify all credentials (never trust implicitly)
- MFA required everywhere
- Aggressive rate limiting
- Log everything
- Anomaly detection
- Quick token revocation

3. Real-Time Monitoring

// Security dashboard
const securityMetrics = {
  failedLogins: [],
  suspiciousEmails: [],
  newDevices: [],
  geochanges: []
};

// Real-time alerts
io.on('connection', (socket) => {
  socket.emit('securityAlert', {
    type: 'NEW_LOCATION',
    user: 'user@company.com',
    location: 'Beijing, China',
    device: 'Unknown Chrome on Linux',
    action: 'REQUIRE_MFA_VERIFICATION'
  });
});

Conclusion and Recommendations

Google's action against this Chinese cartel marks an important turning point, but the problem is far from solved. Similar operations continue operating actively.

For your infrastructure, priorities:

Short term (week 1):

  • Implement login rate limiting
  • Enable mandatory 2FA
  • Monitor login anomalies
  • Educate team about phishing

Medium term (month 1):

  • Implement AI-based detection
  • Detailed authentication logs
  • Zero Trust Architecture
  • Regular simulation tests

Long term (quarter 1):

  • ML-based anomaly system
  • SIEM (Security Information Event Management)
  • Incident response playbooks
  • Partnership with SOC (Security Operations Center)

The implementation cost is far less than the cost of a breach. One compromised account can cost $500k+ in investigation, customer notification, and regulatory compliance.

If you want to understand more about application security, I recommend: JWT Authentication: Secure Implementation in Node.js where we explore token-based security.

Let's go! 🦅

📚 Deepen Your DevOps Security Knowledge

Security is a continuous process, not a destination. Developers who understand both development and security are extremely valued in the market.

If you want to master security in modern applications, I've prepared complete material:

Investment options:

  • $4.90 (single payment)

👉 Learn About Web Security Guide

💡 Material updated with current detection and prevention techniques

Comments (0)

This article has no comments yet 😢. Be the first! 🚀🦅

Add comments