test: 补齐C-01未授权文件攻击矩阵
This commit is contained in:
@@ -1015,3 +1015,4 @@ Core 的独立数据目录目前不等于已授权 Vault。Python 旧笔记写
|
||||
- 精确测试及 `core_process` 全文件 3 项通过,严格 Clippy `-D warnings` 通过。该实现提交为 `bdba729`。
|
||||
- A-04 尚不能记为通过:Core/Host 签名 RC 的原子更新事务与每个切换点 20 次真实重启恢复仍未完成。当前会话也没有受控签名 RC 或旧 RC。
|
||||
- C-01 运行环境复核显示当前 Windows 用户不是管理员,且未发现可用的 `pktmon`、`tshark` 或 `dumpcap` 命令,因此不能生成规划要求的禁止网络零收包证据;已有 AppContainer 文件与环回测试不能替代该证据。
|
||||
- C-01 文件攻击夹具继续补强:由真实编译的恶意二进制在 AppContainer 中分别对未授权 Vault、用户目录、凭据库和其他包诱饵执行各 100 次读取与 100 次写入,总计 800 次文件系统攻击均失败,四个诱饵 SHA-256 保持不变。精确 Rust 测试通过;C-01 状态仍保持未通过,直至网络类别的管理员抓包证据齐备。
|
||||
|
||||
@@ -708,6 +708,84 @@ mod tests {
|
||||
fn real_container_cannot_reach_ipv4_or_ipv6_loopback_listeners() {
|
||||
real_native_protocol_probes(false, false);
|
||||
}
|
||||
#[test]
|
||||
fn real_malicious_binary_cannot_read_or_write_four_ungranted_file_scopes() {
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::os::windows::fs::OpenOptionsExt;
|
||||
use windows_sys::Win32::Storage::FileSystem::*;
|
||||
|
||||
let profile = Profile::create().unwrap();
|
||||
let package = tempfile::tempdir().unwrap();
|
||||
let executable = package.path().join("file-probe.exe");
|
||||
let fixture = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("tests/fixtures/sandbox_network_probe.rs");
|
||||
let compile = std::process::Command::new("rustc")
|
||||
.arg("--edition=2021")
|
||||
.arg(&fixture)
|
||||
.arg("-o")
|
||||
.arg(&executable)
|
||||
.output()
|
||||
.unwrap();
|
||||
assert!(
|
||||
compile.status.success(),
|
||||
"{}",
|
||||
String::from_utf8_lossy(&compile.stderr)
|
||||
);
|
||||
let open = |path: &std::path::Path| {
|
||||
std::fs::OpenOptions::new()
|
||||
.access_mode(READ_CONTROL | WRITE_DAC)
|
||||
.share_mode(FILE_SHARE_READ | FILE_SHARE_WRITE)
|
||||
.custom_flags(FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT)
|
||||
.open(path)
|
||||
.unwrap()
|
||||
};
|
||||
let package_root = open(package.path());
|
||||
let entry = open(&executable);
|
||||
profile.grant_package_read_execute(&package_root).unwrap();
|
||||
profile.grant_package_read_execute(&entry).unwrap();
|
||||
|
||||
let bait_root = tempfile::tempdir().unwrap();
|
||||
let scopes = ["vault", "home", "credentials", "other-package"];
|
||||
let bait: Vec<_> = scopes
|
||||
.iter()
|
||||
.map(|scope| {
|
||||
let directory = bait_root.path().join(scope);
|
||||
std::fs::create_dir(&directory).unwrap();
|
||||
let path = directory.join("bait.txt");
|
||||
std::fs::write(&path, format!("OpenNexus C-01 {scope} bait")).unwrap();
|
||||
path
|
||||
})
|
||||
.collect();
|
||||
let before: Vec<_> = bait
|
||||
.iter()
|
||||
.map(|path| Sha256::digest(std::fs::read(path).unwrap()))
|
||||
.collect();
|
||||
let folder = profile.folder().unwrap();
|
||||
let system = std::path::PathBuf::from(std::env::var_os("SystemRoot").unwrap());
|
||||
let mut arguments = vec!["file_denied_100".to_owned()];
|
||||
arguments.extend(bait.iter().map(|path| path.to_string_lossy().into_owned()));
|
||||
let data = crate::extension_launch_data::LaunchData::new(
|
||||
&executable,
|
||||
&arguments,
|
||||
&system,
|
||||
&folder,
|
||||
&folder.join("Temp"),
|
||||
&std::collections::BTreeMap::new(),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
checked_executable_data(&profile, &executable, None, Some(data)),
|
||||
Some(0)
|
||||
);
|
||||
let after: Vec<_> = bait
|
||||
.iter()
|
||||
.map(|path| Sha256::digest(std::fs::read(path).unwrap()))
|
||||
.collect();
|
||||
assert_eq!(after, before);
|
||||
drop(entry);
|
||||
drop(package_root);
|
||||
profile.remove().unwrap();
|
||||
}
|
||||
#[cfg(feature = "desktop")]
|
||||
#[test]
|
||||
#[ignore = "real MCP tools/call 60-second deadline acceptance; run explicitly"]
|
||||
|
||||
@@ -3,6 +3,18 @@ use std::net::{SocketAddr, TcpStream, UdpSocket};
|
||||
use std::time::Duration;
|
||||
fn main() {
|
||||
let args: Vec<_> = std::env::args().collect();
|
||||
if args.get(1).is_some_and(|value| value == "file_denied_100") {
|
||||
for path in &args[2..] {
|
||||
for _ in 0..100 {
|
||||
if std::fs::File::open(path).is_ok()
|
||||
|| std::fs::OpenOptions::new().write(true).open(path).is_ok()
|
||||
{
|
||||
std::process::exit(88);
|
||||
}
|
||||
}
|
||||
}
|
||||
std::process::exit(0);
|
||||
}
|
||||
if args.get(1).is_some_and(|s| s == "cpu_burn") {
|
||||
std::thread::scope(|scope| {
|
||||
for _ in 0..8 {
|
||||
|
||||
Reference in New Issue
Block a user