ارواح الشياطين
34 subscribers
20 photos
19 videos
17 links
اختصاص اسقاط مواقع دوس اتاك وتنفيذ ثغرات
(اسامه الموسوي + مارس)
Download Telegram
إليك قائمة الأكواد التي تقوم بكشف العناصر المخفيه داخل جوال هوست مع شرح لكل كود:

1. كشف العناصر المخفية وإظهارها:

    document.querySelectorAll('.nosel.uzr').forEach(function(el) {
el.style.display = '';
});

- الشرح: يقوم هذا الكود بإعادة تعيين خاصية display لجميع العناصر التي تحمل الصنف .nosel.uzr إلى القيمة الافتراضية، مما قد يجعلها مرئية إذا كانت مخفية.

2. **إزالة خاصية display باستخدام jQuery:**

    $(".nosel.uzr").css("display", "")

الشرح:ح:** يستخدم jQuery لإزالة خاصية display من جميع العناصر التي تحمل الصنف .nosel.uzr, مما يجعلها مرئية.

3. **إزالة خاصية display عبر style.removeProperty:**

    document.querySelectorAll('.nosel.uzr').forEach(element => {
element.style.removeProperty('display');
});

- **الشرح:** يقوم بإزالة خاصية display من جميع العناصر التي تحمل الصنف .nosel.uzr, مما يمكن أن يجعلها مرئية.

4. **إزالة display وvisibility:**

    document.querySelectorAll('.nosel.uzr').forEach(element => {
element.style.removeProperty('display');
element.style.removeProperty('visibility');
});

- **الشرح:** يقوم بإزالة خصائص display وvisibility من العناصر، مما يجعلها مرئية إذا كانت مخفية باستخدام هإظهار العناصر وإضافة زر جديد:صر وإضافة زر جديد:**

    document.querySelectorAll('.nosel.uzr').forEach(element => {
element.style.display = 'block';
element.style.visibility = 'visible';
element.style.position = 'relative';
element.style.zIndex = '9999';

const newElement = document.createElement('button');
newElement.innerText = 'زر جديد';
newElement.style.margin = '10px';
element.appendChild(newElement);

newElement.addEventListener('click', function() {
alert('تم النقر على الزر الجديد');
});
});

- **الشرح:** يقوم بإظهار العناصر التي تحمل الصنف .nosel.uzr وإضافة زر جديد إلى كل منها. الزر يقوم بعرض تنكشف العناصر وإجراء عمليات محاكاة: وإجراء عمليات محاكاة:**

    document.querySelectorAll('.nosel.uzr').forEach(element => {
element.style.display = 'block';
element.style.visibility = 'visible';
element.style.position = 'relative';
element.style.zIndex = '9999';

const scrollEvent = new Event('scroll', {
view: window,
bubbles: true,
cancelable: true
});
element.dispatchEvent(scrollEvent);

const dragStartEvent = new DragEvent('dragstart', {
dataTransfer: new DataTransfer()
});
const dragEndEvent = new DragEvent('dragend', {
dataTransfer: new DataTransfer()
});
element.dispatchEvent(dragStartEvent);
element.dispatchEvent(dragEndEvent);
});

- **الشرح:** يقوم بإظهار العناصر التي تحمل الصنف .nosel.uzr، ثم يحاكي أحداث التمرير وكشف العناصر المخفية وتعديل خصائصها:صر المخفية وتعديل خصائصها:**

    document.querySelectorAll('*').forEach(element => {
if (window.getComputedStyle(element).display === 'none' ||
window.getComputedStyle(element).visibility === 'hidden' ||
window.getComputedStyle(element).opacity === '0') {

element.style.display = 'block';
element.style.visibility = 'visible';
element.style.opacity = '1';
}
});

