Esempio n. 1
0
def ExecuteADB(request):
    print "\n[INFO] Executing ADB Commands"
    try:
        if request.method == 'POST':
            data = {}
            CMD=request.POST['cmd']
            '''
            #Allow it Since it's functional
            if re.findall(";|\$\(|\|\||&&",CMD):
                print "[ATTACK] Possible RCE"
                return HttpResponseRedirect('/error/')
            '''
            TOOLSDIR=os.path.join(settings.BASE_DIR, 'DynamicAnalyzer/tools/')  #TOOLS DIR
            adb=getADB(TOOLSDIR)
            args=[adb, "-s", getIdentifier()] +  CMD.split(' ')
            resp="error"
            try:
                resp=subprocess.check_output(args)
            except:
                PrintException("[ERROR] Executing ADB Commands")
            data = {'cmd': 'yes','resp': resp}
            return HttpResponse(json.dumps(data), content_type='application/json')
        else:
            return HttpResponseRedirect('/error/')
    except:
        PrintException("[ERROR] Executing ADB Commands")
        return HttpResponseRedirect('/error/')
Esempio n. 2
0
def Touch(request):
    print "\n[INFO] Sending Touch Events"
    try:
        data = {}
        if (request.method == 'POST') and (is_number(
                request.POST['x'])) and (is_number(request.POST['y'])):
            x_axis = request.POST['x']
            y_axis = request.POST['y']
            TOOLSDIR = os.path.join(settings.BASE_DIR,
                                    'DynamicAnalyzer/tools/')  #TOOLS DIR
            adb = getADB(TOOLSDIR)
            args = [
                adb, "-s",
                getIdentifier(), "shell", "input", "tap", x_axis, y_axis
            ]
            data = {'status': 'success'}
            try:
                subprocess.call(args)
            except:
                data = {'status': 'error'}
                PrintException("[ERROR] Performing Touch Action")
        else:
            data = {'status': 'failed'}
        return HttpResponse(json.dumps(data), content_type='application/json')
    except:
        PrintException("[ERROR] Sending Touch Events")
        return HttpResponseRedirect('/error/')
Esempio n. 3
0
def ExportedActivityTester(request):
    print "\n[INFO] Exported Activity Tester"
    try:
        MD5=request.POST['md5']
        PKG=request.POST['pkg']
        m=re.match('[0-9a-f]{32}',MD5)
        if m:
            if re.findall(";|\$\(|\|\||&&",PKG):
                print "[ATTACK] Possible RCE"
                return HttpResponseRedirect('/error/')
            if request.method == 'POST':
                DIR=settings.BASE_DIR
                APP_DIR=os.path.join(settings.UPLD_DIR, MD5+'/')
                TOOLS_DIR=os.path.join(DIR, 'DynamicAnalyzer/tools/')  #TOOLS DIR
                SCRDIR=os.path.join(APP_DIR,'screenshots-apk/')
                data = {}
                adb=getADB(TOOLS_DIR)

                DB=StaticAnalyzerAndroid.objects.filter(MD5=MD5)
                if DB.exists():
                    print "\n[INFO] Fetching Exported Activity List from DB"
                    EXPORTED_ACT=python_list(DB[0].EXPORTED_ACT)
                    if len(EXPORTED_ACT)>0:
                        n=0
                        print "\n[INFO] Starting Exported Activity Tester..."
                        print "\n[INFO] "+str(len(EXPORTED_ACT))+" Exported Activities Identified"
                        for line in EXPORTED_ACT:
                            try:
                                n+=1
                                print "\n[INFO] Launching Exported Activity - "+ str(n)+ ". "+line
                                subprocess.call([adb, "-s", getIdentifier(), "shell", "am","start", "-n", PKG+"/"+line])
                                Wait(4)
                                subprocess.call([adb, "-s", getIdentifier(), "shell", "screencap", "-p", "/data/local/screen.png"])
                                #? get appended from Air :-() if activity names are used
                                subprocess.call([adb, "-s", getIdentifier(), "pull", "/data/local/screen.png", SCRDIR + "expact-"+str(n)+".png"])
                                print "\n[INFO] Activity Screenshot Taken"
                                subprocess.call([adb, "-s", getIdentifier(), "shell", "am", "force-stop", PKG])
                                print "\n[INFO] Stopping App"
                            except:
                                PrintException("[ERROR] Exported Activity Tester")
                        data = {'expacttest': 'done'}
                    else:
                        print "\n[INFO] Exported Activity Tester - No Activity Found!"
                        data = {'expacttest': 'noact'}
                    return HttpResponse(json.dumps(data), content_type='application/json')
                else:
                    print "\n[ERROR] Entry does not exist in DB."
                    return HttpResponseRedirect('/error/')
            else:
                return HttpResponseRedirect('/error/')
        else:
            return HttpResponseRedirect('/error/')
    except:
        PrintException("ERROR] Exported Activity Tester")
        return HttpResponseRedirect('/error/')
Esempio n. 4
0
def GetRes():
    print "\n[INFO] Getting Screen Resolution"
    try:
        TOOLSDIR = os.path.join(settings.BASE_DIR,
                                'DynamicAnalyzer/tools/')  #TOOLS DIR
        adb = getADB(TOOLSDIR)
        resp = subprocess.check_output(
            [adb, "-s",
             getIdentifier(), "shell", "dumpsys", "window"])
        resp = resp.split("\n")
        res = ""
        for line in resp:
            if "mUnrestrictedScreen" in line:
                res = line
                break
        res = res.split("(0,0)")[1]
        res = res.strip()
        res = res.split("x")
        if len(res) == 2:
            return res[0], res[1]
            #width, height
        return "", ""
    except:
        PrintException("[ERROR] Getting Screen Resolution")
        return "", ""
