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

Регистрация
04.09.2014
Сообщения
459
Благодарностей
642
Баллы
93
Вводное слово.

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

Короче я вас предупредил, дальше думайте сами. Кто там искал рецепт поднятия бабла здесь и сейчас? Ну лови, пока лавочка открыта 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 Но подобраные цвета из кода можно выудить без проблем для реализации на более удобном вам языке.
Код:
<?
   if (! isset($_GET["file_name"]) )
   {
      echo '404';
      die;
   }
   else
   {
      $file_name = $_GET["file_name"];
      $url = './img/'.$file_name;
   }
   $bad_captcha = false;
   if ($_GET["gif"] == true) {
   imagepng(
    imagecreatefromstring(
        file_get_contents($url)
    ),
    "$url"
    );
   }
   $captcha = ImageCreateFromPng($url);
   $shirina = ImageSX ($captcha);
   $visota = ImageSY($captcha);

   $sq1[blue] = 0;        $sq1[green] = 0;        $sq1[black] = 0;        $sq1[red] = 0;        $sq1[yellow] = 0;         $sq1[grey] = 0;
   $sq2[blue] = 0;        $sq2[green] = 0;        $sq2[black] = 0;        $sq2[red] = 0;        $sq2[yellow] = 0;         $sq2[grey] = 0;
   $sq3[blue] = 0;        $sq3[green] = 0;        $sq3[black] = 0;        $sq3[red] = 0;        $sq3[yellow] = 0;         $sq3[grey] = 0;
   $sq4[blue] = 0;        $sq4[green] = 0;        $sq4[black] = 0;        $sq4[red] = 0;        $sq4[yellow] = 0;         $sq4[grey] = 0;
   $sq5[blue] = 0;        $sq5[green] = 0;        $sq5[black] = 0;        $sq5[red] = 0;        $sq5[yellow] = 0;         $sq5[grey] = 0;  

    //123
    //39
    for ($y =0 ; $y <$visota; $y++){

        for ($x = 0 ; $x <$shirina ; $x++){
        $rgb = imagecolorat ($captcha, $x, $y);
        $color_tran = imagecolorsforindex($captcha, $rgb);

//     5-40
//     25-60
//     55-90
//     85-110
//     105-123

  
        $pixels[$y][$x][red] = $color_tran[red];
        $pixels[$y][$x][green] = $color_tran[green];
        $pixels[$y][$x][blue] = $color_tran[blue];

        if ($x < 40 and $x > 5) {
            $color =  GetPixelColor ($pixels[$y][$x][red], $pixels[$y][$x][green], $pixels[$y][$x][blue]);
            switch ($color) {
            case "blue":
            $sq1[blue]++;
            break;
            case "green":
            $sq1[green]++;
            break;
            case "black":
            $sq1[black]++;
            break;
            case "red":
            $sq1[red]++;
            break;
            case "yellow":
            $sq1[yellow]++;
            break;
            case "grey":
            $sq1[grey]++;
            break;
            }
        }
        if ($x < 60 and $x > 25) {
            $color =  GetPixelColor ($pixels[$y][$x][red], $pixels[$y][$x][green], $pixels[$y][$x][blue]);
            switch ($color) {
            case "blue":
            $sq2[blue]++;
            break;
            case "green":
            $sq2[green]++;
            break;
            case "black":
            $sq2[black]++;
            break;
            case "red":
            $sq2[red]++;
            break;
            case "yellow":
            $sq2[yellow]++;
            break;
            case "grey":
            $sq2[grey]++;
            break;
            }
        }
        if ($x > 55 and $x < 90) {
            $color =  GetPixelColor ($pixels[$y][$x][red], $pixels[$y][$x][green], $pixels[$y][$x][blue]);
            switch ($color) {
            case "blue":
            $sq3[blue]++;
            break;
            case "green":
            $sq3[green]++;
            break;
            case "black":
            $sq3[black]++;
            break;
            case "red":
            $sq3[red]++;
            break;
            case "yellow":
            $sq3[yellow]++;
            break;
            case "grey":
            $sq3[grey]++;
            break;
            }
        }
        if ($x > 85 and $x < 100) {
            $color =  GetPixelColor ($pixels[$y][$x][red], $pixels[$y][$x][green], $pixels[$y][$x][blue]);
            switch ($color) {
            case "blue":
            $sq4[blue]++;
            break;
            case "green":
            $sq4[green]++;
            break;
            case "black":
            $sq4[black]++;
            break;
            case "red":
            $sq4[red]++;
            break;
            case "yellow":
            $sq4[yellow]++;
            break;
            case "grey":
            $sq4[grey]++;
            break;
            }
        }
        if ($x > 105) {
            $color =  GetPixelColor ($pixels[$y][$x][red], $pixels[$y][$x][green], $pixels[$y][$x][blue]);
            switch ($color) {
            case "blue":
            $sq5[blue]++;
            break;
            case "green":
            $sq5[green]++;
            break;
            case "black":
            $sq5[black]++;
            break;
            case "red":
            $sq5[red]++;
            break;
            case "yellow":
            $sq5[yellow]++;
            break;
            case "grey":
            $sq5[grey]++;
            break;
            }
        }      
        }
    }
    imagedestroy($captcha);

    arsort($sq1);    arsort($sq2);   arsort($sq3);   arsort($sq4);   arsort($sq5);

    $color1 = array_search(current($sq1), $sq1);
    $color2 = array_search(current($sq2), $sq2);
    $color3 = array_search(current($sq3), $sq3);
    $color4 = array_search(current($sq4), $sq4);
    $color5 = array_search(current($sq5), $sq5);
    if ($color1 == $color2 or $color2 == $color3 or $color3 == $color4 or $color4 == $color5) {
        $bad_captcha = true;
//        echo 'ЏовторЯющиесЯ цвета, капча плохаЯ<br>';
    }
    if (current($sq1) < 100 or current($sq2) < 100     or current($sq3) < 100 or current($sq4) < 100 or current($sq1) < 80) {
        $bad_captcha = true;
//        echo 'Ћчень мало основного цвета одной из букв, капча плохаЯ<br>';
    }
    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) {
        $bad_captcha = true;
//        echo 'Ћчень много шума второго цвета одной из букв, капча плохаЯ<br>';
    }
    unlink($url);
    if ($bad_captcha == true) {
      echo 'Bad captcha';
      die;
    }


    // создание обработанной капчи под распознование
    //     5-40    0-35
    //     20-65   35 - 80
    //     50-95   80 - 125
    //     75-115  125 - 165
    //     95-123  165 - 188
    $im = imagecreatetruecolor(193, 39);
    //установка основных цветов:
    $white = imageColorAllocate($im, 255, 255, 255);
