示例#1
0
    def test_parse_when_dex_parser_fails(self, mock_zipfile, mock_mkdtemp,
                                         mock_rmtree, mock_file_parser,
                                         mock_manifest_parser,
                                         mock_cert_parser, mock_dex_parser):
        tmp_directory = Mock()
        file = any_file(filename="any-apk-file")
        manifest = any_file(filename="any-manifest-file-name")
        cert = any_file(filename="any-cert-file-name")
        mock_zipfile.return_value.__enter__.return_value.namelist.return_value = [
            "any-manifest-file-name", "any-cert-file-name", "any-dex-file-name"
        ]
        mock_mkdtemp.return_value = tmp_directory
        mock_file_parser.is_zip_file.return_value = True
        mock_file_parser.return_value.parse.return_value = file
        mock_manifest_parser.looks_like_manifest.side_effect = [
            True, False, False
        ]
        mock_manifest_parser.return_value.parse.return_value = manifest
        mock_cert_parser.looks_like_cert.side_effect = [True, False]
        mock_cert_parser.return_value.parse.return_value = cert
        mock_dex_parser.looks_like_dex.side_effect = [True]
        mock_dex_parser.return_value.parse.side_effect = FileParsingError()

        with self.assertRaises(ApkParsingError):
            ApkParser().parse("any-file-path", extended_processing=True)
        mock_rmtree.assert_called_with(tmp_directory)
示例#2
0
    def test_parse_fails_when_keytool_fails(self, mock_file_parser, mock_popen):
        mock_file_parser.return_value = any_file_parser(file=any_file())
        mock_popen.return_value = any_popen(b"keytool error")

        with self.assertRaises(CertParsingError):
            self.sut.parse("any-file-path", "any-file-name")
        assert_popen_called_once_with(mock_popen, "keytool -printcert -file any-file-path")
示例#3
0
    def test_parse_when_zipfile_fails(self, mock_file_parser, mock_zipfile):
        mock_file_parser.is_zip_file.return_value = True
        mock_file_parser.return_value.parse.return_value = any_file()
        mock_zipfile.side_effect = BadZipFile()

        with self.assertRaises(BadZipFile):
            ApkParser().parse("any-file-path", extended_processing=False)
    def test_parse_without_filename(
            self,
            mock_file,
            mock_isfile,
            mock_access,
            mock_getsize,
            mock_md5,
            mock_sha1,
            mock_sha256,
            mock_sha512
    ):
        mock_isfile.return_value = True
        mock_access.return_value = True
        mock_getsize.return_value = self.ANY_FILE_SIZE
        mock_md5.return_value.hexdigest.return_value = self.ANY_FILE_MD5
        mock_sha1.return_value.hexdigest.return_value = self.ANY_FILE_SHA1
        mock_sha256.return_value.hexdigest.return_value = self.ANY_FILE_SHA256
        mock_sha512.return_value.hexdigest.return_value = self.ANY_FILE_SHA512

        file = self.sut.parse("any-file-path")

        mock_file.assert_called_with("any-file-path", "rb")
        assert_file_equal(
            self,
            expected=any_file(
                filename="any-file-path",
                size=self.ANY_FILE_SIZE,
                md5=self.ANY_FILE_MD5,
                sha1=self.ANY_FILE_SHA1,
                sha256=self.ANY_FILE_SHA256,
                sha512=self.ANY_FILE_SHA512
            ),
            actual=file
        )