def UpdateDB():
    try:
        url = "https://www.malwaredomainlist.com/mdlcsv.php"
        response = urllib2.urlopen(url)
        data = response.read()
        TMP_DIR = os.path.join(MALWARE_DB_DIR,'tmp/')
        TMP_DWD = os.path.join(TMP_DIR,'malwaredomainlist')
        DB = os.path.join(MALWARE_DB_DIR,'malwaredomainlist')
        if not os.path.exists(TMP_DIR):
            os.makedirs(TMP_DIR)
        with open(TMP_DWD,'wb') as f:
            f.write(data)
        #Check1: SHA256 Change
        if sha256(TMP_DWD) != sha256(DB):
            #DB needs update
            #Check2: DB Syntax Changed
            rd = io.open(TMP_DWD,mode='r',encoding="utf8",errors="ignore")
            line = rd.readline()
            rd.close()
            lst = line.split('",')
            if len(lst) == 10:
                #DB Format is not changed. Let's update DB
                print "\n[INFO] Updating Malware Database...."
                shutil.copyfile(TMP_DWD,DB)
            else:
                print "\n[WARNING] Malware Database format from malwaredomainlist.com changed. Database is not updated. Please report to: https://github.com/ajinabraham/Mobile-Security-Framework-MobSF/issues"
        else:
            print "\n[INFO] Malware Database is up-to-date."
        if os.path.isfile(TMP_DWD):
            os.remove(TMP_DWD)
    except:
        PrintException("[ERROR] Malware DB Update")
Esempio n. 6
0
def TakeScreenShot(request):
    print "\n[INFO] Taking Screenshot"
    try:
        if request.method == 'POST':
            MD5=request.POST['md5']
            m=re.match('[0-9a-f]{32}',MD5)
            if m:
                data = {}
                r=random.randint(1, 1000000)
                DIR=settings.BASE_DIR
                SCRDIR=os.path.join(settings.UPLD_DIR, MD5+'/screenshots-apk/')#make sure that list only png from this directory
                TOOLSDIR=os.path.join(DIR, 'DynamicAnalyzer/tools/')  #TOOLS DIR
                adb=getADB(TOOLSDIR)
                subprocess.call([adb, "-s", getIdentifier() ,"shell", "screencap", "-p", "/data/local/screen.png"])
                subprocess.call([adb, "-s", getIdentifier() ,"pull", "/data/local/screen.png", SCRDIR + "screenshot-"+str(r)+".png"])
                print "\n[INFO] Screenshot Taken"
                data = {'screenshot': 'yes'}
                return HttpResponse(json.dumps(data), content_type='application/json') 
            else:
                return HttpResponseRedirect('/error/')
        else:
            return HttpResponseRedirect('/error/')
    except:
        PrintException("[ERROR] Taking Screenshot")
        return HttpResponseRedirect('/error/')
Esempio n. 7
0
def ConnectInstallRun(TOOLSDIR,ADB_CON_ID,APKPATH,PACKAGE,LAUNCH,isACT):
    print "\n[INFO] Starting App for Dynamic Analysis"
    try:
        adb=getADB(TOOLSDIR)
        subprocess.call([adb, "kill-server"])
        subprocess.call([adb, "start-server"])
        print "\n[INFO] ADB Started"
        Wait(5) 
        print "\n[INFO] Connecting to VM/Device"
        subprocess.call([adb, "connect", ADB_CON_ID])
        subprocess.call([adb, "wait-for-device"])
        print "\n[INFO] Mounting"
        if settings.REAL_DEVICE:
            subprocess.call([adb, "-s", getIdentifier(), "shell", "su", "-c", "mount", "-o", "rw,remount,rw", "/system"])
        else:
            subprocess.call([adb, "-s", getIdentifier(), "shell", "su", "-c", "mount", "-o", "rw,remount,rw", "/system"])
            #This may not work for VMs other than the default MobSF VM
            subprocess.call([adb, "-s", getIdentifier(), "shell", "mount", "-o", "rw,remount", "-t", "rfs", "/dev/block/sda6", "/system"])
        print "\n[INFO] Installing APK"
        subprocess.call([adb, "-s", getIdentifier(), "install", "-r", APKPATH])
        if isACT:
            runApp = PACKAGE + "/" + LAUNCH
            print "\n[INFO] Launching APK Main Activity"
            subprocess.call([adb, "-s", getIdentifier(), "shell", "am", "start", "-n", runApp])
        else:
            print "\n[INFO] App Doesn't have a Main Activity"
            #Handle Service or Give Choice to Select in Future.
            pass
        print "[INFO] Testing Environment is Ready!"
    except:
        PrintException("[ERROR]  Starting App for Dynamic Analysis")
def MalwareCheck(urllist):
    RESULT = {}
    domainlist = list()
    try:
        domainlist = getDomains(urllist)
        if len(domainlist) > 0:
            if isInternetAvailable():
                UpdateDB();
            else:
                print "\n[WARNING] No Internet Connection. Skipping Malware Database Update."
            DB = os.path.join(MALWARE_DB_DIR,'malwaredomainlist')
            with io.open(DB,mode='r',encoding="utf8",errors="ignore") as f:
                entry_list = f.readlines()
            for entry in entry_list:
                enlist = entry.split('","')
                if len(enlist) > 5:
                    details_dict = dict()
                    details_dict["domain_or_url"] = enlist[1]
                    details_dict["ip"] = enlist[2]
                    details_dict["desc"] = enlist[4]
                    details_dict["bad"] = "yes"
                    for domain in domainlist:
                        if (domain in details_dict["domain_or_url"]) or (domain in details_dict["ip"]):
                            RESULT[domain] = details_dict
            for domain in domainlist:
                if domain not in RESULT:
                    x = dict()
                    x["bad"] = "no"
                    RESULT[domain] = x
    except:
        PrintException("[ERROR] Performing Malware Check")
    return RESULT
Esempio n. 9
0
def HandleSqlite(SFile):
    print "\n[INFO] SQLite DB Extraction"
    try:
        data=''
        con = sq.connect(SFile)
        cur = con.cursor()
        cur.execute("SELECT name FROM sqlite_master WHERE type='table';")
        tables=cur.fetchall()
        for table in tables:
            data+= "\nTABLE: "+str(table[0]).decode('utf8', 'ignore')+" \n=====================================================\n"
            cur.execute("PRAGMA table_info('%s')" % table)
            rows=cur.fetchall()
            head=''
            for r in rows:
                head+=str(r[1]).decode('utf8', 'ignore') + " | "
            data+=head + " \n=====================================================================\n"
            cur.execute("SELECT * FROM '%s'" % table)
            rows=cur.fetchall()
            for r in rows:
                dat=''
                for x in r:
                    dat+=str(x).decode('utf8', 'ignore') + " | "
                data+=dat+"\n"
        return data
    except:
        PrintException("[ERROR] SQLite DB Extraction")
        pass
