If you have, like I do, a virtual server on hosting service, that support cgi but don’t have access to a shell and php have passthru disabled you still can have access to a shell, even if you can’t install anything on that machine – like anyterm.
There is this project, which I did, called jQuery terminal, that emulate a Unix terminal. All you need is interpreter that will execute shell commands.
Lots of hosting services disable php passthru but leave cgi script, so if you have them you can create simple shell like this one:
UPDATE: If you don’t want to code it yourself (or look at working solution), you can check my project LEASH – Browser Shell. You if you prefer there is also available single file Shell using same library.
#!/bin/bash echo -en "Content-Type: text/plain\r\n\r\n" query=$(/usr/bin/python -c "import urllib; print urllib.unquote_plus('$QUERY_STRING')") eval $query 2>&1
I use python subprocess to decode QUERY_STRING. Probably it can be done using some Unix tools.
On my server I use Python CGI script like this one:.
#!/usr/bin/python import cgi import subprocess as sub try: from json import dumps as json_serialize except ImportError: def json_serialize(obj): result = '' t = type(obj) if t == types.StringType: result += '"%s"' % obj.replace('\\', '\\\\').replace('"', '\\"').replace('\n', '\\n') elif t == types.NoneType: result += 'null' elif t == types.IntType or t == types.FloatType: result += str(obj) elif t == types.LongType: result += str(int(obj)) elif t == types.TupleType: result += '[' + ','.join(map(json_serialize, list(obj))) + ']' elif t == types.ListType: result += '[' + ','.join(map(json_serialize, obj)) + ']' elif t == types.DictType: array = ['"%s":%s' % (k,json_serialize(v)) for k,v in obj.iteritems()] result += '{' + ','.join(array) + '}' else: result += '"unknown type - ' + type(obj).__name__ + '"' return result class Singleton(object): __single = None def __init__(self): Singleton.__single = self def __new__(cls): if Singleton.__single: return Singleton.__single else: return super(Singleton, cls).__new__(cls) class Form(Singleton): def __init__(self): super(Form) self.form = cgi.FieldStorage() def __getitem__(self, name): return self.form.getvalue(name) def execv(command, path): command = 'cd %s && %s && pwd 1>&2' % (path, command) proc = sub.Popen(['/bin/bash', '-c', command], stdout=sub.PIPE, stderr=sub.PIPE) stderr = proc.stderr.read()[:-1] stdout = proc.stdout.read()[:-1] if not os.path.exists(stderr): raise Exception(stdout, stderr) return { "cwd": stderr, "stdout": re.sub('.\x08', '', stdout) } if __name__ == '__main__': print "Content-Type: text/plain" print form = Form() if token() == form['token']: response = {} try: response['result'] = execv(form['command'], form['path']) except Exception, e: response['error'] = e.args[1] response['result'] = {'stdout': e.args[0], 'cwd': form['path']} else: response['error'] = None else: response = {'error': 'You are not authorized', 'result': None} stdout.write(json_serialize(response))
You have enabled passthru in php you can write your shell in php.
Now when you have access to a shell you need to setup interface using jQuery terminal.
<!DOCTYPE HTML> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta charset="utf-8" /> <title>Shell</title> http://code.jquery.com/jquery-1.7.1.min.js http://terminal/js/jquery.mousewheel-min.js http://terminal/js/jquery.terminal.js <link href="terminal/css/jquery.terminal.css" rel="stylesheet"/> <style> .terminal a.ui-slider-handle:focus { outline: none; } body { margin: 0; padding: 0; } html { background-color: #000; } .clear { clear: both; } /* This works only in Safari and Google Chrome */ @media screen and (-webkit-min-device-pixel-ratio:0) { .terminal, .terminal .terminal-output, .terminal .terminal-output div, .terminal .terminal-output div div, .cmd, .terminal .cmd span, .terminal .cmd div { font-weight: bold; } } </style> <script> $(function() { var pwd, last_dir, home_dir; var terminal = $('#shell').terminal(function(command, term) { if (command.replace(/^ *(.*) *$/, '$1') == '-') { pwd = last_dir; return; } term.pause(); $.post("/cgi-bin/cmd.py", { token: term.token(), command: command.replace(/(\\)?~/, function($0,$1) { return $1 ? $0 : home_dir; }), path: pwd }, function(response) { term.echo(response.result.stdout); pwd = response.result.cwd; term.resume(); }); }, { login: function(user, password, authenticate) { $.post("/cgi-bin/cmd.py", { user: user, password: password }, function(token) { if (token) { home_dir = pwd = last_dir = '/home/ + user; } authenticate(token); }); }, prompt: function(callback) { var username = terminal.login_name(); var re = new RegExp("^" + '/home/' + username); var username = '[[;#44D544;]' + username + ']'; var path = '[[;#5555FF;]' + pwd.replace(re, '~') + ']'; callback(username + '[[;#989898;]:]' + path + '[[;#989898;]$] '); }, name: 'shell' }).css({ overflow: 'auto' }); $(window).resize(function() { terminal.css('height', $(window).height()-20); }).resize(); }); </script> </head> <body> <div id="shell"></div> </body> </html>
One thought on “How to have access to a shell without ssh or telnet using jQuery terminal”