示例#5
0
    def test_parse_with_extended_processing(self, mock_zipfile, mock_mkdtemp,
                                            mock_rmtree, mock_file_parser,
                                            mock_manifest_parser,
                                            mock_cert_parser, mock_dex_parser,
                                            mock_aapt):
        tmp_directory = Mock()
        file = any_file(filename="any-apk-file")
        manifest = any_file(filename="any-manifest-file-name")
        cert = any_file(filename="any-cert-file-name")
        dex = any_file(filename="any-dex-file-name")
        resource = any_file(filename="any-resource-file")
        mock_zipfile.return_value.__enter__.return_value.namelist.return_value = [
            "any-manifest-file-name", "any-cert-file-name",
            "any-dex-file-name", "any-resource-file", "any-resource-directory"
        ]
        mock_mkdtemp.return_value = tmp_directory
        mock_file_parser.is_zip_file.return_value = True
        mock_file_parser.is_directory.side_effect = [False, True]
        mock_file_parser.return_value.parse.side_effect = [file, resource]
        mock_manifest_parser.looks_like_manifest.side_effect = [
            True, False, False, False, False
        ]
        mock_manifest_parser.return_value.parse.return_value = manifest
        mock_cert_parser.looks_like_cert.side_effect = [
            True, False, False, False
        ]
        mock_cert_parser.return_value.parse.return_value = cert
        mock_dex_parser.looks_like_dex.side_effect = [True, False, False]
        mock_dex_parser.return_value.parse.return_value = dex
        mock_aapt.get_app_name.return_value = "any-app-name"

        apk = ApkParser().parse("any-file-path", extended_processing=True)

        mock_mkdtemp.assert_called_with(".ninjadroid")
        mock_zipfile.assert_called_with("any-file-path")
        mock_rmtree.assert_called_with(tmp_directory)
        assert_file_equal(self, expected=file, actual=apk)
        self.assert_apk_equal(apk=apk,
                              app_name="any-app-name",
                              manifest=manifest,
                              cert=cert,
                              dex_files=[dex],
                              other_files=[resource])
示例#6
0
    def test_parse_when_no_file_present(self, mock_file_parser, mock_zipfile,
                                        mock_mkdtemp, mock_rmtree):
        tmp_directory = Mock()
        mock_file_parser.is_zip_file.return_value = True
        mock_file_parser.return_value.parse.return_value = any_file()
        mock_zipfile.return_value.__enter__.return_value.namelist.return_value = []
        mock_mkdtemp.return_value = tmp_directory

        with self.assertRaises(ApkParsingError):
            ApkParser().parse("any-file-path", extended_processing=False)
        mock_rmtree.assert_called_with(tmp_directory)
    def test_parse_when_minidom_fails_without_apk_path(self, mock_file,
                                                       mock_file_parser,
                                                       mock_minidom):
        file = any_file(filename="AndroidManifest.xml")
        mock_parser_instance = any_file_parser(file=file)
        mock_file_parser.return_value = mock_parser_instance
        mock_minidom.parse.side_effect = ExpatError()

        with self.assertRaises(AndroidManifestParsingError):
            self.sut.parse(filepath="any-file-path",
                           binary=False,
                           apk_path=None,
                           extended_processing=False)
    def test_parse_when_minidom_fails_with_apk_path_and_extended_processing(
            self, mock_file, mock_file_parser, mock_minidom, mock_aapt):
        file = any_file(filename="AndroidManifest.xml")
        mock_parser_instance = any_file_parser(file=file)
        mock_file_parser.return_value = mock_parser_instance
        mock_minidom.parse.side_effect = ExpatError()
        mock_aapt.get_apk_info.return_value = self.any_aapt_apk_info(
            package_name="any-package-name",
            version_code=1,
            version_name="any-version-name",
            sdk_max="20",
            sdk_min="10",
            sdk_target="15")
        mock_aapt.get_app_permissions.return_value = [
            "any-permission-0", "any-permission-1", "any-permission-2"
        ]
        mock_aapt.get_manifest_info.return_value = self.any_aapt_manifest_info(
            activities=["any-activity-name"],
            services=["any-service-name"],
            receivers=["any-broadcast-receiver-name"])

        manifest = self.sut.parse(filepath="any-file-path",
                                  binary=False,
                                  apk_path="any_apk_path",
                                  extended_processing=True)

        assert_file_parser_called_once_with(mock_parser_instance,
                                            filepath="any-file-path",
                                            filename="AndroidManifest.xml")
        mock_file.assert_called_with("any-file-path", "rb")
        mock_minidom.parse.assert_called_with("any-file-path")
        mock_aapt.get_apk_info.assert_called_with("any_apk_path")
        mock_aapt.get_app_permissions.assert_called_with("any_apk_path")
        mock_aapt.get_manifest_info.assert_called_with("any_apk_path")
        assert_file_equal(self, expected=file, actual=manifest)
        self.assert_manifest_equal(
            manifest=manifest,
            package_name="any-package-name",
            version=AppVersion(code=1, name="any-version-name"),
            sdk=AppSdk(min_version="10", target_version="15",
                       max_version="20"),
            permissions=[
                "any-permission-0", "any-permission-1", "any-permission-2"
            ],
            activities=[AppActivity(name="any-activity-name")],
            services=[AppService(name="any-service-name")],
            receivers=[
                AppBroadcastReceiver(name="any-broadcast-receiver-name")
            ])