Esempio n. 10
0
def ScreenCast(request):
    print "\n[INFO] Invoking ScreenCast Service in VM/Device"
    try:
        global tcp_server_mode
        data = {}
        if (request.method == 'POST'):
            mode = request.POST['mode']
            TOOLSDIR = os.path.join(settings.BASE_DIR,
                                    'DynamicAnalyzer/tools/')  #TOOLS DIR
            adb = getADB(TOOLSDIR)
            IP = settings.SCREEN_IP
            PORT = str(settings.SCREEN_PORT)
            if mode == "on":
                args = [
                    adb, "-s",
                    getIdentifier(), "shell", "am", "startservice", "-a",
                    IP + ":" + PORT, "opensecurity.screencast/.StartScreenCast"
                ]
                data = {'status': 'on'}
                tcp_server_mode = "on"
            elif mode == "off":
                args = [
                    adb, "-s",
                    getIdentifier(), "shell", "am", "force-stop",
                    "opensecurity.screencast"
                ]
                data = {'status': 'off'}
                tcp_server_mode = "off"
            if (mode == "on") or (mode == "off"):
                try:
                    subprocess.call(args)
                    t = threading.Thread(target=ScreenCastService)
                    t.setDaemon(True)
                    t.start()
                except:
                    PrintException("[ERROR] Casting Screen")
                    data = {'status': 'error'}
                    return HttpResponse(json.dumps(data),
                                        content_type='application/json')
            else:
                data = {'status': 'failed'}
        else:
            data = {'status': 'failed'}
        return HttpResponse(json.dumps(data), content_type='application/json')
    except:
        PrintException("[ERROR] Casting Screen")
        return HttpResponseRedirect('/error/')
Esempio n. 11
0
def getIdentifier():
    try:
        if settings.REAL_DEVICE:
            return settings.DEVICE_IP + ":" + str(settings.DEVICE_ADB_PORT)
        else:
            return settings.VM_IP + ":" + str(settings.VM_ADB_PORT)
    except:
        PrintException("[ERROR] Getting ADB Connection Identifier for Device/VM")
def PushtoRecent(NAME, MD5, URL):
    try:
        DB = RecentScansDB.objects.filter(MD5=MD5)
        if not DB.exists():
            NDB = RecentScansDB(NAME=NAME, MD5=MD5, URL=URL, TS=timezone.now())
            NDB.save()
    except:
        PrintException("[ERROR] Adding Scan URL to Database")
Esempio n. 13
0
def DumpData(request):
    #Closing External Services and Dumping data
    print "\n[INFO] Device Data Dump"
    try:
        if request.method == 'POST':
            data = {}
            PACKAGE=request.POST['pkg']
            MD5=request.POST['md5']
            m=re.match('[0-9a-f]{32}',MD5)
            if m:
                if re.findall(";|\$\(|\|\||&&",PACKAGE):
                    print "[ATTACK] Possible RCE"
                    return HttpResponseRedirect('/error/')
                DIR=settings.BASE_DIR
                APKDIR=os.path.join(settings.UPLD_DIR, MD5+'/')
                TOOLSDIR=os.path.join(DIR, 'DynamicAnalyzer/tools/')  #TOOLS DIR
                adb=getADB(TOOLSDIR)
                Proxy("","","","") #Let's try to close Proxy a bit early as we don't have much control on the order of thread execution
                print "\n[INFO] Deleting Dump Status File"
                subprocess.call([adb, "-s", getIdentifier(), "shell", "rm","/sdcard/mobsec_status"])
                print "\n[INFO] Creating TAR of Application Files."
                subprocess.call([adb, "-s", getIdentifier(), "shell", "am", "startservice", "-a", PACKAGE, "opensecurity.ajin.datapusher/.GetPackageLocation"])
                print "\n[INFO] Waiting for TAR dump to complete..."
                if settings.REAL_DEVICE:
                    timeout=settings.DEVICE_TIMEOUT
                else:
                    timeout=settings.VM_TIMEOUT
                start_time=time.time()
                while True:
                    current_time=time.time()
                    if "MOBSEC-TAR-CREATED" in subprocess.check_output([adb, "-s", getIdentifier(), "shell", "cat", "/sdcard/mobsec_status"]):
                        break
                    if (current_time-start_time) > timeout:
                        print "\n[ERROR] TAR Generation Failed. Process timed out."
                        break
                print "\n[INFO] Dumping Application Files from Device/VM"
                subprocess.call([adb, "-s", getIdentifier(), "pull", "/data/local/"+PACKAGE+".tar", APKDIR+PACKAGE+".tar"])
                print "\n[INFO] Stopping ADB"
                subprocess.call([adb, "-s", getIdentifier(), "kill-server"])
                data = {'dump': 'yes'}
                return HttpResponse(json.dumps(data), content_type='application/json') 
            else:
                return HttpResponseRedirect('/error/')
        else:
            return HttpResponseRedirect('/error/')
    except:
        PrintException("[ERROR] Device Data Dump")
        return HttpResponseRedirect('/error/')
def getDomains(urls):
    try:
        DOMAINS=list()
        for url in urls:
            parsed_uri = urlparse(url)
            domain = '{uri.netloc}'.format(uri=parsed_uri)
            if ((domain not in DOMAINS) and
            (len(domain) > 2) and
            ("." in domain) and
            (domain.endswith(".")==False and
            re.search('[a-zA-Z0-9]', domain))):
                DOMAINS.append(domain)
        return DOMAINS
    except:
        PrintException("[ERROR] Extracting Domain form URL")
        pass
