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

Added Base8 decoding to Ares #348

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
147 changes: 147 additions & 0 deletions src/decoders/base8_decoder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
//! Decodes Octal encoded data.
//! Performs error handling and returns a string.
//! Call base8_decoder.crack to use. Returns a Option<String> and check with
//! `result.is_some()` to see if it was successful.
use crate::decoders::interface::check_string_success;

use super::crack_results::CrackResult;
use super::interface::{Crack, Decoder};

use log::{debug, error, info, trace};

/// The Base8 decoder, call:
/// `let base8_decoder = Decoder::<Base8Decoder>::new()` to create a new instance
/// And then call:
/// `result = base8_decoder.crack(input)` to decode a octal encoded string
/// The struct generated by new() comes from interface.rs
/// ```
/// use ares::decoders::base8_decoder::Base8Decoder;
/// use ares::decoders::interface::{Crack, Decoder};
/// use ares::checkers::{athena::Athena, CheckerTypes, checker_type::{Check, Checker}};
///
/// let decode_base32 = Decoder::<Base8Decoder>::new();
/// let athena_checker = Checker::<Athena>::new();
/// let checker = CheckerTypes::CheckAthena(athena_checker);
///
/// let result = decode_base32.crack("150 145 154 154 157 040 167 157 162 154 144", &checker).unencrypted_text;
/// assert!(result.is_some());
/// assert_eq!(result.unwrap()[0], "hello world");
/// ```
pub struct Base8Decoder;

impl Crack for Decoder<Base8Decoder> {
fn new() -> Decoder<Base8Decoder> {
Decoder {
name: "Base8",
description: "Octal (base 8) is a numeral system with eight as the base.",
link: "https://en.wikipedia.org/wiki/Octal",
tags: vec!["octal", "base8"],
popularity: 0.5,
phantom: std::marker::PhantomData,
}
}

fn get_name(&self) -> &str {
self.name
}

fn get_tags(&self) -> &Vec<&str> {
&self.tags
}

/// Calling crack attempts to decode the input string. If it fails, None will be returned,
/// otherwise Some(String) will be returned. The error will be logged into trace.
fn crack(&self, text: &str, checker: &crate::checkers::CheckerTypes) -> CrackResult {
trace!("Attempting to decode Base8 with text: {}", text);
let mut results = CrackResult::new(self, text.to_string());

let decoded = match decode_base8(text) {
Ok(d) => d,
Err(_) => {
debug!("Failed to decode Base8 because decode_base8 returned an Error");
return results;
}
};

if !check_string_success(&decoded, text) {
info!(
"Failed to decode Base8 because check_string_success returned false on string {}",
text
);
return results;
}

let checker_result = checker.check(&decoded);

results.unencrypted_text = Some(vec![decoded]);
results.update_checker(&checker_result);

results
}
}

/// Helper function for Base8Decoder to decode octal encoded text
fn decode_base8(text: &str) -> Result<String, String> {
let mut characters: Vec<String> = Vec::new();

for number in text.split_whitespace() {
let number = match u8::from_str_radix(number, 8) {
Ok(n) => n,
Err(e) => {
error!(
"Failed to convert octal number {} to decimal: {}",
number, e
);
return Err("Failed to convert octal number to decimal".to_string());
}
};

characters.push(std::char::from_u32(number as u32).unwrap().to_string());
}

Ok(characters.join(""))
}

#[cfg(test)]
mod tests {
use super::Base8Decoder;
use crate::checkers::{
athena::Athena, checker_type::Check, checker_type::Checker, CheckerTypes,
};
use crate::decoders::interface::{Crack, Decoder};

#[test]
fn test_base8_decoder() {
let decode_base8 = Decoder::<Base8Decoder>::new();
let athena_checker = Checker::<Athena>::new();
let checker = CheckerTypes::CheckAthena(athena_checker);

let result = decode_base8
.crack("150 145 154 154 157 040 167 157 162 154 144", &checker)
.unencrypted_text;
assert!(result.is_some());
assert_eq!(result.unwrap()[0], "hello world");
}

#[test]
fn test_base8_decoder_fail() {
let decode_base8 = Decoder::<Base8Decoder>::new();
let athena_checker = Checker::<Athena>::new();
let checker = CheckerTypes::CheckAthena(athena_checker);

let result = decode_base8.crack("asdf", &checker).unencrypted_text;

assert!(result.is_none());
}

#[test]
fn test_base8_empty_string() {
let decode_base8 = Decoder::<Base8Decoder>::new();
let athena_checker = Checker::<Athena>::new();
let checker = CheckerTypes::CheckAthena(athena_checker);

let result = decode_base8.crack("", &checker).unencrypted_text;

assert!(result.is_none());
}
}
2 changes: 2 additions & 0 deletions src/decoders/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ pub mod base32_decoder;
pub mod base58_bitcoin_decoder;
/// The base58_monero_decoder module decodes base58 monero
pub mod base58_monero_decoder;
/// The base8_decoder module decodes base8 (octal)
pub mod base8_decoder;
/// The binary_decoder module decodes binary
pub mod binary_decoder;
/// The hexadecimal_decoder module decodes hexadecimal
Expand Down
3 changes: 3 additions & 0 deletions src/filtration_system/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use crate::decoders::a1z26_decoder::A1Z26Decoder;
use crate::decoders::base64_decoder::Base64Decoder;
use crate::decoders::base64_url_decoder::Base64URLDecoder;
use crate::decoders::base65536_decoder::Base65536Decoder;
use crate::decoders::base8_decoder::Base8Decoder;
use crate::decoders::base91_decoder::Base91Decoder;
use crate::decoders::caesar_decoder::CaesarDecoder;
use crate::decoders::citrix_ctx1_decoder::CitrixCTX1Decoder;
Expand Down Expand Up @@ -114,6 +115,7 @@ pub fn filter_and_get_decoders(_text_struct: &DecoderResult) -> Decoders {
let base58_ripple = Decoder::<Base58RippleDecoder>::new();
let base58_flickr = Decoder::<Base58FlickrDecoder>::new();
let base64 = Decoder::<Base64Decoder>::new();
let base8 = Decoder::<Base8Decoder>::new();
let base91 = Decoder::<Base91Decoder>::new();
let base64_url = Decoder::<Base64URLDecoder>::new();
let base65536 = Decoder::<Base65536Decoder>::new();
Expand All @@ -134,6 +136,7 @@ pub fn filter_and_get_decoders(_text_struct: &DecoderResult) -> Decoders {
Box::new(base58_monero),
Box::new(base58_ripple),
Box::new(base58_flickr),
Box::new(base8),
Box::new(base91),
Box::new(base65536),
Box::new(binary),
Expand Down