CVP : Content Vectoring Protocol

Introduction

Présentation

Le protocole CVP a été inventé par CheckPoint pour autoriser des outils informatiques tierces à interagir avec leurs solutions logicielles, et notamment leurs solutions de FireWall. Ceci permet d’apporter la connaissance « applicative » d’outils tiers à leur Firewall et de leur permettre ainsi d’interagir directement dans des règles de sécurité en temps réél d’un Firewall.

Vous avez avez bien compris : CVP va en fait vous permette d’apporter vos algorithmes et de modifier le comportement logiciel des Firewall CheckPoint lots de l’application de leurs règles de sécurité !

Encore plus fort, les serveurs CVP auront le droit de modifier les flux TCP/IP s’ils estiment qu’ils doivent le faire avant que le Firewall renvoie finalement ce flux modifié par vos algorithmes aux clients finaux définies dans les règles de sécurité.

Test CVP : Définition du périmètre

Pour bien comprendre le principe et la mise en place, nous allons établir un test minimaliste de bout en bout : Celui-ci va se limiter à l’inspection d’une requête HTTP vers un serveur web.

En effet, nous allons mettre à disposition de notre Firewall un serveur web de type Apache et établir la règle de sécurité habituelle pour autoriser un flux TCP/IP sur le port 80 à parvenir jusqu’à lui. Mais, nous allons également partir du principe que, notre Internaute aura au préalablement été enregistré dans un outil de sécurité « maison » dans lequel il se sera signé er aura hérité d’un cookie de sécurité. Notre serveur CVP va alors conditionner l’acceptation de la règle de sécurité à la présence dans une base de données applicative locale de ce cookie avant de l’autoriser à accéder au serveur HTTP via la règle de sécurité.

Nous avons ajouté un conditionnement applicatif à l’acceptation d’une règle de Firewalling : Un comportement sommes toute proche d’une sorte de SSO simplifié dans cet exemple.

NB) Evidement nous n’allons pas ici décrire l’outil « de sécurité » sur lequel s’est au préalablement signé l’internaute, ce n’est pas le but de ce post.

Nomenclature Checkpoint Firewall

Définition des objets

Serveurs tierces

Le serveur CVP sera hébergé par l’objet FW_SRV_CVP01 tandis que le serveur web accédé par les internautes sera représenté par FW_SRV_HTTPD tel que:

Type objetNom objetIP addr.NATFonction
HOSTFW_SRV_CVP01192.168.10.123Hide FW GatewayCVP INTENAL SERVER
HOSTFW_SRV_HTTPD192.168.10.122Static 80.133.1.2HTTPD PUBLIC SERVER

Note) Dans notre exemple, le serveur CVP sera représenté par un socket serveur élémentaire écrit en PHP, le serveur web cible sera quant-à lui un simple serveur Apache.

Application OPSEC CVP

Pour indiquer à un Firewall Checkpoint qu’un objet est susceptible de dialoguer en CVP avec les équipements de sécurité, nous allons créer un objet de type « APPLICATION OPSEC » auquel nous allons associer la capacité de gérer le protocole « CVP » tel que :

  • Name: FW_OPSEC_CVPSRV_01
  • Host: FW_SRV_CVP01
  • Server Entities : CVP

Ressource de type CVP

Une ressource est un objet Checkpoint Firewall qui permet de donner des indications sur les propriétés liées à un protocole, par exemple, dans notre cas, nous allons creér une ressource de type « URI » (Uniform Ressource Identifier) qui va nous permettre non seulement de catégoriser ses propriétés (ce que contient l’URL, méthode HTTP utilisé (GET, POST, etc), etc, mais aussi, de la lier (ou non) à une ressource OPSEC de type CVP, l’objet « FW_OPSEC_CVPSRV_01 » que nous avons créé juste avant :

  • Name: FW_RSRC_TEST_PROTECTED_CVP
  • Match:
    • Schemes HTTP
    • Methodes GET, POST, HEAD, PUTFW_SRV_CVP01
  • CVP :
    • Use CVP
    • CVP Server « FW_OPSEC_CVPSRV_01 »
    • CVP Server is allowed to modify content

Note) Nous avons opté pour une ressource de type « URI » car ses propriétés prédéfinies sont proches de HTTP, un protocole sur lequel notre serveur CVP va-t-être questionné via une règle de sécurité, mais nous aurions pu opter pour une autre ressource, plus largement, une ressource de type « TCP ».