Esempio n. 15
0
def FinalTest(request):
    #Closing Services in VM/Device
    global tcp_server_mode
    print "\n[INFO] Collecting Data and Cleaning Up"
    try:
        if request.method == 'POST':
            data = {}
            MD5=request.POST['md5']
            PACKAGE=request.POST['pkg']
            if re.findall(";|\$\(|\|\||&&",PACKAGE):
                print "[ATTACK] Possible RCE"
                return HttpResponseRedirect('/error/') 
            m=re.match('[0-9a-f]{32}',MD5)
            if m:
                #Stop ScreenCast Client if it is running
                tcp_server_mode = "off"
                DIR=settings.BASE_DIR
                APKDIR=os.path.join(settings.UPLD_DIR, MD5+'/')
                TOOLSDIR=os.path.join(DIR, 'DynamicAnalyzer/tools/')  #TOOLS DIR
                adb=getADB(TOOLSDIR)
                #Change to check output of subprocess when analysis is done
                #Can't RCE
                os.system(adb+' -s '+getIdentifier()+' logcat -d dalvikvm:W ActivityManager:I > "'+APKDIR + 'logcat.txt"')
                print "\n[INFO] Downloading Logcat logs"
                #os.system(adb+' -s '+getIdentifier()+' logcat -d Xposed:I *:S > "'+APKDIR + 'x_logcat.txt"')
                subprocess.call([adb, "-s", getIdentifier(), "pull", "/data/data/de.robv.android.xposed.installer/log/error.log", APKDIR + "x_logcat.txt"])

                print "\n[INFO] Downloading Droidmon API Monitor Logcat logs"
                #Can't RCE
                os.system(adb+' -s '+getIdentifier()+' shell dumpsys > "'+APKDIR + 'dump.txt"');
                print "\n[INFO] Downloading Dumpsys logs"

                subprocess.call([adb, "-s", getIdentifier(), "shell", "am", "force-stop", PACKAGE])
                print "\n[INFO] Stopping Application"

                subprocess.call([adb, "-s", getIdentifier(), "shell", "am", "force-stop", "opensecurity.screencast"])
                print "\n[INFO] Stopping ScreenCast Service"

                data = {'final': 'yes'}
                return HttpResponse(json.dumps(data), content_type='application/json') 
            else:
                return HttpResponseRedirect('/error/')
        else:
            return HttpResponseRedirect('/error/')
    except:
        PrintException("[ERROR] Clean Up")
        return HttpResponseRedirect('/error/')
Esempio n. 16
0
def RefreshVM(uuid,snapshot_uuid,vbox_exe):
    print "\n[INFO] Refreshing MobSF VM"
    try:
        #Close VM
        args=[vbox_exe,'controlvm',uuid,'poweroff']
        subprocess.call(args)
        print "\n[INFO] VM Closed"
        #Restore Snapshot
        args=[vbox_exe,'snapshot',uuid,'restore',snapshot_uuid]
        subprocess.call(args)
        print "\n[INFO] VM Restore Snapshot"
        #Start Fresh VM
        args=[vbox_exe,'startvm',uuid]
        subprocess.call(args)
        print "\n[INFO] VM Starting"
    except:
        PrintException("[ERROR] Refreshing MobSF VM")
Esempio n. 17
0
def DynamicAnalyzer(request):

    print "\n[INFO] Dynamic Analysis Started"
    try:
        if request.method == 'POST':
            MD5 = request.POST['md5']
            PKG = request.POST['pkg']
            LNCH = request.POST['lng']
            if re.findall(";|\$\(|\|\||&&", PKG) or re.findall(
                    ";|\$\(|\|\||&&", LNCH):
                print "[ATTACK] Possible RCE"
                return HttpResponseRedirect('/error/')
            m = re.match('[0-9a-f]{32}', MD5)
            if m:
                # Delete ScreenCast Cache
                SCREEN_FILE = os.path.join(settings.STATIC_DIR,
                                           'screen/screen.png')
                if os.path.exists(SCREEN_FILE):
                    os.remove(SCREEN_FILE)
                # Delete Contents of Screenshot Dir
                SCRDIR = os.path.join(settings.UPLD_DIR,
                                      MD5 + '/screenshots-apk/')
                if os.path.isdir(SCRDIR):
                    shutil.rmtree(SCRDIR)
                #Start DM
                Proxy("", "", "", "")
                if settings.REAL_DEVICE:
                    print "\n[INFO] MobSF will perform Dynamic Analysis on real Android Device"
                else:
                    #Refersh VM
                    RefreshVM(settings.UUID, settings.SUUID, settings.VBOX)
                context = {
                    'md5': MD5,
                    'pkg': PKG,
                    'lng': LNCH,
                    'title': 'Start Testing',
                }
                template = "start_test.html"
                return render(request, template, context)
            else:
                return HttpResponseRedirect('/error/')
        else:
            return HttpResponseRedirect('/error/')
    except:
        PrintException("[ERROR] DynamicAnalyzer")
        return HttpResponseRedirect('/error/')
Esempio n. 18
0
def View(request):
    print "\n[INFO] Viewing File"
    try:
        typ = ''
        fil = ''
        rtyp = ''
        dat = ''
        m = re.match('[0-9a-f]{32}', request.GET['md5'])
        if m:
            fil = request.GET['file']
            MD5 = request.GET['md5']
            typ = request.GET['type']
            SRC = os.path.join(settings.UPLD_DIR, MD5 + '/DYNAMIC_DeviceData/')
            sfile = os.path.join(SRC, fil)
            #Prevent Directory Traversal Attacks
            if (("../" in fil) or ("%2e%2e" in fil) or (".." in fil)
                    or ("%252e" in fil)):
                return HttpResponseRedirect('/error/')
            else:
                with io.open(sfile, mode='r', encoding="utf8",
                             errors="ignore") as f:
                    dat = f.read()
                if ((fil.endswith('.xml')) and (typ == 'xml')):
                    rtyp = 'xml'
                elif typ == 'db':
                    dat = HandleSqlite(sfile)
                    dat = dat.decode("windows-1252").encode("utf8")
                    rtyp = 'plain'
                elif typ == 'others':
                    rtyp = 'plain'
                else:
                    return HttpResponseRedirect('/error/')
                context = {
                    'title': escape(ntpath.basename(fil)),
                    'file': escape(ntpath.basename(fil)),
                    'dat': dat,
                    'type': rtyp,
                }
                template = "view.html"
                return render(request, template, context)

        else:
            return HttpResponseRedirect('/error/')
    except:
        PrintException("[ERROR] Viewing File")
        return HttpResponseRedirect('/error/')
