Beispiel #1
0
def api_auth(meta):
    """Check if API Key Matches."""
    if 'HTTP_X_MOBSF_API_KEY' in meta:
        return bool(api_key() == meta['HTTP_X_MOBSF_API_KEY'])
    elif 'HTTP_AUTHORIZATION' in meta:
        return bool(api_key() == meta['HTTP_AUTHORIZATION'])
    return False
Beispiel #2
0
def api_docs(request):
    """Api Docs Route."""
    context = {
        'title': 'REST API Docs',
        'api_key': api_key(),
        'version': settings.MOBSF_VER,
    }
    template = 'general/apidocs.html'
    return render(request, template, context)
def run(request):
    """Source Tree - Java/Smali view."""
    try:
        logger.info('Listing Source files')
        match = re.match('^[0-9a-f]{32}$', request.GET['md5'])
        if not match:
            return print_n_send_error_response(request, 'Scan hash not found')
        md5 = request.GET['md5']
        typ = request.GET['type']
        base = Path(settings.UPLD_DIR) / md5
        if typ == 'smali':
            src = base / 'smali_source'
        else:
            try:
                src = find_java_source_folder(base)[0]
            except StopIteration:
                return print_n_send_error_response(
                    request,
                    'Invalid Directory Structure')

        tree_index = tree_index_maker(src, len(src.as_posix()))
        context = {
            'subfiles': tree_index,
            'title': f'{typ.capitalize()} Source',
            'hash': md5,
            'source_type': typ,
            'version': settings.MOBSF_VER,
            'api_key': api_key(),
        }
        template = 'static_analysis/source_tree.html'
        return render(request, template, context)
    except Exception:
        logger.exception('Getting Source Files')
        return print_n_send_error_response(
            request,
            'Error Getting Source Files')
Beispiel #4
0
def api_test():
    """View for Handling REST API Test."""
    logger.info('\nRunning REST API Unit test')
    auth = api_key()
    try:
        uploaded = []
        logger.info('Running Test on Upload API')
        http_client = Client()
        apk_dir = os.path.join(settings.BASE_DIR, 'StaticAnalyzer/test_files/')
        for filename in os.listdir(apk_dir):
            if not filename.endswith(
                ('.xapk', '.apk', '.ipa', '.appx', '.zip')):
                continue
            if platform.system() == 'Windows' and filename.endswith('.ipa'):
                continue
            fpath = os.path.join(apk_dir, filename)
            if (platform.system() not in ['Darwin', 'Linux']
                    and fpath.endswith('.ipa')):
                continue
            with open(fpath, 'rb') as filp:
                response = http_client.post('/api/v1/upload', {'file': filp},
                                            HTTP_AUTHORIZATION=auth)
                obj = json.loads(response.content.decode('utf-8'))
                if response.status_code == 200 and 'hash' in obj:
                    logger.info('[OK] Upload OK: %s', filename)
                    uploaded.append(obj)
                else:
                    logger.error('Performing Upload %s', filename)
                    return True
        logger.info('[OK] Completed Upload API test')
        logger.info('Running Static Analysis API Test')
        for upl in uploaded:
            resp = http_client.post('/api/v1/scan',
                                    upl,
                                    HTTP_AUTHORIZATION=auth)
            if resp.status_code == 200:
                logger.info('[OK] Static Analysis Complete: %s',
                            upl['file_name'])
            else:
                logger.error('Performing Static Analysis: %s',
                             upl['file_name'])
                return True
        logger.info('[OK] Static Analysis API test completed')
        # Scan List API test
        logger.info('Running Scan List API tests')
        resp = http_client.get('/api/v1/scans', HTTP_AUTHORIZATION=auth)
        if resp.status_code == 200:
            logger.info('Scan List API Test 1 success')
        else:
            logger.error('Scan List API Test 1')
            return True
        resp = http_client.get('/api/v1/scans?page=1&page_size=10',
                               HTTP_AUTHORIZATION=auth)
        if resp.status_code == 200:
            logger.info('Scan List API Test 2 success')
        else:
            logger.error('Scan List API Test 2')
            return True
        resp = http_client.get('/api/v1/scans', HTTP_X_MOBSF_API_KEY=auth)
        if resp.status_code == 200:
            logger.info('Scan List API Test with custom http header 1 success')
        else:
            logger.error('Scan List API Test with custom http header 1')
            return True
        resp = http_client.get('/api/v1/scans?page=1&page_size=10',
                               HTTP_X_MOBSF_API_KEY=auth)
        if resp.status_code == 200:
            logger.info('Scan List API Test with custom http header 2 success')
        else:
            logger.error('Scan List API Test with custom http header 2')
            return True
        logger.info('[OK] Scan List API tests completed')
        # PDF Tests
        logger.info('Running PDF Generation API Test')
        if platform.system() in ['Darwin', 'Linux']:
            pdfs = [
                {
                    'hash': '02e7989c457ab67eb514a8328779f256'
                },
                {
                    'hash': '3a552566097a8de588b8184b059b0158'
                },
                {
                    'hash': '6c23c2970551be15f32bbab0b5db0c71'
                },
                {
                    'hash': '52c50ae824e329ba8b5b7a0f523efffe'
                },
                {
                    'hash': '57bb5be0ea44a755ada4a93885c3825e'
                },
                {
                    'hash': '8179b557433835827a70510584f3143e'
                },
                {
                    'hash': '7b0a23bffc80bac05739ea1af898daad'
                },
            ]
        else:
            pdfs = [
                {
                    'hash': '02e7989c457ab67eb514a8328779f256'
                },
                {
                    'hash': '3a552566097a8de588b8184b059b0158'
                },
                {
                    'hash': '52c50ae824e329ba8b5b7a0f523efffe'
                },
                {
                    'hash': '57bb5be0ea44a755ada4a93885c3825e'
                },
                {
                    'hash': '8179b557433835827a70510584f3143e'
                },
                {
                    'hash': '7b0a23bffc80bac05739ea1af898daad'
                },
            ]
        for pdf in pdfs:
            resp = http_client.post('/api/v1/download_pdf',
                                    pdf,
                                    HTTP_AUTHORIZATION=auth)
            resp_custom = http_client.post('/api/v1/download_pdf',
                                           pdf,
                                           HTTP_X_MOBSF_API_KEY=auth)
            assert (resp.status_code == 200)
            assert (resp_custom.status_code == 200)
            if (resp.status_code == 200
                    and resp._headers['content-type'][1] == 'application/pdf'):
                logger.info('[OK] PDF Report Generated: %s', pdf['hash'])
            else:
                logger.error('Generating PDF: %s', pdf['hash'])
                logger.info(resp.content)
                return True
        logger.info('[OK] PDF Generation API test completed')
        logger.info('Running JSON Report API test')
        # JSON Report
        ctype = 'application/json; charset=utf-8'
        for jsn in pdfs:
            resp = http_client.post('/api/v1/report_json',
                                    jsn,
                                    HTTP_AUTHORIZATION=auth)
            resp_custom = http_client.post('/api/v1/report_json',
                                           jsn,
                                           HTTP_X_MOBSF_API_KEY=auth)
            assert (resp.status_code == 200)
            assert (resp_custom.status_code == 200)
            if (resp.status_code == 200
                    and resp._headers['content-type'][1] == ctype):
                logger.info('[OK] JSON Report Generated: %s', jsn['hash'])
            else:
                logger.error('Generating JSON Response: %s', jsn['hash'])
                return True
        logger.info('[OK] JSON Report API test completed')
        logger.info('Running View Source API test')
        # View Source tests
        files = [{
            'file': 'opensecurity/helloworld/MainActivity.java',
            'type': 'apk',
            'hash': '3a552566097a8de588b8184b059b0158'
        }, {
            'file': 'opensecurity/webviewignoressl/MainActivity.java',
            'type': 'studio',
            'hash': '52c50ae824e329ba8b5b7a0f523efffe'
        }, {
            'file': 'DamnVulnerableIOSApp/AppDelegate.m',
            'type': 'ios',
            'hash': '57bb5be0ea44a755ada4a93885c3825e'
        }]
        if platform.system() in ['Darwin', 'Linux']:
            files.append({
                'file': 'helloworld.app/Info.plist',
                'type': 'ipa',
                'hash': '6c23c2970551be15f32bbab0b5db0c71'
            })
        for sfile in files:
            resp = http_client.post('/api/v1/view_source',
                                    sfile,
                                    HTTP_AUTHORIZATION=auth)
            resp_custom = http_client.post('/api/v1/view_source',
                                           sfile,
                                           HTTP_X_MOBSF_API_KEY=auth)
            assert (resp.status_code == 200)
            assert (resp_custom.status_code == 200)
            if resp.status_code == 200:
                dat = json.loads(resp.content.decode('utf-8'))
                if dat['title']:
                    logger.info('[OK] Reading - %s', sfile['file'])
                else:
                    logger.error('Reading - %s', sfile['file'])
                    return True
            else:
                logger.error('Reading - %s', sfile['file'])
                return True
        logger.info('[OK] View Source API test completed')
        # Compare apps test
        logger.info('Running App Compare API tests')
        resp = http_client.post('/api/v1/compare', {
            'hash1': '3a552566097a8de588b8184b059b0158',
            'hash2': '52c50ae824e329ba8b5b7a0f523efffe',
        },
                                HTTP_AUTHORIZATION=auth)
        assert (resp.status_code == 200)
        resp_custom = http_client.post(
            '/api/v1/compare', {
                'hash1': '3a552566097a8de588b8184b059b0158',
                'hash2': '52c50ae824e329ba8b5b7a0f523efffe',
            },
            HTTP_X_MOBSF_API_KEY=auth)
        assert (resp_custom.status_code == 200)
        if resp.status_code == 200:
            logger.info('[OK] App compare API tests completed')
        else:
            logger.error('App compare API tests failed')
            logger.info(resp.content)
            return True
        logger.info('Running Delete Scan Results test')
        # Deleting Scan Results
        if platform.system() in ['Darwin', 'Linux']:
            scan_md5s = [
                '02e7989c457ab67eb514a8328779f256',
                '3a552566097a8de588b8184b059b0158',
                '6c23c2970551be15f32bbab0b5db0c71',
                '52c50ae824e329ba8b5b7a0f523efffe',
                '57bb5be0ea44a755ada4a93885c3825e',
                '8179b557433835827a70510584f3143e',
                '7b0a23bffc80bac05739ea1af898daad',
            ]
        else:
            scan_md5s = [
                '02e7989c457ab67eb514a8328779f256',
                '3a552566097a8de588b8184b059b0158',
                '52c50ae824e329ba8b5b7a0f523efffe',
                '57bb5be0ea44a755ada4a93885c3825e',
                '8179b557433835827a70510584f3143e',
                '7b0a23bffc80bac05739ea1af898daad',
            ]
        for md5 in scan_md5s:
            resp = http_client.post('/api/v1/delete_scan', {'hash': md5},
                                    HTTP_AUTHORIZATION=auth)
            if resp.status_code == 200:
                dat = json.loads(resp.content.decode('utf-8'))
                if dat['deleted'] == 'yes':
                    logger.info('[OK] Deleted Scan: %s', md5)
                else:
                    logger.error('Deleting Scan: %s', md5)
                    return True
            else:
                logger.error('Deleting Scan: %s', md5)
                return True
        logger.info('Delete Scan Results API test completed')
    except Exception:
        logger.exception('Completing REST API Unit Test')
        return True
    return False