كتابة الـ Finding التقني
أجزاء أي Finding: العنوان، والخطورة، والمكان، والوصف، والـ Impact، والخطوات، والدليل، والإصلاح، والمراجع… بمثال كامل.
نص شرح المعلم والكود الذي كتبه ونتيجة تشغيله، بنفس ترتيب الدرس.
أهلاً بيك. الـ Finding هو الوحدة الأساسية في التقرير. ولو كل Finding مكتوب بنفس الشكل، القارئ بيعرف يلاقي اللي عايزه في ثانْيَة.
الأجزاء: ID وعنوان واضح، يقول المشكلة وفين. الخطورة والـ CVSS. الـ Affected: الـ URL أو الـ host أو الـ parameter بالزبط. الوصف: المشكلة إيه، وليه حصلت.
وبعدين: الـ Impact: المهاجم يقدر يعمل إيه. الـ Steps to Reproduce. الـ Evidence مع الـ Hash. الـ Remediation: الإصلاح. والـ References، زي OWASP و CWE، علشان المطور يقرا أكتر. والعنوان مهم قوي. عنوان وحش: SQL Injection. عنوان كويس: SQL Injection في الـ login form بيسمح بقراية قاعدة البيانات. من العنوان بس، القارئ فهم المشكلة ومكانها وخطورتها. نكتب Finding كامل كـ dictionary ونطبعه. بس فيه حاجة ناقصة… شوف لوحدك. نشغّل… الـ fix فاضي. Finding من غير إصلاح، نصّه ناقص.
finding = {
"id": "F-01",
"title": "SQL Injection in login form",
"severity": "Critical (CVSS 9.8)",
"affected": "http://10.10.10.5/login.php (username)",
"description": "User input is added directly to the SQL query.",
"impact": "An attacker can read the whole customer database.",
"steps": ["Open /login.php", "Username: admin' OR 1=1-- -", "Logged in as admin"],
"evidence": "F-01-admin.png (sha256: 3f9a...)",
"fix": "",
"references": "OWASP A03:2021, CWE-89",
}
for key, value in finding.items():
if isinstance(value, list):
print(f"{key}:")
for i, s in enumerate(value, 1):
print(f" {i}. {s}")
else:
print(f"{key}: {value}")المخرجات
id: F-01 title: SQL Injection in login form severity: Critical (CVSS 9.8) affected: http://10.10.10.5/login.php (username) description: User input is added directly to the SQL query. impact: An attacker can read the whole customer database. steps: 1. Open /login.php 2. Username: admin' OR 1=1-- - 3. Logged in as admin evidence: F-01-admin.png (sha256: 3f9a...) fix: references: OWASP A03:2021, CWE-89
نخلّي الـ code يكتشف ده لوحده: list بالأجزاء المطلوبة، ويطبع أي جزء فاضي. نشغّل… missing fix.
finding = {
"id": "F-01",
"title": "SQL Injection in login form",
"severity": "Critical (CVSS 9.8)",
"affected": "http://10.10.10.5/login.php (username)",
"description": "User input is added directly to the SQL query.",
"impact": "An attacker can read the whole customer database.",
"steps": ["Open /login.php", "Username: admin' OR 1=1-- -", "Logged in as admin"],
"evidence": "F-01-admin.png (sha256: 3f9a...)",
"fix": "",
"references": "OWASP A03:2021, CWE-89",
}
required = ["title", "severity", "affected", "impact", "steps", "evidence", "fix"]
missing = [k for k in required if not finding.get(k)]
print("missing:", missing or "nothing")
for key, value in finding.items():
if isinstance(value, list):
print(f"{key}:")
for i, s in enumerate(value, 1):
print(f" {i}. {s}")
else:
print(f"{key}: {value}")المخرجات
missing: ['fix'] id: F-01 title: SQL Injection in login form severity: Critical (CVSS 9.8) affected: http://10.10.10.5/login.php (username) description: User input is added directly to the SQL query. impact: An attacker can read the whole customer database. steps: 1. Open /login.php 2. Username: admin' OR 1=1-- - 3. Logged in as admin evidence: F-01-admin.png (sha256: 3f9a...) fix: references: OWASP A03:2021, CWE-89
دورك: اكتب الـ fix: استخدم parameterized queries، وشغّل تاني لحد ما مايبقاش فيه حاجة ناقصة.
املا الـ fix بـ Use parameterized queries (prepared statements).
الحل: نشغّل… Finding كامل.
finding = {
"id": "F-01",
"title": "SQL Injection in login form",
"severity": "Critical (CVSS 9.8)",
"affected": "http://10.10.10.5/login.php (username)",
"description": "User input is added directly to the SQL query.",
"impact": "An attacker can read the whole customer database.",
"steps": ["Open /login.php", "Username: admin' OR 1=1-- -", "Logged in as admin"],
"evidence": "F-01-admin.png (sha256: 3f9a...)",
"fix": "Use parameterized queries (prepared statements).",
"references": "OWASP A03:2021, CWE-89",
}
required = ["title", "severity", "affected", "impact", "steps", "evidence", "fix"]
missing = [k for k in required if not finding.get(k)]
print("missing:", missing or "nothing")
for key, value in finding.items():
if isinstance(value, list):
print(f"{key}:")
for i, s in enumerate(value, 1):
print(f" {i}. {s}")
else:
print(f"{key}: {value}")المخرجات
missing: nothing id: F-01 title: SQL Injection in login form severity: Critical (CVSS 9.8) affected: http://10.10.10.5/login.php (username) description: User input is added directly to the SQL query. impact: An attacker can read the whole customer database. steps: 1. Open /login.php 2. Username: admin' OR 1=1-- - 3. Logged in as admin evidence: F-01-admin.png (sha256: 3f9a...) fix: Use parameterized queries (prepared statements). references: OWASP A03:2021, CWE-89
الدرس الجاي: الـ fix ده نفسه… إزاي تكتب توصية إصلاح محددة، والعميل يقدر ينفّدها فعلاً. يلا بينا.
03 / دروس المسار (21)
- 01ليه التقرير أهم حاجة في الـ Pentest
- 02مين بيقرا التقرير؟
- 03نظام Notes من أول دقيقة
- 04Activity Log: كل حاجة بالوقت
- 05خلّي الـ Terminal يسجّل لوحده
- 06الأدلة: إيه اللي يعتبر دليل؟
- 07سلامة الأدلة: Hash و Chain of Custody
- 08إخفاء البيانات الحساسة (Redaction)
- 09خطوات إعادة التنفيد (Steps to Reproduce)
- 10الـ Impact: الخطر الحقيقي على البيزنس
- 11CVSS: الخطورة برقم
- 12الـ Risk Matrix: الاحتمال في الـ Impact
- 13ترتيب الأولويات والـ Quick Wins
- 14هيكل تقرير اختبار الاختراق
- 15الـ Executive Summary: صفحة للإدارة
- 16كتابة الـ Finding التقنيانت هنا
- 17توصيات الإصلاح اللي تتنفّد فعلاً
- 18خلّي Python يكتب التقرير
- 19المراجعة قبل التسليم والـ Retest
- 20تقرير امتحان OSCP
- 21المراجعة النهائية: من الـ Note للتقرير