- **الشرح:** يقوم بفحص جميع العناصر في الصفحة، ويغير خصائص display, visibility, وopacity التفاعل مع العناصر المكشوفة:**التفاعل مع العناصر المكشوفة:**
`javascript
document.querySelectorAll('*').forEach(element => {
if (window.getComputedStyle(element).display !== 'none' &&
window.getComputedStyle(element).opacity !== '0') {

element.addEventListener('click', function() {
console.log('تم النقر على العنصر:', this);
});
}
});

- الشرح: يقوم بإضافة مستمع نقر لجميع العناصر التي لا تكون مخفية، ويطبع رسالة في وحدة التحكم عند النقر على أي منها.
الكود الذي قدمته يغير لون خلفية العناصر على صفحة الويب بين الأحمر والأخضر بشكل متناوب وسريع جدًا. يتم تنفيذ هذا التغيير تلقائيًا وبشكل متكرر باستخدام JavaScript.

### كيف يعمل الكود ببساطة:

1. البحث عن العناصر:
- الكود يبدأ بالبحث عن كل العناصر من نوع div في صفحة الويب ويحفظها في مجموعة.

2. تحديد الألوان:
- ثم يحدد اللونين الأحمر والأخضر كخيارات لتغيير الخلفية.

3. تبديل الألوان:
- الكود يستخدم دالة (setInterval) التي تعمل كل 50 مللي ثانية (أي حوالي 20 مرة في الثانية).
- في كل مرة تعمل فيها الدالة، يتم تغيير لون الخلفية لجميع عناصر div إلى إما الأحمر أو الأخضر بالتناوب.

4. التكرار المستمر:
- يستمر الكود في تبديل الألوان بين الأحمر والأخضر مرارًا وتكرارًا، مما يجعل الخلفية تبدو وكأنها تومض بسرعة.

### كيفية استخدامه:

- افتح أدوات المطور في المتصفح (عن طريق الضغط على زر الفأرة الأيمن واختيار "فحص").
- انسخ الكود والصقه في قسم "Console".
- اضغط Enter، وستلاحظ أن خلفية العناصر تبدأ في التغيير بين الأحمر والأخضر بسرعة.

بهذه الطريقة، الكود يجعل الخلفية تومض بين اللونين الأحمر والأخضر بشكل سريع جدا.

### نسخه من الكود سريعة جدًا (تغيير كل 50 مللي ثانية):

هذا الكود لن يُأثر علئ الاعضاء داخل الموقع لكن يمكنك تعديله لتجعله يأثر علئ الموقع تاثير حقيقي


let messages = document.querySelectorAll('div');

let colors = ['#FF0000', '#00FF00']; // الأحمر، الأخضر
let currentColor = 0;

setInterval(() => {
    messages.forEach(element => {
        element.style.backgroundColor = colors[currentColor];
    });
    currentColor = (currentColor + 1) % colors.length;
}, 50); // تغيير اللون كل 50 مللي ثانية
Channel name was changed to «ارواح الشياطين»
دشرح كيف يُفكر القراصنة أو الدول عند محاولتهم اختراق نظام عسكري مثل نظام إطلاق صواريخ (كمثال: إسرائيل أو أي دولة متقدمة).


---

💥 أولا: ما هو نظام إطلاق الصواريخ؟

نظام إطلاق الصواريخ يشمل:

1. وحدة القيادة والسيطرة (C2 – Command & Control)


2. أجهزة الحواسيب المدمجة (Embedded Systems)


3. أنظمة اتصالات مشفرة (Satellite, RF, Fiber)


4. برمجيات التحكم والإطلاق (Firmware/Software)


5. وحدات التخزين والمعالجة (Local + Cloud/Hybrid if any)



معظم هذه الأنظمة تكون "مغلقة" ومحمية بشكل صارم ومصممة لتكون غير متصلة بالشبكات العامة (مثل الإنترنت).


---

🔐 الحماية الأساسية

كيف تُبنى الحماية؟

Air-Gapping: الأجهزة مفصولة تمامًا عن الإنترنت.

Hardware-based Encryption: التشفير يتم على مستوى العتاد.

Multi-layer Authentication: أكثر من طريقة تحقق للوصول للنظام.

Tamper Detection: النظام يكشف التلاعب أو الوصول غير المصرح به.

Redundancy & Monitoring: وجود أنظمة مراقبة ورد فعل آلي.



---

🧠 منطق الاختراق: كيف يمكن نظريًا اختراق هذا النظام؟

المرحلة 1: الاستكشاف (Reconnaissance)

أول خطوة هي جمع معلومات استخباراتية عن النظام:

نوع المعالج (مثلاً ARM أو MIPS أو غيره)

نوع نظام التشغيل (Real-time OS، Linux خاص، الخ...)

الموردين والمصنعين للقطع الإلكترونية

طرق التحديث (USB؟ شبكة مغلقة؟ أقمار صناعية؟)


هذا عادة يتم من خلال:

وثائق مسربة

أخطاء شركات التوريد (Supply Chain)

الهندسة العكسية من أنظمة مشابهة

تسريبات بشرية (عملاء، مقاولي صيانة)



---

المرحلة 2: استغلال سلسلة التوريد (Supply Chain Attack)

نقطة الضعف الخطيرة دائمًا هي "الإنسان أو المورد":

إرسال قطعة إلكترونية تحتوي backdoor أثناء تصنيع النظام.

التلاعب بالبرمجيات في التحديثات قبل أن تصل إلى النظام.

زرع شيفرة خبيثة (firmware implant) في مرحلة مبكرة.


🔁 هذه الطريقة استخدمها فيروس Stuxnet في إيران.


---

المرحلة 3: الوصول الفيزيائي (Physical Access)

إذا لم يكن بالإمكان الاختراق عن بعد، تبقى الهجمات الفيزيائية:

دخول أحد العملاء الفيزيائيين وتركيب جهاز USB خاص.

استخدام إشارات كهرومغناطيسية (EM injection) للتشويش أو السيطرة.

زرع أجهزة تنصت أو Relay في الكابلات أو لوحات التحكم.



---

المرحلة 4: هجمات عن طريق الموجات اللاسلكية (RF)

إذا كان النظام يتصل عبر موجات أو أقمار صناعية:

يمكن "اعتراض" أو "تشويش" الإشارات.

في حالات نادرة، يمكن تقليد إشارة الأمر الحقيقي باستخدام معدات دقيقة (spoofing).

محاولة الهندسة العكسية للبروتوكول.


⚠️ هذه تتطلب معدات معقدة جدًا ومعلومات داخلية.


---

المرحلة 5: الاستغلال البرمجي (Software Exploits)

إذا كان هناك طريقة ما للوصول إلى البرنامج (سواء عبر جهاز طرفي أو شبكة):

استخدام ثغرة يوم الصفر (Zero-day) في نظام التشغيل أو البرنامج.

تعديل ملفات الإعداد (config) أو استبدال Firmware.

إدخال أوامر حقن (command injection) عبر مدخل غير محمي.



---

☠️ هل يمكن إطلاق صاروخ فعلاً إذا نجح الاختراق؟

نظريًا، نعم، إذا:

1. تم تجاوز جميع الحمايات.


2. تم الدخول إلى واجهة الإطلاق نفسها.


3. تم توفير الأكواد الصحيحة أو تجاوز التحقق.


4. تم التلاعب بجهاز فعلي جاهز ومهيأ للإطلاق.



لكن الواقع يقول: يتم بناء الأنظمة لتطلب تحقق متعدد المستويات — مثل إدخال رموز من عدة مصادر، وسماح من القيادة العليا، ووجود مشغّل بشري للموافقة اليدوية.


---

🧩 خلاصة سيناريوهات الاختراق الممكنة:

الطريقة درجة الصعوبة من يستطيع فعلها؟

1- هجوم شبكة داخلي
🔴 شبه مستحيل دولة فقط
2- استغلال سلسلة التوريد
🟠 صعب جدًا دولة أو تحالف
2- هجوم فيزيائي مباشر
🔴 شبه مستحيل فقط عميل داخلي
3- اختراق RF أو الأقمار
🟠 معقد يحتاج معدات متقدمة جدًا
4- استغلال برمجي مباشر
🔴 شبه مستحيل بدون وصول للنظام
---

بحث مميز هديه للينشرون تم اختراق نضام اطلاق الصواريخ الاسرائيلي وتم التحكم بالنضام

تم اختراق الزيج العالمي من قبل اسامه الموسوي
كيف يمكن لخلل بسيط في المنطق أن يفتح أبواب قلعة رقمية محصنة؟

يسعدنا أن نشارككم تقريرنا الأمني الجديد، وهو دراسة حالة واقعية وعميقة لاستغلال ثغرة حرجة (CVE-2025-2825) في خوادم CrushFTP، تم تطبيقها على بنية تحتية حكومية حساسة.

هذا التقرير لا يستعرض فقط خطوات الاستغلال، بل يغوص في العقلية التحليلية للباحث الأمني وكيفية قراءته لما بين السطور. استكشف معنا:

فن تحويل الفشل إلى نجاح: شاهد كيف تحولت محاولة فاشلة صدّها جدار الحماية (WAF) إلى اختراق كامل.
منطق غير تقليدي: اكتشف كيف تم بناء طلب الاستغلال الذي أربك نظام المصادقة المعقد في الخادم.
فهم معماري عميق: تعلم كيف أن فهم سلوك النظام، وليس فقط تطبيق الأدوات، هو مفتاح كسر الدفاعات.

Target: البوابة الرسمية للخدمة الفيدرالية للعمل والتوظيف في روسيا الاتحادية (rostrud.gov.ru)

هذه الدراسة هي أكثر من مجرد تقرير تقني، إنها نظرة على استراتيجية الهجوم والتفكير المنهجي الذي يميز الخبراء في هذا المجال.

لقراءة التحليل الكامل والاطلاع على التفاصيل التقنية الدقيقة، تفضلوا بزيارة الرابط:
https://www.smartshadow.dev/reporte.html

منقول ...
انشاء برنامج تحليل الطلبات الذكي
smart_filter
كل تعليمات التشغيل والتعامل، وبميزات صغيرة (اختيار منفذ فارغ تلقائيًا، صفحة إدارة الكلمات، صفحة سجل الطلبات، حماية بسيطة من الأخطاء، وشرح لكل ملف).
أكتب التعليمات خطوة-بـ-خطوة حتى تقدر تنفّذها في تيرمكس بدون أخطاء.


---

1) ملخّص الميّزات النهائية

واجهة ويب احترافية بـ Bootstrap (صفحة رئيسية للتحليل، صفحة إدارة للكلمات المحظورة، صفحة لسجل الطلبات).

قاعدة بيانات SQLite واحدة database.db تحتوي جدولين: forbidden_words و request_log.

عند التشغيل يتم إنشاء الجداول تلقائيًا وإضافة كلمات مبدئية (القائمة اللي عطيتنيها).

مطابقة كلمات ممنوعة بشكل غير حساس لحالة الحروف (case-insensitive) وبطريقة سليمة (نستخدم فحص حدود كلمات عندما يكون ذلك مناسبًا).

اختيار منفذ متاح تلقائيًا (يحاول 5000 ثم 5050 ثم 5060 ثم 8000 ...).

تسجيل كل طلب مع التاريخ والوقت والنتيجة تلقائيًا.

صفحة إدارة (إضافة حذف) من الواجهة.

معالجة أخطاء لعرض رسالة مفيدة بدل Internal Server Error.



---

2) تحضير البيئة (Termux)

افتح تيرمكس ونفّذ:

pkg update && pkg upgrade -y
pkg install python -y
pip install flask

(إذا تستخدم حاسوب أو ويندوز استبدل بالطريقة المناسبة: تثبيت Python + pip ثم pip install flask).


---

3) إنشاء بنية المشروع

نفّذ الأوامر التالية لإنشاء المجلدات والملفات بسرعة:

mkdir -p ~/smart_filter/templates ~/smart_filter/static

cd ~/smart_filter

سننشئ ملفات المشروع داخل هذا المجلد.


---

4) كود التطبيق الكامل — app.py

افتح محرر (nano أو أي محرر) ثم أنشئ وادخل الكود التالي:

nano app.py

الصق الكود بالكامل التالي واحفظ:

"""
Smart Request Filter
مشروع: نظام تحليل الطلبات الذكي (Flask + SQLite + Bootstrap)
المطور: أسامة
"""
from flask import Flask, render_template, request, redirect, url_for, flash
import sqlite3
import datetime
import re
import socket
from pathlib import Path

# ----------------------- إعداد التطبيق -----------------------
app = Flask(name)
app.secret_key = "replace-this-with-a-random-key" # يمكن تغييره لاحقاً

BASE_DIR = Path(file).resolve().parent
DB_PATH = BASE_DIR / "database.db"

# الكلمات الافتراضية (القائمة اللي زودتها)
DEFAULT_FORBIDDEN = [
"اختراق",
"اسود",
"اسامه",
"قميص",
"لوحه",
"ادمن",
"admin",
"passwerd"
]

# ----------------------- دوال مساعدة -----------------------
def find_free_port(preferred=(5000, 5050, 5060, 8000, 8080)):
"""يحاول يجد منفذ متاح من القائمة ثم يعيد منفذ حر إن وجد"""
for p in preferred:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
try:
s.bind(("0.0.0.0", p))
return p
except OSError:
continue
# إذا ما أي واحد متاح، اطلب من النظام يعطيك أي منفذ حر
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(("0.0.0.0", 0))
return s.getsockname()[1]

def get_db_conn():
conn = sqlite3.connect(DB_PATH)
conn.row_factory = sqlite3.Row
return conn

def init_db():
"""ينشئ الجداول إن لم تكن موجودة ويضيف كلمات افتراضية"""
conn = get_db_conn()
c = conn.cursor()
c.execute("""
CREATE TABLE IF NOT EXISTS forbidden_words (
id INTEGER PRIMARY KEY AUTOINCREMENT,
word TEXT UNIQUE NOT NULL
)
""")
c.execute("""
CREATE TABLE IF NOT EXISTS request_log (
id INTEGER PRIMARY KEY AUTOINCREMENT,
text TEXT,
result TEXT,
date TEXT
)
""")
conn.commit()
# أضف الكلمات الافتراضية إذا لم تكن موجودة
for w in DEFAULT_FORBIDDEN:
try:
c.execute("INSERT INTO forbidden_words (word) VALUES (?)", (w.strip().lower(),))
except sqlite3.IntegrityError:
pass
conn.commit()
conn.close()

def is_text_forbidden(text):
"""يفحص النص مقابل قائمة الكلمات الممنوعة ويرجع (True, found_list) أو (False, [])"""
if not text:
return False, []
conn = get_db_conn()
c = conn.cursor()
c.execute("SELECT word FROM forbidden_words")
words = [row["word"] for row in c.fetchall()]
conn.close()
found = []
# نستخدم فحص حساس للحدود حيثما أمكن، ونسمح بالتحقق بالـ substring كخطة احتياط
text_l = text.lower()
for w in words:
w_esc = re.escape(w)
# أولًا نبحث عن كلمة كاملة حسب حدود الكلمة (قد لا يكون مثالياً تماماً لكل لغات لكن مفيد)
if re.search(rf"\b{w_esc}\b", text_l):
found.append(w)
# إذا لم يطابق حدود كلمة، نجرب substring بسيط (لبعض الكلمات الانجليزية أو كلمات قصيرة)
elif w in text_l:
found.append(w)
return (len(found) > 0), found

def log_request(text, result):
conn = get_db_conn()
c = conn.cursor()
c.execute("INSERT INTO request_log (text, result, date) VALUES (?, ?, ?)",
(text, result, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
conn.commit()
conn.close()

# ----------------------- صفحات الويب -----------------------
@app.route("/", methods=["GET", "POST"])
def index():
result = None
found = []
if request.method == "POST":
text = request.form.get("req_text", "").strip()
forbidden, found = is_text_forbidden(text)
if forbidden:
result = f"تم رفض الطلب — يحتوي على كلمات محظورة: {', '.join(found)}"
elif text == "":
result = "الطلب فارغ — يرجى إدخال نص."
else:
result = "تم السماح بالطلب "
log_request(text, result)
# flash رسالة قصيرة تظهر لو حبيت
flash(result)
return render_template("index.html", result=result)

@app.route("/manage", methods=["GET", "POST"])
def manage():
conn = get_db_conn()
c = conn.cursor()
if request.method == "POST":
new_word = request.form.get("new_word", "").strip().lower()
if new_word:
try:
c.execute("INSERT INTO forbidden_words (word) VALUES (?)", (new_word,))
conn.commit()
flash(f"تمت إضافة الكلمة: {new_word}")
except sqlite3.IntegrityError:
flash(f"الكلمة موجودة مسبقًا: {new_word}")
# حذف عبر GET param (?delete_id=3)
delete_id = request.args.get("delete_id")
if delete_id:
try:
c.execute("DELETE FROM forbidden_words WHERE id = ?", (delete_id,))
conn.commit()
flash("تم حذف الكلمة")
except Exception as e:
flash("خطأ عند الحذف: " + str(e))
c.execute("SELECT id, word FROM forbidden_words ORDER BY id DESC")
words = c.fetchall()
conn.close()
return render_template("manage.html", words=words)

@app.route("/log")
def log_page():
conn = get_db_conn()
c = conn.cursor()
c.execute("SELECT id, text, result, date FROM request_log ORDER BY id DESC")
logs = c.fetchall()
conn.close()
return render_template("log.html", logs=logs)

# صفحة خطأ بسيطة للـ 500
@app.errorhandler(500)
def internal_error(e):
return render_template("500.html", error=str(e)), 500

# ----------------------- تشغيل التطبيق -----------------------
if name == "main":
init_db()
# نحاول نأخذ منفذ متاح تلقائياً
port = find_free_port()
print(f"Starting server on port {port} ... (open http://127.0.0.1:{port})")
# شغّل مع debug=True أثناء التطوير، غيّره False عند التقديم
app.run(host="0.0.0.0", port=port, debug=True)

ملاحظات في الكود:

find_free_port() يبحث عن منفذ متاح من قائمة تفضيلية ثم يطلب من النظام منفذ عشوائي إن لزم. هذا يمنع رسالة "Address already in use".

is_text_forbidden() يعيد قائمة الكلمات الموجودة (لو موجودة).

init_db() ينشئ الجداول ويضيف كلمات افتراضية.

هناك صفحة خطأ 500.html عرضها إذا صار خطأ (ننشئها لاحقًا).


احفظ واطلع (Ctrl+O ثم Enter ثم Ctrl+X).


---

5) قوالب الواجهة (templates)

افتح مجلد templates وأنشئ هذه الملفات.

templates/index.html

nano templates/index.html

الصق:

<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<meta charset="utf-8">
<title>نظام تحليل الطلبات الذكي</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="bg-light">
<div class="container py-5">
<div class="text-center mb-4">
<h1 class="fw-bold">📊 نظام تحليل الطلبات الذكي</h1>
<p>أدخل نص الطلب وسيتم تحليله مقابل قائمة الكلمات الممنوعة.</p>
<div class="mt-2">
<a href="{{ url_for('manage') }}" class="btn btn-warning me-2">⚙️ إدارة الكلمات</a>
<a href="{{ url_for('log_page') }}" class="btn btn-secondary">📁 سجل الطلبات</a>
</div>
</div>

{% with messages = get_flashed_messages() %}
{% if messages %}
{% for msg in messages %}
<div class="alert alert-info">{{ msg }}</div>
{% endfor %}
{% endif %}
{% endwith %}

<div class="card shadow-sm">
<div class="card-body">
<form method="POST">
<div class="mb-3">
<textarea name="req_text" rows="5" class="form-control" placeholder="اكتب الطلب هنا..." required></textarea>
</div>
<div class="d-grid gap-2 d-sm-flex justify-content-sm-center">
<button class="btn btn-success px-4">🔍 تحليل الطلب</button>
</div>
</form>

{% if result %}
<div class="mt-3 alert {% if 'رفض' in result %}alert-danger{% else %}alert-success{% endif %}">
{{ result }}
</div>
{% endif %}
</div>
</div>
</div>
</body>
</html>

templates/manage.html

nano templates/manage.html

الصق:

<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<meta charset="utf-8">
<title>إدارة الكلمات الممنوعة</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="bg-light">
<div class="container py-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<h2 class="mb-0">⚙️ إدارة الكلمات الممنوعة</h2>
<div>
<a href="{{ url_for('index') }}" class="btn btn-secondary">🏠 الرئيسية</a>
<a href="{{ url_for('log_page') }}" class="btn btn-info text-white">📁 سجل الطلبات</a>
</div>
</div>

{% with messages = get_flashed_messages() %}
{% if messages %}
{% for msg in messages %}
<div class="alert alert-info">{{ msg }}</div>
{% endfor %}
{% endif %}
{% endwith %}

<form method="POST" class="mb-3">
<div class="input-group">
<input name="new_word" class="form-control" placeholder="أضف كلمة جديدة..." required>
<button class="btn btn-success"> إضافة</button>
</div>
</form>

<div class="card">
<div class="card-body">
<table class="table table-striped table-bordered text-center">
<thead class="table-dark">
<tr><th>الكلمة</th><th>حذف</th></tr>
</thead>
<tbody>
{% for w in words %}
<tr>
<td>{{ w['word'] }}</td>
<td><a class="btn btn-danger btn-sm" href="{{ url_for('manage', delete_id=w['id']) }}">🗑 حذف</a></td>
</tr>
{% else %}
<tr><td colspan="2">لا توجد كلمات بعد</td></tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>

templates/log.html

nano templates/log.html

الصق:

<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<meta charset="utf-8">
<title>سجل الطلبات</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="bg-light">
<div class="container py-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<h2 class="mb-0">📁 سجل الطلبات</h2>
<div>
<a href="{{ url_for('index') }}" class="btn btn-secondary">🏠 الرئيسية</a>
<a href="{{ url_for('manage') }}" class="btn btn-warning">⚙️ إدارة الكلمات</a>
</div>
</div>

<div class="card">
<div class="card-body">
<table class="table table-hover table-bordered">
<thead class="table-dark text-center">
<tr><th>#</th><th>النص</th><th>النتيجة</th><th>التاريخ</th></tr>
</thead>
<tbody>
{% for r in logs %}
<tr>
<td class="text-center">{{ r['id'] }}</td>
<td>{{ r['text'] }}</td>
<td>{{ r['result'] }}</td>
<td class="text-center">{{ r['date'] }}</td>
</tr>
{% else %}
<tr><td colspan="4" class="text-center">لا يوجد سجلات بعد</td></tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>

templates/500.html (اختياري لعرض خطأ أنيق)

nano templates/500.html

الصق:

<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<meta charset="utf-8">
<title>خطأ داخلي</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="bg-light">
<div class="container py-5 text-center">
<h1 class="text-danger">حدث خطأ داخلي</h1>
<p>عذراً، حدث خطأ أثناء معالجة الطلب. التفاصيل: {{ error }}</p>
<a href="{{ url_for('index') }}" class="btn btn-primary">العودة للرئيسية</a>
</div>
</body>
</html>


---

6) تشغيل المشروع لأول مرة

1. من داخل مجلد المشروع:



cd ~/smart_filter

2. (اختياري) إنك تريد تتأكد أن ماكو عملية سابقة شغالة:



ps aux | grep app.py
# اذا طلع PID نفذ kill -9 <PID>

3. شغّل:



python app.py

ستطبع لك سطرًا مثل:

Starting server on port 5000 ... (open http://127.0.0.1:5000)

(أو أي منفذ حر اختاره البرنامج، مثلاً 5050 أو 5060).

4. افتح المتصفح وادخل:



http://127.0.0.1:5000

— بعدها تقدر تستخدم الواجهة.


---

7) كيف تعمل الميزات (شرح سريع للعملية)

إضافة كلمة محظورة: افتح صفحة إدارة الكلمات، اكتب الكلمة واضغط زر . تحفظ في DB.

حذف كلمة: اضغط زر 🗑 بجانب الكلمة.

تحليل طلب: اكتب نص في الصفحة الرئيسية ثم اضغط "تحليل الطلب" — النتيجة تظهر وفورًا تُسجَّل في جدول request_log.

عرض السجل: زر "سجل الطلبات" يعرض كل الطلبات مع التاريخ والنتيجة.



---

8) شرح كل ملف بموجز (لتقدمه مع المشروع)

app.py

المسؤول: الخادم (Flask) واللوجيك؛ تهيئة DB؛ تحليل النصوص؛ تسجيل السجلات؛ توجيه الصفحات.


database.db

المسؤول: تخزين جداول forbidden_words و request_log.


templates/index.html

المسؤول: الواجهة الرئيسية لإدخال النصوص وعرض النتائج.


templates/manage.html

المسؤول: واجهة إدارة الكلمات الممنوعة (إضافة/حذف).


templates/log.html

المسؤول: عرض سجل الطلبات بطريقة منظمة.


templates/500.html

المسؤول: صفحة عرض خطأ لطيفة عندما يحدث استثناء داخلي.


static/ (اختياري)

ملفات CSS/صور إضافية إذا تريد تخصيص أكثر.




---

9) نصائح عملية ونقاط مهمة

بعد الانتهاء: اضغط CTRL+C في التيرمكس لإيقاف الخادم.

إذا واجهت رسالة Address already in use: استخدم ps aux | grep app.py ثم kill -9 PID، أو دع الكود يختار منفذ آخر (تمّ تضمينه في الكود).

لو تريد تبدّل DEFAULT_FORBIDDEN، غيّرها داخل app.py أو أضف/احذف من صفحة الإدارة.


--
تكدر تصنع ملف ZIP جاهز للتسليم (يحتوي كل الملفات + قاعدة بيانات). مثال:

cd ~/smart_filter
zip -r smart_filter_submission.zip . -x "pycache/*"

راح ينشئ smart_filter_submission.zip.


---
مشروع بسيط كان مهمتي بالجامعه