Note) Nous avons ajouté l’option « CVP Server is allowed to modify content« , ce qui signifie que si le contenu ne match pas avec la politique du serveur CVP, celui-ci aura le droit de modifier le contenu du flux qui sera renvoyé par le Firewall au client plustôt que de le refuser catégoriquement. Même si cela n’a pas de sens dans le périmètre de notre exemple, nous avons simplement choisi cette option pour vous rapeller que cette possibilité vous est également offerte.

Service

Le service dans un Firewall Checkpoint, est un protocole avec (ou sans) condition, condition symbolisée par l’association à une « ressource ». C’est ce que au final nous autorisons, ou que nous refusons, au sein d’une règle de sécurité.

Nous allons donc créer un « service » mettant en liaison le protocole « HTTP » et la ressource « FW_RSRC_TEST_PROTECTED_CVP » tel que :

  • Service : http
  • Ressource : FW_RSRC_TEST_PROTECTED_CVP

Règle de sécurité

Voilà, tous nos objets sont configurés, il ne nous reste plus qu’à mettre en service une règle de sécurité les prenant en compte tel que:

  • Source: Any
  • Destination:  » « 
  • Services & Applications: « http -> FW_RSRC_TEST_PROTECTED_CVP » (utiliser en cliquant avec le bouton droit dans la celulle de la colponne « Services & Applications » le menu pop-up « Add service plus ressource« ).

Et voilà, il ne reste plus qu’à compiler ces nouveaux objets et cette nouvelle règle de sécurité avant de passer aux réglages du serveur CVP !

Protocole CVP

Introduction

Une question au sens CVP indique généralement un flux et un type d’analyse ( { CODE CVP} ) demandé, par exemple:

  • CHECKFILE – Analyse d’un fichier ou flux de données.
  • CHECKURL – Vérification d’une URL.
  • CHECKSTREAM – Analyse d’un flux en temps réel.
  • CHECKUPLOAD – Analyse des fichiers en téléchargement.
  • CHECKEMAIL – Analyse d’un e-mail.

La syntaxe est la suivante:

CVP/1.0 {CODE CVP} /test.txt HTTP/1.1
Content-Length: x

Le protocole CVP donne une réponse qui contient des headers indiquant sur le type de réponse et un contenu qui peut être le flux non modifié, le flux modifié, ou tout autre phrase selon le type de réponse.

Réponse type:

CVP/1.0 200 OK

Les codes erreurs les plus généraux sont:

  • 200 : OK
  • 400 : Bad request
  • 403 : Interdit
  • 500 : Internal Error

Le principe est donc d’écrire un socket client qui, en fonction de critères métiers qui vous incombent, juge sur son contenu et informe le FireWall du comportement à tenir vis à vis d’un flux.

L’indicateur se fait dans les headers de la réponse avec le champ « X-CVP-Result » qui peut prendre la plupart du temps une valeur parmi celles-ci:

  • PASSED : Le contenu a été accepté
  • MODIFIED : Equivalent de PASSED, mais le contenu a été modifié
  • BLOCKED : Le contenu a été considéré comme à bloquer
  • FAILED : Erreur interne du serveur CVP

D’autres valeurs sont possibles mais plus rarement utilisées telles que:

  • INFECTED : Le flux est infecté par un virus ou un malware
  • CLEANED : Le flux est infecté par un virus ou un malware et a été néttoyé
  • UNSUPPORTED : Contenu non analysable ou requête incompréhensible
  • TIMEOUT : Délai de traitement expiré
  • EXCEEDED : Taille de flux trop large
  • DELAYEED : La réponse sera envoyée de façon asynchrone
  • DISCARDED : Flux rejeté sans prévenir le client

