您的位置:首页 > 理论基础 > 计算机网络

python实用程序-HTTP服务调用系统命令(带白名单)

2013-05-14 22:16 561 查看
本文转自:http://xiaoxia.org/2011/08/16/a-small-python-program-serverinformation/
需求:监听一个端口,提供HTTP接口,通过访问Web地址,调用程序获取各种信息。
例如,想在远程服务器上执行free命令查看远程服务器的内存使用情况,free -m 的base64编码为 ZnJlZSAtbQ== (可以在bash下使用命令生成base64编码 echo -n "free -m"|base64 )则访问下面的地址:http://xiaoxia.org:10000/ZnJlZSAtbQ==提交之后返回类似于下面的结果,
total       used       free     shared    buffers     cached
Mem:         16053      10521       5532          0        871       7874
-/+ buffers/cache:       1776      14277
Swap:        16002          0      16002


为了安全使用,在CommandList文本文件里保存着一个命令列表,即可以允许调用的程序。

ps aux
free -m
netstat -na
cat /proc/meminfo
cat /proc/cpuinfo


代码实现:
1.原始版本源代码:
from BaseHTTPServer import *
import base64, os

decorator = lambda x: x.rstrip("\n") + " (" + base64.b64encode(x.rstrip("\n")) + ")\n"

class Handler(BaseHTTPRequestHandler):
def process(self):
path = self.path.split('?')[0].split('#')[0][1:]
try:
cmd = base64.decodestring(path)
if cmd == "":
return "Command List: \n\n" + "".join(map(decorator, file("CommandList").readlines()))
except:
return "Try to access /[Base64 String]"
if cmd+"\n" in file("CommandList").readlines():
return os.popen(cmd, "r").read()
else:
return cmd + " is not permitted"
def do_GET(self):
self.send_response(200)
buf = self.process()
self.send_header("Content-Type", "text/plain; charset=utf8")
self.send_header("Content-Length", str(len(buf)))
self.end_headers()
self.wfile.write(buf)

httpd = HTTPServer(("", 10000), Handler)
print "Server starting ..."
try:
httpd.serve_forever()
except KeyboardInterrupt: exit()


2.多线程版本源代码:

from BaseHTTPServer import *
from SocketServer import ThreadingMixIn
import base64, os

decorator = lambda x: x.rstrip("\n") + " (" + base64.b64encode(x.rstrip("\n")) + ")\n"

class Handler(BaseHTTPRequestHandler):
def process(self):
path = self.path.split('?')[0].split('#')[0][1:]
try:
cmd = base64.decodestring(path)
if cmd == "":
return "Command List: \n\n" + "".join(map(decorator, file("CommandList").readlines()))
except:
return "Try to access /[Base64 String]"
if cmd+"\n" in file("CommandList").readlines():
return os.popen(cmd, "r").read()
else:
return cmd + " is not permitted"
def do_GET(self):
self.send_response(200)
buf = self.process()
self.send_header("Content-Type", "text/plain; charset=utf8")
self.send_header("Content-Length", str(len(buf)))
self.end_headers()
self.wfile.write(buf)

class ThreadingHTTPServer(ThreadingMixIn, HTTPServer): pass

httpd = ThreadingHTTPServer(("", 10000), Handler)
print "Server starting ..."
try:
httpd.serve_forever()
except KeyboardInterrupt: exit()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息