PYTHON


class PrefixMiddleware(object):

    def __init__(self, app, prefix=''):
        self.app = app
        self.prefix = prefix

    def __call__(self, environ, start_response):

        if environ['PATH_INFO'].startswith(self.prefix):
            environ['PATH_INFO'] = environ['PATH_INFO'][len(self.prefix):]
            environ['SCRIPT_NAME'] = self.prefix
            return self.app(environ, start_response)
        else:
            start_response('404', [('Content-Type', 'text/plain')])
            return ["This url does not belong to the app.".encode()]

# Add to application file e.g : app.py
app.wsgi_app = PrefixMiddleware.PrefixMiddleware(app.wsgi_app, prefix='/graphbureau')
  

# Default Config 

import flask_sock
import simple_websocket
import werkzeug
import gunicorn

from os import name, path as os_path
from platform import system, release, machine, architecture, version
from threading import Thread
from time import sleep
from psutil import virtual_memory, cpu_percent
from requests import get, post
from ast import literal_eval
from re import findall, match
from random import choice
from string import digits
from socket import gethostname
from sys import path as sys_path, version, version_info
from sysconfig import get_platform
from hashlib import sha3_256

from flask import Flask, render_template, request, abort, jsonify, send_from_directory, redirect, url_for, session, make_response, __version__
from turbo_flask import Turbo
from lib import WEBTOMYSQL
from lib import ressources
from lib import MAIL
from uptime import boottime
from _datetime import datetime, timedelta
from uuid import uuid4

__STATIC_DIR = os_path.abspath('./static')
__TEMPLATE_DIR = os_path.abspath('./templates')

app = Flask(__name__, static_folder=__STATIC_DIR, template_folder=__TEMPLATE_DIR)
titre = "..."
app.secret_key = "..."

# Using a production configuration
app.jinja_env.filters['page_title'] = title
app.config['JSON_ADD_STATUS'] = True
app.config['JSON_STATUS_FIELD_NAME'] = 'http_status'
app.config["SESSION_COOKIE_HTTPONLY"] = True
app.config["SESSION_COOKIE_SECURE"] = True
app.config["SESSION_COOKIE_SAMESITE"] = True
app.config["JSON_SORT_KEYS"] = False
# app.config["SERVER_NAME"] = ""
csrf_protection = False


csrf_protection = False

  

turbo = Turbo(app)

# Firt Function
def update_load():
    with app.app_context():
        while True:
            # Type your .html file in template
            turbo.push(turbo.update(render_template(__TURBO_PUSH_PAGE+'dyn_sysinfo.html'), target='load'))
            sleep(0.5)


# Before First @app.route('...')
@app.before_request
def before_first_request():
    # Auto Logout for inactivity
    session.permanent = True
    app.permanent_session_lifetime = timedelta(minutes=25)
    # Turbo Flask Threading
    Thread(target=update_load).start()

### Last Version 

@app.before_first_request
def before_first_request():
    threading.Thread(target=update_load).start()


def update_load():
    with app.app_context():
        while True:
            time.sleep(5)
            turbo.push(turbo.replace(render_template('loadavg.html'), 'load'))


th = threading.Thread(target=update_load)
th.daemon = True
th.start()

## Remove deprecated @before_first_request decorator from "load" example (commit)

# END Last Version 

# Last app. function Before if__name__ = "__main__" :

# Turbo Flask Dynamic update WEB.VX & OTHER Sys infos systems
@app.context_processor
def inject_load():
    info_sys = get("...")
    extract = literal_eval(info_sys.text)
    cpu = extract["cpu_percent"]
    mem = extract["memory"]["percent"]
    return {"cpu_percent": cpu_percent(0),
            "memory": virtual_memory().percent,
            "cpu": cpu,
            "mem": mem}

## Exemple de configuration de Class Function pour un Web clean
#
#

