I am trying to create a website that has links and depending on those links it will load putty with an ssh connection to a specific host. ( this is to be used internally and ie 6)
so far i have ignore the host
<script language="javascript">
function connection(host) {
oShell = new ActiveXObject("Wscript.Shell");
oShell.Run("putty.exe -ssh" + host + "22");
}
</script>
Connection 1
I managed to perform what you need
<script language="javascript">
function connection(host) {
var oShell = new ActiveXObject("Wscript.Shell");
oShell.Run('"c:\\Archivos de programa\\PuTTY\\putty.exe" -ssh '+ host +' 22');
}
</script>
Connection 1
I needed to pass the location of putty executable (with escaped chars) as well as adding some spaces missing in your code (afer -ssh and before 22). As long as putty can run standalone perhaps you can place putty.exe in a network shared location so everyone is able to launch it and most important: there is a consistent location to all users.
Take a look also to the command-line options of putty which can be also interesting for you.
Related
I'm having a task where different users have access to written by an external supplier (computer with limited access) the Kiosk app, and Windows 10 is running under the hood. A kiosk gives access to my company's local web-based apps via browser. Users can print for i.e. working schedules, Holiday requests, payslips etc. Due to GDPR and various other security concerns, I need to ensure that all printing jobs on this particular machine are clean when the user closes the internet browser.
I wrote the simple script in JS that I can add to the main Kiosk. The app will then run the script when the user closes it, and the browser logs off the computer.
The script supposed to run & clean a printer folders which in my case are:
C:\Windows\Sysnative\spool\PRINTERS\*
C:\ProgramData\SPS\Jobs\*", true);
However, my tests indicate that the script somehow does not work!
In one of my Test-Scenarios: Employee A is printing a pay slip, that printing Q is not cleared and now Employee B will log in to the computer and can still print something that does not belong to him.
Here is my code, if you have any idea why printing Q is not cleared, or have maybe a better idea regarding .js code
SiteKiosk.OnReset = waitBeforeDelete;
function waitBeforeDelete()
{
//Give SiteKiosk some time to run through its default session end/screensaver activation methods
evtid = SiteKiosk.Scheduler.AddDelayedEvent(3000, deleteFolders);
}
function deleteFolders(eventID)
{
try
{
//Deleting the folders with the help of the FileSystemObject
var fso = new ActiveXObject("Scripting.FileSystemObject");
fso.DeleteFile("C:\\Windows\\Sysnative\\spool\\PRINTERS\\*", true);
fso.DeleteFile("C:\\ProgramData\\SPS\\Jobs\\*", true);
SiteKiosk.Logfile.Notification("---------------------------------Deleting folder content was successful---------------------------------");
}
catch (e)
{
//Create a SiteKiosk logfile entry in case something goes wrong
SiteKiosk.Logfile.Notification("---------------------------------There was an error deleting the folder content: " + e.description + "---------------------------------");
}
}
I would like to use client-side Javascript to perform a DNS lookup (hostname to IP address) as seen from the client's computer. Is that possible?
Edit: This question gave me an itch, so I put up a JSONP webservice on Google App Engine that returns the clients ip address. Usage:
<script type="application/javascript">
function getip(json){
alert(json.ip); // alerts the ip address
}
</script>
<script type="application/javascript" src="http://jsonip.appspot.com/?callback=getip"> </script>
Yay, no server proxies needed.
Pure JS can't. If you have a server script under the same domain that prints it out you could send a XMLHttpRequest to read it.
I know this question was asked a very long time ago, but I figured I'd offer a more recent answer.
DNS over HTTPS (DoH)
You can send DNS queries over HTTPS to DNS resolvers that support it. The standard for DOH is described in RFC 8484.
This is a similar thing to what all the other answers suggest, only that DoH is actually the DNS protocol over HTTPS. It's also a "proposed" Internet standard and it's becoming quite popular. For example, some major browsers either support it or have plans to support it (Chrome, Edge, Firefox), and Microsoft is in the process of building it into their operating system.
One of the purposes of DoH is:
allowing web applications to access DNS information via existing browser APIs in a safe way consistent with Cross Origin Resource Sharing (CORS)
There's an open source tool made especially for doing DNS lookups from web applications called dohjs. It does DNS over HTTPS (DoH) wireformat queries as described in RFC 8484. It supports both GET and POST methods.
Full disclosure: I am a contributor to dohjs.
Another JavaScript library with similar features is found here - https://github.com/sc0Vu/doh-js-client. I haven't used this one personally, but I think it would work client side as well.
DNS over HTTPS JSON APIs
If you don't want to bother with DNS wireformat, both Google and Cloudflare offer JSON APIs for DNS over HTTPS.
Google's JSON API
Doc: https://developers.google.com/speed/public-dns/docs/doh/json
Endpoint: https://dns.google/resolve?
Cloudflare's JSON API
Doc: https://developers.cloudflare.com/1.1.1.1/dns-over-https/json-format/
Endpoint https://cloudflare-dns.com/dns-query?
Example Javascript code to lookup example.com with Google's JSON DOH API:
var response = await fetch('https://dns.google/resolve?name=example.com');
var json = await response.json();
console.log(json);
Examples from the RFC for DOH GET and POST with wireformat
Here are the examples the RFC gives for both GET and POST (see https://www.rfc-editor.org/rfc/rfc8484#section-4.1.1):
GET example:
The first example request uses GET to request "www.example.com".
:method = GET
:scheme = https
:authority = dnsserver.example.net
:path = /dns-query?dns=AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB
accept = application/dns-message
POST example:
The same DNS query for "www.example.com", using the POST method would
be:
:method = POST
:scheme = https
:authority = dnsserver.example.net
:path = /dns-query
accept = application/dns-message
content-type = application/dns-message
content-length = 33
<33 bytes represented by the following hex encoding>
00 00 01 00 00 01 00 00 00 00 00 00 03 77 77 77
07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 00 01 00
01
Other places to send DOH queries
You can find a list of some public DNS resolvers that support DNS over HTTPS in a couple places:
DNSCrypt has a long list of public DoH and DNSCrypt resolver on their Github, and a nice interactive version of the list at https://dnscrypt.info/public-servers/
Wikipedia - comparison of public recursive nameservers
List on Curl's wiki
(short) list on dnsprivacy.org
Of the above resources, I'd say that the list on Curl's wiki and the DNSCrypt list are are probably the most complete and the most frequently updated. Curl's page also includes a list of open source tools for DoH (servers, proxies, client libs, etc).
There's no notion of hosts or ip-addresses in the javascript standard library. So you'll have to access some external service to look up hostnames for you.
I recommend hosting a cgi-bin which looks up the ip-address of a hostname and access that via javascript.
Very late, but I guess many people will still land here through "Google Airlines". A moderm approach is to use WebRTC that doesn't require server support.
https://hacking.ventures/local-ip-discovery-with-html5-webrtc-security-and-privacy-risk/
Next code is a copy&paste from http://net.ipcalf.com/
// NOTE: window.RTCPeerConnection is "not a constructor" in FF22/23
var RTCPeerConnection = /*window.RTCPeerConnection ||*/ window.webkitRTCPeerConnection || window.mozRTCPeerConnection;
if (RTCPeerConnection) (function () {
var rtc = new RTCPeerConnection({iceServers:[]});
if (window.mozRTCPeerConnection) { // FF needs a channel/stream to proceed
rtc.createDataChannel('', {reliable:false});
};
rtc.onicecandidate = function (evt) {
if (evt.candidate) grepSDP(evt.candidate.candidate);
};
rtc.createOffer(function (offerDesc) {
grepSDP(offerDesc.sdp);
rtc.setLocalDescription(offerDesc);
}, function (e) { console.warn("offer failed", e); });
var addrs = Object.create(null);
addrs["0.0.0.0"] = false;
function updateDisplay(newAddr) {
if (newAddr in addrs) return;
else addrs[newAddr] = true;
var displayAddrs = Object.keys(addrs).filter(function (k) { return addrs[k]; });
document.getElementById('list').textContent = displayAddrs.join(" or perhaps ") || "n/a";
}
function grepSDP(sdp) {
var hosts = [];
sdp.split('\r\n').forEach(function (line) { // c.f. http://tools.ietf.org/html/rfc4566#page-39
if (~line.indexOf("a=candidate")) { // http://tools.ietf.org/html/rfc4566#section-5.13
var parts = line.split(' '), // http://tools.ietf.org/html/rfc5245#section-15.1
addr = parts[4],
type = parts[7];
if (type === 'host') updateDisplay(addr);
} else if (~line.indexOf("c=")) { // http://tools.ietf.org/html/rfc4566#section-5.7
var parts = line.split(' '),
addr = parts[2];
updateDisplay(addr);
}
});
}
})(); else {
document.getElementById('list').innerHTML = "<code>ifconfig | grep inet | grep -v inet6 | cut -d\" \" -f2 | tail -n1</code>";
document.getElementById('list').nextSibling.textContent = "In Chrome and Firefox your IP should display automatically, by the power of WebRTCskull.";
}
The hosted JSONP version works like a charm, but it seems it goes over its resources during night time most days (Eastern Time), so I had to create my own version.
This is how I accomplished it with PHP:
<?php
header('content-type: application/json; charset=utf-8');
$data = json_encode($_SERVER['REMOTE_ADDR']);
echo $_GET['callback'] . '(' . $data . ');';
?>
Then the Javascript is exactly the same as before, just not an array:
<script type="application/javascript">
function getip(ip){
alert('IP Address: ' + ip);
}
</script>
<script type="application/javascript" src="http://www.anotherdomain.com/file.php?callback=getip"> </script>
Simple as that!
Side note: Be sure to clean your $_GET if you're using this in any public-facing environment!
There's a third-party service which provides a CORS-friendly REST API to perform DNS lookups from the browser - https://exana.io/tools/dns/
I am aware this is an old question but my solution may assist others.
I find that the JSON(P) services which make this easy do not last forever but the following JavaScript works well for me at the time of writing.
<script type="text/javascript">function z (x){ document.getElementById('y').innerHTML=x.query }</script>
<script type='text/javascript' src='http://ip-api.com/json/zero.eu.org?callback=z'></script>
The above writes my server's IP on the page it is located but the script can be modified to find any IP by changing 'zero.eu.org' to another domain name.
This can be seen in action on my page at: http://meon.zero.eu.org/
There is a javascript library DNS-JS.com that does just this.
DNS.Query("dns-js.com",
DNS.QueryType.A,
function(data) {
console.log(data);
});
As many people said you need to use an external service and call it. And that will only get you the DNS resolution from the server perspective.
If that's good enough and if you just need DNS resolution you can use the following Docker container:
https://github.com/kuralabs/docker-webaiodns
Endpoints:
[GET] /ipv6/[domain]:
Perform a DNS resolution for given domain and return the associated IPv6
addresses.
{
"addresses": [
"2a01:91ff::f03c:7e01:51bd:fe1f"
]
}
[GET] /ipv4/[domain]:
Perform a DNS resolution for given domain and return the associated IPv4
addresses.
{
"addresses": [
"139.180.232.162"
]
}
My recommendation is that you setup your web server to reverse proxy to the container on a particular endpoint in your server serving your Javascript and call it using your standard Javascript Ajax functions.
Doing this would require to break the browser sandbox. Try to let your server do the lookup and request that from the client side via XmlHttp.
Firefox has a built-in API for this since v60, for WebExtensions:
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/dns/resolve
sure you can do that without using any addition, just pure javascript, by using this method of dns browser.dns.resolve("example.com");
but it is compatible just with FIREFOX 60 you can see more information on MDN https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/dns/resolve
I don't think this is allowed by most browsers for security reasons, in a pure JavaScript context as the question asks.
Maybe I missed the point but in reply to NAVY guy here is how the browser can tell you the 'requestor's' IP address (albeit maybe only their service provider).
Place a script tag in the page to be rendered by the client that calls (has src pointing to) another server that is not loaded balanced (I realize that this means you need access to a 2nd server but hosting is cheap these days and you can set this up easily and cheaply).
This is the kind of code that needs to be added to client page:
On the other server "someServerIown" you need to have the ASP, ASPX or PHP page that;
----- contains server code like this:
"<%
Response.Write("var clientipaddress = '" & Request.ServerVariables("REMOTE_ADDR") & "';")
%>"
(without the outside dbl quotes :-))
---- and writes this code back to script tag:
var clientipaddress = '178.32.21.45';
This effectively creates a Javascript variable that you can access with Javascript on the page no less.
Hopefully, you access this var and write the value to a form control ready for sending back.
When the user posts or gets on the next request your Javascript and/or form sends the value of the variable that the "otherServerIown" has filled in for you, back to the server you would like it on.
This is how I get around the dumb load balancer we have that masks the client IP address and makes it appear as that of the Load balancer .... dumb ... dumb dumb dumb!
I haven't given the exact solution because everyone's situation is a little different. The concept is sound, however. Also, note if you are doing this on an HTTPS page your "otherServerIOwn" must also deliver in that secure form otherwise Client is alerted to mixed content. And if you do have https then make sure ALL your certs are valid otherwise client also gets a warning.
Hope it helps someone! Sorry, it took a year to answer/contribute. :-)
My version is like this:
php on my server:
<?php
header('content-type: application/json; charset=utf-8');
$data = json_encode($_SERVER['REMOTE_ADDR']);
$callback = filter_input(INPUT_GET,
'callback',
FILTER_SANITIZE_STRING,
FILTER_FLAG_ENCODE_HIGH|FILTER_FLAG_ENCODE_LOW);
echo $callback . '(' . $data . ');';
?>
jQuery on the page:
var self = this;
$.ajax({
url: this.url + "getip.php",
data: null,
type: 'GET',
crossDomain: true,
dataType: 'jsonp'
}).done( function( json ) {
self.ip = json;
});
It works cross domain.
It could use a status check. Working on that.
If the client has Java installed, you could do something like this:
ipAddress = java.net.InetAddress.getLocalHost().getHostAddress();
Other than that, you will probably have to use a server side script.
I'm trying to trigger some sort of Folder Selection Dialog, I have a working model with nodejs and the powershell but it only works when the server and client are on the same machine. I need the prompt to occur on the client side triggered from the browser. From what i understand I can not trigger Powershell from Chrome? So is there an alternative or am i just screwed?
My current Powershell script
{
param([string]$Description="Select Folder",[string]$RootFolder="Desktop")
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") |
Out-Null
$objForm = New-Object System.Windows.Forms.FolderBrowserDialog
$objForm.Rootfolder = $RootFolder
$objForm.Description = $Description
$Show = $objForm.ShowDialog()
If ($Show -eq "OK")
{
Return $objForm.SelectedPath
}
Else
{
Write-Error "Operation cancelled by user."
}
}
$folder = Select-FolderDialog # the variable contains user folder selection
write-host $folder
My javascript function
async function asyncfindDir() {
//executes powershell script
let promise = new Promise((resolve, reject) => {
const Shell = require('node-powershell');
const ps = new Shell({
executionPolicy: 'Bypass',
noProfile: true
});
ps.addCommand('./selectfolder.ps1');
ps.invoke()
.then(output => {
//console.log(output);
var shelloutput = output;
console.log (shelloutput + '^^from external script');
res.send(shelloutput);
})
.catch(err => {
console.log('please select a directory path')
//console.log('err');
});
});
};
Is there anyway to get that working locally?
Is there a trigger i'm not aware of to access that kind of dialog from the browser? I know i'm not the only person with this issue but i have yet to see a real solution.
Short answer: No.
Longer answer, is best illustrated by rephrasing your question with a different script name:
Using my browser, can I click on a link to visit a website, and have it run a random
PowerShell script called Delete_All_Files.ps1?
Answers why you will never be able to run a PowerShell script from a browser, on a remote machine, and why browsers will deliberately block you from doing it, because people usually don't want to have all their files deleted when they click on a random link in their email.
If you want to run PowerShell scripts on remote machines, then you should look into PSRemoting and Enter-PSSession.
#kuzimoto is right. If you just want to display a folder dialog box, there are easier ways to do that and Fine Uploader is an easier way.
Replying to your comment: If you want to specify a directory name, the reason you can't do it is because you are essentially asking:
Using my browser, can I click on a link to visit a website, and have
it run a script that will enumerate through all the files and folders
in my C:\ so that it can choose the folder C:\users\Justin
Miller\Desktop\SECRET FILES\?
The reason both operations do not work is because both operations require local computer access. i.e. local script execution access, and local directory knowledge access. Security-wize, we, in general, don't want to visit a random website and have it execute random code, or know what files/folders I have on my machine, which is why you won't be able to do what you want to try to do.
So my goal is to have a web portal where our helpdesk users can lookup a user, find their computer(s) and click on the computer name to launch a remote-viewer application locally. I've attempted through, vb .net, javascript/asp, sql, and I'm out of ideas..
Here's some of the code already attempted.
<script type = "text/javascript" >
function go() {
w = new ActiveXObject("WScript.Shell");
w.run("cmd.exe /c C:\\SCCMRemoteView\\Remote\\CmRcViewer.exe ");
return true;
}
</script>
Returns "Unspecified Error"
Also, tried the
Shell, (var remote.exe, "CmRcViewer.exe","C:\SCCMRemote\Remote\","open","1")
Failed...
Dim Rview As New Process
Rview.StartInfo.FileName = ("C:\SCCMRemote\Remote\CmRcViewer.exe ")
Works, but not after its published to the website (I believe because the base code is aspx - not local)
I know the "Security" risks, but only members of our AD group will have access to the page - so it should be fine... Any ideas would be great!
This is not realistically feasible. The only browser that can support ActiveX calls is IE. IE has discontinued support for ActiveX with Windows 8, no matter which browser you use. With Windows 7, you have to run the browser in an elevated privileges mode (opening you up for those security issues you mentioned).
You can try this, but you will have to register the protocol handler to an executable by making Registry entries on each machine. This process is not something that can be automated from the browser. Your users will have to download and execute something to create the handler.
It appears that some browsers will allow you to do the same thing with a browser based protocol handler, but it is not implemented everywhere.
Dim Address As String = Server.MapPath("~") & "\test.exe"
Process.Start("explorer.exe", Address)
try to use exec instead of run like so:
<script>
function Run() {
try {
var objShell = new ActiveXObject("wscript.shell");
objShell.exec("C:\\SCCMRemoteView\\Remote\\CmRcViewer.exe ");
} catch(e) {
alert(e);
}
}
</script>
<input type="button" name="btn01" onclick="Run()" value="click me">
Furthermore you have to change the security settings for YOUR SPECIFIC site in IE Settings->Security. add your site to the trusted sites and set the activex things... you will have to do that for each Computer/IE in which you want to use that activex/remote thing...
I distribute my desktop application on flash drives to thousands of users on Windows, Mac, and Linux. I have a HTML starter page that has links to the documentation, install guide, release notes, etc. which are all on the flash drive. I would love for the user to just install directly from the browser, but that's exactly what anti-virus programs are trying to prevent (and rightly so). Instead of trying to launch the installer, it's enough to locate the installer and let the user take the last step by themselves.
Is it possible to cause the file system manager (Explorer, Finder, etc.) on the host computer to open the folder containing the file and highlight it? I assume this would require JavaScript and it would probably have to be different for Windows, Mac, and Linux. Plus, work in most browsers (IE, FF, Chrome, Safari, Opera).
Is this on a similar difficulty scale to solving Fermat's Last Theorem?
Thanks
Nope. Browsers (or most of them*) prevent this sort of behavior. They have a wall between your actual file system and the content that the Web serves you. Only the HTML input control breaks this, and they have quite a bit of protection around that, too.
*- You can use an IE ActiveX control, but that is IE-only.
This JS code should work for IE and Firefox on Windows as long as the page was loaded from your local filesystem. You would need to test this on Linux/OSX. I don't know how you would approach chrome/safari/opera.
function execute(command, commandParam)
{
if (isIE()) {
try {
activexShell = new ActiveXObject("Shell.Application");
activexShell.ShellExecute(command, commandParam, "", "open", "1");
exit();
} catch (e) {
alert("exception " + e.name + ': ' + e.message);
}
}
else {
try {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var FileFactory = new Components.Constructor("#mozilla.org/file/local;1","nsILocalFile","initWithPath");
var program = new FileFactory(command);
var process = Components.classes["#mozilla.org/process/util;1"].createInstance(Components.interfaces. nsIProcess);
process.init(program);
process.run(false, commandArray, commandParam.split(" ").length - 1, {});
exit();
} catch (e) {
alert("exception " + e.name + ': ' + e.message);
}
}
}
Of course, you may need to sign the .js file in order to get it to work. For more info, see here: http://www.mozilla.org/projects/security/components/signed-scripts.html