Python小程序: ServerInformation

监听一个端口,提供HTTP接口,通过访问Web地址,调用程序获取各种信息。

例如,想在远程服务器上执行free命令查看远程服务器的内存使用情况,

free -m 的base64编码为 ZnJlZSAtbQ==,则访问下面的地址:

http://xiaoxia.org:10000/ZnJlZSAtbQ==

提交之后返回类似于下面的结果,

             total       used       free     shared    buffers     cached
Mem:           118        114          4          0          3         36
-/+ buffers/cache:         74         44
Swap:          255         56        199

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

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


通过访问Web默认页面:http://xiaoxia.org:10000/ 可以查看这个列表,返回如下类似结果:

Command List: 

ps aux (cHMgYXV4)
free -m (ZnJlZSAtbQ==)
netstat -na (bmV0c3RhdCAtbmE=)
cat /proc/meminfo (Y2F0IC9wcm9jL21lbWluZm8=)
cat /proc/cpuinfo (Y2F0IC9wcm9jL2NwdWluZm8=)

原始版本源代码:

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()

多线程版本源代码:

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()

Python小程序: ServerInformation》有28个想法

    1. Xiaoxia 文章作者

      如果有人喜欢执行这个命令,也可以添加到列表去。
      我没执行过,也不知道是什么结果,应该跟运行系统的时候拔出系统硬盘差不多的效果。

      回复
  1. 永恒沸点

    开始看着很危险的样子,后来看到有个文件对象啊。我说我passwd来着。哈。看了你的文章我才开始PYTHON的。谢谢你

    回复

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据