Eloan ANDRÉ 2 years ago
commit c7a8c0677a

@ -0,0 +1,85 @@
kind: pipeline
type: docker
name: default
trigger:
event:
- push
steps:
- name: build
image: python:3.9-slim-buster
volumes:
- name: docs
path: /docs
commands:
- cd src/
- python -m venv venv
- source venv/bin/activate
- pip install -r requirements.txt
- python setup.py install
- python -m pytest
- python setup.py sdist bdist_wheel
# docker image build
- name: docker-build-and-push
image: plugins/docker
settings:
dockerfile: ./Dockerfile
context: src/
registry: hub.codefirst.iut.uca.fr
repo: hub.codefirst.iut.uca.fr/louis.dufour/detection_d_intrusion
username:
from_secret: SECRET_REGISTRY_USERNAME
password:
from_secret: SECRET_REGISTRY_PASSWORD
- name: generate-and-deploy-docs
image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-docdeployer
failure: ignore
volumes:
- name: docs
path: /docs
commands:
#- cd Documentation/doxygen
#- doxygen Doxyfile
- /entrypoint.sh
when:
branch:
- master
depends_on: [ build ]
# container deployment
- name: deploy-container
image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-dockerproxy-clientdrone:latest
environment:
IMAGENAME: hub.codefirst.iut.uca.fr/louis.dufour/detection_d_intrusion:latest
CONTAINERNAME: containersae
COMMAND: create
OVERWRITE: true
depends_on: [ docker-build-and-push ]
- name: code-analysis
image: sonarsource/sonar-scanner-cli:latest
commands:
- cd src/
- sonar-scanner \
-Dsonar.projectKey=detection_d_intrusion \
-Dsonar.projectName=detection_d_intrusion \
-Dsonar.sources=. \
-Dsonar.host.url=https://codefirst.iut.uca.fr/sonar \
-Dsonar.login=$${PLUGIN_SONAR_TOKEN}
secrets: [ SONAR_TOKEN ]
settings:
# accessible en ligne de commande par $${PLUGIN_SONAR_HOST}
sonar_host: https://codefirst.iut.uca.fr/sonar/
# accessible en ligne de commande par $${PLUGIN_SONAR_TOKEN}
sonar_token:
from_secret: SONAR_TOKEN
depends_on: [build]
volumes:
- name: docs
temp: {}

@ -0,0 +1,15 @@
FROM python:3.9-slim-buster
WORKDIR /app
COPY src/ /app/src/
COPY requirements.txt /app/
COPY setup.py /app/
RUN python -m venv venv
RUN . venv/bin/activate && pip install -r requirements.txt && python setup.py install
RUN python -m pytest
RUN python setup.py sdist bdist_wheel
CMD ["python", "app.py"]

@ -0,0 +1,9 @@
## Rendez-vous du 17 Mars
- Il nous reste 14h (sans compter la séance du 17/03)
- Une fois la BDD qui marche, comment à tester :
- Utiliser des scripts de client pymodbus;
- ou avec des envois de paquets en dur directement dans le decodeur.
#### Prochain rendez-vous le Mardi 21 Mars à 10h15 (Démo du code)

