String in UTF 16

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
masterholdy
User
Beiträge: 11
Registriert: Montag 15. Juni 2015, 18:06

Hi,
ich wollte mir ein Programm bauen mit dem ich das Wlan meiner Fritzbox an/aus machen kann und den Status des Wlanes (an / aus) auslesen kann.

Nun ist das Problem das nicht einfach nur das Password gepostet wird und man sich einloggen kann,
AVM hat sich ein System ausgedacht beim Besuch der Seite fritz.box erhält man einen Challenge String.
Den Challengestr und das eingegebene Password werden in UTF-16 verwandelt, rechnet man challengestr(UTF 16 ) - pw(UTF 16 )
macht daraus ein md5 hash und dann rechnet man challengestr - md5 das ist der response der wird dann an die fb gesendet wenn er stimmt wird man eingeloggt.

Die Frage ist jetzt wie ich aus einem String ein UTF-16. machen kann und daraus wieder ein MD5 Hash.

MFG
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@masterholdy: dafür gibt es "encode":

Code: Alles auswählen

>>> hashlib.md5("Password".encode('utf-16le')).hexdigest()
'fcd9449df6e7e5adaa69b9cf32860e14'
BlackJack

@masterholdy: Man muss den String, falls es sich nicht bereits um ein Unicode-Objekt handelt von einem Bytestring in ein Unicode-Objekt dekodieren — dazu muss man die Kodierung der Bytes kennen! — und dann das Unicode-Objekt in UTF-16 kodierte Bytes. Eventuell mit „byte order mark“ (BOM) und man muss natürlich auch wissen — ob mit oder ohne BOM — in welcher Reihenfolge die Bytes pro 16-Bit-Wert vorliegen müssen.

Für MD5-Hashes gibt es in der Python-Standardbibliothek das `hashlib`-Modul.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@masterholdy
Hängt davon ab, ob Du Python 2 oder 3 und welches encoding Du verwendest. Ich gehe jetzt mal von 'UTF8' als encoding aus:

Unter Python 2 musst Du den String erstmal von UTF8 zu unicode und dann zu UTF16 codieren:

Code: Alles auswählen

>>> 'any_string'.decode('utf8').encode('utf16')
Unter Python 3 ist ein String bereits unicode:

Code: Alles auswählen

>>> 'any_string'.encode('utf16')
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
masterholdy
User
Beiträge: 11
Registriert: Montag 15. Juni 2015, 18:06

danke leute!:)
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

masterholdy hat geschrieben:ich wollte mir ein Programm bauen mit dem ich das Wlan meiner Fritzbox an/aus machen kann und den Status des Wlanes (an / aus) auslesen kann.
Da will ich mal ganz selbstlos den folgenden Link in den Raum werfen: https://bitbucket.org/kbr/fritzconnection/
Wenn Du den entsprechenden Service und die Action kennst, dann geht das damit.
masterholdy
User
Beiträge: 11
Registriert: Montag 15. Juni 2015, 18:06

kbr hat geschrieben:
masterholdy hat geschrieben:ich wollte mir ein Programm bauen mit dem ich das Wlan meiner Fritzbox an/aus machen kann und den Status des Wlanes (an / aus) auslesen kann.
Da will ich mal ganz selbstlos den folgenden Link in den Raum werfen: https://bitbucket.org/kbr/fritzconnection/
Wenn Du den entsprechenden Service und die Action kennst, dann geht das damit.
könntest du mir den vllt sagen wie es ab hier weitergeht? wie sieht den ein post hier aus? oder hatte ich vorher schon ein fehler?

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-
import urllib.parse,urllib.error,urllib.request,re,hashlib,urllib

url = 'http://192.168.178.1'
pw = 'xxx'

fb = urllib.request.urlopen(url + "/login_sid.lua")
fbstring = fb.read().decode('utf-8')
challengestr = re.search(r'<Challenge>(.*)</\Challenge>', fbstring, re.M|re.I).group(1)
challengestr = challengestr+"-"+pw
response = hashlib.md5(challengestr.encode('utf-16le')).hexdigest()

values = {'response' : response
          'page': ''
          'username' : ''}
data = urllib.parse.urlencode(values)
data = data.encode('utf-8') 
post = urllib.request.urlopen(url + "/login_sid.lua", data)
a=post.readall()
fb.close()
print(a)
Ich erhalte hier leider immernoch keine SSID ausgegeben
masterholdy
User
Beiträge: 11
Registriert: Montag 15. Juni 2015, 18:06

ok ich habe die login session nachgebaut, jetzt ist die frage ob es eine einfachere varriante gibt zu entscheiden ob das wlan an oder aus ist als regexp
##an = name="active" checked>&nbsp;<label for="uiView_Active">WLAN-Funknetz aktiv
##aus= name="active" >&nbsp;<label for="uiView_Active">WLAN-Funknetz aktiv
MFG
BlackJack

@masterholdy: Ich würde ja HTML mit einer passenden Bibliothek verarbeiten (BeautifulSoup4 oder lxml.html) und nicht mit regulären Ausdrücken.
masterholdy
User
Beiträge: 11
Registriert: Montag 15. Juni 2015, 18:06

wie würde das den mit lxml aussehen?
BlackJack

@masterholdy: Man würde das parsen lassen, dann das <label>-Element mit dem Attribut ``for`` suchen das den Wert 'uiView_Active' hat, und dort dann den Text aus dem Element auswerten.
masterholdy
User
Beiträge: 11
Registriert: Montag 15. Juni 2015, 18:06

ok danke! ich setzte mich jetztt mal daran das wlan an / aus zumachem :)

wie kann ich das denn machen das man beim starten des scripts per terminal sich aussicht welche funktion man startet und kann ich dort dann ein parameter mit geben?
ich hätte gerne so etwas in richtung von datei.py - status, datei.py - wlan 0,datei.py - wlan 1
mit status geht er in mein def status(): mit wlan in die wlan funktion und gibt dort entweder 1 oder 2 weiter
BlackJack

@masterholdy: Die Kommandozeilenargumente kann man über `sys.argv` bekommen und in der Standardbibliothek gibt es das `argparse`-Modul um die Auswertung davon zu vereinfachen und so zu gestalten wie der Benutzer das üblicherweise erwartet. Als externe Bibliothek könntest Du Dir das `click`-Modul anschauen.
masterholdy
User
Beiträge: 11
Registriert: Montag 15. Juni 2015, 18:06

also status funktioniert könnte mir jemand den fehler beim wlanon/off sagen? das mit dem post will nicht so
falls der response am ende von wlanon/off für jmd. wichtig ist es kommt beide male <function wlanoff at 0x07751E86>

Code: Alles auswählen

import urllib.parse,urllib.error,urllib.request,re,hashlib,urllib,sys

url = 'http://192.168.178.1'
pw = 'pw'
SSID = 'ssid'
headers = {}
headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.81 Safari/537.36'
try:
    commandarg = sys.argv[1]
except Exception as ce:
   commandarg = 100 
    
def login():
    try:

        req = urllib.request.Request(url + "/login_sid.lua", headers=headers)
        resp = urllib.request.urlopen(req)
        respData = resp.read()
        challengereg = re.search(r'<Challenge>(.*)</\Challenge>', respData.decode('utf-8'), re.M|re.I).group(1)
        challengestr = challengereg+"-"+pw
        responsehash = hashlib.md5(challengestr.encode('utf-16le')).hexdigest()
        response = challengereg+"-"+responsehash

        values = {'response' : response,'page': '','username' : ''}
        data = urllib.parse.urlencode(values)
        data = data.encode('utf-8') 
        post = urllib.request.Request(url + "/login_sid.lua",data,headers)
        resp = urllib.request.urlopen(post)
        respData = resp.read()
        sidreg = re.search(r'<SID>(.*)</SID>', respData.decode('utf-8'), re.M|re.I).group(1)
        return(sidreg)
    except Exception as e:
        print(str(e))
        return("Login failed")

def status():
    
    get = urllib.request.Request(url + "/wlan/wlan_settings.lua?sid="+login())
    fbpageresp = urllib.request.urlopen(get)
    fbrespData = fbpageresp.read()

    if 'name="active" checked>&nbsp;<label for="uiView_Active">WLAN-Funknetz aktiv' in  fbrespData.decode('UTF-8'):
        print("W-Lan an!")
    elif 'name="active" >&nbsp;<label for="uiView_Active">WLAN-Funknetz aktiv':
        print("W-Lan aus!")
    else:
        print("Fehler")

def wlan(userinput):
    if userinput == 0:
        wlanoff()
    elif userinput == 1:
        wlanon()
    else:
        print("error")

def wlanoff():
    sid=login()
    get = urllib.request.Request(url + "/wlan/wlan_settings.lua?sid="+sid)
    values = {'sid' : sid,'print:': '','validate:': 'apply','xhr:': '1'}
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8') 
    post = urllib.request.Request(url + "/login_sid.lua",data,headers)
    resp = urllib.request.urlopen(post)
    print(resp)

def wlanon():
    sid=login()
    get = urllib.request.Request(url + "/wlan/wlan_settings.lua?sid="+sid)
    values = {'active' : 'on','SSID:': SSID,'hidden_ssid:': 'on','sid:': sid,'print:': '','validate:':'apply','xhr':'1'}
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8') 
    post = urllib.request.Request(url + "/login_sid.lua",data,headers)
    resp = urllib.request.urlopen(post)
    print(resp)

def main():
    if commandarg == "wlan0":
        wlanoff()
    elif commandarg == "wlan1":
        wlanon()
    elif commandarg == "status":
        status()
    else:
        print("wrong input")
main()

edit:// oder könnte man ein telefon simulieren was dan "#96*0*" für wlan aus sendet und #96*1* für an?
edit-edit:// habe das nochmal mitgeschnitten und habe jetzt erst gesehen das es pro an / aus machen 2 posts gibt einen type document ein xhr einmal ist der initator other einmal ajax.js:139 sagt das jmd. was?

hier die pots:

#an machen
active=on&SSID=meinessid&hidden_ssid=on&sid=dfda492d6f2a56ae&apply= | initator = other | type = document
active=on&SSID=meinessid&hidden_ssid=on&sid=dfda492d6f2a56ae&print=&validate=apply&xhr=1 | initator = ajax.js:139 | type = xhr

#aus machen
sid=dfda492d6f2a56ae&apply= | other
sid=dfda492d6f2a56ae&print=&validate=apply&xhr=1 | ajax
masterholdy
User
Beiträge: 11
Registriert: Montag 15. Juni 2015, 18:06

habe das zum anmachen prbiert aber erhalte tons of errors

Code: Alles auswählen

def wlanon():
    sid=login()
    headers = {
    'Origin': url,
    'Accept-Encoding': 'gzip, deflate',
    'Accept-Language': 'de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4',
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.81 Safari/537.36',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Accept': '*/*',
    'Referer': url+'/wlan/wlan_settings.lua?sid='+sid,
    'Connection': 'keep-alive',
    }

    data = 'active=on&SSID='+SSID+'&hidden_ssid=on&sid='+sid+'&print=&validate=apply&xhr=1'
    requests.post(url+'/wlan/wlan_settings.lua?sid='+sid, headers=headers, data=data)
masterholdy
User
Beiträge: 11
Registriert: Montag 15. Juni 2015, 18:06

kann geclosed werden der fehler war das google chrome die sachen nicht richtig mit geschnitten hat mit firefox habe ich direkt die richtigen daten mitgeschnitten bekommen :c
Antworten