欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

精確查找PHP WEBSHELL木馬 修正版

 更新時(shí)間:2011年04月12日 22:08:29   作者:  
上篇提到了關(guān)于網(wǎng)上流傳查找PHP webshell的python腳本中,不嚴(yán)謹(jǐn)?shù)拇a,并且給出了一個(gè)python的檢測(cè)代碼,同時(shí),下文里也提到不能檢測(cè)到反引號(hào)的命令執(zhí)行的地方。今天,我想了下,現(xiàn)在把思路發(fā)出來(lái)。
先來(lái)看下反引號(hào)可以成功執(zhí)行命名的代碼片段。代碼如下:
復(fù)制代碼 代碼如下:

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

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

$sql = 'SELECT `username` FROM `table` WHERE 1'
/*
無(wú)非是 前面有空白字符,或者在一行代碼的結(jié)束之后,后面接著寫,下面兩行為意外情況,也就是SQL命令里的反引號(hào),要排除的就是它。
*/

正則表達(dá)式該如何寫?
分析:
對(duì)于可移植性的部分共同點(diǎn)是什么?與其他正常的包含反引號(hào)的部分,區(qū)別是什么?
他們前面可以有空格,tab鍵等空白字符。也可以有程序代碼,前提是如果有引號(hào)(單雙)必須是閉合的。才是危險(xiǎn)有隱患的。遂CFC4N給出的正則如下:【(?:(?:^(?:\s+)?)|(?:(?P<quote>["'])[^(?P=quote)]+?(?P=quote)[^`]*?))`(?P<shell>[^`]+)`】。

解釋一下:

【(?:(?:^(?:\s+)?)|(?:(?P<quote>["'])[^(?P=quote)]+?(?P=quote)[^`]*?))】匹配開(kāi)始位置或者開(kāi)始位置之后有空白字符或者前面有代碼,且代碼有閉合的單雙引號(hào)。(這段PYTHON的正則中用了捕獲命名以及反向引用)

【`(?P<shell>[^`]+)`】這個(gè)就比較簡(jiǎn)單了,匹配反引號(hào)中間的字符串。

python腳本檢測(cè)PHP WEBSHELL
然后我將這段代碼寫入程序中,測(cè)試跑了一下discuz的程序。結(jié)果有一個(gè)誤報(bào)。誤報(bào)的位置為“config.inc.php”中的“define(‘UC_DBTABLEPRE', ‘`ucenter`.uc_');”,什么原因造成的?這行代碼符合了前面有閉合的引號(hào),也有反引號(hào)的使用,所以,符合要求,被檢測(cè)到了。如何再排除這種情況呢?這個(gè)有什么特殊的?前面有逗號(hào)“,”?如果是字符串連接的點(diǎn)號(hào)“.”呢?再排除逗號(hào)?

好吧,我錯(cuò)了,我不該用我的思維來(lái)誤導(dǎo)你。換個(gè)思路。找下反引號(hào)可執(zhí)行的代碼的前面字符串的情況,他們只能是行的開(kāi)始,或者有空白字符(包括空格,tab鍵等),再前面也可以有代碼的結(jié)束標(biāo)識(shí)分號(hào)“;”,其他的情況,都是不可以執(zhí)行的吧?嗯,應(yīng)該是這樣。(如有錯(cuò)誤,歡迎斧正)既然思路有了,那正則代碼更好寫了。如下【(^|(?<=;))\s*`[^`]+`】,解釋一下,【(^|(?<=;))】匹配位置,是行的開(kāi)始,或者前面有分號(hào)“;”。【\s*`[^`]+`】空白字符任一個(gè),然后是….(你懂的)。OK,寫好之后,檢測(cè),又發(fā)現(xiàn)一個(gè)問(wèn)題。

匹配引入文件的正則也匹配了“require_once ‘./include/db_'.$database.'.class.php';”這種代碼,什么原因造成的,您自己分析吧。
給出修復(fù)之后的python代碼,如下:
復(fù)制代碼 代碼如下:

#!/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'''(?P<function>\b(?:include|require)(?:_once)?\b)\s*\(?\s*["'](?P<filename>[^;]*(?<!\.(?: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(?P<function>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*`(?P<shell>[^`]+)`\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()

稍微檢測(cè)了一下Discuz7.2的代碼,還是有誤報(bào)的,誤報(bào)的為這種包含sql的代碼:
復(fù)制代碼 代碼如下:

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

稍微檢測(cè)了一下Discuz7.2的代碼,還是有誤報(bào)的,誤報(bào)的為這種包含sql的代碼:
復(fù)制代碼 代碼如下:

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

由于這個(gè)腳本是按照一行一行的代碼來(lái)處理的,所以,有這種誤報(bào)。您自己去修復(fù)吧。相對(duì)網(wǎng)上流傳的腳本來(lái)說(shuō),還是比較準(zhǔn)確的。
歡迎轉(zhuǎn)載。轉(zhuǎn)載請(qǐng)注明來(lái)源,以及留下博客鏈接,同時(shí),不能用于商業(yè)用途。(已經(jīng)修復(fù),增加了反引號(hào)后面【\s*;】的判斷。2010-07-27 17:06)

PS:如果說(shuō)上傳文件也算是危險(xiǎn)的、值得注意的操作的話,建議加上move_uploaded_file函數(shù)的檢測(cè)。你知道在哪里加的。^_^

2010-12-17 關(guān)于這些代碼,已經(jīng)放到google 的代碼托管上了。SVN地址為 http://code.google.com/p/cnxct/ 大家個(gè)獲得最新版。

我是一個(gè)PHPer,寫的python有點(diǎn)憋,有點(diǎn)懶,還請(qǐng)各位安全界的大牛,程序界的前輩不要鄙視,要給建議,謝謝。php版的以后在寫吧。同時(shí),也歡迎各位安全愛(ài)好者反饋?zhàn)钚碌膚eb shell特征代碼,我盡力增加到程序中區(qū)。
完整的代碼
復(fù)制代碼 代碼如下:

#!/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'''(?P<function>\b(?:include|require)(?:_once)?\b)\s*\(?\s*["'](?P<filename>[^;]*(?<!\.(?: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(?P<function>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*`(?P<shell>[^`]+)`\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'(?P<shell>\$_(?: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()

相關(guān)文章

  • 談?wù)勎覍?duì)正則表達(dá)式的認(rèn)識(shí)

    談?wù)勎覍?duì)正則表達(dá)式的認(rèn)識(shí)

    正則表達(dá)式(Regular Expression)是一個(gè)概念,一種語(yǔ)法、句法的約定。每一種具體的語(yǔ)句(C#,Java,JavaScript)有其對(duì)于正則表達(dá)式的具體實(shí)現(xiàn),并且會(huì)有差別。正則表達(dá)式30分鐘入門教程講述的是.net(C#)的正則表達(dá)式
    2014-02-02
  • re模塊的正則匹配的表達(dá)式詳解

    re模塊的正則匹配的表達(dá)式詳解

    這篇文章主要介紹了使用的re模塊的正則匹配的表達(dá)式,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-07-07
  • C# 校驗(yàn)幫助類正則表達(dá)式

    C# 校驗(yàn)幫助類正則表達(dá)式

    很多時(shí)候我們都需要用到一些驗(yàn)證的方法,有時(shí)候需要用正則表達(dá)式校驗(yàn)數(shù)據(jù)時(shí),需要到處找資料,今天小編把自己整理的校驗(yàn)幫助類分享到腳本之家平臺(tái),需要的的朋友參考下
    2017-07-07
  • js 常用正則表達(dá)式表單驗(yàn)證代碼

    js 常用正則表達(dá)式表單驗(yàn)證代碼

    js 常用正則表達(dá)式表單驗(yàn)證代碼,以后大家就可以直接使用了。
    2009-12-12
  • 中文用戶名的js檢驗(yàn)正則

    中文用戶名的js檢驗(yàn)正則

    好多網(wǎng)站需要用中文用戶名注冊(cè),下面的代碼就是客戶端檢測(cè)。強(qiáng)烈建議后臺(tái)也要控制一下。
    2009-11-11
  • 學(xué)習(xí)網(wǎng)址

    學(xué)習(xí)網(wǎng)址

    學(xué)習(xí)網(wǎng)址...
    2006-06-06
  • JS基礎(chǔ)系列之正則表達(dá)式

    JS基礎(chǔ)系列之正則表達(dá)式

    正則表達(dá)式在開(kāi)發(fā)中經(jīng)常會(huì)用到,是個(gè)很好用的東東,今天小編就給大家分享js正則表達(dá)式的基礎(chǔ)知識(shí),非常適合新手學(xué)習(xí)
    2016-12-12
  • 檢查素?cái)?shù)的正則表達(dá)式分享

    檢查素?cái)?shù)的正則表達(dá)式分享

    一般來(lái)說(shuō),我們會(huì)使用正規(guī)表達(dá)式來(lái)做字符串匹配,今天在網(wǎng)上瀏覽的時(shí)候,看到了有人用正則表達(dá)式來(lái)檢查一個(gè)數(shù)字是否為素?cái)?shù)(質(zhì)數(shù)),讓我非常感興趣
    2011-08-08
  • 正則表達(dá)式在UBB論壇中的應(yīng)用

    正則表達(dá)式在UBB論壇中的應(yīng)用

    正則表達(dá)式在UBB論壇中的應(yīng)用...
    2006-06-06
  • 藏在正則表達(dá)式里的陷阱(推薦)

    藏在正則表達(dá)式里的陷阱(推薦)

    本文是小編給大家收藏整理的關(guān)于藏在正則表達(dá)式里的陷阱,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-10-10

最新評(píng)論