Formular-Spamming per PHP

30 03 2012

Ein Kontaktformular, über das der interessierte Besucher mit den Machern in Verbindung treten kann gehört zum guten Ton. Vergreifen sich die Webseiten-Macher selbst im guten Ton, möchte man denen auch gerne seine Meinung kundtun. Immer und immer wieder. Nehmen wir doch als fiktives Beispiel einen guten Deutschen, der zwar Zeit genug findet Minderheiten zu beschimpfen, allerdings nicht dafür, sein Kontaktformular vernünftig abzusichern. So ist es möglich, diesem ohne viel Aufwand zum Ersinnen mehr oder weniger einfallsreicher Texte Mails zukommen zu lassen. Als einziges Pflichtfeld ist die (falsch geschriebene) E-Mail gekennzeichnet, wobei noch nicht einmal eine rudimentäre Gültigkeitsprüfung stattfindet.

Plausibilitätsprüfung mangelhaft

Zum Test basteln wir uns ein Kontaktformular mit vier Feldern. Verlangt werden der Name, ein Betreff, die E-Mail Adresse sowie ein Text. Geprüft wird lediglich, ob die Angabe für die E-Mail nicht leer ist. Damit hätten wir zumindest von der Funktionalität das real existente Kontaktformular nachgebaut.

<?php
if (!empty($_POST)){
	// Die Pruefung beschraenkt sich darauf zu testen, ob das Feld "sender_email" nicht leer ist
	if (empty($_POST['sender_email'])){
		echo '<p>Bitte eine E-Mail Adresse angeben.</p>';
	}

	// Kein Fehler gefunden? Dann sende uns eine Mail
	else {
		// Aus der Angabe der E-Mail und des Namens wird der Absender erzeugt
		if (!empty($_POST['sender_name'])) $header = "From: ".$_POST['sender_name']." <".$_POST['sender_email'].">\n";
		else $header = "From: ".$_POST['sender_email']."\n";
		$header .= 'Content-Type: text/plain; charset="UTF-8";'."\n";
		$header .= 'Content-Transfer-Encoding: 8bit'."\n";
		$header .= "X-mailer: PHP/".phpversion()."\n";
		$header .= "\n";

		// Verschicke die Mail, der Betreff wird als ebensolcher in die Mail gesetzt, die Nachricht als Mail-Text
		if (mail('aaaaaprvdgrwwelt@example.org', $_POST['sender_betreff'], $_POST['sender_nachricht'], $header)){
			echo '<p>Die Anfrage wurde erfolgreich versendet.</p>';
		} else {
			echo '<p>Es ist ein Problem beim Mailversand aufgetreten.</p>';
		}
	}
}

?>

<!-- Das eigentliche Formular ausgeben -->
<form action="<?php echo $_SERVER['PHP_SELF']?>" method="post">
	<p><label>Name:</label> <input type="text" name="sender_name" <?php if (isset($_POST['sender_name'])) echo 'value="'.$_POST['sender_name'].'"'; ?> /></p>
	<p><label>*E-Mail:</label> <input type="text" name="sender_email" <?php if (isset($_POST['sender_email'])) echo 'value="'.$_POST['sender_email'].'"'; ?> /></p>
	<p><label>Betreff:</label> <input type="text" name="sender_betreff" <?php if (isset($_POST['sender_betreff'])) echo 'value="'.$_POST['sender_betreff'].'"'; ?> /></p>
	<p><label>Nachricht:</label> <textarea name="sender_nachricht"><?php if (isset($_POST['sender_nachricht'])) echo $_POST['sender_nachricht']; ?></textarea></p>
	<p><input type="submit" value="Senden" /></p>
</form>

Formular   E-Mail Formular

Mit wenig Aufwand wäre es uns möglich, dieses Formular immer und immer wieder abzusenden. Doch den händischen Aufwand ist uns das nicht wert. Also versuchen wir das Absenden zu automatisieren. Hierfür gibt es Tools, mit denen Spammer tagtäglich unschuldige Webseitenbetreiber belästigen. Daran ist nicht ganz einfach heranzukommen, also schauen wir, was wir nur mittels PHP selbst basteln können.

Das zu tun gibt es verschiedene Ansätze. Man könnte beispielsweise cURL nutzen. Für unser Beispiel verwende ich aus persönlicher Vorliebe und weil cURL nicht auf jedem PHP Webspace installiert ist fsockopen. Die einzelnen Zeilen in der Quelle sind kommentiert, großartig darauf eingehen möchte ich nicht, da man diese mit Grundlagenkenntnissen von PHP durchaus verstehen sollte.

<?php

// Die URL zum Formular. Kann im Quelltext des Formulars aus der Zeile
// <form action="[URL]"> gelesen werden
$url = 'http://demo.tiefergelegt.net/index.php';

// Die Felder, die wir fuellen wollen und der Wert, der gesetzt wird
$post_daten = array(
	'sender_email' => 'test123@example.org',
	'sender_name' => 'aaaaaprvdgrwwelt',
	'sender_betreff' => 'Liebe Gruesse',
	'sender_nachricht' => 'Lorem ipsum dolor sit amet'
);

// Aufsplitten der URL. Wir benoetigen spaeter die einzelnen Teile
$a_url = parse_url($url);

// Erstelle aus dem Array einen Query-String
$post_string =  http_build_query($post_daten);

// Oeffnen der Verbindung zum Remote Server
$fp = fsockopen($a_url['host'], 80) or die ('Konnte keine Verbindung öffnen zu '.$a_url['host']);

	// Senden der Daten
	fputs($fp, "POST ".$a_url['path']." HTTP/1.1\r\n");
	fputs($fp, "Host: ".$a_url['host']." \r\n");
	fputs($fp, "Content-Type: application/x-www-form-urlencoded\r\n");
	fputs($fp, "Content-Length: ".strlen($post_string)."\r\n");
	fputs($fp, "Connection: close\r\n\r\n");
	fputs($fp, $post_string);

// Verbindung wieder schliessen
fclose($fp);

// Bildschirmausgabe zur Information
echo 'Die Daten wurden übermittelt an '.$url.'<br />';
echo 'Der Post-String war '.$post_string;

?>

Meldung   E-Mail

Wollen wir nun nicht ständig den gleichen Text senden, den man relativ einfach aus dem Postfach löschen könnte und sind wir zudem viel zu unkreativ, uns selbst etwas auszudenken, automatisieren wir doch auch diesen Schritt. Wir benötigen lediglich zwei kleine Funktionen. Die erste, gen_woerter, erzeugt x zufaellig zusammengefügte Wörter. gen_email nutzt diese Funktion, um eine einigermaßen real aussehende Mailadresse zu generieren.

function gen_woerter($anzahl_min = 1, $anzahl_max = null, $laenge_min = 2, $laenge_max = 15){
	// Alle moeglichen Zeichen fuer die Woerter
	$zeichen = "abcdefghijklmnopqrstuvwxyz";
	// Variable initialisieren
	$woerter = '';

	// Da sowohl ein Wert fuer die minimale Anzahl Woerter als auch fuer die
	// maximale Anzahl angegeben wurde, muss ein zufaelliger Wert in diesem
	// Bereich erzeugt werden.
	if (is_numeric($anzahl_min) && is_numeric($anzahl)){
		$anzahl = mt_rand($anzahl_min, $anzahl_max);
	}
	// Ansonsten gilt der Wert von $anzahl_min
	else {
		$anzahl = $anzahl_min;
	}

	for ($i = 1; $i <= $anzahl; $i++){
		$wortlaenge = mt_rand($laenge_min, $laenge_max);

		// Erzeuge eine beliebige Zeichenfolge aus $zeichen mit einer
		// zufaelligen Laenge von $laenge_name
		for ($j = 1; $j <= $wortlaenge; $j++) {
			$woerter .= substr($zeichen, mt_rand(0, strlen($zeichen)), 1);
		}
		if ($i < $anzahl) $woerter .= ' ';
	}

	return $woerter;
}

function gen_email(){
	// Die moeglichen Top Level Domains, kann entsprechend erweitert werden
	$tlds = array("com","net","org","de");
	// Initialisieren der Variablen
	$email = "";

	// Erzeuge einen "Namen", nutze hierfuer die Funktion gen_woerter
	$email .= gen_woerter(1, null, 2, 15);

	// Eine E-Mail Adresse enthaelt immer ein @
	$email .= "@";

	// Das selbe Prozedere wie fuer den Namen nun auch fuer die Domain
	$email .= gen_woerter(1, null, 3, 15);

	// Haenge eine beliebige TLD aus unserem Array an
	$email .= '.'.$tlds[mt_rand(0, (sizeof($tlds)-1))];

	return $email;
}

Diese Funktionen nutzen wir in unserem Skript, um die Werte fuer die Felder zu füllen. Das könnte beispielsweisen so aussehen:

// Die Felder, die wir fuellen wollen und der Wert, der gesetzt wird
$post_daten = array(
	'sender_email' => gen_email(),
	'sender_name' => gen_woerter(1, 2, 3, 10),
	'sender_betreff' => gen_woerter(2, 5, 2, 12),
	'sender_nachricht' => gen_woerter(25, 50, 2, 12)
);

Das Ergebnis:

Das Ergebnis

Doch wie bringen wir das PHP Skript nun dazu, immer wieder auf das Formular loszugehen? Da gibt es mehrere Möglichkeiten. Wer einen Server inklusive Webspace sein eigen nennt und dazu noch crontab nutzen darf, stellt hier einfach einen minütlichen Aufruf ein. Das selbe können wir auch Remote mit unserem Linux PC machen, indem wir mit wget das Skript aufrufen (eine andere Alternative wäre die Verwendung von Lynx). Das sähe in etwa so aus:
* * * * * /usr/bin/wget "http://www.example.org/post.php"

Im Windows könnte das mit dem Taskplaner ähnlich funktionieren, wget gibt es auch für dieses System. Des weiteren könnten wir das Skript einfach im Hintergrund unserer eigenen Homepage laufen lassen, indem wir den Code in diese kopieren und die Ausgabezeilen löschen, bzw. per include die Seite aufrufen. Wir könnten auch eine eigene Webseite mit ein paar hübschen Bildchen erstellen, die diesen Code beinhaltet. Dann übernehmen unsere Besucher das Spamming.

Wichtiger Hinweis: Dieser Text soll nicht zur Nachahmung animieren. Das Spammen fremder Kontaktmailer könnte möglicherweise gegen irgendwelche Gesetze verstoßen. Von daher soll hier nur auf die technische Machbarkeit und die Notwendigkeit, geeignete Schutzmaßnahmen für ein Kontaktformular zu treffen hingewiesen werden. Den Beispielen mangelt es an einer vernünftigen Fehlerbehandlung, was aber egal ist, da wir diese ja eh niemals einsetzen werden.


Aktionen

Information

Hinterlasse einen Kommentar