es
Feedback
БАГодельня

БАГодельня

Ir al canal en Telegram

Канал про разработку и безопасность: код, костыли, разбор задач, ревью и размышления. Вещает руководитель отдела разработки: @ipatove Сайт: https://bug-makers.ru Поддержать проект: https://boosty.to/bugctf/donate

Mostrar más
2 608
Suscriptores
-124 horas
-57 días
+2230 días
Archivo de publicaciones
Опубликованы новые задания Пять новых задач доступны на площадке! 📌 Rev / Стружка-код 📌 Misc / Учебная граната 📌 Web / Дес
Опубликованы новые задания Пять новых задач доступны на площадке! 📌 Rev / Стружка-код 📌 Misc / Учебная граната 📌 Web / Десериализатор 📌 OSINT / Абрикос-персик 📌 OSINT / Лёха и кожа Как объявлял ранее, задания теперь будут выходить по субботам в одно и тоже время – в 12:00 по МСК. Следующий релиз через неделю. Отбивки о первых трех самых быстрых решениях на каждую задачу приходят в наш чат. Так же там можно пообщаться и обсудить сложности, если они возникают в процессе решения. Кто первый решит, тот молодец. Поехали! ——— #⃣ #Задачи #CTF 🐞 Канал // Чат // Задачи

Новостной дайджест #2 Доброго здравия всем! Вот и наступило воскресенье, а значит — пора выпускать новости из мира ИБ и IT. �
Новостной дайджест #2 Доброго здравия всем! Вот и наступило воскресенье, а значит — пора выпускать новости из мира ИБ и IT. 📌 Японцы временно остались без пива Японская компания Asahi Group (что-то вроде нашей пивоваренной компании «Балтика») объявила о «сбое систем из-за кибератаки». Были остановлены приём заказов, отгрузки и работа колл-центров. В результате компании пришлось перейти на ручные операции, в приоритете у которых — еда и безалкогольные напитки. Утечки персональных данных не подтверждены, но, по сообщениям медиа, пива на всех желающих уже не хватает. Остаётся лишь ждать восстановления инфраструктуры — официальных сроков пока нет. Моё мнение: это полная катастрофа. 🌐 Источник 📌 Утечка данных авиокомпании WestJet Канадская авиакомпания WestJet подтвердила утечку данных почти 1,2 миллионов пассажиров: имена, даты рождения, документы и детали поездок. Кредитные карты затронуты не были. Детали атаки: 13 июня была зафиксирована «подозрительная активность», после чего компания ограничила работу приложения и сайта и начала форензику. Злоумышленников описали как «сложную криминальную третью сторону», проникшую в систему. Глубоких публичных деталей — что именно затронули и кто стоит за атакой — пока нет. Остаётся загадкой. 🌐 Источник 📌 Взлом медицинского центра Shamir Medical Center Что ж, предыдущая новость оказалась с налётом мистики, но следующая — ещё интереснее. Группировка Qilin (растущая в масштабах атак) заявила о взломе Израильского Shamir Medical Center, выдвинув ультиматум: 700 тысяч долларов за 72 часа. Они утверждают, что похитили до 8 ТБ данных пациентов и внутренних документов. Послание было адресовано «Биби (и Бобе) и Саре». Как часто бывает в государственных интригах, здесь две версии: Qilin заявляет о полном доступе к системе, а власти пишут, что атака была обнаружена на ранней стадии и остановлена (при этом подтвердили утечку части электронных писем с медицинской информацией). Масштабы и типы украденных данных на сегодняшний день ещё уточняются. Публичного дампа данных пока нет. 🌐 Источник 📌 Новости из РФ Хотелось бы завершить наш дайджест новостями из России за эту неделю, но их, по сути, и нет — в этот раз всё спокойно. Зато вот вам факт из отчёта за 3 октября: Глобально DDoS-активность за полугодие выросла на 83%; Россия вошла в топ-10 по числу атак (6-е место) в мире. На первом — США, на втором — Индия, на третьем — Китай. В России больше всего DDoS-атак пришлось на онлайн-ритейл, телекомы и образовательные организации. 🌐 Источник и больше статистики И на этом у меня пока всё. Встретимся в следующий раз! Пишите комментарии и делитесь этими новостями с друзьями. Пока-пока! ——— #⃣ #Новости 🐞 Канал // Чат // Задачи

Площадка с CTF-задачами 📖 Как-то случайно и само собой получилось, что мы запустили сайт с тренировочными задачками. Занимат
Площадка с CTF-задачами 📖 Как-то случайно и само собой получилось, что мы запустили сайт с тренировочными задачками. Заниматься подобным совсем не было цели, все задачи планировались как примеры к постам с разборами и пояснениями различных проблем в коде. Но как-то завертелось, ребята подключились, которые решают и которые помогают делать задачи. И теперь уже некуда отступать, нужно продолжать. Тем более, что новые участники постоянно приходят и пытаются решать. Будем и дальше поддерживать, и развивать площадку. Только немного систематизируем подход, чтобы выходы задач были предсказуемыми и можно было честно соревноваться в скорости решения – релизы в конкретное время и день недели. Первая тройка решивших автоматически объявляется ботом в нашем чате. Чатик, кстати, тоже оживился и постоянно пополняется. Кроме статистики, там можно пообщаться про задачи, разработку и вообще на любую другую отвлеченную тему – кому интересно, заходите. 📌 Ближайшее время на площадке добавится короткие подсказки-разборы в задачах, которые имеют мало решений, чтобы можно было подсмотреть, как решать и в будущем подобную задачу уже было понятнее с какой стороны можно одолеть. Такие подсказки будут снимать часть очков за решение, чтобы было справедливое табло с рейтингом участников. Пока плотно занимаюсь площадкой, посты по разработке и разборы выходят пореже, но они вернуться, как только появится больше свободного времени. 📌 Немного статистики по площадке: – Сайт запущен ровно 1 месяц назад – Опубликовано 35 заданий – Зарегистрировалось 124 человека – 58 человек смогли что-то решить и попасть на Scoreboard – Сдали верных флагов: 480 штук – Ошибочных флагов: 1156 штук 📌 Если у вас тоже есть идеи задач, не стесняйтесь и присылайте мне в личку – будем публиковать. Сейчас почти половина заданий, это те, что присылают ребята. Спасибо им за это, сам бы я точно не справился в одиночку. Авторство есть в описаниях задач, можете ознакомиться с этими героями на сайте. ❗️Важный анонс. Теперь задачи будут публиковаться по субботам в 12:00 по Московскому времени. Это может быть как одна, так и сразу несколько задач, смотря сколько успеем подготовить. Отбивки о публикациях новых задач буду выкладывать сюда в группу. ❗️И напоследок – опубликована новая задача «Мозаика внутри PNG» в категории Stegano. ——— #⃣ #Задачи #CTF 🐞 Канал // Чат // Задачи