@ -0,0 +1,23 @@
## Rendez-vous du 21 Mars
- Commenter la récursivité et justifier *(dans triPacket)*
- En terme de qualité de code c'est Zéro si on rend le décoder brut
- Doxygen
- Docker wazuh
### Ce qu'il reste à faire:
- filtrer les paquets (donc juste un dictionnaire "si j'ai coils 5 qui vaut true et le regsitre 45 j'empêche cette variable à tel valeurs" création de règle)
- Si un scénario est repérer on bloque tout la request *(S'il y a valeur interdite je bloque tout ou non ? (utile soustenance))*
- Prévoir démo soustenance
- Idée indicateur (métrique) pilnt/sonnar *(un code comme ça c'est détruit et refais)*
### Un docker pour:
- Code python
- Docker compose entre tout les container *(postgree, client, serveur, python)*
#### Prochain rendez-vous:
- Mercredi 29 Mars à 8h30 : démo BDD et rapport *(envoie Lundi 27 Mars soir)*
- Jeudi 30 Mars à 9h : oral blanc soutenance

@ -3,9 +3,10 @@
## Utilisation
### Install
```sh
// Install d'outil
python -m pip install pipenv
python3 -m pip install pipenv
// Install module
pip install typer
@ -18,6 +19,24 @@ pipenv update
// Lancement du shell pipenv
pipenv shell
```
**ATTENTION** : lorsque vous voulez faire un pipenv update cela vous donne une version buguée de pymodub qui est là `3.2.0` *(pour voir votre version faite un `pip freeze`)*
#### Marche à suivre:
1) Désinstallez la bibliothèque pymodbus à l'aide de la commande suivante:
> pipenv uninstall pymodbus
2) Installez une version précédente de la bibliothèque pymodbus en utilisant la commande suivante:
> pipenv install pymodbus==3.1.3
### Lancement
il faut lancé 3 terminal pipenv pour :
```sh
./start_server.sh
./start_client.sh
sudo python3 ./decoder.py
```
### Côté BDD
Il faudra que vous connectiez à votre BDD PostgreSQL.
Exécuter le script `Table.sql` qui se trouve dans src avec la commande ci-dessous.
@ -39,21 +58,34 @@ psql -h londres -d <nom_DataBase> -U <votre_nom_utilisateur> -W
**ATTENTION** `londres` est un serveur héberger dans l'infrastructure de notre établissement universitaire.
### Lancement
il faut lancé 3 terminal pipenv pour :
```sh
./start_server.sh
./start_client.sh
sudo python3 ./decoder.py
```
## Notre configuration
* Python (3.9)
* PostgreSQL
* pip (22.0.2)
* pymodbus (3.1.3)
Notre pipfile:
```
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
redis = "*"
click = "*"
prompt-toolkit = "*"
pymodbus = {extras = ["repl"], version = "*"}
sqlalchemy = "*"
scapy = "*"
ipython = "*"
[dev-packages]
[requires]
python_version = "3.9"
```
## Développeurs
* [Louis](https://codefirst.iut.uca.fr/git/louis.dufour)
* [Paul](https://codefirst.iut.uca.fr/git/paul.squizzato)

@ -0,0 +1,5 @@
psycopg2
pandas
getpass
scapy.all
scapy.contrib.modbus

@ -7,7 +7,6 @@
#
# ========================================================================
from cProfile import label
import psycopg2 as psy# pip3 install types-psycopg2
import pandas as pd # pip3 install pandas
import getpass
@ -19,24 +18,36 @@ import getpass
################# Fin Tips #################
def insert_Status(connection,flow):
def insert_Status(type, adresse, valeur):
if __name__ == '__main__':
db_host = input('Nom d\'hôte : ')
if not db_host:
db_host = 'londres'
db_name = input('Nom de la base de données : ')
if not db_name:
db_name = 'dblodufour1'
db_user = input('Utilisateur : ')
if not db_user:
db_user = 'ladufour1'
db_password = getpass('Mot de passe : ')
connection = psy.connect(host=db_host, database=db_name, user=db_user, password=db_password)
cur = connection.cursor()
for row in df.itertuples():
cur.execute("INSERT INTO Status VALUES (%s,%s,%s );",
(row.addresse,
row.type,
row.valeur)
)
for row in df.itertuples():
cur.execute("INSERT INTO Status VALUES (%s,%s,%s );",
(type,
adresse,
valeur)
)
connection.commit()
cur.close()
def status_State(connection):
cur = connection.cursor()
pd.read_sql(''' SELECT adresse, type, valeur FROM Status'''
pd.read_sql(''' SELECT adresse, type, valeur FROM Status''')
res = cur.fetchone()
return res
cur.close()
@ -67,4 +78,7 @@ if __name__ == '__main__':
create_tables(connection, 'Table.sql')
connection.close()
connection.close()
insert_Status(c,1,1)

@ -3,6 +3,8 @@
import scapy.all as scapy
import scapy.contrib.modbus as mb
from triPacket import triPacket
import getpass
def decode(pkt):
prt=0
@ -44,12 +46,12 @@ def decode(pkt):
valInter2=valInter[1:-1]
miniL[2]=valInter2
if miniL.count(0)==0:
if(type(miniL[2])==list):
if type(miniL[2])==list:
if miniL[0]=="r":
for i in range(len(miniL[2])):
if("0x" in miniL[2][i]):
if "0x" in miniL[2][i]:
miniL[2][i]=int(miniL[2][i],16)
if("0x" in str(miniL[1])):
if "0x" in str(miniL[1]):
miniL[1]=int(miniL[1],16)
bigL.append([miniL[0],miniL[1]+i,miniL[2][i]])
if miniL[0]=="c":
@ -92,11 +94,33 @@ def decode(pkt):
bigL.append(miniL)
if bigL!=[]:
print(bigL)
print("attention")
triPacket(bigL,connec)
miniL = [0,0,0,0]
bigL=[]
miniL = [0,0,0,0]
print("In order for data sniffed to be stored inside the database, please register the following :")
db_host = input('host of the database server : ')
if not db_host:
db_host = '192.168.128.141'
db_name = input('name of the database : ')
if not db_name:
db_name = 'dblodufour1'
db_user = input('login of the user : ')
if not db_user:
db_user = 'lodufour1'
db_password = getpass.getpass('user password : ')
connec=[db_host,db_name,db_user,db_password]
# si register 5 = 55 et coil 3 = 1 et coil 12 = 0 :
# ecriture sur le registre 8 à 72 ou coil 9 à 1 impossibles
# if ['r',5,55] and ['c',3,1] and ['c',12,0] and ecriture ['r',8,72]:
#bloquer ecriture
# ecrire registre 5 72,4,4,55,4
scapy.sniff(iface="lo", prn=decode)

@ -0,0 +1,24 @@
import psycopg2 as psy
import pandas as pd
import getpass
def verifRegle(a):
return True
def ecritureBDD(lStatus,connec):
co = None
try:
co = psy.connect(host=connec[0],database=connec[1],user=connec[2],password=connec[3])
cur = co.cursor()
for i in lStatus:
cur.execute("INSERT INTO Status VALUES (%s,%s,%s ) ON CONFLICT (addresse,type) DO UPDATE SET valeur=%s;",(i[1],i[0],i[2],i[2]))
if verifRegle(co):
co.commit()
else:
co.rollback()
cur.close()
except(Exception,psy.DatabaseError) as error:
print(error)
finally:
if co is not None:
co.close()

@ -1,32 +1,3 @@
# Install
```sh
python -m pip install pipenv
pipenv update
pipenv shell
```
# Run
Within pipenv, run in two terminals:
```sh
./start_server.sh
./start_client.sh
```
# Example commands
Within client run:
```
client.read_coils slave=1 address=0
client.write_coil slave=1 address=0 value=1
client.read_coils slave=1 address=0
```
See the first boolean was false in the first read, was written to true, and appears at true in second read.
# Client commands :
```
@ -44,4 +15,5 @@ client.write_registers address=0 values=845,123,0,427,4 slave=1
client.read_holding_registers address=0 count=1 slave=1
client.read_holding_registers address=0 count=100 slave=1
```
```

@ -0,0 +1,22 @@
from ecritureBDD import ecritureBDD
def decoupePacket(lPkt):
if type(lPkt)!=list:
print('pas liste')
return
if len(lPkt)==0:
print('liste vide')
return
if len(lPkt)==1:
return decoupePacket(lPkt[0])
if len(lPkt)==3 and type(lPkt[0])==str:
return [[lPkt[0],int(lPkt[1]),int(lPkt[2])]]
else:
l=[]
for i in lPkt:
l+=decoupePacket(i)
return l
def triPacket(lPkt,connec):
lNettoyee=decoupePacket(lPkt)
ecritureBDD(lNettoyee,connec)
Loading…
Cancel
Save