亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Regex > 正文

精確查找PHP WEBSHELL木馬 修正版

2020-03-16 21:11:58
字體:
來源:轉載
供稿:網友
上篇提到了關于網上流傳查找PHP webshell的python腳本中,不嚴謹的代碼,并且給出了一個python的檢測代碼,同時,下文里也提到不能檢測到反引號的命令執行的地方。今天,我想了下,現在把思路發出來。
 
 
先來看下反引號可以成功執行命名的代碼片段。代碼如下: 
復制代碼代碼如下:

`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+)?)|(?:(?P<quote>["'])[^(?P=quote)]+?(?P=quote)[^`]*?))`(?P<shell>[^`]+)`】。 

解釋一下: 

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

【`(?P<shell>[^`]+)`】這個就比較簡單了,匹配反引號中間的字符串。 
精確查找PHP WEBSHELL木馬 修正版
python腳本檢測PHP WEBSHELL 
然后我將這段代碼寫入程序中,測試跑了一下discuz的程序。結果有一個誤報。誤報的位置為“config.inc.php”中的“define(‘UC_DBTABLEPRE', ‘`ucenter`.uc_');”,什么原因造成的?這行代碼符合了前面有閉合的引號,也有反引號的使用,所以,符合要求,被檢測到了。如何再排除這種情況呢?這個有什么特殊的?前面有逗號“,”?如果是字符串連接的點號“.”呢?再排除逗號? 

好吧,我錯了,我不該用我的思維來誤導你。換個思路。找下反引號可執行的代碼的前面字符串的情況,他們只能是行的開始,或者有空白字符(包括空格,tab鍵等),再前面也可以有代碼的結束標識分號“;”,其他的情況,都是不可以執行的吧?嗯,應該是這樣。(如有錯誤,歡迎斧正)既然思路有了,那正則代碼更好寫了。如下【(^|(?<=;))/s*`[^`]+`】,解釋一下,【(^|(?<=;))】匹配位置,是行的開始,或者前面有分號“;”?!?s*`[^`]+`】空白字符任一個,然后是….(你懂的)。OK,寫好之后,檢測,又發現一個問題。 
精確查找PHP WEBSHELL木馬 修正版
匹配引入文件的正則也匹配了“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'''(?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() 

稍微檢測了一下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'''(?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() 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产亚洲日本欧美韩国| 怡红院精品视频| 亚洲精品按摩视频| 91大神福利视频在线| 国产做受69高潮| 国产精品wwwwww| 欧美日韩亚洲视频一区| 色综合色综合久久综合频道88| 日韩国产中文字幕| 日韩视频第一页| 国产一区二区三区视频免费| 精品日韩中文字幕| 欧美亚洲一级片| 欧美成人一区二区三区电影| 欧美黑人性生活视频| 欧美日本高清视频| 亚洲无线码在线一区观看| xxxx欧美18另类的高清| 亚洲国产成人在线播放| 91高清视频在线免费观看| 97香蕉久久超级碰碰高清版| 国产精品日韩久久久久| 日韩在线一区二区三区免费视频| 国产性色av一区二区| 奇米4444一区二区三区| 国产在线观看不卡| 亚洲国产精品字幕| 2019中文字幕免费视频| 91系列在线观看| 在线播放日韩欧美| 欧美另类老女人| 亚洲一区二区三区视频| 日韩免费av在线| 国产精品视频专区| 中文字幕日韩欧美精品在线观看| 尤物yw午夜国产精品视频明星| 久久久久久国产免费| 欧美性69xxxx肥| 日本成人免费在线| 51精品国产黑色丝袜高跟鞋| 中文日韩电影网站| 欧美性猛交xxxx免费看久久久| 欧美极品少妇xxxxⅹ裸体艺术| 最近2019免费中文字幕视频三| 一本色道久久综合狠狠躁篇的优点| 欧美一区深夜视频| 国产免费一区二区三区在线观看| 一区二区三区亚洲| 97在线视频免费看| 亚洲视频在线视频| 久久免费国产视频| 日韩av日韩在线观看| 亚洲国产欧美一区二区三区同亚洲| 亚洲一级免费视频| 视频直播国产精品| 国产欧美精品va在线观看| 亚洲v日韩v综合v精品v| 日韩国产高清视频在线| 日韩成人xxxx| 亚洲国产成人精品一区二区| 在线电影中文日韩| 性色av一区二区三区免费| 欧美丰满少妇xxxxx做受| 91沈先生作品| 97国产精品人人爽人人做| 国产亚洲精品综合一区91| 亚洲欧美日韩精品久久| 精品视频www| 欧美国产精品va在线观看| 欧美日韩免费在线| 国产亚洲精品美女久久久| 欧美专区在线视频| 菠萝蜜影院一区二区免费| 最近2019年好看中文字幕视频| 国产一区玩具在线观看| 日韩欧美国产网站| 国产精品国产自产拍高清av水多| 国产精品福利久久久| 日韩精品视频在线| 国产精品第一视频| 国产精品看片资源| 久久精视频免费在线久久完整在线看| 欧美插天视频在线播放| 中文字幕日韩在线观看| 久久久久久久久爱| 亚洲最大的网站| 欧美综合激情网| 欧洲日本亚洲国产区| 岛国av一区二区在线在线观看| 1769国产精品| 国产91精品久久久| 精品一区二区三区三区| 亚洲国产精品美女| 色与欲影视天天看综合网| 久久精品福利视频| 日韩av影片在线观看| 欧美一性一乱一交一视频| 日韩视频免费在线| 国产精品第2页| 日韩欧美国产视频| 亚洲第一网站男人都懂| 国产精品久久久久久av| 色噜噜久久综合伊人一本| 亚洲欧美日韩一区在线| 亚洲精品视频久久| 日本一本a高清免费不卡| 欧美一区深夜视频| 69**夜色精品国产69乱| 欧美午夜宅男影院在线观看| 久久久亚洲影院你懂的| 日本aⅴ大伊香蕉精品视频| 91中文在线观看| 国产亚洲综合久久| 欧美猛少妇色xxxxx| 国产成人精品在线观看| 日韩高清av一区二区三区| 国产成人亚洲综合青青| 国产主播欧美精品| 日韩一区二区三区xxxx| 国产精品黄视频| 亚洲欧美日韩另类| 亚洲精品第一页| 日韩男女性生活视频| 91视频国产高清| 久久这里只有精品99| 91精品国产免费久久久久久| 亚洲欧美资源在线| 亚洲国产精品网站| 成人激情视频在线| 国产婷婷成人久久av免费高清| 91精品一区二区| 欧美电影免费观看大全| 尤物yw午夜国产精品视频明星| 国产精品扒开腿爽爽爽视频| 91日本视频在线| 国产欧美最新羞羞视频在线观看| 日韩欧美精品免费在线| 色婷婷av一区二区三区久久| 国产精品网站视频| 国产亚洲欧美aaaa| 日韩在线播放av| 久久精品国产精品亚洲| 亚洲第一页自拍| 亚洲日本欧美日韩高观看| 亚洲第一av在线| 久久久亚洲天堂| 日韩中文字幕视频在线观看| 中文字幕免费精品一区高清| 久久久久久国产精品三级玉女聊斋| 亚洲午夜精品视频| 亚洲高清久久久久久| 欧美国产中文字幕| 欧美日韩国产区| 久久免费国产精品1| 欧美成人午夜视频| 最近2019中文免费高清视频观看www99| www.国产一区| 国产精品对白刺激| 欧美电影院免费观看| 国语自产精品视频在线看抢先版图片| 国产成人精品电影久久久| 国产视频丨精品|在线观看| 色多多国产成人永久免费网站| 欧美成人性生活|