LIMB
Вход Регистрация

тема

Про тестирования телеграм ботов

Romanoff · · 0 ответов · 479 просмотров

Телеграм боты это просто публичные API с пользовательским вводом, в каком-то смысле в мире не существует телеграм ботов 

Да, их не много, да, поиска как такового нет, и все же, забавный факт, любой телеграм бот с функциональностью скринов сайтов, не работает, почему так? 

Гитхабы скажут больше: 
https://github.com/D1n03awr1k/telegram-screenshot-bot (наглядно) 
https://github.com/zaqqazzaqqaz89-del/telegram_screenshot_bot/blob/main/screenshot_service.py (Открывает Playwright - делает скриншот)   
https://github.com/Kamakepar2029/web_screenshot_tg_bot/blob/main/main.py (возвращает HTML)
https://github.com/SergioKK/ScreenshotTelegramBot/blob/master/ScreenshotTelegramBot.py  
https://github.com/JustLike420/TelegramScreenshoter/blob/main/utils/screenshoter.py 

SSRF. Везде. Буквально в каждом репозитории. Их сотни.

Спойлер: CTF код
Python:
import json
import time
import urllib.request

from playwright.sync_api import sync_playwright

def screenshot(url):
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True)

        page = browser.new_page(viewport={
            "width": 1280,
            "height": 720
        })

        page.goto(url, wait_until="networkidle")
        page.screenshot(path="screen.png")

        browser.close()

def send_photo(chat_id, file):
    boundary = "----1234567890"

    data = []

    data.append(f"--{boundary}\r\n".encode())
    data.append(b'Content-Disposition: form-data; name="chat_id"\r\n\r\n')
    data.append(f"{chat_id}\r\n".encode())

    data.append(f"--{boundary}\r\n".encode())
    data.append(b'Content-Disposition: form-data; name="photo"; filename="screen.png"\r\n')
    data.append(b"Content-Type: image/png\r\n\r\n")

    with open(file, "rb") as f:
        data.append(f.read())

    data.append(f"\r\n--{boundary}--\r\n".encode())

    req = urllib.request.Request(
        URL + "sendPhoto",
        data=b"".join(data),
        headers={
            "Content-Type": f"multipart/form-data; boundary={boundary}"
        }
    )

    urllib.request.urlopen(req).read()

def load_env():
    env = {}

    with open(".env", encoding="utf-8") as file:
        for line in file:
            line = line.strip()

            if not line or line.startswith("#"):
                continue

            key, value = line.split("=", 1)
            env[key] = value

    return env


TOKEN = load_env()["TOKEN"]
URL = f"https://api.telegram.org/bot{TOKEN}/"


def api(method, data=None):
    if data is None:
        data = {}

    req = urllib.request.Request(
        URL + method,
        data=json.dumps(data).encode(),
        headers={
            "Content-Type": "application/json"
        }
    )

    with urllib.request.urlopen(req) as response:
        return json.loads(response.read())


def send(chat_id, text):
    api("sendMessage", {
        "chat_id": chat_id,
        "text": text
    })

offset = 0

updates = api("getUpdates")

if updates["result"]:
    offset = updates["result"][-1]["update_id"] + 1

print("Бот запущен. Для остановки нажми Ctrl+C.")

try:
    while True:
        updates = api("getUpdates", {
            "offset": offset,
            "timeout": 1
        })

        for update in updates["result"]:

            offset = update["update_id"] + 1

            message = update.get("message")
            if not message:
                continue

            text = message.get("text")
            if not text:
                continue

            chat_id = message["chat"]["id"]

            if text.startswith("/screen "):
                url = text.split(maxsplit=1)[1]

                try:
                    screenshot(url)
                    send_photo(chat_id, "screen.png")
                except Exception as e:
                    send(chat_id, str(e))

        time.sleep(1)

except KeyboardInterrupt:
    print("\nБот остановлен.")
👍46 🔥6 👏7 🤔12 😢7

Гостевой просмотр. Чтобы отвечать и ставить реакции, войдите или зарегистрируйтесь.