Comment for more tool ideas!
Let's extend the FortiGate WebUI
Tested on FortiOS v7.0, 7.2
Installation:
Result:
javascript:(async function(){document.contains(document.getElementById("tools"))&&document.getElementById("tools").remove();let e="_cliWS",t="",s=["get system status","get system global","get system settings"],l=["get system arp","diag ip arp list"],n=window[e],i=!1,r;function a(e){n.send(`${e}\r`)}function o(e,t){let s=document.querySelector(`table[data-command="${r}"]`);if(s)switch(t){case"arp_cmd1":let[l,n,i,a]=e.replace(/\s+/g," ").split(" ");s.innerHTML+=`<tr><td style="border:1px solid grey;">${l}</td><td style="border:1px solid grey;text-align:center">${n}</td><td style="border:1px solid grey;text-align:center">${i}</td><td style="border:1px solid grey;text-align:center">${a}</td></tr>`;break;case"arp_cmd2":let[o,d,c,$,p,y,g,_,f]=e.replace(/\s+/g," ").split(" ");p=p.replace("00000000",'<span title="Pseudo state used while an ARP entry is initially created or just before it is removed"><f-icon class="fa-connected"></f-icon> NONE<span>'),p=p.replace("00000001",'<span title="First ARP request sent"><f-icon class="fa-connected"></f-icon> INCOMPLETE</span>'),p=p.replace("00000002",'<span title="ARP response is received"><f-icon class="fa-connected"></f-icon> REACHABLE</span>'),p=p.replace("00000004",'<span title="ARP response is not received within expected time"><f-icon class="fa-custom-action"></f-icon> STALE</span>'),p=p.replace("00000008",'<span title="Schedule ARP request"><f-icon class="fa-clock-plus"></f-icon> DELAY</span>'),p=p.replace("00000010",'<span title="Actively sending ARP requests to try and resolve the address"><f-icon class="fa-clock-plus"></f-icon> PROBE</span>'),p=p.replace("00000020",'<span title="Not managed to resolve ARP within max configured number of probes"><f-icon class="fa-cancel"></f-icon> FAILED</span>'),p=p.replace("00000040",'<span title="Device does not support ARP e.g. IPsec Interface"><f-icon class="fa-dismiss"></f-icon> NOARP</span>'),p=p.replace("00000080",'<span title="Statically configured ARP entry">PERMANENT</span>'),s.innerHTML+=`<tr><td style="border:1px solid grey;text-align:center">${d.substring(d.indexOf("=")+1)}</td><td style="border:1px solid grey">${c}</td><td style="border:1px solid grey;text-align:center">${$}</td><td style="border:1px solid grey">${p.substring(p.indexOf("=")+1)}</td><td style="border:1px solid grey;text-align:center">${y.substring(y.indexOf("=")+1)}</td><td style="border:1px solid grey;text-align:center">${g.substring(g.indexOf("=")+1)}</td><td style="border:1px solid grey;text-align:center">${_.substring(_.indexOf("=")+1)}</td><td style="border:1px solid grey;text-align:center">${f.substring(f.indexOf("=")+1)}</td></tr>`;break;default:let[m,b]=e.split(/:(.*)/s);b=b.replace(/[dD]isable/g,'<f-icon class="fa-disabled"></f-icon> <span style="color:silver">Disabled</span>'),b=b.replace(/[nN]ot [aV]vailable/g,'<f-icon class="fa-disabled"></f-icon> <span style="color:silver">Not available</span>'),b=b.replace(/[eE]nable/g,'<f-icon class="fa-enabled"></f-icon> <span>Enabled</span>'),b=b.replace(/[cC]ertified/g,'<f-icon class="fa-enabled"></f-icon> <span>Certified</span>'),s.innerHTML+=`<tr><td style="border: 1px solid grey;">${m}</td><td style="border: 1px solid grey;">${b}</td></tr>`}else{switch((s=document.createElement("table")).dataset.command=r,s.dataset.active="active",s.style.margin="1rem",t){case"arp_cmd1":s.innerHTML='<tr><th style="border:1px solid grey;text-align:left">IP Address</th><th style="border:1px solid grey">Age(min)</th><th style="border:1px solid grey">MAC Address</th><th style="border:1px solid grey">Interface</th></tr>';break;case"arp_cmd2":s.innerHTML='<tr><th style="border:1px solid grey">Interface</th><th style="border:1px solid grey;text-align:left">IP Address</th><th style="border:1px solid grey">MAC Address</th><th style="border:1px solid grey;text-align:left">Status</th><th style="border:1px solid grey">Use</th><th style="border:1px solid grey">Confirm</th><th style="border:1px solid grey">Update</th><th style="border:1px solid grey">Ref</th></tr>';break;default:s.innerHTML='<tr><th style="border:1px solid grey;">Key</th><th style="border:1px solid grey;">Value</th></tr>'}let x=document.querySelector(`li[data-command="${r}"]`);!function e(t,s){s.parentNode.insertBefore(t,s.nextSibling)}(s,x)}}let d="";async function c(e){let s=await e.data.text();if(i){let l="";for(let n in s){let r=s[n];"\r"===l?"\n"===r&&d.length>0?(o(d,t),d=""):"\0"===r&&(d=""):"\r"!==r&&(d+=r),l=r}}else i=!0,a("")}function $(){let t="https:"===location.protocol?"wss:":"ws:",s=`${t}//${location.hostname}:${location.port}/ws/cli/open?cols=500&rows=500`;window[e]=n=new WebSocket(s),n.addEventListener("message",c),n.addEventListener("close",()=>window[e]=null)}let p=[{label:"System info",content:"",script:function(e){n||$();let l=document.createElement("ul");l.id="system-info-command-list",s.forEach(e=>{let s=document.createElement("li");s.style.marginBottom="1rem",s.style.color="green",s.style.cursor="pointer",s.dataset.command=e,s.innerHTML=` ${e}<nu-icon class="icon" style="margin-left:auto;width:18px;height:14px;transform:rotate(0deg)"><svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg" style="width: 18px; height: 18px;"><path d="m12.01 9.531-4.25 4.25a.747.747 0 0 1-1.06 0l-.706-.706a.747.747 0 0 1 0-1.06l3.012-3.012-3.012-3.012a.747.747 0 0 1 0-1.06l.703-.712a.747.747 0 0 1 1.06 0l4.25 4.25a.748.748 0 0 1 .002 1.062z"></path></svg></nu-icon>`,s.onclick=function(){if(t="sys_cmd",n){let e=this.nextSibling&&"TABLE"===this.nextSibling.nodeName?this.nextSibling:null,l=this.querySelector(".icon");if(e)"active"===e.dataset.active?(e.dataset.active="",e.style.display="none",l.style.transform="rotate(0deg)"):(e.dataset.active="active",e.style.display="block",l.style.transform="rotate(90deg)");else{i=!0;let o=s.dataset.command;a(o),r=o,l.style.transform="rotate(90deg)"}}else $()},l.appendChild(s)}),e.innerHTML="",e.style.overflow="auto",e.style.padding="1.5rem",e.appendChild(l)}},{label:"ARP info",content:"",script:function(e){n||$();let s=document.createElement("ul");s.id="system-arp-command-list",l.forEach(e=>{let l=document.createElement("li");l.style.marginBottom="1rem",l.style.color="green",l.style.cursor="pointer",l.dataset.command=e,l.innerHTML=` ${e}<nu-icon class="icon" style="margin-left:auto;width:18px;height:14px;transform:rotate(0deg)"><svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg" style="width: 18px; height: 18px;"><path d="m12.01 9.531-4.25 4.25a.747.747 0 0 1-1.06 0l-.706-.706a.747.747 0 0 1 0-1.06l3.012-3.012-3.012-3.012a.747.747 0 0 1 0-1.06l.703-.712a.747.747 0 0 1 1.06 0l4.25 4.25a.748.748 0 0 1 .002 1.062z"></path></svg></nu-icon>`,l.onclick=function(){if(t="arp_cmd1","diag"==this.innerHTML.substr(6,4)&&(t="arp_cmd2"),n){let e=this.nextSibling&&"TABLE"===this.nextSibling.nodeName?this.nextSibling:null,s=this.querySelector(".icon");if(e)"active"===e.dataset.active?(e.dataset.active="",e.style.display="none",s.style.transform="rotate(0deg)"):(e.dataset.active="active",e.style.display="block",s.style.transform="rotate(90deg)");else{i=!0;let o=l.dataset.command;a(o),r=o,s.style.transform="rotate(90deg)"}}else $()},s.appendChild(l)}),e.innerHTML="",e.style.overflow="auto",e.style.padding="1.5rem",e.appendChild(s)}}],y=document.querySelector("nu-nav-entry"),g=document.createElement("li"),_='<svg version="1.1" id="L4" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="100" viewBox="0 0 100 100" enable-background="new 0 0 0 0" xml:space="preserve"><circle fill="#555" stroke="none" cx="6" cy="50" r="6"><animate attributeName="opacity" dur="1s" values="0;1;0" repeatCount="indefinite" begin="0.1"/></circle><circle fill="#555" stroke="none" cx="26" cy="50" r="6"><animate attributeName="opacity" dur="1s" values="0;1;0" repeatCount="indefinite" begin="0.2"/></circle>circle fill="#555" stroke="none" cx="46" cy="50" r="6"><animate attributeName="opacity" dur="1s" values="0;1;0" repeatCount="indefinite" begin="0.3"/></circle></svg>';g.style.listStyle="none",g.id="tools",g.innerHTML='<div id="menu-toggle" style="color:#000;background-color:goldenrod;margin:0;padding:4px 0 1px 5px;border-left:3px solid #ffd700; display: flex;"><f-icon class="ftnt-webhook icon-lg"></f-icon> Tools<nu-icon class="icon" style="margin-left:auto;width:18px;height:18px;transform:rotate(90deg)"><svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg" style="width:18px;height:18px"><path d="m12.01 9.531-4.25 4.25a.747.747 0 0 1-1.06 0l-.706-.706a.747.747 0 0 1 0-1.06l3.012-3.012-3.012-3.012a.747.747 0 0 1 0-1.06l.703-.712a.747.747 0 0 1 1.06 0l4.25 4.25a.748.748 0 0 1 .002 1.062z"></path></svg></nu-icon></div>',y.before(g);let f=!0,m=document.createElement("ul");async function b(e){let t,s=document.getElementById("ng1-app").getElementsByTagName("div")[0];s.innerHTML=`<div style="position:relative;overflow-y:auto"><pre style="padding:1em;margin:0;display:flex"><code style="width:100%; display:flex; justify-content:center;">${_}</code></pre></div>`,t=e.content,m.querySelectorAll("li").forEach(e=>{e.style["background-color"]="#ffd700",e.style.color="black",e.dataset.active=""}),s.style.width="100%",s.innerHTML=`<div style="position:relative;overflow-y:auto"><pre style="padding:1em;margin:0;display:flex"><code style="width:100%; display:flex; justify-content:center;">${t??_}</code></pre></div>`,e.script?.(s)}m.style.margin=0,m.style.padding=0,p.forEach((e,t)=>{let s=document.createElement("li");s.innerText=e.label,s.style.listStyle="none",s.style.color="black",s.style.backgroundColor="#FFD700",s.style.margin=0,s.style.padding="6px 0 5px 35px",s.style.cursor="pointer",s.style.fontWeight="normal",s.onmouseover=function(){this.style["background-color"]="#FFE86D"},s.onmouseout=function(){"active"!==this.dataset.active&&(this.style["background-color"]="#FFD700"),s.onclick=async function(){this.dataset.active="active",await b(e)}},m.appendChild(s)});let x=document.querySelector("#tools #menu-toggle"),u=x.querySelector(".icon");x.after(m),x.onclick=()=>{f?(m.style.display="none",u.style.transform="rotate(0deg)",f=!1):(m.style.display="block",u.style.transform="rotate(90deg)",f=!0)}})();
Roadmap (planned):
How to do this?
Created on 05-23-2023 03:09 AM Edited on 05-23-2023 03:15 AM
Simply copy the JavaScript code into a new bookmark and click it to load the Tools menu.
Can you share the steps to access this? How to edit the URL with javascript you shared?
The Fortinet Security Fabric brings together the concepts of convergence and consolidation to provide comprehensive cybersecurity protection for all users, devices, and applications and across all network edges.
Copyright 2023 Fortinet, Inc. All Rights Reserved.