# Web part
# End -----------------------------------
import gunicorn
import gevent
import flask_sock
import simple_websocket
import werkzeug
import PrefixMiddleware
from os import name, path
import os.path
from platform import system, release, machine, architecture, version as plt_vers
from threading import Thread
from time import sleep
from psutil import virtual_memory, cpu_percent
from requests import get, post
from ast import literal_eval
from re import findall, match
from random import choice
from string import digits
from socket import gethostname, gethostbyname
from sys import path, version, version_info
from sysconfig import get_platform

from flask import Flask, render_template, request, abort, jsonify, send_from_directory, url_for, session, redirect, make_response, __version__
from turbo_flask import Turbo
from uptime import boottime
from hashlib import sha3_256
from _datetime import datetime, timedelta
from uuid import uuid4
path.insert(1, 'lib/python3.10/site-packages/dcplib')
import WEBTOMYSQL
import MAIL
import ressources



# init VALUES FLASK WEB
__STATIC_DIR = os.path.abspath('./static')
__TEMPLATE_DIR = os.path.abspath('./templates')
__TURBO_PUSH_PAGE = 'turbo_push_pages/'

title = "WEB - TOOLS COMPANY-A"
app = Flask(__name__, static_folder=__STATIC_DIR, template_folder=__TEMPLATE_DIR)
app.secret_key = 'O!c9]UE]b1j.,Fg]}^tJS/;5*)wTA=1BY{!}b#*002IJ+f)[E*'

# API Initialization
#apimanager = flask_restless.APIManager
#apimanager.create_api(methods=['PATCH'], allow_patch_many=True, include_columns=["id", "notes", "dcp"])

# Using a production configuration
app.jinja_env.filters['page_title'] = title
app.config['JSON_ADD_STATUS'] = True
app.config['JSON_STATUS_FIELD_NAME'] = 'http_status'
app.config['JSON_SORT_KEYS'] = False
app.config['SESSION_COOKIE_SAMESITE'] = None
app.config['SESSION_COOKIE_SECURE'] = True
csrf_protection = False

#Add to application file e.g : app.py
app.wsgi_app = PrefixMiddleware.PrefixMiddleware(app.wsgi_app, prefix='/prefix')
turbo = Turbo(app)

# Create Flask application

# Init default function part
# Begin -------------------------
# Function

# RENDER_TEMPLATE
def update_load():
    with app.app_context():
        while True:
            turbo.push(turbo.update(render_template(__TURBO_PUSH_PAGE+'dyn_sysinfo.html'), target='load'))
            sleep(1)
            try:
                turbo.push(turbo.update(render_template(__TURBO_PUSH_PAGE+'dyn_sysinfo_cru.html'), target='load_b'))
                sleep(1)
            except:
                pass


class ALL_FUNCTION:
    # init all variables usefull to call Function
    def __init__(self,
                 page_html=None,
                 name_page=title,
                 arg_dict=None,
                 return_values=None,
                 status=None,
                 bdd=None,
                 data=None,
                 data_b=None):
        self.page_html = page_html
        self.name_page = name_page
        self.arg_dict = arg_dict
        self.return_values = return_values
        self.status = status
        self.bdd = bdd
        self.data = data
        self.data_b = data_b

    # Init BDD Connection
    def connec_dcp(self):
        bddconn = WEBTOMYSQL.WEB_BDD()
        if self.bdd == "localbdd":
            bddconn = bddconn.connec_localbdd()
        if self.bdd == "auth":
            bddconn = bddconn.connec_auth()
        elif self.bdd == "adminbdd2":
            bddconn = bddconn.connec_adminbdd2()
        elif self.bdd == "adminbdd3":
            bddconn = bddconn.connec_adminbdd3()
        return bddconn

    # Render HTML
    def render_html(self):
        if len(session) >= 4 and session['loggedin'] and loggedin():
            return render_template(self.page_html,
                                   title=self.name_page,
                                   letime=datetime,
                                   stylesweb='../web/static/stylesweb.css',
                                   styles_bt='../web/static/css/',
                                   script_bt='../web/static/js/',
                                   dt_css='../web/static/DataTables/', dt_script='../web/static/DataTables/',
                                   get=self.data, get_b=self.data_b, zip=zip, se=session['info'])
        else:
            return redirect(url_for('login'))

    # Render HTML Authentification Section
    def render_html_auth(self):
        return render_template(f'./auth_section/{self.page_html}',
                               title=self.name_page,
                               srv=str(gethostname()).split('.')[0].upper(),
                               stylelogin='../web/static/auth_section/stylelogin.css',
                               get=self.data, styles_bt='../web/static/css/',
                               script_bt='../web/static/js/')


    # Render HTML Authentification Section
    def render_html_profile(self):
        if len(session) >= 4 and session['loggedin'] and loggedin():
            return render_template(f'./profile_section/{self.page_html}',
                                   title=self.name_page,
                                   stylelogin='../static/auth_section/stylelogin.css',
                                   get=self.data,
                                   styles_bt='../static/css/',
                                   script_bt='../static/js/',
                                   se=session['info'])
        else:
            return redirect(url_for('login'))

    # Render JSON for ZingGrid Data in Table
    def render_json(self):
        # head_title = "API Return JSON FORMAT For ZingGrid"
        if len(session) >= 4 and session['loggedin']:
            # head_title = "API Return JSON FORMAT For ZingGrid"
            if self.return_values == 0:
                if self.status is None:
                    self.status = 200
                return jsonify(self.arg_dict)
        else:
            return redirect(url_for('login'))


    def randtoken(self):
        token = "0"
        for i in range(0, 12):
            token += choice(digits)
        return str(token)


