├── .gitignore ├── README.md ├── __init__.py ├── core.py ├── demo.tar ├── dictionaries └── rule.txt ├── result └── result.txt ├── scan.py └── util ├── __init__.py ├── operation.py └── traversal_dir.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | .DS_Store 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | env/ 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .coverage 43 | .coverage.* 44 | .cache 45 | nosetests.xml 46 | coverage.xml 47 | *,cover 48 | .hypothesis/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | 58 | # Flask instance folder 59 | instance/ 60 | 61 | # Sphinx documentation 62 | docs/_build/ 63 | 64 | # PyBuilder 65 | target/ 66 | 67 | # IPython Notebook 68 | .ipynb_checkpoints 69 | 70 | # pyenv 71 | .python-version 72 | 73 | # dotenv 74 | .env 75 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## scaing-backdoor 2 | 3 | 4 | 新一代Webshell扫描工具,通过各种规则和算法实现服务器脚本后门查杀。 5 | 6 | 目前已实现功能: 7 | 8 | + 根据关键字静态扫描webshell 9 | 10 | 11 | ### 使用说明 12 | 13 | ➜ python scan.py -h 14 | scan usage: 15 | 简单使用:scan.py filepath 16 | -h,--help: 获取帮助信息. 17 | -v, --version: 获取scan版本 18 | -p,--path: 指定将要扫描的路径 19 | -l,--low: 系统/数据库弱密码扫描 20 | 21 | ### TODO 22 | 23 | + 文件大小判断(可配置选项) 24 | + 支持多命令选项 25 | + 动态扫描 26 | + 十六进制度读取文件 27 | + 提取webshell关键字 28 | + 弱密码提示/潜在威胁提示 29 | + 提供多系统支持 30 | + 特征库包含各种木马/病毒/文件路径/cms/shell/框架信息等特征码为各个平台提供特征码支持 -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SecWiki/scaing-backdoor/c7804ad02d085f0d1655236a19dbdc041d1fc8f4/__init__.py -------------------------------------------------------------------------------- /core.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | #Version: 0.01 5 | #Create: 2016-01-30 6 | #Authoruis: kun/ 7 | 8 | import array 9 | import sys 10 | 11 | from util import traversal_dir 12 | from util import operation 13 | 14 | #木马特征 15 | def start(param): 16 | print "scaninng now....." 17 | ls = operation.readRetList("dictionaries/rule.txt")#TODO 读取方式升级为用户自定义 18 | cmp(param, ls) 19 | 20 | print "result.txt 结果已保存到result目录" 21 | 22 | #查找木马 23 | def cmp(dir, features): 24 | suspicious = [] 25 | file_list = traversal_dir.traversal_dir(dir) 26 | for filepath in file_list: 27 | if operation.findListStr(filepath, features):#TODO 根据查找到的特征数量定义优先级 28 | suspicious.append(filepath + "\n") 29 | operation.writeList("result/result.txt", suspicious,'w')#TODO 写入方式升级为用户自定义路径 30 | 31 | #检测服务器系统文件 32 | def chkSysFile(): 33 | 34 | 35 | 36 | 37 | if __name__ == '__main__': 38 | start(sys.argv[1]) 39 | 40 | -------------------------------------------------------------------------------- /demo.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SecWiki/scaing-backdoor/c7804ad02d085f0d1655236a19dbdc041d1fc8f4/demo.tar -------------------------------------------------------------------------------- /dictionaries/rule.txt: -------------------------------------------------------------------------------- 1 | .exec( 2 | -------------------------------------------------------------------------------- /result/result.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SecWiki/scaing-backdoor/c7804ad02d085f0d1655236a19dbdc041d1fc8f4/result/result.txt -------------------------------------------------------------------------------- /scan.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | #Version: 0.01 5 | #Create: 2016-01-30 6 | #Authoruis: kun/ 7 | 8 | import sys 9 | import getopt 10 | import core 11 | 12 | def Usage(): 13 | print 'scan usage:' 14 | print '简单使用:scan.py filepath' 15 | print '-h,--help: 获取帮助信息.' 16 | print '-v, --version: 获取scan版本' 17 | print '-p,--path: 指定将要扫描的路径' 18 | print '-l,--low: 系统/数据库弱密码扫描' 19 | def Version(): 20 | print 'scan 0.01 BASE' 21 | def OutPut(args): 22 | print 'Hello, %s'%args 23 | def main(argv): 24 | try: 25 | opts, args = getopt.getopt(argv[1:], 'hvp:', ['path=']) 26 | except getopt.GetoptError, err: 27 | print str(err) 28 | Usage() 29 | sys.exit(2) 30 | if len(opts) == 0: 31 | if len(args): 32 | core.start(args[0]) 33 | else: 34 | print "scanning [options] [param]" 35 | for o, a in opts: 36 | if o in ('-h', '--help'): 37 | Usage() 38 | sys.exit(1) 39 | elif o in ('-v', '--version'): 40 | Version() 41 | sys.exit(0) 42 | elif o in ('-p',): 43 | core.start(a) 44 | sys.exit(0) 45 | else: 46 | Usage() 47 | sys.exit(3) 48 | 49 | if __name__ == '__main__': 50 | main(sys.argv) 51 | -------------------------------------------------------------------------------- /util/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SecWiki/scaing-backdoor/c7804ad02d085f0d1655236a19dbdc041d1fc8f4/util/__init__.py -------------------------------------------------------------------------------- /util/operation.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | #Version: 0.01 5 | #Create: 2016-01-30 6 | #Authoruis: kun/ 7 | 8 | import array 9 | import os 10 | import re 11 | 12 | #读取文件 返回值:整个文件内容 13 | def read(filepath): 14 | text = '' 15 | try: 16 | file_object = open(filepath) 17 | text = file_object.read() 18 | file_object.close() 19 | except IOError: 20 | pass 21 | print filepath, "\topen fail !" 22 | text = -1 23 | return text 24 | 25 | #读取文件 返回值:list 26 | def readRetList(filepath): 27 | ls = [] 28 | try: 29 | file_object = open(filepath) 30 | except IOError: 31 | pass 32 | while 1: 33 | line = file_object.readline() 34 | if not len(line): 35 | break 36 | ls.append(line.strip("\n")) 37 | file_object.close() 38 | return ls 39 | 40 | 41 | #将text写入文件 42 | def write(filepath, text, type): 43 | file_object = open(filepath, type) 44 | try: 45 | file_object.write(text) 46 | finally: 47 | file_object.close() 48 | 49 | #将一个list写入文件,无换行 50 | def writeList(filepath, list, type): 51 | file_object = open(filepath, type) 52 | try: 53 | file_object.writelines(list) 54 | finally: 55 | file_object.close() 56 | 57 | 58 | 59 | #查找filepath文件内容是否包含str字符串 60 | #不包含返回 -1 61 | def find(filepath, str): 62 | file_text = read(filepath) 63 | return file_text.lower().find(str.lower()) 64 | 65 | #文件中查找集合中的字符串,返回值:strList中字符串在文件中存在的数量 66 | def findListStr(filepath, strList): 67 | flag = 0 68 | file_text = read(filepath) 69 | if file_text != -1: 70 | for str in strList: 71 | if file_text.lower().find(str.lower()) != -1: 72 | print str , "\t\t==>",filepath 73 | if flag: 74 | flag += flag 75 | else: 76 | flag = 1 77 | file_text.lower().find(str.lower()) 78 | return flag 79 | 80 | def test(): 81 | print read("../dictionaries/rule.txt") 82 | 83 | 84 | if __name__ == '__main__': 85 | test(); 86 | -------------------------------------------------------------------------------- /util/traversal_dir.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | #Version: 0.01 5 | #Create: 2016-01-30 6 | #Authoruis: kun/ 7 | 8 | import os 9 | 10 | 11 | list = [] 12 | #遍历目录 13 | def traversal_dir(filepath, prin=False): 14 | #遍历filepath下所有文件,包括子目录 15 | files = [] 16 | try: 17 | files = os.listdir(filepath) 18 | except OSError: 19 | pass 20 | print filepath,"\t The folder does not exist!" 21 | if len(files): 22 | for fi in files: 23 | fi_d = os.path.join(filepath,fi) 24 | if os.path.isdir(fi_d): 25 | traversal_dir(fi_d, prin) 26 | else: 27 | if prin : 28 | print os.path.join(filepath,fi_d) 29 | list.append(os.path.join(filepath,fi_d))#添加遍历到的文件 30 | return list 31 | 32 | def print_files(self): 33 | for ls in list: 34 | print ls 35 | 36 | 37 | def test(): 38 | #递归遍历所有文件 39 | traversal_dir('Desktop') 40 | print_files() 41 | 42 | 43 | if __name__ == '__main__': 44 | test() 45 | --------------------------------------------------------------------------------