def test(): # Launch the server. port = random.randint(30000, 45000) command = ['python', 'slow_retrieval_server.py', str(port)] server_process = subprocess.Popen(command, stderr=subprocess.PIPE) time.sleep(.1) try: root_repo, url, server_proc, keyids = util_test_tools.init_repo(tuf=True) reg_repo = os.path.join(root_repo, 'reg_repo') # Make a file in 'reg_repo'. filepath = util_test_tools.add_file_to_repository(reg_repo, 'Test') # Path of the file relative to 'root_repo'. relative_filepath = os.path.relpath(filepath) # Tailor the url. url_to_file = 'http://localhost:'+str(port)+'/'+relative_filepath # Download the content of the file using the server. file_content = urllib.urlopen(url_to_file) print file_content.read() finally: if server_process.returncode is None: server_process.kill() print 'Slow server terminated.\n' util_test_tools.cleanup(root_repo, server_proc)
def test_arbitrary_package_attack(TUF=False): """ <Arguments> TUF: If set to 'False' all directories that start with 'tuf_' are ignored, indicating that tuf is not implemented. <Purpose> Illustrate arbitrary package attack vulnerability. """ ERROR_MSG = 'Arbitrary Package Attack was Successful!\n' try: # Setup. root_repo, url, server_proc, keyids = util_test_tools.init_repo(tuf=TUF) reg_repo = os.path.join(root_repo, 'reg_repo') tuf_repo = os.path.join(root_repo, 'tuf_repo') downloads = os.path.join(root_repo, 'downloads') targets_dir = os.path.join(tuf_repo, 'targets') # Add a file to 'repo' directory: {root_repo} filepath = util_test_tools.add_file_to_repository(reg_repo, 'Test A') file_basename = os.path.basename(filepath) url_to_repo = url+'reg_repo/'+file_basename downloaded_file = os.path.join(downloads, file_basename) if TUF: # Update TUF metadata before attacker modifies anything. util_test_tools.tuf_refresh_repo(root_repo, keyids) # Modify the url. Remember that the interposition will intercept # urls that have 'localhost:9999' hostname, which was specified in # the json interposition configuration file. Look for 'hostname' # in 'util_test_tools.py'. Further, the 'file_basename' is the target # path relative to 'targets_dir'. url_to_repo = 'http://localhost:9999/'+file_basename # Attacker modifies the file at the targets repository. target = os.path.join(targets_dir, file_basename) util_test_tools.modify_file_at_repository(target, 'Evil A') # Attacker modifies the file at the regular repository. util_test_tools.modify_file_at_repository(filepath, 'Evil A') # End of Setup. try: # Client downloads (tries to download) the file. _download(url=url_to_repo, filename=downloaded_file, tuf=TUF) except tuf.DownloadError: # If tuf.DownloadError is raised, this means that TUF has prevented # the download of an unrecognized file. Enable the logging to see, # what actually happened. pass else: # Check whether the attack succeeded by inspecting the content of the # update. The update should contain 'Test A'. Technically it suffices # to check whether the file was downloaded or not. downloaded_content = util_test_tools.read_file_content(downloaded_file) if 'Test A' != downloaded_content: raise ArbitraryPackageAlert(ERROR_MSG) finally: util_test_tools.cleanup(root_repo, server_proc)
def test_extraneous_dependency_attack(TUF=False): """ <Purpose> Illustrate arbitrary package attack vulnerability. <Arguments> TUF: If set to 'False' all directories that start with 'tuf_' are ignored, indicating that tuf is not implemented. """ ERROR_MSG = 'Extraneous Dependency Attack was Successful!\n' try: # Setup. root_repo, url, server_proc, keyids = util_test_tools.init_repo( tuf=TUF) reg_repo = os.path.join(root_repo, 'reg_repo') tuf_repo = os.path.join(root_repo, 'tuf_repo') downloads = os.path.join(root_repo, 'downloads') targets_dir = os.path.join(tuf_repo, 'targets') # Add files to 'repo' directory: {root_repo}. good_dependency_filepath = util_test_tools.add_file_to_repository( reg_repo, '') good_dependency_basename = os.path.basename(good_dependency_filepath) bad_dependency_filepath = util_test_tools.add_file_to_repository( reg_repo, '') bad_dependency_basename = os.path.basename(bad_dependency_filepath) # The dependent file lists the good dependency. dependent_filepath = util_test_tools.add_file_to_repository( reg_repo, good_dependency_basename) dependent_basename = os.path.basename(dependent_filepath) url_to_repo = url + 'reg_repo/' + dependent_basename modified_dependency_list = good_dependency_basename+','+\ bad_dependency_basename if TUF: # Update TUF metadata before attacker modifies anything. util_test_tools.tuf_refresh_repo(root_repo, keyids) # Modify the url. Remember that the interposition will intercept # urls that have 'localhost:9999' hostname, which was specified in # the json interposition configuration file. Look for 'hostname' # in 'util_test_tools.py'. Further, the 'file_basename' is the target # path relative to 'targets_dir'. url_to_repo = 'http://localhost:9999/' + dependent_basename # Attacker adds the dependency in the targets repository. target = os.path.join(targets_dir, dependent_basename) util_test_tools.modify_file_at_repository( target, modified_dependency_list) # Attacker adds the dependency in the regular repository. util_test_tools.modify_file_at_repository(dependent_filepath, modified_dependency_list) # End of Setup. try: # Client downloads (tries to download) the file. _download(url=url_to_repo, filename=dependent_basename, directory=downloads, TUF=TUF) except tuf.DownloadError: # If tuf.DownloadError is raised, this means that TUF has prevented # the download of an unrecognized file. Enable the logging to see, # what actually happened. pass else: # Check if the legitimate dependency was downloaded. if not (os.path.exists( os.path.join(downloads, good_dependency_basename))): raise tuf.DownloadError # Check if the extraneous dependency was downloaded. if os.path.exists(os.path.join(downloads, bad_dependency_basename)): raise ExtraneousDependencyAlert(ERROR_MSG) finally: util_test_tools.cleanup(root_repo, server_proc)
def test_arbitrary_package_attack(TUF=False): """ <Arguments> TUF: If set to 'False' all directories that start with 'tuf_' are ignored, indicating that tuf is not implemented. <Purpose> Illustrate endless data attack vulnerability. """ ERROR_MSG = 'Endless Data Attack was Successful!\n' try: # Setup. root_repo, url, server_proc, keyids = util_test_tools.init_repo( tuf=TUF) reg_repo = os.path.join(root_repo, 'reg_repo') tuf_repo = os.path.join(root_repo, 'tuf_repo') downloads = os.path.join(root_repo, 'downloads') tuf_targets = os.path.join(tuf_repo, 'targets') # Add a file to 'repo' directory: {root_repo} filepath = util_test_tools.add_file_to_repository(reg_repo, 'Test A') file_basename = os.path.basename(filepath) url_to_repo = url + 'reg_repo/' + file_basename downloaded_file = os.path.join(downloads, file_basename) endless_data = 'A' * 100 if TUF: # Update TUF metadata before attacker modifies anything. util_test_tools.tuf_refresh_repo(root_repo, keyids) # Modify the url. Remember that the interposition will intercept # urls that have 'localhost:9999' hostname, which was specified in # the json interposition configuration file. Look for 'hostname' # in 'util_test_tools.py'. Further, the 'file_basename' is the target # path relative to 'targets_dir'. url_to_repo = 'http://localhost:9999/' + file_basename # Attacker modifies the file at the targets repository. target = os.path.join(tuf_targets, file_basename) util_test_tools.modify_file_at_repository(target, endless_data) # Attacker modifies the file at the regular repository. util_test_tools.modify_file_at_repository(filepath, endless_data) # End Setup. try: # Client downloads (tries to download) the file. _download(url=url_to_repo, filename=downloaded_file, tuf=TUF) except tuf.DownloadError: # If tuf.DownloadError is raised, this means that TUF has prevented # the download of an unrecognized file. Enable the logging to see, # what actually happened. pass else: # Check whether the attack succeeded by inspecting the content of the # update. The update should contain 'Test A'. Technically it suffices # to check whether the file was downloaded or not. downloaded_content = util_test_tools.read_file_content( downloaded_file) if 'Test A' != downloaded_content: raise EndlessDataAttack(ERROR_MSG) finally: util_test_tools.cleanup(root_repo, server_proc)
def test_mix_and_match_attack(TUF=False): """ Attack design: There are 3 stages: Stage 1: Consists of a usual mode of operations using tuf. Client downloads a target file. (Initial download) Stage 2: The target file is legitimately modified and metadata correctly updated. Client downloads the target file again. (Patched target download) Stage 3: The target file is legitimately modified and metadata correctly updated again. However, before client gets to download the newly patched target file the attacker replaces the release metadata, targets metadata and the target file with the ones from stage 1 (mix-and-match attack). Note that timestamp metadata is untouched. Further note that same would happen if only target metadata, and target file are reverted. """ ERROR_MSG = '\tMix-And-Match Attack was Successful!\n\n' try: # Setup / Stage 1 # --------------- root_repo, url, server_proc, keyids = util_test_tools.init_repo(tuf=TUF) reg_repo = os.path.join(root_repo, 'reg_repo') downloads = os.path.join(root_repo, 'downloads') evil_dir = tempfile.mkdtemp(dir=root_repo) # Add file to 'repo' directory: {root_repo} filepath = util_test_tools.add_file_to_repository(reg_repo, 'A'*10) file_basename = os.path.basename(filepath) url_to_file = url+'reg_repo/'+file_basename downloaded_file = os.path.join(downloads, file_basename) # Attacker saves the initial file. shutil.copy(filepath, evil_dir) unpatched_file = os.path.join(evil_dir, file_basename) if TUF: print 'TUF ...' tuf_repo = os.path.join(root_repo, 'tuf_repo') tuf_targets = os.path.join(tuf_repo, 'targets') metadata_dir = os.path.join(tuf_repo, 'metadata') release_meta_file = os.path.join(metadata_dir, 'release.txt') targets_meta_file = os.path.join(metadata_dir, 'targets.txt') target = os.path.join(tuf_targets, file_basename) # Update TUF metadata before attacker modifies anything. util_test_tools.tuf_refresh_repo(root_repo, keyids) # Attacker saves the original metadata and the target file. #shutil.copy(target, evil_dir) shutil.copy(release_meta_file, evil_dir) shutil.copy(targets_meta_file, evil_dir) #target_old = os.path.join(evil_dir, file_basename) release_meta_file_old = os.path.join(evil_dir, 'release.txt') targets_meta_file_old = os.path.join(evil_dir, 'targets.txt') # Modify the url. Remember that the interposition will intercept # urls that have 'localhost:9999' hostname, which was specified in # the json interposition configuration file. Look for 'hostname' # in 'util_test_tools.py'. Further, the 'file_basename' is the target # path relative to 'targets_dir'. url_to_file = 'http://localhost:9999/'+file_basename # Client's initial download. _download(url=url_to_file, filename=downloaded_file, tuf=TUF) # Stage 2 # ------- # Developer patches the file and updates the repository. util_test_tools.modify_file_at_repository(filepath, 'B'*11) # Updating tuf repository. This will copy files from regular repository # into tuf repository and refresh the metadata if TUF: util_test_tools.tuf_refresh_repo(root_repo, keyids) # Client downloads the patched file. _download(url=url_to_file, filename=downloaded_file, tuf=TUF) downloaded_content = util_test_tools.read_file_content(downloaded_file) # Stage 3 # ------- # Developer patches the file and updates the repository again. util_test_tools.modify_file_at_repository(filepath, 'C'*10) # Updating tuf repository. This will copy files from regular repository # into tuf repository and refresh the metadata if TUF: util_test_tools.tuf_refresh_repo(root_repo, keyids) # Attacker replaces the metadata and the target file. shutil.copyfile(unpatched_file, target) shutil.copyfile(release_meta_file_old, release_meta_file) shutil.copyfile(targets_meta_file_old, targets_meta_file) # Attacker replaces the patched file with the unpatched one. shutil.copyfile(unpatched_file, filepath) # Client tries to downloads the newly patched file. try: _download(url=url_to_file, filename=downloaded_file, tuf=TUF) except tuf.MetadataNotAvailableError: pass # Check whether the attack succeeded by inspecting the content of the # update. The update should contain 'Test NOT A'. downloaded_content = util_test_tools.read_file_content(downloaded_file) if ('B'*11) != downloaded_content: raise MixAndMatchAttackAlert(ERROR_MSG) finally: util_test_tools.cleanup(root_repo, server_proc)
def tearDown(self): unittest.TestCase.tearDown(self) util_test_tools.cleanup(self.root_repo, self.server_proc)
def tearDown(self): util_test_tools.cleanup(self.root_repo, server_process=self.server_proc)
sys.exit(msg) # Expire timestamp. time.sleep(EXPIRATION) # Try downloading again, this should raise an error. try: _download(url=url_to_repo, filename=downloaded_file, tuf=TUF) except tuf.ExpiredMetadataError, error: pass else: raise IndefiniteFreezeAttackAlert(ERROR_MSG) finally: util_test_tools.cleanup(root_repo, server_proc) try: test_indefinite_freeze_attack(TUF=False) except IndefiniteFreezeAttackAlert, error: print error try: test_indefinite_freeze_attack(TUF=True) except IndefiniteFreezeAttackAlert, error: print error
def test_replay_attack(TUF=False): """ <Arguments> TUF: If set to 'False' all directories that start with 'tuf_' are ignored, indicating that tuf is not implemented. <Purpose> """ try: # Setup. root_repo, url, server_proc, keyids, interpose_json = \ util_test_tools.init_repo(tuf=TUF) reg_repo = os.path.join(root_repo, 'reg_repo') tuf_repo = os.path.join(root_repo, 'tuf_repo') downloads = os.path.join(root_repo, 'downloads') tuf_targets = os.path.join(tuf_repo, 'targets') # Add file to 'repo' directory: {root_repo} filepath = util_test_tools.add_file_to_repository(reg_repo, 'Test A') file_basename = os.path.basename(filepath) url_to_repo = url+'reg_repo/'+file_basename downloaded_file = os.path.join(downloads, file_basename) # Attacker saves the original file into 'evil_dir'. evil_dir = tempfile.mkdtemp(dir=root_repo) vulnerable_file = os.path.join(evil_dir, file_basename) shutil.copy(filepath, evil_dir) # Refresh the tuf repository and apply tuf interpose. if TUF: util_test_tools.tuf_refresh_repo(root_repo, keyids) tuf.interposition.configure(interpose_json) tuf.interposition.interpose() # End Setup. # Client performs initial update. urllib.urlretrieve(url_to_repo, downloaded_file) # Downloads are stored in the same directory '{root_repo}/downloads/' # for regular and tuf clients. downloaded_content = util_test_tools.read_file_content(downloaded_file) msg = '[Initial Updata] Failed to download the file.' if 'Test A' != downloaded_content: raise TestSetupError(msg) # Developer patches the file and updates the repository. util_test_tools.modify_file_at_repository(filepath, 'Test NOT A') # Updating tuf repository. This will copy files from regular repository # into tuf repository and refresh the metad if TUF: util_test_tools.tuf_refresh_repo(root_repo, keyids) # Client downloads the patched file. urllib.urlretrieve(url_to_repo, downloaded_file) # Content of the downloaded file. downloaded_content = util_test_tools.read_file_content(downloaded_file) msg = '[Update] Failed to update the file.' if 'Test NOT A' != downloaded_content: raise TestSetupError(msg) # Attacker tries to be clever, he manages to modifies regular and tuf # targets directory by replacing a patched file with an old one. if os.path.isdir(tuf_targets): target = os.path.join(tuf_targets, file_basename) util_test_tools.delete_file_at_repository(target) shutil.copy(vulnerable_file, tuf_targets) # Verify that 'target' is an old, un-patched file. target = os.path.join(tuf_targets, file_basename) target_content = util_test_tools.read_file_content(target) msg = "The 'target' file contains new data!" if 'Test A' != target_content: raise TestSetupError(msg) else: util_test_tools.delete_file_at_repository(filepath) shutil.copy(vulnerable_file, reg_repo) # Client downloads the file once time. urllib.urlretrieve(url_to_repo, downloaded_file) # Check whether the attack succeeded by inspecting the content of the # update. The update should contain 'Test NOT A'. downloaded_content = util_test_tools.read_file_content(downloaded_file) msg = 'Replay attack was successful!\n' if 'Test NOT A' != downloaded_content: raise ReplayAttackError(msg) finally: tuf.interposition.go_away() util_test_tools.cleanup(root_repo, server_proc)
def test_extraneous_dependencies_attack(): try: # Setup. root_repo, url, server_proc, keyids = util_test_tools.init_repo(tuf=True) reg_repo = os.path.join(root_repo, 'reg_repo') tuf_repo = os.path.join(root_repo, 'tuf_repo') keystore_dir = os.path.join(tuf_repo, 'keystore') metadata_dir = os.path.join(tuf_repo, 'metadata') downloads_dir = os.path.join(root_repo, 'downloads') targets_dir = os.path.join(tuf_repo, 'targets') # 'roles' holds information about delegated roles. roles = {'role1':{'password':['pass1']}, 'role2':{'password':['pass2']}} # Add files to 'reg_repo' directory: {root_repo} role1_path = tempfile.mkdtemp(dir=reg_repo) roles['role1']['filepath'] = \ util_test_tools.add_file_to_repository(role1_path, 'Test A') role2_path = tempfile.mkdtemp(dir=reg_repo) roles['role2']['filepath'] = \ util_test_tools.add_file_to_repository(role2_path, 'Test B') # Update TUF repository. util_test_tools.make_targets_meta(root_repo) util_test_tools.make_release_meta(root_repo) util_test_tools.make_timestamp_meta(root_repo) def _make_delegation(rolename): # Indicate which file client downloads. rel_filepath = os.path.relpath(roles[rolename]['filepath'], reg_repo) roles[rolename]['target_path'] = os.path.join(targets_dir, rel_filepath) rolepath, file_basename = os.path.split(roles[rolename]['filepath']) junk, role_relpath = os.path.split(rolepath) roles[rolename]['targets_dir'] = os.path.join(targets_dir, role_relpath) roles[rolename]['metadata_dir'] = os.path.join(metadata_dir, 'targets') # Create a key to sign a new delegated role. password = roles[rolename]['password'][0] key = signerlib.generate_and_save_rsa_key(keystore_dir, password) roles[rolename]['keyid'] = [key['keyid']] roles[rolename]['dest_path'] = os.path.join(downloads_dir, file_basename) # Create delegation one. util_test_tools.create_delegation(tuf_repo, roles[rolename]['targets_dir'], roles[rolename]['keyid'], password, 'targets', rolename) # Update TUF repository. # util_test_tools.make_targets_meta(root_repo) util_test_tools.make_release_meta(root_repo) util_test_tools.make_timestamp_meta(root_repo) # Modify the url. Remember that the interposition will intercept # urls that have 'localhost:9999' hostname, which was specified in # the json interposition configuration file. Look for 'hostname' # in 'util_test_tools.py'. Further, the 'file_basename' is the target # path relative to 'targets_dir'. roles[rolename]['url'] = 'http://localhost:9999/'+rel_filepath # Perform a client download. urllib_tuf.urlretrieve(roles[rolename]['url'], roles[rolename]['dest_path']) _make_delegation('role1') _make_delegation('role2') # The attack. # Modify a target that was delegated to 'role2'. util_test_tools.modify_file_at_repository(roles['role2']['target_path'], 'Test NOT B') # Load the keystore before rebuilding the metadata. tuf.repo.keystore.load_keystore_from_keyfiles(keystore_dir, roles['role1']['keyid'], roles['role1']['password']) # Rebuild the delegation role metadata. signerlib.build_delegated_role_file(roles['role2']['targets_dir'], roles['role1']['keyid'], metadata_dir, roles['role1']['metadata_dir'], 'role1.txt') # Update release and timestamp metadata. util_test_tools.make_release_meta(root_repo) util_test_tools.make_timestamp_meta(root_repo) # Perform another client download. try: urllib_tuf.urlretrieve(roles['role2']['url'], roles['role2']['dest_path']) except tuf.MetadataNotAvailableError, e: raise finally: server_proc.kill() util_test_tools.cleanup(root_repo, server_proc)
def test_mix_and_match_attack(TUF=False): """ Attack design: There are 3 stages: Stage 1: Consists of a usual mode of operations using tuf. Client downloads a target file. (Initial download) Stage 2: The target file is legitimately modified and metadata correctly updated. Client downloads the target file again. (Patched target download) Stage 3: The target file is legitimately modified and metadata correctly updated again. However, before client gets to download the newly patched target file the attacker replaces the release metadata, targets metadata and the target file with the ones from stage 1 (mix-and-match attack). Note that timestamp metadata is untouched. Further note that same would happen if only target metadata, and target file are reverted. """ ERROR_MSG = '\tMix-And-Match Attack was Successful!\n\n' try: # Setup / Stage 1 # --------------- root_repo, url, server_proc, keyids = util_test_tools.init_repo( tuf=TUF) reg_repo = os.path.join(root_repo, 'reg_repo') downloads = os.path.join(root_repo, 'downloads') evil_dir = tempfile.mkdtemp(dir=root_repo) # Add file to 'repo' directory: {root_repo} filepath = util_test_tools.add_file_to_repository(reg_repo, 'A' * 10) file_basename = os.path.basename(filepath) url_to_file = url + 'reg_repo/' + file_basename downloaded_file = os.path.join(downloads, file_basename) # Attacker saves the initial file. shutil.copy(filepath, evil_dir) unpatched_file = os.path.join(evil_dir, file_basename) if TUF: print 'TUF ...' tuf_repo = os.path.join(root_repo, 'tuf_repo') tuf_targets = os.path.join(tuf_repo, 'targets') metadata_dir = os.path.join(tuf_repo, 'metadata') release_meta_file = os.path.join(metadata_dir, 'release.txt') targets_meta_file = os.path.join(metadata_dir, 'targets.txt') target = os.path.join(tuf_targets, file_basename) # Update TUF metadata before attacker modifies anything. util_test_tools.tuf_refresh_repo(root_repo, keyids) # Attacker saves the original metadata and the target file. #shutil.copy(target, evil_dir) shutil.copy(release_meta_file, evil_dir) shutil.copy(targets_meta_file, evil_dir) #target_old = os.path.join(evil_dir, file_basename) release_meta_file_old = os.path.join(evil_dir, 'release.txt') targets_meta_file_old = os.path.join(evil_dir, 'targets.txt') # Modify the url. Remember that the interposition will intercept # urls that have 'localhost:9999' hostname, which was specified in # the json interposition configuration file. Look for 'hostname' # in 'util_test_tools.py'. Further, the 'file_basename' is the target # path relative to 'targets_dir'. url_to_file = 'http://localhost:9999/' + file_basename # Client's initial download. _download(url=url_to_file, filename=downloaded_file, tuf=TUF) # Stage 2 # ------- # Developer patches the file and updates the repository. util_test_tools.modify_file_at_repository(filepath, 'B' * 11) # Updating tuf repository. This will copy files from regular repository # into tuf repository and refresh the metadata if TUF: util_test_tools.tuf_refresh_repo(root_repo, keyids) # Client downloads the patched file. _download(url=url_to_file, filename=downloaded_file, tuf=TUF) downloaded_content = util_test_tools.read_file_content(downloaded_file) # Stage 3 # ------- # Developer patches the file and updates the repository again. util_test_tools.modify_file_at_repository(filepath, 'C' * 10) # Updating tuf repository. This will copy files from regular repository # into tuf repository and refresh the metadata if TUF: util_test_tools.tuf_refresh_repo(root_repo, keyids) # Attacker replaces the metadata and the target file. shutil.copyfile(unpatched_file, target) shutil.copyfile(release_meta_file_old, release_meta_file) shutil.copyfile(targets_meta_file_old, targets_meta_file) # Attacker replaces the patched file with the unpatched one. shutil.copyfile(unpatched_file, filepath) # Client tries to downloads the newly patched file. try: _download(url=url_to_file, filename=downloaded_file, tuf=TUF) except tuf.MetadataNotAvailableError: pass # Check whether the attack succeeded by inspecting the content of the # update. The update should contain 'Test NOT A'. downloaded_content = util_test_tools.read_file_content(downloaded_file) if ('B' * 11) != downloaded_content: raise MixAndMatchAttackAlert(ERROR_MSG) finally: util_test_tools.cleanup(root_repo, server_proc)
def test_replay_attack(TUF=False): """ <Arguments> TUF: If set to 'False' all directories that start with 'tuf_' are ignored, indicating that tuf is not implemented. <Purpose> Illustrate replay attack vulnerability. """ ERROR_MSG = 'Replay Attack was Successful!\n' try: # Setup. root_repo, url, server_proc, keyids = util_test_tools.init_repo(tuf=TUF) reg_repo = os.path.join(root_repo, 'reg_repo') tuf_repo = os.path.join(root_repo, 'tuf_repo') downloads = os.path.join(root_repo, 'downloads') tuf_targets = os.path.join(tuf_repo, 'targets') # Add file to 'repo' directory: {root_repo} filepath = util_test_tools.add_file_to_repository(reg_repo, 'Test A') file_basename = os.path.basename(filepath) url_to_repo = url+'reg_repo/'+file_basename downloaded_file = os.path.join(downloads, file_basename) # Attacker saves the original file into 'evil_dir'. evil_dir = tempfile.mkdtemp(dir=root_repo) vulnerable_file = os.path.join(evil_dir, file_basename) shutil.copy(filepath, evil_dir) if TUF: # Update TUF metadata before attacker modifies anything. util_test_tools.tuf_refresh_repo(root_repo, keyids) # Modify the url. Remember that the interposition will intercept # urls that have 'localhost:9999' hostname, which was specified in # the json interposition configuration file. Look for 'hostname' # in 'util_test_tools.py'. Further, the 'file_basename' is the target # path relative to 'targets_dir'. url_to_repo = 'http://localhost:9999/'+file_basename # End of Setup. # Client performs initial update. _download(url=url_to_repo, filename=downloaded_file, tuf=TUF) # Downloads are stored in the same directory '{root_repo}/downloads/' # for regular and tuf clients. downloaded_content = util_test_tools.read_file_content(downloaded_file) if 'Test A' != downloaded_content: raise TestSetupError('[Initial Updata] Failed to download the file.') # Developer patches the file and updates the repository. util_test_tools.modify_file_at_repository(filepath, 'Test NOT A') # Updating tuf repository. This will copy files from regular repository # into tuf repository and refresh the metad if TUF: util_test_tools.tuf_refresh_repo(root_repo, keyids) # Client downloads the patched file. _download(url=url_to_repo, filename=downloaded_file, tuf=TUF) # Content of the downloaded file. downloaded_content = util_test_tools.read_file_content(downloaded_file) if 'Test NOT A' != downloaded_content: raise TestSetupError('[Update] Failed to update the file.') # Attacker tries to be clever, he manages to modifies regular and tuf # targets directory by replacing a patched file with an old one. if os.path.isdir(tuf_targets): target = os.path.join(tuf_targets, file_basename) util_test_tools.delete_file_at_repository(target) shutil.copy(vulnerable_file, tuf_targets) # Verify that 'target' is an old, un-patched file. target = os.path.join(tuf_targets, file_basename) target_content = util_test_tools.read_file_content(target) if 'Test A' != target_content: raise TestSetupError("The 'target' file contains new data!") else: util_test_tools.delete_file_at_repository(filepath) shutil.copy(vulnerable_file, reg_repo) # Client downloads the file once more. _download(url=url_to_repo, filename=downloaded_file, tuf=TUF) # Check whether the attack succeeded by inspecting the content of the # update. The update should contain 'Test NOT A'. downloaded_content = util_test_tools.read_file_content(downloaded_file) if 'Test NOT A' != downloaded_content: raise ReplayAttackAlert(ERROR_MSG) finally: util_test_tools.cleanup(root_repo, server_proc)