Esempio n. 19
0
def RunProcess(args):
    try:
        proc = subprocess.Popen(
            args,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
        )
        dat = ''
        while True:
            line = proc.stdout.readline()
            if not line:
                break
            dat += line
        return dat
    except:
        PrintException("[ERROR] Finding Java path - Cannot Run Process")
        return ""
Esempio n. 20
0
def GetEnv(request):

    print "\n[INFO] Setting up Dynamic Analysis Environment"
    try:
        if request.method == 'POST':
            data = {}
            MD5 = request.POST['md5']
            PKG = request.POST['pkg']
            LNCH = request.POST['lng']
            if re.findall(";|\$\(|\|\||&&", PKG) or re.findall(
                    ";|\$\(|\|\||&&", LNCH):
                print "[ATTACK] Possible RCE"
                return HttpResponseRedirect('/error/')
            m = re.match('[0-9a-f]{32}', MD5)
            if m:
                DIR = settings.BASE_DIR
                APP_DIR = os.path.join(settings.UPLD_DIR,
                                       MD5 + '/')  #APP DIRECTORY
                APP_FILE = MD5 + '.apk'  #NEW FILENAME
                APP_PATH = APP_DIR + APP_FILE  #APP PATH
                TOOLS_DIR = os.path.join(DIR,
                                         'DynamicAnalyzer/tools/')  #TOOLS DIR
                DWD_DIR = settings.DWD_DIR
                ADB_CON_ID = getIdentifier()
                PROXY_IP = settings.PROXY_IP  #Proxy IP
                PORT = str(settings.PORT)  #Proxy Port
                WebProxy(APP_DIR, PROXY_IP, PORT)
                ConnectInstallRun(
                    TOOLS_DIR, ADB_CON_ID, APP_PATH, PKG, LNCH,
                    True)  #Change True to support non-activity components
                SCREEN_WIDTH, SCREEN_HEIGHT = GetRes()
                data = {
                    'ready': 'yes',
                    'screen_witdth': SCREEN_WIDTH,
                    'screen_height': SCREEN_HEIGHT,
                }
                return HttpResponse(json.dumps(data),
                                    content_type='application/json')
            else:
                return HttpResponseRedirect('/error/')
        else:
            return HttpResponseRedirect('/error/')
    except:
        PrintException("[ERROR] Setting up Dynamic Analysis Environment")
        return HttpResponseRedirect('/error/')
Esempio n. 21
0
def getADB(TOOLSDIR):
    print "\n[INFO] Getting ADB Location"
    try:
        adb='adb'
        if platform.system()=="Darwin":
            adb_dir=os.path.join(TOOLSDIR, 'adb/mac/')
            subprocess.call(["chmod", "777", adb_dir])
            adb=os.path.join(TOOLSDIR , 'adb/mac/adb')
        elif platform.system()=="Linux":
            adb_dir=os.path.join(TOOLSDIR, 'adb/linux/')
            subprocess.call(["chmod", "777", adb_dir])
            adb=os.path.join(TOOLSDIR , 'adb/linux/adb')
        elif platform.system()=="Windows":
            adb=os.path.join(TOOLSDIR , 'adb/windows/adb.exe')
        return adb
    except:
        PrintException("[ERROR] Getting ADB Location")
        return "adb"
Esempio n. 22
0
def MobSFCA(request):
    try:
        if request.method == 'POST':
            data = {}
            act = request.POST['action']
            TOOLSDIR = os.path.join(settings.BASE_DIR,
                                    'DynamicAnalyzer/tools/')  #TOOLS DIR
            ROOTCA = os.path.join(settings.BASE_DIR,
                                  'DynamicAnalyzer/pyWebProxy/ca.crt')
            adb = getADB(TOOLSDIR)
            if act == "install":
                print "\n[INFO] Installing MobSF RootCA"
                subprocess.call([
                    adb, "-s",
                    getIdentifier(), "push", ROOTCA,
                    "/data/local/tmp/" + settings.ROOT_CA
                ])
                subprocess.call([
                    adb, "-s",
                    getIdentifier(), "shell", "su", "-c", "cp",
                    "/data/local/tmp/" + settings.ROOT_CA,
                    "/system/etc/security/cacerts/" + settings.ROOT_CA
                ])
                subprocess.call([
                    adb, "-s",
                    getIdentifier(), "shell", "rm",
                    "/data/local/tmp/" + settings.ROOT_CA
                ])
                data = {'ca': 'installed'}
            elif act == "remove":
                print "\n[INFO] Removing MobSF RootCA"
                subprocess.call([
                    adb, "-s",
                    getIdentifier(), "shell", "su", "-c", "rm",
                    "/system/etc/security/cacerts/" + settings.ROOT_CA
                ])
                data = {'ca': 'removed'}
            return HttpResponse(json.dumps(data),
                                content_type='application/json')
        else:
            return HttpResponseRedirect('/error/')
    except:
        PrintException("[ERROR] MobSF RootCA Handler")
        return HttpResponseRedirect('/error/')
