NFsec Logo

Funkcje kodujące adresy e-mail w CMS WordPress

14/11/2009 w Bezpieczeństwo Brak komentarzy.  (artykuł nr 189, ilość słów: 1289)

W

iadomości SPAM swoje główne źródło bazy adresów e-mail znajdują w spambotach. Spamboty są to specjalnie zaprogramowane roboty sieciowe – podobne do tych, które indeksują strony dla wyszukiwarek – tylko z tą różnicą, iż robią to pod kontem wyszukiwania ogólnodostępnych adresów e-mail umieszczanych na stronach WWW. Tak zebrane adresy e-mail lądują w bazach danych spamerów, stają się przedmiotem handlu wśród różnych niechcianych kampanii reklamowych czy innych negatywnych form aktywności sieciowej szkodników pod postacią wirusów czy robaków.

Najprostszą metodą walki ze spambotami jest użycie techniki zniekształcania (ang. munging) lub zaciemniania (ang. obfuscation) adresu e-mail. Technika zniekształcania polega na zapisaniu adresu e-mail w formie uniemożliwiającej odczytanie go za pomocą oprogramowania komputerowego. Mimo to pozostaje on w pełni zrozumiały dla ludzkiego rozumu, który potrafi zrekonstruować oryginalny zapis. I tak dla przykładu zwykły adres e-mail pod postacią „nikt@ważny.pl” zostaje zapisany pod postacią „nikt (małpa) ważny (kropka) pl”. Technika ta staje się coraz bardziej popularna wśród użytkowników prywatnych stron WWW, grup dyskusyjnych, for czy czatów – ceniących sobie „czystość” swoich skrzynek pocztowych. Aktualnie istnieje bardzo duże prawdopodobieństwo, że adres e-mail zapisany w czystej postaci zostanie włączony do kolekcji przez złowrogie oprogramowanie komputerowe w tak zwanym procesie zbioru adresów e-mail (ang. e-mail address harvesting). Prywatne adresy przesyłane w wiadomościach e-mail pomiędzy dwoma osobami są najmniej narażone na dołączenie do zbioru (chyba, że jedna z nich posiada drugą w książce adresowej, która została właśnie przejęta przez złośliwe oprogramowanie infekujące jej komputer).

W wielu przypadkach różne zapisy zniekształcania stosowane przez kreatywnych odbiorców wiadomości utrudniają komunikację, która mogłaby zostać nawiązana przez początkujących użytkowników Internetu, a metoda ta wymaga kreatywności! Z prostego względu. Jeśli np. zastosujemy najbardziej znany zapis w postaci „login at host dot com” to jedynie pomożemy spamerom w zbieraniu adresów e-mail. Alternatywną metodą do zniekształcania adresów e-mail jest metoda zaciemniania. Polega ona na zapisaniu adresu e-mail w technice pozwalającej oszukać oprogramowanie komputerowe, a jednocześnie przedstawić adres e-mail w czystej postaci. Najbardziej znaną, która istnieje od zalania dziejów jest odpalenie ulubionego edytora graficznego i zapisanie adresu e-mail w postaci pliku graficznego. Bardziej wyrafinowaną odmianą tej techniki jest ukrycie adresu w animacji flash, która by zmuszała spamera do poszukania prawidłowego pliku .swf, jego ściągnięcia, dekompilacji oraz wyszukaniu w źródle adresu. Niestety techniki te nie mają racji bytu w przypadku stron, w których istnieje duża liczba dynamicznie dodawanych adresów e-mail. Drugą techniką w zaciemnianiu adresów jest zamiana „czytelnych” znaków na „nieczytelne”. Dla przykładu: następujący kod po przeprasowaniu przez przeglądarkę wyświetli adres e-mail „nikt@ważny.pl”:

<script type="text/javascript">
 var name = 'nikt';
 var at = '@';
 var domain = 'ważny.pl';
 document.write(name + at + domain);
</script>

lub

<a href='mailto:m%65@%6D%79%73ite%2E%63om'>Mail</a>

