Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add utility to build all attack tests. #106

Merged
merged 1 commit into from
Dec 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Page contents:
Additional documentation:
- [Using c2pa-attacks](docs/usage.md): How to use the `c2pa-attacks` CLI.
- [Injection attack files](attacks/README.md): Description of example attack files in the `attacks` directory.
- [Utilities](utilities/README.md): Overview of the available utility scripts for managing and generating c2pa-attacks files.
- [Appendix](docs/appendix.md): References and links for more information.

## Overview
Expand Down Expand Up @@ -107,9 +108,11 @@ NOTE: Quicktime (`.mov`) format is not yet fully supported.

## Examples

Here are some example uses of the tool that use files in the `attacks` and `sample` directories. The examples operate on the sample image file `sample/C.jpg` which has attached Content Credentials and the `sample/test.json` manifest file.
If you want to quickly create all possible test files without running each command individually, then the `generate_sample_out.sh` script in the `utilities` directory can be used to get started. More information on that tool is available in utility directory's [README](./utilities/README.md) file. However, it is recommended that you still read through the examples below to understand what that script will produce.

These examples create output in the `sample_out` directory.
These example uses of the tool use the provided files in the `attacks` and `sample` directories. The examples operate on the sample image file `sample/C.jpg` which has attached Content Credentials and the `sample/test.json` manifest file.

The following examples create output in the `sample_out` directory.

### Inject into the author field using direct substitution

Expand Down
28 changes: 28 additions & 0 deletions utilities/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
## Utilities

This directory contains various utilities that can make the creation and management of attack files more convenient.

### generate_sample_out.sh
This script is designed to generate all possible combinations of the malicious attacks based on the sample files. The script must be run from the root directory of the project. It requires one argument which is the path to the c2pa-attacks binary to use for building the sample malicious files. The following command demonstrates running the script from the root directory with all of the defaults:

`./utilities/generate_sample_out.sh {location_of_the_c2pa-attacks_binary}`

There are some combinations that the script does not build. For instance, the `C.jpg` image and the `malicious_certificate.json` manifest are not used with the default flags. The following additional flags may be specified to modify the default settings:

| Flag | Description |
|-----|-----|
| `-d` | Enable the output of debugging information. |
| `-m` | The JSON manifest file location for non-regex substitions. This is used in the `standard` and `all` target modes. Default: `./sample/test.json` |
| `-n` | The output file base name prior to being prefixed with attack details. Default: `signed_image.jpg` |
| `-o` | The output directory for the newly created files. Default: `./sample_out/` |
| `-r` | The location of the JSON manifest file for `regex` subsitutions. Default: `./sample/author_name_regex.json` |
| `-s` | The location of the source image file that will be altered. Default: `./sample/image.jpg` |
| `-t` | The targeted manifest type. Allowed values are `all`, `standard`, and `regex`. Default: `all` |

The `-t` flag allows you to either skip the usage of a regex manifest file or to only use a regex manifest file. This option is provided because regex substitions require a dedicated manifest file with a `C2PA_ATTACK` field specified where you want the injections to occur. The `standard` mode will work with any standard JSON manifest and inject into specification defined fields such as `author` and `title`. The default regex example file makes substitutions in the `author` field. The default setting of `all` will build both the `standard` variants using `test.json` and the `regex` variant using the `author_name_regex.json` manifest from the sample directory. However, you can modify this behavior using the command line flags. For instance, if you wanted to limit the tool to only create malicious files using your own custom regex manifest file, then you could specify the following command:

`./utilities/generate_sample_out.sh -t regex -r {location_of_your_regex_manifest} {location_of_the_c2pa-attacks_binary}`

Anonther example customization of the command line might be to use the malicious certificate manifest definition which will sign the files with the default malicious certificate. Assuming that a locally installed c2pa-attacks binary will be used, the commmand would be as follows:

`./utilities/generate_sample_out.sh -m ./sample/malicious_certificate.json ~/.cargo/bin/c2pa-attacks`
209 changes: 209 additions & 0 deletions utilities/generate_sample_out.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
#!/bin/bash

# Copyright 2023 Adobe. All rights reserved.
# This file is licensed to you under the Apache License,
# Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
# or the MIT license (http://opensource.org/licenses/MIT),
# at your option.
# Unless required by applicable law or agreed to in writing,
# this software is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or
# implied. See the LICENSE-MIT and LICENSE-APACHE files for the
# specific language governing permissions and limitations under
# each license.

# This script is designed to build all supported attacks based on the sample files.
# It doesn't build variants using C.jpg or the malicious certificate by default.
# These can be built used by changing the defaults using the command line.
#
# It is expected that this tool will be run from the root directory of the project.
# ./scripts/generate_sample_out.sh {location_of_the_c2pa-attacks_binary_to_use}
#
# Not all combinations of malicious files can be built. This will result in a few known errors.
# These errors will either mention a CBOR error or they will say that a file is being skipped.
# These errors are expected and doesn't indicated a failure of the tool.
# The errors are only displayed when the tool is in debugging mode.

# Whether to output debugging information
debugging=false

# The list of target locations where substitutions will occur
target_fields=("title" "author" "person_identifier" "claim_generator" "vendor" "label" "instance_id" "format" "regex")

# The location of the attack file directory.
attack_dir="./attacks/"

# The list of attack files to use for this run.
# These are assumed to exist in the attack_dir directory.
attack_files=("rendering.attack" "special_characters.attack" "sql_injection.attack" "ten_thousand_characters.attack" "xss.attack")

