Skip to content

Commit

Permalink
Add new features and fixed bugs
Browse files Browse the repository at this point in the history
- Added TeleViewer.py
- Implemented multiprocessing for spamming messages
- Implemented saving results to txt and JSON dumps
- Fixed other misc bugs
  • Loading branch information
tsale committed Jan 22, 2024
1 parent a3fb108 commit 249715d
Show file tree
Hide file tree
Showing 4 changed files with 286 additions and 44 deletions.
7 changes: 6 additions & 1 deletion .gitignore
Expand Up @@ -9,4 +9,9 @@ replit.nix
.upm
__pycache__/*
helpers/__pycache__/*
.vscode/*
.vscode/*
*.session
results.txt
downloads/*
*.json
*.txt
48 changes: 36 additions & 12 deletions README.md
@@ -1,20 +1,23 @@
# TeleTracker

This repository contains Python scripts, `TeleTexter.py` and `TeleGatherer.py`, designed to assist analysts in tracking and disrupting active malware campaigns that use Telegram for command and control (C2) communications.
This repository contains Python scripts, `TeleTexter.py`, `TeleGatherer.py` and `TeleViewer.py`, designed to assist analysts in tracking and disrupting active malware campaigns that use Telegram for command and control (C2) communications.

### TeleGatherer.py

`TeleGatherer.py` is the main script for gathering information regarding the channels of which the bots operate. It provides functionalities to:
- Retrieve basic information about a bot.
- Gather details about a specific chat, including chat administrators and member count.
- Information about the user behind the telegram channel, including Username and provided first and last name.
- Optionally, provides with a menu to choose from:
- Reading all channel messages from a different user or bot. (MONITOR)
- Deleting all messages from the malicious channel. (DISRUPT)
- Spam the malicious channel with a specific message of your choise (DISRUPT)
`TeleGatherer.py` is the main script for gathering intelligence on the activities of threat actors and the data they collect from compromised hosts. It has been updated with new features and improvements:

- [x] View all channel messages and download all uploaded content such as documents, photos, videos, and other media. Content is saved in a directory called 'downloads'.
- [x] Select the number of messages to download, starting from the newest to the oldest.
- [x] Save all text in two formats: pretty text with basic info and full JSON dumps of every message.
- [x] Retrieve basic information about a bot and its owner along with other channel-related information.
- [x] Existing features have undergone many improvements, including bug fixes and enhancements.
- [x] Optionally, provides a menu to choose from:
- ***Reading*** all new messages from a different user or bot. (MONITOR)
- ***Deleting*** all messages from the malicious channel. (DISRUPT)
- ***Spamming*** the malicious channel with a specific message of your choice using multiprocessing to send hundreds of messages per second. (DISRUPT)

> [!NOTE]
> This script could be useful for threat intelligence analysts or reserachers who want to monitor, collect and track adversaries that use Telegram for C2 communication.
> This script is intended for threat intelligence analysts or researchers who want to monitor, collect, and track adversaries using Telegram for C2 communication.
## Installation

Expand All @@ -24,7 +27,7 @@ To use these scripts, Python must be installed on your system, along with the `r
```git clone https://github.com/tsale/TeleTracker.git```

2. Install the required Python package:\
`pip install requests`
`pip install -r requirements`

## Usage

Expand All @@ -38,13 +41,34 @@ To send messages continuously:

`python TeleTexter.py -t YOUR_BOT_TOKEN -c YOUR_CHAT_ID -m "Your message here" --spam`

### Introducing Televiewer.py

`Televiewer.py` is the latest tool, allowing you to view and download all messages and media from the threat actor-controlled telegram channel. You can use this feature by selecting the number 6 from the initial menu after running `TeleGathere.py`. With `Televiewer.py` features, you can:

- View all channel messages and download all uploaded content, including documents, photos, videos, and other media. All downloaded content is saved in a `downloads` directory.
- Specify the number of messages to download, from the newest to the oldest.
- Save all text in two formats: clean, readable text with basic info saved in a Txt file and a comprehensive list of every message saved in a JSON file.

To use `Televiewer.py`, create a Telegram API and add your `API_hash` and `API_id` to the `.env` file. in the below format:

```
API_ID="XXX"
API_HASH="XXX"
```


### TeleGatherer.py

To gather intelligence from a Telegram channel:\
To gather intelligence from a Telegram channel:

`python TeleGatherer.py -t YOUR_BOT_TOKEN -c YOUR_CHAT_ID`

## Recent Updates

- Ability to view and download all types of media from channels.
- Option to select the number of messages for downloading.
- Dual format text saving: pretty text and full JSON dumps.
- Numerous improvements and bug fixes to enhance existing features.

## Disclaimer

Expand Down
149 changes: 118 additions & 31 deletions TeleGatherer.py
Expand Up @@ -4,6 +4,8 @@
import argparse
import multiprocessing
from helpers.TeleTexter import send_telegram_message
from helpers.TeleViewer import process_messages


def parse_dict(title, dictionary):
result = f"{title}:\n"
Expand All @@ -15,6 +17,13 @@ def parse_dict(title, dictionary):
return result + "\n"


def deleteMessage(bot_token, chat_id, message_id):
url = f"https://api.telegram.org/bot{bot_token}/deleteMessage"
data = {"chat_id": chat_id, "message_id": message_id}
response = requests.post(url, data=data)
return response.json()


def get_my_commands(chat_id, bot_token):
url = f"https://api.telegram.org/bot{bot_token}/getMyCommands"
data = {"chat_id": chat_id}
Expand Down Expand Up @@ -64,6 +73,18 @@ def get_chat_member_count(bot_token, chat_id):
return response.json()


def get_latest_messageid(bot_token, chat_id):
response = send_telegram_message(bot_token, chat_id, ".")
if response.get("ok") == True:
message_id = response.get('result').get('message_id')
deleteMessage(bot_token, chat_id, message_id)
return message_id
else:
print("Error: Unable to retrieve latest message id: ",
response.get("description"))
return None


def main(bot_token, chat_id):
# Retrieve information and print in a pretty format
can_read = get_bot_info(bot_token).get('result',
Expand All @@ -89,13 +110,21 @@ def main(bot_token, chat_id):
print("1. Monitor for new messages from a different bot")
print("2. Send a message to the malicious telegram channel")
print("3. Spam the malicious telegram channel with a specific message")
print("4. Delete all messages from the malicious telegram channel")
print("5. EXIT")
print(
"4. Delete all messages from the malicious telegram channel that are sent within 24 hours"
)
print(
"5. Get approximate number of messages on the malicious telegram channel"
)
print("6. Get messages from the malicious telegram channel")
print("7. EXIT")
choice = input("\nEnter your choice: ")
if choice == '1':
offset = None # Variable to keep track of the last update ID
if can_read:
print("\t [*] Administrator persmission granted. Monitoring for new messages....")
print(
"\t [*] Administrator persmission granted. Monitoring for new messages...."
)
while True:
try:
updates = get_updates(bot_token, offset)
Expand All @@ -114,36 +143,94 @@ def main(bot_token, chat_id):

elif choice == '2':
message = input("Enter the message you want to send: ")
send_telegram_message(bot_token, chat_id, message)

response = send_telegram_message(bot_token, chat_id, message)
if response.get("ok") == True:
print("Message sent. Response:")
pprint.pprint(response)

elif choice == '3':
message = input("Enter the message you want to spam: ")
processes = []
for _ in range(1000000000): # Adjust the number of processes as needed
p = multiprocessing.Process(target=send_telegram_message, args=(bot_token, chat_id, message))
p.start()
processes.append(p)

for p in processes:
p.join()

message = input("Enter the message you want to spam: ")
processes = []
for _ in range(1000000000): # Adjust the number of processes as needed
p = multiprocessing.Process(target=send_telegram_message,
args=(bot_token, chat_id, message))
p.start()
processes.append(p)

for p in processes:
p.join()

elif choice == '4':
x = 0
consecutive_not_found = 0
url = f"https://api.telegram.org/bot{bot_token}/deleteMessage"
while consecutive_not_found < 100:
data = {"chat_id": chat_id, "message_id": x}
response = requests.post(url, data=data)
if response.status_code == 200:
print("Message deleted successfully!")
x += 1
consecutive_not_found = 0
elif response.status_code == 400:
consecutive_not_found += 1
time.sleep(0.04) # Delay to respect rate limits, adjust as needed
print(f"Deleted {x} messages from the malicious channel.")

x = get_latest_messageid(bot_token, chat_id)
try:
consecutive_not_found = 0
deleted_num = 0
while consecutive_not_found < 100:
max_retries = 5
for i in range(max_retries):
try:
if x is None:
break
response = deleteMessage(bot_token, chat_id, x)
if response.get("ok") == True:
print(f"Deleted message {x}")
x -= 1
deleted_num += 1
consecutive_not_found = 0
elif response.get("ok") == False and response.get(
"description"
) == "Bad Request: message can't be deleted for everyone":
print(
f"Message {x} is an old message. You can only delete messages that are within 24 hours."
)
x -= 1
elif response.get("ok") == False:
print(f"Message {x} not found.")
consecutive_not_found += 1
x -= 1
except Exception as e:
print(
f"Error: {e}. Attempt {i+1} of {max_retries}. Retrying in 5 seconds..."
)
time.sleep(5)
time.sleep(0.04) # Delay to respect rate limits, adjust as needed
print(f"Deleted {deleted_num} messages from the malicious channel.")
except Exception as e:
print(f"Error: {x}")

elif choice == '5':
message_id = get_latest_messageid(bot_token, chat_id)
if message_id is not None:
print(
f"Approximate number of messages on the malicious channel: {message_id}"
)
else:
print(message_id)

elif choice == '6':
try:
message_id = get_latest_messageid(bot_token, chat_id)
print(f"\t\n TOTAL NUMBER OF MESSAGES: ~{message_id}\n")
num_messages = input(
"Press ENTER to retreive all messages or enter a number (Downloading from Newest to Oldest): "
)
if num_messages == "":
num_messages = message_id
else:
num_messages = int(num_messages)
question = input(
"Would you like to start from a specific message_id? (y/n): ")
if question.lower() == 'y':
message_id = int(
input(f"Enter the message_id offset to start from: "))
if message_id is not None:
process_messages(bot_token, chat_id, num_messages, message_id)
else:
print(message_id)
except Exception as e:
print(f"Error: {e}")

elif choice == '7':
print("Exiting...")
break
else:
Expand All @@ -153,7 +240,7 @@ def main(bot_token, chat_id):
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Telegram Bot Script")
parser.add_argument("-t", "--bot_token", help="Telegram Bot Token")
parser.add_argument("-c", "--chat_id", help="Telegram Chat ID")
parser.add_argument("-c", "--chat_id", help="Telegram Chat ID", type=int)
args = parser.parse_args()

main(args.bot_token, args.chat_id)

0 comments on commit 249715d

Please sign in to comment.