daisho
SHODAN
|
Wollte nur mal Fragen ob jemand sowas schon im Einsatz hat, wenn nicht dann nicht (Google bedienen kann ich selber auch ). Geht prinzipiell darum dass ich permanent/regelmäßig aus der LTE/5G Verbindung rausgeschmissen werde wenn ich viel Traffic verursache (Fullspeed-Download, ev. auch Upload), aber leider so dass die Verbindung zwischen Modem und Mast/Provider weiterbesteht, aber auf der Ebene darüber nichts mehr geht (keinerlei TCP Verbindung irgendwo hin möglich, die Provider-Seite läuft allerdings im Sausebraus ). Ich hatte das interessanterweise auch bei Magenta als Provider früher genauso So oder so, ich brauche ein Script das optimalerweise auf meinem Windows Server (Linux geht theoretisch auch, Windows wäre mir lieber) läuft und regelmäßig Connectivity überprüft und im Problemfall auf die FritzBox geht (falls das über API geht wäre das natürlich besser als irgendein interaktives Script) und dort einen Reconnect auslöst.
|
spunz
Super ModeratorSuper Moderator
|
|
Viper780
Er ist tot, Jim!
|
|
daisho
SHODAN
|
Die meisten Skripte inklusive von JDownloader laufen scheinbar nicht mehr oder aus irgendeinem Grund nicht auf meiner Box. Der Service und Action urn:schemas-upnp-org:service: WANIPConnection:1#ForceTermination findet man überall, liefert aber nur Fehler zurück, obwohl die auch so in der fritz.box/tr64desc.xml so gelistet sind. Das Carsten Script nutzt jetzt eine andere URL und Service-Name: http://fritz.box:49000/igd2upnp/control/WANIPConn1urn:schemas-upnp-org:service:WANIPConn ection:2#ForceTermination Das "funktioniert" interessanterweise (unter Anführungszeichen, komme später dazu). Es gibt auch ein PIP Package FritzConnection welches sehr angenehm zu benutzen ist ( https://fritzconnection.readthedocs...ng_started.html), Initialisierung dauert allerdings etwas lang (liest da die komplette Box aus denke ich) deswegen ist das Carsten Script einfach performanter. Mein Problem hat sich dadurch leider nicht gelöst. Im Event Log der Box sehe ich zwar: 03.12.23 23:59:16 Internet connection established successfully. IP address: 11.222.333.444, DNS server: 22.33.44.55 and 22.33.44.55, gateway: -
03.12.23 23:59:16 Internet connection cleared.
Aber das passiert quasi "instant" (ohne Unterbrechung bei regelmäßigen Pings z.B.) und ändert nichts an einer Problemsituation. Es löst bei mir nicht die Mobile LTE/5G Connection und sucht neu, was bei einem Druck auf den "Reconnect" Button in der UI passiert. Dann sieht das üblicherweise so aus: 04.12.23 07:21:32 Internet connection established successfully. IP address: 11.222.333.444, DNS server: 22.33.44.55 and 22.33.44.55, gateway: -
04.12.23 07:21:32 Mobile network connection established (75000/75000 kbit/s).
04.12.23 07:21:32 Connecting to mobile network...
04.12.23 07:21:32 Mobile network found.
04.12.23 07:21:31 Search for mobile networks in range.
04.12.23 07:20:59 Internet connection cleared.
04.12.23 07:20:51 Login to the FRITZ!Box user interface from the IP address X.X.X.X.
Werde mal den Entwicklungssupport bei AVM anschreiben ob die mir helfen können, hier in den API Beschreibungen habe ich leider keine Funktion gesehen die mich Mobile Provider neu suchen lässt o.Ä. (dafür kann ich PIN/PUK setzen o.Ä.).
|
daisho
SHODAN
|
Schade Der TR064 Service WANIPConnection1 ist nur für DSL-Verbindungen funktional. WANIPConnection2 ist hingegen ein UPNP Service. Dieser nutzt einen anderen Mechanismus für den Disconnect. Der TR064 Service X_AVM-DE_WANMobileConnection1 hat bisher keine Möglichkeit der Zwangstrennung. Dieses Enhancement ist aktuell auch nicht auf der Roadmap.
Wir hoffen, dass Sie mit dieser Info weiterkommen und wünschen viel Erfolg bei Ihrem Entwicklungsprojekt. Geht dann wohl echt nur über interaktives Skript. Drei hat mir außerdem versichert dass das so bleiben wird weil es ein Sprach-SIM-Tarif ist und kein Home-Internet-Datentarif
|
mr.nice.
differential image maker
|
Es gibt Steckerleisten, die in regelmäßigen Abständen IPs pingen können und wenn etwas nicht erreichbar ist, gewisse Steckdosen aus- und einschalten können. Ich denke das würde in deinem Fall auch eine Möglichkeit sein.
|
Viper780
Er ist tot, Jim!
|
Es gibt Steckerleisten, die in regelmäßigen Abständen IPs pingen können und wenn etwas nicht erreichbar ist, gewisse Steckdosen aus- und einschalten können. Ich denke das würde in deinem Fall auch eine Möglichkeit sein. Ein nettes SmartHome Projekt mit einem Shelly
|
daisho
SHODAN
|
Das stimmt, wäre sogar super einfach zu machen (via URL Aufruf dass dann eine Aktion ausführt). Sauberer für die Uptime wäre wohl der Weg über das UI, vermute dass der Bootvorgang der Box doch etwas länger dauert als einfach nur ein Reconnect (das ist innerhalb von ein paar Sekunden wieder da). Aber AutoHotKey oder so mit Image Recognition im Skript ... bäh
|
COLOSSUS
AdministratorGNUltra
|
Exponiert das FRITZ!Box-Webinterface denn eine solche Funktion, die du per Browser ausloesen kannst? (Die die Verbindung zum APN wiederherstellt, oder das LTE-Modem rebootet?) Wenn ja, dann kann man das auch Headless scripten - die Frage ist lediglich, wie muehsam es (auch je nach Wahl des Toolings) wird. Vielleicht hat man im Dunstkreis von Freetz(-NG) auch eine Loesung fuer dein Problem parat -> https://freetz-ng.github.io/freetz-ng/Ich wuerde jedenfalls davon ausgehen, dass auch die Embedded-FW auf deiner Fritzbox entweder via Hayes/AT Command Set und/oder QMI mit dem LTE-Modem spricht, und man, das Wissen um das richtige Kommando vorausgesetzt, das mit Shell-Zugriff bzw. RCE ausloesen wird koennen, auch wenn es von keiner offiziellen API exponiert wird.
|
daisho
SHODAN
|
Custom Firmware wollte ich eigentlich nicht drauf spielen, Shell Access gibt es in der Default Firmware scheinbar mittlerweile auch nicht mehr. Die XHR Requests sind nicht so schwer zu finden: "response=4272944f63b22f0c91a4604ae4d6266c%2311e844957f2ed0c3f579ec7436ab972aafd86ad43368e981aab014e7017c1d7c&lp=&loginView=simple&username=fritz1234",
"xhr=1&sid=840a0cc9d330f675&lang=en&page=netMoni&xhrId=reconnect&disconnect=true&useajax=1&no_sidrenew=",
"xhr=1&sid=840a0cc9d330f675&logout=1&no_sidrenew=",
Natürlich: wtf ist die "response". Dr. Google fand eine Technical Note (AVM Technical Note - Session ID_EN - Nov2020.pdf) zum Login und das enthält netterweise auch ein Python Example inklusive des Handlings der Challenge-Response Authentication für ein Login. Funktioniert auch soweit und eine SID kann geholt werden. Absetzen des Reconnect Commands wird damit wohl kein Problem mehr sein. Example: #!/usr/bin/env python3
# vim: expandtab sw=4 ts=4
"""
FRITZ!OS WebGUI Login
Get a sid (session ID) via PBKDF2 based challenge response algorithm.
Fallback to MD5 if FRITZ!OS has no PBKDF2 support.
AVM 2020-09-25
"""
import sys
import hashlib
import time
import urllib.request
import urllib.parse
import xml.etree.ElementTree as ET
LOGIN_SID_ROUTE = "/login_sid.lua?version=2"
class LoginState:
def __init__(self, challenge: str, blocktime: int):
self.challenge = challenge
self.blocktime = blocktime
self.is_pbkdf2 = challenge.startswith("2$")
def get_sid(box_url: str, username: str, password: str) -> str:
""" Get a sid by solving the PBKDF2 (or MD5) challenge-response process. """
try:
state = get_login_state(box_url)
except Exception as ex:
raise Exception("failed to get challenge") from ex
if state.is_pbkdf2:
print("PBKDF2 supported")
challenge_response = calculate_pbkdf2_response(state.challenge, password)
else:
print("Falling back to MD5")
challenge_response = calculate_md5_response(state.challenge, password)
if state.blocktime > 0:
print(f"Waiting for {state.blocktime} seconds...")
time.sleep(state.blocktime)
try:
sid = send_response(box_url, username, challenge_response)
except Exception as ex:
raise Exception("failed to login") from ex
if sid == "0000000000000000":
raise Exception("wrong username or password")
return sid
def get_login_state(box_url: str) -> LoginState:
""" Get login state from FRITZ!Box using login_sid.lua?version=2 """
url = box_url + LOGIN_SID_ROUTE
http_response = urllib.request.urlopen(url)
xml = ET.fromstring(http_response.read())
# print(f"xml: {xml}")
challenge = xml.find("Challenge").text
blocktime = int(xml.find("BlockTime").text)
return LoginState(challenge, blocktime)
def calculate_pbkdf2_response(challenge: str, password: str) -> str:
""" Calculate the response for a given challenge via PBKDF2 """
challenge_parts = challenge.split("$")
# Extract all necessary values encoded into the challenge
iter1 = int(challenge_parts[1])
salt1 = bytes.fromhex(challenge_parts[2])
iter2 = int(challenge_parts[3])
salt2 = bytes.fromhex(challenge_parts[4])
# Hash twice, once with static salt...
hash1 = hashlib.pbkdf2_hmac("sha256", password.encode(), salt1, iter1)
# Once with dynamic salt.
hash2 = hashlib.pbkdf2_hmac("sha256", hash1, salt2, iter2)
return f"{challenge_parts[4]}${hash2.hex()}"
def calculate_md5_response(challenge: str, password: str) -> str:
""" Calculate the response for a challenge using legacy MD5 """
response = challenge + "-" + password
# the legacy response needs utf_16_le encoding
response = response.encode("utf_16_le")
md5_sum = hashlib.md5()
md5_sum.update(response)
response = challenge + "-" + md5_sum.hexdigest()
return response
def send_response(box_url: str, username: str, challenge_response: str) -> str:
""" Send the response and return the parsed sid. raises an Exception on error """
# Build response params
post_data_dict = {"username": username, "response": challenge_response}
post_data = urllib.parse.urlencode(post_data_dict).encode()
headers = {"Content-Type": "application/x-www-form-urlencoded"}
url = box_url + LOGIN_SID_ROUTE
# Send response
http_request = urllib.request.Request(url, post_data, headers)
http_response = urllib.request.urlopen(http_request)
# Parse SID from resulting XML.
xml = ET.fromstring(http_response.read())
return xml.find("SID").text
def main():
if len(sys.argv) < 4:
print(
f"Usage: {sys.argv[0]} [url]http://fritz.box[/url] user pass"
)
exit(1)
url = sys.argv[1]
username = sys.argv[2]
password = sys.argv[3]
sid = get_sid(url, username, password)
print(f"Successful login for user: {username}")
print(f"sid: {sid}")
if __name__ == "__main__":
main()
|
spunz
Super ModeratorSuper Moderator
|
|
Viper780
Er ist tot, Jim!
|
TR064 ist aber nur für DSL nicht für 5G
|
spunz
Super ModeratorSuper Moderator
|
TR064 ist aber nur für DSL nicht für 5G Das hindert AVM nicht daran auch weitere Funktionen einzubauen. Von der Zigbee Lampe, Wlan Konfig, Anrufbeantworter bis zum NAS Server ist ja alles mit dabei. Man hat es schlicht und einfach nicht auf der Roadmap, siehe auch dem Kommentar von AVM weiter oben.
|
daisho
SHODAN
|
Keine Tragödie. Problem ist auf meiner Seite quasi solved. Hab es mit Postman gerade getestet, mit dem Skript oben einfach SID holen und mit Postman dann einen einfachen POST Request absetzen: http://fritz.box/data.lua
Parameter:
xhr = 1
sid = {{sid}}
lang = en
page = netMoni
xhrId = reconnect
disconnect = true
useajax = 1
no_sidrenew =
Fetzt 1A Muss das jetzt nur noch ins Python-Skript einbauen, davor einen Ping-Check auf Google.at o.Ä. setzen damit das Skript weiß wann es die Connection killen soll voila. Mal schauen ob ich am Wochenende dazu komme, jetzt um Weihnachten hat das nicht so hohe Priorität
|
RoboByte
Bloody Newbie
|
@daisho hast du den Python-Script schon fertig?
Ich suche auch so einen Reconnect-Script. Würde den gern automatisch jeden Tag über mein NAS starten (z.B. Linux/Cronjobs).
|