diff --git a/config/__pycache__/__init__.cpython-311.pyc b/config/__pycache__/__init__.cpython-311.pyc index 423a636..c2b3435 100644 Binary files a/config/__pycache__/__init__.cpython-311.pyc and b/config/__pycache__/__init__.cpython-311.pyc differ diff --git a/config/__pycache__/settings.cpython-311.pyc b/config/__pycache__/settings.cpython-311.pyc index 96bce55..ff0e6b3 100644 Binary files a/config/__pycache__/settings.cpython-311.pyc and b/config/__pycache__/settings.cpython-311.pyc differ diff --git a/config/__pycache__/urls.cpython-311.pyc b/config/__pycache__/urls.cpython-311.pyc index 0b85e94..ee51d80 100644 Binary files a/config/__pycache__/urls.cpython-311.pyc and b/config/__pycache__/urls.cpython-311.pyc differ diff --git a/config/__pycache__/wsgi.cpython-311.pyc b/config/__pycache__/wsgi.cpython-311.pyc index 9c49e09..eaee1fe 100644 Binary files a/config/__pycache__/wsgi.cpython-311.pyc and b/config/__pycache__/wsgi.cpython-311.pyc differ diff --git a/core/__pycache__/__init__.cpython-311.pyc b/core/__pycache__/__init__.cpython-311.pyc index 74b1112..047881b 100644 Binary files a/core/__pycache__/__init__.cpython-311.pyc and b/core/__pycache__/__init__.cpython-311.pyc differ diff --git a/core/__pycache__/admin.cpython-311.pyc b/core/__pycache__/admin.cpython-311.pyc index a5ed392..56aeaf3 100644 Binary files a/core/__pycache__/admin.cpython-311.pyc and b/core/__pycache__/admin.cpython-311.pyc differ diff --git a/core/__pycache__/apps.cpython-311.pyc b/core/__pycache__/apps.cpython-311.pyc index 6f131d4..e0e3fad 100644 Binary files a/core/__pycache__/apps.cpython-311.pyc and b/core/__pycache__/apps.cpython-311.pyc differ diff --git a/core/__pycache__/context_processors.cpython-311.pyc b/core/__pycache__/context_processors.cpython-311.pyc index 75bf223..b06b680 100644 Binary files a/core/__pycache__/context_processors.cpython-311.pyc and b/core/__pycache__/context_processors.cpython-311.pyc differ diff --git a/core/__pycache__/models.cpython-311.pyc b/core/__pycache__/models.cpython-311.pyc index e061640..7f239d4 100644 Binary files a/core/__pycache__/models.cpython-311.pyc and b/core/__pycache__/models.cpython-311.pyc differ diff --git a/core/__pycache__/urls.cpython-311.pyc b/core/__pycache__/urls.cpython-311.pyc index 5a69659..03c758d 100644 Binary files a/core/__pycache__/urls.cpython-311.pyc and b/core/__pycache__/urls.cpython-311.pyc differ diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index 2a36fd6..ed91b94 100644 Binary files a/core/__pycache__/views.cpython-311.pyc and b/core/__pycache__/views.cpython-311.pyc differ diff --git a/core/admin.py b/core/admin.py index 8c38f3f..adde0cb 100644 --- a/core/admin.py +++ b/core/admin.py @@ -1,3 +1,9 @@ from django.contrib import admin +from .models import FileScan -# Register your models here. +@admin.register(FileScan) +class FileScanAdmin(admin.ModelAdmin): + list_display = ('filename', 'risk_level', 'file_hash', 'created_at') + list_filter = ('risk_level', 'created_at') + search_fields = ('filename', 'file_hash') + readonly_fields = ('file_hash', 'created_at') \ No newline at end of file diff --git a/core/migrations/0001_initial.py b/core/migrations/0001_initial.py new file mode 100644 index 0000000..c4bc426 --- /dev/null +++ b/core/migrations/0001_initial.py @@ -0,0 +1,28 @@ +# Generated by Django 5.2.7 on 2026-01-31 03:52 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='FileScan', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('filename', models.CharField(max_length=255)), + ('file_hash', models.CharField(db_index=True, max_length=64)), + ('risk_level', models.CharField(choices=[('LOW', 'Low'), ('MEDIUM', 'Medium'), ('HIGH', 'High')], max_length=10)), + ('reasons', models.TextField()), + ('created_at', models.DateTimeField(auto_now_add=True)), + ], + options={ + 'ordering': ['-created_at'], + }, + ), + ] diff --git a/core/migrations/__pycache__/0001_initial.cpython-311.pyc b/core/migrations/__pycache__/0001_initial.cpython-311.pyc new file mode 100644 index 0000000..33ff0c6 Binary files /dev/null and b/core/migrations/__pycache__/0001_initial.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/__init__.cpython-311.pyc b/core/migrations/__pycache__/__init__.cpython-311.pyc index 9c833c8..c1aeff2 100644 Binary files a/core/migrations/__pycache__/__init__.cpython-311.pyc and b/core/migrations/__pycache__/__init__.cpython-311.pyc differ diff --git a/core/models.py b/core/models.py index 71a8362..c0209e8 100644 --- a/core/models.py +++ b/core/models.py @@ -1,3 +1,20 @@ from django.db import models -# Create your models here. +class FileScan(models.Model): + RISK_LEVELS = [ + ('LOW', 'Low'), + ('MEDIUM', 'Medium'), + ('HIGH', 'High'), + ] + + filename = models.CharField(max_length=255) + file_hash = models.CharField(max_length=64, db_index=True) # SHA256 + risk_level = models.CharField(max_length=10, choices=RISK_LEVELS) + reasons = models.TextField() + created_at = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return f"{self.filename} - {self.risk_level}" + + class Meta: + ordering = ['-created_at'] \ No newline at end of file diff --git a/core/templates/base.html b/core/templates/base.html index 1e7e5fb..8ebbcbc 100644 --- a/core/templates/base.html +++ b/core/templates/base.html @@ -1,25 +1,61 @@ - - - {% block title %}Knowledge Base{% endblock %} - {% if project_description %} - - - - {% endif %} - {% if project_image_url %} - - - {% endif %} - {% load static %} - - {% block head %}{% endblock %} + + + {% block title %}Cloud Malware Detection{% endblock %} + {% if project_description %} + + {% endif %} + {% load static %} + + + + + + + + + + + + + {% block extra_head %}{% endblock %} + + - - {% block content %}{% endblock %} +
+ {% block content %}{% endblock %} +
+ + + + + + {% block extra_js %}{% endblock %} - - + \ No newline at end of file diff --git a/core/templates/core/index.html b/core/templates/core/index.html index faec813..c02b0b2 100644 --- a/core/templates/core/index.html +++ b/core/templates/core/index.html @@ -1,145 +1,161 @@ {% extends "base.html" %} +{% load static %} -{% block title %}{{ project_name }}{% endblock %} - -{% block head %} - - - - -{% endblock %} +{% block title %}Cloud Malware Detection Web App - Home{% endblock %} {% block content %} -
-
-