//    $blue = imageColorAllocate($im, 0, 0, 255);
//    $red = imageColorAllocate($im, 255, 0, 0);
//    $green = imageColorAllocate($im, 0, 255, 0);
//    $yellow = imageColorAllocate($im, 255, 255, 0);
//    $grey = imageColorAllocate($im, 190, 190, 190);
    $black = imageColorAllocate($im, 0, 0, 0);



        for ($y =0 ; $y <39; $y++){
            $xnew = 0;
            for ($x = 5 ; $x <40 ; $x++){
                $color =  GetPixelColor ($pixels[$y][$x][red], $pixels[$y][$x][green], $pixels[$y][$x][blue]);
                if ($color == $color1){
                    imagesetpixel($im, $xnew, $y, $black);
                }
                else{
                    imagesetpixel($im, $xnew, $y, $white);
                }
                $xnew++;
            }
        }
  
        for ($y =0 ; $y <39; $y++){
            $xnew = 35;
            for ($x = 20 ; $x <65 ; $x++){
                $color =  GetPixelColor ($pixels[$y][$x][red], $pixels[$y][$x][green], $pixels[$y][$x][blue]);
                if ($color == $color2){
                    imagesetpixel($im, $xnew, $y, $black);
                }
                else{
                    imagesetpixel($im, $xnew, $y, $white);
                }
                $xnew++;
            }
        }

        for ($y =0 ; $y <39; $y++){
            $xnew = 80;
            for ($x = 50 ; $x <95 ; $x++){
                $color =  GetPixelColor ($pixels[$y][$x][red], $pixels[$y][$x][green], $pixels[$y][$x][blue]);
                if ($color == $color3){
                    imagesetpixel($im, $xnew, $y, $black);
                }
                else{
                    imagesetpixel($im, $xnew, $y, $white);
                }
                $xnew++;
            }
        }  

        for ($y =0 ; $y <39; $y++){
            $xnew = 125;
            for ($x = 75 ; $x <115 ; $x++){
                $color =  GetPixelColor ($pixels[$y][$x][red], $pixels[$y][$x][green], $pixels[$y][$x][blue]);
                if ($color == $color4){
                    imagesetpixel($im, $xnew, $y, $black);
                }
                else{
                    imagesetpixel($im, $xnew, $y, $white);
                }
                $xnew++;
            }
        }

        for ($y =0 ; $y <39; $y++){
            $xnew = 165;
            for ($x = 95 ; $x <123 ; $x++){
                $color =  GetPixelColor ($pixels[$y][$x][red], $pixels[$y][$x][green], $pixels[$y][$x][blue]);
                if ($color == $color5){
                    imagesetpixel($im, $xnew, $y, $black);
                }
                else{
                    imagesetpixel($im, $xnew, $y, $white);
                }
                $xnew++;
            }
        }  
     imagepng ($im, $url);
     echo 'Ok!';



    function GetPixelColor ($r, $g, $b) {
                    $pixel = 'white';
            if ($r == 51 and $g == 43 and $b == 102 or
                $r == 51 and $g == 0 and $b == 102 or
                $r == 51 and $g == 0 and $b == 153 or          
                $r == 0 and $g == 0 and $b == 102 or          
                $r == 0 and $g == 43 and $b == 102 or
                $r == 0 and $g == 43 and $b == 153 or
                $r == 0 and $g == 0 and $b == 153 or           
                $r == 51 and $g == 43 and $b == 153 or
                $r == 51 and $g == 85 and $b == 153 or          
                $r == 51 and $g == 43 and $b == 102 or
                $r == 102 and $g == 85 and $b == 153) {
                $pixel = 'blue';
            }
            if ($r == 102 and $g == 0 and $b == 153 or
                $r == 153 and $g == 0 and $b == 153 or
                $r == 153 and $g == 0 and $b == 102 or
                $r == 153 and $g == 43 and $b == 102 or
                $r == 153 and $g == 43 and $b == 153 or
                $r == 102 and $g == 43 and $b == 102 or          
                $r == 153 and $g == 85 and $b == 153 or
                $r == 204 and $g == 85 and $b == 153 or
                $r == 204 and $g == 85 and $b == 204 or
                $r == 204 and $g == 128 and $b == 204 or
                $r == 102 and $g == 0 and $b == 102) {
                $pixel = 'red';
            }
            if ($r == 51 and $g == 128 and $b == 153 or
                $r == 51 and $g == 128 and $b == 102 or
                $r == 51 and $g == 170 and $b == 153 or
                $r == 51 and $g == 170 and $b == 102 or          
                $r == 102 and $g == 170 and $b == 153 or
                $r == 102 and $g == 170 and $b == 204) {
                $pixel = 'green';
            }
            if ($r == 153 and $g == 128 and $b == 0 or
                $r == 102 and $g == 128 and $b == 0 or
                $r == 102 and $g == 128 and $b == 51 or
                $r == 102 and $g == 170 and $b == 0 or          
                $r == 153 and $g == 128 and $b == 51 or       
                $r == 153 and $g == 170 and $b == 0 or
                $r == 153 and $g == 170 and $b == 51 or
                $r == 204 and $g == 170 and $b == 102 or
                $r == 153 and $g == 170 and $b == 102) {
                $pixel = 'yellow';
            }      
            if ($r == 153 and $g == 128 and $b == 153 or
                $r == 153 and $g == 128 and $b == 102 or
                $r == 102 and $g == 128 and $b == 102 or
                $r == 102 and $g == 170 and $b == 102 or           
                $r == 153 and $g == 170 and $b == 153 or
                $r == 204 and $g == 170 and $b == 153 or               
                $r == 102 and $g == 128 and $b == 153) {
                $pixel = 'grey';
            }      
            if ($r == 0 and $g == 43 and $b == 0 or
                $r == 0 and $g == 85 and $b == 0 or       
                $r == 51 and $g == 43 and $b == 51 or
                $r == 0 and $g == 43 and $b == 51 or
                $r == 51 and $g == 85 and $b == 51 or
                $r == 51 and $g == 85 and $b == 0 or               
                $r == 102 and $g == 85 and $b == 102 or           
                $r == 51 and $g == 43 and $b == 0) {
                $pixel = 'black';
            }
    return $pixel;
    }