Локальный домен devilbox показывает казино 📖 Devilbox – это локальный веб-сервер на основе Docker. Простой и удобный инструм
Локальный домен devilbox показывает казино 📖 Devilbox – это локальный веб-сервер на основе Docker. Простой и удобный инструмент с кучей предустановленных версий php и приложений, нужных для веб-разработки: MySql, Redis, Elasticsearch и тд. Когда много разных проектов на php, то довольно удобно использовать и быстро переключаться. При запуске локального веб-сервера создается локальный хост. Его можно сделать какой угодно, но по умолчанию запускается dvl.to. И уже к этому домену можно быстро создавать любые поддомены для разных локальных проектов, например, test.dvl.to или back-1.dvl.to и так далее. Devilbox автоматически резолвит имена этих виртуальных хостов и на локальном компьютере в браузере открывается локальный проект. 📌 Но сегодня у Devilbox начались проблемы. Сперва не разобрались в чем дело – аякс-запросы из фронта к бекенду на свой же хост стали выдавать ошибки CORS, которые случаются только при запросах между разными хостами. А потом в запаре разработчик скинул в чат ссылку на свою локалку, вместо тестового хоста и тут все встало на свои места. При переходе по ссылке открылся не рабочий тестовый сайт, а сайт с казино. При повторном переходе сайт с вебкамщицами, а потом и совсем порнуха. Оказалось, что кто-то купил домен dvl.to и настроил его dns-ы так, что сам домен и его поддомены выполняют редирект на рекламу чернухи. Проверить DNS-ы домена можно тут: https://mxtoolbox.com/SuperTool.aspx 📌 Исправляется проблема просто – нужно или изменить основной локальный домен для Devilbox или в хостах прописать ip своей локалки. Но сама ситуация интересная и очень комичная: кто-то выкупил дефолтный домен локального веб-сервера и делает редиректы на чернушную рекламу. ❗️ И анонс, который в сториз от канала уже был сегодня – в 21:00 по МСК выйдут две новые задачи на площадке с ctf-задачами. ——— #⃣ #Юмор #Devilbox 🐞 Канал // Чат // Задачи

Новостной дайджест #1 ⚡️ Подборка самых интересных событий из мира информационной безопасности за эту неделю. Сбором и обрабо
Новостной дайджест #1 ⚡️ Подборка самых интересных событий из мира информационной безопасности за эту неделю. Сбором и обработкой данных занимался Дмитрий Кустовский из команды БАГодельня. 📌 Интерлюдия Я – Евгений Ипатов, автор канала, перестал успевать во всех направлениях, в которые стала расти БАГодельня. Как-то само собой получилось, что мы запустили площадку с задачами (там их уже 30 шт.) – туда нужно готовить таски и следить за их корректной работой. Также параллельно занимаемся разработкой полноценного сайта. Ну и основная работа у меня есть. Однако во всей этой суете не хочется забывать про главное в БАГодельне – посты на канал. Авторские заметки с разборами задач, алгоритмами и прочими разработческими штуками никуда не денутся, просто их будет чуточку меньше, как вы уже, наверняка, заметили. Чтобы материалов на канале не стало меньше и немного разбавить посты про задачи, добавим новую рубрику – новостной дайджест, который будет выходить раз в неделю по воскресеньям. В этом мне помогут ребята из команды, которые увлекаются OSINT-ом, это как раз их стезя. А теперь передаю слово Диме, он приготовил классную подборку со своими комментариями. 📌 Новости из мира ИБ 📖 Привет всем! Меня зовут Дмитрий Кустовский (или же 3T0T_FL4G_1MB4). Я — молодой участник команды БАГодельня с апреля, буду вести нашу новую рубрику новостей из сферы цифровой безопасности на канале 😁 Давайте же перейдём сразу к теме. ⚡️ Открывает рубрику у нас новость из Америки, где подросток взломал казино. Ему не пришлось как-то ломать подсеть или в целом прибегать к манипуляциям с кодом. Он просто... прикинулся айтишником компании и через LinkedIn убедил техподдержку сбросить пароль. Ну и дальше по классике: появился доступ к внутренним сервисам, а после этого — сбои в работе самого казино. Итог такой деятельности — ущерб в 100 МИЛЛИОНОВ долларов. Более подробно в источнике. ⚡️ Идём дальше, и КРУЧЕ. В Иране буквально рухнул крупнейший банк Sepah — клиенты лишились доступа как к онлайн-сервису, так и к банкоматам. И здесь без преуменьшения, ведь при попытке переключиться на резервные площадки было также невозможно — хакеры и тут постарались, всё повреждено. Даже есть информация о том, что был не только удалённый взлом, но и физический. Можно сказать, банк какой-то невезучий. Всё потому, что на ЭТОТ ЖЕ банк ранее совершила атаку другая хакерская группа. Они украли 12 ТБ данных (около 42 миллионов клиентов). В них вошли пароли, совершённые транзакции и аккаунты. Группировка требовала выкуп в размере 42 миллионов долларов в биткоинах взамен на то, что они не сольют данные в сеть. Банк старался успокоить народ и отрицал взлом, на что хакеры выпустили в сеть часть данных. Подробнее про невезучий банк: тут. ⚡️ И напоследок — ближе к нашим краям. 22 августа на наш портал «Госуслуги» была совершена массовая DDoS-атака из-за рубежа. Всего за час, по данным Downdetector, было зафиксировано 122 жалобы на работу портала, а за сутки — 1271 жалоба. В тот же период велись крупные атаки на другие государственные сервисы. По информации — ничего не пострадало, кроме нервов людей, кому понадобились Госуслуги в тот момент. Все отбились, всё хорошо. Подробнее в источнике. 👨‍💻 И на этой ноте завершаю нашу сводку новостей. Буду и дальше сёрфить интернет в поисках интересной информации для вас! Встретимся в следующее воскресенье! ❗️Ждем ваши комментарии по этим новостям и в целом по новому формату – пишите под постом или сразу в наш чат. ——— #⃣ #Новости 🐞 Канал // Чат // Задачи

Призовая задача «Двери» ❗️ Эта задача анонсировалась заранее и за ее решение первая тройка решивших получит небольшие призы:
Призовая задача «Двери» ❗️ Эта задача анонсировалась заранее и за ее решение первая тройка решивших получит небольшие призы: 3 месяца премиум в телеграм. Решения в призовой зачет принимаются до 4 октября 12:00 по МСК. 📌 В этот раз задание разбито на две части. Первая в категории Stegano – «Дверь», ее решение помимо флага, дает подсказку и доступ ко второй части челенджа – задача из категории Misc «Двери». Для получения приза необходимо решить обе задач, успеть сделать это за неделю, и стать одним из трех самых быстрых. 📌 Ответы в зачет принимаются до 4 октября 12:00 МСК, есть ровно неделя на решение. Потом будет пост с полным разбором этой задачи и объявлением победителей. Кто первый, тот молодец. Поехали! ❗️ Ссылки на задачи: – Первую часть: Дверь – Вторая часть: Двери ——— #⃣ #Задачи #CTF #Misc 🐞 Канал // Чат // Задачи

Задача «Практикующий жонглер» от DUCKERZ 📖 Ребята из DUCKERZ – команда CTF-еров, у которых тоже есть площадка с задачами, пр
Задача «Практикующий жонглер» от DUCKERZ 📖 Ребята из DUCKERZ – команда CTF-еров, у которых тоже есть площадка с задачами, прислали нам челендж из категории web. Он уже опубликован на сайте – «Практикующий жонглер». Давайте пробовать решать :) И как всегда, если будут сложности – заходите в чат, там можем обсудить и помочь друг другу! А кто первый справится, тот молодец. Поехали! Решать задачу: Практикующий жонглер. ❗️P.S. Прошлую неделю пропустили, но в эту субботу в 12:00 по МСК выйдет призовая задача на скорость, символические призы получит первая тройка самых быстрых. ——— #⃣ #Задачи #CTF #Web 🐞 Канал // Чат // Задачи

Слепая SQL-инъекция. Часть 2 Вторая часть, продолжение предыдущего поста «Слепая SQL-инъекция». 📖 Такие атаки, где нет явног
Слепая SQL-инъекция. Часть 2 Вторая часть, продолжение предыдущего поста «Слепая SQL-инъекция». 📖 Такие атаки, где нет явного ответа сервера о результате запроса, на БД сложно выполнять в «ручном режиме», нужно писать скрипты или пользоваться готовыми инструментами. Самый мощный инструмент для таких целей – sqlmap. Он умеет работать полностью автоматически, если передать нужный адрес уязвимости и правильный набор параметров. Для тестирования этого инструмента и подобных типов уязвимостей, опубликовано две задачки на нашей площадке. Первая уязвимость отвечает true/false, а вторая совсем ничего не подсказывает, и в добавок ограничена по ресурсам, чтобы потренироваться с настройками таймингов. 📌 Запуска sqlmap на примере второй задачи опишу, тут больше всего флагов:
sqlmap -u "http://31.207.77.216:4005/check?number=1" --technique=T --time-sec=2 --delay=1 --timeout=3 --dbms=SQLite --hex --level=5 --risk=3 -T flag -C flag --dump -v 6
-u "http://31.207.77.216:4005/check?number=1" – адрес цели --technique=T – указываем тип техники для атаки Time-based --time-sec=2 – время задержки для проверки условий --delay=1 – интервалы задержек между запросами --timeout=3 – ожидание ответа сервера --dbms=SQLite – тип субд --hex – кодирование данных --level=5 – уровень тестирования(от 1 до 5, 5 максимальный набор) --risk=3 – уровень риска(1-3, на сколько заметный пейлоад в запросе) -T flag -C flag – имена целевой таблицы и колонки --dump – получение данных -v 6 – уровень дебага при работе программы И это только часть флагов, которые доступны в утилите sqlmap. Инструмент умеет автоматически определять СУБД, извлекать имена БД, имена и структуры таблиц, а так же собирать и выкачивать полный дамп базы данных. 📌 Инструменты – это хорошо, но в самых не стандартных ситуациях спасают только самодельные скрипты. К тому же написание скриптов это еще и гимнастика для мозгов, а самое главное – способ детальнее погрузиться в тему и разобраться в вопросе более детально. Хорошо пользоваться готовым инструментов, когда понимаешь как он устроен. Поэтому для примеров решения задачек прикладываю еще два скрипта, которые помогут более детально разобраться в способах применения слепой инъекции. 📌 Скрипты нахождения флагов из тестовых задачек на тему поста: Первый скрипт – простой брутфорс флага из таблицы по одному символу: скрипт. Второй скрипт, который использует бинарный поиск для оптимизации и ускорения: скрипт. ❗️ Потренировать можно тут: – Слепая инъекцияСовсем слепая инъекция ——— #⃣ #SQL #БазаЗнаний 🐞 Канал // Чат // Задачи

Слепая SQL-инъекция. Часть 1 📖 Про sql-инъекции уже был пост, в том примере был понятен результат запросов – при добавлении
Слепая SQL-инъекция. Часть 1 📖 Про sql-инъекции уже был пост, в том примере был понятен результат запросов – при добавлении инъекций, сайт отдавал результат выполнения запросов к базе данных. Это был описан пример UNION-инъекции. Но такого «подарка» с удобным дебагом не всегда можно получить, чаще уязвимые эндпоинты ничего не отвечают или результат запроса можно определить только по косвенным данным. Когда есть хоть какой-то признак успешного выполнения запроса, то логика сводится к бинарной – успешно прошел запрос или нет. В таких случаях инъекции нужно строить с условиями. В случае вставки или удаления данных все понятно, а для получения значений, нужно немного помудрить. Целиком получить имя БД, таблиц и значения из них уже не получится, однако можно вытянуть нужную информацию по символу – разделяя результат посимвольно с помощью substr и перебором сравнивая с алфавитом. 📌 Пример инъекции:
1 AND (SELECT SUBSTR(flag_column,{position},1) FROM flag LIMIT 1) = '{char}'
Где {position} – это позиция символа, который пытаемся определить для записи из колонки flag_column в таблице flag. А {char} – это символ, с которым сверяемся. Если мы угадали первый символ, то запрос будет содержать какой-то ответ, поскольку условие вернет true. Так перебирая по одному символу и опираясь на статус ответа запроса, можно получить не только значения из таблицы, но и саму структуру таблиц. Например, в mysql можно сделать запрос к INFORMATION_SCHEMA, которая возвращает список и описание таблиц. 📌 Чтобы не делать полный брутфорс 95 печатных символов ASCII(от 32 до 126), из которых может состоять текст(имена таблиц, содержимое и тд), можно ускорить поиск в 13-14 раз с помощью бинарного поиска: log₂(95) ≈ 7 запросов на один символ. В самой инъекции меняется только условие >= '{char}', вместо равенства стало неравенство. Так мы существенно оптимизируем поиск. 📌 Однако, если сервер совсем никак не реагирует на инъекции и всегда отвечает одинаково, такой подход не сработает, поскольку нет никаких признаков, которые бы сигнализировали об успешном нахождении правильного символа. Но и такую проблему можно решить – с помощью техники Time-based. При успешном выполнении условия, мы умышленно загружаем и/или делаем паузу на стороне сервера, чтобы по времени ответа можно было определить успешность запроса. В mysql такое легко сделать с помощью: SLEEP(3), где 3 – это количество секунд, на которые «задумается» mysql. Дальше, остается только изменить логику обработки – вместо самих ответом запросов, опираться на их время выполнения. В некоторых СУБД нет sleep или он может быть отключен в настройках. В подобных случаях можно самим сделать задержку – использовать в запросах сложные или рекурсивные расчеты, которые так же вызовут задержку ответа. К примеру, в sqlite нет sleep, но есть функция randomblob, которая генерирует рандомные байты, и если запросить большое количество, то запрос может подвисать на несколько секунд. 📌 Как защититься Точно так же, как и с другими типами инъекций – экранировать все данные, которые используются в запросах. Вредоносные данные могут приходить на публичные эндпоинты и на приватные, через другие методы или прослойки. Любой запрос к базе данных должен быть экранирован, даже если он на прямую не использует публичные данные. ❗️Для тестирования подобных инъекций опубликовано две задачи на нашей площадке, на них можно потренироваться: – Слепая инъекцияСовсем слепая инъекция 👨‍💻 Не влезает все в один пост. Тут только теоретическая часть, следом выйдет второй пост со скриптами и описанием инструментов. ——— #⃣ #SQL #БазаЗнаний 🐞 Канал // Чат // Задачи

Задача «Тест по YAML». Разбор и победители 📖 6 сентября запускали задачку «Тест по YAML», за ее решения были назначены призы
Задача «Тест по YAML». Разбор и победители 📖 6 сентября запускали задачку «Тест по YAML», за ее решения были назначены призы первым трем решившим. Задачу на данный момент одолели шесть человек. Первая тройка по времени решения: 🥇 fASTYYY – приз 3 месяца премиум телеграм вручен 🥈 AlexB – приз 250 звезд телеграм вручен 🥉 xof – приз 100 звезд телеграм. Отказался от приза в пользу фонда развития БАГодельни 😁 Поздравляю! Кому интересна задача, можно попробовать свои силы тут: площадка с задачами. 📌 Разбор задачи Смысл задания был в том, чтобы передать не сервер такой текст Yaml, который будет парситься двумя версиями Yaml: 1.1 и 1.2. И результат парсинга должен отличаться, не равные результаты нужно получить, причем версия 1.1 должна сформировать число 1337. Задача показывает, как сильно могут отличаться парсеры в зависимости от версии. И что это нужно учитывать в разработке, чтобы не попасть в неприятности при обновлении библиотек или рефакторинге кода. К тому же, кроме отличий в версиях парсинга, Yaml в некоторых случаях выполняет преобразования значений весьма неочевидным образом, что тоже может легко привести к неприятным сюрпризам. Есть очень наглядный квиз, который показывает проблемы и странное поведение Yaml. Проверить свои навыки можно в задаче(часть показано в тесте) и в оригинальном квизе, откуда скопированы эти вопросы(тут из больше - 22 шт): ohyaml.wtf. 📌 Решение Решить можно было несколькими способами. Я знаю два решения, но подозреваю, что можно придумать еще несколько, если кто-то знает еще варианты – присылайте в комментарии. Первое решение Yaml версии 1.1 поддерживает шестидесятеричное число, которые можно передавать в формате a:b, которое потом преобразуется в десятичное по формуле a * 60 + b. Видимо, эта функция высчитывала количество минут, если передать часы:минуты. Но в версии Yaml 1.2 такая запись уже не обрабатывается и парсится как обычная строка. Поэтому если передать 22:17, то в версии 1.1 это будет 22 * 60 + 17 = 1337. А в 1.2 это просто строка «22:17». Таким образом значения будут отличаться, и версия 1.1 сформирует нужное, для получения флага, значение Второе решение Решение основано также на системе исчисления, только уже восьмеричной. Если Yaml 1.1 обрабатывает значение, которое имеет ведущий ноль и остальные цифры не превышают 7, то такое значение конвертируется из восьмеричного в десятичное число. Поэтому, если парсить 02471, то версия 1.1 преобразует его в десятичное 1337. А Yaml версии 1.2 посчитает такое значение строкой и оставит «02471». 📌 Полезные ссылки – Попробовать решить задачку: тут – Квиз про парсинг в Yaml: ohyaml.wtf – Статья на Habr: «YAML из Ада» ——— #⃣ #Задачи #Разбор #CTF 🐞 Канал // Чат // Задачи

Выборка WHERE txt_field = 0 для текстовых полей 📖 Сразу оговорюсь – я понимаю, что никому в здравом уме не придет идея делат
Выборка WHERE txt_field = 0 для текстовых полей 📖 Сразу оговорюсь – я понимаю, что никому в здравом уме не придет идея делать подобные запросы умышлено. Но понимание таких нюансов может пригодиться для упрощения дебага, а также при каких-то нестандартных ситуациях, не связанных с разработкой для продакшена. Как раз во время поиска проблемы с выборками из БД и был обнаружен подобный запрос. В коде был баг, который при определенных обстоятельствах превращал параметр строкового ключа в число ноль и в типе int использовался для запроса к базе данных MySql. Не сразу обнаружился ноль в запросе, и пришлось повозиться, прежде удалось понять, почему вместо выборки по строковому ключу, возвращаются вообще все данные из таблицы. 📌 Странные запросы и результаты На скрине упрощенная таблица БД, которая состоит из двух полей – id и txt_field. Поле txt_field имеет тип varchar и хранит строки. Если сделать такой sql запрос:
SELECT * FROM `tbl_test` WHERE `txt_field` = 0;
В ответ получим три строки:
id  txt_field
1   kek
2   kek_1
3   kek_2
А такой запрос:
SELECT * FROM `tbl_test` WHERE `txt_field` = 1;
Вернет одну строку:
id  txt_field
4   1_kek
📌 Почему так происходит? Странные выборки получаются и не очень очевидные. Но это нормальное поведение MySql. Когда в запросе нужно сравнить число и строку, MySql пытается сделать приведение к одному типу данных. Но приведение типов с MySql работает по своим правилам, вот таким: – Читает строку слева направо до первого нечислового символа – Если в начале строки нет цифр, результат преобразования будет равен нулю – Если есть цифры, то берет только числовую часть и отбрасывает остатки Поэтому все строки, которые начинаются с нечисловых символов, становятся равны нулю и удовлетворяют условиям выборки WHERE txt_field = 0. Однако, если в начале строки есть число, то такая строка преобразуется в числовое значение, поэтому запрос с WHERE txt_field = 1, выдаст результат с «1_kek». 📌 Примеры преобразований строк в число:
'123kek' → 123
'kek_1' → 0 (первый символ не цифра)
'1_kek' → 1
'1.23kek' → 1.23
'kek' → 0
'' (пустая строка) → 0
——— #⃣ #Костыли #sql #Типы 🐞 Канал // Чат // Задачи

Алгоритм Ray Casting 📖 При работе с картами или любой другой сеткой координат, иногда нужно определить, находится ли объект
Алгоритм Ray Casting 📖 При работе с картами или любой другой сеткой координат, иногда нужно определить, находится ли объект внутри области или за ее пределами. Самый частый и наглядный случай, с которым приходилось сталкиваться в работе с вебом – это определение доступности адреса в конкретной зоне доставки. Первый раз, когда с подобным столкнулись, начали выдумывать свой алгоритм, но быстро сообразили, что должны быть и готовые формулы и алгоритмы. Так и оказалось. 📌 Ray Casting – простой, но очень действенный алгоритм для определения положения точки относительно многоугольной области: точка находится внутри или снаружи. Для проверки положения, из точки выпускается луч право и считается сколько произошло пересечений с областью. Если пересечений четное количество, то точка находится за пределами области, а если не четное, то внутри. Ноль – четное число, тут нет противоречий или дополнительных обработок, логика не ломается. Для наглядности, в картинке к посту добавил область на карте и трех жуков, от них отходят лучи. И только у того, кто внутри треугольника, луч пересекает зону нечетное количество раз – единожды. Для не областей с стандартными формами, пересечений может быть 3, 5, 7 и тд. Но все равно условие с четностью будет выполняться. Чтобы рассчитать количество пересечений, есть математическая формула:
xIntersection = xj + (y - yj) * (xi - xj) / (yi - yj)
Это уравнение прямой через две точки (xj,yj) и (xi,yi), решенное относительно x при заданном y. Зная эту формула, написать метод определения положения точки относительно области, уже дело техники. Для примера можно посчитать географические координаты, используя долготу и широту:
function isPointInPolygon(point, polygon) {
  const { lng: pointX, lat: pointY } = point;
  let isInside = false;

  // Проходим по всем ребрам многоугольника
  for (let currentIndex = 0, previousIndex = polygon.length - 1;
    currentIndex < polygon.length;
    previousIndex = currentIndex++) {

    const currentVertex = polygon[currentIndex];
    const previousVertex = polygon[previousIndex];

    const { lng: currentX, lat: currentY } = currentVertex;
    const { lng: previousX, lat: previousY } = previousVertex;

    // Проверяем, пересекает ли луч ребро
    const isRayCrossingEdge = (currentY > pointY) !== (previousY > pointY);
    const edgeIntersectionX = previousX +
      (pointY - previousY) * (currentX - previousX) / (currentY - previousY);

    if (isRayCrossingEdge && pointX < edgeIntersectionX) {
      isInside = !isInside;
    }
  }
  
  return isInside;
}
И пример использования:
const deliveryZone = [
  { lng: 34.349, lat: 53.417 },
  { lng: 34.066, lat: 53.141 },
  { lng: 34.706, lat: 53.150 },
];
const clientAddress = { lng: 34.350, lat: 53.410 };

console.log(isPointInPolygon(clientAddress, deliveryZone));
👨‍💻 Код можно запустить онлайн тут: ссылка. ❗️Такой расчет можно делать не только с географической картой, но и любой другой 2d сеткой координат. ——— #⃣ #БазаЗнаний #RayCasting 🐞 Канал // Чат // Задачи

Файлы .git в публичной папке 📖 Контроль версий кода – удобный инструмент, уже давно без него не представляется ни одна разра
Файлы .git в публичной папке 📖 Контроль версий кода – удобный инструмент, уже давно без него не представляется ни одна разработка. Я еще немного застал системы контроля версий svn, потом mercurial, а потом и git, который сейчас стал стандартом и, кажется, нет альтернатив. Каждый проект имеет свой git-репозиторий, который зачастую попадает в продакшен или вообще используется для деплоя. Да, не все приложения разворачиваются с докерами, куберами и прочим, очень много реальных и живых проектов все еще используют ci/cd с набором скриптов для автоматического стягивания с репозитория и последующего билда. И есть такие, которые полностью в ручном режиме релизятся. Такие решения даже могут быть оправданы. Но не об этом пост. Это я все к тому, что так или иначе зачастую на продакшене оказывается актуальный репозиторий, а вместе с ним и все его файлы настроек, объектов, логов, хуков и всего остального. Бывает такое, что папка .git попадает на прод и это факт. И встречается это куда чаще, чем отлаженные инфраструктуры с ci/cd и прочими примочками. 📌 То, что папка .git зачастую лежит в продакшене – это реальность. Это не плохо и не хорошо, такую ситуацию диктуют куча разных условий, которые для каждого проекта свои. Но очень плохо и не безопасно то, что .git с завидной регулярностью упускается разработчиками из виду и попадает не просто в продакшен, а в публичную папку. Если не позаботиться о приватности, то весь репозиторий со всеми его ветками и коммитами, можно легко найти и полностью скачать. А имея полный доступ к кодовой базе и истории коммитов, найти уязвимость в проекте становится делом времени. И если еще в коде захардкожены доступы или файлы конфигов находятся под контролем версий, то это совсем уже печально и такая находка сродни получению полного доступа. 📌 Как эксплуатировать Если .git оказалась в публичной папке, то скорее всего это будет корень проекта. Поэтому самый простой способ обнаружить открытый репозиторий, это «дернуть» файл с конфигурацией, который есть в каждой папке .git, по урлу: хост/.git/config. Если папка доступна, то получится скачать файл конфигурации. Цель найдена, остается выкачать все файлы. «Руками» такое сделать не реально для больших репозиториев, поэтому нужна автоматизация. Можно написать свой парсер, а можно воспользоваться готовым инструментом git-dumper. Git-dumper работает на python и установить его можно через pip:
pip install git-dumper
И остается только запустить git-dumper, указав адрес сайта-цели и папку, в которую скачать весь .git:
git-dumper http://хост.com ./folder
Готово. А что делать со скаченной папкой .git всем и так понятно — удалить, а о существующей проблеме с безопасностью сообщить владельцу ресурса, откуда выкачали репозиторий. 📌 Как защититься Чтобы папка не была доступна, ее нужно выносить на уровень выше, чем публичная. Тогда она будет недоступна по http. Но такой подход подразумевает изменение вложенности, если такое сложно и трудозатратно организовать, то можно закрыть доступ на уровне сервера. Для nginx это делается через конфиг для хоста:
location ~ /\.git {
    deny all;
}
А для веб-сервера Apache нужно добавить правило в .htaccess:
<DirectoryMatch "/\.git">
    Order allow,deny
    Deny from all
</DirectoryMatch>
📌 Тренировка: Для тестирования эксплуатации этой уязвимости запущенна задачка «Старый коммит» на нашей площадке с коллекцией челенджей. А если будут сложности, то приходите в чат, там можно пообщаться и задать вопросы. ——— #⃣ #БазаЗнаний #Web #git 🐞 Канал // Чат // Задачи

Задача «Тест по YAML» ❗️ Эта задача анонсировалась заранее и будет небольшое награждение первой тройки решивших. Призы символ
Задача «Тест по YAML» ❗️ Эта задача анонсировалась заранее и будет небольшое награждение первой тройки решивших. Призы символические, но так интереснее, чтобы был небольшой азарт. Ссылка на задачу на нашей площадке: задание. 📌 Исходники бекендовой части задачи прикреплены на сайте. Описание задачи не большое: Для получения флага, нужно получить 1337 очков в тесте, где представлены 7 вопросов про парсинг YAML-файлов. Ответы проверяются в бекенде, по запросу с фронта. 📌 Заявки принимаются на сайте с задачами, где фиксируется время отправки и валидность флага. Про первые три решения автоматически сообщает бот в нашем чате. Ответы в зачет принимаются до 12 сентября 12:00 МСК, есть ровно неделя на решение. Далее будет пост с полным разбором этой задачи и объявлением победителей. Кто первый, тот молодец. Поехали! ❗️ Ссылка на задачу: перейти. ——— #⃣ #Задачи #CTF 🐞 Канал // Чат // Задачи

Как хранить и обрабатывать деньги? ❗️ Быстрый ответ на вопрос. Храните свои деньги в сберегательной кассе. А если это чужие д
Как хранить и обрабатывать деньги? ❗️ Быстрый ответ на вопрос. Храните свои деньги в сберегательной кассе. А если это чужие деньги, то лучше их хранить в базе данных в полях с типами INTEGER, BIGINT, NUMERIC или специализированным типом Money, если его поддерживает СУБД. Но никак не в типах с плавающей точкой, это приведет к ошибкам и появлению лишнего или потере существующего баланса. Деньги обязательно должны храниться и обрабатываться только в целочисленных типах данных. А если нужны копейки, то число должно быть умножено на 100, а при необходимости форматированного вывода, достаточно обратно поделить на 100 и вывести целую и дробную части. Иногда можно гранить рубли и копейки в разных полях, но все также в целочисленных типах данных. Аналогично должна происходить и логика обработки в коде, а не только хранение. 📌 Для наглядности: 0.1 + 0.2 !== 0.3 – это условие вернет true. Например, в js 0.1 + 0.2 = 0.30000000000000004. В других языках ситуация такая же. Это небольшая погрешность, но при работе с крупными объемами данных и большим количеством операций над этими значениями, можно получить серьезную проблему. Почему так происходит? Числа с плавающей точкой хранятся в двоичной системе исчисления по стандарту IEEE 754. Это не ошибка языка, а следствие того, что числа 0.1 и 0.2 являются бесконечными дробями в двоичной системе, так же как 1/3 (0.33333...) является бесконечной дробью в десятичной системе исчисления. То есть это нормальное поведение чисел и об этом нужно знать при работе с деньгами, иначе такой очень маленький(0.00000000000000004) «хвост» может вызвать кучу проблем. 📌 На тему поста для демонстрации проблемы опубликована задача: Обменник валют «У Апишечки». В задаче приложен код с ошибкой в типах данных, и если правильно воспользоваться этой проблемой, то можно увеличить свой баланс счета. Попробуйте решить, а если возникнут сложности, то приходите в чат, там можно спросить помощи или подсказку, а также там выходят анонсы новых небольших и простеньких задач, про которые не упоминается в канале. ——— #⃣ #БазаЗнаний #Ошибки 🐞 Канал // Чат // Задачи

Запуск сайта с задачами 📖 В недавнем опросе по поводу тем постов и сложности задач, которые периодически публикуются тут в к
Запуск сайта с задачами 📖 В недавнем опросе по поводу тем постов и сложности задач, которые периодически публикуются тут в канале, мнения разделились – кому-то нужны полегче, а кому-то посложнее задачи. Но постить все подряд сюда в канал будет неудобно, вся лента только из задач и будет состоять, если публиковать и простые челенджи, а нужно еще оставить место и для основной тематики – заметки про разработку и разборы задач. А также хочется вести общий рейтинг по очкам участников за всю истории, и автоматизировать уведомления про первые три решения, это нужно для определения победителей в задачах с призами. Да и в целом, собрать все в одном месте будет удобнее, чем искать задачи по ленте в телеграм. 📌 Поэтому решено запустить сайт с коллекцией задач. Пока там постоянно будет находиться только такие задачи, которые не требуют отдельных инстансов на сервере и не отнимают много ресурсов. Но в будущем, если будет интерес, то может доработаем площадку. Сайт уже заработал и там есть шесть задач – две старые, которые уже упоминались в канале и четыре новые. Можно переходить и решать: ссылка. Две задачки из новых вчера ребята начали уже разбирать – в чате канала был предварительный анонс, а еще две совсем новые, они опубликованы одновременно с этим постом. Еще можно успеть решить первым! 📌 Новые задачи, которые еще не видели в канале: – OSINT / Поездка: Беларусь – OSINT / Смертельный интим – STEGO / Комариный писк – MISC / Лабиринт Эти задачки прилично проще, чем те, что решали в канале, поэтому у всех есть возможность решить. Вперед! ❗️ Сайт с задачами: https://ctf.bug-makers.ru ——— #⃣ #CTF #Задачи 🐞БАГодельня: Канал // Чат // Задачи

Игра «Сапер». Пример использования алгоритма DFS 📖 В прошлом году ездил в столицу на поезде и взял с собой ноутбук, но не ск
Игра «Сапер». Пример использования алгоритма DFS 📖 В прошлом году ездил в столицу на поезде и взял с собой ноутбук, но не скачал туда ничего посмотреть или послушать. В дороге без интернета скучно, и чтобы чем-то заняться, написал «Сапёра». Сама по себе игра не сложная в реализации, но есть один интересный момент. Когда игрок кликает по клетке с «нулем» – ячейка поля, в которой нет мин и во всех соседних клетках тоже пусто, то должна открыться сразу вся область поля соседствующими «нулями». То есть открывается часть поля, со всеми соседствующими клетками с нулями, пока не встретится граница или ячейка с цифрами (от 1 до 8, зависит от количества клеток-соседей с минами). Если начать выдумывать свой алгоритм раскрытия поля с пустыми ячейками, то можно прилично закопаться в условиях и циклах. Именно этим я и занялся сперва – начал мудрить свой алгоритм. Но закопавшись в ветвлении логики, начал вспоминать алгоритмы, которые кроме как в тренировочных задачах, больше особо и не использовал раньше. Может быть, у кого-то в рабочих задачах и пригождаются алгоритмы каждый день, но я с ними пересекаюсь только во всяких учебных и тренировочных задачах или в описании статей. Поэтому нужный алгоритм пришел на ум не сразу и сперва занимался дурью с условиями и изобретал свое решение. 📌 Для такой задачи идеально подходит DFS – поиск по графу в глубину. Если кто понимает за асимптотику, то сложность этого алгоритма O(n), то есть линейная – время работы алгоритма линейно с увеличением размера входных данных. Это очень хороший показатель для алгоритма. Смысл алгоритма заключается в рекурсивном обходе всех соседей и сборе массива валидных координат. Так без лишних условий можно пробежаться по всем соседям и собрать нужные ячейки, которые будут открыты. Для наглядности код алгоритма на примере поиска пустых ячеек в сапере:
function findAllEmptyCells(matrix, startY, startX) {
    // Размер игрового поля
    const rows = matrix.length;
    const cols = matrix[0].length;
    // Направления поиска соседей:
    // Вверх, влево, вниз, вправо 
    const directions = [[-1,0], [0,-1], [1,0], [0,1]]; 
    // Матрица посещённых клеток
    const visited = [];
    const result = []; 
  
    function dfs(y, x) {
        // Проверка границ, значений из клеток соседей 
        // и актуальность посещения клетки
        if (y < 0 || y >= rows || x < 0 || x >= cols || matrix[y][x] !== 0 || visited[y][x]) {
            return;
        }

        // Помечаем ячейку как посещенную
        visited[y][x] = true; 
        // Добавляем координаты в результат
        result.push([y, x]);  
        
        // Рекурсивно проверяем всех соседей
        for (const [dy, dx] of directions) {
            dfs(y + dy, x + dx);
        }
    }

    dfs(startY, startX);
    return result;
}
📌 Для наглядности еще пример, как отработает алгоритм. Допустим, у нас есть поле:
[1, 1, 1, 0]
[1, 0, 0, 1] 
[0, 0, 1, 1]
При клике на ячейку [1,1] (значение 0), алгоритм найдет все связанные пустые ячейки и вернет матрицу координат этих нулей: [[1,1], [1,2], [2,0], [2,1]] Решение получается очень простым и предсказуемым. Но чтобы его написать, нужно иметь в запасе какой-то набор базовых алгоритмов. Учить наизусть подобные алгоритмы нет смысла, но понимать, как они работают и знать про их существование не будет лишним. Учить наизусть только для собесов надо, на сколько я понимаю 😁. А в реальных задачах такое не часто встречается и достаточно просто знать и вовремя вспоминать, чтобы можно было нагуглить описание и применить. Это мое мнение, не призываю никого, если есть желание заучивать, то занимайтесь) 💣 Полный код сапера можно посмотреть в моем github, реализован на js. А так же можно поиграть и потестить логику, билд тут: Сапёр. ——— #⃣ #DFS #Алгоритмы #Сапер 🐞БАГодельня: Канал // Чат

Задача «Тихий страж». Решение 2 Решение задачки из поста от 20 августа: описание задачи Бинарник для тренировки реверса и его
Задача «Тихий страж». Решение 2 Решение задачки из поста от 20 августа: описание задачи Бинарник для тренировки реверса и его исходник можно скачать тут: github https://github.com/Ipatov/CTF-Silent-Guardian 📌 Второе решение. Полный реверсинг бинарника Для реверса бинарника, его сперва нужно выкачать. Самый простой способ – это подключиться к серверу, закодировать файл ctf в base64, и полученную строку у себя на компьютере обратно сконвертировать в бинарник: Кодируем: cat ./ctf | base64 Сохраняем бинарник: echo "строка_base64" | base64 -d > output_binary Теперь нужно сделать дизассемблирование бинарника, для этого есть программы: бесплтаная Ghidra и IDA(платная и бесплатная версии). Обе программы работают примерно одинаково. Запускаем приложение и выбираем нужный бинарник, на выходе получаем список функций и их код, используемые данные, которые зашиты в бинарнике, а также получаем схему логики – ее кусочек на превью поста, это скрин из IDA. Код бинарника после реверса отображается кодом ассемблера. Но ассемблер сложноват для восприятия, однако его можно перевести в си-подобный псевдокод. Конвертировать умеет и Ghidra и IDA – с этим нет проблем. Поэтому переводим код в си-подобный и смотрим, что происходит внутри бинарника. Для тех, у кого нет установленных программ для реверса, залил самые интересные куски псевдокода в гитхаб: github. В репозитории полный код функций main и sub_1345, а также объект с данными .rodata – это статичные данные, которые хранятся внутри скомпилированного приложения, они нам тоже пригодятся. Когда бинарник декомпилирован начинаем анализировать полученный код, первым делом находим точку входа – это функция start, там будет вызов функций с логикой, в данным случае это main. Внутри функции main сразу же находим нужный нам участок, вот самое интересное:
if ( !strcmp(buf, "/flag") )
{
    v6 = (unsigned __int8 *)sub_1345(&unk_2030, 26, "YnJ1aA==", 8);
    if ( v6 )
    {
    for ( i = 0; i != 26; ++i )
    {
        v8 = v6[i];
        putchar(v8);
    }
    free(v6);
    }
}
Псевдокод нормально читается, и из него становится ясно, что запущенный процесс ждет строку «/flag», которую мы передавали в первом варианте решения. Далее происходит какая-то обработка данных из переменной unk_2030 внутри функции sub_1345, а итоговый результат выводится в stdout. Нужно теперь разобраться, что делает функция sub_1345 и найти значение переменной unk_2030. Анализируем код sub_1345:
_BYTE *__fastcall sub_1345(__int64 a1, size_t a2, __int64 a3, unsigned __int64 a4)
{
  _BYTE *v8; // rdi
  size_t v9; // rsi
  
  v8 = malloc(a2);
  v9 = 0;
  do
  {
    v8[v9] = *(_BYTE *)(a1 + v9) ^ *(_BYTE *)(a3 + v9 % a4);
    ++v9;
  }
  while ( v9 < a2 );
  return v8;
}
Это простая логика XOR-а, где по байты ключа ксора используются по очереди и по кругу, если длина ключа короче зашифрованной строки. Если код не читается, то его можно переписать на более понятный – это нейронки хорошо умеют, но за ними нужно перепроверять. Один раз нарывался на то, что нейронка неправильно отформатировала код и потратил пол дня, пока не понял, что копаюсь с неправильным куском логики. Теперь мы знаем, что для получения флага, нужно выполнить xor для значения из unk_2030 с ключом «YnJ1aA==». Ключ, кстати, был виден в первом решении, когда выполнялся strings для изучения бинарника. Остается найти значение unk_2030 – оно хранится в .rodata, разбитое по байтам. Забираем его оттуда и выполняем преобразование xor-ом. Чтобы не считать ксор руками, можно написать простой скрипт, например, на питоне: скрипт / запустить. Раскодированная строка — это наш флаг. Победа! ❗️ Важный анонс Следующая задача будет запущена 6 сентября в 12:00 по МСК. Категория web. За первые три решения будут призы: 3 месяца премиума в телеграм, 250 и 100 звезд. Не пропустите 😁 ——— #⃣ #CTF #РазборыЗадач 🐞БАГодельня: Канал // Чат

Задача «Тихий страж». Решение 1 Решение задачки из поста от 20 августа: описание задачи. Подключение к серверу будет доступно
Задача «Тихий страж». Решение 1 Решение задачки из поста от 20 августа: описание задачи. Подключение к серверу будет доступно еще все выходные, можно попробовать порешать после прочтения этого разбора. Бинарник для тренировки реверса и его исходник можно скачать тут: github. 📖 Кратко суть задачи: есть доступ к серверу, где нужно найти флаг. При подключении сразу виден бинарник и скрипт, в котором описан запуск этого бинарника. Так же из условия задачи понятно, что нужно либо реверсить бинарный файл либо найти запущенный процесс и передать ему ключ. 📌 Первое решение. Через анализ системы и бинарника В первую очередь после подключения к серверу смотрим, какие файлы нам доступны:
> ls -la
-rwxr-xr-x    1 ctfuser  ctfuser      14072 Aug 20 20:18 ctf
-rwxr-xr-x    1 ctfuser  ctfuser         56 Aug 20 20:17 entrypoint.sh
Из содержимого entrypoint.sh понимаем, что в системе скорее всего запущен бинарник ctf. Поэтому стоит проверить, работает он еще или нет:
> ps aux | grep ctf
8 ctfuser   0:00 ./ctf
И замечаем, что процесс запущен в системе, его PID = 8. Теперь нужно понять, что делает этот процесс и с чем взаимодействует. Одна из подсказок была, про то, что всё в linux – это файлы. Проверяем наш процесс с помощью lsof:
> lsof -p 8
8  /home/ctfuser/ctf  0  /dev/null
8  /home/ctfuser/ctf  1  pipe:[58609665]
8  /home/ctfuser/ctf  2  pipe:[58609666]
8  /home/ctfuser/ctf  4  pipe:[58608517]
8  /home/ctfuser/ctf  69  pipe:[58608517]
В ответе для нас самый интересный третий столбец, он хранит FD (File Descriptor) — числовой идентификатор, который процесс использует для работы с этим открытым файлом. FD 0 — это стандартный ввод (stdin). FD 1 — вывод (stdout). FD 2 — вывод ошибок (stderr). А вот FD 4 и FD 69 — это дополнительные файловые дескрипторы. И они оба подключены к одному и тому же каналу (58608517). Поскольку по условию задачи нам нужно найти «Стража» и сказать передать ему правильную команду, то скорее всего какой-то из нестандартных FD настроен на чтение данных. И чтобы отправить строку процессу нужно записать строку через файловый дескриптор: echo "строка" > /proc/$PID/fd/$FD, где $PID – это PID процесса, у нас это 8, а $FD – файловый дескриптор 4 или 69. 📌 Остается понять, какие данные нужно передать. Возвращаемся к условию задачи и там находим, что «Кодовая фраза где-то рядом... возможно, даже в самом бинарнике». Тут мы можем сделать дизассемблирование бинарника или сперва попробовать просто извлечь из него все доступные строки. Пробуем вариант попороще – извлекаем строки с помощью утилиты strings и анализируем содержимое:
> strings ./ctf
...
__libc_start_main
free
libc.musl-x86_64.so.1
__deregister_frame_info
ATUSH
|$xH
...
pipe
dup2
/flag
read
YnJ1aA==
d@Sn
;*3$"
GCC: (Alpine 14.2.0) 14.2.0
.shstrtab
...
Часть вывода я отрезал – там лишнее и заметил троеточием. В выводе замечаем несколько не стандартных строк – это /flag и YnJ1aA==. Вторая часть это base64 строка, раскодируем ее на всякий случай, получаем bruh. Но строка /flag больше всего подходит под «команду для стража», поскольку в начале строки есть слеш и в целом «flag» уже хранит намек. Пробуем отправить эту строку нашему стражу:
> echo "/flag" > /proc/8/fd/4
BugCTF{FD_69_IS_THE_KEY}  
Сработало! Флаг получен. Это работает с fd 4 и 69, оба дескриптора принимают значение и отдают флаг, если строка с командой корректная. ❗️Второй способ решения – через реверсиинг бинарника, не влезает в этот пост, не хватает лимита телеграмм. Опубликую вечером вторым постом. ——— #⃣ #CTF #РазборыЗадач 🐞БАГодельня: Канал // Чат

Костылим со всей силы в sql-запросах 📖 Пару лет назад был пост с кодревью, где числовой постфикс к имени файла находился бру
Костылим со всей силы в sql-запросах 📖 Пару лет назад был пост с кодревью, где числовой постфикс к имени файла находился брутфорсом, перебирая все доступные имена. Освежить в памяти можно тут: Новая папка(123). Сегодня получилось реализовать тоже самое только с базой данных. Сперва не планировал писать, но задачка получилась интересная и не стандартная – костыль, который вряд ли кому-то пригодится в том виде, как он есть, однако показывает не самые стандартные возможности SQL. 📌 Что имеем? Есть таблица в БД mysql, куда пишутся записи с некоторыми данными, а одно из полей хранит уникальный ключ такого вида: keyname_123, где 123 – это инкремент для уникальности. Нужно узнать самый большой постфикс для ключа и добавить запись с ключом keyname_(N+1). Важное примечание. В силу некоторых обстоятельств, сделать по-человечески, и вынести индекс ключа в отдельный столбец, и по нему уже делать выборку, в данном случае нельзя. Можем работать только с такой строкой. 📌 Как реализовано? С помощью while цикла делались запросы к таблице для проверки существования записи с ключом keyname_i, где i – инкремент от 0 и до конца, с увеличением на единицу. Цикл крутится, пока запрос к БД не вернет пустой ответ, это сигнализирует о найденном индексе ключа, который можно использовать для новой записи. В данном случае индексов может быть не много, не более десятка, но что может стать с проектом в будущем никто не знает, и такой поиск индекса будет серьезной проблемой при увеличении объемов. Да и в целом, перебор значений — это уж совсем крайний случай. 📌 Как сделать получше? А теперь несколько вариантов, как еще можно решить эту задачу, не мучая БД лишними запросами. 1. Так же перебором, но гонять в цикле не запросы к БД, а данные. Сделать запрос вида:
SELECT key_column 
  FROM tbl_test 
 WHERE key_column LIKE 'kek_%';  
Достаем все ключи и находим самый большой индекс. Такой вариант будет работать быстрее и меньше грузить БД на небольших объемах данных. 2. Для mysql 8.0+ версий можно написать запрос и регуляркой отрезать от ключа текстовую часть, оставив только числовой постфикс. И сразу же в запросе получить максимальное значение. То есть один запросом получаем сразу максимальный индекс. Запрос:
SELECT MAX(CONVERT(REGEXP_SUBSTR (key_column, '[0-9]+$'), INT)) AS max_prefix
  FROM tbl_test 
 WHERE key_column like 'kek_%';
3. Для mysql ниже 8 версии, где нет поддержки REGEXP_SUBSTR, тоже можно реализовать запрос, как во втором примере, но через предварительный подсчет символов до числа. Запрос:
SELECT MAX(CAST(SUBSTRING(key_column, 5) AS UNSIGNED)) AS max_prefix
  FROM tbl_test 
 WHERE key_column LIKE 'kek_%';
Если у кого есть еще идеи sql-запросов, кидайте в комментарии, может быть есть более простые или интересные варианты. ——— #️⃣ #sql #костыли 🐞БАГодельня: Канал // Чат