Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion objection/console/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ def version() -> None:
@click.option('--script-source', '-l', default=None, help=(
'A script file to use with the the "path" config type. '
'Remember that use the name of this file in your "path". It will be next to the config.'), show_default=False)
@click.option('--bundle-id', '-b', default=None, help='The bundleid to set when codesigning the IPA')
@click.option('--bundle-id', '-B', default=None, help='The bundleid to set when codesigning the IPA')
def patchipa(source: str, gadget_version: str, codesign_signature: str, provision_file: str, binary_name: str,
skip_cleanup: bool, pause: bool, unzip_unicode: bool, gadget_config: str, script_source: str,
bundle_id: str) -> None:
Expand Down
13 changes: 13 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ Homepage = "https://github.com/sensepost/objection"
Repository = "https://github.com/sensepost/objection"
"Bug Tracker" = "https://github.com/sensepost/objection/issues"

[project.optional-dependencies]
test = [
"pytest>=7.0.0",
"pytest-cov>=4.0.0",
]

[project.scripts]
objection = "objection.console.cli:cli"

Expand All @@ -55,3 +61,10 @@ objection = [
"utils/assets/*.xml",
"agent.js",
]

[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = "test_*.py"
python_classes = "Test*"
python_functions = "test_*"
addopts = "-v --strict-markers"
16 changes: 8 additions & 8 deletions tests/commands/android/test_keystore.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from unittest import mock

from objection.commands.android.keystore import entries, clear
from ...helpers import capture
from ...helpers import capture, normalize_table_whitespace


class TestKeystore(unittest.TestCase):
Expand All @@ -13,11 +13,11 @@ def test_entries_handles_empty_data(self, mock_api):
with capture(entries, []) as o:
output = o

expected_output = """Alias Key Certificate
------- ----- -------------
expected_output = """Alias Key Certificate
----- --- -----------
"""

self.assertEqual(output, expected_output)
self.assertEqual(normalize_table_whitespace(output), normalize_table_whitespace(expected_output))

@mock.patch('objection.state.connection.state_connection.get_api')
def test_entries_handles(self, mock_api):
Expand All @@ -30,12 +30,12 @@ def test_entries_handles(self, mock_api):
with capture(entries, []) as o:
output = o

expected_output = """Alias Key Certificate
------- ----- -------------
test True True
expected_output = """Alias Key Certificate
----- ---- -----------
test True True
"""

self.assertEqual(output, expected_output)
self.assertEqual(normalize_table_whitespace(output), normalize_table_whitespace(expected_output))

@mock.patch('objection.state.connection.state_connection.get_api')
@mock.patch('objection.commands.android.keystore.click.confirm')
Expand Down
24 changes: 12 additions & 12 deletions tests/commands/ios/test_bundles.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from objection.commands.ios.bundles import show_frameworks, _should_include_apple_bundles, _should_print_full_path, \
_is_apple_bundle, show_bundles
from ...helpers import capture
from ...helpers import capture, normalize_table_whitespace


class TestBundles(unittest.TestCase):
Expand Down Expand Up @@ -76,7 +76,7 @@ def test_show_frameworks_prints_without_apple_bundles(self, mock_api):
MapKit za.apple.MapKit 1 /MapKit
"""

self.assertEqual(output, expected)
self.assertEqual(normalize_table_whitespace(output), normalize_table_whitespace(expected))

@mock.patch('objection.state.connection.state_connection.get_api')
def test_show_frameworks_prints_with_apple_bundles(self, mock_api):
Expand All @@ -93,7 +93,7 @@ def test_show_frameworks_prints_with_apple_bundles(self, mock_api):
MapKit za.apple.MapKit 1 /MapKit
"""

self.assertEqual(output, expected)
self.assertEqual(normalize_table_whitespace(output), normalize_table_whitespace(expected))

@mock.patch('objection.state.connection.state_connection.get_api')
def test_show_frameworks_prints_with_apple_bundles_and_full_paths(self, mock_api):
Expand All @@ -110,7 +110,7 @@ def test_show_frameworks_prints_with_apple_bundles_and_full_paths(self, mock_api
MapKit za.apple.MapKit 1 /MapKit
"""

self.assertEqual(output, expected)
self.assertEqual(normalize_table_whitespace(output), normalize_table_whitespace(expected))

@mock.patch('objection.state.connection.state_connection.get_api')
def test_show_bundles_prints_bundles(self, mock_api):
Expand All @@ -119,15 +119,15 @@ def test_show_bundles_prints_bundles(self, mock_api):
with capture(show_bundles, []) as o:
output = o

expected = """Executable Bundle Version Path
------------------------ ---------------------------------- --------- -------------------------------------------
AppleIDSSOAuthentication com.apple.AppleIDSSOAuthentication 1 /AppleIDSSOAuthentication
LinguisticData com.apple.LinguisticData 1 ...nguisticDataLinguisticDataLinguisticData
hockeyapp net.hockeyapp.sdk.ios 1 /hockeyapp
MapKit za.apple.MapKit 1 /MapKit
expected = """Executable Bundle Version Path
------------------------ ---------------------------------- ------- ------------------------------------------------------------------------
AppleIDSSOAuthentication com.apple.AppleIDSSOAuthentication 1 /AppleIDSSOAuthentication
LinguisticData com.apple.LinguisticData 1 /LinguisticData/LinguisticDataLinguisticDataLinguisticDataLinguisticData
hockeyapp net.hockeyapp.sdk.ios 1 /hockeyapp
MapKit za.apple.MapKit 1 /MapKit
"""

self.assertEqual(output, expected)
self.assertEqual(normalize_table_whitespace(output), normalize_table_whitespace(expected))

@mock.patch('objection.state.connection.state_connection.get_api')
def test_show_bundles_prints_bundles(self, mock_api):
Expand All @@ -144,4 +144,4 @@ def test_show_bundles_prints_bundles(self, mock_api):
MapKit za.apple.MapKit 1 /MapKit
"""

self.assertEqual(output, expected)
self.assertEqual(normalize_table_whitespace(output), normalize_table_whitespace(expected))
10 changes: 5 additions & 5 deletions tests/commands/ios/test_cookies.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from unittest import mock

from objection.commands.ios.cookies import get
from ...helpers import capture
from ...helpers import capture, normalize_table_whitespace


class TestCookies(unittest.TestCase):
Expand Down Expand Up @@ -30,9 +30,9 @@ def test_get(self, mock_api):
with capture(get, []) as o:
output = o

expected_output = """Name Value Expires Domain Path Secure HTTPOnly
------ ------- ------------------------- -------- ------ -------- ----------
foo bar 01-01-1970 00:00:00 +0000 foo.com / false true
expected_output = """Name Value Expires Domain Path Secure HTTPOnly
---- ----- ------------------------- ------- ---- ------ --------
foo bar 01-01-1970 00:00:00 +0000 foo.com / false true
"""

self.assertEqual(output, expected_output)
self.assertEqual(normalize_table_whitespace(output), normalize_table_whitespace(expected_output))
18 changes: 9 additions & 9 deletions tests/commands/ios/test_keychain.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from objection.commands.ios.keychain import _should_output_json, dump, dump_raw, clear, add, \
_data_flag_has_identifier, _get_flag_value, _should_do_smart_decode
from ...helpers import capture
from ...helpers import capture, normalize_table_whitespace


class TestKeychain(unittest.TestCase):
Expand Down Expand Up @@ -68,10 +68,10 @@ def test_dump_to_screen_handles_empty_data(self, mock_api):
expected_output = """Note: You may be asked to authenticate using the devices passcode or TouchID
Save the output by adding `--json keychain.json` to this command
Dumping the iOS keychain...
Created Accessible ACL Type Account Service Data
--------- ------------ ----- ------ --------- --------- ------
Created Accessible ACL Type Account Service Data
------- ---------- --- ---- ------- ------- ----
"""
self.assertEqual(output, expected_output)
self.assertEqual(normalize_table_whitespace(output), normalize_table_whitespace(expected_output))

@mock.patch('objection.state.connection.state_connection.get_api')
def test_dump_to_screen(self, mock_api):
Expand All @@ -87,11 +87,11 @@ def test_dump_to_screen(self, mock_api):
expected_output = """Note: You may be asked to authenticate using the devices passcode or TouchID
Save the output by adding `--json keychain.json` to this command
Dumping the iOS keychain...
Created Accessible ACL Type Account Service Data
--------- ------------ ----- ------ --------- --------- ------
now None None foo foo bar
Created Accessible ACL Type Account Service Data
------- ---------- ---- ---- ------- ------- ----
now None None foo foo bar
"""
self.assertEqual(output, expected_output)
self.assertEqual(normalize_table_whitespace(output), normalize_table_whitespace(expected_output))

@mock.patch('objection.state.connection.state_connection.get_api')
def test_dump_raw(self, mock_api):
Expand Down Expand Up @@ -141,7 +141,7 @@ def test_adds_item_validates_data_key_to_need_identifier(self):
with capture(add, ['--data', 'test_data']) as o:
output = o

self.assertEqual(output, 'When specifying the --data flag, either --account or --server should also be added\n')
self.assertEqual(output, 'When specifying the --data flag, either --account or --service should also be added\n')

@mock.patch('objection.state.connection.state_connection.get_api')
def test_adds_item_successfully(self, mock_api):
Expand Down
10 changes: 5 additions & 5 deletions tests/commands/ios/test_nsurlcredentialstorage.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from unittest import mock

from objection.commands.ios.nsurlcredentialstorage import dump
from ...helpers import capture
from ...helpers import capture, normalize_table_whitespace


class TestNsusercredentialstorage(unittest.TestCase):
Expand All @@ -20,9 +20,9 @@ def test_dump(self, mock_api):
with capture(dump, []) as o:
output = o

expected_output = """Protocol Host Port Authentication Method User Password
---------- ------- ------ ----------------------- ------ ----------
https foo.bar 80 Default foo bar
expected_output = """Protocol Host Port Authentication Method User Password
-------- ------- ---- --------------------- ---- --------
https foo.bar 80 Default foo bar
"""

self.assertEqual(output, expected_output)
self.assertEqual(normalize_table_whitespace(output), normalize_table_whitespace(expected_output))
57 changes: 33 additions & 24 deletions tests/commands/test_filemanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
_pwd_android, ls, _ls_ios, _ls_android, download, _download_ios, _download_android, upload, rm, _rm_android
from objection.state.device import device_state, Ios, Android
from objection.state.filemanager import file_manager_state
from ..helpers import capture
from ..helpers import capture, normalize_table_whitespace


class TestFileManager(unittest.TestCase):
Expand Down Expand Up @@ -278,13 +278,16 @@ def test_lists_readable_ios_directory_using_helper_method(self, mock_api):
output = o

expected_outut = """NSFileType Perms NSFileProtection Read Write Owner Group Size Creation Name
------------ ------- ------------------ ------ ------- ------- ------- --------- ---------- ------
A B C True False D (E) F (G) 115.4 GiB H test
------------ ------- ------------------ ------ ------- ------- ------- --------- ---------- ------
A B C True False D (E) F (G) 115.4 GiB H test

Readable: True Writable: False
"""
Readable: True Writable: False
"""

self.assertEqual(output, expected_outut)
self.assertEqual(
normalize_table_whitespace(output),
normalize_table_whitespace(expected_outut),
)

@mock.patch('objection.state.connection.state_connection.get_api')
def test_lists_readable_ios_directory_using_helper_method_no_attributes(self, mock_api):
Expand All @@ -306,13 +309,16 @@ def test_lists_readable_ios_directory_using_helper_method_no_attributes(self, mo
output = o

expected_outut = """NSFileType Perms NSFileProtection Read Write Owner Group Size Creation Name
------------ ------- ------------------ ------ ------- --------- --------- ------ ---------- ------
n/a n/a n/a True True n/a (n/a) n/a (n/a) n/a n/a test
------------ ------- ------------------ ------ ------- --------- --------- ------ ---------- ------
n/a n/a n/a True True n/a (n/a) n/a (n/a) n/a n/a test

Readable: True Writable: True
"""
Readable: True Writable: True
"""

self.assertEqual(output, expected_outut)
self.assertEqual(
normalize_table_whitespace(output),
normalize_table_whitespace(expected_outut),
)

@mock.patch('objection.state.connection.state_connection.get_api')
def test_lists_unreadable_ios_directory_using_helper_method(self, mock_api):
Expand Down Expand Up @@ -354,13 +360,16 @@ def test_lists_readable_android_directory_using_helper_method(self, mock_api):
output = o

expected_outut = """Type Last Modified Read Write Hidden Size Name
------ ----------------------- ------ ------- -------- ------- ------
File 2017-10-05 07:36:41 GMT True True False 249.0 B test
------ ----------------------- ------ ------- -------- ------- ------
File 2017-10-05 07:36:41 GMT True True False 249.0 B test

Readable: True Writable: True
"""
Readable: True Writable: True
"""

self.assertEqual(output, expected_outut)
self.assertEqual(
normalize_table_whitespace(output),
normalize_table_whitespace(expected_outut),
)

@mock.patch('objection.state.connection.state_connection.get_api')
def test_lists_unreadable_android_directory_using_helper_method(self, mock_api):
Expand Down Expand Up @@ -407,7 +416,7 @@ def test_downloads_file_with_ios_helper(self, mock_open, mock_api):

file_manager_state.cwd = '/foo'

with capture(_download_ios, '/foo', '/bar') as o:
with capture(_download_ios, '/foo', '/bar', False) as o:
output = o

expected_output = """Downloading /foo to /bar
Expand All @@ -423,7 +432,7 @@ def test_downloads_file_with_ios_helper(self, mock_open, mock_api):
def test_downloads_file_but_fails_on_unreadable_with_ios_helper(self, mock_api):
mock_api.return_value.ios_file_readable.return_value = False

with capture(_download_ios, '/foo', '/bar') as o:
with capture(_download_ios, '/foo', '/bar', False) as o:
output = o

self.assertEqual(output, 'Downloading /foo to /bar\nUnable to download file. File is not readable.\n')
Expand All @@ -433,10 +442,10 @@ def test_downloads_file_but_fails_on_file_type_with_ios_helper(self, mock_api):
mock_api.return_value.ios_file_readable.return_value = True
mock_api.return_value.ios_file_path_is_file.return_value = False

with capture(_download_ios, '/foo', '/bar') as o:
with capture(_download_ios, '/foo', '/bar', False) as o:
output = o

self.assertEqual(output, 'Downloading /foo to /bar\nUnable to download file. Target path is not a file.\n')
self.assertEqual(output, 'Downloading /foo to /bar\nTo download folders, specify --folder.\n')

@mock.patch('objection.state.connection.state_connection.get_api')
@mock.patch('objection.commands.filemanager.open', create=True)
Expand All @@ -447,7 +456,7 @@ def test_downloads_file_with_android_helper(self, mock_open, mock_api):

file_manager_state.cwd = '/foo'

with capture(_download_android, '/foo', '/bar') as o:
with capture(_download_android, '/foo', '/bar', False) as o:
output = o

expected = """Downloading /foo to /bar
Expand All @@ -466,7 +475,7 @@ def test_downloads_file_but_fails_on_unreadable_with_android_helper(self, mock_o

file_manager_state.cwd = '/foo'

with capture(_download_android, '/foo', '/bar') as o:
with capture(_download_android, '/foo', '/bar', False) as o:
output = o

self.assertFalse(mock_open.called)
Expand All @@ -480,11 +489,11 @@ def test_downloads_file_but_fails_on_file_type_with_android_helper(self, mock_op

file_manager_state.cwd = '/foo'

with capture(_download_android, '/foo', '/bar') as o:
with capture(_download_android, '/foo', '/bar', False) as o:
output = o

self.assertFalse(mock_open.called)
self.assertEqual(output, 'Downloading /foo to /bar\nUnable to download file. Target path is not a file.\n')
self.assertEqual(output, 'Downloading /foo to /bar\nTo download folders, specify --folder.\n')

def test_file_upload_method_proxy_validates_arguments(self):
with capture(upload, []) as o:
Expand Down
Loading
Loading