Шаг 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

Ну а под ней, типа в коментах, было написано следущее (напоминаю, мы знаем имя-регион):

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

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

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

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

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

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

Код:
// http://site.ru/page.php?region={-Variable.region-}&name={-Variable.name-} - это ссылка
// страница page.php должна содержать примерно такой код:

  if  (!isset($_GET["region"]))  {
  $region = 'Россия';
  }
  else
  {
  $region = trim($_GET["region"]);
  }
  if  (!isset($_GET["name"] ))
  {
  $name = '<i>Имя удалено админом</i>';
  }
  else
  {
  $name = trim($_GET["name"]);
  }
После этого в любое место можно поставить <? echo $name ?> и <echo $region>. И на странице будет написано то, что вы туда передали извне. А извне сие приходило через сокращалки. Такой простой метод позволяет персонализировать инфу.

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


Шаг 6. Абузы.

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

А денюшка капала. И капает до сих пор. Любителям пофапать на стату скриншот прилагаю. За июнь-июль, когда я вышел на пик:
stats.jpg

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

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

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

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

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

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

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

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

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

Вложения

  • 231,8 КБ Просмотры: 585

Для запуска проектов требуется программа ZennoPoster или ZennoDroid.
Это основное приложение, предназначенное для выполнения автоматизированных шаблонов действий (ботов).
Подробнее...