Esempio n. 23
0
def Download(MD5,DWDDIR,APKDIR,PKG):
    print "\n[INFO] Generating Downloads"
    try:
        Logcat=os.path.join(APKDIR,'logcat.txt')
        xLogcat=os.path.join(APKDIR,'x_logcat.txt')
        Dumpsys=os.path.join(APKDIR,'dump.txt')
        Sshot=os.path.join(APKDIR,'screenshots-apk/')
        Web=os.path.join(APKDIR,'WebTraffic.txt')
        Star=os.path.join(APKDIR, PKG+'.tar')

        
        DLogcat=os.path.join(DWDDIR,MD5+'-logcat.txt')
        DxLogcat=os.path.join(DWDDIR,MD5+'-x_logcat.txt')
        DDumpsys=os.path.join(DWDDIR,MD5+'-dump.txt')
        DSshot=os.path.join(DWDDIR,MD5+'-screenshots-apk/')
        DWeb=os.path.join(DWDDIR,MD5+'-WebTraffic.txt')
        DStar=os.path.join(DWDDIR,MD5+'-AppData.tar')
        
        #Delete existing data 
        dellist = [DLogcat,DxLogcat,DDumpsys,DSshot,DWeb,DStar]
        for item in dellist:
            if os.path.isdir(item):
                shutil.rmtree(item)
            elif os.path.isfile(item):
                os.remove(item)
        #Copy new data
        shutil.copyfile(Logcat,DLogcat)
        shutil.copyfile(xLogcat,DxLogcat)
        shutil.copyfile(Dumpsys,DDumpsys)
        try:
            shutil.copytree(Sshot,DSshot)
        except:
            pass
        try:
            shutil.copyfile(Web,DWeb)
        except:
            pass  
        try:
            shutil.copyfile(Star,DStar)
        except:
            pass
    except:
        PrintException("[ERROR] Generating Downloads")
Esempio n. 24
0
def ScreenCastService():
    global tcp_server_mode
    print "\n[INFO] ScreenCast Service Status: " + tcp_server_mode
    try:
        SCREEN_DIR = os.path.join(settings.STATIC_DIR, 'screen/')
        if not os.path.exists(SCREEN_DIR):
            os.makedirs(SCREEN_DIR)

        s = socket.socket()
        if tcp_server_mode == "on":
            s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            ADDR = (settings.SCREEN_IP, settings.SCREEN_PORT)
            s.bind(ADDR)
            s.listen(10)
            while (tcp_server_mode == "on"):
                ss, address = s.accept()
                print "Got Connection from: ", address[0]
                if settings.REAL_DEVICE:
                    IP = settings.DEVICE_IP
                else:
                    IP = settings.VM_IP
                if address[0] == IP:
                    '''
                    Very Basic Check to ensure that only MobSF VM/Device is allowed to connect 
                    to MobSF ScreenCast Service.
                    '''
                    with open(SCREEN_DIR + 'screen.png', 'wb') as f:
                        while True:
                            data = ss.recv(1024)
                            if not data:
                                break
                            f.write(data)
                else:
                    print "\n[ATTACK] An unknown client :" + address[
                        0] + " is trying to make a connection with MobSF ScreenCast Service!"
        elif tcp_server_mode == "off":
            s.close()
    except:
        s.close()
        PrintException("[ERROR] ScreenCast Server")
        pass
Esempio n. 25
0
def SaveOnExit():
    print "\n[INFO] Saving Captured Web Proxy Data"
    try:
        global REQUEST_LIST, URLS, TRAFFIC, log
        print "\n[INFO] Saving URLS"
        with open(os.path.join(log, "urls"), "w") as f2:
            URLS = list(set(URLS))
            URLS = '\n'.join(URLS)
            f2.write(URLS)

        print "\n[INFO] Saving WebTraffic"
        with open(os.path.join(log, "WebTraffic.txt"), "w") as f3:
            f3.write(TRAFFIC)

        print "\n[INFO] Saving Request Objects"
        with codecs.open(os.path.join(log, "requestdb"), "w", "utf-8") as f:
            json.dump(REQUEST_LIST, f)

    except:
        PrintException("[ERROR] Saving Captured Web Proxy Data")
    REQUEST_LIST = []
    URLS = []
    TRAFFIC = ""
def Upload(request):
    try:
        response_data = {}
        response_data['url'] = ''
        response_data['description'] = ''
        response_data['status'] = ''
        if request.method == 'POST':
            form = UploadFileForm(request.POST, request.FILES)
            if form.is_valid():
                file_type = request.FILES['file'].content_type
                print "[INFO] MIME Type: " + file_type + " FILE: " + str(
                    request.FILES['file'].name)
                if (file_type == "application/octet-stream" or file_type
                        == "application/vnd.android.package-archive"
                        or file_type == "application/x-zip-compressed"
                    ) and request.FILES['file'].name.endswith('.apk'):  #APK
                    md5 = handle_uploaded_file(request.FILES['file'], '.apk')
                    response_data[
                        'url'] = 'StaticAnalyzer/?name=' + request.FILES[
                            'file'].name + '&type=apk&checksum=' + md5
                    response_data['status'] = 'success'
                    PushtoRecent(request.FILES['file'].name, md5,
                                 response_data['url'])
                    print "\n[INFO] Performing Static Analysis of Android APK"
                elif (file_type == "application/zip"
                      or file_type == "application/octet-stream"
                      or file_type == "application/x-zip-compressed"
                      ) and request.FILES['file'].name.endswith(
                          '.zip'):  #Android /iOS Zipped Source
                    md5 = handle_uploaded_file(request.FILES['file'], '.zip')
                    response_data[
                        'url'] = 'StaticAnalyzer/?name=' + request.FILES[
                            'file'].name + '&type=zip&checksum=' + md5
                    response_data['status'] = 'success'
                    PushtoRecent(request.FILES['file'].name, md5,
                                 response_data['url'])
                    print "\n[INFO] Performing Static Analysis of Android/iOS Source Code"
                elif ((file_type == "application/octet-stream"
                       or file_type == "application/x-itunes-ipa"
                       or file_type == "application/x-zip-compressed")
                      and request.FILES['file'].name.endswith('.ipa')
                      ):  #iOS Binary
                    if platform.system() == "Darwin":
                        md5 = handle_uploaded_file(request.FILES['file'],
                                                   '.ipa')
                        response_data[
                            'url'] = 'StaticAnalyzer_iOS/?name=' + request.FILES[
                                'file'].name + '&type=ipa&checksum=' + md5
                        response_data['status'] = 'success'
                        PushtoRecent(request.FILES['file'].name, md5,
                                     response_data['url'])
                        print "\n[INFO] Performing Static Analysis of iOS IPA"
                    else:
                        response_data['url'] = 'MAC_ONLY/'
                        response_data['status'] = 'success'
                        print "\n[ERROR] Static Analysis of iOS IPA requires OSX"
                else:
                    response_data['url'] = ''
                    response_data['description'] = 'File format not Supported!'
                    response_data['status'] = 'error'
                    print "\n[ERROR] File format not Supported!"

            else:
                response_data['url'] = ''
                response_data['description'] = 'Invalid Form Data!'
                response_data['status'] = 'error'
                print "\n[ERROR] Invalid Form Data!"
        else:
            response_data['url'] = ''
            response_data['description'] = 'Method not Supported!'
            response_data['status'] = 'error'
            print "\n[ERROR] Method not Supported!"
            form = UploadFileForm()
        r = HttpResponse(json.dumps(response_data),
                         content_type="application/json")
        r['Access-Control-Allow-Origin'] = '*'
        return r
    except:
        PrintException("[ERROR] Uploading File:")
