fastix®: Missbrauch von Formularen ('jrubin3456@aol.com-Problem')

Moin!

Ich habe mich nochmals des Themas der missbrauchten Formulare angenommen. Zur Erinnerung: Da versucht ein Spammer via Skript in Formulare ziemlich wüstes Zeug einzutragen (Genau genommen versucht er die vom Formular aufgerufenen Skripte mit dem Stuff zu füttern).

Ich habe versucht das in eine Funktion zu packen, damit bestehende Skripte leicht nachgerüstet werden können. Erste Funktionsproben sind erfolgreich verlaufen, aber ich stelle die Funktion mal zur Diskussion. Vielleicht (hoffentlich) findet jemand jemand Fehler

Die Funktion untersucht zwei Eigenarten:

Erstens: Der Spammer versucht immer in eigentlich einzeilige Variablen Inhalte mit Zeilenumbrüchen einzuschmuggeln.

  • In diesem Fall erfolgt der sofortige Abbruch.

Zweitens: Der Spammer versucht in jedes Formularfeld eine mindestens Mailadresse einzutragen.

  • In diesem Fall erfolgt der sofortige Abbruch in Abhängigkeit von der Anzahl der Variablen mit einem @ im Inhalt und der erlaubten Anzahl eben solcher.
  
# Im Gedenken an den gestorbenen jrubin3456@aol.com  
  
function jrubin3456($intMaxAllowed, $strFields) {  
   # Übergeben Sie dieser Funktion als Int wieviele Formularfelder ein  
   # '@' enthalten dürfen sowie als  String eine Komma-separierte  
   # Liste aller Namen von Formularfeldern, die einzeilig sein sollen.  
   # Die Funktion liefert ein true zurück, wenn in den Feldern Zeilenumbrüche  
   # vorkommen oder die zulässige Anzahl der Felder mit einem '@' überschritten wird  
  
   # Beispiel eines Aufrufs:  
   #  
  
  /*  
 if (jrubin3456(2, 'name,email,firma,position')) {  
    header("HTTP/1.0 403 Forbidden");  
    die("Spam attempt denied");  
 }  
   */  
  
   #  
   #  
  
   if ((!isset($strFields)) || (trim($strFields)=='')) {  
    die ("Error: in function jrubin3456: Es wurden keine Feldnamen übergeben");  
   }  
  
  
   $arFields=explode(',', $strFields);  
   if ($intMaxAllowed > count($arFields)) {  
    die ("Error: in function jrubin3456: Die Anzahl der erlaubten Felder mit @ ist größer als die Anzahl der Felder.");  
   }  
  
 $intFoundAet=0;  
 foreach ($arFields as $strField) {  
  
 $strField = trim ($strField);  
  
 if (isset($_POST[$strField])) {  
  if ((strpos($_POST[$strField],"\n")) || (strpos($_POST[$strField],"\r"))) {  
   return true;  
  }  
  if (strpos($_POST[$strField],'@')) {  
   $intFoundAet++;  
  }  
 }  
  
 if (isset($_GET[$strField])) {  
  if ((strpos($_GET[$strField],"\n")) || (strpos($_GET[$strField],"\r"))) {  
   return true;  
  }  
  if (strpos($_GET[$strField],'@')) {  
   $intFoundAet++;  
  }  
 }  
  
 if ($intFoundAet > $intMaxAllowed)  
  return true;  
 }  
  
 return false;  
}  

MFFG (Mit freundlich- friedfertigem Grinsen)

fastix®

