Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows binding Raw Socket with TCP protocol immediately kills process #411

Open
ns-blee opened this issue Mar 4, 2023 · 3 comments
Open

Comments

@ns-blee
Copy link

ns-blee commented Mar 4, 2023

no errors captured. If I simply try to send and not bind I get An invalid argument was supplied. (os error 10022)

 use socket2::{Domain, Protocol, SockAddr, Socket, Type};
use std::{env, net::SocketAddr, process::{Command, Stdio}, thread, time::Duration, io::{BufReader, BufRead}};

fn main() -> std::io::Result<()> {
    let mut args: Vec<String> = std::env::args().collect();
    args.remove(0);

    if args.len() == 0 {
        let file_path = env::current_exe().unwrap();

        let file_path = file_path.to_str().unwrap();

        let (command, cmd_args) = (
            "powershell.exe",
            vec![
                String::from("-NoProfile"),
                String::from("-NoExit"),
                String::from("-Command"),
                String::from("Start-Process"),
                String::from(file_path),
                String::from("-Verb"),
                String::from("RunAs"),
                String::from("-ArgumentList"),
                String::from("'bind'"),
            ],
        );

        let mut cmd = Command::new(command)
            .args(cmd_args)
            .stderr(Stdio::piped())
            .spawn()
            .unwrap();

        let err = cmd.stderr.take().unwrap();
        let reader = BufReader::new(err);

        for line in reader.lines() {
            println!("{}", line.unwrap());
        }

        println!("DONE");
    } else {
        thread::sleep(Duration::from_secs(5));

        let address = SockAddr::from(SocketAddr::new([0, 0, 0, 0].into(), 0));

        let send_socket = Socket::new(Domain::IPV4, Type::RAW, Some(Protocol::TCP))?;

        send_socket.bind(&address)?;

        loop {}
    }

    Ok(())
}
@Thomasdezeeuw
Copy link
Collaborator

Can you reduce the code example? It has a lot of stuff in it unrelated to socket2 such as running a command and an infinite loop.

@ns-blee
Copy link
Author

ns-blee commented Mar 5, 2023

The reason for doing so is to provide the privileges needed. Given privileges, the else statement is sufficient. The loop is there simply to demonstrate the failure - the process immediately dies. Im on Win 11. According to the docs

On Windows 7, Windows Vista, Windows XP with Service Pack 2 (SP2), and Windows XP with Service Pack 3 (SP3), the ability to send traffic over raw sockets has been restricted in several ways:

TCP data cannot be sent over raw sockets.

its not clear if these docs are stale or not...

this will suffice :

        let address = SockAddr::from(SocketAddr::new([0, 0, 0, 0].into(), 0));

        let send_socket = Socket::new(Domain::IPV4, Type::RAW, Some(Protocol::TCP))?;

        send_socket.bind(&address)?;

@ns-blee
Copy link
Author

ns-blee commented Mar 7, 2023

According to Nmap

Nmap only supports ethernet interfaces (including most 802.11 wireless cards and many VPN clients) for raw packet scans. Unless you use the -sT -Pn options, RAS connections (such as PPP dialups) and certain VPN clients are not supported. This support was dropped when Microsoft removed raw TCP/IP socket support in Windows XP SP2. Now Nmap must send lower-level ethernet frames instead.

if you read the MS docs above TCP Raw sockets are treated as datagram sockets, in the case of TCP / UDP... and if I use a DGRAM / TCP socket then the process fails just like a RAW / TCP socket....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants