Please open Telegram to view this post
VIEW IN TELEGRAM
🤔5🔥4
💸 Как за $2 вскрыть дыру в кешбэке
В Июне одного Ибшника осенило -- "Почему бы не проверить одну бизнес-логику кешбэков и получить небольшую прибыль?" Ниже разбор уязвимости, которая в проекте "X" была скрыта за
🧠 Суть уязвимости
1. При реальном начислении кешбэка из суммы продукции amount используется
2. Каждую ночь планировщик запускает
3. Пользователь может вручную проверить буфер через вызов
Если вызвать два
Псевдокот🥺 для понимания:
😈 How to hack?
1. Подготовка тестового окружения
Регистрации фейкового пользователя и эмуляция 40 покупок по $1 при 2.5% кешбэка:
🔵 В результате
2. Параллельный Redeem
Тут можно бурпом обойтись и его параллельной отправкой запросов
3. Сбор и анализ результатов
🔵 Оба запроса вернули успешный
🔵 Баланс вырос на $0.40 вместо $0.20
4. Проверка остаточных данных
После вызова:
🔵
🔵
🖌 Исправление
Два пункта, которые назовётлюбой вайбкодер middle разработчик:
🔵 Отказ от
🔵 Блокировка доступа к буферу при
Исправляем псевдокот🥺 , чтоб понималось ещё лучше 💥
🍺 Итоги
Да, не самый классный баг, но всё ради "смари что можно сделать". На всё про всё ушло два доллара (на самом деле 229 рублей, но ради кликбейтного заголовка цены стали в долларах 😏 ) -- цена большого red bull в пятёрочке у дома (или чебупиццу), от которого и родилась идея пошатать бизнес-логику.
В Июне одного Ибшника осенило -- "Почему бы не проверить одну бизнес-логику кешбэков и получить небольшую прибыль?" Ниже разбор уязвимости, которая в проекте "X" была скрыта за
float64, асинхронным батчем и отсутствием блокировок.1. При реальном начислении кешбэка из суммы продукции amount используется
math.Floor(pct*100)/100 (с учётом возможных артефактов двоичного представления), а остаток (< 0.01) накапливается в fractionBuffer;2. Каждую ночь планировщик запускает
FlushBuffer(), где применяется math.Round(buffer*100)/100 (округление до ближайшего цента) и деньги переводятся в основной баланс;3. Пользователь может вручную проверить буфер через вызов
RedeemBuffer(), где тоже используется math.Floor и вычитание из буфера без блокировки.Если вызвать два
RedeemBuffer() параллельно на одном и том же пользователе, оба прочтут один и тот же buffer, начислят floor(buffer) и вычтут только один раз, в результате integer-часть оказывается зачисленной дважды.Опустил транзакции бд
Псевдокот
type UserAccount struct {
ID string
Balance float64 // основной баланс в долларах
fractionBuffer float64 // накопленная дробная часть
}
// начисление кешбэк при покупке
func (ua *UserAccount) ProcessPurchase(amount float64, rate float64) {
pct := amount * rate
credited := math.Floor(pct*100) / 100
ua.Balance += credited
ua.fractionBuffer += pct - credited
}
func (ua *UserAccount) RedeemBuffer() {
toCredit := math.Floor(ua.fractionBuffer*100) / 100
ua.Balance += toCredit
ua.fractionBuffer -= toCredit
}
func FlushBuffer(all []*UserAccount) {
for _, ua := range all {
toCredit := math.Round(ua.fractionBuffer*100) / 100
ua.Balance += toCredit
ua.fractionBuffer = 0
}
}
1. Подготовка тестового окружения
Регистрации фейкового пользователя и эмуляция 40 покупок по $1 при 2.5% кешбэка:
Balance = $0.80, fractionBuffer = $0.202. Параллельный Redeem
Тут можно бурпом обойтись и его параллельной отправкой запросов
3. Сбор и анализ результатов
200 OK с credited: 0.204. Проверка остаточных данных
После вызова:
Balance = 0.80 + 2×0.20 = $1.20fractionBuffer = 0.00Два пункта, которые назовёт
float64 и хранение всего в int64 центах;Без учета микросервисов и передачи данных в битах по rpc
RedeemBuffer и FlushBuffer или иные бестпрактис решенияИсправляем псевдокот
type UserAccount struct {
ID string
mu sync.Mutex
BalanceCents int64 // целые центы
fractionCents int64 // накопленные центы < 100
}
func (ua *UserAccount) ProcessPurchase(amountCents int64, ratePermille int64) {
ua.mu.Lock()
defer ua.mu.Unlock()
pct := amountCents * ratePermille / 1000
creditedDollars := pct / 100
ua.BalanceCents += creditedDollars * 100 // конвертация долларов в центы
ua.fractionCents += pct % 100 // остаток в центах
}
func (ua *UserAccount) RedeemBuffer() {
ua.mu.Lock()
defer ua.mu.Unlock()
toCredit := ua.fractionCents // начисляем все накопленные центы
ua.BalanceCents += toCredit
ua.fractionCents = 0 // обнуляем буфер
}
func FlushBuffer(all []*UserAccount) {
for _, ua := range all {
ua.mu.Lock()
ua.BalanceCents += ua.fractionCents // начисляем все накопленные центы
ua.fractionCents = 0 // обнуляем буфер
ua.mu.Unlock()
}
}
Да, не самый классный баг, но всё ради "смари что можно сделать". На всё про всё ушло два доллара
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥18❤4🤔1
Астрологи с улыбкой хитрой
Неделю глупости ввели:
«Теперь дурак у нас в почёте!»
Роскомпозор уж на коне.
Принят странный был закончик -
Ищи в сети лишь по часам.
Нет разрешения? - штраф в догонку,
Пять тысяч вынь, отдай властям!
Не успел сходить в уборную?
Проси заранее, дружок!
Иначе штраф - держи контрольный,
Плати, не бегай за порог.
Уже с начала сентября
Закроют сеть, что кормила всех,
Прощай, родной свободный доступ,
Рунета ждёт немой успех.
Но что грустить? Ведь есть замена -
Чебурнет шагает в дом.
Безопасно, хоть и бедно,
Интернет теперь с замком.
Теперь стабильно, хоть и скучно,
Но безопасно, говорят.
За все вопросы - строго, чётко,
В туалет - через Госуслуг портал.
Смеёмся сквозь слезу и верим:
«А может, шутка астролога, друг?»
Пока надежда теплится, проверим,
Что дурачками стали не все вокруг?
Неделю глупости ввели:
«Теперь дурак у нас в почёте!»
Роскомпозор уж на коне.
Принят странный был закончик -
Ищи в сети лишь по часам.
Нет разрешения? - штраф в догонку,
Пять тысяч вынь, отдай властям!
Не успел сходить в уборную?
Проси заранее, дружок!
Иначе штраф - держи контрольный,
Плати, не бегай за порог.
Уже с начала сентября
Закроют сеть, что кормила всех,
Прощай, родной свободный доступ,
Рунета ждёт немой успех.
Но что грустить? Ведь есть замена -
Чебурнет шагает в дом.
Безопасно, хоть и бедно,
Интернет теперь с замком.
Теперь стабильно, хоть и скучно,
Но безопасно, говорят.
За все вопросы - строго, чётко,
В туалет - через Госуслуг портал.
Смеёмся сквозь слезу и верим:
«А может, шутка астролога, друг?»
Пока надежда теплится, проверим,
Что дурачками стали не все вокруг?
🤔9🔥5❤1
❤6🔥3
Please open Telegram to view this post
VIEW IN TELEGRAM
😁33
Отец знакомого работает в VK. Сегодня срочно вызвали на совещание. Вернулся поздно и ничего не объяснил. Сказал лишь собирать вещи, скачивать новый мессенджер и бежать в магазин за продуктами на две недели. Сейчас едем куда-то далеко за город, где мессенджер MAX ловит. Не знаю что происходит, но мне кажется началось...
😁51🤔10🔥2❤1
Всё чаще секреты утекают не из кода, а из внутренних систем типа Confluence, Jira, корпоративных вики и мессенджеров
1. Сканирование контента
2. Эвристика/шаблоны/LSP
3. Результат
Но с чем мы сталкиваемся, разбирая выхлоп?
- С проблемами😎
Да, вот и появляется куча FP и структуры, которые нам совершенно не подходят. Вот тут и появляется идея сделать фильтрацию через ИИ. Но упс, а что нам теперь, скармливать все наши данные в нейронку, даже если локальную, то представьте сколько это данных и контекста. Тут нам и приходят на помощь zero-shot модели.
🤗Ссылка - ТЫК
- Кандидат признаётся "секретом", если:
- сработало сильное правило или высокая уверенность эвристики, или/и
- zero-shot модель оценила вероятность ≥ порога.
Регулярки и энтропия дают точные, но ограниченные результаты, они видят только то, что явно похоже на известные токены (GitHub, Slack, AWS и т.п.).
Zero-shot модель добавляет гибкость и контекст. Она умеет распознавать скрытые или "словесно замаскированные" секреты, например, когда пароль указан в тексте без префиксов или когда он указан как тестовый (ага, те самые тестовые пароли, идущие в прод
В итоге, снижается число ложных срабатываний, не теряя полноты и без проблем с ложным информированием о тестовых данных.
Рекомендация простая - создать небольшой «золотой» набор размеченных страниц и посчитать precision / recall / F1 до и после включения пост-верификации.
На практике zero-shot модель даёт заметный прирост точности без серьёзной потери полноты при корректной настройке порога (на тестах мне удалось достичь точности определения валидного секрета, с отсеиванием тестовых и фп в 98.4%)
Zero-shot классификация не заменяет ручной контроль, но превращает поиск утечек в управляемый и воспроизводимый процесс, а не в хаотичный ручной grep по страницам. А как итог, отмечу, что Вы можете достаточно быстро привести ранее затруднительные задачи в ML-powered AppSec и без использования "нанытой видеокарты".
Спасибо за внимание и буду рад, если накидаете моделей на тесты
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10🤔1