# # coding: utf-8
# # +-------------------------------------------------------------------
# # | aaPanel x6
# # +-------------------------------------------------------------------
# # | Copyright (c) 2015-2017 aaPanel(www.aapanel.com) All rights reserved.
# # +-------------------------------------------------------------------
# # | Author: lkqiang <lkq@aapanel.com>
# # +-------------------------------------------------------------------
# # +--------------------------------------------------------------------
# # |   宝塔webshell 内置扫描
# # +--------------------------------------------------------------------
#
# import public, hashlib, os, sys, json, time, re
# import send_mail
#
#
# class webshell_check:
#     __PATH = '/www/server/panel/data/'
#     __mail_config = '/www/server/panel/data/stmp_mail.json'
#     __mail_list_data = '/www/server/panel/data/mail_list.json'
#     __dingding_config = '/www/server/panel/data/dingding.json'
#     __mail_list = []
#     __weixin_user = []
#
#     def __init__(self):
#         self.mail = send_mail.send_mail()
#         if not os.path.exists(self.__mail_list_data):
#             ret = []
#             public.writeFile(self.__mail_list_data, json.dumps(ret))
#         else:
#             try:
#                 mail_data = json.loads(public.ReadFile(self.__mail_list_data))
#                 self.__mail_list = mail_data
#             except:
#                 ret = []
#                 public.writeFile(self.__mail_list_data, json.dumps(ret))
#         if not os.path.exists(self.__PATH + 'webshell_rule.json'):
#             rule = ["@\\$\\_\\(\\$\\_", "\\$\\_=\"\"", "\\${'\\_'",
#                     "@preg\\_replace\\((\")*\\/(\\S)*\\/e(\")*,\\$_POST\\[\\S*\\]", "base64\\_decode\\(\\$\\_",
#                     "'e'\\.'v'\\.'a'\\.'l'", "\"e\"\\.\"v\"\\.\"a\"\\.\"l\"", "\"e\"\\.\"v\"\\.\"a\"\\.\"l\"",
#                     "\\$(\\w)+\\(\"\\/(\\S)+\\/e", "\\(array\\)\\$_(POST|GET|REQUEST|COOKIE)", "\\$(\\w)+\\(\\${",
#                     "@\\$\\_=", "\\$\\_=\\$\\_", "chr\\((\\d)+\\)\\.chr\\((\\d)+\\)", "phpjm\\.net", "cha88\\.cn",
#                     "c99shell", "phpspy", "Scanners", "cmd\\.php", "str_rot13", "webshell", "EgY_SpIdEr",
#                     "tools88\\.com", "SECFORCE", "eval\\(('|\")\\?>", "preg_replace\\(\"\\/\\.\\*\\/e\"",
#                     "assert\\(('|\"|\\s*)\\$", "eval\\(gzinflate\\(", "gzinflate\\(base64_decode\\(",
#                     "eval\\(base64_decode\\(", "eval\\(gzuncompress\\(", "ies\",gzuncompress\\(\\$",
#                     "eval\\(gzdecode\\(", "eval\\(str_rot13\\(", "gzuncompress\\(base64_decode\\(",
#                     "base64_decode\\(gzuncompress\\(", "eval\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)",
#                     "assert\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)",
#                     "require\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)",
#                     "require_once\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)",
#                     "include\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)",
#                     "include_once\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)", "call_user_func\\((\"|')assert(\"|')",
#                     "call_user_func\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)",
#                     "\\$_(POST|GET|REQUEST|COOKIE)\\[([^\\]]+)\\]\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)\\[",
#                     "echo\\(file_get_contents\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)",
#                     "file_put_contents\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)\\[([^\\]]+)\\],('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)",
#                     "fputs\\(fopen\\((.+),('|\")w('|\")\\),('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)\\[",
#                     "SetHandlerapplication\\/x-httpd-php", "php_valueauto_prepend_file", "php_valueauto_append_file"]
#             public.WriteFile(self.__PATH + 'webshell_rule.json', json.dumps(rule))
#
#     # 返回配置邮件地址
#     def return_mail_list(self):
#         return self.__mail_list
#
#     # 查看自定义邮箱配置
#     def get_user_mail(self):
#         qq_mail_info = json.loads(public.ReadFile(self.__mail_config))
#         if len(qq_mail_info) == 0:
#             return False
#         return qq_mail_info
#
#     # 查看钉钉
#     def get_dingding(self):
#         qq_mail_info = json.loads(public.ReadFile(self.__dingding_config))
#         if len(qq_mail_info) == 0:
#             return False
#         return qq_mail_info
#
#     # 查看能使用的告警通道
#     def get_settings(self):
#         qq_mail_info = json.loads(public.ReadFile(self.__mail_config))
#         if len(qq_mail_info) == 0:
#             user_mail = False
#         else:
#             user_mail = True
#         dingding_info = json.loads(public.ReadFile(self.__dingding_config))
#         if len(dingding_info) == 0:
#             dingding = False
#         else:
#             dingding = True
#         ret = {}
#         ret['user_mail'] = {"user_name": user_mail, "mail_list": self.__mail_list, "info": self.get_user_mail()}
#         ret['dingding'] = {"dingding": dingding, "info": self.get_dingding()}
#         return ret
#
#     # 返回站点
#     def return_site(self):
#         data = public.M('sites').field('name,path').select()
#         ret = {}
#         for i in data:
#             ret[i['name']] = i['path']
#         return public.returnMsg(True, ret)
#
#     # 获取规则
#     def get_rule(self):
#         ret = []
#         if os.path.exists(self.__PATH + 'webshell_rule.json'):
#             try:
#                 data = json.loads(public.ReadFile(self.__PATH + 'webshell_rule.json'))
#                 return data
#             except:
#                 return False
#         else:
#             return False
#
#     def get_dir(self, path):
#         return_data = []
#         data2 = []
#         [[return_data.append(os.path.join(root, file)) for file in files] for root, dirs, files in os.walk(path)]
#         for i in return_data:
#             if str(i.lower())[-4:] == '.php':
#                 data2.append(i)
#         return data2
#
#     # 目录
#     def getdir_list(self, path_data):
#         if os.path.exists(str(path_data)):
#             return self.get_dir(path_data)
#         else:
#             return False
#
#     # 扫描
#     def scan(self, filelist, rule):
#         import time
#         time_data = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
#         ret = []
#         data2 = []
#         for file in filelist:
#             try:
#                 data = open(file).read()
#                 for r in rule:
#                     if re.compile(r).findall(data):
#                         result = {}
#                         result[file] = r
#                         ret.append(result)
#                         data = ("%s [!] %s %s  \n" % (time_data, file, r))
#                         data2.append(file)
#             except:print('%s File opening failed! !! Skipping'%file)
#         return data2
#
#     # 上传webshell
#     def upload_shell(self, data):
#         if len(data) == 0: return []
#         return_data = []
#         for i in data:
#             if self.upload_file_url(i):
#                 return_data.append(i)
#         return return_data
#
#     def san_dir(self, path, send='mail'):
#         file = self.getdir_list(path)
#         if not file: return exit( "Directory does not exist")
#         rule = self.get_rule()
#         if not rule: return exit("Rule is empty or rule file is wrong")
#         result = self.scan(file, rule)
#         return_data = self.upload_shell(result)
#         tongdao = self.get_settings()
#         if len(return_data) >= 1:
#             if send == 'dingding':
#                 if tongdao['dingding']:
#                     msg="Webshell killing found the Trojan in the % s directory as follows:%s"%(path,return_data)
#                     self.mail.dingding_send(msg)
#             elif send == 'mail':
#                 if tongdao['user_mail']:
#
#                     title = "Webshell killing found the Trojan in the % s directory as follows" % (path)
#                     body = "Webshell search and found that the Trojan exists in the %s directory as follows: %s" % (path, return_data)
#                     if len(self.__mail_list)==0:
#             			if tongdao['user_mail']['user_name']:
#                         		self.mail.qq_smtp_send(str(tongdao['user_mail']['info']['qq_mail']), title=title, body=body)
#                     else:
#                         for i in self.__mail_list:
#                             if tongdao['user_mail']['user_name']:
#                                 self.mail.qq_smtp_send(str(i), title=title, body=body)
#         return return_data
#
#     def send_san_dir(self, path, send):
#         file = self.getdir_list(path)
#         if not file: return exit( "Directory does not exist")
#         rule = self.get_rule()
#         if not rule: return exit("Rule is empty or rule file is wrong")
#         result = self.scan(file, rule)
#         return_data = self.upload_shell(result)
#         tongdao = self.get_settings()
#         if len(return_data) >= 1:
#             if send == 'dingding':
#                 if tongdao['dingding']:
#                     msg="Webshell search and found that the Trojan exists in the %s directory as follows: %s"%(path,return_data)
#                     self.mail.dingding_send(msg)
#             elif send == 'mail':
#                 if tongdao['user_mail']:
#                     title = "Webshell killing found the Trojan in the %s directory as follows" % (path)
#                     body = "Webshell search and found that the Trojan exists in the %s directory as follows: %s" % (path, return_data)
#                     if len(self.__mail_list)==0:
#                         self.mail.qq_smtp_send(str(tongdao['user_mail']['info']['qq_mail']), title=title, body=body)
#                     else:
#                         for i in self.__mail_list:
#                             self.mail.qq_smtp_send(str(i), title=title, body=body)
#         return return_data
#
#     def upload_file_url(self, filename):
#         try:
#             if os.path.exists(filename):
#                 data = public.ExecShell(
#                     '/usr/local/curl/bin/curl https://scanner.baidu.com/enqueue -F archive=@%s' % filename)
#                 data = json.loads(data[0])
#                 time.sleep(3)
#                 import http_requests
#                 default_headers = {
#                     'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
#                 }
#                 data_list = http_requests.get(url=data['url'], headers=default_headers, verify=False)
#                 data2 = data_list.json()
#                 if 'data' in data2[0]:
#                     if len(data2[0]['data']) >= 1:
#                         if 'descr' in data2[0]['data'][0]:
#                             if 'WebShell' in data2[0]['data'][0]['descr']:
#                                 print('%s file is a Trojan'%filename)
#                                 self.send_baota2(filename)
#                                 return True
#                 return False
#             else:
#                 return False
#         except:
#             return False
#
#     def read_file_md5(self, filename):
#         if os.path.exists(filename):
#             with open(filename, 'rb') as fp:
#                 data = fp.read()
#             file_md5 = hashlib.md5(data).hexdigest()
#             return file_md5
#         else:
#             return False
#
#     def send_baota2(self, filename):
#         cloudUrl = 'http://www.bt.cn/api/panel/btwaf_submit'
#         pdata = {'codetxt': public.ReadFile(filename), 'md5': self.read_file_md5(filename), 'type': '0',
#                  'host_ip': public.GetLocalIp(), 'size': os.path.getsize(filename)}
#         ret = public.httpPost(cloudUrl, pdata)
#         return True
#
#     def send_baota(self, filename):
#         if not os.path.exists(filename): return False
#         cloudUrl = 'http://www.bt.cn/api/panel/btwaf_submit'
#         pdata = {'codetxt': public.ReadFile(filename), 'md5': self.read_file_md5(filename), 'type': '0',
#                  'host_ip': public.GetLocalIp(), 'size': os.path.getsize(filename)}
#         ret = public.httpPost(cloudUrl, pdata)
#         if ret == '1':
#             return self.check_webshell(filename)
#         elif ret == '-1':
#             return self.check_webshell(filename)
#         else:
#             return False
#
#     def check_webshell(self, filename):
#         if not os.path.exists(filename): return False
#         cloudUrl = 'http://www.bt.cn/api/panel/btwaf_check_file'
#         pdata = {'md5': self.read_file_md5(filename), 'size': os.path.getsize(filename)}
#         ret = public.httpPost(cloudUrl, pdata)
#         if ret == '0':
#             return False
#         elif ret == '1':
#             return False
#         elif ret == '-1':
#             return False
#         else:
#             return False
#
#     def __get_md5(self, s):
#         m = hashlib.md5()
#         m.update(s.encode('utf-8'))
#         return m.hexdigest()
#
#
# if __name__ == "__main__":
#     public.WriteFile('/www/server/panel/data/webshell_data.json', json.dumps([]))
#     type = sys.argv[1]
#     path = sys.argv[2]
#     send = sys.argv[3]
#     os.chdir("/www/server/panel")
#     import sys
#     sys.path.append('class')
#     import public
#     aa = webshell_check()
#     print('Start scanning webshell')
#     start_time=time.time()
#     if type == 'dir':
#         data = aa.san_dir(path)
#         public.WriteFile('/www/server/panel/data/webshell_data.json', json.dumps(data))
#         localtime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
#         if len(data) >= 1:
#             public.WriteLog('aaPanel built-in webshell killing','Killing the %s directory found the following Trojan %s'%(path,data))
#         else:
#         	public.WriteLog('aaPanel built-in webshell killing','Checking and killing [ %s ] directory did not find any risks'%(path))
#     elif type=='site':
#         data = public.M('sites').where('name=?', (path,)).field('name,id,path').select()
#         localtime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
#         if len(data) >= 1:
#             path = data[0]['path']
#             ##木马返回在这里
#             data = aa.send_san_dir(path, send)
#             if len(data) >= 1:
#                 public.WriteLog('aaPanel built-in webshell killing', 'Killing the %s directory found the following Trojan %s' % (path, data))
#             else:
#             	public.WriteLog('aaPanel built-in webshell killing','Checking and killing [ %s ] directory did not find any risks'%(path))
#
#
