|
#!/usr/bin/env python3 |
|
|
|
|
|
# : : |
|
# : : |
|
# : : |
|
# ______ : : |
|
# |______| : : |
|
# _ | | .' : |
|
# | `-._ | | _.-" : |
|
# __________________|_____`._______ / /____________________________.-.____________ _.-" '. |
|
# __.`-------------------____----------`--/`._.`-----| o| | ..__...____...-" : |
|
# || (____) | LGB | ====================== |____________| : \_\ : |
|
# ||_______________________________________|__________| ====================== | : .--" : |
|
# '-._o o____(_)_____________| ============= ____..o---' `.__/ .-" _ : |
|
# `. __0-------''-` `---..--._(|_o______.-----` `.O.` / / ," ,- .' |
|
# ) o .' // || __//__ (_)(`,(_,'L_,_____ ____....__ _ |
|
# / ( \\ || `------` "' " """ """" .'cgmm |
|
# / \___________// |
|
# / __/-----------` |
|
# _./ ( |
|
# _.-` ) ==================================================================================================================================== |
|
# \\ ( = ==== ====== ==== === === ==== == ======= ========== ===== ======== == === == = |
|
# \\ _ o ) = ========= == ==== == ====== ===== == == ==== == ====== ========= ==== ======== ======== ==== ===== ===== = |
|
# \\_.-` ( = ======== ==== == ==== ===== ===== ==== == ==== == ===== ======== == === ======== ======== ==== ===== ===== = |
|
# (_____________) = ======== ==== == ==== ===== ===== ======== ==== == == === ======= ==== == ======== ======== === ===== ===== = |
|
# = ==== ==== == ==== ===== ===== ======== ==== == === == ======= ==== == ======== ==== ======= ===== = |
|
# = ======== ==== == ==== ===== ===== === == ==== == ==== = ======= == ======== ======== ==== ===== ===== = |
|
# = ======== ==== == ==== ===== ===== ==== == ==== == ===== ======= ==== == ======== ======== ==== ===== ======== |
|
# = ========= == ==== == ====== ===== == == == == ====== ======= ==== == ======== ======== ==== ===== ===== = |
|
# = ========== ====== ======= ====== ==== === ======= ======= ==== == == == ==== ===== ===== = |
|
# ==================================================================================================================================== |
|
""" |
|
🚨 FOOTGUN ALERT: SERIOUS SECURITY RISKS 🚨 |
|
|
|
This bot executes Claude commands DIRECTLY on your host system with NO SANDBOXING. |
|
|
|
RISKS: |
|
- Claude can read/write ANY file your user has access to |
|
- Claude can execute system commands and scripts |
|
- Claude can install software, modify configurations |
|
- Claude can access your SSH keys, browser data, documents |
|
- If your Telegram account is compromised, attackers get full system access |
|
- Claude's --dangerously-skip-permissions flag bypasses all safety checks |
|
|
|
SAFER ALTERNATIVES: |
|
1. Use the Docker version for proper isolation |
|
2. Run this on a dedicated VM with limited access |
|
3. Use a restricted user account with minimal permissions |
|
4. Never run this on a machine with sensitive data |
|
|
|
YOU HAVE BEEN WARNED. Use at your own risk. |
|
""" |
|
|
|
import json |
|
import os |
|
import subprocess |
|
import sys |
|
from datetime import datetime |
|
from pathlib import Path |
|
|
|
from telegram import Bot, Update |
|
from telegram.ext import ( |
|
Application, |
|
CommandHandler, |
|
MessageHandler, |
|
filters, |
|
ContextTypes, |
|
) |
|
|
|
# Additional runtime warning |
|
print("=" * 60) |
|
print("🚨 SECURITY WARNING 🚨") |
|
print("This bot runs Claude with FULL SYSTEM ACCESS") |
|
print("Press Ctrl+C now if you're not sure about the risks") |
|
print("=" * 60) |
|
|
|
|
|
class ClaudeTelegramDaemon: |
|
def __init__(self, token: str, chat_id: str): |
|
self.token = token |
|
self.chat_id = chat_id |
|
self.bot = Bot(token) |
|
|
|
async def handle_message(self, update: Update, context: ContextTypes.DEFAULT_TYPE): |
|
""" |
|
⚠️ WARNING: This executes Claude with full system access! |
|
Handle incoming telegram messages and execute Claude commands. |
|
""" |
|
message = update.message |
|
if not message or not message.text: |
|
return |
|
|
|
# Only respond to messages from our configured chat |
|
if str(message.chat_id) != self.chat_id: |
|
return |
|
|
|
user_message = message.text |
|
print(f"[{datetime.now()}] ⚠️ EXECUTING UNSANDBOXED: {user_message}") |
|
|
|
# Build and execute the Claude command with streaming JSON output |
|
cmd = [ |
|
"claude", |
|
"--dangerously-skip-permissions", # ⚠️ THIS IS THE DANGEROUS PART |
|
"--verbose", |
|
"--output-format", |
|
"stream-json", |
|
"-p", |
|
user_message, |
|
] |
|
|
|
try: |
|
print(f"[{datetime.now()}] ⚠️ Executing Claude command...") |
|
|
|
process = subprocess.Popen( |
|
cmd, |
|
stdout=subprocess.PIPE, |
|
stderr=subprocess.PIPE, |
|
text=True, |
|
cwd=str(Path(__file__).parent.parent), |
|
) |
|
|
|
results = [] |
|
error_occurred = False |
|
|
|
# Read streaming JSON objects line by line |
|
for line in process.stdout: |
|
if line.strip(): |
|
try: |
|
json_obj = json.loads(line.strip()) |
|
|
|
# Handle errors |
|
if json_obj.get("is_error", False): |
|
error_occurred = True |
|
error_msg = json_obj.get("result", "Unknown error") |
|
await message.reply_text(f"Error: {error_msg[:4000]}") |
|
print(f"[{datetime.now()}] Error: {error_msg}") |
|
|
|
# Handle results |
|
elif "result" in json_obj and json_obj["result"]: |
|
result_text = json_obj["result"] |
|
results.append(result_text) |
|
|
|
# Send result in chunks if needed (Telegram max is 4096 chars) |
|
for i in range(0, len(result_text), 4096): |
|
await message.reply_text(result_text[i : i + 4096]) |
|
|
|
except json.JSONDecodeError: |
|
print( |
|
f"[{datetime.now()}] Failed to parse JSON: {line.strip()}" |
|
) |
|
continue |
|
|
|
process.wait() |
|
|
|
# Handle completion |
|
if process.returncode == 0 and not error_occurred: |
|
if not results: |
|
await message.reply_text( |
|
"Command completed but no output was returned." |
|
) |
|
print(f"[{datetime.now()}] Claude command executed successfully") |
|
elif process.returncode != 0: |
|
stderr_output = process.stderr.read() |
|
error_msg = f"Error executing Claude command:\n{stderr_output}" |
|
print(f"[{datetime.now()}] {error_msg}") |
|
await message.reply_text(f"Error: {stderr_output[:4000]}") |
|
|
|
except Exception as e: |
|
error_msg = f"Exception executing Claude: {str(e)}" |
|
print(f"[{datetime.now()}] {error_msg}") |
|
await message.reply_text(error_msg) |
|
|
|
async def start_command(self, update: Update, context: ContextTypes.DEFAULT_TYPE): |
|
"""Handle /start command.""" |
|
await update.message.reply_text( |
|
"CLAUDE TELEGRAM DAEMON\n\n" |
|
"🚨 WARNING: This bot has FULL ACCESS to your system!\n" |
|
"Claude can read files, execute commands, install software.\n\n" |
|
"Send messages carefully. Consider using the Docker version instead.\n\n" |
|
"Type anything to execute it with Claude..." |
|
) |
|
|
|
def run(self): |
|
"""Run the telegram bot.""" |
|
print(f"Starting Telegram bot for chat ID: {self.chat_id}") |
|
|
|
application = Application.builder().token(self.token).build() |
|
|
|
# Add handlers |
|
application.add_handler(CommandHandler("start", self.start_command)) |
|
application.add_handler( |
|
MessageHandler(filters.TEXT & ~filters.COMMAND, self.handle_message) |
|
) |
|
|
|
# Run the bot |
|
application.run_polling(drop_pending_updates=True) |
|
|
|
|
|
if __name__ == "__main__": |
|
# Get configuration from environment |
|
token = os.environ.get("TELEGRAM_BOT_TOKEN") |
|
if not token: |
|
print("Error: Please set TELEGRAM_BOT_TOKEN environment variable") |
|
sys.exit(1) |
|
|
|
chat_id = os.environ.get("TELEGRAM_CHAT_ID", "") |
|
if not chat_id: |
|
print("Error: Please set TELEGRAM_CHAT_ID environment variable") |
|
sys.exit(1) |
|
|
|
bot = ClaudeTelegramBot(token, chat_id) |
|
bot.run() |