
Identifier les points d'entrée de l'application
Comment identifier les points d'entrée et d'injection possibles d'une application web en analysant les requêtes et réponses HTTP, y compris les paramètres, les en-têtes et les cookies.
| ID |
|---|
| WSTG-INFO-06 |
Résumé
L'énumération de l'application et de sa surface d'attaque est une étape primordiale avant que tout test approfondi puisse être entrepris, car elle permet au testeur d'identifier les zones probables de faiblesse. Cette section vise à aider à identifier et à cartographier les zones de l'application qui devraient être examinées une fois l'énumération et la cartographie terminées.
Objectifs du test
- Identifier les points d'entrée et d'injection possibles par l'analyse des requêtes et des réponses.
Comment tester
Avant que tout test ne commence, le testeur doit toujours avoir une bonne compréhension de l'application et de la façon dont l'utilisateur et le navigateur communiquent avec elle. Lorsque le testeur parcourt l'application, il doit faire attention à toutes les requêtes HTTP ainsi qu'à chaque paramètre et champ de formulaire qui est transmis à l'application. Il doit accorder une attention particulière au moment où les requêtes GET sont utilisées et au moment où les requêtes POST sont utilisées pour transmettre des paramètres à l'application. De plus, il doit également faire attention au moment où d'autres méthodes pour les services RESTful sont utilisées.
Notez que pour voir les paramètres envoyés dans le corps des requêtes telles qu'une requête POST, le testeur peut vouloir utiliser un outil tel qu'un proxy d'interception (voir outils). Dans la requête POST, le testeur doit également porter une attention particulière à tous les champs de formulaire cachés qui sont transmis à l'application, car ceux-ci contiennent généralement des informations sensibles telles que des informations d'état, la quantité d'articles, le prix des articles, etc., que le développeur n'a jamais voulu que quiconque voie ou modifie.
L'utilisation d'un proxy d'interception et d'une application de prise de notes (par exemple, un tableur) pour cette étape de test est populaire parmi les testeurs. Le proxy gardera une trace de chaque requête et réponse entre le testeur et l'application au fur et à mesure qu'il l'explore. De plus, à ce stade, les testeurs interceptent généralement chaque requête et réponse afin qu'ils puissent voir exactement chaque en-tête, paramètre, etc. qui est transmis à l'application et ce qui est renvoyé. Cela peut être assez fastidieux par moments, en particulier sur les grands sites interactifs (pensez à une application bancaire). Cependant, l'expérience montrera ce qu'il faut rechercher et cette phase peut être considérablement optimisée.
Au fur et à mesure que le testeur parcourt l'application, il doit prendre note de tous les paramètres intéressants dans l'URL, les en-têtes personnalisés ou le corps des requêtes/réponses, et les enregistrer dans un tableur. Le tableur doit inclure la page demandée (il peut être bon d'ajouter également le numéro de requête du proxy, pour référence future), les paramètres intéressants, le type de requête (GET, POST, etc.), si l'accès est authentifié/non authentifié, si TLS est utilisé, s'il fait partie d'un processus en plusieurs étapes, si WebSockets est utilisé et toute autre note pertinente. Une fois qu'il a cartographié chaque zone de l'application, il peut ensuite parcourir l'application et tester chacune des zones qu'il a identifiées et prendre des notes pour ce qui a fonctionné et ce qui n'a pas fonctionné. Le reste de ce guide identifiera comment tester chacun de ces domaines d'intérêt, mais cette section doit être entreprise avant que l'un des tests réels ne puisse commencer.
Voici quelques points d'intérêt pour toutes les requêtes et réponses. Dans la section des requêtes, concentrez-vous sur les méthodes GET et POST car celles-ci constituent la majorité des requêtes. Notez que d'autres méthodes, telles que PUT et DELETE, peuvent également être trouvées. Souvent, ces requêtes plus rares, si elles sont autorisées, peuvent exposer des vulnérabilités. Il existe une section spéciale dans ce guide dédiée au test de ces méthodes HTTP.
Requêtes
- Identifier où les GET sont utilisés et où les POST sont utilisés.
- Identifier tous les paramètres utilisés dans une requête POST (ceux-ci sont dans le corps de la requête).
- Dans la requête POST, portez une attention particulière à tous les paramètres cachés. Lorsqu'un POST est envoyé, tous les champs du formulaire (y compris les paramètres cachés) seront envoyés dans le corps du message HTTP à l'application. Ceux-ci ne sont généralement pas vus à moins qu'un proxy ne soit utilisé, ou que le code source HTML ne soit visualisé. La modification de ces paramètres cachés peut entraîner des modifications des pages suivantes qui se chargent, des données qu'elles contiennent et du degré d'accès accordé.
- Identifier tous les paramètres utilisés dans une requête GET (c'est-à-dire dans l'URL), en particulier la chaîne de requête (apparaissant généralement après un point d'interrogation ?).
- Identifier tous les paramètres de la chaîne de requête. Ceux-ci sont généralement au format de paire, tel que `foo=bar`. Notez également que de nombreux paramètres peuvent être dans une chaîne de requête séparés par un `&`, `~`, `:` ou tout autre caractère spécial ou encodage.
- Veuillez noter que lors de l'identification de plusieurs paramètres dans une chaîne ou dans une requête POST, certains ou tous les paramètres seront nécessaires pour exécuter les attaques. Le testeur doit identifier tous les paramètres (même s'ils sont encodés ou cryptés) et identifier ceux qui sont traités par l'application. Les sections suivantes du guide expliqueront comment tester ces paramètres. A ce stade, il est important de s'assurer que chacun d'entre eux est identifié.
- Faites également attention à tous les en-têtes supplémentaires ou de type personnalisé qui ne sont pas typiquement vus (tels que `debug : false`).
Réponses
- Identifier où de nouveaux cookies sont définis (en-tête `Set-Cookie`), modifiés ou ajoutés.
- Identifier toutes les redirections (code d'état HTTP 3xx), les codes d'état 400 (en particulier 403 Interdit) et les erreurs internes du serveur 500 lors des réponses normales (c'est-à-dire les requêtes non modifiées).
- Notez également où des en-têtes intéressants sont utilisés. Par exemple, `Server: BIG-IP` indique que le site est équilibré en charge. Ainsi, si un site est équilibré en charge et qu'un serveur est mal configuré, le testeur peut avoir à effectuer plusieurs requêtes pour accéder au serveur vulnérable, selon le type d'équilibrage de charge utilisé.
OWASP Attack Surface Detector
L'outil Attack Surface Detector (ASD) examine le code source et découvre les points de terminaison d'une application web, les paramètres que ces points de terminaison acceptent et le type de données de ces paramètres. Cela inclut les points de terminaison non liés qu'une araignée ne serait pas en mesure de trouver, ainsi que les paramètres facultatifs qui sont complètement inutilisés dans le code côté client. Il a également la capacité de calculer les changements de surface d'attaque entre deux versions d'une application.
L'Attack Surface Detector est disponible en tant que plugin pour ZAP et Burp Suite, et un outil de ligne de commande est également disponible. L'outil de ligne de commande exporte la surface d'attaque sous forme de sortie JSON, qui peut ensuite être utilisée par le plugin ZAP et Burp Suite. Ceci est utile pour les cas où le code source n'est pas fourni directement au testeur de pénétration. Par exemple, le testeur de pénétration peut obtenir le fichier de sortie json d'un client qui ne souhaite pas fournir le code source lui-même.
Comment utiliser
Le fichier jar CLI est disponible en téléchargement à partir de https://github.com/secdec/attack-surface-detector-cli/releases.
Vous pouvez exécuter la commande suivante pour qu'ASD identifie les points de terminaison à partir du code source de l'application web cible.
java -jar attack-surface-detector-cli-1.3.5.jar
Voici un exemple d'exécution de la commande contre OWASP RailsGoat.
$ java -jar attack-surface-detector-cli-1.3.5.jar railsgoat/
Beginning endpoint detection for '<...>/railsgoat' with 1 framework types
Using framework=RAILS
[0] GET: /login (0 variants): PARAMETERS={url=name=url, paramType=QUERY_STRING, dataType=STRING}; FILE=/app/controllers/sessions_controller.rb (lines '6'-'9')
[1] GET: /logout (0 variants): PARAMETERS={}; FILE=/app/controllers/sessions_controller.rb (lines '33'-'37')
[2] POST: /forgot_password (0 variants): PARAMETERS={email=name=email, paramType=QUERY_STRING, dataType=STRING}; FILE=/app/controllers/
password_resets_controller.rb (lines '29'-'38')
[3] GET: /password_resets (0 variants): PARAMETERS={token=name=token, paramType=QUERY_STRING, dataType=STRING}; FILE=/app/controllers/p
assword_resets_controller.rb (lines '19'-'27')
[4] POST: /password_resets (0 variants): PARAMETERS={password=name=password, paramType=QUERY_STRING, dataType=STRING, user=name=user, paramType=QUERY_STRING, dataType=STRING, confirm_password=name=confirm_password, paramType=QUERY_STRING, dataType=STRING}; FILE=/app/controllers/password_resets_controller.rb (lines '5'-'17')
[5] GET: /sessions/new (0 variants): PARAMETERS={url=name=url, paramType=QUERY_STRING, dataType=STRING}; FILE=/app/controllers/sessions_controller.rb (lines '6'-'9')
[6] POST: /sessions (0 variants): PARAMETERS={password=name=password, paramType=QUERY_STRING, dataType=STRING, user_id=name=user_id, paramType=SESSION, dataType=STRING, remember_me=name=remember_me, paramType=QUERY_STRING, dataType=STRING, url=name=url, paramType=QUERY_STRING, dataType=STRING, email=name=email, paramType=QUERY_STRING, dataType=STRING}; FILE=/app/controllers/sessions_controller.rb (lines '11'-'31')
[7] DELETE: /sessions/{id} (0 variants): PARAMETERS={}; FILE=/app/controllers/sessions_controller.rb (lines '33'-'37')
[8] GET: /users (0 variants): PARAMETERS={}; FILE=/app/controllers/api/v1/users_controller.rb (lines '9'-'11')
[9] GET: /users/{id} (0 variants): PARAMETERS={}; FILE=/app/controllers/api/v1/users_controller.rb (lines '13'-'15')
... coupé ...
[38] GET: /api/v1/mobile/{id} (0 variants): PARAMETERS={id=name=id, paramType=QUERY_STRING, dataType=STRING, class=name=class, paramType=QUERY_STRING, dataType=STRING}; FILE=/app/controllers/api/v1/mobile_controller.rb (lines '8'-'13')
[39] GET: / (0 variants): PARAMETERS={url=name=url, paramType=QUERY_STRING, dataType=STRING}; FILE=/app/controllers/sessions_controller.rb (lines '6'-'9')
Generated 40 distinct endpoints with 0 variants for a total of 40 endpoints
Successfully validated serialization for these endpoints
0 endpoints were missing code start line
0 endpoints were missing code end line
0 endpoints had the same code start and end line
Generated 36 distinct parameters
Generated 36 total parameters
- 36/36 have their data type
- 0/36 have a list of accepted values
- 36/36 have their parameter type
--- QUERY_STRING: 35
--- SESSION: 1
Finished endpoint detection for '<...>/railsgoat'
----------
-- DONE --
0 projects had duplicate endpoints
Generated 40 distinct endpoints
Generated 40 total endpoints
Generated 36 distinct parameters
Generated 36 total parameters
1/1 projects had endpoints generated
To enable logging include the -debug argumentVous pouvez également générer un fichier de sortie JSON à l'aide de l'indicateur `-json`, qui peut être utilisé par le plugin pour ZAP et Burp Suite. Voir les liens suivants pour plus de détails.
Tests des points d'entrée de l'application
Voici deux exemples de vérification des points d'entrée d'une application.
Exemple 1
Cet exemple montre une requête GET qui achèterait un article à partir d'une application d'achat en ligne.
GET /shoppingApp/buyme.asp?CUSTOMERID=100&ITEM=z101a&PRICE=62.50&IP=x.x.x.x HTTP/1.1
Host: x.x.x.x
Cookie: SESSIONID=Z29vZCBqb2IgcGFkYXdhIG15IHVzZXJuYW1lIGlzIGZvbyBhbmQgcGFzc3dvcmQgaXMgYmFyTous les paramètres de la requête tels que CUSTOMERID, ITEM, PRICE, IP, et le Cookie, qui pourraient simplement être des paramètres encodés ou des paramètres utilisés pour l'état de la session.
Exemple 2
Cet exemple montre une requête POST qui vous connecterait à une application.
POST /example/authenticate.asp?service=login HTTP/1.1
Host: x.x.x.x
Cookie: SESSIONID=dGhpcyBpcyBhIGJhZCBhcHAgdGhhdCBzZXRzIHByZWRpY3RhYmxlIGNvb2tpZXMgYW5kIG1pbmUgaXMgMTIzNA==;CustomCookie=00my00trusted00ip00is00x.x.x.x00
user=admin&pass=pass123&debug=true&fromtrustIP=trueOn peut noter que les paramètres sont envoyés à plusieurs endroits :
- Dans la chaîne de requête :
service - Dans l'en-tête Cookie :
SESSIONID,CustomCookie - Dans le corps de la requête :
user,pass,debug,fromtrustIP
Le fait d'avoir une variété d'emplacements d'injection offre à l'attaquant des possibilités de chaînage qui pourraient améliorer les chances de trouver un bogue dans le code de traitement.