Skip to content

Latest commit

 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cradle-net

Networking hooks and state helpers for Cradle plugins

It is meant to be used by plugins that want to inspect connections, DNS lookups, transmitted buffers, and WinHTTP request metadata while the agent is running

What It Captures

  • Winsock connect, send, sendto, recv, and closesocket
  • DNS lookups through getaddrinfo and GetAddrInfoW
  • WinHTTP user-agent, host, request path, headers, request body, and pending reads
  • Also tries to capture stack traces for captured data chunks

Because the current hook engine does not have return hooks yet, cradle-net records recv and WinHttpReadData operations as pending reads with the destination address and requested length instead of having the legit final bytes

Example

use cradle_hooks::HookEngine;
use cradle_net::monitor::NetMonitor;
use cradle_plugin_api::{AgentEvent, CradleMutex, CradlePlugin, register_plugin};
use cradle_shared::CradleResult;

#[derive(Default)]
struct NetAwarePlugin {
    monitor: Option<NetMonitor>,
    hooked_winsock: bool,
}

impl CradlePlugin for NetAwarePlugin {
    fn name(&self) -> &str {
        "net-aware"
    }

    fn init(&mut self, engine: CradleMutex<HookEngine>) -> CradleResult {
        self.monitor = Some(NetMonitor::new(engine));
        Ok(())
    }

    fn on_event(&mut self, event: &AgentEvent) -> CradleResult {
        if let AgentEvent::DllLoaded { name, .. } = event {
            if name.to_lowercase().contains("ws2_32")
                && !self.hooked_winsock
                && let Some(monitor) = self.monitor.as_mut()
            {
                monitor.install_winsock()?;
                self.hooked_winsock = true;
            }
        }

        Ok(())
    }
}

register_plugin!(NetAwarePlugin);

Reading State

NetMonitor::state() returns a shared NetState. You should inspect it from the plugin to decide when to return an OK result

if let Some(monitor) = &self.monitor {
    let state = monitor.state();
    let state = state.lock();

    for connection in state.connections.values() {
        for chunk in &connection.tx_log {
            if let Some(stack_trace) = &chunk.stack_trace {
                // Return addresses captured from the target process
                let _ = stack_trace;
            }
        }
    }
}

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages