Blue (h/c)at Café
3.25K subscribers
403 photos
9 videos
4 files
146 links
Здесь живут истории о безопасности — искренние, местами хаотичные, с оттенком усталости и самоиронии, но всегда честные и технически точные. Юмор слегка непостижимый, а котики появляются по мере критической необходимости. Без них никак.
Download Telegram
🐈 Признание в ориентации

Да, вынужден признаться. Я – MlSec. И нет, это не из-за тренда или желания заработать милльёны и уехать на Бали дышать маткой 👀. Это вызвано потребностью в данном классе специалистов и рабочими задачами. Но я так, на пол-шишечки, в данном направлении, так что не судите строго.

📝 Чего добился за время молчания:

🔵 Создал свою лабораторию по тестированию (про неё будет информация чуть позже);
🔵 Написал версию 0.1 документа "Проектирование и внедрение MlSec".
В данный момент могу сказать спасибо информации Николая Павлова, которая дала посмотреть на этот мир в курсе от Softline, ChatGPT, который поправляет меня, исправляет ошибки и ставит запятые, когда я пишу большой текст (пока >35 000 слов, не считая мемы, схемы, документацию и переведённые стандарты с mitre atlas (сейчас готовлю интерактивный сайт на русском языке с автообновлением));


🔵 Начали делать сайт для нашего мини-проекта;
🔵 Написал маленький Defect Dojo для уязвимостей ML, найденных проблем в датасетах, проблем в цепочках поставок и тд;
🔵 Проанализировал более 30 инструментов для разных задач в области MlSec;
🔵 И продвигал данный документ и разработки.

🗺 Дорожная карта

1. Создание и публикация сайта с интерактивной mitre atlas, документацией и самим документом в бета-версии;
2. Тестирование инструментов в компании;
3. Публикация документа версии 1.0 на Github;
4. Публикация части инструментов;
5. Кооперация с исследователями;
6. To be continued…

Процесс идёт достаточно долго из-за загруженности на работе, но я надеюсь, что справлюсь с данной задачей.

🙂 Про канал

Далее я буду чередовать посты про appsec (готовы уже 3) с постами про MlSec.

MlSecOps-а не существует

Всем добра и не лысеть 🥺
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥21😁53🤔2
🧠 RLAIF — когда LLM начинает учить LLM

В этот раз — без громких CVE и срочных патчей. Зато с духотой поговорим о подходе, который может полностью изменить ландшафт обучения языковых моделей. Имя ему — RLAIF (Reinforcement Learning from AI Feedback). Да, всё верно — обучение на обратной связи от другой LLM, а не от человека.

Началось всё, как водится, с того, что кто-то где-то устал. Устал платить аннотаторам, устал ждать обратную связь по каждому «ответу на вопрос», устал строить пайплайн, в котором человек вручную решает, какой из двух ответов от модели «более человечный». А потом в 2022 году в Anthropic решили: а почему бы не заменить человека другой LLM-кой? И родился RLAIF — Reinforcement Learning from AI Feedback.

🧠 Из чего состоит пайплайн

Схема достаточно проста:

- Актёр (LLM) генерирует несколько ответов;
- Критик (другая LLM) оценивает их по ряду метрик: полезность, безопасность, релевантность;
- На основе этих «оценок» модель оптимизируется — чаще всего через PPO или DPO.

Получается замкнутый цикл, одна модель обучает другую, и всё это — без привлечения людей. Что логично - "зачем вручную объяснять LLM, как звучит «нормальный» ответ, если другая LLM уже умеет это распознавать?"

🧪 Зачем вообще это нужно

Основные плюсы:
- Уходит потребность в тысячах аннотированных пар от людей;
- Быстрее запуск и масштабирование пайплайна;
- При хорошем критике — качество на уровне RLHF.

Минусы тоже есть, и главный из них — критик. Если он неточен, непоследователен или слишком «мягкий» — результат быстро уходит в сторону. Тут важно выбирать модель, которая адекватно отражает человеческие ценности и «понимает» контекст, а не просто выдаёт рандомное число.

⚙️ Что использовать для экспериментов

Если хочется попробовать на практике:
- trl — PPO, DPO, RewardModel из коробки;
- Axolotl — Yдля YAML-фетишистов, кто не любит писать скрипты;
- DeepSpeed Chat — для обучения крупных моделей (если хочешь учить 40B и при этом не убить сервер);
- Colossal-AI — максимальное ускорение на уровне инфраструктуры.

👀 Где брать модели и датасеты

- Актёры: Mistral, LLaMA 2, Falcon
- Критики: Vicuna, Alpaca, GPT-4-аналоги или кастомные reward-модели.
- Датасеты: OpenHermesPreferences, Dahoas, HH-RLHF — всё, что содержит предпочтения «лучший vs худший» ответ.

💩 Куда всё идёт

- RLAIF уже используется в продакшене в ряде ML-команд, и всё больше моделей обучаются именно так;
- Мультимодальный RLAIF уже на горизонте (текст + картинки + немного боли);
- В критически важных отраслях (SecOps, Healthcare) уже тестируются гибридные модели, где финальную проверку проводит человек, а черновую — LLM-критик.

👀 Заключение

Идея о том, что ИИ может обучать другой ИИ — уже не фантастика. Это реальность. Но как и в любой системе с обратной связью, важно понимать: кто даёт оценку, тот и формирует финальный результат. Поэтому если планируете строить обучение на RLAIF — начните не с модели, а с критика. От его адекватности зависит весь процесс.

#mlsec
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥102🤔1
😊 API Gateway как линия фронта в Web3

Внимание: CatSwap в этом тексте — не стартап и не “очередной ”, а наш pet-проект для иллюстрации. Он нужен, чтобы показать, как Web3-сервисы должны мыслить в части защиты API — не опираясь на бэкэнд, а начиная с Gateway.


В Web3 большинство угроз входит не через «модные» DeFi-примитивы, а через вполне классический API-интерфейс. Просто формат другой: не form-data, а подписанный JSON с маршрутом, суммой и временной меткой. CatSwap, как агрегатор, — типичный пример. Все транзакции, котировки, swap-запросы проходят через публичное API.

Чеклист по защите API Gateway

▫️ HTTPS (TLS 1.2+) + WAF
• Принудительное HTTPS;
• WAF / WAF с OWASP CRS, бот-контролем и Geo-ACL.

▫️ Аутентификация
• JWT в envoy.filters.http.jwt_authn;
• Web3-подписи (EIP-191/712) через Proxy-Wasm (X-Address + X-Signature);
• Challenge-nonce, защита от replay-атак.

▫️ Авторизация (OPA / ExtAuthz)
• RBAC/ABAC-политики по ролям, slippageTolerance, gasPrice, геопозиция, времени суток;
• Динамические политики Rego + GitOps-репозиторий.

▫️ JSON-валидация запросов
• OpenAPI-схемы → Envoy JSON Validator, ошибка 400 при несоответствии;
• Чёткое разделение обязательных и опциональных полей.

▫️ Rate Limit & QoS
/v1/quote ≤ 1000 r/m; /v1/swap ≤ 100 r/m;
• Circuit breaker, retry, max concurrent;
• Приоритет маршрутов, Kubernetes Resource Limits.

▫️ API Gateway (Envoy + Proxy-Wasm)
• JWT (RS256) через envoy.filters.http.jwt_authn;
• JSON Schema Validator — строгая валидация payload;
• Rate-limit, circuit breaker, retry с экспоненциальным backoff;
• ExtAuthz → ML-анализ;
• mTLS внутри кластера (Istio-SDS или Envoy native).

▫️ Логирование & мониторинг
• JSON Access Logs (path, key, user_id, latency, tx_hash);
• Prometheus (p95/p99, ошибки, RPS) / Grafana—дашборды;
• OpenTelemetry + Jaeger; трассировка end-to-end;
• GitOps-аудит конфигов (ArgoCD/Flux).

▫️ Management plane hardening
• Bastion-host с MFA для доступа к административным интерфейсам;
• Жёсткие IAM-роли и Just-In-Time elevation для операторов.

▫️ CI/CD & GitOps
• Инфраструктура как код (Terraform, Helm);
• ArgoCD синхронизация; PR-ревью, tfsec/checkov, canary-релизы.

▫️ Supply chain security & SBOM
• Генерация и хранение SBOM для всех контейнеров и зависимостей;
• Подпись артефактов (cosign/Sigstore) и верификация на этапе деплоя.

▫️ Контроль изменений и drift detection
• Policy as Code (OPA, Terraform Sentinel);
• Инструменты проверки конфигураций (tfsec, Checkov, Conftest).

▫️ ML-анализ в Gateway 💻
• Isolation Forest в Seldon Core; Envoy ExtAuthz вызывает /predict;
• Блокировка при score > 0.8; алёрты в SIEM/Slack.

▫️ API lifecycle & versioning
• Явное управление версиями API, deprecation-policy, backward-compatibility тесты;
• Тёмные и канареечные запуски (traffic mirroring) новых эндпоинтов.

▫️ Disaster recovery & multi-region failover
• Репликация Gateway в нескольких регионах; автоматический DNS-фейловер;
• Документированные RTO/RPO и регулярные drill-тесты.

▫️ Пентесты & Bug Bounty
• Ежеквартальные внешние пентесты API Gateway и RPC-узлов;
• Запуск программы Bug Bounty (HackerOne / Standoff / bizone) для непрерывного обнаружения уязвимостей.

▫️ План реагирования на инциденты (по просьбе SOC)
• Определённые playbook: detection → containment → eradication → recovery;
• SLA/TTR для критичных сервисов; регулярные учения.

▫️ Приватные RPC (PrivateLink / IAM)
• JSON-RPC узлы скрыты за VPC Endpoint (PrivateLink / PSC);
• Доступ по SigV4 / ACL; rate-limit и circuit breaker перед нодами.

▫️ HTTP-security headers
• HSTS (Strict-Transport-Security), CSP, X-Frame-Options, X-Content-Type-Options;
• Защита от clickjacking и MIME-sniffing.

▫️ Сегментация сети и ограничения доступа
• Kubernetes NetworkPolicies; NSG/Security Groups;
• Микросегментация: отдельные VPC/subnet для критичных сервисов.

🔫 А зачем

В общем, это не просто чеклист для галочки. Это попытка собрать разумную, масштабируемую и живучую архитектуру, в которой API Gateway — не прослойка между интернетом и микросервисами, а полноценная точка принятия решений.

#appsec
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥105🤔3😡1
🛠 Ориентация Север - я хочу, чтобы ты верил

#️⃣ соSOC при построении машинного обучения - с одной стороны звучит страшно, а на самом деле не имеет особого концептуального отличия от обычной деятельности SOC (долбиться в глаза).

#️⃣ Основные сложности, наверное, следующие:
➡️ Если вдруг захотите завести себе MLку и поставить её на мониторинг, то перед этим стоит выстроить здравые процессы SOC'a, который покрывает основную часть инфраструктуры и процессов - действия юзверей, активность на критических машинах и так далее.
Покрыть всё в любом случае не получится, если у вас нету адекватной инвентаризации, которая вытащит откуда-нибудь очередной богом забытый WS 2008, о котором знали 2 человека и те уволились пять лет назад🧐

➡️ Для ML есть своя матрица угроз MITRE (выше упомянутый Atlas), которая содержит уже знакомые техники, вроде Unsecured Credentials , Phishing, Reverse Shell и так далее, а с другой стороны новые техники, которые иногда могут быть неподвластны SOC'у - например, некоторые техники из Reconnaissance.

Хотя если кто-то придумает корреляшку на то, что потенциальный злоумышленник читает вашу публичную документацию, или пришёл на доклад, где рассказываете как вы классно обучили свои модель, то остаётся только руку пожать 🙂 (ни футболки, ни вымпела, ни ручки, просто большое человеческое спасибо)

#️⃣ А так, SOC при ML, за исключением некоторых уязвимостей характерных только для моделей, очень сильно напоминает обычный мониторинг логов с Ваших прикладов и внутренних доступов.

#️⃣ Теперь по дорожной карте, которая была пару постов выше:

1. Документация пишется. Готова большая часть со стороны MLgbtSecOps'a;
2. Вот как допишем основную часть и сделаем нормальную структуру - выкатим на публику, но есть нюанс;
3. Нюанс как раз заключается в том, что встал вопрос "Сколько нужно не самых глупых безопасников, чтобы сделать сайт?" - двух просто не хватило😭

Не болейте и не пропускайте приём таблеток👍
Please open Telegram to view this post
VIEW IN TELEGRAM
😁9🤔21
💙 AppSec, баги, лето, Питер

📍 Где и когда - Питер, 3 Июля (четверг)

Регистрация - ТЫК, места быстро кончаются (Открыта до 27-ого)

Указывайте ваши реальные имена, иначе не сможете попасть на площадку проведения


📝 Программа

🟢 Харденинг GitLab на примере ВКонтакте — Дмитрий Земляков (VK)
🟢 Автоматизация поиска IDOR’ов с помощью DAST — Андрей Кан (Ozon Fintech)
🟢 Атака одним пакетом: новый метод Race Condition — Никита Распопов (VK)
🟢 100 000 оттенков JS: от DoS до кражи денег — Всеволод Кокорин (SolidLab)
🟢 Летняя афтепати с возможностью обсудить волнующие темы в неформальной обстановке

🎉 После этого всего — летняя афтепати, где можно будет:

🔵 Поговорить про темы, которые нельзя обсуждать в приличном обществе;
🔵 Найти тех, кто тоже задолбалсялся бороться с теми же проблемами;
🔵 Ну и просто нормально отдохнуть. Мы это заслужили! ❤️
Please open Telegram to view this post
VIEW IN TELEGRAM
7🔥1🤔1
😁14🤔1
💻 Go Security Audit

- Ну Го


В последние месяцы сообщество «вайбкодеров» набирает обороты, быстрая разработка прототипов и использование хайповых (или так уже никто не говорит 👀) библиотек стали нормой. Но вместе с ростом популярности приходят и проблемы. С каждым днём существования легкого доступа к LLM требования к качеству и безопасности кода только ужесточаются, и приходится всё внимательнее разбирать каждую строчку - от параметризации запросов и управления таймаутами до корректной работы с токенами, конкурентностью и цепочкой зависимостей.

Далее, я подобрал примеры ошибок, которые допускают не только нейронки, но также и обычные НЕВАЙБ кодеры.


💉 Инъекции — beyond?
Почему важно? Любая конкатенация строки + ввод = дыра.
// Плохо: fmt.Sprintf + Query

query := fmt.Sprintf("SELECT id, email FROM users WHERE email = '%s'", email)
db.Query(query)


// Правильно: PrepareContext + таймаут + закрытие stmt

ctx, cancel := context.WithTimeout(ctx, 200*time.Millisecond)
defer cancel()
stmt, err := db.PrepareContext(ctx, `
  SELECT id, email 
  FROM users 
  WHERE email = $1 AND deleted = FALSE
`)
if err != nil { return err }
defer stmt.Close()
row := stmt.QueryRowContext(ctx, email)

🔵 Контроль таймаута, явное закрытие stmt, фильтрация «мягко удалённых» записей.
🔵 Для Mongo/Redis — запрещайте $where-выражения, ограничивайте глубину BSON и размер документа ( (bson.M{"\$where": …})).


🔑 JWT & ключи — RS256 + кэйсинг заголовков
parser := &jwt.Parser{ValidMethods: []string{"RS256"}}
token, err := parser.ParseWithClaims(tokenStr, &CustomClaims{}, func(t *jwt.Token) (interface{}, error) {
    return publicKey, nil
})

🔵 Отбрасываем HS*-вставки, проверяем alg, jti, nbf, exp.
🔵 Приватные ключи держим в HSM/Vault, ротация через PKCS#11 или Vault Transit.


🗑 unsafe & бинарные протоколы
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&b))
hdr.Len = header.Length
hdr.Cap = header.Length

Только после Code Review - проверка границ, выравнивания и GC-безопасности.


🔗 Зависимости & Supply Chain
🔵 govulncheck в CI/CD с --mode=imports + --mode=versions.
🔵 Go Proxy — свой прокси-миррор, чтобы исключить проблемки.
🔵 Блокировка PR при CVSS >= 8 (или epss/kev/ТЫК) и альтернативные фиксы через replace в go.mod.


🌪 Context & Cancellation — чтобы не "утекал" код
Корректная передача context — базовый стандарт зрелых Go-сервисов.
// Создаём контекст с дедлайном для HTTP-запроса
ctx, cancel := context.WithTimeout(parentCtx, 2*time.Second)
defer cancel()  // обязательный вызов!
req, _ := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
_, err := http.DefaultClient.Do(req)

🔵 Никогда не забывать defer cancel(), даже при раннем return


🏎 Concurrency & Data Races — -race, sync vs atomic
// две горутины одновременно плюсуют visits
var visits int
go func() { visits++ }()
go func() { visits++ }()

Запуск go test -race в CI обнаружит такие случаи
Очень требовательно к ресурсам и не рекомендуется в монолитах или говно-микросервисах


// Правильно:
// С Mutex
var (
visitsMu sync.Mutex
visits int
)
go func() {
visitsMu.Lock()
visits++
visitsMu.Unlock()
}()

// Или атомарно
var visitsAtomic uint64
go func() {
atomic.AddUint64(&visitsAtomic, 1)
}()



Panic Recovery & Fault Tolerance — graceful failover
Паника в одном handler’е не должна убивать весь HTTP-сервер:
func recoveryMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer func() {
if rec := recover(); rec != nil {
log.Error().
Interface("penic", rec).
Msg("recovered from penic xD in handler")
http.Error(w, "internal error", http.StatusInternalServerError)
}
}()
next.ServeHTTP(w, r)
})
}

🔵 Прокидываем middleware на самый верх стека роутинга


🗒 Выводы
Их не будет, просто примеры из практики. Смотрите внимательнее, что вам выдаёт chatgpt или аналоги.

Добра и позитива appsec-ам, остальным соболезную 💥
Please open Telegram to view this post
VIEW IN TELEGRAM
10🔥97🤔2
😁222🔥1🤔1
👍 Финальный отсчёт до конца приёма заявок

Да-да, тот самый кликбейтный заголовок для пентестеров (ну вы помните), и снова не для аппсеков. Напоминаем — участие открыто до 30 июня, и времени остаётся совсем чуть-чуть👌

Что нужно, чтобы попасть в историю
🟢 Вы сами — ваши идеи и опыт превыше всего
🟢 Яркие успехи или не менее ценные провалы
🟢 Курьёзные факапы, которые держали в напряжении не только вас

Что не стоит делать
🟣 Разглашать NDA
🟣 Делать что-то на грани закона (или за ней)
🟣 Использовать блэчерские отчеты (нет, правда — не стоит)

Подать заявку и снова перечитать подробности — ТЫК

Не тяните до последнего вечера 29-го июня — хотя, кого мы обманываем, вы же настоящие хацкеры и любите бесить организаторов 👍

Успехов и ждём ваших историй!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥72
😁16🤔1
Умный #meme
😁17🤔1
Час до начала, остальных пускать будем уже подпитых (шутка)



Или нет 🤣
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔5🔥4
💸 Как за $2 вскрыть дыру в кешбэке

В Июне одного Ибшника осенило -- "Почему бы не проверить одну бизнес-логику кешбэков и получить небольшую прибыль?" Ниже разбор уязвимости, которая в проекте "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
}
}


😈 How to hack?

1. Подготовка тестового окружения
Регистрации фейкового пользователя и эмуляция 40 покупок по $1 при 2.5% кешбэка:
🔵 В результате Balance = $0.80, fractionBuffer = $0.20

2. Параллельный Redeem
Тут можно бурпом обойтись и его параллельной отправкой запросов

3. Сбор и анализ результатов
🔵 Оба запроса вернули успешный 200 OK с credited: 0.20
🔵 Баланс вырос на $0.40 вместо $0.20

4. Проверка остаточных данных
После вызова:
🔵 Balance = 0.80 + 2×0.20 = $1.20
🔵 fractionBuffer = 0.00

🖌 Исправление

Два пункта, которые назовёт любой вайбкодер middle разработчик:
🔵 Отказ от 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()
}
}


🍺 Итоги

Да, не самый классный баг, но всё ради "смари что можно сделать". На всё про всё ушло два доллара (на самом деле 229 рублей, но ради кликбейтного заголовка цены стали в долларах 😏) -- цена большого red bull в пятёрочке у дома (или чебупиццу), от которого и родилась идея пошатать бизнес-логику.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥184🤔1
Forwarded from sdnv's funk-hole
😁273🔥2🤔2
😁24🤔2
17😁8🤔2
Астрологи с улыбкой хитрой
Неделю глупости ввели:
«Теперь дурак у нас в почёте!»
Роскомпозор уж на коне.

Принят странный был закончик -
Ищи в сети лишь по часам.
Нет разрешения? - штраф в догонку,
Пять тысяч вынь, отдай властям!

Не успел сходить в уборную?
Проси заранее, дружок!
Иначе штраф - держи контрольный,
Плати, не бегай за порог.

Уже с начала сентября
Закроют сеть, что кормила всех,
Прощай, родной свободный доступ,
Рунета ждёт немой успех.

Но что грустить? Ведь есть замена -
Чебурнет шагает в дом.
Безопасно, хоть и бедно,
Интернет теперь с замком.

Теперь стабильно, хоть и скучно,
Но безопасно, говорят.
За все вопросы - строго, чётко,
В туалет - через Госуслуг портал.

Смеёмся сквозь слезу и верим:
«А может, шутка астролога, друг?»
Пока надежда теплится, проверим,
Что дурачками стали не все вокруг?
🤔9🔥51
F
😡18🤔4🔥1😁1
https://reg.russiarunning.com/event/Onlayn4

Не реклама, на правах доброго сердца ♥️
6🔥3
Ну, пупупу получается. Press F aeroflot
😁41
Пупупу x2. Без негатива 💥
Please open Telegram to view this post
VIEW IN TELEGRAM
😁33