Niestety kody te są bardzo wadliwe, ze względu na ich boleśnie prostą możliwość odkodowania – nawet przez nie za bardzo wyrafinowane spamboty. Rozwiązaniem może okazać się metoda, której autorem jest Tim Williams, a która została zmodyfikowana przez Andrew Moulden’a oraz przepisana na kod PHP przez Ross’a Killen’a. Jej działanie polega na:

  • Pobraniu adresu e-mail, który ma zostać chroniony przez spambotami.
  • Przekształceniu go na małe litery.
  • Stworzeniu metody szyfrowania, która posłuży do zaszyfrowania adresu.
  • Wpisaniu zaszyfrowanego adresu e-mail oraz szyfru w dokument (oba te kawałki kodu są w zasadzie bezużyteczne dla zbieracza adresów).
  • Następnie owinąć te fragmenty kodu w JavaScript by faktycznie ukazać przeglądającemu użytkownikowi strony klikalny adres e-mail powstały z zaszyfrowanego klucza oraz tekstu.

Najważniejszą rzeczą jest, aby nie używać tego samego klucza za każdym razem, gdy adres e-mail jest kodowany. Gdyby technika ta zyskała szersze zastosowanie autor spambota z pewnością wykorzystałby ten fakt, do napisania metody dekodującej adres. Wiele trudniej jest zrobić to, gdy klucz jest dynamiczny i zmienia się za każdym razem, gdy zostaje użyta funkcja szyfrująca. Poniżej przedstawiam dwie takie funkcje, które zostały przystosowane już do użycia w systemie blogowym WordPress. Pierwsza z nich nazywa się munge:

function munge($atts, $content = null) {
    extract(shortcode_atts(array(
	'address' => 'user@user.com',
	), $atts));
    $address = strtolower($address);
    $coded = "";
    $unmixedkey ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.@";
    $inprogresskey = $unmixedkey;
    $mixedkey="";
    $unshuffled = strlen($unmixedkey);
    for ($i = 0; $i <= strlen($unmixedkey); $i++)
    {
	$ranpos = rand(0,$unshuffled-1);
	$nextchar = $inprogresskey{$ranpos};
	$mixedkey .= $nextchar;
	$before = substr($inprogresskey,0,$ranpos);
	$after = substr($inprogresskey,$ranpos+1,$unshuffled-($ranpos+1));
	$inprogresskey = $before.''.$after;
	$unshuffled -= 1;
    }
    $cipher = $mixedkey;

    $shift = strlen($address);

    $txt = "<script type=\"text/javascript\">\n";
    for ($j=0; $j<strlen($address); $j++)
    {
	if (strpos($cipher,$address{$j}) == -1 )
	{
		$chr = $address{$j};
		$coded .= $address{$j};
	}
	else
	{
		$chr = (strpos($cipher,$address{$j}) + $shift) %strlen($cipher);
		$coded .= $cipher{$chr};
	}
    }
    $txt .= "		coded = \"" . $coded . "\"\n" .
	"		key = \"".$cipher."\"\n".
	"		shift=coded.length\n".
	"		link=\"\"\n".
	"		for (i=0; i<coded.length; i++) {\n" .
	"		    if (key.indexOf(coded.charAt(i))==-1) {\n" .
	"		      ltr = coded.charAt(i)\n" .
	"		      link += (ltr)\n" .
	"		    }\n" .
	"		    else {     \n".
	"		      ltr = (key.indexOf(coded.charAt(i))-shift+key.length) % key.length\n".
	"		      link += (key.charAt(ltr))\n".
	"		    }\n".
	"		  }\n".
	"		document.write(\"<a href='mailto:\"+link+\"'>\"+link+\"</a>\")\n" .
        "	<" . "/script>\n";
    return $txt;
}
add_shortcode('antispam', 'munge');

Tak przygotowany kod można wkleić do pliku functions.php znajdującego się w głównym katalogu wybranej skórki / tematu. Plik ten jest automatycznie ładowany podczas inicjalizacji systemu WordPress dlatego każda funkcja znajdująca się w jego wnętrzu również jest automatycznie uaktywniana. Istnieje również możliwość zapisania całości np. jako plik antispam.php i umieszczeniu go w katalogu plugins systemu WordPress. Wówczas tak stworzoną „wtyczkę” należy aktywować z panelu administratora. Od tej pory każdy adres e-mail ujęty w znacznik „antispam” w taki sposób:

[antispam address="nikt@wazny.pl"]

Wewnątrz źródła strony adres będzie miał postać:

<script type="text/javascript">
	coded = "mJ4DNy4.HZNDgsW1"
		key = "uE3A6fe7tzQ25W0soPUSaZDVhMOckvLNyGTrmxnXl9IgKCY@bqR4FiHw1jBJdp8."
		shift=coded.length
		link=""
		for (i=0; i<coded.length; i++) {
		    if (key.indexOf(coded.charAt(i))==-1) {
		      ltr = coded.charAt(i)
		      link += (ltr)
		    }
		    else {     
		      ltr = (key.indexOf(coded.charAt(i))-shift+key.length) % key.length
		      link += (key.charAt(ltr))
		    }
		  }
		document.write("<a href='mailto:"+link+"'>"+link+"</a>")
</script>

Drugą funkcją jest funkcja o nazwie hide_email autorstwa Maurits’a van der Schee. Tak na prawdę jest to ta sama implementacja używająca tylko trochę innego algorytmu szyfrującego z zoptymalizowanym kodem JavaScript oraz zgodna ze standardem prasera XHTML 1.0:

function hide_email($atts, $content = null) {
    extract(shortcode_atts(array(
        'address' => 'user@user.com',
        ), $atts));
    $address = strtolower($address);
    $character_set = '+-.0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz';
    $key = str_shuffle($character_set); $cipher_text = ''; $id = 'e'.rand(1,999999999);
    for ($i=0;$i<strlen($address);$i+=1) $cipher_text.= $key[strpos($character_set,$address[$i])];
    $script = 'var a="'.$key.'";var b=a.split("").sort().join("");var c="'.$cipher_text.'";var d="";';
    $script.= 'for(var e=0;e<c.length;e++)d+=b.charAt(a.indexOf(c.charAt(e)));';
    $script.= 'document.getElementById("'.$id.'").innerHTML="<a href=\\"mailto:"+d+"\\">"+d+"</a>"';
    $script = "eval(\"".str_replace(array("\\",'"'),array("\\\\",'\"'), $script)."\")";
    $script = '<script type="text/javascript">/*<![CDATA[*/'.$script.'/*]]>*/</script>';
    return '<span id="'.$id.'">[Adres e-mail chroniony JavaScript]</span>'.$script;
}
add_shortcode('hideemail', 'hide_email');

Od tej pory każdy adres e-mail ujęty w znacznik “hideemail” w taki sposób:

[hideemail address="nikt@wazny.pl"]

Wewnątrz źródła strony adres będzie miał postać:

<span id="e885754433">[Adres e-mail chroniony JavaScript]</span><script type="text/javascript">/*<![CDATA[*/eval("var a=\"IMUstxVKiC9j7gZ+O@Yl5REeJw2WDQXbFyfBAGh8r0u-1.zpm4_adH36cPLSokTqnvN\";var b=a.split(\"\").sort().join(\"\");var c=\"o.Sogo.SoU-6H\";var d=\"\";for(var e=0;e<c.length;e++)d+=b.charAt(a.indexOf(c.charAt(e)));document.getElementById(\"e885754433\").innerHTML=\"<a href=\\\"mailto:\"+d+\"\\\">\"+d+\"</a>\"")/*]]>*/</script>

Wadą tego typu rozwiązań jest możliwość odgadnięcia adresów e-mail przez bardziej wyrafinowane boty, które zdolne są do wykonywania kodu JavaScript. Istnieje również prawdopodobieństwo, że wraz z popularyzacją tego typu rozwiązań – metody te są łamane i dodawane do nowszych wersji robotów przeszukujących Sieć – tym bardziej, że rozłożenie pozycji klucza jak i zaszyfrowanego kodu zawsze jest stałym elementem. Nie mniej jednak jest to znacznie lepsza metoda niż czysty tekst.
Więcej informacji: Hide email address in source code

Kategorie K a t e g o r i e : Bezpieczeństwo

Tagi T a g i : , , ,

Zostaw odpowiedź.

Musisz być zalogowany by móc komentować.