Analyzing your requirements and generating your app…

-
- Loading… +
+
+
+
+

Cloud Malware Detection Web App

+

Securely scan your files for potential threats using advanced static analysis and hash matching.

+ +
+
+
+ +
+
+
-

AppWizzy AI is collecting your requirements and applying the first changes.

-

This page will refresh automatically as the plan is implemented.

-

- Runtime: Django {{ django_version }} · Python {{ python_version }} - — UTC {{ current_time|date:"Y-m-d H:i:s" }} -

-
-
- -{% endblock %} \ No newline at end of file + + +
+
+
+
+
+

Upload File for Analysis

+
+ {% csrf_token %} +
+ +
+ +
Click or drag file here to upload
+

Maximum file size: 10MB

+
+
+
+ +
+
+
+
+ + {% if result %} +
+
+ Scan Result: {{ result.risk_level }} RISK +
+
+

{{ result.filename }}

+

SHA256 Hash: {{ result.file_hash }}

+

Reasons for Assessment:

+
    + {% for reason in result.reasons.split|slice:":-1" %} +
  • {{ reason }}
  • + {% empty %} +
  • {{ result.reasons }}
  • + {% endfor %} +
+
+
+ {% endif %} + +
+

Recent Scans

+
+ + + + + + + + + + {% for scan in recent_scans %} + + + + + + {% empty %} + + + + {% endfor %} + +
FilenameRisk LevelDate
{{ scan.filename }} + + {{ scan.risk_level }} + + {{ scan.created_at|date:"M d, Y H:i" }}
No recent scans found.
+
+
+
+
+
+{% endblock %} + +{% block extra_js %} + +{% endblock %} diff --git a/core/urls.py b/core/urls.py index 6299e3d..6018759 100644 --- a/core/urls.py +++ b/core/urls.py @@ -1,7 +1,7 @@ from django.urls import path - -from .views import home +from . import views urlpatterns = [ - path("", home, name="home"), -] + path("", views.index, name="index"), + path("scan/", views.scan_file, name="scan_file"), +] \ No newline at end of file diff --git a/core/views.py b/core/views.py index c9aed12..0c5c4eb 100644 --- a/core/views.py +++ b/core/views.py @@ -1,25 +1,71 @@ +import hashlib import os -import platform +from django.shortcuts import render, redirect +from django.http import JsonResponse +from django.views.decorators.csrf import csrf_exempt +from .models import FileScan -from django import get_version as django_version -from django.shortcuts import render -from django.utils import timezone +def index(request): + scans = FileScan.objects.all()[:10] + return render(request, "core/index.html", {"recent_scans": scans}) - -def home(request): - """Render the landing screen with loader and environment details.""" - host_name = request.get_host().lower() - agent_brand = "AppWizzy" if host_name == "appwizzy.com" else "Flatlogic" - now = timezone.now() - - context = { - "project_name": "New Style", - "agent_brand": agent_brand, - "django_version": django_version(), - "python_version": platform.python_version(), - "current_time": now, - "host_name": host_name, - "project_description": os.getenv("PROJECT_DESCRIPTION", ""), - "project_image_url": os.getenv("PROJECT_IMAGE_URL", ""), - } - return render(request, "core/index.html", context) +def scan_file(request): + if request.method == 'POST' and request.FILES.get('file'): + uploaded_file = request.FILES['file'] + filename = uploaded_file.name + content = uploaded_file.read() + + # Calculate SHA256 + sha256_hash = hashlib.sha256(content).hexdigest() + + # Basic Static Analysis + risk_level = 'LOW' + reasons = [] + + # 1. Extension check + ext = os.path.splitext(filename)[1].lower() + danger_exts = ['.exe', '.dll', '.bin', '.sh', '.bat', '.msi', '.js', '.vbs', '.ps1', '.py'] + if ext in danger_exts: + risk_level = 'MEDIUM' + reasons.append(f"Suspicious file extension: {ext}") + + # 2. Content check (basic keyword search) + suspicious_keywords = [ + b'eval(', b'exec(', b'os.system(', b'subprocess.run(', b'base64.b64decode(', + b'chmod +x', b'rm -rf', b'powershell', b'cmd.exe' + ] + found_keywords = [] + for kw in suspicious_keywords: + if kw in content: + found_keywords.append(kw.decode()) + + if found_keywords: + risk_level = 'HIGH' + reasons.append(f"Found suspicious code patterns: {', '.join(found_keywords)}") + + if not reasons: + reasons.append("No immediate threats found via static analysis.") + + # Save to DB + scan = FileScan.objects.create( + filename=filename, + file_hash=sha256_hash, + risk_level=risk_level, + reasons="; ".join(reasons) + ) + + if request.headers.get('X-Requested-With') == 'XMLHttpRequest': + return JsonResponse({ + 'filename': scan.filename, + 'hash': scan.file_hash, + 'risk_level': scan.risk_level, + 'reasons': scan.reasons, + 'created_at': scan.created_at.strftime('%Y-%m-%d %H:%M:%S') + }) + + return render(request, "core/index.html", { + "result": scan, + "recent_scans": FileScan.objects.all()[:10] + }) + + return redirect('index') \ No newline at end of file diff --git a/static/css/custom.css b/static/css/custom.css index 925f6ed..bebe23f 100644 --- a/static/css/custom.css +++ b/static/css/custom.css @@ -1,4 +1,108 @@ -/* Custom styles for the application */ -body { - font-family: system-ui, -apple-system, sans-serif; +:root { + --primary-bg: #1a1a1a; + --secondary-bg: #2d2d2d; + --accent: #00ff9d; + --accent-hover: #00e68e; + --hazard: #ff9f43; + --danger: #ee5253; + --text-light: #f8f9fa; + --text-muted: #adb5bd; } + +body { + background-color: var(--primary-bg); + color: var(--text-light); + font-family: 'Inter', sans-serif; +} + +.font-heading { + font-family: 'Space Grotesk', sans-serif; +} + +.text-accent { + color: var(--accent); +} + +.bg-secondary-dark { + background-color: var(--secondary-bg); +} + +.btn-accent { + background-color: var(--accent); + color: #1a1a1a; + border: none; + transition: all 0.3s ease; +} + +.btn-accent:hover { + background-color: var(--accent-hover); + color: #1a1a1a; + transform: translateY(-2px); + box-shadow: 0 5px 15px rgba(0, 255, 157, 0.3); +} + +.border-accent { + border-color: var(--accent) !important; +} + +.border-dashed { + border-style: dashed !important; +} + +.cursor-pointer { + cursor: pointer; +} + +.animate-glow { + animation: glow 3s infinite alternate; +} + +@keyframes glow { + from { + text-shadow: 0 0 10px rgba(0, 255, 157, 0.2); + } + to { + text-shadow: 0 0 30px rgba(0, 255, 157, 0.6); + } +} + +.card { + border-radius: 1rem; + overflow: hidden; +} + +.upload-zone { + transition: all 0.3s ease; +} + +.upload-zone:hover .border-dashed { + border-color: var(--accent) !important; + background-color: rgba(0, 255, 157, 0.05); +} + +.table-dark { + background-color: var(--secondary-bg); +} + +.table-secondary-dark { + background-color: #333; +} + +.hero-section { + background: radial-gradient(circle at top right, rgba(0, 255, 157, 0.1), transparent); +} + +.result-card { + animation: slideUp 0.5s ease-out; +} + +@keyframes slideUp { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} \ No newline at end of file diff --git a/staticfiles/css/custom.css b/staticfiles/css/custom.css index 108056f..bebe23f 100644 --- a/staticfiles/css/custom.css +++ b/staticfiles/css/custom.css @@ -1,21 +1,108 @@ - :root { - --bg-color-start: #6a11cb; - --bg-color-end: #2575fc; - --text-color: #ffffff; - --card-bg-color: rgba(255, 255, 255, 0.01); - --card-border-color: rgba(255, 255, 255, 0.1); + --primary-bg: #1a1a1a; + --secondary-bg: #2d2d2d; + --accent: #00ff9d; + --accent-hover: #00e68e; + --hazard: #ff9f43; + --danger: #ee5253; + --text-light: #f8f9fa; + --text-muted: #adb5bd; } + body { - margin: 0; + background-color: var(--primary-bg); + color: var(--text-light); font-family: 'Inter', sans-serif; - background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end)); - color: var(--text-color); - display: flex; - justify-content: center; - align-items: center; - min-height: 100vh; - text-align: center; - overflow: hidden; - position: relative; } + +.font-heading { + font-family: 'Space Grotesk', sans-serif; +} + +.text-accent { + color: var(--accent); +} + +.bg-secondary-dark { + background-color: var(--secondary-bg); +} + +.btn-accent { + background-color: var(--accent); + color: #1a1a1a; + border: none; + transition: all 0.3s ease; +} + +.btn-accent:hover { + background-color: var(--accent-hover); + color: #1a1a1a; + transform: translateY(-2px); + box-shadow: 0 5px 15px rgba(0, 255, 157, 0.3); +} + +.border-accent { + border-color: var(--accent) !important; +} + +.border-dashed { + border-style: dashed !important; +} + +.cursor-pointer { + cursor: pointer; +} + +.animate-glow { + animation: glow 3s infinite alternate; +} + +@keyframes glow { + from { + text-shadow: 0 0 10px rgba(0, 255, 157, 0.2); + } + to { + text-shadow: 0 0 30px rgba(0, 255, 157, 0.6); + } +} + +.card { + border-radius: 1rem; + overflow: hidden; +} + +.upload-zone { + transition: all 0.3s ease; +} + +.upload-zone:hover .border-dashed { + border-color: var(--accent) !important; + background-color: rgba(0, 255, 157, 0.05); +} + +.table-dark { + background-color: var(--secondary-bg); +} + +.table-secondary-dark { + background-color: #333; +} + +.hero-section { + background: radial-gradient(circle at top right, rgba(0, 255, 157, 0.1), transparent); +} + +.result-card { + animation: slideUp 0.5s ease-out; +} + +@keyframes slideUp { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} \ No newline at end of file