From 0728ad61ff7f44a75cb40d424320705274583be5 Mon Sep 17 00:00:00 2001 From: octospacc Date: Mon, 2 Oct 2023 21:45:09 +0200 Subject: [PATCH] Add Vodafone station web hacks, upd TPLink hacks --- ...Hacks.user.js => TP-Link Web Hacks.user.js | 20 ++-- Vodafone Station Revolution Web Hacks.user.js | 111 ++++++++++++++++++ WebMetaPreviewProxy.py | 46 +++++--- 3 files changed, 153 insertions(+), 24 deletions(-) rename TP-Link Hacks.user.js => TP-Link Web Hacks.user.js (81%) create mode 100644 Vodafone Station Revolution Web Hacks.user.js diff --git a/TP-Link Hacks.user.js b/TP-Link Web Hacks.user.js similarity index 81% rename from TP-Link Hacks.user.js rename to TP-Link Web Hacks.user.js index a020548..0943090 100644 --- a/TP-Link Hacks.user.js +++ b/TP-Link Web Hacks.user.js @@ -1,7 +1,7 @@ // ==UserScript== -// @name TP-Link Hacks -// @description Let's hack some useful features into the TP-Link WebUI! -// @version 1.0 +// @name TP-Link Web Hacks +// @description Let's hack some useful features into the TP-Link WebUI! (Tested on AC750 RE200) +// @version 1.1 // @author OctoSpacc // @namespace https://octt.eu.org // @match http://192.168.*.*/* @@ -13,14 +13,14 @@ (function(){ GM_setValue('Password', GM_getValue('Password', 'admin')); -GM_setValue('IPs', GM_getValue('IPs', [])); +GM_setValue('IPs', GM_getValue('IPs', [])); var Ips = GM_getValue('IPs'); var IsPageAllowed = (Ips.length == 0 || (Ips.length > 0 && Ips.includes(location.hostname))); if (IsPageAllowed) { // Note: localStorage is reset on new login and isn't reliable, we must use sessionStorage - var Opts = new URLSearchParams(location.hash.toLowerCase()).get('tplinkhacks'); + var Opts = new URLSearchParams(location.hash.toLowerCase()).get('tplinkwebhacks'); if (Opts !== null) { sessionStorage.setItem('HacksPrevOpts', Opts); } else { @@ -50,11 +50,11 @@ if (IsPageAllowed) { }; function AfterCmd() { - console.log('[TP-Link Hacks] Command completed.'); + console.log('[TP-Link Web Hacks] Command completed.'); if (Opts.closeafter) { var Wait = 5000; - console.log(`[TP-Link Hacks] CloseAfter was specified. The page will close itself in ${Wait/1000} seconds.`); - setTimeout(function(){ window.close(); }, 5000); + console.log(`[TP-Link Web Hacks] CloseAfter was specified. The page will close itself in ${Wait/1000} seconds.`); + setTimeout(function(){ window.close(); }, Wait); }; }; @@ -83,7 +83,7 @@ if (IsPageAllowed) { function Main() { if (Opts && Opts.cmd) { - console.log(`[TP-Link Hacks] Trying to call command: ${Opts.cmd}.`); + console.log(`[TP-Link Web Hacks] Trying to call command: ${Opts.cmd}.`); ReLogin(); switch (Opts.cmd.toLowerCase()) { case 'reboot': Reboot(); break; @@ -98,6 +98,6 @@ if (IsPageAllowed) { }); } else { - console.log('[TP-Link Hacks] Script matched this page but the IP whitelist check is negative. Stopping.'); + console.log('[TP-Link Web Hacks] Script matched this page but the IP whitelist check is negative. Stopping.'); }; })(); diff --git a/Vodafone Station Revolution Web Hacks.user.js b/Vodafone Station Revolution Web Hacks.user.js new file mode 100644 index 0000000..5d0ae49 --- /dev/null +++ b/Vodafone Station Revolution Web Hacks.user.js @@ -0,0 +1,111 @@ +// ==UserScript== +// @name Vodafone Station Revolution Web Hacks +// @description Let's hack some useful features into the Vodafone Station Revolution WebUI! +// @version 1.0 +// @author OctoSpacc +// @namespace https://octt.eu.org +// @match http://192.168.*.*/* +// @match http://vodafone.station/* +// @grant GM_getValue +// @grant GM_setValue +// @grant window.close +// ==/UserScript== + +(function(){ +GM_setValue('Password', GM_getValue('Password', 'admin')); +GM_setValue('IPs', GM_getValue('IPs', [])); + +var Ips = GM_getValue('IPs'); +var IsPageAllowed = (Ips.length == 0 || (Ips.length > 0 && Ips.includes(location.hostname))); + +if (IsPageAllowed) { + // Note: localStorage is reset on new login and isn't reliable, we must use sessionStorage + var Opts = new URLSearchParams(location.hash.toLowerCase()).get('vodafonestationwebhacks'); + if (Opts !== null) { + sessionStorage.setItem('HacksPrevOpts', Opts); + } else { + Opts = sessionStorage.getItem('HacksPrevOpts'); + sessionStorage.removeItem('HacksPrevOpts'); + }; + Opts = JSON.parse(Opts); + + function qs(Query) { + return document.querySelector(Query); + }; + + function WaitTill(Cond, Fun) { + var Intv = setInterval(function(){ + if (Cond()) { + clearInterval(Intv); + Fun(); + }; + }, 100); + }; + + function WaitElClick(Query, Fun) { + WaitTill(function(){ return qs(Query); }, function(){ + qs(Query).click(); + if (Fun) Fun(); + }); + }; + + function AfterCmd() { + console.log('[Vodafone Station Revolution Web Hacks] Command completed.'); + if (Opts.closeafter) { + var Wait = 7500; + console.log(`[Vodafone Station Revolution Web Hacks] CloseAfter was specified. The page will close itself in ${Wait/1000} seconds.`); + setTimeout(function(){ window.close(); }, Wait); + }; + }; + + function ReLogin() { + WaitTill(function(){ return qs('input#login_Password'); }, function(){ + qs('input#login_Password').value = GM_getValue('Password'); + WaitElClick('#btn_login'); + }); + }; + + function ExpertMode() { + WaitElClick('#modeSelectorOptions *[data-val="Expert"]'); + }; + + function Reboot() { + setTimeout(function(){ + location.hash = '#cat=status-and-support_restart'; + WaitElClick('#btn_restart', function(){ + WaitElClick('#popUp_RestartConfirmationMessage_Button_Apply', function(){ + AfterCmd(); + }); }); + }, 1500); + }; + + function OpenLogs() { + setTimeout(function(){ + location.hash = '#cat=status-and-support_event-log'; + WaitElClick('#navigator *[navi-value="sysLog"] a', function(){ + AfterCmd(); + }); + }, 1500); + }; + + function Main() { + if (Opts && Opts.cmd) { + console.log(`[Vodafone Station Revolution Web Hacks] Trying to call command: ${Opts.cmd}.`); + ReLogin(); + ExpertMode(); + switch (Opts.cmd.toLowerCase()) { + case 'reboot': Reboot(); break; + case 'openlogs': OpenLogs(); break; + }; + }; + }; + + window.addEventListener('load', function(){ + // Wait a bit for the WebUI to settle down, accounting for slow machines/connections + setTimeout(Main, 1500); + }); + +} else { + console.log('[Vodafone Station Revolution Web Hacks] Script matched this page but the IP whitelist check is negative. Stopping.'); +}; +})(); diff --git a/WebMetaPreviewProxy.py b/WebMetaPreviewProxy.py index 736c165..fd1067f 100755 --- a/WebMetaPreviewProxy.py +++ b/WebMetaPreviewProxy.py @@ -10,15 +10,19 @@ from bs4 import BeautifulSoup # | Configuration | # # *--------------------* # Host = ('localhost', 8080) -Debug = False +Debug = True # *--------------------* # -# Don't let the Zuck know this is a bot -UserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.59' +# Must be stealth about this since there are some nasty servers in the world! (Zuck, Musk, ...) +ProxyHeaders = { + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36", + "Sec-Fetch-Site": "same-origin", +} AppMeta = { + "SiteName": "Web Meta Preview Proxy", "Title": "Web Meta Preview Proxy", - "Description": "A simple way to live.", + "Description": "HTML metadata provided in a proxied and paginated form.", } # @@ -30,7 +34,7 @@ class Handler(BaseHTTPRequestHandler): Res = {} Url = self.path[1:] try: - Req = urlopen(Request(Url, headers={"User-Agent": UserAgent})) + Req = urlopen(Request(Url, headers=ProxyHeaders)) Res['Code'] = 200 Res['Body'] = MakePage(Code=Req.code, Url=Url, Meta=HtmlToMeta(Req.read().decode())) except (HTTPError, URLError) as e: @@ -86,9 +90,15 @@ def MakePage(Meta:dict=None, Code:int=None, Url:str=None): {MetaToHtmlHead(ContextAppMeta(Meta))} @@ -100,7 +110,7 @@ def MakePage(Meta:dict=None, Code:int=None, Url:str=None): --> -

Proxied URL: {Url}

+

Proxied URL: {Url}

Proxied HTTP Response: {Code}

{MetaToHtmlBody(Meta) if Meta else '

Could not retrieve any metadata from the requested URL.

'}

@@ -113,24 +123,30 @@ def ContextAppMeta(Meta:dict=None): #New = DictJoin(AppMeta, Meta) New = dict(AppMeta) if Meta: - if Meta['Title']: New['Title'] = f"{Meta['Title']} | {AppMeta['Title']}" - if Meta['Description']: New['Description'] = Meta['Description'] + if Meta['SiteName']: New['SiteName'] = f"{Meta['SiteName']} | {AppMeta['SiteName']}" + if Meta['Title']: New['Title'] = f"{Meta['Title']} | {AppMeta['Title']}" + if Meta['Description']: New['Description'] = f"{Meta['Description']} | {AppMeta['Description']}" + if Meta['Image']: New['Image'] = Meta['Image'] return New def MetaToHtmlHead(Meta:dict): Meta = DictHtmlSafe(Meta) return f'''\ -{f'{Meta["Title"]}' if Meta["Title"] else ''} -{f'' if Meta["Description"] else ''} +{f'' if DictKeyIf(Meta, 'SiteName') else ''} +{f'{Meta["Title"]}' if DictKeyIf(Meta, 'Title') else ''} +{f'' if DictKeyIf(Meta, 'Description') else ''} +{f'' if DictKeyIf(Meta, 'Image') else ''} ''' def MetaToHtmlBody(Meta:dict): Meta = DictHtmlSafe(Meta) return f'''

-{f'
Title
{Meta["Title"]}
' if DictKeyIf(Meta, 'Title') else ''} -{f'
Description
{Meta["Description"]}
' if DictKeyIf(Meta, 'Description') else ''} -{f'
Image
' if DictKeyIf(Meta, 'Image') else ''} -{f'
Type
{Meta["Type"]}
' if DictKeyIf(Meta, 'Type') else ''} +{f'
Site Name
{Meta["SiteName"]}
' if DictKeyIf(Meta, 'SiteName') else ''} +{f'
Title
{Meta["Title"]}
' if DictKeyIf(Meta, 'Title') else ''} +{f'
Description
{Meta["Description"]}
' if DictKeyIf(Meta, 'Description') else ''} +{f'
Image
' if DictKeyIf(Meta, 'Image') else ''} +{f'
Type
{Meta["Type"]}
' if DictKeyIf(Meta, 'Type') else ''} +{f'
Html
{Meta["_Html_"]}
' if DictKeyIf(Meta, '_Html_') and Debug else ''}
''' def HtmlToMeta(Html:str): @@ -145,10 +161,12 @@ def HtmlToMeta(Html:str): Description = SoupAttrIf(Soup.find('meta', attrs={"name": "description"}), 'content') return { + "SiteName": SoupAttrIf(Soup.find('meta', attrs={"property": "og:site_name"}), 'content'), "Title": Title, "Description": Description, "Image": SoupAttrIf(Soup.find('meta', attrs={"property": "og:image"}), 'content'), "Type": SoupAttrIf(Soup.find('meta', attrs={"property": "og:type"}), 'content'), + "_Html_": Html, } if __name__ == '__main__':