检测文件是否为木马 @time: 2025-02-19 @param file_path: 文件路径 @return: 是否可疑, 规则名称
(self, file_path: str)
| 422 | return True |
| 423 | |
| 424 | def detect(self, file_path: str) -> tuple: |
| 425 | """检测文件是否为木马 |
| 426 | @time: 2025-02-19 |
| 427 | @param file_path: 文件路径 |
| 428 | @return: <tuple> 是否可疑, 规则名称 |
| 429 | """ |
| 430 | try: |
| 431 | # 基础检查 |
| 432 | if not os.path.exists(file_path) or not os.path.isfile(file_path): |
| 433 | return False, '' |
| 434 | |
| 435 | # 检查文件大小 |
| 436 | file_size = os.path.getsize(file_path) |
| 437 | if file_size < 1024: # 小于1KB,视为空文件 |
| 438 | return False, '' |
| 439 | if file_size > 10 * 1024 * 1024: # 10MB限制 |
| 440 | return False, '' |
| 441 | |
| 442 | # 频率限制检查 |
| 443 | if not self._check_rate_limit(): |
| 444 | logging.warning("Cloud detection rate limit exceeded for: {}".format(file_path)) |
| 445 | return False, '' |
| 446 | |
| 447 | # 确保有可用的检测URL |
| 448 | if not self._update_check_url(): |
| 449 | return False, '' |
| 450 | |
| 451 | # 读取文件内容 |
| 452 | file_content = self.ReadFile(file_path) |
| 453 | if not file_content: |
| 454 | return False, '' |
| 455 | |
| 456 | # 计算文件MD5 |
| 457 | md5_hash = self.FileMd5(file_path) |
| 458 | if not md5_hash: |
| 459 | return False, '' |
| 460 | |
| 461 | # 发送检测请求 |
| 462 | try: |
| 463 | upload_data = { |
| 464 | 'inputfile': file_content, |
| 465 | 'md5': md5_hash |
| 466 | } |
| 467 | response = requests.post(self.check_url, upload_data, timeout=20) |
| 468 | # 添加响应内容检查 |
| 469 | if not response.content: |
| 470 | # logging.error("Empty response from cloud detection for file: {}".format(file_path)) |
| 471 | return False, '' |
| 472 | try: |
| 473 | result = response.json() |
| 474 | except json.JSONDecodeError as je: |
| 475 | # logging.error("Invalid JSON response from cloud detection for {}: {}".format(file_path, response.content)) |
| 476 | return False, '' |
| 477 | |
| 478 | # 查看是否需要告警 |
| 479 | if isinstance(result, dict) and result.get('msg') == 'ok': |
| 480 | try: |
| 481 | is_webshell = result.get('data', {}).get('data', {}).get('level') == 5 |
nothing calls this directly
no test coverage detected