Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bump to main #22

Merged
merged 8 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## 02/12/2024

- Release v0.1.7 Gemini-self-protector for Flask
- Fix bug
- Refactor source code
- Add new dashboard metrix

## 12/11/2023

- Release v0.1.6 Gemini-self-protector for Flask
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Gemini - The Runtime Application Self Protection (RASP) Solution Combined With Deep Learning

[![CodeQL](https://github.com/noobpk/gemini-self-protector/actions/workflows/codeql.yml/badge.svg?branch=main)](https://github.com/noobpk/gemini-self-protector/actions/workflows/codeql.yml)
[![trivy](https://github.com/noobpk/gemini-self-protector/actions/workflows/trivy.yml/badge.svg?branch=main)](https://github.com/noobpk/gemini-self-protector/actions/workflows/trivy.yml)
![Static Badge](https://img.shields.io/badge/python-3.x-blue?logo=python)
![Static Badge](https://img.shields.io/badge/Deep%20Learning-orange)
![Static Badge](https://img.shields.io/badge/Convolutional%20Neural%20Network-yellow)
Expand Down Expand Up @@ -76,6 +77,10 @@ Gemini supports 3 modes and recommends sensitivity levels for the application to

## Screenshot

### New Dashboard Metrix

![image](https://github.com/user-attachments/assets/d7733f82-fc81-42a2-99f6-b08d6f5255be)

### Dashboard

<img width="1440" alt="image" src="https://github.com/noobpk/gemini-self-protector/assets/31820707/068048ef-42cf-4032-b064-137d69abccb6">
Expand Down
8 changes: 7 additions & 1 deletion gemini-python/gemini_self_protector/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# Changelog

## v0.1.5 (12/11/2023)
## v0.1.6 (2/12/2024)

- Fix bug
- Refactor source code
- Add new dashboard metrix

## v0.1.6 (12/11/2023)

- Fix bug
- Refactor source code
Expand Down
1,006 changes: 640 additions & 366 deletions gemini-python/gemini_self_protector/poetry.lock

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion gemini-python/gemini_self_protector/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "gemini_self_protector"
version = "0.1.6"
version = "0.1.7"
description = "Runtime Application Self-Protection"
authors = ["lethanhphuc"]
license = "MIT"
Expand All @@ -16,6 +16,8 @@ cachetools = "^5.3.1"
passlib = "^1.7.4"
requests = "^2.31.0"
tqdm = "^4.66.1"
argon2-cffi = "^23.1.0"
psutil = "^6.1.0"

[tool.poetry.dev-dependencies]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -714,3 +714,13 @@ def g_serve_diagnostic() -> None:
"_Gemini.g_serve_diagnostic", e
)
)

def g_server_performance() -> None:
try:
return _Utils.g_server_performance()
except Exception as e:
logger.error(
"[x_x] Something went wrong at {0}, please check your error message.\n Message - {1}".format(
"_Gemini.g_server_performance", e
)
)
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from flask import Flask, Blueprint, request, render_template, session, redirect, url_for, flash, jsonify, send_file
from ._logger import logger
from ._gemini import _Gemini
from passlib.hash import argon2
import argon2
from datetime import datetime
import ipaddress
import re
Expand All @@ -13,6 +13,8 @@
import urllib.parse
import sys

ph = argon2.PasswordHasher()

class _Gemini_GUI(object):

def __init__(self, flask_app: Flask) -> None:
Expand Down Expand Up @@ -148,7 +150,7 @@ def gemini_install():
"g_serve_key": g_serve_key
})
_Gemini.update_gemini_user({
"password": argon2.hash(password),
"password": ph.hash(password),
})
logger.info(
"[+] Install gemini-self-protector successful.!")
Expand Down Expand Up @@ -207,8 +209,11 @@ def gemini_login():
app_username = _Gemini.get_gemini_user().username
app_password = _Gemini.get_gemini_user().password

password_check = argon2.verify(password, app_password)

try:
password_check = ph.verify(app_password, password)
except argon2.exceptions.VerifyMismatchError:
return render_template('gemini-protector-gui/accounts/login.html', msg="Incorrect Username / Password")

if username == app_username and password_check:
session['gemini_logged_in'] = True
flash('Welcome back {}!'.format(
Expand Down Expand Up @@ -241,7 +246,7 @@ def gemini_profile():
return render_template('gemini-protector-gui/home/profile.html', msg="Invalid password")

_Gemini.update_gemini_config({
"gemini_app_password": argon2.hash(password),
"gemini_app_password": ph.hash(password),
})
logger.info("[+] Update password successful.")
return redirect(url_for('nested_service.gemini_login'))
Expand Down Expand Up @@ -271,6 +276,7 @@ def gemini_dashboard():
request_log = _Gemini.get_gemini_request_log()
beharvior_log = _Gemini.get_gemini_behavior_log()
# predict_server_status = _Gemini.health_check_predict_server()
server_performance = _Gemini.g_server_performance()

sorted_request_log_data = sorted(
request_log, key=lambda x: x.time)
Expand All @@ -281,7 +287,7 @@ def gemini_dashboard():
start_index = (page - 1) * per_page
end_index = start_index + per_page
limited_request_log_data = sorted_request_log_data[start_index:end_index]

attack_counts = {
'Malicious Request': 0,
'ACL Block': 0,
Expand Down Expand Up @@ -320,7 +326,8 @@ def gemini_dashboard():
_gemini_notification_channel=gemini_config.notification_channel,
_gemini_attack_counts=attack_counts,
_any_attack_count_gt_zero=any_attack_count_gt_zero,
_gemini_beharvior_log_data=beharvior_log
_gemini_beharvior_log_data=beharvior_log,
_server_performance=server_performance
)
except Exception as e:
logger.error("[x_x] Something went wrong at {0}, please check your error message.\n Message - {1}".format(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import socket
from hashlib import sha256
from requests.exceptions import ConnectionError

import psutil

class _Utils(object):
def g_wvd_serve_predict(_payload) -> None:
Expand Down Expand Up @@ -176,7 +176,7 @@ def create_path() -> None:

def load_banner():
print(
"""\033[1;31m \n
r"""\033[1;31m \n
__ ___ __ ___ ___ __ __ __ ___ ___ __ ___ __ __
/ _` |__ |\/| | |\ | | /__` |__ | |__ |__) |__) / \ | |__ / ` | / \ |__)
\__> |___ | | | | \| | .__/ |___ |___ | | | \ \__/ | |___ \__, | \__/ | \
Expand Down Expand Up @@ -282,7 +282,7 @@ def g_decoder_and_rule_based_detection(_string):
"""Decode a string using the specified encoding type."""

# Remove the invalid escape sequences - # Remove the backslash
string = _string.replace("\%", "%").replace("\\", "").replace("<br/>", "")
string = _string.replace(r"\%", "%").replace("\\", "").replace("<br/>", "")

string = string.encode().decode("unicode_escape")

Expand All @@ -308,7 +308,7 @@ def g_decoder_and_rule_based_detection(_string):
# Try second base64-decode
try:
string = (
string.replace("\%", "%")
string.replace(r"\%", "%")
.replace("\\", "")
.replace("<br/>", "")
.replace(" ", "")
Expand Down Expand Up @@ -394,6 +394,46 @@ def g_decoder_and_rule_based_detection(_string):
)
)

def g_server_performance():
try:
# Conversion factor for bytes to GB
BYTES_TO_GB = 1_073_741_824

server_metrix = {
"CPU": None,
"MEMORY": None,
"NETWORK_IN": None,
"NETWORK_OUT": None,
"DISK_READ": None,
"DISK_WRITE": None,
}

# Fetch CPU and memory metrics
server_metrix["CPU"] = psutil.cpu_percent(interval=1)
server_metrix["MEMORY"] = psutil.virtual_memory().percent

# Fetch network metrics
net_io = psutil.net_io_counters()
server_metrix["NETWORK_IN"] = net_io.bytes_recv / BYTES_TO_GB # Total bytes received
server_metrix["NETWORK_OUT"] = net_io.bytes_sent / BYTES_TO_GB # Total bytes sent

# Fetch disk metrics
disk_io = psutil.disk_io_counters()
server_metrix["DISK_READ"] = disk_io.read_bytes / BYTES_TO_GB # Total bytes read
server_metrix["DISK_WRITE"] = disk_io.write_bytes / BYTES_TO_GB # Total bytes written

# Round all values to 2 decimal places
for key in server_metrix:
if isinstance(server_metrix[key], (float, int)):
server_metrix[key] = round(server_metrix[key], 2)

return server_metrix
except Exception as e:
logger.error(
"[x_x] Something went wrong at {0}, please check your error message.\n Message - {1}".format(
"_Utils.g_server_performance", e
)
)

class _Validator(object):
def validate_g_serve_key(_key) -> None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,108 @@
<div class="card-block">
<div class="row d-flex align-items-center">
<div class="col-auto">
{%if _anti_dos %}
{%if _server_performance['CPU'] < 80 %}
<i class="feather icon-cpu f-30 text-c-green"></i>
{%else%}
<i class="feather icon-cpu f-30 text-c-red"></i>
{% endif %}
</div>
<div class="col">
<h3 class="f-w-300">{{_server_performance['CPU']}}%</h3>
<span class="d-block text-uppercase">CPU USAGE</span>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6 col-xl-4">
<div class="card">
<div class="card-block">
<div class="row d-flex align-items-center">
<div class="col-auto">
{%if _server_performance['MEMORY'] < 80 %}
<i class="feather icon-cpu f-30 text-c-green"></i>
{%else%}
<i class="feather icon-cpu f-30 text-c-red"></i>
{% endif %}
</div>
<div class="col">
<h3 class="f-w-300">{{_server_performance['MEMORY']}}%</h3>
<span class="d-block text-uppercase">MEMORY USAGE</span>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6 col-xl-4">
<div class="card">
<div class="card-block">
<div class="row d-flex align-items-center">
<div class="col-auto">
<i class="feather icon-activity f-30 text-c-green"></i>
</div>
<div class="col">
<h3 class="f-w-300">{{_server_performance['NETWORK_IN']}} GB</h3>
<span class="d-block text-uppercase">NETWORK IN</span>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6 col-xl-4">
<div class="card">
<div class="card-block">
<div class="row d-flex align-items-center">
<div class="col-auto">
<i class="feather icon-disc f-30 text-c-green"></i>
</div>
<div class="col">
<h3 class="f-w-300">{{_server_performance['DISK_READ']}} GB</h3>
<span class="d-block text-uppercase">DISK READ</span>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6 col-xl-4">
<div class="card">
<div class="card-block">
<div class="row d-flex align-items-center">
<div class="col-auto">
<i class="feather icon-disc f-30 text-c-green"></i>
</div>
<div class="col">
<h3 class="f-w-300">{{_server_performance['DISK_WRITE']}} GB</h3>
<span class="d-block text-uppercase">DISK WRITE</span>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6 col-xl-4">
<div class="card">
<div class="card-block">
<div class="row d-flex align-items-center">
<div class="col-auto">
<i class="feather icon-activity f-30 text-c-green"></i>
</div>
<div class="col">
<h3 class="f-w-300">{{_server_performance['NETWORK_OUT']}} GB</h3>
<span class="d-block text-uppercase">NETWORK OUT</span>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6 col-xl-4">
<div class="card">
<div class="card-block">
<div class="row d-flex align-items-center">
<div class="col-auto">
{%if _anti_dos %}
<i class="feather icon-shield f-30 text-c-green"></i>
{%else%}
<i class="feather icon-activity f-30 text-c-red"></i>
<i class="feather icon-shield f-30 text-c-red"></i>
{% endif %}
</div>
<div class="col">
Expand Down