diff --git a/Cargo.lock b/Cargo.lock index 071d7820c..c042a18eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -365,16 +365,6 @@ dependencies = [ "hybrid-array", ] -[[package]] -name = "bstr" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" -dependencies = [ - "memchr", - "serde", -] - [[package]] name = "bumpalo" version = "3.20.2" @@ -445,28 +435,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "chrono-tz" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93698b29de5e97ad0ae26447b344c482a7284c737d9ddc5f9e52b74a336671bb" -dependencies = [ - "chrono", - "chrono-tz-build", - "phf", -] - -[[package]] -name = "chrono-tz-build" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c088aee841df9c3041febbb73934cfc39708749bf96dc827e3359cd39ef11b1" -dependencies = [ - "parse-zoneinfo", - "phf", - "phf_codegen", -] - [[package]] name = "clap" version = "4.6.1" @@ -631,16 +599,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "crossbeam-deque" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - [[package]] name = "crossbeam-epoch" version = "0.9.18" @@ -803,12 +761,6 @@ dependencies = [ "syn", ] -[[package]] -name = "deunicode" -version = "1.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abd57806937c9cc163efc8ea3910e00a62e2aeb0b8119f1793a978088f8f6b04" - [[package]] name = "digest" version = "0.10.7" @@ -1164,30 +1116,6 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" -[[package]] -name = "globset" -version = "0.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3" -dependencies = [ - "aho-corasick", - "bstr", - "log", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "globwalk" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" -dependencies = [ - "bitflags", - "ignore", - "walkdir", -] - [[package]] name = "h2" version = "0.4.14" @@ -1381,15 +1309,6 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" -[[package]] -name = "humansize" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7" -dependencies = [ - "libm", -] - [[package]] name = "hybrid-array" version = "0.4.12" @@ -1610,22 +1529,6 @@ dependencies = [ "icu_properties", ] -[[package]] -name = "ignore" -version = "0.4.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3d782a365a015e0f5c04902246139249abf769125006fbe7649e2ee88169b4a" -dependencies = [ - "crossbeam-deque", - "globset", - "log", - "memchr", - "regex-automata", - "same-file", - "walkdir", - "winapi-util", -] - [[package]] name = "indexmap" version = "2.14.0" @@ -2164,15 +2067,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "parse-zoneinfo" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f2a05b18d44e2957b88f96ba460715e295bc1d7510468a2f3d3b44535d26c24" -dependencies = [ - "regex", -] - [[package]] name = "pem-rfc7468" version = "0.7.0" @@ -2188,87 +2082,6 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" -[[package]] -name = "pest" -version = "2.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" -dependencies = [ - "memchr", - "ucd-trie", -] - -[[package]] -name = "pest_derive" -version = "2.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11f486f1ea21e6c10ed15d5a7c77165d0ee443402f0780849d1768e7d9d6fe77" -dependencies = [ - "pest", - "pest_generator", -] - -[[package]] -name = "pest_generator" -version = "2.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8040c4647b13b210a963c1ed407c1ff4fdfa01c31d6d2a098218702e6664f94f" -dependencies = [ - "pest", - "pest_meta", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pest_meta" -version = "2.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220" -dependencies = [ - "pest", - "sha2 0.10.9", -] - -[[package]] -name = "phf" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" -dependencies = [ - "phf_shared", -] - -[[package]] -name = "phf_codegen" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" -dependencies = [ - "phf_generator", - "phf_shared", -] - -[[package]] -name = "phf_generator" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" -dependencies = [ - "phf_shared", - "rand 0.8.6", -] - -[[package]] -name = "phf_shared" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" -dependencies = [ - "siphasher", -] - [[package]] name = "pin-project" version = "1.1.12" @@ -3153,28 +2966,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" -[[package]] -name = "siphasher" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" - [[package]] name = "slab" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" -[[package]] -name = "slug" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "882a80f72ee45de3cc9a5afeb2da0331d58df69e4e7d8eeb5d3c7784ae67e724" -dependencies = [ - "deunicode", - "wasm-bindgen", -] - [[package]] name = "smallvec" version = "1.15.1" @@ -3511,24 +3308,11 @@ dependencies = [ [[package]] name = "tera" -version = "1.20.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8004bca281f2d32df3bacd59bc67b312cb4c70cea46cbd79dbe8ac5ed206722" +checksum = "38ea62bd58771b570262e11ffa274fa9eda9986bd886e6e3a1f7f42afef8024c" dependencies = [ - "chrono", - "chrono-tz", - "globwalk", - "humansize", - "lazy_static", - "percent-encoding", - "pest", - "pest_derive", - "rand 0.8.6", - "regex", "serde", - "serde_json", - "slug", - "unicode-segmentation", ] [[package]] @@ -3947,12 +3731,6 @@ version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" -[[package]] -name = "ucd-trie" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" - [[package]] name = "unicode-bidi" version = "0.3.18" @@ -3980,12 +3758,6 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" -[[package]] -name = "unicode-segmentation" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" - [[package]] name = "unicode-xid" version = "0.2.6" diff --git a/Cargo.toml b/Cargo.toml index d7cecf0f8..1788fb6c1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,7 @@ clap = { version = "4.5.23", features = ["derive", "env"] } serde_yaml = "0.9" regex = "1" sqlx = { version = "0.8", features = ["runtime-tokio", "postgres", "chrono", "json", "uuid"] } -tera = "1" +tera = "2" hickory-resolver = { version = "0.26", default-features = false, features = ["tokio", "system-config"] } # OpenTelemetry diff --git a/ares-llm/src/prompt/helpers.rs b/ares-llm/src/prompt/helpers.rs index d941c5213..abdd3bd73 100644 --- a/ares-llm/src/prompt/helpers.rs +++ b/ares-llm/src/prompt/helpers.rs @@ -241,12 +241,20 @@ mod tests { }); let mut ctx = Context::new(); insert_credential_context(&mut ctx, &payload); - let json = ctx.into_json(); - assert_eq!(json["credential_username"], "admin"); - assert_eq!(json["credential_domain"], "contoso.local"); - assert_eq!(json["credential_auth_type"], "password"); + assert_eq!( + ctx.get("credential_username").and_then(|v| v.as_str()), + Some("admin") + ); + assert_eq!( + ctx.get("credential_domain").and_then(|v| v.as_str()), + Some("contoso.local") + ); + assert_eq!( + ctx.get("credential_auth_type").and_then(|v| v.as_str()), + Some("password") + ); assert!( - json.get("credential_password").is_none(), + ctx.get("credential_password").is_none(), "credential_password must never be exposed to templates" ); } @@ -261,9 +269,11 @@ mod tests { }); let mut ctx = Context::new(); insert_credential_context(&mut ctx, &payload); - let json = ctx.into_json(); - assert_eq!(json["credential_auth_type"], "hash/ticket"); - assert!(json.get("credential_password").is_none()); + assert_eq!( + ctx.get("credential_auth_type").and_then(|v| v.as_str()), + Some("hash/ticket") + ); + assert!(ctx.get("credential_password").is_none()); } #[test] @@ -271,8 +281,7 @@ mod tests { let payload = json!({"target": "192.168.58.10"}); let mut ctx = Context::new(); insert_credential_context(&mut ctx, &payload); - let json = ctx.into_json(); - assert!(json.get("credential_username").is_none()); - assert!(json.get("credential_password").is_none()); + assert!(ctx.get("credential_username").is_none()); + assert!(ctx.get("credential_password").is_none()); } } diff --git a/ares-llm/src/prompt/templates.rs b/ares-llm/src/prompt/templates.rs index 64ab51687..52f61baa9 100644 --- a/ares-llm/src/prompt/templates.rs +++ b/ares-llm/src/prompt/templates.rs @@ -399,7 +399,7 @@ pub fn render_agent_instructions_with_extras( ctx.insert("undominated_forests", undominated_forests); op.insert_into(&mut ctx); for (k, v) in extras { - ctx.insert(*k, v); + ctx.insert(k.to_string(), v); } TEMPLATES @@ -453,7 +453,7 @@ pub fn render_task_template( ) -> Result { let mut ctx = Context::new(); for (key, value) in variables { - ctx.insert(key.as_str(), value); + ctx.insert(key.clone(), value); } render_template_with_context(template_name, &ctx) } diff --git a/ares-llm/templates/redteam/agents/system_instructions.md.tera b/ares-llm/templates/redteam/agents/system_instructions.md.tera index 2df0fa978..1bf68566c 100644 --- a/ares-llm/templates/redteam/agents/system_instructions.md.tera +++ b/ares-llm/templates/redteam/agents/system_instructions.md.tera @@ -301,7 +301,7 @@ The operator strategy has configured the following technique priority ordering. | Weight | Technique | Description | |--------|-----------|-------------| {% for entry in technique_priorities -%} -| {{ entry.1 }} | {{ entry.0 }} | {% if entry.0 == "dc_secretsdump" %}secretsdump on domain controllers{% elif entry.0 == "golden_ticket" %}Kerberos golden ticket forgery{% elif entry.0 == "forest_trust_escalation" %}cross-forest trust key exploitation{% elif entry.0 == "child_to_parent" %}ExtraSid child-to-parent escalation{% elif entry.0 == "secretsdump" %}hash dump on member servers{% elif entry.0 == "credential_reuse" %}cross-domain hash reuse{% elif entry.0 == "mssql_access" %}MSSQL service exploitation{% elif entry.0 == "mssql_linked_server" %}MSSQL linked server pivoting{% elif entry.0 == "mssql_impersonation" %}MSSQL EXECUTE AS escalation{% elif entry.0 == "constrained_delegation" %}S4U2Self/S4U2Proxy abuse{% elif entry.0 == "unconstrained_delegation" %}TGT capture via coercion{% elif entry.0 == "rbcd" %}resource-based constrained delegation{% elif entry.0 == "esc1" %}ADCS ESC1 (enrollee supplies SAN){% elif entry.0 == "esc4" %}ADCS ESC4 (template owner can modify){% elif entry.0 == "esc8" %}ADCS ESC8 (HTTP enrollment + relay){% elif entry.0 == "acl_abuse" %}AD ACL chain exploitation{% elif entry.0 == "kerberoast" %}SPN-based hash extraction{% elif entry.0 == "asrep_roast" %}AS-REP roasting (no-preauth accounts){% elif entry.0 == "password_spray" %}password spraying / username-as-password{% elif entry.0 == "gmsa" %}gMSA password extraction{% elif entry.0 == "low_hanging_fruit" %}LDAP descriptions, SYSVOL, GPP, LAPS{% elif entry.0 == "smb_signing_disabled" %}NTLM relay via unsigned SMB{% elif entry.0 == "domain_admin" %}domain admin credential use{% else %}{{ entry.0 }}{% endif %} | +| {{ entry[1] }} | {{ entry[0] }} | {% if entry[0] == "dc_secretsdump" %}secretsdump on domain controllers{% elif entry[0] == "golden_ticket" %}Kerberos golden ticket forgery{% elif entry[0] == "forest_trust_escalation" %}cross-forest trust key exploitation{% elif entry[0] == "child_to_parent" %}ExtraSid child-to-parent escalation{% elif entry[0] == "secretsdump" %}hash dump on member servers{% elif entry[0] == "credential_reuse" %}cross-domain hash reuse{% elif entry[0] == "mssql_access" %}MSSQL service exploitation{% elif entry[0] == "mssql_linked_server" %}MSSQL linked server pivoting{% elif entry[0] == "mssql_impersonation" %}MSSQL EXECUTE AS escalation{% elif entry[0] == "constrained_delegation" %}S4U2Self/S4U2Proxy abuse{% elif entry[0] == "unconstrained_delegation" %}TGT capture via coercion{% elif entry[0] == "rbcd" %}resource-based constrained delegation{% elif entry[0] == "esc1" %}ADCS ESC1 (enrollee supplies SAN){% elif entry[0] == "esc4" %}ADCS ESC4 (template owner can modify){% elif entry[0] == "esc8" %}ADCS ESC8 (HTTP enrollment + relay){% elif entry[0] == "acl_abuse" %}AD ACL chain exploitation{% elif entry[0] == "kerberoast" %}SPN-based hash extraction{% elif entry[0] == "asrep_roast" %}AS-REP roasting (no-preauth accounts){% elif entry[0] == "password_spray" %}password spraying / username-as-password{% elif entry[0] == "gmsa" %}gMSA password extraction{% elif entry[0] == "low_hanging_fruit" %}LDAP descriptions, SYSVOL, GPP, LAPS{% elif entry[0] == "smb_signing_disabled" %}NTLM relay via unsigned SMB{% elif entry[0] == "domain_admin" %}domain admin credential use{% else %}{{ entry[0] }}{% endif %} | {% endfor -%} {% else -%}