Загрузка...

Sqli в боте? Или как украсть нюдсы у тсов

Тема в разделе Python создана пользователем Кассандра 12 июн 2024. (поднята 1 авг 2025 в 08:30) 706 просмотров

  1. Кассандра
    [IMG]

    Вступление
    Всем привет. Начну с небольшой предыстории. На момент жалобы я был на посту проверяющего в разделе программирования. Мне было поручено проверять выполненные тестовые задания, без которых нельзя получить префикс. При проверке учитывается несколько факторов, такие как: структура, умение пользоваться фичами языка и базовые знания работы с бд (ну и другие факторы) . За время работы мне удалось выделить несколько "красных флагов", благодаря которым можно очень быстро выдавать префикс, не продолжая проверку. Одним из них является форматирование sql запросов без экранирования символов или валидации данных. К сожалению, находились люди, которые начинали спорить, говоря, что всегда так делали и ничего плохого не случилось. Да, я соглашусь, кто в здравом уме будет искать скули в боте телеграм) Сегодня решил почистить папку с клонированными репками от ненужного. Во время удаления я наткнулся на папочку с проверенными работами. В дирках я обычно создавал файлик result.md, куда писал итог тестирования. Удаляя и читая результаты(ну как такое не почитать, воспоминания же), наткнулся на свой хештег #sqli . Вдруг, мне стало интересно: а не зря ли я так душил молодых. Запустив код мои сомнения развеялись.

    Сам проект
    Ниже я реализовал базовый функционал, который поможет в демонстрации. В тз был пункт про поиск вещей по части их названия.
    Очень простой способ поиска, который мне все демонстрировали:
    SQL
    select * from table_name where column_name like '%to_search%'
    Написал простенького бота с одним хендлером. (Код накидан мельком для демонстрации)​
    Python
    @dp.message_handler()
    async def test_handler(msg: Message):
    with db.connection:
    db.cursor.execute(f"SELECT * FROM users WHERE data like'%{msg.text}%' ")
    result = db.cursor.fetchall()

    if not result:
    return await msg.answer("Ничего не найдено:( ")

    res_text = ""
    for res in result:
    res_text += f"\nАйди: {res[0]} Значение: {res[1]}"
    return await msg.answer(f"Найдено: {res_text} \n ")
    Sqliter я пока раскрывать не буду, сохраним интригу​


    Начинаем знакомиться
    [IMG]
    Перед лицом у нас тот самый поиск по подстроке:
    Ввожу данные - получаю результат.
    Предлагаю попробовать что-нибудь сломать) Попробуем одинарные и двойные кавычки

    [IMG]
    При двойных поиск отработал штатно, но одинарная что-то натворила. Давайте попробуем починить)
    В sql можно комментировать код при помощи `--` Предлагаю жестко закрыть кавычку и проигнорировать то, что правее нашей точки форматирования

    [IMG]
    Урааа, мы смогли починить! Бежим требовать зп у админа бота.
    Думаем что делать дальше. Я не гуру в sql-injection и всё, что описано здесь, было создано с использованием личных знаний sql и гуглёшки встроенных функций sqlite.
    В sql есть прекрасная вещь, как union Она позволяет объединять таблички на выводе. inner outer lift right и все дела. Я хочу получить список всех табличек в бд. Для этого можно использовать встроенный прикол
    SQL
    select sql from sqlite_master
    Но как это сделать? Union! Единственное, что нам требуется - узнать кол-во возвращаемых в запросе колонок.

    [IMG]
    логично, что у нас больше одной колонки)

    [IMG]
    оп, что-то вышло
    вкидываем наш прикол
    Вот какие таблички у нас есть (1=0 добавил, чтобы из самой таблички значения не брались):

    [IMG]
    [IMG]
    Оп, у нас есть табличка admin_rights, там что-то интересное, смотрим кол-во записей в ней

    [IMG]
    одна запись, как приятно. Давайте прочитаем что там. Название колонок мы знаем.

    [IMG]
    Немного быдлокодим на sql и вауля

    А если мы будем возвращать не звёздочку? Так еще и sqlite3.Row используем!

    Теперь select выглядит так:
    Python
    db.cursor.execute(f"SELECT id, data FROM users WHERE data like'%{msg.text}%' ")
    А вывод так:
    Python
    res_text += f"\nАйди: {res['id']} Значение: {res['data']}"
    [IMG]
    Норм, да?)​


    Вывод очень прост - так не делайте)
    [IMG]
    (id не чекалось, прямой пользовательский ввод)
    [IMG]

    [IMG]тут апдейтик, в тз селекта не было

    К сожалению, это все скрины, которые получилось откопать.
     
    12 июн 2024 Изменено
  2. Skittle_Chan
    Skittle_Chan 12 июн 2024 упорство никогда не заменит талант
    я так только с сайтами делал,а оказывается это можно и тут использовать,мм
     
  3. json
    json 12 июн 2024 1450 13 янв 2023
    хахаха, сяп.
    спасибо за новичка, понял что торопится не надо
    даже в несложных проектах начал использовать ORM.
    но бля новый проверяющий стал уже не проверяющим и все блять, заново делать тз

    так то тебе :+rep: , просто время было чуть-чуть сложное и разозлился.
    p.s. если можно, могу у тебя спросить кое что в тг?)
     
    1. Посмотреть предыдущие комментарии (21)
    2. json
      whom, ну тв проверяющего снял, не знаю
    3. whom
      json, ты видел как себя вел этот проверяющий и какое тестовое он скинул?
    4. json
      whom, мне тоже скинул не сладость и срок 4 дня. итог: полупрофи
  4. LIMP
    LIMP 13 июн 2024 Discover L.I.M.P. say it 240 17 авг 2020
    так я так и не понял, sqlite это хорошо или плохо?
     
    1. Vulgar
      LIMP, экранирование символов или валидацию данных делай и будет тебе спокойный сон и никто не узнает что хранит твоя бд бота
    2. LIMP
      Vulgar, ну вот глянь, вот пример как я использую sqlite, тут есть проблемы?

      Python
      cursor.execute("CREATE TABLE IF NOT EXISTS accounts (id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER, currency TEXT, card INTEGER, username TEXT)")

      ## если что это разные участки кода


      cursor.execute("INSERT INTO accounts (user_id, currency, card, username) VALUES (?, 'byn', 0, ?)", (callback.from_user.id, callback.from_user.username))


      cursor.execute("SELECT * FROM accounts WHERE user_id = ?", (callback.from_user.id,))

  5. squids
    squids 15 июн 2024 можете заказать разработку у меня, не ошибетесь 4633 6 май 2019
    Прошлым летом писал в лс всем ботам, если находил какого-то бота, который не здоровался - сразу понимал, что бот не защищен от инъекций

    У меня было следующее имя в телеграме:
    Код
    '--
     
    1. whom
      squids, хуевая защита так-то, бот-то не работает в конечном итоге. Нужно отражение спец символов юзать, что давно уже есть во всех орм
  6. AIexa
    AIexa 20 июн 2024 Лучший софт - lolz.live/threads/1634798/ :+rep: 12 357 24 мар 2020
    в sqlite есть stmt (prepare если гуглить), которая все сразу фиксит
    Python
    cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('Charlie', 35))
     
    1. Кассандра Автор темы
      AIexa, это да. Некоторые игнорируют эту вещь)
    2. squids
      AIexa, в sqlite такое есть только когда разработку бота заказывают не у школьника за 500 рублей.
    3. whom
      AIexa, самое забавное что уязвимость стара как мир, а люди все равно её допускают
  7. whom
    whom 20 июн 2024 Качественная разработка lolz.live/threads/7145903
    База про sql, джуниоры с форума не хотят учить нормальные ОРМ и из-за этого страдают.

    Помню даже в гарант боте был баг с sqli
    --- Сообщение объединено с предыдущим 20 июн 2024
    А, ну и sqlite3, которая не поддерживает ассинхронность используется в ассинхронном контексте, classique
     
    20 июн 2024 Изменено
    1. Посмотреть предыдущие комментарии (2)
    2. whom
      AIexa, я прочел статью и могу сказать, что джангоОРМ решила почти все проблемы о которых говорит автор.

      Для проектов которые у нас на форуме да и 95% проектов айти в целом ОРМ достаточно, она проще, и код писать банально быстрее.
    3. AIexa
      whom, хз, поверхностно ее видел, но не разбирался. Пока что не работал с проектами, где пришлось бы ее юзать
Top
Загрузка...