Commit 5348b38b authored by Vincent Mazenod's avatar Vincent Mazenod
Browse files

enahnce courses

parent 0621f13a
<!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>authentification</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/authentication.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>heartbleed</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/heartbleed.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>
## authentification
"<i class="fa fa-wikipedia-w" aria-hidden="true"></i> processus permettant à un système de s'assurer de la légitimité de la demande d'accès faite par une entité (être humain ou un autre système...) afin d'autoriser l'accès de cette entité à des ressources du système (systèmes, réseaux, applications…) conformément au paramétrage du contrôle d'accès ."
* identification
* authentification
* ACL
## preuves
* ce que je sais
* mot de passe, numéro d'identification personnel
* ce que je possède
* carte d'identité, carte à puce, droit de propriété, certificat électronique, diplôme, passeport, Token, Token OTP, préiphérique
* ce que je suis
* photo, caractéristique physique, voire biométrie
* ce que je sais faire
* geste, signature
## sur le web
* authentification HTTP
* basic
* digest
* authentification par formulaire
* authentification déportée
* OAuth
* authentification d'API
## apache & .htaccess
* [EnablingUseOfApacheHtaccessFiles](https://help.ubuntu.com/community/EnablingUseOfApacheHtaccessFiles)
* surcharge du vhost courant (déconseillé)
```
$ sudo vi /etc/apache2/apache2.conf
<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All # None par défaut
Order allow,deny
allow from all
</Directory>
```
Note:
- potentiellement danegreux
- php.ini surchargeable aussi
- tems d'exec max
- taille de fichier max
- reporting d'erreur
- configurable en cas de virtual hosting
- à creuser
## auth basic .htaccess
```
$ vi /var/www/http-basic/.htaccess
AuthType Basic
AuthName "Big Basic Secret"
AuthUserFile /var/www/http-basic/.htpasswd
Require valid-user
```
[htpasswd](https://httpd.apache.org/docs/2.2/programs/htpasswd.html) outil de création des utilisateurs
```
$ htpasswd -c /var/www/http-basic/.htpasswd guest
$ htpasswd /var/www/http-basic/.htpasswd otheruser
```
## auth basic
le client demande un contenu (protégé)
```http
GET /http-basic/ HTTP/1.1
Host: go.od
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0 Iceweasel/31.8.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
```
## auth basic
le serveur répond que le contenu est protégé
```http
HTTP/1.1 401 Authorization Required
Date: Wed, 21 Oct 2015 13:26:29 GMT
Server: Apache/2.2.22 (Debian)
WWW-Authenticate: Basic realm="Big Basic Secret"
Content-Length: 472
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>401 Authorization Required</title>
</head><body>
<h1>Authorization Required</h1>
</body>
```
## auth basic
![HTTP basic auth](images/authentication/http-basic-auth.png "HTTP basic auth")
## auth basic
```http
GET /http-basic/ HTTP/1.1
Host: go.od
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0 Iceweasel/31.8.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Authorization: Basic b3dhc3A6cGFzc3dvcmQ=
```
[base64](https://fr.wikipedia.org/wiki/Base64)(username:password)
## auth digest
* Même schéma que la version Basic excepeté
* algorithme de hashage [MD5](https://fr.wikipedia.org/wiki/MD5) plutôt qu'un simple encodage [base64](https://fr.wikipedia.org/wiki/Base64)
* ajout d'un [nonce](http://fr.wikipedia.org/wiki/Nonce_cryptographique), rattacher à la session de communication, pour éviter les [attaques "par rejeu"](https://fr.wikipedia.org/wiki/Attaque_par_rejeu)
```
$ sudo a2enmod auth_digest
$ sudo service apache2 reload
```
## auth digest
!["Basic Digest Auth"](images/authentication/http-digest-auth.png "Basic Digest Auth")
## auth digest .htaccess
```
$ vi /var/www/http-digest/.htaccess
AuthType Digest
AuthName "authdigest"
AuthDigestDomain "/"
AuthDigestProvider file
AuthUserFile "/var/www/http-digest/.htdigest"
Require valid-user
```
[htdigest](https://httpd.apache.org/docs/2.2/fr/programs/htdigest.html) outil de création des utilisateurs
```
htdigest -c /var/www/http-basic/.htdigest "authdigest" guest
htdigest /var/www/http-basic/.htdigest "authdigest" otheruser
```
## auth digest
le client demande un contenu (protégé)
```http
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Digest realm="OwaspSample",
nonce="Ny8yLzIwMDIgMzoyNjoyNCBQTQ",
opaque="0000000000000000", \
stale=false,
algorithm=MD5,
qop="auth"
```
## auth digest
le serveur répond que le contenu est protégé
```http
GET /example/owasp/test.asmx HTTP/1.1
Accept: */*
Authorization: Digest username="owasp",
realm="OwaspSample",
qop="auth",
algorithm="MD5",
uri="/example/owasp/test.asmx",
nonce="Ny8yLzIwMDIgMzoyNjoyNCBQTQ",
nc=00000001,
cnonce="c51b5139556f939768f770dab8e5277a",
opaque="0000000000000000",
response="2275a9ca7b2dadf252afc79923cd3823"
```
Note:
- haché plus réversible même si MD5 ca craint un peu
- le nonce evite le rejeu
- le serveur connait les nonce qu'il a émis
- il sait qu'ils ne sont valables qu'une fois
- http://slideplayer.fr/slide/1622495/ -> slide 30
- le cnonce agit comme un salt
- évite le cassage du mot de passe par dictionnaire
- toujours pas de lockout
- attaque man in the middle
- demande de nonce au serveur et l'envoie au client et renvoie le resultat du cacul au serveur
- pas de blocage testable à l'infini
## authentification par formulaire
le plus courant
```
<form method="POST" action="login">
<input type="text" name="username">
<input type="password" name="password">
</form>
```
## authentification par formulaire
* le mot de passe est transmis en clair au serveur
* https :)
* stocker les mots de passe en clair sur le serveur est un mauvaise idée
* stocker les hashés est un bonne pratique
* [Rockyou.com en 2010](http://commedansdubeurre.ch/?story=162-piratage-de-32-millions-de-comptes-utilisateurs-chez-rockyou-recours-collectif-depose)
Note:
- peut être en GET
- plus facile pour le scripter en brute force
- et encore
- passe dans l'url?
- server-status intéressant
- http sniffbale https ok
- peut avoir du code coté client (calcul du md5 en js avant soumiision par exemple)
- 3 étapes
- formulaire
- traitement serveur
- la ressource (notamment accès direct) ou information 403 avec la suite
- dépend beaucoup des développeurs
- best practice
- esapi OWASP
- récupération du token de session suffit souvent (passé par GET par exemple SID ou par cookie)
- potentiellement
- lock out sur brute force
- paramètre assitionel - timestamp
- XSS redirect user vers une page d'auth fake
- SQL injection
- marche aussi avec un interpréteur de commande LDAP
- pour l'attaque des fois ca répond 200 alors que c'est non (ca devrait être 403)
- méfiance
## oAuth
* tri-partie
<div style="text-align: center">
![oAuth](images/oAuth.png "oAuth")<!-- .element style="width: 50%" -->
</div>
| Version | SSL | Token | Technique |
| --------- | ----------- | --------------- | ------------------------ |
| oAuth 1.0 | optionel | sans expiration | mise en place compliquée |
| oAuth 2.0 | obligatoire | révocable | simple et plus léger |
* 1.0 incompatible avec 2.0
* <i class="fa fa-newspaper-o"></i> [How to Secure Your REST API using Proven Best Practices](https://stormpath.com/blog/secure-your-rest-api-right-way)
Note:
- authentification simple (instagram)
- souvent autorisations partielles attribuées à l'app
- le token évite de rejouer l'auth
- oAuth 1.0 en clair lire le token
- pas de consensus sur la version 1 ou 2 sur Internet
- confiance dans consumer (l'app qui demande l'autorisation)
## Les attaques brute force
* Différents types
* Attaque par dictionnaires
* devine automatiquement les paramètres d'authentification à partir d'une liste d'utilisateur / mot de passe
* optimisable avec de la probabilité, [des dictionnaires au hasard](https://dazzlepod.com/site_media/txt/passwords.txt), de l'ingénieurie sociale, du flaire etc ...
* Attaque par recherche
* essayer toutes les combinisaons de caractères
* trouver un mot de passe de 8 caractères composé exclusivement de caractères alphabétiques: 26<sup>8</sup> possibilités
* Attaque par recherche basée sur des règles
* décliner via des règles les propositions d'un dictionnaire
* leetspeakation automatique
* [John the Ripper](http://www.openwall.com/john/) permet de générer des mots de passes dérivant de parties du username
## [THC Hydra](http://www.thc.org/thc-hydra/)
* multi-protocole: IMAP, SMB, HTTP, VNC, MS-SQL MySQL, SMTP, SSH, VNC, Asterisk, ...
* [RTFM](https://github.com/vanhauser-thc/thc-hydra)
* [liste de usernames](https://raw.githubusercontent.com/maryrosecook/commonusernames/master/usernames.txt)
* [liste de mots de passe](https://wiki.skullsecurity.org/index.php?title=Passwords)
<pre>
<code data-trim class="hljs bash" style="font-size: 22px">
hydra 192.168.1.26 ssh2 -s 22 -P pass.txt -L users.txt -e nrs -t 10
</code>
</pre>
* attaque du protocole ssh sur le port 22
* 10 threads à la fois
* essaie toutes les combinaisons possibles entre les username de users.txt et les mots de passe de pass.txt
* + mot de passe vide
* + mot de passe = username
* + mot de passe = username à l'envers
* [OWASP - Testing for Brute Force](https://www.owasp.org/index.php/Testing_for_Brute_Force_%28OWASP-AT-004%29)
* [Using Hydra to dictionary-attack web-based login forms](http://insidetrust.blogspot.fr/2011/08/using-hydra-to-dictionary-attack-web.html)
* voir aussi [medusa](http://foofus.net/goons/jmk/medusa/medusa.html)
Note:
- Burp Suite
- Patator
## attaques offline
* Dépend de la puissance de calcul
* Non furtive
* Reproductible
* [OPHCRACK (the time-memory-trade-off-cracker)](http://lasecwww.epfl.ch/~oechslin/projects/ophcrack/)
* monde windows
* fichiers SAM
* fonctionne avec des [dictionnaires](http://ophcrack.sourceforge.net/tables.php)
* <i class="fa fa-gift"></i> <a href="http://www.newbiecontest.org/index.php?page=epreuve&no=224">obtenir le pass d'un compte windows en moins de 10 minutes</a><!-- tips: le xp free suffit -->
* [Password Cracking: Lesson 2](http://www.computersecuritystudent.com/SECURITY_TOOLS/PASSWORD_CRACKING/lesson2/)
* [John the Ripper](http://www.openwall.com/john/)
* monde UNIX/BSD
* fichier /etc/passwd + /etc/shadow
* mangling rules: leet speak, custom ...
<pre>
<code data-trim>
unshadow /etc/passwd /etc/shadow > mypasswd
</code>
</pre>
* [Checking Password Complexity with John the Ripper](http://www.admin-magazine.com/Articles/John-the-Ripper)
## attaques par tables arc-en-ciel
* [Project RainbowCrack](http://www.antsight.com/zsl/rainbowcrack/)
* [CrackStation](https://crackstation.net/)
* avec la signature de smithy dans la table user
<pre>
<code data-trim>
5f4dcc3b5aa765d61d8327deb882cf99
</code>
</pre>
## <i class="fa fa-medkit"></i> Se protéger
* bien choisir son système d'authentification
* bien implémenter son système d'authentification
* [ESAPI (The OWASP Enterprise Security API)](https://www.owasp.org/index.php/Category:OWASP_Enterprise_Security_API)
* libs & bundles éprouvés
* mettre un nombre d'essais maximum consécutifs
* plugin anti brute force
* wordpress
* drupal
* compléter par des restrictions par IP, voir par blocs d'IPs
* instaurer des règles de durcissement au moment du choix du mot de passe
* pas contournable côté client ;)
* sensibilisez vos utilisateurs
* [<i class="fa fa-desktop"></i> Se protéger avec de bons mots de passe](http://doc.m4z3.me/_/bpu/se_proteger_avec_de_bons_mots_de_passe.htm#/cover)
* [<i class="fa fa-video-camera"></i> Se protéger avec de bons mots de passe](http://webtv.u-clermont1.fr/media-MEDIA150410174414391)
## heartbleed
![heartbleed](images/heartbleed/heartbleed.png "heartbleed")
## un système vulnérable ...
[Ubuntu server 12.04.4](http://ubuntu-release.locaweb.com.br/12.04/)
```bash
sudo apt-get install nginx
```
### surtout pas d'upgrade pour garder des services vulnérables ;)
[paramétrage réseau](/zz2-f5-securite-logicielle-22-securite-des-applications-web.html#recreer-lenvironnement-de-cours-dans-virtualbox)
## architecture typique
* nginx route le traffic http (80/443)
* vers d'autres serveurs web
* dans notre cas une debian
* avec apache
Note:
- appli node sur port exotique
- possibilité de filtrage de requête
- [load balancing](http://nginx.org/en/docs/http/load_balancing.html) pour pas cher
- accessoirement nickel pour les migrations
## nginx
<pre>
<code data-trim class="hljs bash" style="font-size: 23px; min-height: 560px">
upstream debian80 {
server 172.16.76.144:80;
}
server {
listen 80;
server_name heart.bleed;
# don't mess with security :p
rewrite ^ https://heart.bleed$request_uri? permanent;
}
server {
listen 443;
server_name heart.bleed;
ssl on;
ssl_certificate /etc/nginx/ssl/keys/heartbleed.crt;
ssl_certificate_key /etc/nginx/ssl/keys/heartbleed.key;
location / {
proxy_pass http://debian80/;
proxy_set_header Host $http_host;
}
}
</code>
</pre>
## heartbleed
* découverte en mars 2014
* par Google & Codenomicon
* présente depuis mars 2012
* introduite à la suite d'un "bug fix" par un contributeur bénévole
* validée le 31 décembre 2011
* faille d'implémentation dans openssl
<div style="text-align: center">
<img src="images/heartbleed/heartbleed_explanation_1.png"/>
</div>
<div style="text-align: center">