Для того чтобы запустить шаблон, откройте нужную программу. Нажмите кнопку «Добавить», и выберите файл проекта, который хотите запустить.
Подробнее о том, где и как выполняется проект.

Последнее редактирование:

Dr.Pipetka

Client
Регистрация
12.12.2017
Сообщения
1 315
Благодарностей
869
Баллы
113
Интересный подход к капче. Статья интересная. Молодец, спасибо.
 

backoff

Client
Регистрация
20.04.2015
Сообщения
6 095
Благодарностей
6 496
Баллы
113
Понравилось. Хороший текст с отступлениями.
Несколько месяцев назад я тоже обратил внимание на данную идею :-) еще себе записал все протестить, потестил, и поставил в задачи )))
Но другая идея забрала все время, что в итоге просто забил.
 
Регистрация
04.09.2014
Сообщения
459
Благодарностей
642
Баллы
93

Alexmd

Client
Регистрация
10.12.2018
Сообщения
1 021
Благодарностей
1 423
Баллы
113
Это одна из самых мотивирующих статей за все время проведения конкурсов. Спасибо.
 
  • Спасибо
Реакции: Atlas и iBotovod

pars

Пользователь
Регистрация
10.12.2016
Сообщения
78
Благодарностей
41
Баллы
18
Отличная статья ,и очень интересный подход к "прокладке" - возьму на карандаш !
 

