hamaghafursmaldet
This commit is contained in:
parent
27bd5182e3
commit
d57d2a227f
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,3 +1,9 @@
|
|||||||
from django.contrib import admin
|
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')
|
||||||
28
core/migrations/0001_initial.py
Normal file
28
core/migrations/0001_initial.py
Normal file
@ -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'],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
BIN
core/migrations/__pycache__/0001_initial.cpython-311.pyc
Normal file
BIN
core/migrations/__pycache__/0001_initial.cpython-311.pyc
Normal file
Binary file not shown.
Binary file not shown.
@ -1,3 +1,20 @@
|
|||||||
from django.db import models
|
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']
|
||||||
@ -1,25 +1,61 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>{% block title %}Knowledge Base{% endblock %}</title>
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
{% if project_description %}
|
<title>{% block title %}Cloud Malware Detection{% endblock %}</title>
|
||||||
<meta name="description" content="{{ project_description }}">
|
{% if project_description %}
|
||||||
<meta property="og:description" content="{{ project_description }}">
|
<meta name="description" content="{{ project_description }}">
|
||||||
<meta property="twitter:description" content="{{ project_description }}">
|
{% endif %}
|
||||||
{% endif %}
|
{% load static %}
|
||||||
{% if project_image_url %}
|
<!-- Google Fonts -->
|
||||||
<meta property="og:image" content="{{ project_image_url }}">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<meta property="twitter:image" content="{{ project_image_url }}">
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
{% endif %}
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&family=Space+Grotesk:wght@500;700&display=swap" rel="stylesheet">
|
||||||
{% load static %}
|
|
||||||
<link rel="stylesheet" href="{% static 'css/custom.css' %}?v={{ deployment_timestamp }}">
|
<!-- Bootstrap 5 CDN -->
|
||||||
{% block head %}{% endblock %}
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
|
||||||
|
|
||||||
|
<!-- Custom CSS -->
|
||||||
|
<link rel="stylesheet" href="{% static 'css/custom.css' %}?v={{ deployment_timestamp }}">
|
||||||
|
|
||||||
|
{% block extra_head %}{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
|
<body class="bg-dark text-light">
|
||||||
|
<nav class="navbar navbar-expand-lg navbar-dark border-bottom border-secondary">
|
||||||
|
<div class="container">
|
||||||
|
<a class="navbar-brand fw-bold" href="{% url 'index' %}">
|
||||||
|
<i class="bi bi-shield-lock-fill text-accent me-2"></i>CloudScan
|
||||||
|
</a>
|
||||||
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
<div class="collapse navbar-collapse" id="navbarNav">
|
||||||
|
<ul class="navbar-nav ms-auto">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{% url 'index' %}">Home</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/admin/">Admin</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
<body>
|
<main>
|
||||||
{% block content %}{% endblock %}
|
{% block content %}{% endblock %}
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer class="py-4 border-top border-secondary mt-5">
|
||||||
|
<div class="container text-center text-secondary">
|
||||||
|
<p>© 2026 Cloud Malware Detection Web App. Built with Django & Security in mind.</p>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<!-- Bootstrap JS CDN -->
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
{% block extra_js %}{% endblock %}
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@ -1,145 +1,161 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
{% block title %}{{ project_name }}{% endblock %}
|
{% block title %}Cloud Malware Detection Web App - Home{% endblock %}
|
||||||
|
|
||||||
{% block head %}
|
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
|
|
||||||
<style>
|
|
||||||
: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);
|
|
||||||
}
|
|
||||||
|
|
||||||
* {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
body::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 100 100'><path d='M-10 10L110 10M10 -10L10 110' stroke-width='1' stroke='rgba(255,255,255,0.05)'/></svg>");
|
|
||||||
animation: bg-pan 20s linear infinite;
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes bg-pan {
|
|
||||||
0% {
|
|
||||||
background-position: 0% 0%;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
background-position: 100% 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
main {
|
|
||||||
padding: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
background: var(--card-bg-color);
|
|
||||||
border: 1px solid var(--card-border-color);
|
|
||||||
border-radius: 16px;
|
|
||||||
padding: 2.5rem 2rem;
|
|
||||||
backdrop-filter: blur(20px);
|
|
||||||
-webkit-backdrop-filter: blur(20px);
|
|
||||||
box-shadow: 0 12px 36px rgba(0, 0, 0, 0.25);
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: clamp(2.2rem, 3vw + 1.2rem, 3.2rem);
|
|
||||||
font-weight: 700;
|
|
||||||
margin: 0 0 1.2rem;
|
|
||||||
letter-spacing: -0.02em;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin: 0.5rem 0;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
opacity: 0.92;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loader {
|
|
||||||
margin: 1.5rem auto;
|
|
||||||
width: 56px;
|
|
||||||
height: 56px;
|
|
||||||
border: 4px solid rgba(255, 255, 255, 0.25);
|
|
||||||
border-top-color: #fff;
|
|
||||||
border-radius: 50%;
|
|
||||||
animation: spin 1s linear infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes spin {
|
|
||||||
to {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.runtime code {
|
|
||||||
background: rgba(0, 0, 0, 0.25);
|
|
||||||
padding: 0.15rem 0.45rem;
|
|
||||||
border-radius: 4px;
|
|
||||||
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sr-only {
|
|
||||||
position: absolute;
|
|
||||||
width: 1px;
|
|
||||||
height: 1px;
|
|
||||||
padding: 0;
|
|
||||||
margin: -1px;
|
|
||||||
overflow: hidden;
|
|
||||||
clip: rect(0, 0, 0, 0);
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 1rem;
|
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 0.85rem;
|
|
||||||
opacity: 0.75;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<main>
|
<section class="hero-section py-5 mb-5">
|
||||||
<div class="card">
|
<div class="container">
|
||||||
<h1>Analyzing your requirements and generating your app…</h1>
|
<div class="row align-items-center">
|
||||||
<div class="loader" role="status" aria-live="polite" aria-label="Applying initial changes">
|
<div class="col-lg-6">
|
||||||
<span class="sr-only">Loading…</span>
|
<h1 class="display-4 fw-bold mb-3 font-heading">Cloud Malware Detection Web App</h1>
|
||||||
|
<p class="lead mb-4 text-secondary">Securely scan your files for potential threats using advanced static analysis and hash matching.</p>
|
||||||
|
<div class="d-flex gap-3">
|
||||||
|
<a href="#scan-area" class="btn btn-accent btn-lg px-4 shadow-sm">Start Scanning</a>
|
||||||
|
<a href="#recent-scans" class="btn btn-outline-light btn-lg px-4">View History</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-6 d-none d-lg-block">
|
||||||
|
<div class="hero-image-placeholder text-center p-5">
|
||||||
|
<i class="bi bi-shield-check-fill display-1 text-accent animate-glow"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p class="hint">AppWizzy AI is collecting your requirements and applying the first changes.</p>
|
</section>
|
||||||
<p class="hint">This page will refresh automatically as the plan is implemented.</p>
|
|
||||||
<p class="runtime">
|
<div class="container" id="scan-area">
|
||||||
Runtime: Django <code>{{ django_version }}</code> · Python <code>{{ python_version }}</code>
|
<div class="row justify-content-center">
|
||||||
— UTC <code>{{ current_time|date:"Y-m-d H:i:s" }}</code>
|
<div class="col-lg-8">
|
||||||
</p>
|
<div class="card bg-secondary-dark border-secondary shadow-lg mb-5">
|
||||||
</div>
|
<div class="card-body p-4 p-md-5">
|
||||||
</main>
|
<h3 class="card-title mb-4 font-heading">Upload File for Analysis</h3>
|
||||||
<footer>
|
<form action="{% url 'scan_file' %}" method="post" enctype="multipart/form-data" id="scanForm">
|
||||||
Page updated: {{ current_time|date:"Y-m-d H:i:s" }} (UTC)
|
{% csrf_token %}
|
||||||
</footer>
|
<div class="upload-zone mb-4" id="dropZone">
|
||||||
|
<input type="file" name="file" id="fileInput" class="d-none" required>
|
||||||
|
<div class="text-center p-5 border border-2 border-dashed border-secondary rounded-3 cursor-pointer" id="uploadTrigger">
|
||||||
|
<i class="bi bi-cloud-arrow-up display-4 text-secondary mb-3"></i>
|
||||||
|
<h5 class="text-light" id="fileLabel">Click or drag file here to upload</h5>
|
||||||
|
<p class="text-secondary small">Maximum file size: 10MB</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="d-grid">
|
||||||
|
<button type="submit" class="btn btn-accent btn-lg fw-bold py-3" id="submitBtn">
|
||||||
|
<span id="btnText">Scan File</span>
|
||||||
|
<span id="btnSpinner" class="spinner-border spinner-border-sm d-none" role="status"></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if result %}
|
||||||
|
<div class="result-card card {% if result.risk_level == 'HIGH' %}border-danger{% elif result.risk_level == 'MEDIUM' %}border-warning{% else %}border-success{% endif %} bg-secondary-dark mb-5 shadow-lg">
|
||||||
|
<div class="card-header {% if result.risk_level == 'HIGH' %}bg-danger{% elif result.risk_level == 'MEDIUM' %}bg-warning text-dark{% else %}bg-success{% endif %} fw-bold">
|
||||||
|
Scan Result: {{ result.risk_level }} RISK
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<h4 class="mb-3">{{ result.filename }}</h4>
|
||||||
|
<p class="mb-2"><strong>SHA256 Hash:</strong> <code class="text-accent">{{ result.file_hash }}</code></p>
|
||||||
|
<p class="mb-0"><strong>Reasons for Assessment:</strong></p>
|
||||||
|
<ul class="mt-2">
|
||||||
|
{% for reason in result.reasons.split|slice:":-1" %}
|
||||||
|
<li>{{ reason }}</li>
|
||||||
|
{% empty %}
|
||||||
|
<li>{{ result.reasons }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div id="recent-scans" class="mb-5">
|
||||||
|
<h3 class="mb-4 font-heading">Recent Scans</h3>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-dark table-hover border-secondary">
|
||||||
|
<thead class="table-secondary-dark">
|
||||||
|
<tr>
|
||||||
|
<th>Filename</th>
|
||||||
|
<th>Risk Level</th>
|
||||||
|
<th>Date</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for scan in recent_scans %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ scan.filename }}</td>
|
||||||
|
<td>
|
||||||
|
<span class="badge {% if scan.risk_level == 'HIGH' %}bg-danger{% elif scan.risk_level == 'MEDIUM' %}bg-warning text-dark{% else %}bg-success{% endif %}">
|
||||||
|
{{ scan.risk_level }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>{{ scan.created_at|date:"M d, Y H:i" }}</td>
|
||||||
|
</tr>
|
||||||
|
{% empty %}
|
||||||
|
<tr>
|
||||||
|
<td colspan="3" class="text-center text-secondary">No recent scans found.</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block extra_js %}
|
||||||
|
<script>
|
||||||
|
const dropZone = document.getElementById('dropZone');
|
||||||
|
const uploadTrigger = document.getElementById('uploadTrigger');
|
||||||
|
const fileInput = document.getElementById('fileInput');
|
||||||
|
const fileLabel = document.getElementById('fileLabel');
|
||||||
|
const scanForm = document.getElementById('scanForm');
|
||||||
|
const submitBtn = document.getElementById('submitBtn');
|
||||||
|
const btnText = document.getElementById('btnText');
|
||||||
|
const btnSpinner = document.getElementById('btnSpinner');
|
||||||
|
|
||||||
|
uploadTrigger.addEventListener('click', () => fileInput.click());
|
||||||
|
|
||||||
|
fileInput.addEventListener('change', () => {
|
||||||
|
if (fileInput.files.length > 0) {
|
||||||
|
fileLabel.textContent = fileInput.files[0].name;
|
||||||
|
uploadTrigger.classList.add('border-accent');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
scanForm.addEventListener('submit', () => {
|
||||||
|
submitBtn.disabled = true;
|
||||||
|
btnText.textContent = 'Analyzing...';
|
||||||
|
btnSpinner.classList.remove('d-none');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Drag and drop logic
|
||||||
|
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
|
||||||
|
dropZone.addEventListener(eventName, e => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
}, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
['dragenter', 'dragover'].forEach(eventName => {
|
||||||
|
dropZone.addEventListener(eventName, () => dropZone.classList.add('bg-secondary'), false);
|
||||||
|
});
|
||||||
|
|
||||||
|
['dragleave', 'drop'].forEach(eventName => {
|
||||||
|
dropZone.addEventListener(eventName, () => dropZone.classList.remove('bg-secondary'), false);
|
||||||
|
});
|
||||||
|
|
||||||
|
dropZone.addEventListener('drop', e => {
|
||||||
|
const dt = e.dataTransfer;
|
||||||
|
const files = dt.files;
|
||||||
|
fileInput.files = files;
|
||||||
|
if (files.length > 0) {
|
||||||
|
fileLabel.textContent = files[0].name;
|
||||||
|
uploadTrigger.classList.add('border-accent');
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
from . import views
|
||||||
from .views import home
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("", home, name="home"),
|
path("", views.index, name="index"),
|
||||||
|
path("scan/", views.scan_file, name="scan_file"),
|
||||||
]
|
]
|
||||||
@ -1,25 +1,71 @@
|
|||||||
|
import hashlib
|
||||||
import os
|
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
|
def index(request):
|
||||||
from django.shortcuts import render
|
scans = FileScan.objects.all()[:10]
|
||||||
from django.utils import timezone
|
return render(request, "core/index.html", {"recent_scans": scans})
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
def home(request):
|
# Calculate SHA256
|
||||||
"""Render the landing screen with loader and environment details."""
|
sha256_hash = hashlib.sha256(content).hexdigest()
|
||||||
host_name = request.get_host().lower()
|
|
||||||
agent_brand = "AppWizzy" if host_name == "appwizzy.com" else "Flatlogic"
|
|
||||||
now = timezone.now()
|
|
||||||
|
|
||||||
context = {
|
# Basic Static Analysis
|
||||||
"project_name": "New Style",
|
risk_level = 'LOW'
|
||||||
"agent_brand": agent_brand,
|
reasons = []
|
||||||
"django_version": django_version(),
|
|
||||||
"python_version": platform.python_version(),
|
# 1. Extension check
|
||||||
"current_time": now,
|
ext = os.path.splitext(filename)[1].lower()
|
||||||
"host_name": host_name,
|
danger_exts = ['.exe', '.dll', '.bin', '.sh', '.bat', '.msi', '.js', '.vbs', '.ps1', '.py']
|
||||||
"project_description": os.getenv("PROJECT_DESCRIPTION", ""),
|
if ext in danger_exts:
|
||||||
"project_image_url": os.getenv("PROJECT_IMAGE_URL", ""),
|
risk_level = 'MEDIUM'
|
||||||
}
|
reasons.append(f"Suspicious file extension: {ext}")
|
||||||
return render(request, "core/index.html", context)
|
|
||||||
|
# 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')
|
||||||
@ -1,4 +1,108 @@
|
|||||||
/* Custom styles for the application */
|
:root {
|
||||||
body {
|
--primary-bg: #1a1a1a;
|
||||||
font-family: system-ui, -apple-system, sans-serif;
|
--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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,21 +1,108 @@
|
|||||||
|
|
||||||
:root {
|
:root {
|
||||||
--bg-color-start: #6a11cb;
|
--primary-bg: #1a1a1a;
|
||||||
--bg-color-end: #2575fc;
|
--secondary-bg: #2d2d2d;
|
||||||
--text-color: #ffffff;
|
--accent: #00ff9d;
|
||||||
--card-bg-color: rgba(255, 255, 255, 0.01);
|
--accent-hover: #00e68e;
|
||||||
--card-border-color: rgba(255, 255, 255, 0.1);
|
--hazard: #ff9f43;
|
||||||
|
--danger: #ee5253;
|
||||||
|
--text-light: #f8f9fa;
|
||||||
|
--text-muted: #adb5bd;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
background-color: var(--primary-bg);
|
||||||
|
color: var(--text-light);
|
||||||
font-family: 'Inter', sans-serif;
|
font-family: 'Inter', sans-serif;
|
||||||
background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end));
|
}
|
||||||
color: var(--text-color);
|
|
||||||
display: flex;
|
.font-heading {
|
||||||
justify-content: center;
|
font-family: 'Space Grotesk', sans-serif;
|
||||||
align-items: center;
|
}
|
||||||
min-height: 100vh;
|
|
||||||
text-align: center;
|
.text-accent {
|
||||||
overflow: hidden;
|
color: var(--accent);
|
||||||
position: relative;
|
}
|
||||||
|
|
||||||
|
.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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user