# Specific Class to get DATA on ZingGRid Tables
class API:
    # Class to get API response {JSON}, requested by ZingGrid modules
    def __init__(self, base, rqst, data=None, meth=None):
        self.base = base
        self.rqst = rqst
        self.data = data
        self.meth = meth

    # Return REQUEST SQL RESULT
    def select_mysql(self):
        sql = ALL_FUNCTION(bdd=self.base)
        cur = sql.connec_dcp().cursor()
        cur.execute(self.rqst, self.data)
        fields = [field_md[0] for field_md in cur.description]
        result = [dict(zip(fields, row)) for row in cur.fetchall()]
        cur.close()
        return result

    # Update statements in All ZingGrid Table
    def update_mysql(self):
        sql = ALL_FUNCTION(bdd=self.base)
        cur = sql.connec_dcp()
        if self.meth == "PATCH":
            cur.cursor().execute(self.rqst % self.data)
        elif self.meth == "POST":
            cur.cursor().execute(self.rqst, self.data)
        cur.commit()
        cur.close()
        return 200

    # Return REQUEST SQL RESULT
    def standard(self):
        sql = ALL_FUNCTION(bdd=self.base)
        cur = sql.connec_dcp().cursor()
        cur.execute(self.rqst, self.data)
        return cur

# End Function Part -------------------


# Web Part
# Begin ---------------
@app.before_first_request
def before_first_request():
    # Auto Logout for inactivity
    session.permanent = True
    app.permanent_session_lifetime = timedelta(minutes=25)
    # Turbo Flask Threading
    Thread(target=update_load).start()



# APP Configuration DEV Env
if __name__ == "__main__":
    app.run(debug=True, port=5000, host="127.0.0.1")
    app.config.update(SECRET_KEY="[A Modifier]",
                      STATIC_FOLDER='static',
                      TEMPLATES_FOLDER='templates',
                      FLASK_ENV='production',
                      SERVER_NAME="web.exemple.com",
                      TESTING=False,
                      DEBUG=True,
                      TITRE=title,
                      JSONIFY_PRETTYPRINT_REGULAR=True)
    turbo.init_app(app)

SECURITY EVAL OSCAP



oscap xccdf eval --profile xccdf_org.ssgproject.content_profile_ospp --results-arf results.xml --report report.html /usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml

oscap oval eval --datastream-id ds.xml --oval-id xccdf.xml --results oval-results.xml scap-ds.xml
oscap oval eval --results results.xml r2860-rhel-oval.xml

oscap info --profile xccdf_org.ssgproject.content_profile_ospp /usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml


wget https://www.redhat.com/security/data/metrics/com.redhat.rhsa-all.xccdf.xml
wget https://www.redhat.com/security/data/oval/com.redhat.rhsa-all.xml

oscap oval eval --results results.xml --report report.html com.redhat.rhsa-all.xml


13.2. Auditing Security Vulnerabilities of Red Hat Products
wget https://www.redhat.com/security/data/metrics/com.redhat.rhsa-all.xccdf.xml
wget https://www.redhat.com/security/data/oval/com.redhat.rhsa-all.xml

oscap xccdf eval --results results-rhsa.xml --report report-rhsa.html com.redhat.rhsa-all.xccdf.xml


13.2.3. Source data stream
wget https://www.redhat.com/security/data/metrics/ds/com.redhat.rhsa-all.ds.xml

oscap xccdf eval --results results.xml --report report.html com.redhat.rhsa-all.ds.xml


13.4. How to Evaluate DISA STIG

wget https://dl.dod.cyber.mil/wp-content/uploads/stigs/zip/U_RHEL_7_V3R2_STIG_SCAP_1-2_Benchmark.zip
unzip U_RHEL_7_V3R2_STIG_SCAP_1-2_Benchmark.zip

oscap info U_RHEL_7_V3R2_STIG_SCAP_1-2_Benchmark.xml

oscap xccdf eval \
--profile xccdf_mil.disa.stig_profile_MAC-1_Public \
--results-arf results.xml \
--report report.html \
U_RHEL_7_V3R2_STIG_SCAP_1-2_Benchmark.xml


source = https://static.open-scap.org/openscap-1.3/oscap_user_manual.html#_auditing_securityvulnerabilities_of_red_hat_products
  

LINUX

Rename multiple files with prefix or suffix in Linux console
Count number of files in directory and subdirectories
Replace spaces in file names by underscores on Linux console
Shell Script - check if another instance of same script is running
NTP Server Configuration

# For more information about this file, see the ntp.conf(5) man page.

# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (https://www.pool.ntp.org/join.html).
server ntp.kuro-home.net iburst
server ntp.genoscope.cns.fr iburst
server ntp-p1.obspm.fr iburst
server saturne.obs-besancon.fr iburst prefer
server ntp.crashdump.fr iburst

# Reduce the maximum number of servers used from the pool.
tos maxclock 5

# Record the frequency of the system clock.
driftfile /var/lib/ntp/drift

# Disable configuration and monitoring access by default.
#restrict default nomodify noquery
#restrict default nomodify

# Enable all access for localhost.
#restrict 127.0.0.1
#restrict ::1
restrict localhost
restrict -6 ::1
restrict default kod limited nomodify notrap nopeer noquery
restrict -6 default kod limited nomodify notrap nopeer noquery

# Enable writing of statistics records.
#statistics clockstats cryptostats loopstats peerstats

# TLS
nts key /etc/nginx/certs/privkey.pem
nts cert /etc/nginx/certs/fullchain.pem
nts cookie /var/lib/ntp/nts-keys
Kill multiple instances apps

ps ax | grep  | grep -v grep | awk '{print $1}' | xargs kill
# or
kill -9 `pgrep ssh`
kill -9 `pgrep telnet`
Scan Multiple Network - Subnet, telnet, ssh, where you specified username or company

#!/bin/bash

base_ip="192.168."
sub=16
i=20
type="auto" # set on one to check one IP | auto to range

if [ ${type} == "auto" ]; then
while [ ${sub} -le 64 ]; do
                if [ ${i} == 255 ]; then
                        echo "end of subnet = ${sub}"
                        sub=$(( ${sub} + 1 ))
                        i=1
                fi
        echo "IP courant = ${i}, sur le subnet ${sub}"
        # TIMEOUT=5; telnet ${base_ip}${i}
        { printf "HEAD /\n\n"; sleep 2; } | telnet ${base_ip}${sub}.${i} & sleep 2 && kill %1
        { printf "HEAD /\n\n"; sleep 2; } | ssh username@${base_ip}${sub}.${i} & sleep 2 && kill %1
        { printf "HEAD /\n\n"; sleep 2; } | ssh company@${base_ip}${sub}.${i} & sleep 2 && kill %1
        i=$(( ${i} + 1 ))
        echo "${base_ip}${sub}.${i}"