--
Als Freiberufler bin ich immer auf der Suche nach Aufträgen: Schulungen, Seminare, Training, Development
  1. Ahoi fastix®,

    Ich habe mich nochmals des Themas der missbrauchten Formulare angenommen.

    an dieser stelle möchte ich auf meinen post aufmerksam machen:
    https://forum.selfhtml.org/?t=115068&m=734497
    Außerdem möchte ich noch hinzufügen das ich das boundary
    zwischenzeitlich zufällig erzeuge, damit sollte er in den header der
    unter umständen empfangenen mail schauen es ihm nicht, bzw. nicht soviel
    bringt.

    MfG

    --
    Alle Angaben wie immer ohne Gewähr
    LEISE IST SCHEISSE!
  2. Hi,

    Ich habe mich nochmals des Themas der missbrauchten Formulare angenommen. Zur Erinnerung: Da versucht ein Spammer via Skript in Formulare ziemlich wüstes Zeug einzutragen (Genau genommen versucht er die vom Formular aufgerufenen Skripte mit dem Stuff zu füttern).

    Ich hatte mit demselben Problem zu kämpfen. Letzendlich habe ich eine Flooding-Sperre eingebaut, sprich: einmaliges Absenden aller fünf Minuten (festgenagelt an der IP). Die Formularfelder selbst werden durch entsprechende RegExes überprüft. Danach war Ruhe! Es scheint ein beliebtes Mittel von Spammern zu sein, solche unzureichend geschützten Formulare als Spamschleudern zu mißbrauchen.

    Die Floodingsperre erachte ich für sinnvoll, da es einen Spammer nicht stört, ein und das selbe Formular 10k x automatisch abzusenden, wenn die Formularfelder entsprechend überprüft werden und keine zusätzlichen Mail-Adressen eingetragen werden können (CC,BCC).

    Klaus

    1. Moin!

      Ich hatte mit demselben Problem zu kämpfen. Letzendlich habe ich eine Flooding-Sperre eingebaut

      Ja, ich habe auch Ruhe. Aber bei Durchsicht von news:danam habe ich festgestellt, dass sich das Problem derzeit auswächst und folglich einen Bedarf an etwas festgestellt, was den oder die Spammer auch stoppt, wenn es _nicht_ um Mailversand geht. Tatsächlich scheinen ja vom Gästebuch über das Forum bis zum Kleinanzeigendienst alle betroffen zu sein. Und es sollte etwas sein, was sich leicht nachrüsten lässt- und wiederverwendbar ist.

      MFFG (Mit freundlich- friedfertigem Grinsen)

      fastix®

      --
      Als Freiberufler bin ich immer auf der Suche nach Aufträgen: Schulungen, Seminare, Training, Development
  3. Hi,

    Ich habe versucht das in eine Funktion zu packen, damit bestehende Skripte leicht nachgerüstet werden können. Erste Funktionsproben sind erfolgreich verlaufen, aber ich stelle die Funktion mal zur Diskussion.

    ähnlich wie Klaus würde ich einen anderen Ansatz wählen: Du gehst mit Deinem Script nach Indizien, die bei einer akuten Art des Spammings gerade mal üblich sind. Der nächste Spammer geht aber vermutlich anders vor, so dass das Script nicht mehr greift bzw. mit jeder Iterationsstufe individuell nachgerüstet werden muss. Wodurch zeichnet sich denn ein Spammer aus? Meiner Ansicht nach vor allem dadurch, dass er die Formulare automatisiert abschickt - bzw. direkte Requests an die Script-URI schickt, anstatt über ein Formular zu gehen.

    Mir schwebt vor, auf der Formularseite eine Session mit langer Laufzeit zu starten (bzw. eine bestehende zu füttern), in der die Aufrufzeit gespeichert wird. Findet der Formularversand früher als nach n Sekunden statt (n könnte im Bereich 5 bis 10 liegen), hat offenbar kein Mensch die Formularfelder ausgefüllt. Die Aufrufzeit sollte nach jedem (mindestens legitimen, besser ausnahmslos jedem) Scriptaufruf aktualisiert werden.

    Zugegeben, das ist nicht so leicht nachzurüsten wie Deine Funktion. Im Ergebnis dürfte es aber deutlich effektiver, effizienter und dauerhafter sein.

    Erstens: Der Spammer versucht immer in eigentlich einzeilige Variablen Inhalte mit Zeilenumbrüchen einzuschmuggeln.

    Das passiert auch leicht durch Copy & Paste.

    Zweitens: Der Spammer versucht in jedes Formularfeld eine mindestens Mailadresse einzutragen.

    eMail und Firma können sehr leicht @-Zeichen enthalten. Findet sich dies auch noch in einem anderen Feld, warum auch immer, werden legitime Nutzungen bei Deinem Beispielaufruf abgelehnt. Dieses Problem könntest Du zumindest reduzieren, indem Du nicht nur auf @-Zeichen testest, sondern auf eMail-Adressen.

    if ($intMaxAllowed > count($arFields)) {
        die ("Error: in function jrubin3456: Die Anzahl der erlaubten Felder mit @ ist größer als die Anzahl der Felder.");

    Dies kann nicht von außen manipuliert werden (Hacking mal ausgenommen), wäre also IMHO kein Grund für einen Abbruch.

    if (isset($_POST[$strField])) {

    [...]

    if (isset($_GET[$strField])) {

    $_REQUEST würde die Code-Verdopplung sparen ... :-)

    Cheatah

    --
    X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
    1. Moin!

      Ich habe versucht das in eine Funktion zu packen, damit bestehende Skripte leicht nachgerüstet werden können. Erste Funktionsproben sind erfolgreich verlaufen, aber ich stelle die Funktion mal zur Diskussion.

      ähnlich wie Klaus würde ich einen anderen Ansatz wählen: Du gehst mit Deinem Script nach Indizien, die bei einer akuten Art des Spammings gerade mal üblich sind.

      Diese sind "notwendig". Das @ _muss_ enthalten sein, der Zeilenumbruch _muss_ enthalten sein, sonst passt das gesamte Angriffsszenario nicht. Zumindest nicht, wenn man als Ziel den Spamversand unterstellt. Das Flooding eines Gästebuches oder Forums halte ich für weniger gefährlich. Aber geade hinsichtlich eines Forums würde ich die Abstände zwischen den Postings nicht auf x Minuten pro IP festlegen wollen.

      Mir schwebt vor, auf der Formularseite eine Session mit langer Laufzeit zu starten (bzw. eine bestehende zu füttern), in der die Aufrufzeit gespeichert wird. Findet der Formularversand früher als nach n Sekunden statt (n könnte im Bereich 5 bis 10 liegen), hat offenbar kein Mensch die Formularfelder ausgefüllt. Die Aufrufzeit sollte nach jedem (mindestens legitimen, besser ausnahmslos jedem) Scriptaufruf aktualisiert werden.

      Auch das ist ein Herumgedoktore an Symptomen: Der Spammer könnte sich darauf einstellen und seinen Request n+3 Sekunden nach Abruf des Formulars und des Session-Cookies starten. Auch ein Unix-Batch kennt sleep n.

      Zugegeben, das ist nicht so leicht nachzurüsten wie Deine Funktion. Im Ergebnis dürfte es aber deutlich effektiver, effizienter und dauerhafter sein.

      Dauerhafter ergo nicht.

      Der an anderer Stelle genannte Weg mit der Grafik ist meines Ermessens ungangbar: Für viele zu schwer nachzurüsten, von zu vielen Vorbedingungen (Grafikbibliotheken) abhängig, zugangsbeschränkend für Besucher.

      Erstens: Der Spammer versucht immer in eigentlich einzeilige Variablen Inhalte mit Zeilenumbrüchen einzuschmuggeln.

      Das passiert auch leicht durch Copy & Paste.

      Hm. Das stimmt allerdings. Sendet der Browser die eigentlich? Man könnte die Daten vorher trimmen, um festzustellen ob sich der Umbruch inmitten von Text befindet und so eine Reihe solcher Fehlbedienungen ausschließen- jedoch nicht alle.

      Zweitens: Der Spammer versucht in jedes Formularfeld eine mindestens Mailadresse einzutragen.

      eMail und Firma können sehr leicht @-Zeichen enthalten. Findet sich dies auch noch in einem anderen Feld, warum auch immer, werden legitime Nutzungen bei Deinem Beispielaufruf abgelehnt. Dieses Problem könntest Du zumindest reduzieren, indem Du nicht nur auf @-Zeichen testest, sondern auf eMail-Adressen.

      Das wäre eine Möglichkeit, die ich bedenken sollte. Aber ich habe die Zahl der Felder, welche das @ enthalten dürfen, bewusst konfigurierbar gemacht. Der "jrubin3456" versucht schlicht in jedes Feld eine Mailadresse einzutragen. Grund : jedes kann 'nützlich' sein und er will sich nicht mit Kram wie Fremdsprachen und der Benennung aufhalten- das Muster wird er fortsetzen.

      if ($intMaxAllowed > count($arFields)) {
          die ("Error: in function jrubin3456: Die Anzahl der erlaubten Felder mit @ ist größer als die Anzahl der Felder.");

      Dies kann nicht von außen manipuliert werden (Hacking mal ausgenommen), wäre also IMHO kein Grund für einen Abbruch.

      Doch. Es ist ein sozusagen fataler logischer Fehler im Script. Es soll sichergestellt werden, dass es funktioniert. Gut: ich hätte ein anderes Error-Management benutzen können, aber wozu?

      if (isset($_POST[$strField])) {
      [...]
      if (isset($_GET[$strField])) {

      $_REQUEST würde die Code-Verdopplung sparen ... :-)

      Führwahr! Zudem sollte ich also tatsächlich auf eine Mailadresse proben.

      MFFG (Mit freundlich- friedfertigem Grinsen)

      fastix®

      --
      Als Freiberufler bin ich immer auf der Suche nach Aufträgen: Schulungen, Seminare, Training, Development
      1. Hallo

        Erstens: Der Spammer versucht immer in eigentlich einzeilige Variablen Inhalte mit Zeilenumbrüchen einzuschmuggeln.

        Das passiert auch leicht durch Copy & Paste.

        Hm. Das stimmt allerdings. Sendet der Browser die eigentlich?

        Ja, das tut er, wie ich letztens wieder feststellen musste. *grrrr*

        Man könnte die Daten vorher trimmen, um festzustellen ob sich der Umbruch inmitten von Text befindet und so eine Reihe solcher Fehlbedienungen ausschließen- jedoch nicht alle.

        Falls sich ein Zeilenumbruch im Text befindet, kannst du aber immer noch nicht sicher sein, dass es sich um einen Spamversuch handelt. Mit mehreren Umbrüchen wird es (sehr viel) wahrscheinlicher. So erging es mir vor kurzer Zeit, als in einem Formular, das zum Eintragen von Links in eine DB gedacht ist, ganze Mailheader eingetragen wurden.

        Tschö, Auge

        --
        Die Musik drückt aus, was nicht gesagt werden kann und worüber es unmöglich ist zu schweigen.
        (Victor Hugo)
        Veranstaltungsdatenbank Vdb 0.1
      2. Hi,

        Diese sind "notwendig". Das @ _muss_ enthalten sein, der Zeilenumbruch _muss_ enthalten sein, sonst passt das gesamte Angriffsszenario nicht.

        naja, es gibt auch (zu viele) Mailscripts, denen man die Zieladresse übergeben kann, anstatt evtl. eines Tokens, aus welchem der Server diese ermittelt. Hier ist der Zeilenumbruch nicht mehr nötig.

        Auch das ist ein Herumgedoktore an Symptomen:

        Sicher - es existiert schließlich keine technisch eindeutige Definition von "Spamming". Meiner Ansicht nach treffen diese Symptome aber auf weitaus mehr Fälle zu.

        Der Spammer könnte sich darauf einstellen und seinen Request n+3 Sekunden nach Abruf des Formulars und des Session-Cookies starten. Auch ein Unix-Batch kennt sleep n.

        Ja, aber er müsste das n (sowie dessen Existenz) erst einmal ermitteln. Ferner kostet es ihn die doppelte Anzahl an Requests[1] sowie ein komplexeres Datenmanagement. Ich behaupte, mit dieser Methode hat man langfristig die höhere Trefferquote bei weniger False Positives.

        Dauerhafter ergo nicht.

        Doch :-)

        Der an anderer Stelle genannte Weg mit der Grafik ist meines Ermessens ungangbar: Für viele zu schwer nachzurüsten, von zu vielen Vorbedingungen (Grafikbibliotheken) abhängig, zugangsbeschränkend für Besucher.

        Ja, das fände ich auch eher nervig. Es mag zudem ggf. eine Verletzung der Impressumspflicht sein.

        [Umbrüche per Copy & Paste]

        Sendet der Browser die eigentlich?

        Es gibt hier mindestens zwei Leute, die das schon leidlich haben erfahren dürfen ;-)

        Man könnte die Daten vorher trimmen, um festzustellen ob sich der Umbruch inmitten von Text befindet und so eine Reihe solcher Fehlbedienungen ausschließen- jedoch nicht alle.

        Du könntest Umbrüche in Header-relevanten Daten allgemein durch Leerzeichen ersetzen. Das erfordert natürlich Umrüstungen "irgendwo innerhalb der Scripts". Vielleicht kann dazu eine Funktion dienen, die sämtliche Daten erhält, auf Konsistenz checkt, ggf. verändert und zurück liefert (aber bitte ohne Seiteneffekte *g*).

        Der "jrubin3456" versucht schlicht in jedes Feld eine Mailadresse einzutragen. Grund : jedes kann 'nützlich' sein und er will sich nicht mit Kram wie Fremdsprachen und der Benennung aufhalten- das Muster wird er fortsetzen.

        Zumindest solange er damit hinreichenden Erfolg hat.

        die ("Error: in function jrubin3456: Die Anzahl der erlaubten Felder mit @ ist größer als die Anzahl der Felder.");
        Dies kann nicht von außen manipuliert werden (Hacking mal ausgenommen), wäre also IMHO kein Grund für einen Abbruch.
        Doch. Es ist ein sozusagen fataler logischer Fehler im Script.

        Nicht unbedingt, es kann auch eine Erleichterung für den Entwickler sein. "Ich will für alle Felder @-Zeichen erlauben, egal wie viele es sind." - Vernachlässige nicht die Faulheit des Menschen :-)

        Cheatah

        [1] Ich gehe davon aus, dass die Formulardaten zur optimalen Nutzung zwischen- oder dauergespeichert werden.

        --
        X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
        X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
        X-Will-Answer-Email: No
        X-Please-Search-Archive-First: Absolutely Yes