Exemple de serveur CVP en PHP

Le port d’écoute TCP/IP par défaut d’un serveur CVP est le 9000, voici à quoi devrait ressembler notre socket serveur :

socketServeurCVP.php :

#!/bin/php
<?php

$timeToSleep=1;
$crlf="\r\n";

include "analyseCVPcontent.php";

$hostName=gethostname();
$IP=gethostbyname($hostName);
$PORT=9000;

set_time_limit(0);

$socketServeur = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (!$socket) { die("Erreur de création de socket : " . socket_strerror(socket_last_error()) . "\n"); }
if (!socket_bind($socket, $host, $port)) { die("Erreur lors de la liaison du socket : " . socket_strerror(socket_last_error($socket)) . "\n"); }
if (!socket_listen($socket)) { die("Erreur lors de la mise en écoute du socket : " . socket_strerror(socket_last_error($socket)) . "\n"); }

$killProcess=false;

do {
     
     sleep($timeToSleep);

     $client = socket_accept($socket);
     if ($client === false) { 
         echo "Erreur lors de l'acceptation de la connexion : " . socket_strerror(socket_last_error($socket)) . "\n"; 
     } else {
          
          $request = socket_read($client, 2048);         
          preg_match('/Content-Length: (\d+)/i', $request, $matches);
          $contentLength = $matches[1] ?? 0;
          
          $content = "";
          
          if ($contentLength > 0) {
               $content = socket_read($client, $contentLength);
               $modifiedContent=""
               $res = analyseContenuCVP($content, $modifiedContent);
          }
          
          $responseHeader = "CVP/1.0 200 OK".$crlf;
          $response="";
          $resContent="";
          $resCode="";
          
          if ($res) {
               if ($modifiedContent=="") {
                    $resCode="ACCEPT";
                    $resContent=$content;       
               } else {
                    $resCode="MODIFIED";
                    $resContent=$modifiedContent;
               }
          } else {
               $resCode="REJECT";
          }
          
          if ($resContent!=""){ $responseHeader .= "Content-Length: ".strlen($resContent).$crlf; }
          $responseHeader .= "X-CVP-Result: ".$resCode.$crlf;
          $responseHeader .= $crlf;
          $response = $responseHeader;
          if ($resContent!=""){ $response .= $resContent; }
          
          socket_write($client, $response, strlen($response));
          socket_close($client);

     }

     $killProcess=(strtolower(@getenv("killCVPSockServer"))=="true");

} while (!$killProcess);
     

Le script « analyseCVPcontent.php » étant un script dédié à la function « analyseContenuCVP() » du script principal et dédiée à l’analyse du contenu reçu la le socket du serveur CVP et soumis à analyse et éventuellement à modification, il se limite à:

analyseCVPcontent.php :

<?php

function  analyseContenuCVP($initialContent, &$optionalModifiedContent=""){
   $res=false;

    ...
    ...
    // ici figure le code de votre analyse de contenu
    // celui-ci doit positionner $res=true en cas d'acceptation du contenu
    // et inscrire optionnellement dans $optionalModifiedContent le contenu modifié par
    // vos soins si besoin est.
    ...
    ...

   return ($res);
}

Exemples de questions / réponses CVP

Exemple 1

Un process contrôle par CVP qui modifie le contenu d’un fichier pour le mettre en majuscules

Question:

CVP/1.0 CHECKFILE /test.txt HTTP/1.1
Content-Length: 11

hello world

Réponse:

CVP/1.0 200 OK
Content-Length: 11
X-CVP-Result: MODIFIED

HELLO WORLD

Exemple 2

Question:

CVP/1.0 CHECKFILE /corrupted_file.txt HTTP/1.1
Content-Length: 50

Corrupted data that cannot be processed.

Réponse:

CVP/1.0 500 Internal Server Error
X-CVP-Result: FAILED

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *