From c963c7f7ff4840ec50f7b6824745919cfdeab3b0 Mon Sep 17 00:00:00 2001
From: Simone Margaritelli <evilsocket@gmail.com>
Date: Mon, 18 Dec 2023 15:09:56 +0100
Subject: [PATCH] new: added socks5 plugin (closes #26)

---
 Cargo.lock                | 15 +++++++++
 Cargo.toml                |  3 ++
 README.md                 |  2 +-
 src/main.rs               |  2 +-
 src/plugins/mod.rs        |  2 ++
 src/plugins/socks5/mod.rs | 66 +++++++++++++++++++++++++++++++++++++++
 test-servers/socks5.sh    |  8 +++++
 7 files changed, 96 insertions(+), 2 deletions(-)
 create mode 100644 src/plugins/socks5/mod.rs
 create mode 100755 test-servers/socks5.sh

diff --git a/Cargo.lock b/Cargo.lock
index 4b8fec3..e90927b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1289,6 +1289,20 @@ version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
 
+[[package]]
+name = "fast-socks5"
+version = "0.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d449e348301d5fb9b0e5781510d8235ffe3bbac3286bd305462736a9e7043039"
+dependencies = [
+ "anyhow",
+ "async-trait",
+ "log",
+ "thiserror",
+ "tokio",
+ "tokio-stream",
+]
+
 [[package]]
 name = "fastrand"
 version = "2.0.1"
@@ -2013,6 +2027,7 @@ dependencies = [
  "ctor",
  "ctrlc",
  "env_logger",
+ "fast-socks5",
  "glob",
  "hex",
  "human_bytes",
diff --git a/Cargo.toml b/Cargo.toml
index 1739042..cd5b35a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -79,6 +79,7 @@ scylla = { version = "0.10.1", optional = true }
 paho-mqtt = { version = "0.12.3", optional = true }
 csv = "1.3.0"
 pavao = { version = "0.2.3", optional = true }
+fast-socks5 = { version = "0.9.2", optional = true }
 
 [dev-dependencies]
 tempfile = "3.8.0"
@@ -109,6 +110,7 @@ default = [
     "scylla",
     "tcp_ports",
     "samba",
+    "socks5",
 ]
 http = ["dep:url", "dep:reqwest", "dep:base64", "dep:ntlmclient"]
 dns = ["dep:trust-dns-resolver"]
@@ -137,6 +139,7 @@ redis = []
 scylla = ["dep:scylla"]
 tcp_ports = []
 samba = ["dep:pavao"]
+socks5 = ["dep:fast-socks5"]
 
 [profile.release]
 lto = true        # Enable link-time optimization
diff --git a/README.md b/README.md
index 8000d52..5a3d1fc 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@ For the building instructions, usage and the complete list of options [check the
 
 ## Supported Protocols/Features:
 
-AMQP (ActiveMQ, RabbitMQ, Qpid, JORAM and Solace), Cassandra/ScyllaDB, DNS subdomain enumeration, FTP, HTTP (basic authentication, NTLMv1, NTLMv2, multipart form, custom requests with CSRF support, files/folders enumeration, virtual host enumeration), IMAP, Kerberos pre-authentication and user enumeration, LDAP, MongoDB, MQTT, Microsoft SQL, MySQL, Oracle, PostgreSQL, POP3, RDP, Redis, Samba, SSH / SFTP, SMTP, STOMP (ActiveMQ, RabbitMQ, HornetQ and OpenMQ), TCP port scanning, Telnet, VNC.
+AMQP (ActiveMQ, RabbitMQ, Qpid, JORAM and Solace), Cassandra/ScyllaDB, DNS subdomain enumeration, FTP, HTTP (basic authentication, NTLMv1, NTLMv2, multipart form, custom requests with CSRF support, files/folders enumeration, virtual host enumeration), IMAP, Kerberos pre-authentication and user enumeration, LDAP, MongoDB, MQTT, Microsoft SQL, MySQL, Oracle, PostgreSQL, POP3, RDP, Redis, Samba, SSH / SFTP, SMTP, Socks5, STOMP (ActiveMQ, RabbitMQ, HornetQ and OpenMQ), TCP port scanning, Telnet, VNC.
 
 ## Benchmark
 
diff --git a/src/main.rs b/src/main.rs
index 3ca4f0a..08ec6d9 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -27,7 +27,7 @@ fn setup() -> Result<Options, session::Error> {
 
     if env::var_os("RUST_LOG").is_none() {
         // set `RUST_LOG=debug` to see debug logs
-        env::set_var("RUST_LOG", "info,blocking=off,pavao=off");
+        env::set_var("RUST_LOG", "info,blocking=off,pavao=off,fast_socks5=off");
     }
 
     env_logger::builder()
diff --git a/src/plugins/mod.rs b/src/plugins/mod.rs
index ee388c0..1ae31fa 100644
--- a/src/plugins/mod.rs
+++ b/src/plugins/mod.rs
@@ -45,6 +45,8 @@ pub(crate) mod samba;
 pub(crate) mod scylla;
 #[cfg(feature = "smtp")]
 pub(crate) mod smtp;
+#[cfg(feature = "socks5")]
+pub(crate) mod socks5;
 #[cfg(feature = "sql")]
 mod sql;
 #[cfg(feature = "ssh")]
diff --git a/src/plugins/socks5/mod.rs b/src/plugins/socks5/mod.rs
new file mode 100644
index 0000000..344340e
--- /dev/null
+++ b/src/plugins/socks5/mod.rs
@@ -0,0 +1,66 @@
+use std::time::Duration;
+
+use async_trait::async_trait;
+use ctor::ctor;
+
+use crate::session::{Error, Loot};
+use crate::utils;
+use crate::Options;
+use crate::Plugin;
+
+use crate::creds::Credentials;
+
+#[ctor]
+fn register() {
+    crate::plugins::manager::register("socks5", Box::new(Socks5::new()));
+}
+
+#[derive(Clone)]
+pub(crate) struct Socks5 {}
+
+impl Socks5 {
+    pub fn new() -> Self {
+        Socks5 {}
+    }
+}
+
+#[async_trait]
+impl Plugin for Socks5 {
+    fn description(&self) -> &'static str {
+        "SOCKS5 password authentication."
+    }
+
+    fn setup(&mut self, _opts: &Options) -> Result<(), Error> {
+        Ok(())
+    }
+
+    async fn attempt(&self, creds: &Credentials, timeout: Duration) -> Result<Option<Loot>, Error> {
+        let address: String = utils::parse_target_address(&creds.target, 1080)?;
+        let res = tokio::time::timeout(
+            timeout,
+            fast_socks5::client::Socks5Stream::connect_with_password(
+                address.clone(),
+                "ifcfg.co".to_owned(),
+                80,
+                creds.username.clone(),
+                creds.password.clone(),
+                fast_socks5::client::Config::default(),
+            ),
+        )
+        .await
+        .map_err(|e| e.to_string())?;
+
+        return Ok(if res.is_ok() {
+            Some(Loot::new(
+                "socks5",
+                &address,
+                [
+                    ("username".to_owned(), creds.username.to_owned()),
+                    ("password".to_owned(), creds.password.to_owned()),
+                ],
+            ))
+        } else {
+            None
+        });
+    }
+}
diff --git a/test-servers/socks5.sh b/test-servers/socks5.sh
new file mode 100755
index 0000000..238c66f
--- /dev/null
+++ b/test-servers/socks5.sh
@@ -0,0 +1,8 @@
+docker run \
+    --security-opt no-new-privileges \
+    --name socks5 \
+    --restart unless-stopped \
+    -p 1080:1080 \
+    -e PROXY_USER=admin666 \
+    -e PROXY_PASSWORD=test12345 \
+    yarmak/socks5-server
\ No newline at end of file