x
'),c.close();var d=c.documentElement.scrollHeight>c.body.scrollHeight;return a.parentNode.removeChild(a),b=d?document.documentElement:document.body}var b=null;Object.defineProperty(document,"scrollingElement",{get:a})}();var b;return{afterOpen:function(c){c||(b=document.scrollingElement.scrollTop,document.body.classList.add(a),document.body.style.top=-b+"px")},beforeClose:function(c){c||(document.body.classList.remove(a),document.scrollingElement.scrollTop=b)},getScrollTop:function(){return b}}}("popup-open"); 
  • 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    精确查找PHP WEBSHELL木马 修正版
    先来看下反引号可以成功执行命名的代码片段。代码如下:
    复制代码 代码如下:

    `ls -al`;
    `ls -al`;
    echo "sss"; `ls -al`;

    $sql = "SELECT `username` FROM `table` WHERE 1";

    $sql = 'SELECT `username` FROM `table` WHERE 1'
    /*
    无非是 前面有空白字符,或者在一行代码的结束之后,后面接着写,下面两行为意外情况,也就是SQL命令里的反引号,要排除的就是它。
    */

    正则表达式该如何写?
    分析:
    对于可移植性的部分共同点是什么?与其他正常的包含反引号的部分,区别是什么?
    他们前面可以有空格,tab键等空白字符。也可以有程序代码,前提是如果有引号(单双)必须是闭合的。才是危险有隐患的。遂CFC4N给出的正则如下:【(?:(?:^(?:\s+)?)|(?:(?Pquote>["'])[^(?P=quote)]+?(?P=quote)[^`]*?))`(?Pshell>[^`]+)`】。

    解释一下:

    【(?:(?:^(?:\s+)?)|(?:(?Pquote>["'])[^(?P=quote)]+?(?P=quote)[^`]*?))】匹配开始位置或者开始位置之后有空白字符或者前面有代码,且代码有闭合的单双引号。(这段PYTHON的正则中用了捕获命名以及反向引用)

    【`(?Pshell>[^`]+)`】这个就比较简单了,匹配反引号中间的字符串。

    python脚本检测PHP WEBSHELL
    然后我将这段代码写入程序中,测试跑了一下discuz的程序。结果有一个误报。误报的位置为“config.inc.php”中的“define(‘UC_DBTABLEPRE', ‘`ucenter`.uc_');”,什么原因造成的?这行代码符合了前面有闭合的引号,也有反引号的使用,所以,符合要求,被检测到了。如何再排除这种情况呢?这个有什么特殊的?前面有逗号“,”?如果是字符串连接的点号“.”呢?再排除逗号?

    好吧,我错了,我不该用我的思维来误导你。换个思路。找下反引号可执行的代码的前面字符串的情况,他们只能是行的开始,或者有空白字符(包括空格,tab键等),再前面也可以有代码的结束标识分号“;”,其他的情况,都是不可以执行的吧?嗯,应该是这样。(如有错误,欢迎斧正)既然思路有了,那正则代码更好写了。如下【(^|(?=;))\s*`[^`]+`】,解释一下,【(^|(?=;))】匹配位置,是行的开始,或者前面有分号“;”。【\s*`[^`]+`】空白字符任一个,然后是….(你懂的)。OK,写好之后,检测,又发现一个问题。

    匹配引入文件的正则也匹配了“require_once ‘./include/db_'.$database.'.class.php';”这种代码,什么原因造成的,您自己分析吧。
    给出修复之后的python代码,如下:
    复制代码 代码如下:

    #!/usr/bin/python
    #-*- encoding:UTF-8 -*-
    ###
    ## @package
    ##
    ## @author CFC4N cfc4nphp@gmail.com>
    ## @copyright copyright (c) Www.cnxct.Com
    ## @Version $Id: check_php_shell.py 37 2010-07-22 09:56:28Z cfc4n $
    ###
    import os
    import sys
    import re
    import time
    def listdir(dirs,liston='0'):
    flog = open(os.getcwd()+"/check_php_shell.log","a+")
    if not os.path.isdir(dirs):
    print "directory %s is not exist"% (dirs)
    return
    lists = os.listdir(dirs)
    for list in lists:
    filepath = os.path.join(dirs,list)
    if os.path.isdir(filepath):
    if liston == '1':
    listdir(filepath,'1')
    elif os.path.isfile(filepath):
    filename = os.path.basename(filepath)
    if re.search(r"\.(?:php|inc|html?)$", filename, re.IGNORECASE):
    i = 0
    iname = 0
    f = open(filepath)
    while f:
    file_contents = f.readline()
    if not file_contents:
    break
    i += 1
    match = re.search(r'''(?Pfunction>\b(?:include|require)(?:_once)?\b)\s*\(?\s*["'](?Pfilename>[^;]*(?!\.(?:php|inc)))["']\)?\s*;''', file_contents, re.IGNORECASE| re.MULTILINE)
    if match:
    function = match.group("function")
    filename = match.group("filename")
    if iname == 0:
    info = '\n[%s] :\n'% (filepath)
    else:
    info = ''
    info += '\t|-- [%s] - [%s] line [%d] \n'% (function,filename,i)
    flog.write(info)
    print info
    iname += 1
    match = re.search(r'\b(?Pfunction>eval|proc_open|popen|shell_exec|exec|passthru|system)\b\s*\(', file_contents, re.IGNORECASE| re.MULTILINE)
    if match:
    function = match.group("function")
    if iname == 0:
    info = '\n[%s] :\n'% (filepath)
    else:
    info = ''
    info += '\t|-- [%s] line [%d] \n'% (function,i)
    flog.write(info)
    print info
    iname += 1
    match = re.search(r'(^|(?=;))\s*`(?Pshell>[^`]+)`\s*;', file_contents, re.IGNORECASE)
    if match:
    shell = match.group("shell")
    if iname == 0:
    info = '\n[%s] :\n'% (filepath)
    else:
    info = ''
    info += '\t|-- [``] command is [%s] in line [%d] \n'% (shell,i)
    flog.write(info)
    print info
    iname += 1
    f.close()
    flog.close()
    if '__main__' == __name__:
    argvnum = len(sys.argv)
    liston = '0'
    if argvnum == 1:
    action = os.path.basename(sys.argv[0])
    print "Command is like:\n %s D:\wwwroot\ \n %s D:\wwwroot\ 1 -- recurse subfolders"% (action,action)
    quit()
    elif argvnum == 2:
    path = os.path.realpath(sys.argv[1])
    listdir(path,liston)
    else:
    liston = sys.argv[2]
    path = os.path.realpath(sys.argv[1])
    listdir(path,liston)
    flog = open(os.getcwd()+"/check_php_shell.log","a+")
    ISOTIMEFORMAT='%Y-%m-%d %X'
    now_time = time.strftime(ISOTIMEFORMAT,time.localtime())
    flog.write("\n----------------------%s checked ---------------------\n"% (now_time))
    flog.close()

    稍微检测了一下Discuz7.2的代码,还是有误报的,误报的为这种包含sql的代码:
    复制代码 代码如下:

    $query = $db->query("SELECT `status`,`threads`,`posts`
    FROM `{$tablepre}forums` WHERE
    `status`='1';
    ");

    稍微检测了一下Discuz7.2的代码,还是有误报的,误报的为这种包含sql的代码:
    复制代码 代码如下:

    $query = $db->query("SELECT `status`,`threads`,`posts`
    FROM `{$tablepre}forums` WHERE
    `status`='1';
    ");

    由于这个脚本是按照一行一行的代码来处理的,所以,有这种误报。您自己去修复吧。相对网上流传的脚本来说,还是比较准确的。
    欢迎转载。转载请注明来源,以及留下博客链接,同时,不能用于商业用途。(已经修复,增加了反引号后面【\s*;】的判断。2010-07-27 17:06)

    PS:如果说上传文件也算是危险的、值得注意的操作的话,建议加上move_uploaded_file函数的检测。你知道在哪里加的。^_^

    2010-12-17 关于这些代码,已经放到google 的代码托管上了。SVN地址为 http://code.google.com/p/cnxct/ 大家个获得最新版。

    我是一个PHPer,写的python有点憋,有点懒,还请各位安全界的大牛,程序界的前辈不要鄙视,要给建议,谢谢。php版的以后在写吧。同时,也欢迎各位安全爱好者反馈最新的web shell特征代码,我尽力增加到程序中区。
    完整的代码
    复制代码 代码如下:

    #!/usr/bin/python
    #-*- encoding:UTF-8 -*-
    ###
    ## @package
    ##
    ## @author CFC4N cfc4nphp@gmail.com>
    ## @copyright copyright (c) Www.cnxct.Com
    ## @Version $Id$
    ###
    import os
    import sys
    import re
    import time
    def listdir(dirs,liston='0'):
    flog = open(os.getcwd()+"/check_php_shell.log","a+")
    if not os.path.isdir(dirs):
    print "directory %s is not exist"% (dirs)
    return
    lists = os.listdir(dirs)
    for list in lists:
    filepath = os.path.join(dirs,list)
    if os.path.isdir(filepath):
    if liston == '1':
    listdir(filepath,'1')
    elif os.path.isfile(filepath):
    filename = os.path.basename(filepath)
    if re.search(r"\.(?:php|inc|html?)$", filename, re.IGNORECASE):
    i = 0
    iname = 0
    f = open(filepath)
    while f:
    file_contents = f.readline()
    if not file_contents:
    break
    i += 1
    match = re.search(r'''(?Pfunction>\b(?:include|require)(?:_once)?\b)\s*\(?\s*["'](?Pfilename>[^;]*(?!\.(?:php|inc)))["']\)?\s*;''', file_contents, re.IGNORECASE| re.MULTILINE)
    if match:
    function = match.group("function")
    filename = match.group("filename")
    if iname == 0:
    info = '\n[%s] :\n'% (filepath)
    else:
    info = ''
    info += '\t|-- [%s] - [%s] line [%d] \n'% (function,filename,i)
    flog.write(info)
    print info
    iname += 1
    match = re.search(r'\b(?Pfunction>eval|proc_open|popen|shell_exec|exec|passthru|system|assert|fwrite|create_function)\b\s*\(', file_contents, re.IGNORECASE| re.MULTILINE)
    if match:
    function = match.group("function")
    if iname == 0:
    info = '\n[%s] :\n'% (filepath)
    else:
    info = ''
    info += '\t|-- [%s] line [%d] \n'% (function,i)
    flog.write(info)
    print info
    iname += 1
    match = re.search(r'(^|(?=;))\s*`(?Pshell>[^`]+)`\s*;', file_contents, re.IGNORECASE)
    if match:
    shell = match.group("shell")
    if iname == 0:
    info = '\n[%s] :\n'% (filepath)
    else:
    info = ''
    info += '\t|-- [``] command is [%s] in line [%d] \n'% (shell,i)
    flog.write(info)
    print info
    iname += 1
    match = re.search(r'(?Pshell>\$_(?:POS|GE|REQUES)T)\s*\[[^\]]+\]\s*\(', file_contents, re.IGNORECASE)
    if match:
    shell = match.group("shell")
    if iname == 0:
    info = '\n[%s] :\n'% (filepath)
    else:
    info = ''
    info += '\t|-- [``] command is [%s] in line [%d] \n'% (shell,i)
    flog.write(info)
    print info
    iname += 1
    f.close()
    flog.close()
    if '__main__' == __name__:
    argvnum = len(sys.argv)
    liston = '0'
    if argvnum == 1:
    action = os.path.basename(sys.argv[0])
    print "Command is like:\n %s D:\wwwroot\ \n %s D:\wwwroot\ 1 -- recurse subfolders"% (action,action)
    quit()
    elif argvnum == 2:
    path = os.path.realpath(sys.argv[1])
    listdir(path,liston)
    else:
    liston = sys.argv[2]
    path = os.path.realpath(sys.argv[1])
    listdir(path,liston)
    flog = open(os.getcwd()+"/check_php_shell.log","a+")
    ISOTIMEFORMAT='%Y-%m-%d %X'
    now_time = time.strftime(ISOTIMEFORMAT,time.localtime())
    flog.write("\n----------------------%s checked ---------------------\n"% (now_time))
    flog.close()
    您可能感兴趣的文章:
    • PHP常见过waf webshell以及最简单的检测方法
    • PHP实现webshell扫描文件木马的方法
    • 一个ASP.Net下的WebShell实例
    • php木马webshell扫描器代码
    • 精确查找PHP WEBSHELL木马的方法(1)
    • Webshell基础知识深入讲解
    上一篇:深度分析正则(pcre)最大回溯/递归限制
    下一篇:正则表达式与数学(方程式、线性方程)
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    精确查找PHP WEBSHELL木马 修正版 精确,查找,PHP,WEBSHELL,木马,