Пара слов про CМС

Discussion in 'Десятый конкурс статей' started by BblTPE3BUTEJlb, Dec 10, 2018.

Tags:
  1. BblTPE3BUTEJlb

    BblTPE3BUTEJlb Client

    Joined:
    Sep 4, 2014
    Messages:
    75
    Likes Received:
    127
    Вводное слово.

    Небольшой дисклаймер:
    Только в познавательных целях. Повторение действий, изложенных ниже, запросто может квалифицироваться как мошенничество. А еще есть интересная статья за создание вредоносных программ. Так что все действия – только на ваш страх и риск. Хотя у нас пока сажают только реальных инет-террористов за лайки под постами Навального. Но все может измениться.

    Короче я вас предупредил, дальше думайте сами. Кто там искал рецепт поднятия бабла здесь и сейчас? Ну лови, пока лавочка открыта 8-)

    Исходный расклад

    Все начиналось дождливым мартовским утром 18-го года. В активе был относительно быстрый Интернет, про версия зенопостера, еще полгода капмонстра на 5 потоков. Но все это простаивало без дела. Так же был уже видавший виды фикус 8350 с 16 гб на борту, и собранный из говна и палок старого железа другой выкидышь от амд – fx-4300. В пассиве – безденежье на фоне общей разрухи в стране, свежая гарантия продолжения онной еще 6 лет, и уведомление о сокращении с работы в качестве бонуса. А еще мне сильно были нужны деньги.

    Состояние мое на фоне этих событий было не то что нервным, скорее была апатия и безразличие. Но я искал идею. Времени теперь было много, я читал и думал, думал и читал… На форуме уже мелькали статьи о СМС трафике, в частности вдумчиво мной была переварена приглянувшаяся статья «200к рублей на бесплатном СМС-трафике». Нет, аналогичных дыр я не нашел. Просто в тот день после ознакомления с оной я пошел проверять, что представлено на российском рынке в этом сегменте. МТС и Мегафон отпали сразу, ибо требовали в обязательном порядке номер телефона. Форма отправки тогда еще присутствовала у теле2 для всех желающих (на настоящий момент уже убрана), но всю малину портила рекапча 2, затраты на ее пробив явно не соответствовали выхлопу.

    А вот компания «Билайн» по сей день позволяет отправить СМС своему абоненту со своего сайта. Правда, капча там зубодробительная. Самодельная. Но все же не рекапча. Но обо всем по порядку.

    Шаг 1. Анализируем форму отправки.

    Далеко ходить не надо. https://moskva.beeline.ru/customers/products/mobile/services/details/otpravka-sms/
    form.jpg
    Что имеем? Форма как форма, ничего особо сложного. Натравить Зенопостер не проблема, если пока не трогать капчу. Вспомнив пяток своих друзей абонентов Билайн, я забил руками каждому сообщение в стиле «Вася ты охренел? Ну-ка быстро перезвони Анонимусу!». К концу набора пятого сообщения первый Вася уже звонил мне на трубу. Потом второй. Третьему, четвертому и пятому звонил уже я с вопросом, какого хрена не звонишь, я же СМС заслал? А не было, оказывается, СМС. Но форма радостно отрапортовала об успешных пяти отправленных. Посему было сделано предположение о 2-х СМС с одного IP, благо что он у меня выделенный и белый-прибелый. Через пару часов я повторил операцию с обратного конца. Теперь вопрос «Ну чего тебе, твою налево, надо-то?» задал уже пятый и четвертый Василий. Посему выходило 2 СМС с одного IP в час. Ок, фиксируем инфу.

    А далее задался я вопросом, а как сами операторы борются с рассылками? И нагуглил статью уже лохматого года, но именно про Билайн, где они с умным видом описывали базовые основы борьбы с «плохими» сообщениями, напоминавшие почтовый антиспам, но с поправкой на короткие сообщения. Впрочем, представители Билайна гордо заявляли о победе над 95% СМС спам рассылок. Ок, я почти поверил. Сейчас я сходу эту статью нагуглить не могу (все в ваших руках), но выводы я сделал следующие: наверняка фильтруется контактная информация в теле сообщения – телефоны, урлы, возможно коммерческие стоп слова, то очень похоже, это признак для антиспама. Скорее всего играет роль и трастовость IP (и косвенные подтверждения я сему факту потом получил). Ладно, урлы зауникалить мы как-нить сумеем, но вот ведь проблемка… Значит, чистую коммерцию, как и гемблинг, всякие форексы, крипту, знакомства, адалт – все это продвигать, скорее всего, крайне геморойно. Наверняка сообщение порежут стоп слова. Плюс ко всему это у меня IP белее некуда, а где взять пачку таких за разумные деньги, да что бы более менее трастовые?

    Тупик?

    Нет! В этот момент у меня сформировалась схема слива в голове. Но сначала надо было решить проблему номер 2, ибо если капча не пробьется, все идет лесом.

    Шаг 2. Пробиваем капчу.

    captcha.jpg

    Найти решение было реально сложно. Посудите сами, как пробить эти капчи, если примерно в 20% случаях эту картинку не может однозначно распознать живой человек?! Поэтому первые шаги были немного предсказуемы.

    Заход в лоб универсальным модулем капмостра привел к фиаско. Примерно 2% успешно распознанных капч, что смело можно считать погрешностью. Это был определенно не наш путь. Ладно, пришлось заняться глубоким обучением.

    Успешно загуглив уроки Ростоникса собственно по обучению капмостра, потратив эдак дня два, выкрутив все настройки на максимум я добился… 6% распознавания. Мда, не густо. Второй заход с увеличением выборки, откидыванием заведомо непробиваемых капч подняли процент до 12, но в реальной жизни при полевых испытаниях он дай бог был в районе 7. Кроме того, неверный ввод на сайте порождал следущую, еще более ужасную комбинацию, что приводило к зацикливанию. Сайт, вероятно, защищался таким образом. Но это я понял не сразу.

    Сразу я попытался обойти препятствие с боку, но попытка влезть в код страницы, дав иные параметры размера капчи, тем самым получив бОльшую картинку, гораздо более легкую для распознавания, всегда приводила к ошибке отправки, даже при заведомо верном решении. Я не знаю как называется эта защита, когда как-то сверяется код отправленый сервером, и код с которого пришел запрос, но это явно было оно. Какой-то яваскрипт за этим следил. Но если вы посмотрите на коды яваскриптов той страницы, идею отловить его думаю оставит каждый. Соответственно страницу было трогать нельзя.

    Честно говоря, я думал это все, конец. Проект был отложен, я пошел читать другие конкурсные работы в надежде сформировать другую свою идею. Но ничего не приходило. Дней через пять я посетил друга, с которым мы прилично эдак наклюкались коньячка. В пьяном уже угаре, не помню зачем, когда он отлучался припудрить носик, я повернулся к его компу, благо какой-то древний калькулятор у него в режиме 24/7 стоит на кухне. Видимо на фоне впечатлений последних дней набрал по памяти урл формы, с которой ковырялся последние дней 10, и уставился на нее. Но по возвращении мой приятель увидел ее, тут же предложил отписать какой-то Маше СМСку, и, не дожидаясь моего согласия, отодвинул меня. Я опущу то, что пьяный дурак может написать молодой (я надеюсь) девушке, интересным моментом было совсем другое. Быстро накидав телефон и пахабный текст, он уткнулся в знакомую мне капчу, выплюнувшей заведомо труднопробиваемый вариант, да помноженный на опъянение... С фразой «Ну что за на… он мне тут сует, б…», он начал тыкать «обновить». Ровно до тех пор, пока на 7-8 попытке вылезла вполне читаемая картинка. Сие событие было отмечено фразой «О, норм! Эта сойдет».

    Тут призадумался уже я. «Нормальную» капчу мой модуль взял бы без проблем. Последовательность действий стала понятна. Долбиться лбом в стену что бы изредка ее пробивать не следовало. Надо стать пользователем. И повторить его логику действий. Не надо даже пытаться пробивать непробиваемое. Эксперимента ради я раздал вай фай со своего телефона, дабы сменить IP, и ткнулся в эту форму с другого браузера. Ну да. Оно так и работало. Примерно одна из 10 капч была пробиваемой.

    И пусть каждый, кто скажет теперь, что пьянство зло, убьет себя ап стену. Впрочем, правда и то, что это только пьяному море по колено. На утро с головной болью я с трудом соображал, что мне с этой информацией делать. Как понять, что капчу не стоит пытаться разгадывать, а проще попросить другую?

    И мной был придуман алгоритм.

    Берем картинку. Средствами зенопостера фоткаем ее и отправляем на анализ. Далее:

    а) разбиваем картинку на 5 прямоугольников, с наложением на соседние области. Последний прямоугольник получался слегка поменьше, но сие мешало не сильно;
    sqwear.jpg
    Сорри, с рисованием у меня с детства беда, очень приблизительно показано, но надеюсь идея понятна.

    б) анализируем цвет каждого пикселя. Приводим оттенки цветов к основным. Я это делал просто путем сравнения с эталонными значениями, выуженными из фотошопа. В результате все оттенки синего считались просто синим, красного – красным, и т.п.

    в) затем простой суммой цветов пикселей определялся преобладающий цвет в квадрате. И заодно второй по популярности.

    г) далее фильтры. Если основной цвет соседних квадратов был идентичным, капча забраковывалась. Наложения одноцветных соседних цифр друг на друга проводили к диким комбинациям, пагубно влияющими на распознавание. Также забраковывались капчи с примерно равным соотношением двух основных цветов в квадрате (в пределах 10%) – так как выделить цвет основной цифры за помехами становилось затруднительно;

    г*) голос из декабря 18-го: в принципе надо было еще добавить отношение белого цвета к черному после обработки в квадрате, что бы откинуть мелкие символы, приводившие впоследствии к ошибкам распознавания. Т.е. за основной цвет принимались помехи. Но сие так и не было реализовано, оставшись на уровне идеи, и на производительность повлияло не сильно;

    д) Не прошедшие фильтр капчи забраковывались. В проекте инициировалось обновление капчи, и далее по циклу с пункта а. Если же фильтры успешно проходились, из основных цветов квадратов собиралась новая картинка, уже без наложения, а просто в стык. Ну и наиболее популярный цвет менялся на черный, все остальные цвета игнорировались и заполнялись белым. Получались отличные капчи, на которые капмостру даже не пришлось накладывать дополнительные фильтры, ибо 90% помех другого цвета тупо обрезалось.

    Для примера, что выплевывает скрипт на таком алгоритме:

    1.jpg

    Тоже не самая простая капча, но уже вполне пробиваемая.

    А далее уже по проторенной дорожке – обучение капмонстра на этих капчах, часа 4 ожидания, и вауля! Очень достойный процент пробива. Ну как по мне. Впрочем, мой алгоритм дает и осечки:
    2.jpg
    Понятно, что такая капча не пробиваема. Примерно 5% таких. Хотите уменьшить процент брака – крутите отношения основных цветов. Но отсеете и много пробиваемых. Так что просто примите это. Или придумывайте сами чего-нить.

    Модуль давал за 60% распознавания. По-моему, 68%, если точно.

    О плохом. Я х.з. куда дел этот модуть. За последние полгода у меня случилась эпидемия на харды. Они дохли один за другим. Если найду на еще одном компе, который сча далековато (но обучал я именно на нем, так что надежда есть), то потом выложу. Кто хочет снять сливки первым – все в ваших руках. Я тоже не умел. Но смог же!

    Изначально я хотел написать анализ каптч в лоб на шарпе в зенопостере. И даже честно попробовал накатать скрипт. Но… Шарп совсем не мое. Особенно для задач, без проблем решаемых на коленке на знакомом инструменте. Обработчик жаловался на какую-то ошибку, я пытался понять что она вообще значит…

    Затем я стал искать библиотеки яваскриптов для работы с графикой. С этим языком я знаком гораздо лучше, но… Не предназначен он для этого. Что-то отдаленное вроде попадалось для Node.js, однако как оно поведет себе в среде зенопостера…

    Еще была идейка накатать утилиту на питоне, и просто вызывать ее из проекта с параметрами. Но мы пошли другим путем.

    В итоге, поскольку капмонстр у меня стоял на FX-4300 для разгрузки основного, и для его 5 потоков этого компа хватало за глаза, на него же впоследствии была подселена БД и поставлен Денвер. Кто будет сие делать руками, не забудьте развести капмостр и вебсервер по разным портам. Проапгрейденный до последней 5-й (5.9 вроде) версии PHP и утыканый дополнительными модулями меня вполне устроил в качестве средства реализации задуманного. Скриншот капчи POST запросом кидался на скрипт-обработчик. А в ответ приходил ответ или « Bad captcha», что означало ткнуть кнопку перезагрузки капчи и взять новую для анализа, или урл на обработанную хорошую. Соответственно хорошая капча отправлялась уже капмостру. Листинг этого PHP скрипт (вернее, одну из ранних версий) смотрите ниже. Быдлокодинг на PHP во всей красе:D Но подобраные цвета из кода можно выудить без проблем для реализации на более удобном вам языке.
    Code (text):
    1.  
    2. <?
    3.    if (! isset($_GET["file_name"]) )
    4.    {
    5.       echo '404';
    6.       die;
    7.    }
    8.    else
    9.    {
    10.       $file_name = $_GET["file_name"];
    11.       $url = './img/'.$file_name;
    12.    }
    13.    $bad_captcha = false;
    14.    if ($_GET["gif"] == true) {
    15.    imagepng(
    16.     imagecreatefromstring(
    17.         file_get_contents($url)
    18.     ),
    19.     "$url"
    20.     );
    21.    }
    22.    $captcha = ImageCreateFromPng($url);
    23.    $shirina = ImageSX ($captcha);
    24.    $visota = ImageSY($captcha);
    25.  
    26.    $sq1[blue] = 0;        $sq1[green] = 0;        $sq1[black] = 0;        $sq1[red] = 0;        $sq1[yellow] = 0;         $sq1[grey] = 0;
    27.    $sq2[blue] = 0;        $sq2[green] = 0;        $sq2[black] = 0;        $sq2[red] = 0;        $sq2[yellow] = 0;         $sq2[grey] = 0;
    28.    $sq3[blue] = 0;        $sq3[green] = 0;        $sq3[black] = 0;        $sq3[red] = 0;        $sq3[yellow] = 0;         $sq3[grey] = 0;
    29.    $sq4[blue] = 0;        $sq4[green] = 0;        $sq4[black] = 0;        $sq4[red] = 0;        $sq4[yellow] = 0;         $sq4[grey] = 0;
    30.    $sq5[blue] = 0;        $sq5[green] = 0;        $sq5[black] = 0;        $sq5[red] = 0;        $sq5[yellow] = 0;         $sq5[grey] = 0;  
    31.  
    32.     //123
    33.     //39
    34.     for ($y =0 ; $y <$visota; $y++){
    35.  
    36.         for ($x = 0 ; $x <$shirina ; $x++){
    37.         $rgb = imagecolorat ($captcha, $x, $y);
    38.         $color_tran = imagecolorsforindex($captcha, $rgb);
    39.  
    40. //     5-40
    41. //     25-60
    42. //     55-90
    43. //     85-110
    44. //     105-123
    45.  
    46.  
    47.         $pixels[$y][$x][red] = $color_tran[red];
    48.         $pixels[$y][$x][green] = $color_tran[green];
    49.         $pixels[$y][$x][blue] = $color_tran[blue];
    50.  
    51.         if ($x < 40 and $x > 5) {
    52.             $color =  GetPixelColor ($pixels[$y][$x][red], $pixels[$y][$x][green], $pixels[$y][$x][blue]);
    53.             switch ($color) {
    54.             case "blue":
    55.             $sq1[blue]++;
    56.             break;
    57.             case "green":
    58.             $sq1[green]++;
    59.             break;
    60.             case "black":
    61.             $sq1[black]++;
    62.             break;
    63.             case "red":
    64.             $sq1[red]++;
    65.             break;
    66.             case "yellow":
    67.             $sq1[yellow]++;
    68.             break;
    69.             case "grey":
    70.             $sq1[grey]++;
    71.             break;
    72.             }
    73.         }
    74.         if ($x < 60 and $x > 25) {
    75.             $color =  GetPixelColor ($pixels[$y][$x][red], $pixels[$y][$x][green], $pixels[$y][$x][blue]);
    76.             switch ($color) {
    77.             case "blue":
    78.             $sq2[blue]++;
    79.             break;
    80.             case "green":
    81.             $sq2[green]++;
    82.             break;
    83.             case "black":
    84.             $sq2[black]++;
    85.             break;
    86.             case "red":
    87.             $sq2[red]++;
    88.             break;
    89.             case "yellow":
    90.             $sq2[yellow]++;
    91.             break;
    92.             case "grey":
    93.             $sq2[grey]++;
    94.             break;
    95.             }
    96.         }
    97.         if ($x > 55 and $x < 90) {
    98.             $color =  GetPixelColor ($pixels[$y][$x][red], $pixels[$y][$x][green], $pixels[$y][$x][blue]);
    99.             switch ($color) {
    100.             case "blue":
    101.             $sq3[blue]++;
    102.             break;
    103.             case "green":
    104.             $sq3[green]++;
    105.             break;
    106.             case "black":
    107.             $sq3[black]++;
    108.             break;
    109.             case "red":
    110.             $sq3[red]++;
    111.             break;
    112.             case "yellow":
    113.             $sq3[yellow]++;
    114.             break;
    115.             case "grey":
    116.             $sq3[grey]++;
    117.             break;
    118.             }
    119.         }
    120.         if ($x > 85 and $x < 100) {
    121.             $color =  GetPixelColor ($pixels[$y][$x][red], $pixels[$y][$x][green], $pixels[$y][$x][blue]);
    122.             switch ($color) {
    123.             case "blue":
    124.             $sq4[blue]++;
    125.             break;
    126.             case "green":
    127.             $sq4[green]++;
    128.             break;
    129.             case "black":
    130.             $sq4[black]++;
    131.             break;
    132.             case "red":
    133.             $sq4[red]++;
    134.             break;
    135.             case "yellow":
    136.             $sq4[yellow]++;
    137.             break;
    138.             case "grey":
    139.             $sq4[grey]++;
    140.             break;
    141.             }
    142.         }
    143.         if ($x > 105) {
    144.             $color =  GetPixelColor ($pixels[$y][$x][red], $pixels[$y][$x][green], $pixels[$y][$x][blue]);
    145.             switch ($color) {
    146.             case "blue":
    147.             $sq5[blue]++;
    148.             break;
    149.             case "green":
    150.             $sq5[green]++;
    151.             break;
    152.             case "black":
    153.             $sq5[black]++;
    154.             break;
    155.             case "red":
    156.             $sq5[red]++;
    157.             break;
    158.             case "yellow":
    159.             $sq5[yellow]++;
    160.             break;
    161.             case "grey":
    162.             $sq5[grey]++;
    163.             break;
    164.             }
    165.         }      
    166.         }
    167.     }
    168.     imagedestroy($captcha);
    169.  
    170.     arsort($sq1);    arsort($sq2);   arsort($sq3);   arsort($sq4);   arsort($sq5);
    171.  
    172.     $color1 = array_search(current($sq1), $sq1);
    173.     $color2 = array_search(current($sq2), $sq2);
    174.     $color3 = array_search(current($sq3), $sq3);
    175.     $color4 = array_search(current($sq4), $sq4);
    176.     $color5 = array_search(current($sq5), $sq5);
    177.     if ($color1 == $color2 or $color2 == $color3 or $color3 == $color4 or $color4 == $color5) {
    178.         $bad_captcha = true;
    179. //        echo 'ЏовторЯющиесЯ цвета, капча плохаЯ<br>';
    180.     }
    181.     if (current($sq1) < 100 or current($sq2) < 100     or current($sq3) < 100 or current($sq4) < 100 or current($sq1) < 80) {
    182.         $bad_captcha = true;
    183. //        echo 'Ћчень мало основного цвета одной из букв, капча плохаЯ<br>';
    184.     }
    185.     if (current($sq1) < next($sq1)*1.1 or current($sq2) < next($sq2)*1.1 or current($sq3) < next($sq3)*1.1 or current($sq4) < next($sq4)*1.1 or current($sq5) < next($sq5)*1.1) {
    186.         $bad_captcha = true;
    187. //        echo 'Ћчень много шума второго цвета одной из букв, капча плохаЯ<br>';
    188.     }
    189.     unlink($url);
    190.     if ($bad_captcha == true) {
    191.       echo 'Bad captcha';
    192.       die;
    193.     }
    194.  
    195.  
    196.     // создание обработанной капчи под распознование
    197.     //     5-40    0-35
    198.     //     20-65   35 - 80
    199.     //     50-95   80 - 125
    200.     //     75-115  125 - 165
    201.     //     95-123  165 - 188
    202.     $im = imagecreatetruecolor(193, 39);
    203.     //установка основных цветов:
    204.     $white = imageColorAllocate($im, 255, 255, 255);
    205. //    $blue = imageColorAllocate($im, 0, 0, 255);
    206. //    $red = imageColorAllocate($im, 255, 0, 0);
    207. //    $green = imageColorAllocate($im, 0, 255, 0);
    208. //    $yellow = imageColorAllocate($im, 255, 255, 0);
    209. //    $grey = imageColorAllocate($im, 190, 190, 190);
    210.     $black = imageColorAllocate($im, 0, 0, 0);
    211.  
    212.  
    213.  
    214.         for ($y =0 ; $y <39; $y++){
    215.             $xnew = 0;
    216.             for ($x = 5 ; $x <40 ; $x++){
    217.                 $color =  GetPixelColor ($pixels[$y][$x][red], $pixels[$y][$x][green], $pixels[$y][$x][blue]);
    218.                 if ($color == $color1){
    219.                     imagesetpixel($im, $xnew, $y, $black);
    220.                 }
    221.                 else{
    222.                     imagesetpixel($im, $xnew, $y, $white);
    223.                 }
    224.                 $xnew++;
    225.             }
    226.         }
    227.  
    228.         for ($y =0 ; $y <39; $y++){
    229.             $xnew = 35;
    230.             for ($x = 20 ; $x <65 ; $x++){
    231.                 $color =  GetPixelColor ($pixels[$y][$x][red], $pixels[$y][$x][green], $pixels[$y][$x][blue]);
    232.                 if ($color == $color2){
    233.                     imagesetpixel($im, $xnew, $y, $black);
    234.                 }
    235.                 else{
    236.                     imagesetpixel($im, $xnew, $y, $white);
    237.                 }
    238.                 $xnew++;
    239.             }
    240.         }
    241.  
    242.         for ($y =0 ; $y <39; $y++){
    243.             $xnew = 80;
    244.             for ($x = 50 ; $x <95 ; $x++){
    245.                 $color =  GetPixelColor ($pixels[$y][$x][red], $pixels[$y][$x][green], $pixels[$y][$x][blue]);
    246.                 if ($color == $color3){
    247.                     imagesetpixel($im, $xnew, $y, $black);
    248.                 }
    249.                 else{
    250.                     imagesetpixel($im, $xnew, $y, $white);
    251.                 }
    252.                 $xnew++;
    253.             }
    254.         }  
    255.  
    256.         for ($y =0 ; $y <39; $y++){
    257.             $xnew = 125;
    258.             for ($x = 75 ; $x <115 ; $x++){
    259.                 $color =  GetPixelColor ($pixels[$y][$x][red], $pixels[$y][$x][green], $pixels[$y][$x][blue]);
    260.                 if ($color == $color4){
    261.                     imagesetpixel($im, $xnew, $y, $black);
    262.                 }
    263.                 else{
    264.                     imagesetpixel($im, $xnew, $y, $white);
    265.                 }
    266.                 $xnew++;
    267.             }
    268.         }
    269.  
    270.         for ($y =0 ; $y <39; $y++){
    271.             $xnew = 165;
    272.             for ($x = 95 ; $x <123 ; $x++){
    273.                 $color =  GetPixelColor ($pixels[$y][$x][red], $pixels[$y][$x][green], $pixels[$y][$x][blue]);
    274.                 if ($color == $color5){
    275.                     imagesetpixel($im, $xnew, $y, $black);
    276.                 }
    277.                 else{
    278.                     imagesetpixel($im, $xnew, $y, $white);
    279.                 }
    280.                 $xnew++;
    281.             }
    282.         }  
    283.      imagepng ($im, $url);
    284.      echo 'Ok!';
    285.  
    286.  
    287.  
    288.     function GetPixelColor ($r, $g, $b) {
    289.                     $pixel = 'white';
    290.             if ($r == 51 and $g == 43 and $b == 102 or
    291.                 $r == 51 and $g == 0 and $b == 102 or
    292.                 $r == 51 and $g == 0 and $b == 153 or          
    293.                 $r == 0 and $g == 0 and $b == 102 or          
    294.                 $r == 0 and $g == 43 and $b == 102 or
    295.                 $r == 0 and $g == 43 and $b == 153 or
    296.                 $r == 0 and $g == 0 and $b == 153 or          
    297.                 $r == 51 and $g == 43 and $b == 153 or
    298.                 $r == 51 and $g == 85 and $b == 153 or          
    299.                 $r == 51 and $g == 43 and $b == 102 or
    300.                 $r == 102 and $g == 85 and $b == 153) {
    301.                 $pixel = 'blue';
    302.             }
    303.             if ($r == 102 and $g == 0 and $b == 153 or
    304.                 $r == 153 and $g == 0 and $b == 153 or
    305.                 $r == 153 and $g == 0 and $b == 102 or
    306.                 $r == 153 and $g == 43 and $b == 102 or
    307.                 $r == 153 and $g == 43 and $b == 153 or
    308.                 $r == 102 and $g == 43 and $b == 102 or          
    309.                 $r == 153 and $g == 85 and $b == 153 or
    310.                 $r == 204 and $g == 85 and $b == 153 or
    311.                 $r == 204 and $g == 85 and $b == 204 or
    312.                 $r == 204 and $g == 128 and $b == 204 or
    313.                 $r == 102 and $g == 0 and $b == 102) {
    314.                 $pixel = 'red';
    315.             }
    316.             if ($r == 51 and $g == 128 and $b == 153 or
    317.                 $r == 51 and $g == 128 and $b == 102 or
    318.                 $r == 51 and $g == 170 and $b == 153 or
    319.                 $r == 51 and $g == 170 and $b == 102 or          
    320.                 $r == 102 and $g == 170 and $b == 153 or
    321.                 $r == 102 and $g == 170 and $b == 204) {
    322.                 $pixel = 'green';
    323.             }
    324.             if ($r == 153 and $g == 128 and $b == 0 or
    325.                 $r == 102 and $g == 128 and $b == 0 or
    326.                 $r == 102 and $g == 128 and $b == 51 or
    327.                 $r == 102 and $g == 170 and $b == 0 or          
    328.                 $r == 153 and $g == 128 and $b == 51 or      
    329.                 $r == 153 and $g == 170 and $b == 0 or
    330.                 $r == 153 and $g == 170 and $b == 51 or
    331.                 $r == 204 and $g == 170 and $b == 102 or
    332.                 $r == 153 and $g == 170 and $b == 102) {
    333.                 $pixel = 'yellow';
    334.             }      
    335.             if ($r == 153 and $g == 128 and $b == 153 or
    336.                 $r == 153 and $g == 128 and $b == 102 or
    337.                 $r == 102 and $g == 128 and $b == 102 or
    338.                 $r == 102 and $g == 170 and $b == 102 or          
    339.                 $r == 153 and $g == 170 and $b == 153 or
    340.                 $r == 204 and $g == 170 and $b == 153 or              
    341.                 $r == 102 and $g == 128 and $b == 153) {
    342.                 $pixel = 'grey';
    343.             }      
    344.             if ($r == 0 and $g == 43 and $b == 0 or
    345.                 $r == 0 and $g == 85 and $b == 0 or      
    346.                 $r == 51 and $g == 43 and $b == 51 or
    347.                 $r == 0 and $g == 43 and $b == 51 or
    348.                 $r == 51 and $g == 85 and $b == 51 or
    349.                 $r == 51 and $g == 85 and $b == 0 or              
    350.                 $r == 102 and $g == 85 and $b == 102 or          
    351.                 $r == 51 and $g == 43 and $b == 0) {
    352.                 $pixel = 'black';
    353.             }
    354.     return $pixel;
    355.     }
    356.  
    Шаг 3. Абоненты билайна.

    Сразу скажу, тестовые прогоны по генеренке из квоты номеров показали впоследствии отвратительные результаты. Поэтому было принято стандартное решение – парсинг Авито. Но не своими силами, ибо я допиливал свою часть, и если решение уже есть, зачем искать лишние приключения на свой зад? Мой выбор пал на Mikhail B., и я не ошибся. Очень отзывчивый человек, рекомендую. Однако мне не нужен был весь функционал его шаблона, я просто парсил связку имя-телефон. В принципе, для работы небольшими партиями (ночью спарсил – днем разослал, и так по кругу), достаточно хранить эти данные в обычных тхт файлах. Но у меня получился готовый парсер на руках (который уже собирал данные) и еще не доведенная до ума идея. Я пошел через базу данных, в результате к денверу и капмонстру подъехала еще и Mongo. Неожиданно да? На самом деле все просто, с реляционками я работал последний раз лет 5 назад. В зенопостере нет встроеного инструмента для общения с такой базой (не утверждаю, я просто пошел своим путем), поэтому на том же PHP были написаны три скрипта.

    Средствами зенопостера бралась связка имя-телефон, отправлялся запрос на API мегафона (вот вам урл http://moscow.megafon.ru/api/mfn/info?msisdn=9037560000 для примера, очень мило с их стороны, не правда ли? Но фильтрует по таймигу запросы с 1 IP. А у нас как раз дохрена разных проксей пакетных! У Билайна тоже есть такой сервис, за капчей, угадайте какой), а дальше название оператора, номер, имя абонента и регион уходили гет запросом на первый php скрипт, создававший в базе соответствующий документ.

    Второй скрипт отдавал рандомного абанента (номер-имя-регион) по оператору и ставил метку, что этот абонент обработан.

    И третий скрипт эту метку снимал, если из зенопостера приходил соответствующий запрос по ветке Bad End.

    Они все элементарные, заточенные на PHP API Монго, полагаю нормальным людям не к чему :D

    Расписывать про эту часть что-то большее я думаю смысла нет. Новичкам будет проще без БД, продвинутым на том же денвере реляционки бы хватило по уши. Вместе с шарпом и без промежуточных костылей. А я – не формат :bt:



    Шаг 4: Прокси и заполнение форм

    Прокси это проблема. Пробовал несколько сервисов за все время. Ибо, например, бункером ползуется половина этого форума в складчину, они быстрые, но, откровенно говоря, засранные, меня не устроили, так что я запросил кеш бек. Вообще популярное, дешёвое и общедоступное не рекомендую. Я так и не нашел оптимальный вариант, хоть и остановился на предложении Proxy.am. 3000 ip, 300 потоков (не реклама. Ибо суппорт странный, а реально из пакета нормальных проксей где-то половина. На мой вопрос, а собсно почему это так мне предложили перейти на тариф выше. За свой счет ессно). Впрочем, на 30 браузерных потоков зенопостра на FX-8350 этого хватало. Но тоже, откровенно говоря, заюзанные прокси. Отдельным шаблоном отлавливались свежие, постоянно обновлялись. Так получалось более менее.

    3аполнить форму средствами зенопостра сможет любой человек с более-менее прямыми руками. Я добавил в проект счетчик на количество обновлений капч и выход при превышении. У меня он стоял на 30, и в итоге иногда шаблон выплевывал «капча не пробита», т.е. не подобралась нормальная с 30 попыток, которую можно кинуть капмонстру. Это косвенно говорит о качестве проксика. И если этого не сделать, как уже говорил, получите зацикливание.

    Что еще добавлю. Когда я писал этот шаблон, я использовал всю инфу, что написано в статье про анонимность с одного из предыдущих конкурсов. В шаблоне она есть. В новых версиях достаточно просто поставить галочки, и выкинуть всю ветку. Проверено. Работает.


    Шаг 5. А что слать?

    На самом деле на этом этапе была загублена не одна хорошая идея. Но не мной :ah:

    Логично предположить, что рассылая СМС, вы получите потенциального пользователя с телефоном в руке. Вап клик напрашивался. А тут внезапно оказалось, что у нас есть партнерка, позиционирующая себя как эксклюзивного партнера Билайна. Более того, там оказался очень дружелюбный сапорт, и от моего трафа нос воротить не стали (в отличие от
    wap.click, фу такими быть!). Правда я изначально им сказал, что это спам соцсетей через прокладку (реально были и такие опыты, впоследствии успешно похороненые). Но вопросов не было. Наоборот мне периодически потом их менеджер писал «Давай еще! Больше!». Но все это было потом.

    А на момент старта надо было организовать слив. Не стандартно, иначе получим такую же хреновую конверсию, как у автора статьи про 200к (сорри бро, но это так. Не довел ты идею до ума, но с другой стороны, зачем тебе нужен Лексус?).

    Итак, у нас есть имя и регион. Мной была создана страничка, прикидывавшаяся страницей сайта, на ней было написано что-то типа «Ржачный видос, абассака. В кадре редкий долбоящер!». Далее стояла картинка, являющаяся ссылкой слива:
    forbiden.jpg
    Ну а под ней, типа в коментах, было написано следущее (напоминаю, мы знаем имя-регион):

    - А знаю кто это! Это Вася!

    - Откуда такой взялся?

    - из Зажопинска!

    - Долб..б это Вася!

    Вы бы кликнули? Создавайте талантливые прокладки. Пользователи очень любят личное упоминание. В принципе, все эти данные можно и с Авито снимать. С точностью до города.

    На всякий случай поясню.

    Code (text):
    1.  
    2. // http://site.ru/page.php?region={-Variable.region-}&name={-Variable.name-} - это ссылка
    3. // страница page.php должна содержать примерно такой код:
    4.  
    5.   if  (!isset($_GET["region"]))  {
    6.   $region = 'Россия';
    7.   }
    8.   else
    9.   {
    10.   $region = trim($_GET["region"]);
    11.   }
    12.   if  (!isset($_GET["name"] ))
    13.   {
    14.   $name = '<i>Имя удалено админом</i>';
    15.   }
    16.   else
    17.   {
    18.   $name = trim($_GET["name"]);
    19.   }
    20.  


    После этого в любое место можно поставить <? echo $name ?> и <echo $region>. И на странице будет написано то, что вы туда передали извне. А извне сие приходило через сокращалки. Такой простой метод позволяет персонализировать инфу.

    Ну и сливать трафик ессно на видео платник. Пусть пользователь ищет там себя. А вдруг найдет?


    Шаг 6. Абузы.

    Вопрос важный, потому что они есть. И если партнерке это оказалось похрен, они привыкшие отбиваться, процент абуз оказался допустимым, то вот хостеры… Есть оказывается редиски, которые им пишут. Сначала я сидел на крупном российском хостере. Из плюсов его было то, что он всех с претензиями шлет либо сразу в суд, либо в полицию, либо нахрен. И мало кто сие дело доведет до государственных инстанций. Однако жим-жим дал о себе знать, и я решил переехать в более спокойное место. Рассудив, что на государственном уровне Украина и Россия не сильно любят друг дружку нынче, съехал я на украинский хостинг. И надо же было такому случиться, что мне таки попался какой-то дотошный украинец (вероятно в двухсимочном телефоне, ибо иногда конвертился даже очень далекий бурж). Хостинг попросил объяснений, а пяток доменов, регнутых там же, сняты с делегирования. Ессно объяснять им я ничего не стал, нашел на этом форуме голландский абузоустойчивый хостинг, китайский регистратор доменов, и больше меня никто не беспокоил.

    А денюшка капала. И капает до сих пор. Любителям пофапать на стату скриншот прилагаю. За июнь-июль, когда я вышел на пик:
    stats.jpg
    Ну а потом возможности рассылки перекрыли объемы пополнения абонентов, и все пошло на убыль. А потом умер хард, и востанавливал я более важный проект. А этот – ну наверное востанавливать кому-то из читающих эту статью.

    Вместо заключения.
    Как, было интересно? Хочется повторить? Вперед. Только помните, шаблон из коробки работать не будет, для этого вам нужно повторить мою инфраструктуру. А это не рационально. Моей задачей было максимально разгрузить фикус 8350 – ессно не самый убогий системник (эти ваши четырехядерные i5 дай бог удержат 20 потоков), но далеко и не сервер. Пока в зенопостере не появился мониторинг нагрузки, регулярно наблюдал вылет из учетки.

    Шаблон прилагаемый (кстати, тоже ранняя версия) вам будет полезен просто для анализа и обучения. Есть тонкость – на станице отправки СМС несколько раз изменялась верстка чуток, шаблон приходилось править. Поэтому поля может и не найти сходу. Но это не самая большая проблема. Ну и ветка с теле2 потеряла актуальность.
    А вообще, по тому, что я рассказал в статье – я думаю у вас уже все есть и так для самостоятельного написания. Давать такой инструмент, работающий из коробки, каждому первому - имхо, перебор.

    Когда у меня кончились номера, я просто запустил второй круг по этой же базе. Думал все будет плохо. А нет, 70% от первого прогона конверт. О чем сие говорит? Я думаю о проксях.

    И немного лирики напоследок:

    Я шел от идеи до первых денег 2 месяца, постоянно допиливая и дописывая, спремляя острые углы. У меня получился хороший результат. Я думаю любой здравомыслящий человек, внятно прочитавший эту статью, накидает аналогичный шаблон под свои нужды максимум за недельку. Ну а кому надо все на блюдечке – составляйте ТЗ и ищите исполнителя. А я с этой темой завязал. Карму пора чистить.

    Впрочем, на разумные вопросы я готов ответить.

    Кто бы что ни говорил, а голодуха очень здорово тонизирует соображалку. Я нашел другое направление, более белое и интересное. Его и рою, да все больше на запад. Даже думаю перевезти туда свою тушку, ибо… Ладно, это совсем другая история. Работы официальной так и не нашел кстати, но уже думаю мне пока и не надо.

    Спасибо за ваше внимание, и спасибо команде зенолаба за софт. Делайте его еще лучше!
    Ну и с наступающим всех!
     

    Attached Files:

    • sms.xmlz
      File size:
      231.8 KB
      Views:
      91
    Last edited: Dec 10, 2018
    Atlas, ZSHab, sanjaz and 34 others like this.
  2. Dr.Pipetka

    Dr.Pipetka Client

    Joined:
    Dec 12, 2017
    Messages:
    191
    Likes Received:
    105
    Интересный подход к капче. Статья интересная. Молодец, спасибо.
     
  3. backoff

    backoff Client

    Joined:
    Apr 20, 2015
    Messages:
    2,431
    Likes Received:
    1,943
    Понравилось. Хороший текст с отступлениями.
    Несколько месяцев назад я тоже обратил внимание на данную идею :-) еще себе записал все протестить, потестил, и поставил в задачи )))
    Но другая идея забрала все время, что в итоге просто забил.
     
  4. BblTPE3BUTEJlb

    BblTPE3BUTEJlb Client

    Joined:
    Sep 4, 2014
    Messages:
    75
    Likes Received:
    127
    Аналогично. Потому считай и отдаю всем желающим.
     
  5. Alexmd

    Alexmd Client

    Joined:
    Dec 10, 2018
    Messages:
    3
    Likes Received:
    4
    Это одна из самых мотивирующих статей за все время проведения конкурсов. Спасибо.
     
    Atlas and iBotovod like this.
  6. pars

    pars Пользователь

    Joined:
    Dec 10, 2016
    Messages:
    52
    Likes Received:
    16
    Отличная статья ,и очень интересный подход к "прокладке" - возьму на карандаш !
     
  7. melutsk

    melutsk Client

    Joined:
    Aug 3, 2016
    Messages:
    317
    Likes Received:
    55
    Давно думал про такую штуку. Годнота.
     
  8. yriy158

    yriy158 Client

    Joined:
    Aug 10, 2013
    Messages:
    357
    Likes Received:
    209
    Супер, годно, интересно, креативно)
    Подскажи, на пост/гет переделать шаб под этот сайтец не пробовал для увеличения скорости? Или там хитрые скрпты/защита?
    Я то свой траф бесполезно сливал, согласен)) но под укр траф мало годной монетизации что было, что есть по моему.
     
  9. Сибиряк

    Сибиряк Client

    Joined:
    Jul 12, 2014
    Messages:
    255
    Likes Received:
    61
    Хорошая статья! Спасибо! Удачи и не голодайте [​IMG]
     
  10. Osedjuse

    Osedjuse Client

    Joined:
    Jul 31, 2016
    Messages:
    293
    Likes Received:
    267
    у меня не получилось, несколько параметров генерируются на JS, а тут я уже не особо шарю, как повторить скрипт
     
  11. BblTPE3BUTEJlb

    BblTPE3BUTEJlb Client

    Joined:
    Sep 4, 2014
    Messages:
    75
    Likes Received:
    127
    Вот моя реакция, когда я сунулся в яваскрипты:


    А так основаня проблема не в рассылке, а в данных. Возможности даже такого рассыльщика перекрывают возможности парсера в несколько раз. Слать по генеренке - я пробовал. Раз в 10 конверт в минус.
     
  12. samsonnn

    samsonnn Client

    Joined:
    Jun 2, 2015
    Messages:
    945
    Likes Received:
    492
    понравился подход к капче)))
     
    Atlas and AZANIR like this.
  13. juder

    juder Client

    Joined:
    Aug 5, 2018
    Messages:
    44
    Likes Received:
    8
    Хорошо написано, легко читается, хоть и много букв! Аффтар маладец! :ay:
     
    Atlas and lzlmrf like this.
  14. BblTPE3BUTEJlb

    BblTPE3BUTEJlb Client

    Joined:
    Sep 4, 2014
    Messages:
    75
    Likes Received:
    127
    Много вопросов в личку, которые можно объединить в один, суть которого: пробовал, пишет что отправлено, на деле нет.
    Погуглите Cloudmark + вымпелком.
    Еще раз повторяю, реклама в лоб не зайдет.
     
  15. vezunppc

    vezunppc Client

    Joined:
    Sep 8, 2011
    Messages:
    5
    Likes Received:
    4
    Оригинальная статья, с меня +

    Но с такими скилами в программировании, IMHO, тебе лучше подучить английский язык и спокойно работать программёром за 50$ в час (4-5 тысяч $ в месяц) в том же бурже
    и в свободное время пилить свои белые проектики ))
     
    BblTPE3BUTEJlb likes this.
  16. backoff

    backoff Client

    Joined:
    Apr 20, 2015
    Messages:
    2,431
    Likes Received:
    1,943
    может сразу лучше выучить инженерию и пойти в НАСА за 15-20к$/мес .... советчик )))
    как будто он кому-то сразу нужен будет или таких людей мало ....
     
    lzlmrf likes this.
  17. vezunppc

    vezunppc Client

    Joined:
    Sep 8, 2011
    Messages:
    5
    Likes Received:
    4
    Смотри на мир шире
    вот список людей из России кто заработал уже больше 50-100к баксов, с оплатой 30-80 баксов в час, и это только РНР программисты
    https://www.upwork.com/o/profiles/browse/?q=php&revenue=10000&pt=independent&english=1&loc=russia

    у меня знакомы программист яваскрипт и пару фреймворков немного изучивший, прокачал англ язык, через апворк прокачал скилы и акк, за 1 год с 10$ в час поднялся до 40-50$, потом ушёл на фултайм за 4-5К в месяц,
    был тим лидом, сейчас прожект менеджер в америкнском стартапе моб прокси, получает 6-7К в месяц

    я всегда завидовал хорошим программистам, и не понимал, как они не могут найти работу
    сейчас сам прокачиваю, пока зенку и потом нужные по ходу языки программирования и учу англ язык

    кстати в НАСА может сразу и не получится, но в Теслу устроиться вполне реально, если переедет в США
    и мое пожелание Вытрезвителю, было не стёбом, а реальное предложение по реализации его талантов, говнокодеров много, а людей с мозгами, реально способные решать проблемы с разных точек зрения мало и их расхватывают работодатели, и я думаю он сможет
     
    Last edited: Dec 15, 2018
    Atlas and zenno.xxx like this.
  18. BblTPE3BUTEJlb

    BblTPE3BUTEJlb Client

    Joined:
    Sep 4, 2014
    Messages:
    75
    Likes Received:
    127
    Дружище, спасиб тебе, конечно, за лестную оценку о моих навыках, но сие не правда :D
    Понимаешь, я не особо люблю стиль написания кода, принятый в интерпрайсе, плюс ко всему считаю ООП тупой ветвью программирования. Во всех языках. Ибо сие усложняет софт, плодит ошибки и жрет лишние ресурсы. В результате мой код на сторону мало кого интересует. Его сложно поддерживать со стороны.
    Моя сила в нестандартном мышлении. Ну вижу я там, где толпа мимо пробежала, где себя применить. Вот тут да, я могу из идей, уже изложенных на конкурсах, слепить свою уникальную. Ну и руками дописать что-то недостающие мне. Пусть и в виде веб сервисов, как в данном случае.
    А так я как раз всегда предпочитал на относительно свободном графике работать на дядю для стабильного прикрытия своей задницы пусть небольшой, но стабильной копеечкой, а собно фишки рубить на стороне в свободное время. Поэтому отказывался от повышений у дяди, который тоже видел прекрасно мои скилы, но не понимал, почему я не хочу больше работать и больше денег. В итоге я доотказывался :D
    А на тему США... Думаю я, как проложить себе туда дорожку в нормальном статусе. Английский кстати мне и не сильно учить надо 8-)
    В НАСА кстати не граждан не берут, как в любую другую контору государственной важности.
     
    Last edited: Dec 15, 2018
    GATSBY and Andrew Shell like this.
  19. pars

    pars Пользователь

    Joined:
    Dec 10, 2016
    Messages:
    52
    Likes Received:
    16
    Во первых свободного времени не будет - то тебе так кажется что оно будет, по факту в это время тебе будет пофиг на проекты какие либо .
    Во вторых 4-5 тысяч $ в месяц (если это в офисе,если в бурже онлайн то ты врядли найдешь столько заказов, будет либо сразу куча срочных либо тишина) включают в себя е*лю от начальнальства/дорогу на работу/кучу до***бов.... да и такие деньги можно поднимать зенкой свободно , если голова есть на плечах .
     
    Last edited: Dec 15, 2018
    BblTPE3BUTEJlb likes this.
  20. BblTPE3BUTEJlb

    BblTPE3BUTEJlb Client

    Joined:
    Sep 4, 2014
    Messages:
    75
    Likes Received:
    127
    И да, 4-5 в месяц в Америке это не абы какие деньги. Так, нижняя планка среднего класса. Со скрипом
     
    Andrew Shell likes this.
  21. Andrew Shell

    Andrew Shell Client

    Joined:
    Nov 24, 2016
    Messages:
    26
    Likes Received:
    7
    Ну да. У нас так и есть. Но не на чел, а на семью![​IMG]
     
  22. ffeniks

    ffeniks Client

    Joined:
    Jun 3, 2016
    Messages:
    201
    Likes Received:
    51
    Спасибо за статью
     
  23. linkod

    linkod Пользователь

    Joined:
    Oct 11, 2018
    Messages:
    117
    Likes Received:
    0
    У меня сугубо познавательный вопрос. Сколько смс было отправлено, чтобы получить цифру на скриншоте в рублях?
     
  24. BblTPE3BUTEJlb

    BblTPE3BUTEJlb Client

    Joined:
    Sep 4, 2014
    Messages:
    75
    Likes Received:
    127
    Примерно 5к в день.
     
    linkod likes this.
  25. leha52rus

    leha52rus Client

    Joined:
    Jun 1, 2017
    Messages:
    145
    Likes Received:
    16
    Очень необычно, взял на заметку,спасибо!
     

Пользователи просматривающие тему (Пользователей: 0, Гостей: 0)