done
else
        echo ${i}
        # TIMEOUT=5; telnet ${base_ip}${i}
        { printf "HEAD /\n\n"; sleep 2; } | telnet ${base_ip}${sub}.${i} & sleep 2 && kill %1
        { printf "HEAD /\n\n"; sleep 2; } | ssh username@${base_ip}${sub}.${i} & sleep 2 && kill %1
        { printf "HEAD /\n\n"; sleep 2; } | ssh company@${base_ip}${sub}.${i} & sleep 2 && kill %1
        i=$(( ${i} + 1 ))
        echo "${base_ip}${sub}.${i}"
fi
Create Multiple Dirs with number index

mkdir ABC{1..10}
# Same with chown & chmod

NGINX FullConfiguration

Nginx Config Ex.

geo $ip_ok
{
1.2.3.4/24 1;
}


access_log /var/log/nginx/access.log main;

server {
        listen 1.2.3.4:443 ssl;
	http2 on;
	http3 on;
        #listen [::]:443 ssl http2;
        server_name ex.domain.com;

        # SSL configuration
        #
        # listen 443 ssl default_server;
        # listen [::]:443 ssl default_server;
        #
        # Note: You should disable gzip for SSL traffic.
        # See: https://bugs.debian.org/773332
        #
       # Read up on ssl_ciphers to ensure a secure configuration.
        # See: https://bugs.debian.org/765782
        #
        # Self signed certs generated by the ssl-cert package
        # Don't use them in a production server!
        #
        # include snippets/snakeoil.conf;
        include /etc/nginx/mime.types;
        include /etc/nginx/fastcgi_params;
        root /sur/share/nginx/html;

        # Add index.php to the list if you are using PHP
        index index.html index.htm index.nginx-debian.html;


        set $CSP_image  "img-src      'self' 'unsafe-inline' 'unsafe-eval' data: *.printfriendly.com *.w.org *.gravatar.com *.vimeocdn.com img.shields.io badge.fury.io codecov.io user-images.githubusercontent.com $server_name d25lcipzij17d.cloudfront.net *.tile.openstreetmap.org; ";
        set $CSP_script "script-src   'self' 'unsafe-inline' 'unsafe-eval' $server_name *.w.org *.gravatar.com *.googleapis.com *.jsdelivr.net *.printfriendly.com *.kxcdn.com *.vimeocdn.com *.hs-analytics.net *.securitymetrics.com *.google-analytics.com $server_name *.jquery.com *.datatables.net *.skypack.dev *.bootstrapcdn.com $server_name; ";
        set $CSP_style  "style-src    'self' 'unsafe-inline' *.googleapis.com *.bootstrapcdn.com *.gstatic.com *.vimeocdn.com $server_name cdnjs.cloudflare.com $server_name fonts.gstatic.com fonts.googleapis.com; ";
        set $CSP_font   "font-src     'self' data: $server_name *.bootstrapcdn.com github.com $server_name fonts.gstatic.com fonts.googleapis.com github.com; ";
        set $CSP_frame  "frame-src    'self' 'unsafe-inline' $server_name vpsts.speedtestcustom.com vpst.speedtestcustom.com;";
        set $CSP_object "object-src   'self' $server_name; ";
        set $CSP_connect "connect-src 'self' https://code.jquery.com/jquery-latest.min.js $server_name; ";
        set $CSP        "default-src  'self' ; ${CSP_image} ${CSP_script} ${CSP_style} ${CSP_font} ${CSP_frame} ${CSP_object} ${CSP_connect}";


        ssl_certificate /etc/nginx/certs/wild.pem;
        ssl_certificate_key /etc/nginx/certs/privkey.wild.pem;
        ssl_dhparam /etc/nginx/certs/dhparams.pem;
        # SECURITY PART
        ssl_protocols  TLSv1.2 TLSv1.3;
        ssl_prefer_server_ciphers on;
        #ssl_ciphers HIGH:!aNULL:!MD5;
        ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA38';
        ssl_session_cache    shared:SSL:10m;
        ssl_session_timeout  10m;
        # GZIP CONFIG
        gzip off;
        gzip_disable "msie6";

        gzip_vary on;
        gzip_proxied any;
        gzip_comp_level 6;
        gzip_buffers 16 8k;
        gzip_http_version 1.1;
        gzip_min_length 256;
        gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/rss+xml text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/jpeg image/png image/svg+xml image/x-icon;
        # la directive ci-dessus permet de lister les types de fichier à compresser

        ssl_stapling off;
        ssl_stapling_verify off;

        # User Restrictions
        ## Start: Size Limits & Buffer Overflows ##
        client_body_buffer_size  100k;
        client_header_buffer_size 200k;
        client_max_body_size 200k;
        large_client_header_buffers 2 100k;
        ## END: Size Limits & Buffer Overflows ##

        ## TCP Security ##
        tcp_nopush on;
        tcp_nodelay on;
        types_hash_max_size 2048;
        ## TCP Security ##

        ## Start: Timeouts ##
        client_body_timeout   10;
        client_header_timeout 10;
        keepalive_timeout     5;
        send_timeout          10;
        ## End: Timeouts ##

        ssl_session_tickets off;
        # Add Header Security
        # add_header  Cache-Control "no-transform" always;
        add_header 'Cache-Control' "public, max-age=10, no-transform" always;
        add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
        add_header X-Frame-Options "https://$server_name$request_uri" always;
        add_header X-XSS-Protection "1; mode=block" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header Content-Security-Policy $CSP;
        #add_header X-Frame-Options "SAMEORIGIN" always;
        add_header Expect-CT "enforce, max-age=300, report-uri='https://$server_name$request_uri'";
        #add_header Strict-Transport-Security: "max-age=36072000; includeSubDomains; preload";
        add_header Referrer-Policy "strict-origin-when-cross-origin" always;
        add_header 'Access-Control-Allow-Origin' https://$server_name$request_uri always;
        #add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, HEAD, PATCH, UPDATE, PUT';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
        add_header 'Access-Control-Allow-Origin' $http_origin;
        add_header Set-Cookie "Path=/; HttpOnly; Secure";
        valid_referers none blocked server_names;
        autoindex off;


        # Default HOME
        location / {

                if ( $request_method !~ ^(GET)$ )
                {
                                return 403;
                }
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        #include conf.d/default-ip-allowed.conf;
        #allow 0.0.0.0;
        #deny all;
        include /etc/nginx/default.d/*.conf;

        error_page 404 /custom_404.html;
        location = /custom_404.html {
        }

        error_page 403 /custom_403.html;
        location = /custom_403.html {
        }

        error_page 500 502 503 504 /custom_50x.html;
        location = /custom_50x.html {
        }

        }



        # 01
        location /01/ {
                        include conf.d/default-ip-allowed.conf;
                        include conf.d/allowed-ips-from-domains.conf;
                        deny all;
                        include default.d/error.conf;

                        if ($allowed_country = no) {
                                return 403;
                        }


                        if ($invalid_referer) {
                                 return   403;
                        }


                        if ( $request_method !~ ^(GET|POST)$ )
                        {
                                        return 403;
                        }

                        # try_files $uri $uri/ =404;
                        #rewrite ^/exp01/(.*) /$1 break;
                        #rewrite ^ $scheme://$server_name$request_uri? permanent;

                        proxy_pass https://ip_server:443/;
                        include conf.d/proxy.conf;
			# Remettre les baslies HTML <>
                        #sub_filter 'head' 'titleExemple Titre/title/head';
                        #sub_filter 'body' 'h1Exemple Chapter 1/h1';
                        sub_filter_once on;
        }

          location ~ /\.ht {
                        deny all;
                }