init
This commit is contained in:
561
back/internal/jokes.md
Normal file
561
back/internal/jokes.md
Normal file
@@ -0,0 +1,561 @@
|
||||
|
||||
**********
|
||||
|
||||
На собеседовании в школе для особо одарённых детей шестилетнего Вовочку попросили рассказать, чем автобус отличается от троллейбуса.
|
||||
Вовочка ничего скрывать от тёти не стал и честно ей сообщил, что автобус работает на двигателе внутреннего сгорания, а троллейбус - на электродвигателе переменного тока.
|
||||
Оказалось - ничего подобного!
|
||||
Просто троллейбус с рогами, а автобус - без.
|
||||
И нечего тут морочить тёте голову!
|
||||
|
||||
**********
|
||||
|
||||
Гламурная москвичка приезжает погостить в деревню к бабушке.
|
||||
|
||||
- Бабуль, куда у вас тут ночью сходить можно?
|
||||
- В ведро.
|
||||
|
||||
**********
|
||||
|
||||
Только перечитывая в 40 лет книгу "Д'Артаньян и три мушкетёра" ты наконец-то начинаешь понимать, что единственный положительный герой в этой книге - кардинал Ришелье...
|
||||
|
||||
**********
|
||||
|
||||
Вместо того, чтобы у себя в Алжире, Марокко и Тунисе строить жизнь, как во Франции, люди приезжают во Францию, чтобы там создать себе такую жизнь, как в Алжире, Марокко и Тунисе. Это странно. Ещё более странно заставлять при этом и французов жить, как в Алжире, Марокко и Тунисе.
|
||||
|
||||
**********
|
||||
|
||||
Твоя религия ничего МНЕ не запрещает. Она запрещает ТЕБЕ. Уясни это.
|
||||
|
||||
**********
|
||||
|
||||
Антон Силуанов предложил россиянам не думать о ключевой ставке ЦБ.
|
||||
Также россиянам не стоит думать о:
|
||||
|
||||
- процентах по кредитам;
|
||||
- курсе рубля;
|
||||
- тарифах ЖКХ;
|
||||
- ценах в магазинах.
|
||||
В то же время россиянам стоит думать о:
|
||||
- госдолге США;
|
||||
- крахе доллара;
|
||||
- величии державы;
|
||||
- необходимости потерпеть.
|
||||
|
||||
**********
|
||||
|
||||
Василий Иванович с Петькой сидят, скучают. Василий Иванович:
|
||||
|
||||
- Петька, сгоняй на хутор к старику-самогонщику, сообрази чего-нибудь!
|
||||
- Это можно.
|
||||
Через час Петька возвращается. Василий Иванович:
|
||||
- Ну как?
|
||||
- Да нет у него ни фига.
|
||||
- Эх, молодежь, всему вас учить надо. Пойдем вместе.
|
||||
Приходят к деду. Василий Иванович:
|
||||
- Здорово, отец!
|
||||
- Здорово, сынки!
|
||||
- Мы вот к тебе от имени Советской власти. Вот я гляжу, хата у тебя старая.
|
||||
- Ох, какая старая!
|
||||
- Петька, запиши: новую хату ему от Советской власти! И жена у тебя вроде старая...
|
||||
- Ой, какая старая!!
|
||||
- Петька, запиши: новую жену ему от Советской власти!
|
||||
- Сынки! Родненькие! Да сколько ж я вас ждал!
|
||||
Ну, сели за стол, выпили, с собой взяли. Уже в дверях Василий Иванович как бы невзначай:
|
||||
- Слышь, дед! А может у тебя и /хрен/ старый?
|
||||
- Уж каккой старый!!!
|
||||
- Петька, запиши: /хрен/ ему от Советской власти!
|
||||
|
||||
**********
|
||||
|
||||
Таможенник поднимается на корабль для досмотра.
|
||||
|
||||
- Наркотики есть?
|
||||
Хозяин корабля отвечает:
|
||||
- Есть. Вот, пожалуйста (достает чемодан). Вот героин, вот кокаин. Все аккуратно упаковано,вот шприц готовый.
|
||||
Таможенник, вытаращив глаза:
|
||||
- А может, и оружие есть?
|
||||
Хозяин (достает другой чемодан):
|
||||
- Вот Макаров, вот Калашник ,вот патроны к ним. Все как надо.
|
||||
Таможенник с усмешкой:
|
||||
- Наверное, и валюта есть?
|
||||
Хозяин достает третий чемодан:
|
||||
- Вот миллион долларов, пожалуйста.
|
||||
Таможенник, ничего не понимая:
|
||||
- И это все ваше?
|
||||
Хозяин:
|
||||
- Нет, это ваше. Мое в трюме.
|
||||
|
||||
**********
|
||||
|
||||
Летит самолет. Пилот по громкой связи:
|
||||
|
||||
- Уважаемые дамы и господа, вас приветствует командир корабля. Прослушайте информацию о нашем полете. Наш полет проходит на высоте 10 тысяч метров со скоростью 900 километров в час, температура за бортом...БЛИН...А-А-А-А!.. ЭТО ЧТО ТАКОЕ?.. НУ, КРЫНДЕЦ...
|
||||
В салоне гробовая тишина.
|
||||
Через минуту опять по радио:
|
||||
- Прошу извинения у уважаемых пассажиров. Просто это наша стюардесса опрокинула на меня горячий кофе. Видели ли бы вы теперь мои белые брюки спереди...
|
||||
Мужик в первом ряду:
|
||||
- Твои брюки, это все херня! Видел бы ты мои брюки сзади...
|
||||
|
||||
**********
|
||||
|
||||
Новый учитель, придя в класс, обнаружил, что одного мальчика дразнят Мойше-дурачок. На перемене он спросил ребят, почему они его так обзывают.
|
||||
|
||||
- Да он и вправду дурачок, господин учитель. Если дать ему большую монету в пять шекелей и маленькую в десять, он выберет пять, потому что думает, что она больше. Вот, смотрите...
|
||||
Парень достает две монеты и предлагает Мойше выбрать. Тот, как всегда,
|
||||
выбирает пять. Учитель с удивлением спращивает:
|
||||
- Почему же ты выбрал монету в пять шекелей, а не в десять?
|
||||
- Посмотрите, она же больше, господин учитель!
|
||||
После уроков учитель подошел к Мойше.
|
||||
- Неужели ты не понимаешь, что пять шекелей больше только по размерам,
|
||||
но на десять шекелей можно купить больше?
|
||||
- Конечно понимаю, господин учитель.
|
||||
- Так почему же ты выбираешь пять?
|
||||
- Потому что, если я выберу десять, они перестанут давать мне деньги!
|
||||
|
||||
**********
|
||||
|
||||
Как разные народы переносят низкие температуры:
|
||||
+10 C: Американцев трясет. Русские сажают огурцы в огородах.
|
||||
+1.6 C: У итальянцев не заводятся машины. Русские ездят с опущенными стеклами.
|
||||
0 C: В Америке замерзает вода. В России вода загустевает.
|
||||
|
||||
- 17.9 C: В Нью-Йорке домовладельцы включают отопление. Русские последний раз в сезоне выезжают на пикники.
|
||||
- 42 C: В Европе не функционирует транспорт. Русские едят мороженое на улице.
|
||||
- 73 C: Финский спецназ эвакуирует Санта-Клауса из Лапландии. Русские надевают ушанки.
|
||||
- 114 C: Замерзает этиловый спирт. У русских плохое настроение.
|
||||
- 273 C: Абсолютный ноль, остананавливается атомарное движение. Русские ругаются: "Холодно, мля!"
|
||||
- 295 C: У католиков в аду замерзают черти. Российская сборная по футболу становится чемпионом мира.
|
||||
|
||||
**********
|
||||
|
||||
На дискотеке в Германии русский в майке с надписью: "У турков три проблемы".
|
||||
К нему тут же подходит турок и спрашивает:
|
||||
|
||||
- Ты чего? Проблем ищешь? Ты наехать хочешь?
|
||||
- Это ваша первая проблема. Агрессивность. Вы всегда пытаетесь создавать проблемы на пустом месте.
|
||||
Когда дискотека заканчивается, то русского уже подкарауливает группа
|
||||
турков.
|
||||
- Сейчас ты ответишь за свои слова! - говорят они.
|
||||
- Это ваша вторая проблема. Вы не можете решать свои проблемы сами и сразу собираете своих по любому поводу.
|
||||
- Да как ты смеешь с нами так говорить?!! - турки повыхватывали ножи...
|
||||
- Это ваша третья проблема, - продолжает русский. - Вы всегда приходите с ножами на перестрелку.
|
||||
|
||||
**********
|
||||
|
||||
ДЕЛОВОЕ ПРЕДЛОЖЕНИЕ
|
||||
(пер. с англ, автор мне неизвестен)
|
||||
Джонни очень хотел одну девушку в своем офисе, но она принадлежала другому... Как-то раз ему стало так невмоготу, что он подошел к ней и сказал: "Я
|
||||
дам тебе 1000 долларов, если ты мне отдашься", но девушка ответила "НЕТ".
|
||||
Джонни сказал: "Да я быстро - я брошу деньги на пол, ты нагнешься подобрать, а как поднимешь - я уже закончу". Девушка задумалась на секунду, и ответила, что должна проконсультироваться с бойфрендом.
|
||||
|
||||
Она позвонила и рассказала тому все. Бойфренд ответил: "Проси 2000, и поднимай деньги очень быстро, так чтоб он даже не успел спустить штаны".
|
||||
Девушка согласилась, и дала свое согласие Джонни.
|
||||
|
||||
Прошло полчаса, бойфренд ждет, а девушка все не звонит... Наконец спустя 45 минут бойфренд позвонил сам и спросил, что случилось. Девушка ответила: "Этот подонок расплатился монетами."
|
||||
|
||||
МОРАЛЬ: Всегда рассматривайте деловое предложение досконально, до того, как вы его примете и вас поимеют!
|
||||
|
||||
**********
|
||||
|
||||
Начало учебного года в американской школе. Классная руководительница знакомит класс:
|
||||
|
||||
- Дети, у нас новенький – Шакиро Сузуки из Японии, знакомьтесь. А сейчас начинаем урок и посмотрим, как хорошо вы знаете американскую историю.
|
||||
Кто сказал "Свобода или смерть"?
|
||||
В классе мертвая тишина. Сузуки вскидывает руку:
|
||||
- Патрик Генри, 1775 год, Филадельфия.
|
||||
- Очень хорошо. А чьи слова: "Государство – это народ, и как таковое никогда не должно умереть"?
|
||||
Опять рука Сузуки:
|
||||
- Абрахам Линкольн, 1863 год, Вашингтон.
|
||||
Учительница строго смотрит на класс:
|
||||
- Стыдно, дети! Сузуки – японец, а знает американскую историю лучше всех!
|
||||
В этот момент тихий голос с задней парты:
|
||||
- Задолбали сраные япошки!
|
||||
Учительница резко оборачивается:
|
||||
- Кто сказал???!!!
|
||||
Сузуки вскакивает и оттарабанивает:
|
||||
- Генерал МакАртур, остров Гвадалканал, 1942 год.
|
||||
Возмущенный вопль:
|
||||
- Сузуки – дерьмо!!!
|
||||
И ни секунды задержки:
|
||||
- Валентино Росси на мотогонках ГранПри-Бразилия в Рио де Жанейро, 2002
|
||||
год! –выпаливает японец!
|
||||
Класс в истерике, училка в обмороке, распахивается дверь и появляется
|
||||
разъяренный директор школы:
|
||||
- Вашу мать! Что здесь за бардак???!!!
|
||||
Не успевший сесть Сузуки:
|
||||
- Президент Ельцин, заседание парламента России, 1993 год!
|
||||
|
||||
**********
|
||||
|
||||
Муж:
|
||||
|
||||
- Какого тёща приезжает?
|
||||
Жена:
|
||||
- Числа или хрена?
|
||||
|
||||
**********
|
||||
|
||||
Лозунг "Задушим коррупцию" был признан экстремистским как призывающий к
|
||||
насильственному свержению существующего строя.
|
||||
|
||||
**********
|
||||
|
||||
Урок "Основы православной культуры". Учительница:
|
||||
|
||||
- И помните, дети! Те, кто будет учиться на "4" и "5", попадут в рай. А
|
||||
те, кто будет учиться на "2" и "3", - в ад!
|
||||
Вовочка с задней парты:
|
||||
- Мариванна, а что, закончить школу живым нельзя?
|
||||
|
||||
**********
|
||||
|
||||
Штаб Ку Клукс Клана:
|
||||
|
||||
- Скажите, как вступить в вашу организацию?
|
||||
- Это просто. Нужно замочить 6 негров и одного кота.
|
||||
- А кота за что?
|
||||
- Поздравляю, вы приняты
|
||||
|
||||
**********
|
||||
|
||||
Увидев на холодильнике всего два магнитика - из Магадана и Воркуты, воры покормили кота и вымыли посуду.
|
||||
|
||||
**********
|
||||
|
||||
Боевик ИГИЛ остановил автомобиль христианской пары.
|
||||
Боевик ИГИЛ: «Ты мусульманин?»
|
||||
Христианин: «Да, я мусульманин».
|
||||
Боевик ИГИЛ: «Если ты мусульманин, перескажи суру из Корана».
|
||||
Христианин рассказал стихотворение из Библии.
|
||||
Боевик ИГИЛ: «Хорошо, можешь ехать».
|
||||
Через несколько минут жена, едва переведя дух, говорит мужу: «Не могу поверить, как ты пошел на такой риск. Почему ты сказал, что мы мусульмане? Если бы он узнал, что ты врёшь, он убил бы нас обоих!»
|
||||
«Зря волновалась. Если бы они знали Коран, они бы никогда не убивали людей!» – ответил ей муж.
|
||||
|
||||
**********
|
||||
|
||||
Сборная России взяла 4 золота на международной олимпиаде по физике в Цюрихе. Деньги и белые BMW никто не предложил. Даже не заметили.
|
||||
|
||||
**********
|
||||
|
||||
Когда в стране коррупции нет — микролитражки мчат по хайвеям.
|
||||
Когда коррупция — Бентли тащатся по бездорожью.
|
||||
Всё просто, брат.
|
||||
|
||||
**********
|
||||
|
||||
Интересно, а если провести обыск у всего руководства ФСБ - можно будет обратно понизить пенсионный возраст?
|
||||
|
||||
**********
|
||||
|
||||
Центр организации дорожного движения Москвы пришел к выводу, что личный автомобиль гражданину не нужен. 93% времени он стоит на приколе, а лишь 7% используется, заявил руководитель Департамента транспорта Максим Ликсутов.
|
||||
Остроумные люди посоветовали Максиму Ликсутову отрезать пенис, которым он пользуется меньше 10 минут в день.
|
||||
|
||||
**********
|
||||
|
||||
По поводу слов Кадырова, что его достало, что во всем обвиняют кавказцев... Знакомый татарин сказал: До тех пор пока ты ЧЕЛОВЕК, никого в России твоя национальность особо не интересует. Как только стал СКОТИНОЙ всем сразу интересно, чья это скотина гадит?
|
||||
|
||||
**********
|
||||
|
||||
Зачем пересаживать чиновников на отечественные автомобили, если они имеют право на бесплатный проезд в общественном транспорте?
|
||||
|
||||
**********
|
||||
|
||||
Почему те, кто хочет носить хиджаб не живут там, где его ношение приветствуется?
|
||||
|
||||
**********
|
||||
|
||||
В кафе заходит человек с собакой и заключает с посетителями пари,что его пес сейчас будет разговаривать. Но собака молчит. Человек оплачивает пари и уходит под общий хохот.
|
||||
|
||||
- Из-за тебя я проиграл уйму денег! - говорит хозяин собаке. - Почему ты не заговорил?
|
||||
- Чудак! - отвечает пес. - Ты только представь, сколько денег мы загребем завтра.
|
||||
|
||||
**********
|
||||
|
||||
Выходит утром гаишник на дорогу, голова после вчерашнего раскалывается.
|
||||
Смотрит - джип несется. Ну он остановил его с целью сбора средств на опохмел. Смотрит, а там бомж сидит. Документы проверил - правда, бомжа машина. Ну мент его спрашивает:
|
||||
|
||||
- Ты же бомж. Ты где такую крутую тачку взял?
|
||||
- А мне пьяные новые русские предложили, если я их рассмешу - джип мой. Ну я их и рассмешил.
|
||||
- А как?
|
||||
- Да я одному лысому на голову нагадил, у него сразу волосы выросли, вот умора была.
|
||||
Мент шапку снимает, там лысина. Он и говорит:
|
||||
- А ты мне так можешь?
|
||||
- Могу.
|
||||
Бомж гадит менту на лысину, a из кустов раздается хохот и крик:
|
||||
- Не, ну ваще, да я ему еще и хату подарю.
|
||||
|
||||
**********
|
||||
|
||||
Вовочка приходит в аптеку:
|
||||
|
||||
- Дайте мне упаковку презервативов!
|
||||
- Во-первых, это не для детей, - отвечает аптекарь, - а во-вторых, пусть придет папа и возьмет нужный размер.
|
||||
- Во-первых, это не для детей, а от детей, а во-вторых, это не для папы, а мама едет на курорт, и какие там размеры будут, она еще не знает...
|
||||
|
||||
Кенийский бегун Абель Мутай был всего в нескольких футах от финиша, но перепутал с вывесками и остановился, думая, что завершил гонку. Испанский бегун, Иван Фернандес, стоял за ним и, понимая, что происходит, начал кричать на кенийца, чтобы он продолжил бег. Мутай не знал испанского и не понял. Понимая, что происходит, Фернандес толкнул Мутая к победе. Журналист спросил Ивана: «Зачем ты это сделал?» Иван ответил: «Моя мечта заключается в том, чтобы когда-нибудь у нас была такая общественная жизнь, где мы толкаемся и помогаем друг другу побеждать». Журналистка настаивала: «Но почему ты дал победить Кении?» Иван ответил:«Я не дал ему победить, он собирался победить. Гонка была его». Журналист настаивал, и снова спросил: «А ведь можно было победить!» Иван посмотрел на него и ответил: «А в чем заслуга моей победы? Какая честь будет в этой медали? Что бы моя мама об этом подумала? Ценности передаются из поколения в поколение. Каким ценностям мы учим наших детей?»
|
||||
|
||||
**********
|
||||
|
||||
Попали в Ад американец, индус и русский. Встретил их Черт и говорит:
|
||||
|
||||
- Всем, кто сюда попадает, даю шанс перейти в Рай.
|
||||
И достает здоровенный кнут (побольше, чем у Харрисона Форда в "Последнем
|
||||
крестовом походе"):
|
||||
- Кто выдержит три удара не закричав - отпускаю! Можете защищаться, чем хотите.
|
||||
Первым вышел американец.
|
||||
- Чем хочешь защищаться?
|
||||
Американец взял здоровый гранитный камень:
|
||||
- Я готов!
|
||||
Черт размахнулся в первый раз и... камень вдребезги. Второй раз - и американец заорал как бешенный...
|
||||
- Следующий, - говорит Черт.
|
||||
Выходит индус.
|
||||
- Чем будешь защищаться?
|
||||
- Ничем! - отвечает индус, - Я 80 лет занимался йогой, и в медитации тело не чувствует боли!
|
||||
- Ладно.
|
||||
Первый удар. Индус: - Ошшш...
|
||||
Второй удар. Индус: - Ошшш...
|
||||
Третий удар. Индус: - Ошшш...
|
||||
- Ух е# твою... Еще никто не выдерживал трех ударов. - говорит Черт. - Ну
|
||||
что ж, ты свободен, можешь спокойно идти в Рай.
|
||||
- Нет, - говорит индус, - хочу остаться и посмотреть. Во всех анекдотах русские выигрывают. Хочу увидеть, как у него на этот раз получится.
|
||||
- Ладно, останься. Ну, чем думаешь защищаться? - обращается Черт к русскому.
|
||||
- Чем защищаться - индусом, конечно...
|
||||
|
||||
**********
|
||||
|
||||
Отвечать надо быстро, не раздумывая и не тратя понапрасну время.
|
||||
А главное - не мошенничать!
|
||||
|
||||
1. Вы участвуете в соревнованиях и обогнали бегуна, занимающего вторую
|
||||
позицию. Какую позицию вы теперь занимаете?
|
||||
Ответ: Если вы ответили, что вы теперь первый - то вы абсолютно не
|
||||
правы.
|
||||
Вы обогнали второго бегуна и заняли его место, так что вы теперь на
|
||||
второй позиции.
|
||||
Попробуйте не ошибиться во втором вопросе.
|
||||
2. Вы обогнали последнего бегуна, на какой позиции вы теперь находитесь?
|
||||
Ответ: Если вы ответили на предпоследнем - вы опять абсолютно не правы.
|
||||
Подумайте. Как можно обогнать бегуна, идущего последним? Если вы бежите
|
||||
за ним, значит он не последний. Ответ - это невозможно. Получается, что
|
||||
использование мозга ваша не самая сильная сторона.
|
||||
Как бы то ни было - вот еще один вопрос. Ничего не пишите и не
|
||||
используйте калькулятор, и помните - вы должны отвечать быстро.
|
||||
Возьмите 1000. Прибавьте 40. Прибавьте еще тысячу. Прибавьте 30.
|
||||
Еще 1000.
|
||||
Плюс 20. Плюс 1000. И плюс 10. Что получилось?
|
||||
Ответ 5000? Опять неверно. Правильный ответ 4100. Попробуйте пересчитать
|
||||
на калькуляторе.
|
||||
Сегодня точно не ваш день. Но, может быть, получится с последним вопросом.
|
||||
У отца Мэри есть пять дочерей: 1. Чача 2. Чече 3. Чичи 4 Чочо.
|
||||
Вопрос: Как зовут пятую дочь? Думайте быстро. Ответ чуть ниже.
|
||||
Ответ: Чучу? НЕТ! Конечно, ее зовут Мэри. Прочтите еще раз вопрос.
|
||||
ВЫВОД: Вы самое слабое звено - прощайте.
|
||||
|
||||
**********
|
||||
|
||||
Мужик просыпается с утра с жуткого бодуна, открывает глаза, голова болит, оглядывается по сторонам: фуууу, дома... встает с кровати, ощупывает себя - е-мое, в пижаме... в жизни пижаму не одевал. Смотрит - на туалетном столике стакан воды, таблетка аспирина и записка от жены:
|
||||
"Милый, завтрак на столе, все прибрала, твоя навеки - жена". Мужик в совершенном непонимании, выпивает таблетку и идет в ванную... по пути обнаруживает, что квартира не то что чистая, просто вылизана до блеска, сын сидит у себя в комнате, делает уроки...
|
||||
|
||||
- Сынок, а что вчера было?
|
||||
- Ты пришел пьяный, как обычно под утро. Облевал всю прихожую, нагадил мимо унитаза, побил в кухне всю посуду, поставил матери фингал под глазом.
|
||||
- Ну и, что случилось с мамой, с квартирой???
|
||||
- Ааа, ты про это, просто когда тебя мама стала укладывать спать и начала стягивать с тебя штаны, ты заорал "уйди, сука - Я ЖЕНАТЫЙ!!!"
|
||||
|
||||
**********
|
||||
|
||||
Штатский Джонс был назначен в армейский учебный центр, где он должен был просвещать рекрутов по поводу различных правительственных обязательств перед ними, особенно о Страховании Жизни Военослужащих (СЖВ). Вскоре после этого лейтенант центра заметил, что Джонс имеет почти 100%-ю продажу страховок СЖВ, чего раньше никогда не бывало. Лейтенант сел в конце заполненной рекрутами комнаты и стал слушать торговую подачу Джонса. Джонс объяснил новым рекрутам основы СЖВ, а затем сказал:
|
||||
"Если у вас есть СЖВ и вы пошли в бой и погибли, - правительство обязано выплатить вашим наследникам 200 000$. Если у вас нет СЖВ и вы пошли в бой и погибли, - правительство обязано выплатить вашим наследникам максимум всего лишь 6000$". "А теперь", сказал он в заключение, "как вы думаете, кого они пошлют в бой первыми?"
|
||||
|
||||
**********
|
||||
|
||||
- Ватсон, а что это вы курите? Дайте угадаю - табак "Королева Вирджиния"
|
||||
с листочками вишни, из юбилейного выпуска в бархатной упаковке?
|
||||
- Поразительно, Холмс! Как это вы угадали?
|
||||
- Ей-богу, Ватсон! Ну не миссис Хадсон же свистнула из моей комнаты
|
||||
последнюю пачку!
|
||||
|
||||
**********
|
||||
|
||||
У последней остановки метро ждет автобуса инженер, который допоздна
|
||||
делал халтуру на работе. Полдвенадцатого ночи. Автобуса нет. Он весь
|
||||
задубел... И тут возле него останавливается шикарный Лексус, опускается
|
||||
окно и девушка типа “порномодель” говорит: "Садитесь, я вас подвезу". Он
|
||||
отнекивается, мол денег нету...Она: "Да какие деньги! Вы ж на бирюлевский
|
||||
автобус тут стоите... А как они ходят?! Садитесь, я так вас подвезу, а то
|
||||
замерзнете..."
|
||||
Он сел назад. Поехали. Тепло. Класс. И тут она спрашивает:
|
||||
|
||||
- Ничего, если мы за подружкой моей заедем? Я с ней раньше
|
||||
договаривалась. Но это по пути... Пара минут...
|
||||
Он говорит:
|
||||
- Конечно... Хозяин-барин. Какие вопросы...
|
||||
Заехали. Выходит девушка такого же калибра, как и первая. Плюхается на
|
||||
сиденье и говорит:
|
||||
- Мань, я похавать не успела. Давай причалим к магазинчику хавки купим...
|
||||
Причалили... Та зашла... Выходит. У нее 2 бутылки французского шампанского
|
||||
по штуке баксов, сувенирное (на полкило) ведерочко черной икры,
|
||||
французские батоны, еще что-то в фирменных коробочках...
|
||||
Едут... Высаживают мужика... И тут та, что со жратвой говорит:
|
||||
- Мань, а что мы тут в машине крошить будем?
|
||||
А та, что за рулем - мужику:
|
||||
- Вы не против, если мы на пять минут к вам зайдем, перекусим и дальше
|
||||
поедем?
|
||||
Он извиняется, что мол, холостяцкий беспорядок, они: “Ничего... Мы
|
||||
ненадолго...”
|
||||
Поднялись к нему. Выпили эти две бутылки. Закусили... И /делали взрослые дела/ втроем до утра.
|
||||
|
||||
А через какое-то время эти телки прохаживаются в Доме кино по какой-то
|
||||
тусовке. И одна говорит:
|
||||
|
||||
- Как все это меня достало! Эти престарелые плейбои, этот Михалков со
|
||||
своими проститутками, этот Гусман старый дедун, эти все заслуженные
|
||||
П***** России... Блин, смотреть уже на них не могу.
|
||||
А вторая:
|
||||
- Слушай, давай плюнем на это все и поедем к Коле в Бирюлево!
|
||||
Первая:
|
||||
- Да-а... К Коле в Бирюлево... Думаешь, он нас вспомнит?
|
||||
|
||||
ПАМЯТНИК ЛАБРАДОРУ МОНТИ *** В городе Квиснсленде (Австралия) жил лабрадор по кличке Монти. Хозяин был глубоко пожилым человеком. Он всегда брал Монти в походы по местным магазинам и обучил его носить в зубах свою корзину с продуктами. Однажды владелец Монти был не в силах пойти по магазинам. Он послал Монти со списком покупок и деньгами в корзине. Монти обошел все магазины, в которые он заходил вместе с хозяином. Продавцы читали записку и клали в корзинку необходимое. С тех пор Монти каждый день бегал по магазинам с корзинкой в зубах. Монти получил такую известность, что когда случилось неизбежное и он умер, местная община решила возвести ему памятник в виде бронзовой статуи с корзинкой, полной продуктов. Теперь, бронзовый Монти в натуральную величину сидит при входе в торговый центр, куда он бегал за продуктами для своего хозяина. Памятник установили 15 июня 1996 года.
|
||||
**********
|
||||
|
||||
Как попасть в рай (притча)
|
||||
По длинной, дикой, утомительной дороге шел человек с собакой.
|
||||
Шел он себе шел, устал, собака тоже устала. Вдруг перед ним - оазис!
|
||||
Прекрасные ворота, за оградой - музыка, цветы, журчание ручья,
|
||||
словом, отдых.
|
||||
|
||||
- Что это такое? - спросил путешественник у привратника.
|
||||
- Это рай, ты уже умер, и теперь можешь войти и отдохнуть
|
||||
по-настоящему.
|
||||
- А есть там вода?
|
||||
- Сколько угодно: чистые фонтаны, прохладные бассейны...
|
||||
- А поесть дадут?
|
||||
- Все, что захочешь.
|
||||
- Но со мной собака.
|
||||
- Сожалею, сэр, с собаками нельзя. Ее придется оставить здесь.
|
||||
И путешественник пошел мимо.. Через некоторое время дорога привела его
|
||||
на ферму. У ворот тоже сидел привратник.
|
||||
- Я хочу пить, - попросил путешественник.
|
||||
- Заходи, во дворе есть колодец.
|
||||
- А моя собака?
|
||||
- Возле колодца увидишь поилку.
|
||||
- А поесть?
|
||||
- Могу угостить тебя ужином.
|
||||
- А собаке?
|
||||
- Найдется косточка.
|
||||
- А что это за место?
|
||||
- Это рай.
|
||||
- Как так? Привратник у дворца неподалеку сказал мне, что рай - там.
|
||||
- Врет он все. Там ад.
|
||||
- Как же вы, в раю, это терпите?
|
||||
- Это нам очень полезно. До рая доходят только те, кто не бросает
|
||||
своих друзей.
|
||||
|
||||
**********
|
||||
|
||||
Мужик едет на встречу, опаздывает, нервничает, не может найти место
|
||||
припарковаться. Поднимает лицо к небу и говорит:
|
||||
— Господи, помоги мне найти место для парковки. Я тогда брошу пить и
|
||||
буду каждое воскресенье ходить в церковь!
|
||||
Вдруг чудесным образом появляется свободное местечко. Мужик снова
|
||||
обращается к небу:
|
||||
— А, всё, не надо. Нашёл!
|
||||
|
||||
**********
|
||||
|
||||
Журналисты спрашивают у фермера:
|
||||
|
||||
- Скажите, как у вас прошел год.
|
||||
- Не поверите, замечательно. Урожай зерна хороший - без хлеба не
|
||||
останусь, картошка удалась - опять таки буду не голодный, а еще свинья
|
||||
опоросилась...
|
||||
- Вы не хотели бы поблагодарить за это президента?
|
||||
- Да с чего ж? Пахал сам, сеял сам, растил и собирал опять таки сам - в
|
||||
чем тут его заслуга.
|
||||
- Как так? (жестко) А вы подумайте!
|
||||
- А, ну ежли подумать, то насчет свиньи не отрицаю, тут всяко могло
|
||||
быть...
|
||||
|
||||
**********
|
||||
|
||||
Сомалийский иммигрант прибыл в Берлин. Он останавливает первого человека, которого он видит и говорит: "Благодарю вас, господин. Германия позволила мне жить в этой стране, дала мне жилье, денег на еду, бесплатное медицинское обслуживание, бесплатное образование и никаких налогов!" Прохожий отвечает: "Вы ошибаетесь, я афганец." Человек идет дальше и встречает другого прохожего: "Спасибо за то, что такая красивая страна Германия! и т.д.". Человек говорит: "Я не немец, я иракец!" Вновь прибывший идет дальше, к следующему человеку, пожимает ему руку и говорит: "Спасибо за прекрасную Германию!" "Этот человек поднимает руку и говорит: "Я из Пакистана, я не из Германии!" Он, наконец, видит - идет милая дама. Спрашивает: "Вы немка?" Она говорит: "Нет, я из Индии!" Озадаченный, он спрашивает ее: "А где же немцы?" Индуска проверяет часы и отвечает: "Так они сейчас работают!"
|
||||
|
||||
**********
|
||||
|
||||
Cидит Мухаммед на корточках в Берлине и плюет на землю через дырку в зубах. Вдруг появляется фея и говорит:
|
||||
— Я социалистическая социальная либеральная фея! Я прилетела, чтобы исполнить три желания!
|
||||
— Посмотри, какая у меня дырка во рту! Я хочу, чтобы мне вылечили и вставили все зубы!
|
||||
Не успел Мухаммед произнести эти слова, как тотчас вышел закон о бесплатном лечении и протезировании зубов для социальных иностранцев, и его рот засиял белоснежной голливудской улыбкой.
|
||||
— Я очень скучаю по своим четырем женам и пятнадцати детишкам, а также по родителям, братьям и сестрам, родителям-братьям-сестрам моих жен! Я хочу, чтобы мы все жили на роскошной вилле, и чтобы денег всегда много было!
|
||||
Не успел Мухаммед договорить, как оказался в прекрасной вилле! На столе — текст закона о воссоединении семей для социальных иностранцев, а также банковские распечатки со сведениями о поступивших пособиях. Дом полностью меблирован и оснащен электроприборами в соответствии с законом о помощи в приобретении мебели и бытовой техники для социальных иностранцев.
|
||||
Счастливый Мухаммед просто не знает, чего бы ему еще попросить, ведь одно желание еще осталось. И он попросил:
|
||||
— Хочу стать настоящим немцем. Не только по гражданству. Хочу быть голубоглазым блондином, и чтоб меня звали Фриц Шульц!
|
||||
Не успел он закончить фразу, как все исчезло, и он обнаружил себя вновь сидящим на корточках и плюющим на землю сквозь дырку в зубах.
|
||||
— Что случилось? — спросил он у феи.
|
||||
— Как не стыдно, господин Шульц, клянчить у государства! Вы должны заботиться о себе сами! Идите и ищите работу!
|
||||
|
||||
**********
|
||||
|
||||
А давайте больным детям на лечение брать из бюджета, а депутатам зарплату собирать на первом канале!
|
||||
|
||||
**********
|
||||
|
||||
Идёт Будда с учениками по дороге. Видит: яма, в ней вол, крестьянин пытается его вытянуть, но сил не хватает. Будда кивнул ученикам, они быстро помогли вытянуть животное. Идут дальше, снова яма, в ней вол, на краю сидит крестьянин и горько плачет. Будда прошёл мимо и как бы не заметил. Ученики его спрашивают:
|
||||
|
||||
- Учитель, почему ты не захотел помочь этому крестьянину?
|
||||
- Помочь плакать?
|
||||
|
||||
**********
|
||||
|
||||
Воздушный шар сбился с курса, и воздухоплаватель срочно опустился с ним вниз. Увидев внизу человека, он спросил:
|
||||
|
||||
- Извините, где я нахожусь?
|
||||
- Вы находитесь на воздушном шаре, в 15м над землей. Ваши координаты - 5°28'17" N и 100°40'19" E.
|
||||
- Похоже, вы математик, - вздохнул воздухоплаватель.
|
||||
- Да, я математик, - согласился прохожий. - Как вы догадались?
|
||||
- Ваш ответ, по-видимому, точный и полный, но для меня совершенно бесполезный. Я по-прежнему не знаю, где я нахожусь, и что мне делать. Вы мне нисколько не помогли, только напрасно отняли время.
|
||||
- А вы, похоже, из управленцев, - заметил математик.
|
||||
- Я действительно топ-менеджер серьезной компании, - воспрял воздухоплаватель. - Но как вы догадались? Вы видели меня по телевизору?
|
||||
- Зачем? - удивился математик. - Судите сами: вы не понимаете ни где вы находитесь, ни что вам следует делать, в этом вы полагаетесь на нижестоящих. Спрашивая совета у эксперта, вы ни на секунду не задумываетесь, способны ли вы понять его ответ, и когда оказывается, что это - не так, вы возмущаетесь вместо того, чтобы переспросить. Вы находитесь ровно в том же положении, что и до моего ответа, но теперь почему-то обвиняете в этом меня. Наконец, вы находитесь выше других только благодаря дутому пузырю, и если с ним что-то случится - падение станет для вас фатальным.
|
||||
|
||||
**********
|
||||
|
||||
Забавно, что когда Сбербанк празднует свой юбилей, то он считает свою историю с 1841 года, а когда ему задают вопросы про вклады 1991 года, то оказывается, что это совершенно другой банк.
|
||||
|
||||
**********
|
||||
|
||||
А давайте что-нибудь споем в поддержку артистов, попавших в сложную финансовую ситуацию?
|
||||
|
||||
**********
|
||||
|
||||
Горит здание Сбербанка.
|
||||
Звонок в пожарную охрану:
|
||||
|
||||
- Срочно приезжайте!!! Пожар в здании Сбербанка!!!
|
||||
- Одну минуту, я переключу вас на специалиста
|
||||
играет бодрая музыка, затем слышатся радостные фразы: "Если вы хотите узнать о наших новых услугах - нажмите "1". Если хотите заключить договор на монтаж противопожарного оборудования - нажмите "2". Внимание! Пожарная охрана представляет вам совершенно новый способ тушения пожаров! Хотите узнать больше? Нажмите "3". Не услышали свой вариант? Оставайтесь на линии. Приготовьте кадастровый номер вашего объекта, а также паспортные данные его владельца. Ваш звонок очень важен для нас - оставайтесь на линии.
|
||||
Хотите попробовать потушить пожар самостоятельно? Воспользуйтесь услугой "Продвинутый пожарный"! Чтобы узнать, как подключить - нажмите "5""
|
||||
........
|
||||
- Оператор пожарной охраны Сергей, чем я могу вам помочь?
|
||||
- У нас пожар! Горит три помещения!
|
||||
- Скажите, как я могу к вам обращаться?
|
||||
- Вы идиот? У нас здание горит! Не надо ко мне обращаться, срочно выезжайте тушить!
|
||||
- Подскажите кадастровый номер здания и ФИО владельца
|
||||
- Да не знаю я никакого кадастрового номера, я назвал вам адрес! Этого недостаточно, чтобы выехать на тушение пожара?!
|
||||
- Оставайтесь на линии, я переведу вас на специалиста по поддержке
|
||||
Играет бодрая музыка,"Если вы хотите заказать монтаж противопожарной сигнализации - произнесите: "Монтаж сигнализации", Если вы хотите подключиться к услуге "Круглосуточный пожарный расчет" - произнесите: "Подключиться". Вы не выбрали подходящий вариант. Ваш звонок будет переведен на оператора".
|
||||
- Здравствуйте, меня зовут Александр, чем могу помочь?!
|
||||
- У нас здание горит! Сделайте что-нибудь!
|
||||
- Подскажите, как я могу к вам обращаться?
|
||||
- Б...!!! С....! .... ....! Пожар!!!
|
||||
- Наши специалисты рассмотрят вашу проблему. Скажите, по какому номеру мы можем с вами связаться?
|
||||
|
||||
**********
|
||||
|
||||
А разве первыми в военкомат вызывают не тех, у кого на машине наклеено: "Можем повторить!"?
|
||||
|
||||
**********
|
||||
|
||||
Не спрашивай у мужчины про его доходы, у женщины про возраст, у патриота, откуда у него американский паспорт.
|
||||
|
||||
**********
|
642
back/internal/knocker.go
Normal file
642
back/internal/knocker.go
Normal file
@@ -0,0 +1,642 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/sha256"
|
||||
_ "embed"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
//go:embed jokes.md
|
||||
var jokesFile string
|
||||
|
||||
func GetRandomJoke() string {
|
||||
// Инициализируем генератор случайных чисел
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
||||
jokes := strings.Split(jokesFile, "**********")
|
||||
|
||||
var cleanJokes []string
|
||||
for _, joke := range jokes {
|
||||
if trimmed := strings.TrimSpace(joke); trimmed != "" {
|
||||
cleanJokes = append(cleanJokes, trimmed)
|
||||
}
|
||||
}
|
||||
|
||||
if len(cleanJokes) == 0 {
|
||||
return "Шутки не найдены"
|
||||
}
|
||||
|
||||
return cleanJokes[rand.Intn(len(cleanJokes))]
|
||||
}
|
||||
|
||||
const (
|
||||
// Системная переменная для ключа шифрования
|
||||
EncryptionKeyEnvVar = "GO_KNOCKER_SERVE_PASS"
|
||||
)
|
||||
|
||||
// Config представляет конфигурацию port knocking
|
||||
type Config struct {
|
||||
Targets []Target `yaml:"targets"`
|
||||
}
|
||||
|
||||
// Target представляет цель для port knocking
|
||||
type Target struct {
|
||||
Host string `yaml:"host"`
|
||||
Ports []int `yaml:"ports"`
|
||||
Protocol string `yaml:"protocol"` // "tcp" или "udp"
|
||||
Delay Duration `yaml:"delay"` // задержка между пакетами
|
||||
WaitConnection bool `yaml:"wait_connection"` // ждать ли установления соединения
|
||||
Gateway string `yaml:"gateway"` // шлюз для отправки (опционально)
|
||||
}
|
||||
|
||||
// Duration для поддержки YAML десериализации времени
|
||||
type Duration time.Duration
|
||||
|
||||
func (d *Duration) UnmarshalYAML(value *yaml.Node) error {
|
||||
var str string
|
||||
if err := value.Decode(&str); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
duration, err := time.ParseDuration(str)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*d = Duration(duration)
|
||||
return nil
|
||||
}
|
||||
|
||||
// PortKnocker основная структура для выполнения port knocking
|
||||
type PortKnocker struct{}
|
||||
|
||||
// NewPortKnocker создает новый экземпляр PortKnocker
|
||||
func NewPortKnocker() *PortKnocker {
|
||||
return &PortKnocker{}
|
||||
}
|
||||
|
||||
// Execute выполняет port knocking на основе конфигурации
|
||||
func (pk *PortKnocker) Execute(configFile, keyFile string, verbose bool, globalWaitConnection bool) error {
|
||||
// Читаем конфигурацию
|
||||
config, err := pk.loadConfig(configFile, keyFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("ошибка загрузки конфигурации: %w", err)
|
||||
}
|
||||
|
||||
return pk.ExecuteWithConfig(config, verbose, globalWaitConnection)
|
||||
}
|
||||
|
||||
// ExecuteWithConfig выполняет port knocking с готовой конфигурацией
|
||||
func (pk *PortKnocker) ExecuteWithConfig(config *Config, verbose bool, globalWaitConnection bool) error {
|
||||
if verbose {
|
||||
fmt.Printf("Загружена конфигурация с %d целей\n", len(config.Targets))
|
||||
}
|
||||
|
||||
// Выполняем port knocking для каждой цели
|
||||
for i, target := range config.Targets {
|
||||
if verbose {
|
||||
fmt.Printf("Цель %d/%d: %s:%v (%s)\n", i+1, len(config.Targets), target.Host, target.Ports, target.Protocol)
|
||||
}
|
||||
|
||||
// Применяем глобальный флаг если не задан локально
|
||||
if globalWaitConnection && !target.WaitConnection {
|
||||
target.WaitConnection = true
|
||||
}
|
||||
|
||||
if err := pk.knockTarget(target, verbose); err != nil {
|
||||
return fmt.Errorf("ошибка при knocking цели %s: %w", target.Host, err)
|
||||
}
|
||||
|
||||
// Добавляем задержку между целями (кроме последней)
|
||||
if i < len(config.Targets)-1 && target.Delay > 0 {
|
||||
if verbose {
|
||||
fmt.Printf("Ожидание %v перед следующей целью...\n", time.Duration(target.Delay))
|
||||
}
|
||||
time.Sleep(time.Duration(target.Delay))
|
||||
}
|
||||
}
|
||||
|
||||
if verbose {
|
||||
fmt.Println("Port knocking завершен успешно")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// loadConfig загружает конфигурацию из файла с поддержкой шифрования
|
||||
func (pk *PortKnocker) loadConfig(configFile, keyFile string) (*Config, error) {
|
||||
data, err := os.ReadFile(configFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("не удалось прочитать файл конфигурации: %w", err)
|
||||
}
|
||||
|
||||
// Проверяем, зашифрован ли файл (начинается с "ENCRYPTED:")
|
||||
if strings.HasPrefix(string(data), "ENCRYPTED:") {
|
||||
fmt.Println("Обнаружен зашифрованный файл конфигурации")
|
||||
|
||||
// Получаем ключ шифрования
|
||||
key, err := pk.getEncryptionKey(keyFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("не удалось получить ключ шифрования: %w", err)
|
||||
}
|
||||
|
||||
// Расшифровываем данные
|
||||
decryptedData, err := pk.decrypt(data[10:], key) // пропускаем "ENCRYPTED:"
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("не удалось расшифровать конфигурацию: %w", err)
|
||||
}
|
||||
data = decryptedData
|
||||
}
|
||||
|
||||
// Парсим YAML
|
||||
var config Config
|
||||
if err := yaml.Unmarshal(data, &config); err != nil {
|
||||
return nil, fmt.Errorf("не удалось разобрать YAML: %w", err)
|
||||
}
|
||||
|
||||
return &config, nil
|
||||
}
|
||||
|
||||
// LoadConfigFromString загружает конфигурацию из строки YAML
|
||||
func LoadConfigFromString(yamlStr string) (*Config, error) {
|
||||
// Проверяем, зашифрована ли строка (начинается с "ENCRYPTED:")
|
||||
if strings.HasPrefix(yamlStr, "ENCRYPTED:") {
|
||||
// Создаем временный PortKnocker для расшифровки
|
||||
pk := NewPortKnocker()
|
||||
|
||||
// Получаем ключ шифрования
|
||||
key, err := pk.getEncryptionKey("")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("не удалось получить ключ шифрования: %w", err)
|
||||
}
|
||||
|
||||
// Расшифровываем данные
|
||||
decryptedData, err := pk.decrypt([]byte(yamlStr[10:]), key) // пропускаем "ENCRYPTED:"
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("не удалось расшифровать конфигурацию: %w", err)
|
||||
}
|
||||
yamlStr = string(decryptedData)
|
||||
}
|
||||
|
||||
// Парсим YAML
|
||||
var config Config
|
||||
if err := yaml.Unmarshal([]byte(yamlStr), &config); err != nil {
|
||||
return nil, fmt.Errorf("не удалось разобрать YAML: %w", err)
|
||||
}
|
||||
|
||||
return &config, nil
|
||||
}
|
||||
|
||||
// getEncryptionKey получает ключ шифрования из файла или системной переменной и хеширует его
|
||||
func (pk *PortKnocker) getEncryptionKey(keyFile string) ([]byte, error) {
|
||||
var rawKey []byte
|
||||
var err error
|
||||
|
||||
if keyFile != "" {
|
||||
// Читаем ключ из файла
|
||||
rawKey, err = os.ReadFile(keyFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("не удалось прочитать файл ключа: %w", err)
|
||||
}
|
||||
} else {
|
||||
// Пытаемся получить ключ из системной переменной
|
||||
key := os.Getenv(EncryptionKeyEnvVar)
|
||||
if key == "" {
|
||||
return nil, fmt.Errorf("ключ шифрования не найден ни в файле, ни в переменной %s", EncryptionKeyEnvVar)
|
||||
}
|
||||
rawKey = []byte(key)
|
||||
}
|
||||
|
||||
// Хешируем ключ SHA256 чтобы получить всегда 32 байта для AES-256
|
||||
hash := sha256.Sum256(rawKey)
|
||||
return hash[:], nil
|
||||
}
|
||||
|
||||
// decrypt расшифровывает данные с помощью AES-GCM
|
||||
func (pk *PortKnocker) decrypt(encryptedData []byte, key []byte) ([]byte, error) {
|
||||
// Декодируем base64
|
||||
data, err := base64.StdEncoding.DecodeString(string(encryptedData))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("не удалось декодировать base64: %w", err)
|
||||
}
|
||||
|
||||
// Создаем AES cipher
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("не удалось создать AES cipher: %w", err)
|
||||
}
|
||||
|
||||
// Создаем GCM
|
||||
gcm, err := cipher.NewGCM(block)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("не удалось создать GCM: %w", err)
|
||||
}
|
||||
|
||||
// Извлекаем nonce
|
||||
nonceSize := gcm.NonceSize()
|
||||
if len(data) < nonceSize {
|
||||
return nil, fmt.Errorf("данные слишком короткие")
|
||||
}
|
||||
|
||||
nonce, ciphertext := data[:nonceSize], data[nonceSize:]
|
||||
|
||||
// Расшифровываем
|
||||
plaintext, err := gcm.Open(nil, nonce, ciphertext, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("не удалось расшифровать: %w", err)
|
||||
}
|
||||
|
||||
return plaintext, nil
|
||||
}
|
||||
|
||||
// knockTarget выполняет port knocking для одной цели
|
||||
func (pk *PortKnocker) knockTarget(target Target, verbose bool) error {
|
||||
// Проверяем на "шутливую" цель 1
|
||||
if target.Host == "8.8.8.8" && len(target.Ports) == 1 && target.Ports[0] == 8888 {
|
||||
pk.showEasterEgg()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Проверяем на "шутливую" цель 2
|
||||
if target.Host == "1.1.1.1" && len(target.Ports) == 1 && target.Ports[0] == 1111 {
|
||||
pk.showRandomJoke()
|
||||
return nil
|
||||
}
|
||||
|
||||
protocol := strings.ToLower(target.Protocol)
|
||||
if protocol != "tcp" && protocol != "udp" {
|
||||
return fmt.Errorf("неподдерживаемый протокол: %s", target.Protocol)
|
||||
}
|
||||
|
||||
// Вычисляем таймаут как половину интервала между пакетами
|
||||
timeout := time.Duration(target.Delay) / 2
|
||||
if timeout < 100*time.Millisecond {
|
||||
timeout = 100 * time.Millisecond // минимальный таймаут
|
||||
}
|
||||
|
||||
for i, port := range target.Ports {
|
||||
if verbose {
|
||||
fmt.Printf(" Отправка пакета на %s:%d (%s)\n", target.Host, port, protocol)
|
||||
}
|
||||
|
||||
if err := pk.sendPacket(target.Host, port, protocol, target.WaitConnection, timeout, target.Gateway); err != nil {
|
||||
if target.WaitConnection {
|
||||
return fmt.Errorf("ошибка отправки пакета на порт %d: %w", port, err)
|
||||
} else {
|
||||
if verbose {
|
||||
fmt.Printf(" Предупреждение: не удалось отправить пакет на порт %d: %v\n", port, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Задержка между пакетами (кроме последнего)
|
||||
if i < len(target.Ports)-1 {
|
||||
delay := time.Duration(target.Delay)
|
||||
if delay > 0 {
|
||||
if verbose {
|
||||
fmt.Printf(" Ожидание %v...\n", delay)
|
||||
}
|
||||
time.Sleep(delay)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// sendPacket отправляет один пакет на указанный хост и порт
|
||||
func (pk *PortKnocker) sendPacket(host string, port int, protocol string, waitConnection bool, timeout time.Duration, gateway string) error {
|
||||
address := net.JoinHostPort(host, fmt.Sprintf("%d", port))
|
||||
|
||||
var conn net.Conn
|
||||
var err error
|
||||
|
||||
// Настройка локального адреса если указан шлюз
|
||||
var localAddr net.Addr
|
||||
if gateway != "" {
|
||||
if strings.Contains(gateway, ":") {
|
||||
localAddr, err = net.ResolveTCPAddr("tcp", gateway)
|
||||
if err != nil {
|
||||
return fmt.Errorf("не удалось разрешить адрес шлюза %s: %w", gateway, err)
|
||||
}
|
||||
} else {
|
||||
// Если указан только IP, добавляем порт 0
|
||||
localAddr, err = net.ResolveTCPAddr("tcp", gateway+":0")
|
||||
if err != nil {
|
||||
return fmt.Errorf("не удалось разрешить адрес шлюза %s: %w", gateway, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch protocol {
|
||||
case "tcp":
|
||||
if localAddr != nil {
|
||||
dialer := &net.Dialer{
|
||||
LocalAddr: localAddr,
|
||||
Timeout: timeout,
|
||||
}
|
||||
conn, err = dialer.Dial("tcp", address)
|
||||
} else {
|
||||
conn, err = net.DialTimeout("tcp", address, timeout)
|
||||
}
|
||||
case "udp":
|
||||
if localAddr != nil {
|
||||
dialer := &net.Dialer{
|
||||
LocalAddr: localAddr,
|
||||
Timeout: timeout,
|
||||
}
|
||||
conn, err = dialer.Dial("udp", address)
|
||||
} else {
|
||||
conn, err = net.DialTimeout("udp", address, timeout)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("неподдерживаемый протокол: %s", protocol)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if waitConnection {
|
||||
return fmt.Errorf("не удалось подключиться к %s: %w", address, err)
|
||||
} else {
|
||||
// Для UDP и TCP без ожидания соединения просто отправляем пакет
|
||||
return pk.sendPacketWithoutConnection(host, port, protocol, localAddr)
|
||||
}
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
// Отправляем пустой пакет
|
||||
_, err = conn.Write([]byte{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("не удалось отправить пакет: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// sendPacketWithoutConnection отправляет пакет без установления соединения
|
||||
func (pk *PortKnocker) sendPacketWithoutConnection(host string, port int, protocol string, localAddr net.Addr) error {
|
||||
address := net.JoinHostPort(host, fmt.Sprintf("%d", port))
|
||||
|
||||
switch protocol {
|
||||
case "udp":
|
||||
// Для UDP просто отправляем пакет
|
||||
var conn net.Conn
|
||||
var err error
|
||||
|
||||
if localAddr != nil {
|
||||
dialer := &net.Dialer{
|
||||
LocalAddr: localAddr,
|
||||
}
|
||||
conn, err = dialer.Dial("udp", address)
|
||||
} else {
|
||||
conn, err = net.Dial("udp", address)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("не удалось создать UDP соединение к %s: %w", address, err)
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
_, err = conn.Write([]byte{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("не удалось отправить UDP пакет: %w", err)
|
||||
}
|
||||
|
||||
case "tcp":
|
||||
// Для TCP без ожидания соединения используем короткий таймаут
|
||||
var conn net.Conn
|
||||
var err error
|
||||
|
||||
if localAddr != nil {
|
||||
dialer := &net.Dialer{
|
||||
LocalAddr: localAddr,
|
||||
Timeout: 100 * time.Millisecond,
|
||||
}
|
||||
conn, err = dialer.Dial("tcp", address)
|
||||
} else {
|
||||
conn, err = net.DialTimeout("tcp", address, 100*time.Millisecond)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
// Для TCP без ожидания соединения игнорируем ошибки подключения
|
||||
return nil
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
_, err = conn.Write([]byte{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("не удалось отправить TCP пакет: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// showEasterEgg показывает забавный ASCII-арт
|
||||
func (pk *PortKnocker) showEasterEgg() {
|
||||
fmt.Println("\n🎯 🎯 🎯 EASTER EGG ACTIVATED! 🎯 🎯 🎯")
|
||||
fmt.Println()
|
||||
|
||||
// Анимированный ASCII-арт
|
||||
frames := []string{
|
||||
`
|
||||
╭─────────────────╮
|
||||
│ 🚀 PORT │
|
||||
│ KNOCKER │
|
||||
│ 🎯 1.0.1 │
|
||||
│ │
|
||||
│ 🎮 GAME ON! │
|
||||
╰─────────────────╯
|
||||
`,
|
||||
`
|
||||
╭─────────────────╮
|
||||
│ 🚀 PORT │
|
||||
│ KNOCKER │
|
||||
│ 🎯 1.0.1 │
|
||||
│ │
|
||||
│ 🎯 BULLSEYE! │
|
||||
╰─────────────────╯
|
||||
`,
|
||||
`
|
||||
╭─────────────────╮
|
||||
│ 🚀 PORT │
|
||||
│ KNOCKER │
|
||||
│ 🎯 1.0.1 │
|
||||
│ │
|
||||
│ 🎪 MAGIC! │
|
||||
╰─────────────────╯
|
||||
`,
|
||||
}
|
||||
|
||||
for i := 0; i < 3; i++ {
|
||||
fmt.Print("\033[2J\033[H") // Очистка экрана
|
||||
fmt.Println(frames[i%len(frames)])
|
||||
time.Sleep(1500 * time.Millisecond)
|
||||
}
|
||||
|
||||
fmt.Println("\n🎉 Поздравляем! Вы нашли пасхалку!")
|
||||
fmt.Println("🎯 Попробуйте: ./port-knocker -t \"tcp:8.8.8.8:8888\"")
|
||||
fmt.Println("🚀 Port Knocker - теперь с пасхалками!")
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
func (pk *PortKnocker) showRandomJoke() {
|
||||
joke := GetRandomJoke()
|
||||
|
||||
// ANSI цветовые коды
|
||||
const (
|
||||
colorReset = "\033[0m"
|
||||
colorRed = "\033[31m"
|
||||
colorGreen = "\033[32m"
|
||||
colorYellow = "\033[33m"
|
||||
colorBlue = "\033[34m"
|
||||
colorPurple = "\033[35m"
|
||||
colorCyan = "\033[36m"
|
||||
colorWhite = "\033[37m"
|
||||
colorBold = "\033[1m"
|
||||
)
|
||||
|
||||
// Функция для подсчета видимой длины строки (без ANSI кодов) в рунах
|
||||
visibleLength := func(s string) int {
|
||||
// Удаляем ANSI escape последовательности
|
||||
clean := s
|
||||
for strings.Contains(clean, "\033[") {
|
||||
start := strings.Index(clean, "\033[")
|
||||
end := strings.Index(clean[start:], "m")
|
||||
if end == -1 {
|
||||
break
|
||||
}
|
||||
clean = clean[:start] + clean[start+end+1:]
|
||||
}
|
||||
// Возвращаем количество рун, а не байт
|
||||
return len([]rune(clean))
|
||||
}
|
||||
|
||||
// Функция для умного разбиения строки
|
||||
splitLine := func(line string, maxWidth int) []string {
|
||||
runes := []rune(line)
|
||||
if len(runes) <= maxWidth {
|
||||
return []string{line}
|
||||
}
|
||||
|
||||
var result []string
|
||||
remaining := line
|
||||
|
||||
for len([]rune(remaining)) > maxWidth {
|
||||
// Ищем позицию для разрыва в пределах maxWidth
|
||||
breakPos := maxWidth
|
||||
remainingRunes := []rune(remaining)
|
||||
|
||||
for i := maxWidth; i >= 0; i-- {
|
||||
if i < len(remainingRunes) {
|
||||
char := remainingRunes[i]
|
||||
// Разрываем на пробеле, знаке пунктуации или в конце строки
|
||||
if char == ' ' || char == ',' || char == '.' || char == '!' ||
|
||||
char == '?' || char == ':' || char == ';' || char == '-' {
|
||||
breakPos = i + 1
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Если не нашли подходящего места, разрываем по maxWidth
|
||||
if breakPos == maxWidth {
|
||||
breakPos = maxWidth
|
||||
}
|
||||
|
||||
// Создаем строку из рун
|
||||
breakString := string(remainingRunes[:breakPos])
|
||||
result = append(result, strings.TrimSpace(breakString))
|
||||
remaining = strings.TrimSpace(string(remainingRunes[breakPos:]))
|
||||
}
|
||||
|
||||
if len([]rune(remaining)) > 0 {
|
||||
result = append(result, remaining)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// Разбиваем исходную шутку на строки
|
||||
originalLines := strings.Split(joke, "\n")
|
||||
|
||||
// Обрабатываем каждую строку и разбиваем длинные
|
||||
var processedLines []string
|
||||
for _, line := range originalLines {
|
||||
if strings.TrimSpace(line) == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
splitLines := splitLine(line, 80)
|
||||
processedLines = append(processedLines, splitLines...)
|
||||
}
|
||||
|
||||
// Находим максимальную длину строки для рамки (в рунах)
|
||||
maxLength := 0
|
||||
for _, line := range processedLines {
|
||||
lineLength := len([]rune(line))
|
||||
if lineLength > maxLength {
|
||||
maxLength = lineLength
|
||||
}
|
||||
}
|
||||
|
||||
// Убеждаемся, что maxLength не меньше минимальной ширины для заголовков
|
||||
minWidth := 60 // Минимальная ширина для заголовков
|
||||
if maxLength < minWidth {
|
||||
maxLength = minWidth
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
fmt.Printf("%s%s╭%s", colorPurple, colorBold, colorReset)
|
||||
fmt.Printf("%s%s", colorYellow, strings.Repeat("─", maxLength+2))
|
||||
fmt.Printf("%s%s╮%s\n", colorPurple, colorBold, colorReset)
|
||||
|
||||
headerText := " Зацени Анектотец! 🤣 "
|
||||
fmt.Printf("%s%s│%s", colorPurple, colorBold, colorReset)
|
||||
fmt.Printf("%s%s%s%s", colorCyan, colorBold, headerText, colorReset)
|
||||
fmt.Printf("%s%s", colorYellow, strings.Repeat(" ", 1+maxLength-visibleLength(headerText)))
|
||||
fmt.Printf("%s%s│%s\n", colorPurple, colorBold, colorReset)
|
||||
|
||||
fmt.Printf("%s%s├%s", colorPurple, colorBold, colorReset)
|
||||
fmt.Printf("%s%s", colorYellow, strings.Repeat("─", maxLength+2))
|
||||
fmt.Printf("%s%s┤%s\n", colorPurple, colorBold, colorReset)
|
||||
|
||||
// Выводим обработанные строки шутки
|
||||
for _, line := range processedLines {
|
||||
fmt.Printf("%s%s│%s", colorPurple, colorBold, colorReset)
|
||||
fmt.Printf("%s%s%s", colorWhite, line, colorReset)
|
||||
fmt.Printf("%s%s", colorYellow, strings.Repeat(" ", 2+maxLength-len([]rune(line))))
|
||||
fmt.Printf("%s%s│%s\n", colorPurple, colorBold, colorReset)
|
||||
}
|
||||
|
||||
fmt.Printf("%s%s├%s", colorPurple, colorBold, colorReset)
|
||||
fmt.Printf("%s%s", colorYellow, strings.Repeat("─", maxLength+2))
|
||||
fmt.Printf("%s%s┤%s\n", colorPurple, colorBold, colorReset)
|
||||
|
||||
// Вычисляем правильную ширину для нижних строк
|
||||
cmdText := "Попробуйте: ./port-knocker -t \"tcp:1.1.1.1:1111\""
|
||||
titleText := "🚀 Port Knocker - теперь с шутками! 🤣"
|
||||
|
||||
fmt.Printf("%s%s│%s", colorPurple, colorBold, colorReset)
|
||||
fmt.Printf("%s%s%s%s", colorGreen, colorBold, cmdText, colorReset)
|
||||
fmt.Printf("%s%s", colorYellow, strings.Repeat(" ", 2+maxLength-visibleLength(cmdText)))
|
||||
fmt.Printf("%s%s│%s\n", colorPurple, colorBold, colorReset)
|
||||
|
||||
fmt.Printf("%s%s│%s", colorPurple, colorBold, colorReset)
|
||||
fmt.Printf("%s%s%s%s", colorBlue, colorBold, titleText, colorReset)
|
||||
fmt.Printf("%s%s", colorYellow, strings.Repeat(" ", maxLength-visibleLength(titleText)))
|
||||
fmt.Printf("%s%s│%s\n", colorPurple, colorBold, colorReset)
|
||||
|
||||
fmt.Printf("%s%s╰%s", colorPurple, colorBold, colorReset)
|
||||
fmt.Printf("%s%s", colorYellow, strings.Repeat("─", maxLength+2))
|
||||
fmt.Printf("%s%s╯%s\n", colorPurple, colorBold, colorReset)
|
||||
fmt.Println()
|
||||
}
|
Reference in New Issue
Block a user