Esempio n. 27
0
def FindJava():
    try:
        if platform.system() == "Windows":
            print "\n[INFO] Finding JDK Location in Windows...."
            WIN_JAVA_LIST = [
                "C:/Program Files/Java/", "C:/Program Files (x86)/Java/"
            ]  #JDK 7 jdk1.7.0_17/bin/
            for WIN_JAVA_BASE in WIN_JAVA_LIST:
                JDK = []
                for dirname in os.listdir(WIN_JAVA_BASE):
                    if "jdk" in dirname:
                        JDK.append(dirname)
                if len(JDK) == 1:
                    print "\n[INFO] Oracle JDK Identified. Looking for JDK 1.7 or above"
                    j = ''.join(JDK)
                    if re.findall(JAVA_VER, j):
                        WIN_JAVA = WIN_JAVA_BASE + j + "/bin/"
                        args = [WIN_JAVA + "java"]
                        dat = RunProcess(args)
                        if "oracle" in dat:
                            print "\n[INFO] Oracle Java (JDK >= 1.7) is installed!"
                            return WIN_JAVA
                elif len(JDK) > 1:
                    print "\n[INFO] Multiple JDK Instances Identified. Looking for JDK 1.7 or above"
                    for j in JDK:
                        if re.findall(JAVA_VER, j):
                            WIN_JAVA = WIN_JAVA_BASE + j + "/bin/"
                            break
                        else:
                            WIN_JAVA = ""
                    if len(WIN_JAVA) > 1:
                        args = [WIN_JAVA + "java"]
                        dat = RunProcess(args)
                        if "oracle" in dat:
                            print "\n[INFO] Oracle Java (JDK >= 1.7) is installed!"
                            return WIN_JAVA
            PrintException("[ERROR] Oracle JDK 1.7 or above is not found!")
            return ""
        else:
            print "\n[INFO] Finding JDK Location in Linux/MAC...."
            MAC_LINUX_JAVA = "/usr/bin/"
            args = [MAC_LINUX_JAVA + "java"]
            dat = RunProcess(args)
            if "oracle" in dat:
                print "\n[INFO] Oracle Java is installed!"
                args = [MAC_LINUX_JAVA + "java", '-version']
                dat = RunProcess(args)
                f_line = dat.split("\n")[0]
                if re.findall(JAVA_VER, f_line):
                    print "\n[INFO] JDK 1.7 or above is available"
                    return MAC_LINUX_JAVA
                else:
                    PrintException(
                        "[ERROR] Please install Oracle JDK 1.7 or above")
                    return ""
            else:
                PrintException(
                    "[ERROR] Oracle Java JDK 1.7 or above is not found!")
                return ""
    except:
        PrintException("[ERROR] Oracle Java (JDK >=1.7) is not found!")
        return ""
Esempio n. 28
0
def RunAnalysis(APKDIR,MD5,PACKAGE):
    print "\n[INFO] Dynamic File Analysis"
    Web=os.path.join(APKDIR,'WebTraffic.txt')
    Logcat=os.path.join(APKDIR,'logcat.txt')
    xLogcat=os.path.join(APKDIR,'x_logcat.txt')
    traffic=''
    wb=''
    xlg=''
    try:
        with io.open(Web,mode='r',encoding="utf8",errors="ignore") as f:
            wb=f.read()
    except:
        pass

    with io.open(Logcat,mode='r',encoding="utf8",errors="ignore") as f:
        traffic=f.read()
    with io.open(xLogcat,mode='r',encoding="utf8",errors="ignore") as f:
        xlg=f.read()
    traffic=wb+traffic+xlg
    URLS=[]
    #URLs My Custom regex
    p = re.compile(ur'((?:https?://|s?ftps?://|file://|javascript:|data:|www\d{0,3}[.])[\w().=/;,#:@?&~*+!$%\'{}-]+)', re.UNICODE) 
    urllist=re.findall(p, traffic.lower())
    for url in urllist:
        if url not in URLS:
            URLS.append(url)
                        
    #Email Etraction Regex
    EMAILS=[]
    regex = re.compile(("[\w.-]+@[\w-]+\.[\w.]+"))
    for email in regex.findall(traffic.lower()):
        if ((email not in EMAILS) and (not email.startswith('//'))):
            if email=="*****@*****.**":
                pass
            else:
                EMAILS.append(email)
    #Extract Device Data
    try:
        TARLOC=os.path.join(APKDIR,PACKAGE+'.tar')
        UNTAR_DIR = os.path.join(APKDIR,'DYNAMIC_DeviceData/')
        if not os.path.exists(UNTAR_DIR):
            os.makedirs(UNTAR_DIR)
        with tarfile.open(TARLOC) as tar:
            try:
                tar.extractall(UNTAR_DIR)
            except:
                pass
    except:
        PrintException("[ERROR] TAR EXTRACTION FAILED")
    #Do Static Analysis on Data from Device
    xmlfiles=''
    SQLiteDB=''
    OtherFiles=''
    typ=''
    UNTAR_DIR = os.path.join(APKDIR,'DYNAMIC_DeviceData/')
    if not os.path.exists(UNTAR_DIR):
        os.makedirs(UNTAR_DIR)
    try:
        for dirName, subDir, files in os.walk(UNTAR_DIR):
            for jfile in files:
                file_path=os.path.join(UNTAR_DIR,dirName,jfile)
                if "+" in file_path:
                    shutil.move(file_path,file_path.replace("+","x"))
                    file_path=file_path.replace("+","x")
                fileparam=file_path.replace(UNTAR_DIR,'')
                if jfile=='lib':
                    pass
                else:
                    if jfile.endswith('.xml'):
                        typ='xml'
                        xmlfiles+="<tr><td><a href='../View/?file="+escape(fileparam)+"&md5="+MD5+"&type="+typ+"'>"+escape(fileparam)+"</a></td><tr>"
                    else:
                        with io.open(file_path, mode='r',encoding="utf8",errors="ignore") as f:
                            b=f.read(6)
                        if b=="SQLite":
                            typ='db'
                            SQLiteDB+="<tr><td><a href='../View/?file="+escape(fileparam)+"&md5="+MD5+"&type="+typ+"'>"+escape(fileparam)+"</a></td><tr>" 
                        elif not jfile.endswith('.DS_Store'):
                            typ='others'
                            OtherFiles+="<tr><td><a href='../View/?file="+escape(fileparam)+"&md5="+MD5+"&type="+typ+"'>"+escape(fileparam)+"</a></td><tr>"
    except:
        PrintException("[ERROR] Dynamic File Analysis")
        pass              
    return URLS,EMAILS,wb,xmlfiles,SQLiteDB,OtherFiles