# The source JSON manifest file for non-regex use cases.
# This uses the standard es256 certificate files from the sample directory
source_json="./sample/test.json"

# This manifest file is similar to test.json but it uses the malicious_certificate for signing.
# It is not intended for the regex mode of c2pa-attacks
malicious_cert_json="./sample/malicious_certificate.json"

# Setting the default manifest that will be used.
# This can be overridden by the command line.
manifest_file="${source_json}"

# The base JSON manifest file for use with the regex functionality.
# This file has the string "C2PA_ATTACK" embedded within it.
# The "C2PA_ATTACK" string will be replaced with the malicious string.
regex_test_file="./sample/author_name_regex.json"

# The default output directory where newly created files will be placed.
sample_out_dir="./sample_out/"

# The default base name of the newly created file.
# This name will be prefixed with information about the modifications.
output_name="signed_image.jpg"

# The default source image that will have content credentials added to it.
source_image="./sample/image.jpg"

# targets
build_target="all"

# Display usage information when an unexpected or malformed flag is provided.
usage() {
echo "USAGE: $(basename $0) [-d] [-m manifest_file] [-n output_file_name] [-o output_file_directory] [-s source_image] binary_location" >&2
echo "-d: Print debugging statements"
echo "-m: The location of a manifiest file for non-regex substitutions. (default: ${source_name})"
echo "-n: The ending to use for output file names. (default: ${output_name})"
echo "-o: The output file directory. (default: ${sample_out_dir})"
echo "-r: The location of the manifest file for regex substitutions. (default: ${regex_test_file})"
echo "-s: The source image file that will be altered. (default: ${source_image})"
echo "-t: The type of manifest files to use (all, standard, or regex). (default: ${build_target})"
}

# Retrieve any optional command line parameters
while getopts 'dm:n:o:r:s:t:' OPTION; do
case "$OPTION" in
d)
debugging=true
;;
m)
manifest_file="${OPTARG}"
if ! test -f "$manifest_file"; then
echo "ERROR: Invalid manifest file location"
exit 1
fi
;;
n)
output_name="${OPTARG}"
;;
o)
sample_out_dir=="${OPTARG}"
;;
r)
regex_test_file="${OPTARG}"
if ! test -f "$regex_test_file"; then
echo "ERROR: Invalid regex manifest file location"
exit 1
fi
;;
s)
source_image="${OPTARG}"
if ! test -f "$source_image"; then
echo "ERROR: Invalid source image file location"
exit 1
fi
;;
t)
build_target="${OPTARG}"
if [ "${build_target}" != "all" ] && [ "${build_target}" != "standard" ] && [ "${build_target}" != "regex" ] ; then
echo "ERROR: Invalid target field selection. The value must be all, standard, or regex"
exit 1
fi
;;
?)
usage
exit 0
;;
esac
done

# Reset $1 to the location of c2pa-attacks binary if necessary
if [ $OPTIND -gt 0 ] ; then
shift "$(($OPTIND - 1))"
fi

# Check for the location of the c2pa-attacks binary in $1
if [ -z "$1" ] ; then
echo "ERROR: Please supply the location of the c2pa-attacks binary to use for the builds"
usage
exit 1
fi

# Set the location of the c2pa-attacks binary.
binary_location="$1"

# Verify that the path to the c2pa-attacks binary is valid
if ! type "$binary_location" > /dev/null; then
echo "ERROR: Unable to locate the provided location of the c2pa-attacks binary"
echo "Please double check the path provided to ensure that it points to a valid location"
exit 1
fi

# Display debugging information on which files will be created
if [ "$debugging" = true ] ; then
if [ "${build_target}" = "regex" ]; then
echo "DEBUG: Only building files based on the regex manifest"
elif [ "${build_target}" = "standard" ]; then
echo "DEBUG: Only building based on a standard manifest file. The regex manifest will be ignored."
else
echo "DEBUG: Building all combinations of files."
fi
fi

# Start creating the malicious files in the output directory.

# For each of the listed attack files
for attack_file in "${attack_files[@]}"; do

## For each of the target substitution locations
for target_field in "${target_fields[@]}"; do

# Ignore regex substitutions if it is in standard-only mode
if [ "${target_field}" = "regex" ] && [ "${build_target}" = "standard" ]; then
continue
fi

# Ignore standard fields if it is regex-only mode
if [ "${target_field}" != "regex" ] && [ "${build_target}" = "regex" ]; then
continue
fi

# Build the command line with all of the appropriate values
command_line="${binary_location} ${source_image}"

if [ "${target_field}" = "regex" ]; then
command_line="${command_line} -m ${regex_test_file}"
else
command_line="${command_line} -m ${source_json}"
fi

command_line="${command_line} -o ${sample_out_dir}${output_name}"
command_line="${command_line} -t ${target_field}"
command_line="${command_line} -a ${attack_dir}${attack_file}"
command_line="${command_line} -f"

# Show the complete command line when debugging
if [ "$debugging" = true ] ; then
echo "DEBUG: ${command_line}"
fi

# Execute the command line and capture any errors
output=$(eval $command_line)

# Output errors from the command line
# This is only printed in debugging mode because some errors are expected in normal operation.
if [ -n "$output" ] && [ "$debugging" = true ] ; then
echo "${output}"
fi
done

done
Loading