melutsk

Client
Регистрация
03.08.2016
Сообщения
1 349
Благодарностей
1 259
Баллы
113
Давно думал про такую штуку. Годнота.
 

yriy158

Client
Регистрация
10.08.2013
Сообщения
490
Благодарностей
302
Баллы
63
Супер, годно, интересно, креативно)
Подскажи, на пост/гет переделать шаб под этот сайтец не пробовал для увеличения скорости? Или там хитрые скрпты/защита?
Я то свой траф бесполезно сливал, согласен)) но под укр траф мало годной монетизации что было, что есть по моему.
 
Регистрация
12.07.2014
Сообщения
916
Благодарностей
373
Баллы
63

ТРОН

Client
Регистрация
31.07.2016
Сообщения
336
Благодарностей
381
Баллы
63
на пост/гет переделать шаб под этот сайтец не пробовал для увеличения скорости
у меня не получилось, несколько параметров генерируются на JS, а тут я уже не особо шарю, как повторить скрипт
 
Регистрация
04.09.2014
Сообщения
459
Благодарностей
642
Баллы
93
Подскажи, на пост/гет переделать шаб под этот сайтец не пробовал для увеличения скорости? Или там хитрые скрпты/защита?
Вот моя реакция, когда я сунулся в яваскрипты:

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

samsonnn

Client
Регистрация
02.06.2015
Сообщения
1 802
Благодарностей
1 474
Баллы
113
понравился подход к капче)))
 
  • Спасибо
Реакции: Atlas и AZANIR

juder

Client
Регистрация
05.08.2018
Сообщения
62
Благодарностей
21
Баллы
8
Хорошо написано, легко читается, хоть и много букв! Аффтар маладец! :ay:
 
  • Спасибо
Реакции: Atlas и lzlmrf
Регистрация
04.09.2014
Сообщения
459
Благодарностей
642
Баллы
93
Много вопросов в личку, которые можно объединить в один, суть которого: пробовал, пишет что отправлено, на деле нет.
Погуглите Cloudmark + вымпелком.
Еще раз повторяю, реклама в лоб не зайдет.
 

vezunppc

Client
Регистрация
08.09.2011
Сообщения
10
Благодарностей
4
Баллы
3
Оригинальная статья, с меня +

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

backoff

Client
Регистрация
20.04.2015
Сообщения
6 095
Благодарностей
6 496
Баллы
113
тебе лучше подучить английский язык и спокойно работать программёром за 50$ в час (4-5 тысяч $ в месяц) в том же бурже
может сразу лучше выучить инженерию и пойти в НАСА за 15-20к$/мес .... советчик )))
как будто он кому-то сразу нужен будет или таких людей мало ....
 
  • Спасибо
Реакции: lzlmrf

vezunppc

Client
Регистрация
08.09.2011
Сообщения
10
Благодарностей
4
Баллы
3
может сразу лучше выучить инженерию и пойти в НАСА за 15-20к$/мес .... советчик )))
как будто он кому-то сразу нужен будет или таких людей мало ....
Смотри на мир шире
вот список людей из России кто заработал уже больше 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К в месяц

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

кстати в НАСА может сразу и не получится, но в Теслу устроиться вполне реально, если переедет в США
и мое пожелание Вытрезвителю, было не стёбом, а реальное предложение по реализации его талантов, говнокодеров много, а людей с мозгами, реально способные решать проблемы с разных точек зрения мало и их расхватывают работодатели, и я думаю он сможет
 
Последнее редактирование:
  • Спасибо
Реакции: Atlas и zenno.xxx
Регистрация
04.09.2014
Сообщения
459
Благодарностей
642
Баллы
93
Дружище, спасиб тебе, конечно, за лестную оценку о моих навыках, но сие не правда :D
Понимаешь, я не особо люблю стиль написания кода, принятый в интерпрайсе, плюс ко всему считаю ООП тупой ветвью программирования. Во всех языках. Ибо сие усложняет софт, плодит ошибки и жрет лишние ресурсы. В результате мой код на сторону мало кого интересует. Его сложно поддерживать со стороны.
Моя сила в нестандартном мышлении. Ну вижу я там, где толпа мимо пробежала, где себя применить. Вот тут да, я могу из идей, уже изложенных на конкурсах, слепить свою уникальную. Ну и руками дописать что-то недостающие мне. Пусть и в виде веб сервисов, как в данном случае.
А так я как раз всегда предпочитал на относительно свободном графике работать на дядю для стабильного прикрытия своей задницы пусть небольшой, но стабильной копеечкой, а собно фишки рубить на стороне в свободное время. Поэтому отказывался от повышений у дяди, который тоже видел прекрасно мои скилы, но не понимал, почему я не хочу больше работать и больше денег. В итоге я доотказывался :D
А на тему США... Думаю я, как проложить себе туда дорожку в нормальном статусе. Английский кстати мне и не сильно учить надо 8-)
В НАСА кстати не граждан не берут, как в любую другую контору государственной важности.
 
Последнее редактирование:
  • Спасибо
Реакции: GATSBY и Andrew Shell

pars

Пользователь
Регистрация
10.12.2016
Сообщения
78
Благодарностей
41
Баллы
18
Оригинальная статья, с меня +

Но с такими скилами в программировании, IMHO, тебе лучше подучить английский язык и спокойно работать программёром за 50$ в час (4-5 тысяч $ в месяц) в том же бурже
и в свободное время пилить свои белые проектики ))
Во первых свободного времени не будет - то тебе так кажется что оно будет, по факту в это время тебе будет пофиг на проекты какие либо .
Во вторых 4-5 тысяч $ в месяц (если это в офисе,если в бурже онлайн то ты врядли найдешь столько заказов, будет либо сразу куча срочных либо тишина) включают в себя е*лю от начальнальства/дорогу на работу/кучу до***бов.... да и такие деньги можно поднимать зенкой свободно , если голова есть на плечах .
 
Последнее редактирование:
  • Спасибо
Реакции: BblTPE3BUTEJlb
Регистрация
04.09.2014
Сообщения
459
Благодарностей
642
Баллы
93
И да, 4-5 в месяц в Америке это не абы какие деньги. Так, нижняя планка среднего класса. Со скрипом
 
  • Спасибо
Реакции: Andrew Shell

Andrew Shell

Client
Регистрация
24.11.2016
Сообщения
39
Благодарностей
16
Баллы
8

ffeniks

Client
Регистрация
03.06.2016
Сообщения
312
Благодарностей
411
Баллы
63
Спасибо за статью
 

linkod

Пользователь
Регистрация
11.10.2018
Сообщения
118
Благодарностей
1
Баллы
16
У меня сугубо познавательный вопрос. Сколько смс было отправлено, чтобы получить цифру на скриншоте в рублях?
 
Регистрация
04.09.2014
Сообщения
459
Благодарностей
642
Баллы
93
  • Спасибо
Реакции: linkod

leha52rus

Client
Регистрация
01.06.2017
Сообщения
266
Благодарностей
91
Баллы
28
Очень необычно, взял на заметку,спасибо!
 

bitport

Client
Регистрация
15.10.2016
Сообщения
117
Благодарностей
14
Баллы
18
Похоже билайн прикрыли лавочку
 

Alex1987

Client
Регистрация
21.06.2016
Сообщения
48
Благодарностей
6
Баллы
8
в теле 2 есть в литве ищи и будет тебе счастье )
 

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)