Esempio n. 29
0
def APIAnalysis(PKG,LOCATION):
    print "\n[INFO] Dynamic API Analysis"
    dat=""
    API_BASE64=[]
    API_FILEIO=[]
    API_RELECT=[]
    API_SYSPROP=[]
    API_CNTRSLVR=[]
    API_CNTVAL=[]
    API_BINDER=[]
    API_CRYPTO=[]
    API_ACNTMNGER=[]
    API_DEVICEINFO=[]
    API_NET=[]
    API_DEXLOADER=[]
    API_CMD=[]
    API_SMS=[]
    try:
        with open(LOCATION,"r") as f:
            dat=f.readlines()
        ID="Droidmon-apimonitor-" + PKG +":"
        for line in dat:
            line = line.decode('utf8', 'ignore')
            if (ID) in line:
                #print "LINE: " + line
                param, value = line.split(ID,1)
                #print "PARAM is :" + param
                #print "Value is :"+ value
                try:
                    APIs=json.loads(value,strict=False)
                    RET=''
                    CLS=''
                    MTD=''
                    ARGS=''
                    MTD= str(APIs["method"]) 
                    CLS= str(APIs["class"])
                    #print "Called Class: " + CLS
                    #print "Called Method: " + MTD
                    if APIs.get('return'):
                        RET=str(APIs["return"])
                        #print "Return Data: " + RET
                    else:
                        #print "No Return Data"
                        RET = "No Return Data"
                    if APIs.get('args'):
                        ARGS=str(APIs["args"])
                        #print "Passed Arguments" + ARGS
                    else:
                        #print "No Arguments Passed"
                        ARGS= "No Arguments Passed"
                    #XSS Safe
                    D="</br>METHOD: "+ escape(MTD) + "</br>ARGUMENTS: "+ escape(ARGS) + "</br>RETURN DATA: "+escape(RET)
                    
                    if re.findall("android.util.Base64",CLS):
                        API_BASE64.append(D)
                    if re.findall('libcore.io|android.app.SharedPreferencesImpl$EditorImpl',CLS):
                        API_FILEIO.append(D)
                    if re.findall('java.lang.reflect',CLS):
                        API_RELECT.append(D)
                    if re.findall('android.content.ContentResolver|android.location.Location|android.media.AudioRecord|android.media.MediaRecorder|android.os.SystemProperties',CLS):
                        API_SYSPROP.append(D)
                    if re.findall('android.app.Activity|android.app.ContextImpl|android.app.ActivityThread',CLS):
                        API_BINDER.append(D)
                    if re.findall('javax.crypto.spec.SecretKeySpec|javax.crypto.Cipher|javax.crypto.Mac',CLS):
                        API_CRYPTO.append(D)
                    if re.findall('android.accounts.AccountManager|android.app.ApplicationPackageManager|android.app.NotificationManager|android.net.ConnectivityManager|android.content.BroadcastReceiver',CLS):
                        API_ACNTMNGER.append(D)
                    if re.findall('android.telephony.TelephonyManager|android.net.wifi.WifiInfo|android.os.Debug',CLS):
                        API_DEVICEINFO.append(D)
                    if re.findall('dalvik.system.BaseDexClassLoader|dalvik.system.DexFile|dalvik.system.DexClassLoader|dalvik.system.PathClassLoader',CLS):
                        API_DEXLOADER.append(D)
                    if re.findall('java.lang.Runtime|java.lang.ProcessBuilder|java.io.FileOutputStream|java.io.FileInputStream|android.os.Process',CLS):
                        API_CMD.append(D)
                    if re.findall('android.content.ContentValues',CLS):
                        API_CNTVAL.append(D)
                    if re.findall('android.telephony.SmsManager',CLS):
                        API_SMS.append(D)
                    if re.findall('java.net.URL|org.apache.http.impl.client.AbstractHttpClient',CLS):
                        API_NET.append(D)
                except:
                    PrintException("[ERROR] Parsing JSON Failed for: " + value)
    except:
        PrintException("[ERROR] Dynamic API Analysis")
        pass
    return list(set(API_NET)),list(set(API_BASE64)), list(set(API_FILEIO)), list(set(API_BINDER)), list(set(API_CRYPTO)), list(set(API_DEVICEINFO)), list(set(API_CNTVAL)), list(set(API_SMS)), list(set(API_SYSPROP)),list(set(API_DEXLOADER)),list(set(API_RELECT)),list(set(API_ACNTMNGER)),list(set(API_CMD)) 
Esempio n. 30
0
def WebProxy(APKDIR,ip,port):
    print "\n[INFO] Starting Web Proxy"
    try:
        Proxy(ip,port,APKDIR,"on")
    except:
        PrintException("[ERROR] Starting Web Proxy")