示例#9
0
    def test_file_as_dict(self):
        file = any_file(filename="any-file-name",
                        size=10,
                        md5="any-file-md5",
                        sha1="any-file-sha1",
                        sha256="any-file-sha256",
                        sha512="any-file-sha512")

        result = file.as_dict()

        self.assertEqual(
            {
                "file": "any-file-name",
                "size": 10,
                "md5": "any-file-md5",
                "sha1": "any-file-sha1",
                "sha256": "any-file-sha256",
                "sha512": "any-file-sha512",
            }, result)
    def test_parse_binary(self, mock_file, mock_file_parser, mock_axmlprinter,
                          mock_minidom):
        file = any_file(filename="AndroidManifest.xml")
        mock_parser_instance = any_file_parser(file=file)
        mock_file_parser.return_value = mock_parser_instance
        mock_axmlprinter.return_value = self.any_axmlprinter()
        mock_minidom.parseString.return_value = self.any_axmlprinter_xml(
            package_name="any-package-name",
            version_code="1",
            version_name="any-version-name",
            sdk_max="20",
            sdk_min="10",
            sdk_target="15",
            permissions=[
                "any-permission-1", "any-permission-2", "any-permission-0"
            ])

        manifest = self.sut.parse(filepath="any-file-path",
                                  binary=True,
                                  apk_path=None,
                                  extended_processing=False)

        assert_file_parser_called_once_with(mock_parser_instance,
                                            filepath="any-file-path",
                                            filename="AndroidManifest.xml")
        mock_file.assert_called_with("any-file-path", "rb")
        mock_axmlprinter.assert_called_with(ANY)
        mock_minidom.parseString.assert_called_with("any-axml-raw-value")
        assert_file_equal(self, expected=file, actual=manifest)
        self.assert_manifest_equal(manifest=manifest,
                                   package_name="any-package-name",
                                   version=AppVersion(code=1,
                                                      name="any-version-name"),
                                   sdk=AppSdk(min_version="10",
                                              target_version="15",
                                              max_version="20"),
                                   permissions=[
                                       "any-permission-0", "any-permission-1",
                                       "any-permission-2"
                                   ],
                                   activities=[],
                                   services=[],
                                   receivers=[])
示例#11
0
    def test_parse(self, mock_file_parser, mock_popen, mock_uri_signature,
                   mock_shell_signature):
        file = any_file()
        mock_parser_instance = any_file_parser(file=file)
        mock_file_parser.return_value = mock_parser_instance
        mock_popen.return_value = any_popen(
            b"any-string\nany-url\nany-command")
        mock_uri_signature.return_value = self.any_signature(
            matches=[(None, False), ("any-url", True), (None, False)])
        mock_shell_signature.return_value = self.any_signature(
            matches=[(None, False), (None, False), ("any-command", True)])

        dex = DexParser().parse("any-file-path", "any-file-name")

        assert_file_parser_called_once_with(mock_parser_instance,
                                            filepath="any-file-path",
                                            filename="any-file-name")
        assert_popen_called_once_with(mock_popen, "strings any-file-path")
        assert_file_equal(self, expected=file, actual=dex)
        self.assertEqual(["any-command", "any-string", "any-url"],
                         dex.get_strings())
        self.assertEqual(["any-url"], dex.get_urls())
        self.assertEqual(["any-command"], dex.get_shell_commands())
        self.assertEqual([], dex.get_custom_signatures())
