Cleaned up Windows server and added more docs
This commit is contained in:
parent
28dd9f5138
commit
7390a2e3bf
120
Cargo.lock
generated
120
Cargo.lock
generated
@ -211,7 +211,7 @@ dependencies = [
|
|||||||
"num-traits",
|
"num-traits",
|
||||||
"serde",
|
"serde",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"windows-targets",
|
"windows-targets 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -403,7 +403,7 @@ checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"errno-dragonfly",
|
"errno-dragonfly",
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -769,7 +769,7 @@ checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||||
"windows-sys",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -866,7 +866,7 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"windows-targets",
|
"windows-targets 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1151,7 +1151,7 @@ dependencies = [
|
|||||||
"errno 0.3.3",
|
"errno 0.3.3",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys",
|
"linux-raw-sys",
|
||||||
"windows-sys",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1269,7 +1269,7 @@ dependencies = [
|
|||||||
"colored",
|
"colored",
|
||||||
"log",
|
"log",
|
||||||
"time",
|
"time",
|
||||||
"windows-sys",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1294,7 +1294,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9"
|
checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1345,6 +1345,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"simple_logger",
|
"simple_logger",
|
||||||
"sparse-05-common",
|
"sparse-05-common",
|
||||||
|
"windows-service",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1505,7 +1506,7 @@ dependencies = [
|
|||||||
"fastrand",
|
"fastrand",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
"rustix",
|
"rustix",
|
||||||
"windows-sys",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1582,7 +1583,7 @@ dependencies = [
|
|||||||
"signal-hook-registry",
|
"signal-hook-registry",
|
||||||
"socket2",
|
"socket2",
|
||||||
"tokio-macros",
|
"tokio-macros",
|
||||||
"windows-sys",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1745,6 +1746,12 @@ version = "0.2.89"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f"
|
checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "widestring"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
@ -1773,7 +1780,27 @@ version = "0.50.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "af6041b3f84485c21b57acdc0fee4f4f0c93f426053dc05fa5d6fc262537bbff"
|
checksum = "af6041b3f84485c21b57acdc0fee4f4f0c93f426053dc05fa5d6fc262537bbff"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-targets",
|
"windows-targets 0.48.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-service"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cd9db37ecb5b13762d95468a2fc6009d4b2c62801243223aabd44fca13ad13c8"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
"widestring",
|
||||||
|
"windows-sys 0.45.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.45.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets 0.42.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1782,7 +1809,22 @@ version = "0.48.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-targets",
|
"windows-targets 0.48.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.42.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm 0.42.2",
|
||||||
|
"windows_aarch64_msvc 0.42.2",
|
||||||
|
"windows_i686_gnu 0.42.2",
|
||||||
|
"windows_i686_msvc 0.42.2",
|
||||||
|
"windows_x86_64_gnu 0.42.2",
|
||||||
|
"windows_x86_64_gnullvm 0.42.2",
|
||||||
|
"windows_x86_64_msvc 0.42.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1791,51 +1833,93 @@ version = "0.48.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
|
checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows_aarch64_gnullvm",
|
"windows_aarch64_gnullvm 0.48.0",
|
||||||
"windows_aarch64_msvc",
|
"windows_aarch64_msvc 0.48.0",
|
||||||
"windows_i686_gnu",
|
"windows_i686_gnu 0.48.0",
|
||||||
"windows_i686_msvc",
|
"windows_i686_msvc 0.48.0",
|
||||||
"windows_x86_64_gnu",
|
"windows_x86_64_gnu 0.48.0",
|
||||||
"windows_x86_64_gnullvm",
|
"windows_x86_64_gnullvm 0.48.0",
|
||||||
"windows_x86_64_msvc",
|
"windows_x86_64_msvc 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.42.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_gnullvm"
|
name = "windows_aarch64_gnullvm"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
|
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.42.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_msvc"
|
name = "windows_aarch64_msvc"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
|
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.42.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnu"
|
name = "windows_i686_gnu"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
|
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.42.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_msvc"
|
name = "windows_i686_msvc"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
|
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.42.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnu"
|
name = "windows_x86_64_gnu"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
|
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.42.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnullvm"
|
name = "windows_x86_64_gnullvm"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
|
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.42.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_msvc"
|
name = "windows_x86_64_msvc"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
|
|||||||
@ -14,4 +14,8 @@ Doing so will create an environment which has all the dependencies necessary in
|
|||||||
|
|
||||||
## Proofs of concept
|
## Proofs of concept
|
||||||
|
|
||||||
There are multiple proofs of concept that are made to further develop libraries and further this project as well as provide stepping stones to help educate new contributors, and they are located in [the examples folder](./examples/README.md)
|
There are multiple proofs of concept that are made to further develop libraries and further this project as well as provide stepping stones to help educate new contributors, and they are located in [the examples folder](./examples/README.md)
|
||||||
|
|
||||||
|
## Somewhat mature bind shell
|
||||||
|
|
||||||
|
The most mature implementation of Sparse would be the Sparse version 0.5 bind shell, which has documentation in [its appropriate folder](./sparse-05/README.md)
|
||||||
|
|||||||
15
flake.nix
15
flake.nix
@ -63,7 +63,6 @@
|
|||||||
craneLib = (crane.mkLib pkgs).overrideToolchain toolchain;
|
craneLib = (crane.mkLib pkgs).overrideToolchain toolchain;
|
||||||
|
|
||||||
src = craneLib.cleanCargoSource (craneLib.path ./.);
|
src = craneLib.cleanCargoSource (craneLib.path ./.);
|
||||||
windowsSrc = craneLib.path ./.;
|
|
||||||
|
|
||||||
commonArgs = {
|
commonArgs = {
|
||||||
inherit src;
|
inherit src;
|
||||||
@ -83,8 +82,6 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
commonWindowsArgs = commonArgs // {
|
commonWindowsArgs = commonArgs // {
|
||||||
src = windowsSrc;
|
|
||||||
|
|
||||||
CARGO_BUILD_TARGET = "x86_64-pc-windows-gnu";
|
CARGO_BUILD_TARGET = "x86_64-pc-windows-gnu";
|
||||||
|
|
||||||
SPARSE_BUILD_WINPCAP = "${winpcap}/Lib";
|
SPARSE_BUILD_WINPCAP = "${winpcap}/Lib";
|
||||||
@ -110,11 +107,21 @@
|
|||||||
cargoExtraArgs = "-p sparse-05-server --locked";
|
cargoExtraArgs = "-p sparse-05-server --locked";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
sparse-05-windows-service = craneLib.buildPackage (commonWindowsArgs
|
||||||
|
// {
|
||||||
|
artifacts = windowsArtifacts;
|
||||||
|
|
||||||
|
pname = "sparse-05-windows-server";
|
||||||
|
cargoExtraArgs = "-p sparse-05-server --locked --features service";
|
||||||
|
});
|
||||||
|
|
||||||
sparse-05-client = craneLib.buildPackage (commonArgs // {
|
sparse-05-client = craneLib.buildPackage (commonArgs // {
|
||||||
inherit artifacts;
|
inherit artifacts;
|
||||||
|
|
||||||
SPARSE_WINDOWS_SERVER =
|
SPARSE_WINDOWS_SERVER =
|
||||||
"${sparse-05-windows-server}/bin/sparse-05-server.exe";
|
"${sparse-05-windows-server}/bin/sparse-05-server.exe";
|
||||||
|
SPARSE_WINDOWS_SERVICE =
|
||||||
|
"${sparse-05-windows-service}/bin/sparse-05-server.exe";
|
||||||
SPARSE_LINUX_SERVER =
|
SPARSE_LINUX_SERVER =
|
||||||
"${sparse-05-linux-server}/bin/sparse-05-server";
|
"${sparse-05-linux-server}/bin/sparse-05-server";
|
||||||
|
|
||||||
@ -155,7 +162,7 @@
|
|||||||
|
|
||||||
packages = {
|
packages = {
|
||||||
inherit sparse-05-linux-server sparse-05-windows-server
|
inherit sparse-05-linux-server sparse-05-windows-server
|
||||||
sparse-05-client;
|
sparse-05-windows-service sparse-05-client;
|
||||||
|
|
||||||
inherit sparse-c2-linux-beacon sparse-c2-server sparse-c2-client;
|
inherit sparse-c2-linux-beacon sparse-c2-server sparse-c2-client;
|
||||||
|
|
||||||
|
|||||||
@ -17,4 +17,57 @@
|
|||||||
|
|
||||||
# Sparse 0.5
|
# Sparse 0.5
|
||||||
|
|
||||||
Sparse 0.5 is a stopgap
|
Sparse 0.5 is a stopgap solution until the C2 framework itself is more mature. It has several improvements over the proof of concept version, to include:
|
||||||
|
|
||||||
|
- The client is no longer bound to the server, the configuration can be shared
|
||||||
|
- A richer CLI with Sparse specific commands such as #upload, #download, and #edit
|
||||||
|
- A Windows version using winpcap, with both standalone binary and service versions
|
||||||
|
|
||||||
|
# Obtaining
|
||||||
|
|
||||||
|
Currently, there are no prebuilt binaries. However, sparse can easily be built if the [Nix package manager](https://nixos.org/download) is installed. Just clone this repository and run `nix build .#sparse-05-client` and the client will be placed in `result/bin`.
|
||||||
|
|
||||||
|
# Use
|
||||||
|
|
||||||
|
Using sparse centers around the client. The client can generate new servers as well as the configuration file necessary to connect to the server, connect to a server for a shell, and verify the connection against a server.
|
||||||
|
|
||||||
|
## Generating a new server
|
||||||
|
|
||||||
|
Sparse supports 3 different targets:
|
||||||
|
- Linux
|
||||||
|
- Windows
|
||||||
|
- Windows service
|
||||||
|
|
||||||
|
The basics center around `sparse-05-client generate <name> [-p <port>] [-t <target>]`. This generates both a server and the configuration file necessary to connect to the server. The keys and port ensure that the connection is unique, which has the added property that multiple versions of `sparse-05` can be running on a target system with the same port.
|
||||||
|
|
||||||
|
If the port is not specified, it defaults to 54248.
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
|
||||||
|
To install the Linux service, there are a few options:
|
||||||
|
|
||||||
|
- Run as root
|
||||||
|
- Run with CAP_NET_RAW and CAP_SETUID as a non-root user
|
||||||
|
- Run in a Docker container running as root on Linux with kernel version 5.13 or greater and the `--privileged` and `--pid=host` flags
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
The Windows version requires an installation of winpcap 4.1, which can be downloaded from [their website](https://www.winpcap.org/install/default.htm).
|
||||||
|
|
||||||
|
As of Jan 25 2023, Windows Defender is suspicious of exe builds of the sparse server but only tries to submit samples and does not declare it malicious.
|
||||||
|
|
||||||
|
### Windows service
|
||||||
|
|
||||||
|
The Windows service has the same requirements, but can be installed with `sc create <service name> DisplayName= <service name> binPath= <service exe path>`.
|
||||||
|
|
||||||
|
As of Jan 25 2023, Windows Defender marks the Windows service binary as malicious
|
||||||
|
|
||||||
|
## Connect
|
||||||
|
|
||||||
|
After installing and running the server, it is possible to connect using the generated `scon` file and `sparse-05-client` with `sparse-05-client connect <name>.scon <service ip>:<service port>`.
|
||||||
|
|
||||||
|
This brings up a shell that can run commands. However, there are special commands that are injected:
|
||||||
|
|
||||||
|
- `#help`: shows sparse specific help
|
||||||
|
- `#sysinfo`: prints information about the system being connected to
|
||||||
|
- `#upload [local] [remote]`: uploads a file from the local path to the remote path
|
||||||
|
|||||||
@ -13,14 +13,16 @@ pub fn print_capabilities(capabilities: &Capabilities, ip: &IpAddr) {
|
|||||||
OperatingSystem::Windows => "Windows",
|
OperatingSystem::Windows => "Windows",
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
println!(
|
if matches!(&capabilities.operating_system, OperatingSystem::Linux) {
|
||||||
"\tInside a container: \t{}",
|
println!(
|
||||||
if capabilities.docker_container {
|
"\tInside a container: \t{}",
|
||||||
"yes"
|
if capabilities.docker_container {
|
||||||
} else {
|
"yes"
|
||||||
"no"
|
} else {
|
||||||
}
|
"no"
|
||||||
);
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
if capabilities.docker_container {
|
if capabilities.docker_container {
|
||||||
println!(
|
println!(
|
||||||
"\tContainer breakout: \t{}",
|
"\tContainer breakout: \t{}",
|
||||||
|
|||||||
@ -18,6 +18,12 @@ pub const SPARSE_WINDOWS_SERVER_BINARY: &'static [u8] =
|
|||||||
#[cfg(not(debug_assertions))]
|
#[cfg(not(debug_assertions))]
|
||||||
pub const SPARSE_WINDOWS_SERVER_BINARY: &'static [u8] =
|
pub const SPARSE_WINDOWS_SERVER_BINARY: &'static [u8] =
|
||||||
include_bytes!(std::env!("SPARSE_WINDOWS_SERVER"));
|
include_bytes!(std::env!("SPARSE_WINDOWS_SERVER"));
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
pub const SPARSE_WINDOWS_SERVICE_BINARY: &'static [u8] =
|
||||||
|
include_bytes!("../../../../target/x86_64-pc-windows-gnu/debug/sparse-05-server.exe");
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
pub const SPARSE_WINDOWS_SERVICE_BINARY: &'static [u8] =
|
||||||
|
include_bytes!(std::env!("SPARSE_WINDOWS_SERVICE"));
|
||||||
|
|
||||||
pub async fn generate(mut name: PathBuf, port: u16, target: TargetOs) -> anyhow::Result<()> {
|
pub async fn generate(mut name: PathBuf, port: u16, target: TargetOs) -> anyhow::Result<()> {
|
||||||
let mut csprng = rand::thread_rng();
|
let mut csprng = rand::thread_rng();
|
||||||
@ -31,7 +37,7 @@ pub async fn generate(mut name: PathBuf, port: u16, target: TargetOs) -> anyhow:
|
|||||||
|
|
||||||
let old_file_part = name.file_name().unwrap().to_owned();
|
let old_file_part = name.file_name().unwrap().to_owned();
|
||||||
|
|
||||||
if matches!(target, TargetOs::Windows) {
|
if matches!(target, TargetOs::Windows) || matches!(target, TargetOs::WindowsService) {
|
||||||
let mut file_part = name.file_name().unwrap().to_owned();
|
let mut file_part = name.file_name().unwrap().to_owned();
|
||||||
file_part.push(OsString::from(".exe"));
|
file_part.push(OsString::from(".exe"));
|
||||||
name.pop();
|
name.pop();
|
||||||
@ -40,14 +46,15 @@ pub async fn generate(mut name: PathBuf, port: u16, target: TargetOs) -> anyhow:
|
|||||||
|
|
||||||
let mut file = file.open(&name).await?;
|
let mut file = file.open(&name).await?;
|
||||||
|
|
||||||
if matches!(target, TargetOs::Windows) {
|
if matches!(target, TargetOs::Windows) || matches!(target, TargetOs::WindowsService) {
|
||||||
name.pop();
|
name.pop();
|
||||||
name.push(old_file_part);
|
name.push(old_file_part);
|
||||||
}
|
}
|
||||||
|
|
||||||
file.write_all(match target {
|
file.write_all(match target {
|
||||||
TargetOs::Windows => SPARSE_WINDOWS_SERVER_BINARY,
|
|
||||||
TargetOs::Linux => SPARSE_LINUX_SERVER_BINARY,
|
TargetOs::Linux => SPARSE_LINUX_SERVER_BINARY,
|
||||||
|
TargetOs::Windows => SPARSE_WINDOWS_SERVER_BINARY,
|
||||||
|
TargetOs::WindowsService => SPARSE_WINDOWS_SERVICE_BINARY
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
file.write_all(CONFIG_SEPARATOR).await?;
|
file.write_all(CONFIG_SEPARATOR).await?;
|
||||||
|
|||||||
@ -17,6 +17,7 @@ fn to_socket_addr(src: &str) -> Result<SocketAddr, std::io::Error> {
|
|||||||
pub enum TargetOs {
|
pub enum TargetOs {
|
||||||
Linux,
|
Linux,
|
||||||
Windows,
|
Windows,
|
||||||
|
WindowsService,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::str::FromStr for TargetOs {
|
impl std::str::FromStr for TargetOs {
|
||||||
@ -25,6 +26,7 @@ impl std::str::FromStr for TargetOs {
|
|||||||
match input {
|
match input {
|
||||||
"linux" => Ok(Self::Linux),
|
"linux" => Ok(Self::Linux),
|
||||||
"windows" => Ok(Self::Windows),
|
"windows" => Ok(Self::Windows),
|
||||||
|
"windows-service" => Ok(Self::WindowsService),
|
||||||
_ => Err("could not parse target operating system"),
|
_ => Err("could not parse target operating system"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -106,6 +106,7 @@ pub mod messages {
|
|||||||
pub docker_breakout: bool,
|
pub docker_breakout: bool,
|
||||||
pub setuid: bool,
|
pub setuid: bool,
|
||||||
pub root: bool,
|
pub root: bool,
|
||||||
|
pub service: bool,
|
||||||
pub userent: Option<String>,
|
pub userent: Option<String>,
|
||||||
pub transport: TransportType,
|
pub transport: TransportType,
|
||||||
pub hostname: Option<String>,
|
pub hostname: Option<String>,
|
||||||
|
|||||||
@ -17,6 +17,7 @@ sparse-05-common = { version = "0.1.0", path = "../sparse-05-common" }
|
|||||||
ecies-ed25519 = { version = "0.5.1", features = ["serde"] }
|
ecies-ed25519 = { version = "0.5.1", features = ["serde"] }
|
||||||
packets = { path = "../../packets" }
|
packets = { path = "../../packets" }
|
||||||
pcap-sys = { path = "../../pcap-sys", optional = true }
|
pcap-sys = { path = "../../pcap-sys", optional = true }
|
||||||
|
windows-service = { version = "0.6.0", optional = true }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
cc = "1.0"
|
cc = "1.0"
|
||||||
@ -25,4 +26,5 @@ cc = "1.0"
|
|||||||
default = ["pcap"]
|
default = ["pcap"]
|
||||||
docker-breakout = []
|
docker-breakout = []
|
||||||
exit = []
|
exit = []
|
||||||
|
service = ["dep:windows-service"]
|
||||||
pcap = ["dep:pcap-sys"]
|
pcap = ["dep:pcap-sys"]
|
||||||
|
|||||||
@ -11,6 +11,7 @@ pub struct SrvCapabilities {
|
|||||||
pub docker_breakout: bool,
|
pub docker_breakout: bool,
|
||||||
pub setuid: bool,
|
pub setuid: bool,
|
||||||
pub root: bool,
|
pub root: bool,
|
||||||
|
pub service: bool,
|
||||||
pub userent: Option<String>,
|
pub userent: Option<String>,
|
||||||
pub transport: TransportType,
|
pub transport: TransportType,
|
||||||
pub hostname: Option<String>,
|
pub hostname: Option<String>,
|
||||||
@ -26,6 +27,7 @@ impl SrvCapabilities {
|
|||||||
operating_system: self.operating_system.clone(),
|
operating_system: self.operating_system.clone(),
|
||||||
root: self.root,
|
root: self.root,
|
||||||
setuid: self.setuid,
|
setuid: self.setuid,
|
||||||
|
service: self.service,
|
||||||
transport: self.transport,
|
transport: self.transport,
|
||||||
userent: self.userent.clone(),
|
userent: self.userent.clone(),
|
||||||
}
|
}
|
||||||
@ -79,7 +81,7 @@ fn get_username(uid: u32) -> anyhow::Result<Option<String>> {
|
|||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
fn get_username(_uid: u32) -> anyhow::Result<Option<String>> {
|
fn get_username(_uid: u32) -> anyhow::Result<Option<String>> {
|
||||||
Ok(std::env::var("USERPROFILE").ok())
|
Ok(std::env::var("USERNAME").ok())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
@ -125,6 +127,7 @@ fn get_current_capabilities() -> anyhow::Result<SrvCapabilities> {
|
|||||||
docker_breakout,
|
docker_breakout,
|
||||||
setuid,
|
setuid,
|
||||||
root,
|
root,
|
||||||
|
service: false,
|
||||||
userent,
|
userent,
|
||||||
transport,
|
transport,
|
||||||
hostname,
|
hostname,
|
||||||
@ -134,20 +137,19 @@ fn get_current_capabilities() -> anyhow::Result<SrvCapabilities> {
|
|||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
fn get_current_capabilities() -> anyhow::Result<SrvCapabilities> {
|
fn get_current_capabilities() -> anyhow::Result<SrvCapabilities> {
|
||||||
let userent = get_username(0)?;
|
let userent = get_username(0)?;
|
||||||
|
let hostname = std::env::var("COMPUTERNAME").ok();
|
||||||
|
let service_name = hostname.clone().map(|name| format!("{name}$"));
|
||||||
|
|
||||||
Ok(SrvCapabilities {
|
Ok(SrvCapabilities {
|
||||||
operating_system: OperatingSystem::Windows,
|
operating_system: OperatingSystem::Windows,
|
||||||
docker_container: false,
|
docker_container: false,
|
||||||
docker_breakout: false,
|
docker_breakout: false,
|
||||||
setuid: false,
|
setuid: false,
|
||||||
|
service: userent.as_deref() == service_name.as_deref(),
|
||||||
root: userent.as_deref() == Some("Administrator"),
|
root: userent.as_deref() == Some("Administrator"),
|
||||||
userent: userent.clone(),
|
userent: userent.clone(),
|
||||||
transport: TransportType::RawUdp, /*if userent.as_deref() == Some("Administrator") {
|
transport: TransportType::RawUdp,
|
||||||
TransportType::RawUdp
|
hostname,
|
||||||
} else {
|
|
||||||
TransportType::Udp
|
|
||||||
},*/
|
|
||||||
hostname: None,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use std::{
|
|||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
net::Ipv4Addr,
|
net::Ipv4Addr,
|
||||||
sync::{mpsc::channel, Arc, Mutex},
|
sync::{mpsc::channel, Arc, Mutex},
|
||||||
thread,
|
thread, ffi::OsString,
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::{bail, Context};
|
use anyhow::{bail, Context};
|
||||||
@ -18,7 +18,7 @@ mod capabilities;
|
|||||||
mod connection;
|
mod connection;
|
||||||
mod interface;
|
mod interface;
|
||||||
|
|
||||||
fn main() -> anyhow::Result<()> {
|
fn main_to_run() -> anyhow::Result<()> {
|
||||||
simple_logger::SimpleLogger::new()
|
simple_logger::SimpleLogger::new()
|
||||||
.with_level(log::LevelFilter::Off)
|
.with_level(log::LevelFilter::Off)
|
||||||
.with_module_level("sparse-05-server", log::LevelFilter::Debug)
|
.with_module_level("sparse-05-server", log::LevelFilter::Debug)
|
||||||
@ -119,3 +119,37 @@ fn main() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn main() -> anyhow::Result<()> {
|
||||||
|
main_to_run()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(all(windows, feature = "service"))]
|
||||||
|
fn main() -> Result<(), windows_service::Error> {
|
||||||
|
windows_main::actual_main_func()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(all(windows, not(feature = "service")))]
|
||||||
|
fn main() -> anyhow::Result<()> {
|
||||||
|
main_to_run()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(all(windows, feature = "service"))]
|
||||||
|
mod windows_main {
|
||||||
|
use std::ffi::OsString;
|
||||||
|
use windows_service::service::ServiceControl;
|
||||||
|
use windows_service::service_control_handler::{self, ServiceControlHandlerResult};
|
||||||
|
use windows_service::service_dispatcher;
|
||||||
|
|
||||||
|
fn main_wrapper(args: Vec<OsString>) {
|
||||||
|
super::main_to_run().expect("error running service");
|
||||||
|
}
|
||||||
|
|
||||||
|
windows_service::define_windows_service!(ffi_service_main, main_wrapper);
|
||||||
|
|
||||||
|
pub fn actual_main_func() -> Result<(), windows_service::Error> {
|
||||||
|
service_dispatcher::start("sparse", ffi_service_main)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user