Automatyczne wykrywanie spamu na Blox.

Trochę z rozpędu po ostatnim spojrzeniu na beznadziejną captchę na Blox, trochę zażenowany brakiem działania administratorów Blox w tak wydawałoby się prostej sprawie, trochę chcąc odkurzyć stare skrypty i znajomość Perla, trochę ze względu na zainteresowaniem tematem spamu, a w końcu trochę dla zabawy, postanowiłem zrobić przymiarkę do automatycznego wykrywania spamu na Blox. Chodzi o określanie, czy dany blog służy wyłącznie spamowaniu, oczywiście automatycznie, a co za tym idzie nie ze stuprocentową pewnością.

Administratorzy zapowiedzieli, że captcha zostanie poprawiona w kwietniu (trzymam za słowo i liczę na to, zapewne nie tylko ja), więc spamblogów nie powinno od tej pory przybywać. Zatem postanowiłem skupić się nie na liście nowozałożonych blogów, tylko na liście nowych wpisów, czyli aktywnych spamblogach. Co prawda pierwotny plan zakładał przeiterowanie się po wszystkich blogach i określenie prawdopodobieństwa, czy jest to spamblog, ale nie znalazłem niestety listy wszystkich blogów na Blox. Owszem, można próbować robić rzeźbę pod tytułem „przeiterujmy się po tagach”, ale nadal nie daje to gwarancji uzyskania listy wszystkich blogów – wystarczy, że ktoś nie taguje i system nie dotrze do jego bloga, więc stanęło na tym, że obserwuję listę nowych wpisów i stamtąd biorę dane. Przy okazji oceniam nie tyle cały blog, co poszczególne wpisy, co może być przydatne.

Podejście pierwsze – pobierz i oceń. Na samym początku stwierdziłem, że będę pobierał wpis do oceny i oceniał na podstawie arbitralnych kryteriów. Pomysł szybko upadł – zmiany w algorytmie oceniania powodowały niekompatybilność z poprzednimi danymi, a zmiany były konieczne – wychodziły coraz to nowe kryteria i ich wagi. Wersjonowanie algorytmu przy ocenie nie pomagało, bo dane były tracone. OK, nie jest to wszystko aż tak proste, jak się wydawało na początku.

Podejście drugie – pobierz i zapisz jak najwięcej cech wyróżniających dla danego wpisu/bloga, a potem pomyśli się nad algorytmem. No niestety, zapisywanie dużej ilości danych może być ciekawe, szczególnie, że potem można sięgnąć do wiedzy ze studiów i określić poziomy istotności poszczególnych parametrów (albo popytać kumpla o gotowca, może jeszcze ma…). Wytrenuje się AI na próbce kontrolnej, a potem AI sama zrobi resztę. Brzmi fajnie, ale trochę overkill, poza tym, mało odporne na dołożenie kolejnych parametrów, gdyby przyszło mi do głowy ich wyciąganie.

Podejście trzecie, aktualne,kompromisowe – pobierz i zapisz istotne (wybrane arbitralnie przeze mnie) cechy wyróżniające dany wpis. Osobny skrypt ma algorytm procentowy, każda cecha może przyjmować wartości 0-100% prawdopodobieństwa bycia spamem. Następnie w zależności od ilości cech wylicz prawdopodobieństwo dla całego wpisu przy pomocy średniej ważonej. Rezultaty są dość interesujące.

Tutaj lista blogów (praktycznie nikt nie korzystał, więc wywaliłem), które sklasyfikowałem jako spamerskie z prawdopodobieństwem 80% i więcej. Format prawdopodobieństwo bycia spamem (%), spacja, link do bloga. Nie widzę (szybko patrząc) żadnego false positive, a wy? Aktualnie jest takich blogów 375 na 2404 wszystkich sprawdzonych blogów. Jasne, nie jest to cud techniki, ale przy dodaniu pewnych prostych whitelist myślę, że można spokojnie blokować automatem wszystkie blogi z prawdopodobieństwem od 70% w górę.

Szczegółów badanych cech oraz algorytmu nie chcę na razie opisywać, bo po co spamerzy mają się bronić? Jak będzie utrudnione zakładanie nowych blogów, to pomyślę o tym. Na razie cały czas zbierają się dane… Gdyby byli chętni do przeglądania wyniku w celu wychwytywania false positive’ów (wpisujcie miasta, które przeglądają ;-)), to mogę pomyśleć o wystawianiu listy spamów automatem co jakiś czas.

Całość napisana oczywiście w Perlu, główny moduł zbierający z użyciem WWW::Mechanize (genialna sprawa do crawlerów).

UPDATE: Drobny update statystyk z dnia 27.04.2012 – 13481 unikatowe blogi (wcześniej chyba były unikatowe wpisy, ale mniejsza), w tym 1094 do natychmiastowego wycięcia (80% i więcej). Dla porządku 70% i więcej to 2438 sztuki. Listy nie zamieszczam, bo zainteresowanie było znikome. A captcha nadal nie została poprawiona, choć koniec kwietnia…

Spam na Blox, czyli jak nie implementować CAPTCHA.

Od dłuższego czasu serwis blogowy Blox boryka się z plagą spamu. Słyszałem zapewnienia, że moderatorzy/admini walczą z tym zjawiskiem, ale wydaje mi się, że bez większych sukcesów, a nawet, że problem spamu się nasila. Jest to zjawisko dla wszystkich (poza spamerami) niekorzystne, a nierzadko na stronie głównej o pewnych porach spamy stanowią 30 i więcej procent wpisów.

Postanowiłem zerknąć na proces zakładania konta od początku. Pierwsze co rzuciło mi się w oczy, to prostota CAPTCHA. Być może parę lat temu wystarczało coś takiego, by odstraszyć spamerów, ale wojna trwa – istnieją narzędzia do automatycznego rozpoznawania nawet dość skomplikowanych CAPTCHA ze stosunkowo dużą pewnością (grubo ponad 50%). Niedawno nawet Jogger, który pozwalał właścicielowi bloga na mocne zmiany wyglądu CAPTCHA (kształt, wielkość, kolor), przy komentarzach dorzucił do niej litery obok cyfr, bo spamerzy się przebijali…

Żeby sprawdzić, czy nie przypadek, że CAPTCHA jest taka słaba, wcisnąłem F5, raz, drugi, trzeci… I okazało się, że trafiłem na powtarzające się słowa. Chwilę się pobawiłem i faktycznie, nie da się ukryć, CAPTCHA powtarza się i to – na oko – często. Postanowiłem sprawę zbadać dokładniej.

Sposób badania: uruchomienie przeglądarki, wyczyszczenie historii, w każdej serii 50 przeładowań strony (F5 lub ctrl-r), zapisanie wyników do pliku (każdy wynik w pojedynczej linii) w takiej kolejności, w jakiej się pojawiały. Żeby wykluczyć wpływ User Agent i czasu, każda seria wykonywana na różnej przeglądarce i w odstępie minimum kilkudziesięciu minut.

W pierwszej serii (przeglądarka chromium) 50 ciągów wyrazów wystąpiły 32 unikatowe ciągi, przy czym 4 wystąpiły trzykrotnie, 10 dwukrotnie, a 18 tylko raz. Dodatkowo rzuciła mi się w oczy prawdopodobna metoda powstawania wielu CAPTCHA – podział słowa na sylaby, połączone z ew. wyrzuceniem niektórych liter, a następnie wymieszanie tych slab. Przykładowo zykamu i kazymu (czyli muzyka), letefon, fontele i fonlete (czyli telefon), zetagagataze (czyli gazeta), lafiorka, fiorkala, fiorlaka (czyli kalafior).

Druga seria, kilkadziesiąt minut później na midori – 34 unikatowe ciągi, jeden wystąpił czterokrotnie, 13 dwukrotnie, 20 jednokrotnie. Wyrazy zdecydowanie powtarzają się między seriami – dla obu serii łącznie wystąpiło 46 unikatowych ciągów, 2 wystąpiły pięciokrotnie, 6 – czterokrotnie, 8 – trzykrotnie, 12 -dwukrotnie, 18 – jednokrotnie.

Ponieważ ciąg znaków pod którym można poprać losowany obrazek może być stały (z danego można korzystać wiele razy), postanowiłem uprościć sobie pobieranie i przeliczanie. Szybki skrypt, który przy pomocy wget pobiera zadaną ilość obrazków i zapisuje do kolejnych plików, a następnie sprawdzenie sum kontrolnych (md5) tychże plików. I tu ciekawostka – sumy kontrolne praktycznie się nie powtarzają. Sprawdziłem organoleptycznie i faktycznie – o ile wyrazy powtarzają się często, to praktycznie każdy plik jest binarnie inny. Czyli raczej mała ilość wyrazów raczej nie wynika z chęci cache’owania.

Dla porządku: dla 100 plików 3 miały takie same sumy kontrolne, a kolejne 5 sum występowało dwa razy. Powtórzyłem eksperyment dla 1000 plików. Pojawiło się 611 unikatowych sum kontrolnych, jedna z sum występowała 7 razy, jedna 6, sześć wystąpiło 5 razy, cztery – 20 razy, trzy – 53 razy, dwie – 188 razy i jedna – 342 razy.

Nie sprawdzałem dokładnie, czy dany wyraz w CAPTCHA koreluje z ciągiem w treści (na oko nie), ani z jaką skutecznością zadziała automatyczne rozpoznawanie, ale przy tak częstym powtarzaniu się ciągów znaków i plików nie ma to znaczenia – wygląda, że baza jest za mała, a przekształcenie zbyt proste i można spokojnie stworzyć skrypt, który porówna sumę md5 wygenerowanego pliku z arbitralną bazą.

O problemie pisałem wstępnie na forum, póki co bez odzewu. W każdym razie liczę na to, że wpis zmotywuje administratorów blox do załatania ewidentnej dziury w zakładaniu nowych kont. Obecne likwidowanie spamerskich blogów przypomina wylewanie wody z łódki, zamiast załatania w niej dziury, przez którą wody nabiera.

Oczywiście najlepsze byłoby podpięcie jakiegoś znanej, sprawdzonej implementacji CAPTCHA, zamiast wymyślania koła od nowa (i to sugestia dla tych, którzy chcą stosować tego typu rozwiązanie) ale wydaje się, że nawet z istniejącą implementacją można prosto zadziałać w taki sposób, że stanie się ona choć w części efektywna. Przede wszystkim mam na myśli zwiększenie bazy słów i ilości przekształceń.

Obok złych wiadomości są też i dobre – co prawda problem nie jest to Blox, tylko ogólnie dotyczy konto.gazeta.pl, ale – jak wynika z korespondencji z administratorami Blox – jest znany i ma być najdalej w kwietniu poprawiony. Pozostaje uzbroić się w odrobinę cierpliwości i liczyć na to, że po załataniu dziury uda się skutecznie pozbyć spamerów. W tej chwili bywa tak, że 100% wpisów na głównej stanowią spamy…

Pagerank, statystyki, reklamy, czyli cykliczne podsumowanie bloga.

Dawno nie było nic o statystykach na blogu – ostatni wpis w tym temacie prawie półtora roku temu. No to tak dla pamięci – systemy operacyjne. Windows XP – 36,5%, Windows 7 – 22,3%, Vista – 9,2%, czyli łącznie Windows łącznie 68%. Skutek większej ilości wejść z wyszukiwarki na niezwiązane z Linuksem frazy, zapewne. Linux prawie 26%, Mac OS X – spadek do 2,2%.

Jeśli chodzi o przeglądarki to Firefox nadal trzyma się mocno – 51%. Nie jest niespodzianką przyrost użytkowników Chrome – 19%, lekki spadek Opery – 11,5%. Różne wersje IE – minimalne umocnieni, do 10,5%. Safari 2,5%, Mozilla/5.0 (Netscape) – drastyczny spadek do 4%.

Rozdzielczość ekranu bez większych zmian – liderem pozostaje kategoria 1280×800 lub 1280×1024 z 32,5% (nadal spadek).

Tradycyjnie Google zamieszało z pagerankiem. Tym razem pozytywnie, bo jest 5 dla tego bloga, natomiast zdziwił mnie wysoki pagerank moich pozostałych nowych tworów – zarówno mój blog muzyczny jak i blog będący fanpage Bez Krótkich Spodni mają aż 4. Czyli więcej od mojego starego bloga. Chyba aberracja.

Zmieniło się trochę, jeśli chodzi o zabawę z reklamami. Pożegnałem AdTaily, próbowałem znaleźć polską alternatywę. Bez efektów. Koniec końców postanowiłem wrócić do ogólnoświatowego monopolisty w tym względzie, czyli Google. W sumie za wcześnie mówić o efektach, jedno co warto powiedzieć to fakt, że Google, mimo kreowania się na proste, wcale proste nie jest. Za dużo opcji, za dużo terminów. Cóż, taki standard, ale przydałby się widok uproszczony, przynajmniej na początku. 😉