示例#12
0
    def test_init(self, mock_file_parser, mock_get_localzone, mock_popen):
        file = any_file()
        mock_parser_instance = any_file_parser(file=file)
        mock_file_parser.return_value = mock_parser_instance
        mock_popen.return_value = any_popen(
            response=b"Owner: CN=OwnerName, OU=OwnerUnit, O=OwnerOrganization, L=OwnerCity, ST=OwnerState, C=OwnerCountry\n" \
                     b"Issuer: CN=IssuerName, OU=IssuerUnit, O=IssuerOrganization, L=IssuerCity, ST=IssuerState, C=IssuerCountry\n" \
                     b"Serial number: 558e7595\n" \
                     b"Valid from: Sat Jun 27 12:06:13 CEST 2015 until: Tue Feb 26 11:06:13 CET 2515\n" \
                     b"Certificate fingerprints:\n" \
                     b"\t MD5: 90:22:EF:0C:DB:C3:78:87:7B:C3:A3:6C:5A:68:E6:45\n" \
                     b"\t SHA1: 5A:C0:6C:32:63:7F:5D:BE:CA:F9:38:38:4C:FA:FF:ED:20:52:43:B6\n" \
                     b"\t SHA256: E5:15:CC:BC:5E:BF:B2:9D:A6:13:03:63:CF:19:33:FA:CE:AF:DC:ED:5D:2F:F5:98:7C:CE:37:13:64:4A:CF:77\n" \
                     b"Signature algorithm name: SHA1withRSA\n" \
                     b"Subject Public Key Algorithm: 1024-bit RSA key\n" \
                     b"Version: 3"
        )
        mock_get_localzone.return_value.localize.side_effect = ValueError()

        cert = self.sut.parse("any-file-path", "any-file-name")

        assert_file_parser_called_once_with(mock_parser_instance, filepath="any-file-path", filename="any-file-name")
        assert_popen_called_once_with(mock_popen, "keytool -printcert -file any-file-path")
        assert_file_equal(self, expected=file, actual=cert)
        self.assertEqual("558e7595", cert.get_serial_number())
        self.assertEqual(
            CertValidity(valid_from="Sat Jun 27 12:06:13 CEST 2015", valid_to="Tue Feb 26 11:06:13 CET 2515"),
            cert.get_validity()
        )
        self.assertEqual(
            CertFingerprint(
                md5="90:22:EF:0C:DB:C3:78:87:7B:C3:A3:6C:5A:68:E6:45",
                sha1="5A:C0:6C:32:63:7F:5D:BE:CA:F9:38:38:4C:FA:FF:ED:20:52:43:B6",
                sha256="E5:15:CC:BC:5E:BF:B2:9D:A6:13:03:63:CF:19:33:FA:CE:AF:DC:ED:5D:2F:F5:98:7C:CE:37:13:64:4A:CF:77",
                signature="SHA1withRSA",
                version="3"
            ),
            cert.get_fingerprint()
        )
        self.assertEqual(
            CertParticipant(
                name="OwnerName",
                email="",
                unit="OwnerUnit",
                organization="OwnerOrganization",
                city="OwnerCity",
                state="OwnerState",
                country="OwnerCountry",
                domain=""
            ),
            cert.get_owner()
        )
        self.assertEqual(
            CertParticipant(
                name="IssuerName",
                email="",
                unit="IssuerUnit",
                organization="IssuerOrganization",
                city="IssuerCity",
                state="IssuerState",
                country="IssuerCountry",
                domain=""
            ),
            cert.get_issuer()
        )
示例#13
0
    def test_apk_as_dict(self):
        apk = APK(
            filename="any-apk-file-name",
            size=10,
            md5hash="any-apk-file-md5",
            sha1hash="any-apk-file-sha1",
            sha256hash="any-apk-file-sha256",
            sha512hash="any-apk-file-sha512",
            app_name="any-app-name",
            cert=Cert(
                filename="any-cert-file-name",
                size=20,
                md5hash="any-cert-file-md5",
                sha1hash="any-cert-file-sha1",
                sha256hash="any-cert-file-sha256",
                sha512hash="any-cert-file-sha512",
                serial_number="any-cert-serial-number",
                validity=CertValidity(
                    valid_from="any-cert-validity-from",
                    valid_to="any-cert-validity-to"
                ),
                fingerprint=CertFingerprint(
                    md5="any-cert-fingerprint-md5",
                    sha1="any-cert-fingerprint-sha1",
                    sha256="any-cert-fingerprint-sha256",
                    signature="any-cert-fingerprint-signature",
                    version="any-cert-fingerprint-version"
                ),
                owner=CertParticipant(
                    name="any-cert-owner-name",
                    email="any-cert-owner-email",
                    unit="any-cert-owner-unit",
                    organization="any-cert-owner-organization",
                    city="any-cert-owner-city",
                    state="any-cert-owner-state",
                    country="any-cert-owner-country",
                    domain="any-cert-owner-domain"
                ),
                issuer=CertParticipant(
                    name="any-cert-issuer-name",
                    email="any-cert-issuer-email",
                    unit="any-cert-issuer-unit",
                    organization="any-cert-issuer-organization",
                    city="any-cert-issuer-city",
                    state="any-cert-issuer-state",
                    country="any-cert-issuer-country",
                    domain="any-cert-issuer-domain"
                )
            ),
            manifest=AndroidManifest(
                filename="any-manifest-file-name",
                size=30,
                md5hash="any-manifest-file-md5",
                sha1hash="any-manifest-file-sha1",
                sha256hash="any-manifest-file-sha256",
                sha512hash="any-manifest-file-sha512",
                package_name="any-package-name",
                version=AppVersion(code=1, name="any-version-name"),
                sdk=AppSdk(min_version="10", target_version="15", max_version="20"),
                permissions=[],
                activities=[],
                services=[],
                receivers=[]
            ),
            dex_files=[
                Dex(
                    filename="any-dex-file-name",
                    size=40,
                    md5hash="any-dex-file-md5",
                    sha1hash="any-dex-file-sha1",
                    sha256hash="any-dex-file-sha256",
                    sha512hash="any-dex-file-sha512",
                    strings=[],
                    urls=[],
                    shell_commands=[],
                    custom_signatures=[]
                )
            ],
            other_files=[
                any_file(
                    filename="any-resource-file-name",
                    size=50,
                    md5="any-resource-file-md5",
                    sha1="any-resource-file-sha1",
                    sha256="any-resource-file-sha256",
                    sha512="any-resource-file-sha512"
                )
            ]
        )

        result = apk.as_dict()

        self.assertEqual(
            {
                "file": "any-apk-file-name",
                "size": 10,
                "md5": "any-apk-file-md5",
                "sha1": "any-apk-file-sha1",
                "sha256": "any-apk-file-sha256",
                "sha512": "any-apk-file-sha512",
                "name": "any-app-name",
                "cert": {
                    "file": "any-cert-file-name",
                    "size": 20,
                    "md5": "any-cert-file-md5",
                    "sha1": "any-cert-file-sha1",
                    "sha256": "any-cert-file-sha256",
                    "sha512": "any-cert-file-sha512",
                    "serial_number": "any-cert-serial-number",
                    "validity": {
                        "from": "any-cert-validity-from",
                        "until": "any-cert-validity-to"
                    },
                    "fingerprint": {
                        "md5": "any-cert-fingerprint-md5",
                        "sha1": "any-cert-fingerprint-sha1",
                        "sha256": "any-cert-fingerprint-sha256",
                        "signature": "any-cert-fingerprint-signature",
                        "version": "any-cert-fingerprint-version"
                    },
                    "owner": {
                        "name": "any-cert-owner-name",
                        "email": "any-cert-owner-email",
                        "unit": "any-cert-owner-unit",
                        "organization": "any-cert-owner-organization",
                        "city": "any-cert-owner-city",
                        "state": "any-cert-owner-state",
                        "country": "any-cert-owner-country",
                        "domain": "any-cert-owner-domain"
                    },
                    "issuer": {
                        "name": "any-cert-issuer-name",
                        "email": "any-cert-issuer-email",
                        "unit": "any-cert-issuer-unit",
                        "organization": "any-cert-issuer-organization",
                        "city": "any-cert-issuer-city",
                        "state": "any-cert-issuer-state",
                        "country": "any-cert-issuer-country",
                        "domain": "any-cert-issuer-domain"
                    }
                },
                "manifest": {
                    "file": "any-manifest-file-name",
                    "size": 30,
                    "md5": "any-manifest-file-md5",
                    "sha1": "any-manifest-file-sha1",
                    "sha256": "any-manifest-file-sha256",
                    "sha512": "any-manifest-file-sha512",
                    "package": "any-package-name",
                    "version": {
                        "code": 1,
                        "name": "any-version-name"
                    },
                    "sdk": {
                        "min": "10",
                        "target": "15",
                        "max": "20"
                    },
                    "permissions": []
                },
                "dex": [
                    {
                        "file": "any-dex-file-name",
                        "size": 40,
                        "md5": "any-dex-file-md5",
                        "sha1": "any-dex-file-sha1",
                        "sha256": "any-dex-file-sha256",
                        "sha512": "any-dex-file-sha512",
                        "strings": [],
                        "urls": [],
                        "shell_commands": []
                    }
                ],
                "other": [
                    {
                        "file": "any-resource-file-name",
                        "size": 50,
                        "md5": "any-resource-file-md5",
                        "sha1": "any-resource-file-sha1",
                        "sha256": "any-resource-file-sha256",
                        "sha512": "any-resource-file-sha512",
                    }
                ]
            },
            result
        )