Fritz!Box Login mit VB

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 16 Antworten in diesem Thema. Der letzte Beitrag () ist von tbbear.

    Fritz!Box Login mit VB

    Hi,

    ich möchte mich mit WebRequest an meine Fritz!Box 3272 anmelden.

    @petaod hat mir dankenswerterweise einen Link zukommen lassen, wo genau das versucht wird. Allerdings stammt der Link aus dem Jahr 2010, da mach ich mal lieber einen frischen Thread auf.

    Hier ist das leicht modifizierte Coding:

    VB.NET-Quellcode

    1. Private myContainer As CookieContainer = New CookieContainer
    2. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    3. Dim myLoginResponse As String = FritzBoxLogin(myPassword) 'Logon Fritz!Box and get response
    4. End Sub
    5. Private Function FritzBoxLogin(ByVal Passwort As String) As String
    6. Debug.Print(vbNewLine & "Test started -------------------------------------------------------------")
    7. 'Define Login Request
    8. Dim Login As HttpWebRequest = CType(HttpWebRequest.Create("http://fritz.box/cgi-bin/webcm"), HttpWebRequest)
    9. Login.Method = "POST"
    10. 'Login.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13"
    11. Login.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0"
    12. Login.CookieContainer = myContainer
    13. Login.AllowAutoRedirect = True
    14. Login.ContentType = "application/x-www-form-urlencoded"
    15. Dim Post As String = "getpage=../html/de/menus/menu2.html&errorpage=../html/index.html&var:lang=de&var:pagename=home&var:menu=home&=&login:command/password=" & Passwort
    16. Debug.Print("Post: " & Post)
    17. Login.ContentLength = Post.Length
    18. 'Perform login
    19. Dim Wr As New StreamWriter(Login.GetRequestStream(), System.Text.Encoding.Default)
    20. Wr.Write(Post) : Wr.Close()
    21. 'Get response
    22. Dim Re As New StreamReader(Login.GetResponse.GetResponseStream())
    23. Dim Response As String = Re.ReadToEnd : Re.Close()
    24. Return Response
    25. End Function


    Leider klappt das nicht ... ich bekomme eine Exception in der Anweisung

    VB.NET-Quellcode

    1. Dim Re As New StreamReader(Login.GetResponse.GetResponseStream())


    Web Exception wurde nicht behandelt: The remote server returned an error: (404) Not Found.

    Die Anweisung produziert eine lange List von Fehlermeldungen, die wohl einen Trace der Ereignisse dokumentieren. Das sagt mir aber leider auch nach eingehender "Lektüre" nicht viel.

    Ich habe versucht die Aufrufparameter zu überprüfen. Ich hab dazu TamperData in meinem Firefox installiert und mal den Login über die fritz.box URL "getampert"

    Damit hab ich den Login.UserAgent aktualisiert.

    Das dürfte zwar nicht falsch gewesen sein. Aber leider hilft es nicht, die Exception bleibt bestehen.

    Ich könnte mir vorstellen, dass der Post String nicht richtig gesetzt ist. Aber das ist halt nur eine Vermutung ... und was da drin stehen muss, da hab ich keine Ahnung.

    TamperData zeigt meinen Aufruf nicht an ... vermutlich kommt es also noch zu gar keinem WebRequest ...

    Na, vielleicht ist jemand so freundlich, mir ein bissl auf die Sprünge zu helfen.

    LG
    Peter

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Peter329“ ()

    Um die Kommunikation per HttpWebRequest zu automatisieren ist es sehr hilfreich, diese mittels Browser einmal aufzuzeichnen.
    Installiere HttpFox oder ein ähnliches Tool und programmiere das (intelligent) nach, was tatsächlich auf der Leitung passiert.

    Peter329 schrieb:

    (404) Not Found.
    deutet allerdings auf einen Trivialfehler hin, dass du eine URL ansprichst, die es gar nicht gibt.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    Peter329 schrieb:

    (404) Not Found.

    deutet allerdings auf einen Trivialfehler hin, dass du eine URL ansprichst, die es gar nicht gibt.


    Jau ... Trivialfehler ... die URL sieht mir schon ein bissl suspect aus! Die müsste man halt herausfinden ! Nur wie ?

    Soweit ich das sehe, wird die Adresse

    http://fritz.box/login.lua

    verwendet. Die führt im Browser zum Login Screen. Nur wenn ich das oben in POST eintrage erhalte ich immer noch den Fehler 404 not found ...

    Die Idee mit HttpFox klingt natürlich sehr gut ! Das Add On hab ich installiert ... nur kann ich es nicht bedienen.

    Nach Beschreibung sollte es "rechts unten" ein neues Symbol geben. So viel ich auch gucke, da gibt es kein neues Symbol. Ich hab dann in den Einstellungen eingetragen:

    Automatisch starten, wenn der Browser started
    HttpFox immer in einem neuen Fenster öffnen

    Und natürlich hab ich meinen Script Blocker deaktiviert.

    Trotzdem tut sich nix !

    Was mach ich denn jetzt schon wieder falsch ?

    LG
    Peter

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Peter329“ ()

    ... so, jetzt hab ich herausgefunden, wie man den HttpFox started (das kleine Symbol gibt es nämlich nicht mehr).

    Ich habe jetzt den Anmeldevorgang an meine Fritz!Box aufgezeichnet. (s. Anhang). Aber wie geht man damit jetzt um ?

    Offensichtlich startet das Ganze mit der URL fritz.box, das ist keine Überraschung.

    Danach wird fritz.box/logincheck.lua aufgerufen (da wird wohl das Passwort abgefragt? )

    Und dann geht es weiter mit fritz.box/login.lua

    Irgendwann wird eine sid zugewiesen ... und dann ist man wohl angemeldet.

    Zu Beginn gibt es keine POST Daten, sondern nur HEADER Daten.

    Der User-Agent den ich eingetragen hatte stimmt ... aber wie das mit den anderen Parametern aussieht, das ist offen.

    Egal welche URL ich bei "Post" eintrage .... ich kriege den 404 not found Fehler.

    Was macht man denn jetzt mit so einem Trace! Irgendwie fühle ich mich hoffnungslos überfordert!

    LG
    Peter
    Bilder
    • HttpFox 01.jpg

      391,75 kB, 1.320×967, 449 mal angesehen
    In die Post Property kommt keine Url rein sodern die Postdaten, das sind die Daten, die du wenn du auf den Login Button klickst, an die Fritzbox sendest. Bin mir nicht sicher wie die bei der Fritzbox genau aussehen werd aber dann mal gucken. Dürften aber in dem Schema sein 'username=xxx?password=xxx'

    *Edit*

    Das ganze ist doch etwas kniffliger, da das Passwort gehasht wird das übernimmt die md5.js. Habs mir aber jetzt nicht weiter angesehen.

    Spoiler anzeigen

    /*
    * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
    * Digest Algorithm, as defined in RFC 1321.
    * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
    * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
    * Distributed under the BSD License
    * See pajhome.org.uk/crypt/md5 for more info.
    */
    /*
    * Configurable variables. You may need to tweak these to be compatible with
    * the server-side, but the defaults work in most cases.
    */
    var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
    var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
    /* var chrsz = 8; */ /* bits per input character. 8 - ASCII; 16 - Unicode */
    var chrsz = 16; /* bits per input character. 8 - ASCII; 16 - Unicode */
    /*
    * These are the functions you'll usually want to call
    * They take string arguments and return either hex or base-64 encoded strings
    */
    function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
    function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
    function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
    function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
    function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
    function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }
    /*
    * Perform a simple self-test to see if the VM is working
    */
    function md5_vm_test()
    {
    return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
    }
    /*
    * Calculate the MD5 of an array of little-endian words, and a bit length
    */
    function core_md5(x, len)
    {
    /* append padding */
    x[len >> 5] |= 0x80 << ((len) % 32);
    x[(((len + 64) >>> 9) << 4) + 14] = len;
    var a = 1732584193;
    var b = -271733879;
    var c = -1732584194;
    var d = 271733878;
    for(var i = 0; i < x.length; i += 16)
    {
    var olda = a;
    var oldb = b;
    var oldc = c;
    var oldd = d;
    a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
    d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
    c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);
    b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
    a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
    d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);
    c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
    b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
    a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);
    d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
    c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
    b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
    a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);
    d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
    c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
    b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329);
    a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
    d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
    c = md5_gg(c, d, a, b, x[i+11], 14, 643717713);
    b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
    a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
    d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083);
    c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
    b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
    a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);
    d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
    c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
    b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);
    a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
    d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
    c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);
    b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
    a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
    d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
    c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562);
    b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
    a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
    d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);
    c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
    b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
    a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174);
    d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
    c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
    b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);
    a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
    d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
    c = md5_hh(c, d, a, b, x[i+15], 16, 530742520);
    b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
    a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
    d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);
    c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
    b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
    a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);
    d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
    c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
    b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
    a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);
    d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
    c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
    b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649);
    a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
    d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
    c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);
    b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
    }
    return Array(a, b, c, d);
    }
    /*
    * These functions implement the four basic operations the algorithm uses.
    */
    function md5_cmn(q, a, b, x, s, t)
    {
    return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
    }
    function md5_ff(a, b, c, d, x, s, t)
    {
    return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
    }
    function md5_gg(a, b, c, d, x, s, t)
    {
    return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
    }
    function md5_hh(a, b, c, d, x, s, t)
    {
    return md5_cmn(b ^ c ^ d, a, b, x, s, t);
    }
    function md5_ii(a, b, c, d, x, s, t)
    {
    return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
    }
    /*
    * Calculate the HMAC-MD5, of a key and some data
    */
    function core_hmac_md5(key, data)
    {
    var bkey = str2binl(key);
    if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);
    var ipad = Array(16), opad = Array(16);
    for(var i = 0; i < 16; i++)
    {
    ipad = bkey[i] ^ 0x36363636;
    opad[i] = bkey[i] ^ 0x5C5C5C5C;
    }
    var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
    return core_md5(opad.concat(hash), 512 + 128);
    }
    /*
    * Add integers, wrapping at 2^32. This uses 16-bit operations internally
    * to work around bugs in some JS interpreters.
    */
    function safe_add(x, y)
    {
    var lsw = (x & 0xFFFF) + (y & 0xFFFF);
    var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
    return (msw << 16) | (lsw & 0xFFFF);
    }
    /*
    * Bitwise rotate a 32-bit number to the left.
    */
    function bit_rol(num, cnt)
    {
    return (num << cnt) | (num >>> (32 - cnt));
    }
    /*
    * Convert a string to an array of little-endian words
    * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
    */
    function str2binl(str)
    {
    var bin = Array();
    var mask = (1 << chrsz) - 1;
    for(var i = 0; i < str.length * chrsz; i += chrsz)
    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
    return bin;
    }
    /*
    * Convert an array of little-endian words to a string
    */
    function binl2str(bin)
    {
    var str = "";
    var mask = (1 << chrsz) - 1;
    for(var i = 0; i < bin.length * 32; i += chrsz)
    str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
    return str;
    }
    /*
    * Convert an array of little-endian words to a hex string.
    */
    function binl2hex(binarray)
    {
    var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
    var str = "";
    for(var i = 0; i < binarray.length * 4; i++)
    {
    str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
    hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF);
    }
    return str;
    }
    /*
    * Convert an array of little-endian words to a base-64 string
    */
    function binl2b64(binarray)
    {
    var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    var str = "";
    for(var i = 0; i < binarray.length * 4; i += 3)
    {
    var triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16)
    | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
    | ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
    for(var j = 0; j < 4; j++)
    {
    if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
    else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
    }
    }
    return str;
    }
    Bilder
    • FritzBoxPostData.png

      34,44 kB, 601×531, 277 mal angesehen

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Fakiz“ ()

    Bei mir funktioniert ein Login so:
    GET http://fritz.box/

    Dann ein POST http://fritz.box/cgi-bin/webcm
    Mit folgenden Headern
    Referer: http://fritz.box/cgi-bin/webcm?getpage=../html/index_inhalt.html
    Content-Type: http://fritz.box/cgi-bin/webcm?getpage=../html/index_inhalt.html
    Accept: http://fritz.box/cgi-bin/webcm?getpage=../html/index_inhalt.html
    und folgenden POST-Daten:
    getpage=../html/de/menus/menu2.html&errorpage=../html/index.htm&var:lang=de&var:pagename=home&var:menu=home&login:command/password=MeinPasswort Das entspricht so ziemlich dem, was auch im Beispielcode gemacht wird.
    Das kann bei dir natürlich variieren.
    Du hast anscheinend ein anderes Modell, aber so ungefähr dürfte es bei dir auch aussehen.
    Der POST bei dir geht zu http://fritz.box/login.lua und den Referer benötigst du anscheinend nicht nicht.
    Die vielen GETs dazwischen benötigst du vermutlich nicht.
    Aber du musst dir die POST-Daten in HttpFox anschauen und die ins Programm einbauen.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Vielen Dank an euch beide für eure Antworten!

    Ich hab versucht erst mal die Hinweise von Petaod umzusezten. Ich habe mir die Klasse HttpWebRequest angesehen und alle Login. Parameter explizit gesetzt, soweit mir das sinnvoll erschien.

    Die Adressen habe ich jetzt abgeändert - ich bin mir aber nicht sicher, ob das den Hinweisen von @petaod wirklich entspricht.

    VB.NET-Quellcode

    1. Private Function FritzBoxLogin(ByVal Passwort As String) As String
    2. Debug.Print(vbNewLine & "Test started -------------------------------------------------------------")
    3. 'Define login Requeest
    4. Dim Login As HttpWebRequest = CType(HttpWebRequest.Create("http://fritz.box"), HttpWebRequest)
    5. Login.Method = "POST"
    6. Login.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0"
    7. Login.AllowAutoRedirect = True
    8. Login.ContentType = "application/x-www-form-urlencoded"
    9. Login.KeepAlive = True
    10. Login.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
    11. Login.Referer = ""
    12. Login.CookieContainer = myContainer
    13. Dim Post As String = "getpage=http://fritz.box/login.lua&errorpage=http://fritz.box/html/index.html&var:lang=de&var:pagename=home&var:menu=home&=&login:command/password=" & Passwort
    14. Login.ContentLength = Post.Length
    15. Debug.Print("Post: " & Post)
    16. 'Perform login
    17. Dim Wr As New StreamWriter(Login.GetRequestStream(), System.Text.Encoding.Default)
    18. Wr.Write(Post)
    19. Wr.Close()
    20. 'Get response
    21. Dim Re As New StreamReader(Login.GetResponse.GetResponseStream())
    22. Dim Response As String = Re.ReadToEnd
    23. Re.Close()
    24. Debug.Print("Response: " & Response)
    25. Debug.Print(vbNewLine & "Test ended ---------------------------------------------------------------")
    26. Return Response
    27. End Function


    Das ist die Debug Ausgabe:

    Test started -------------------------------------------------------------

    Post: getpage=http://fritz.box/login.lua&errorpage=http://fritz.box/html/index.html&var:lang=de&var:pagename=home&var:menu=home&=&login:command/password=xxxxxxxxxxxxx
    Response: <!DOCTYPE html>
    <html>
    <head>
    <title>FRITZ!Box</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta http-equiv="expires" content="0">
    <!--<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />-->
    <script type="text/javascript">
    var g_HelpWin = null;
    </script>
    </head>
    <frameset id="frame_set" rows="*">
    <frame src="/logincheck.lua" id="frame_content" scrolling="auto" frameborder="0" />
    </frameset>
    <noframes>
    <body>
    <p>Ihr Browser unterstützt keine XHTML-Frames.</p>
    <p>Sie können die <a href="/logincheck.lua">FRITZ!Box Benutzeroberfläche</a> aber trotzdem ohne Einschränkung nutzen.</p>
    </body>
    </noframes>
    </html>

    Test ended ---------------------------------------------------------------

    Das sieht mir irgendwie noch nicht so richtig erfolgreich aus.

    Mit dieser Definition

    VB.NET-Quellcode

    1. Dim Login As HttpWebRequest = CType(HttpWebRequest.Create("http://fritz.box/cgi-bin/webcm"), HttpWebRequest)


    Erhalte ich wie vorher den 404 not found Fehler.

    Übrigens, ich habe eine Fritz!Box 3272 ...

    LG
    Peter
    Erst mal Danke für eure Hinweise, die mir sehr weitergeholfen haben!

    So wie ich das verstehe, ist das Login Verfahren abgeändert worden. Weil einige "böse Buben" das Passwort im Klartext ausgelesen haben - wie das funktionierte kann man in YouTube bewundern. :)

    Das Login ist jetzt abhängig von der jeweiligen Fritz!OS Version. Das neue Verfahren vermeidet es, das Passwort im Klartext zu senden ... man muss sich eine Session ID sid besorgen und die ist beim Aufruf der Seiten vorzuweisen. Nach 10 Minuten ohne Aktivitäten verfällt die sid.

    Wie erhält man nun eine Session Id.

    Dazu braucht man zunächst einmal eine Challenge. Das ist ein String, der von der Fritz!Box dynamisch vergeben wird. Diese Challenge erhält man über den Aufruf der Seite login_sid.lua. Die Challenge wird dann mit dem eigenen Passwortverkettet:

    Challenge-Password (inklusive "-" Zeichen).

    Und dieser String wird dann mit md5.js in einen Hash-String umgewandelt. Der ist dann für das Login zu verwenden. Damit ist sichergestellt, dass der Hash auch bei gleichem Passwort immer anders aussieht.

    Zunächst mal hab ich die Challenge generieren lassen, indem ich die Seite login_sid.lua auslese.

    VB.NET-Quellcode

    1. Dim Request As HttpWebRequest = CType(WebRequest.Create("http://Fritz.box/login_sid.lua"), HttpWebRequest)
    2. Request.Method = "POST"
    3. Request.ContentType = "application/x-www-form-urlencoded"
    4. Dim Post As String = " "
    5. Dim byteArray() As Byte = Encoding.UTF8.GetBytes(Post)
    6. Request.ContentLength = byteArray.Length
    7. Dim DataStream As Stream = Request.GetRequestStream()
    8. DataStream.Write(byteArray, 0, byteArray.Length)
    9. DataStream.Close()
    10. Dim Response As HttpWebResponse = CType(Request.GetResponse(), HttpWebResponse)
    11. DataStream = Response.GetResponseStream()
    12. Dim reader As New StreamReader(DataStream)
    13. Dim ServerResponse As String = reader.ReadToEnd()
    14. reader.Close()
    15. DataStream.Close()
    16. Response.Close()
    17. Debug.Print("Server Response Length=" & ServerResponse.Length.ToString)
    18. Debug.Print(ServerResponse & "<<<")


    Ich erhalte die Ausgabe:

    XML-Quellcode

    1. <?xml version="1.0" encoding="utf-8"?><SessionInfo><SID>0000000000000000</SID><Challenge>eae8d6c2</Challenge><BlockTime>0</BlockTime><Rights></Rights></SessionInfo>


    und da steht die Challenge drin.

    Aber allein bei diesem Coding kommen mir schon Zweifel.

    Ich brauche doch gar keinen Post ! Wenn ich den Post auf einen Nullstring kürze, kriege ich einen Fehler. Also habe ich einfach ein Blank stehen lassen. Ist das also richtig, was ich da treibe ? Wie Codiere ich denn einen GET, der keine POST Daten übergibt ?

    Wäre nett, wenn ein Fachman über meinen Code schauen könnte.

    LG
    Peter
    Hey, du hast doch hier blog.soldierer.com/wp-content/…cal_Note_-_Session_ID.pdf
    einen Beispiel Code. Es reicht GET für die Challenge.

    C#-Quellcode

    1. public string GetChallenge ()
    2. {
    3. XDocument doc = XDocument.Load(@"http://fritz.box/cgi- bin/webcm?getpage=../html/login_sid.xml");
    4. XElement info = doc.FirstNode as XElement;
    5. return info.Element("Challenge").Value;
    6. }


    C#-Quellcode

    1. public string SeiteEinlesen (string url, string sid)
    2. {
    3. Uri uri = new Uri(url + "?sid=" + sid);
    4. HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
    5. HttpWebResponse response = request.GetResponse() as HttpWebResponse;
    6. StreamReader reader = new StreamReader(response.GetResponseStream());
    7. string str = reader.ReadToEnd();
    8. return str;
    9. }


    Für die SID brauchst du dann einen POST.


    Das ist meine Signatur und sie wird wunderbar sein!
    Ich hab jetzt den Code aus dem obigen Blog nach VB umgeschrieben und mit ein paar Kommentaren versehen:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    2. 'Session ID ermitteln
    3. Dim sid As String = GetSessionId(benutzername, kennwort) '<-- enter userid and password
    4. If sid = "0000000000000000" Then
    5. Debug.Print("Login NOT successful")
    6. Exit Sub
    7. End If
    8. Debug.Print("Login successful")
    9. 'Test Session ID
    10. Dim seite As String = SeiteEinlesen("http://fritz.box/home/home.lua", sid)
    11. MessageBox.Show(seite)
    12. End Sub
    13. Public Function GetSessionId(benutzername As String, kennwort As String) As String
    14. 'Get current session ID
    15. Dim doc As XDocument = XDocument.Load("http://fritz.box/login_sid.lua")
    16. Dim sid As String = GetValue(doc, "SID")
    17. If sid = "0000000000000000" Then
    18. 'Get new Session ID
    19. Dim challenge As String = GetValue(doc, "Challenge")
    20. Dim uri As String = "http://fritz.box/login_sid.lua?username=" + _
    21. benutzername + "&response=" + GetResponse(challenge, kennwort)
    22. doc = XDocument.Load(uri)
    23. sid = GetValue(doc, "SID")
    24. End If
    25. Return sid
    26. End Function
    27. Public Function GetResponse(challenge As String, kennwort As String) As String
    28. 'Create Hash String from challenge and password
    29. Return challenge + "-" + GetMD5Hash(challenge + "-" + kennwort)
    30. End Function
    31. Public Function GetMD5Hash(input As String) As String
    32. 'Hash a string
    33. Dim md5Hasher As MD5 = MD5.Create()
    34. Dim data As Byte() = md5Hasher.ComputeHash(Encoding.Unicode.GetBytes(input))
    35. Dim sb As StringBuilder = New StringBuilder()
    36. For i As Integer = 0 To data.Count - 1
    37. sb.Append(data(i).ToString("x2"))
    38. Next
    39. Return sb.ToString()
    40. End Function
    41. Public Function GetValue(doc As XDocument, name As String) As String
    42. 'Get parameter from XML Document
    43. Dim info As XElement = CType(doc.FirstNode, XElement)
    44. Return info.Element(name).Value
    45. End Function
    46. Public Function SeiteEinlesen(url As String, sid As String) As String
    47. 'Read a page using sid
    48. Dim Uri As Uri = New Uri(url + "?sid=" + sid)
    49. Dim request As HttpWebRequest = CType(WebRequest.Create(Uri), HttpWebRequest)
    50. Dim response As HttpWebResponse = CType(request.GetResponse(), HttpWebResponse)
    51. Dim reader As StreamReader = New StreamReader(response.GetResponseStream())
    52. Dim str As String = reader.ReadToEnd()
    53. Return str
    54. End Function


    Das sieht eigentlich alles sehr vielversprechend aus. Und es läuft auch alles sauber durch, der Hash String wird korrekt gebildet ... nur die sid bleibt bei x'0000000000

    Dummerweise wird auch keine Fehlermeldung (außer meiner eigenen) angezeigt ... :(

    Ich verstehe auch nicht, welche "Userid" da verwendet werden soll. Meine Fritz!Box hat nur ein Password ! Ich hab mal die Windows Userid eingetragen ... bzw. einen Null String ... das Ergebnis bleibt das Gleiche.

    LG
    Peter

    C#-Quellcode

    1. public string GetSid (string challenge, string response)
    2. {
    3. HttpWebRequest request = WebRequest.Create(@"http://fritz.box/cgi- bin/webcm") as HttpWebRequest;
    4. request.Method = "POST";
    5. request.ContentType = "application/x-www-form-urlencoded";
    6. string parameter = String.Format(@"login:command/response={0}- {1}&getpage=../html/login_sid.xml", challenge, response);
    7. byte[] bytes = Encoding.ASCII.GetBytes(parameter);
    8. request.ContentLength = bytes.Length; Stream stream = request.GetRequestStream();
    9. stream.Write(bytes, 0, bytes.Length);
    10. stream.Close();
    11. HttpWebResponse wr = request.GetResponse() as HttpWebResponse;
    12. StreamReader reader = new StreamReader(wr.GetResponseStream());
    13. string str = reader.ReadToEnd();
    14. XDocument doc = XDocument.Parse(str);
    15. XElement info = doc.FirstNode as XElement;
    16. return info.Element("SID").Value;
    17. }


    seh ich bei dir nicht..
    Das ist meine Signatur und sie wird wunderbar sein!
    Jetzt verstehe ich, was du meinst:

    Beispiel-Code für den Bezug einer Session-ID Firmware-Version xx.04.74

    Bei mir wird aber ein anderes Verfahren verlangt:

    Beispiel-Code für den Bezug einer Session-ID ab FRITZ!OS 5.50

    Meine Fritz!Box ist nämlich auf Version 6.30

    [edit]

    Mein Coding läuft jetzt ohne jede Änderung! Yehey!

    Ich kann mir das nur so erklären, dass die Kiste aufgrund der vielen Fehlversuche den Zugang temporär gesperrt hat.

    Die Angabe des Users hat in meinem Fall keine Bedeutung. Das kann auf anderen Fritz!Box Geräten sicherlich anders sein !

    Das Logout funktioniert übrigens auch.

    VB.NET-Quellcode

    1. Dim uri As String = "http://fritz.box/login_sid.lua?logout=" + "&sid=" + sid
    2. Dim doc As XDocument = XDocument.Load(uri)


    Ich bin begeistert.

    Herzlichen Dank! Ohne eure Unterstützung hätte ich das NIE hinbekommen!

    LG
    Peter

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „Peter329“ ()