mirror of
https://github.com/pumpbin/pumpbin
synced 2026-03-14 23:04:30 -07:00
feat!: v1.0.0
Implementing a Plug-in System with Extism. Serialize the Plugin struct with Cap'n Proto for backward compatibility. Refactor the project code.
This commit is contained in:
1763
Cargo.lock
generated
1763
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
14
Cargo.toml
14
Cargo.toml
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "pumpbin"
|
name = "pumpbin"
|
||||||
version = "0.3.0"
|
version = "1.0.0"
|
||||||
authors = ["b1n <b1n@b1n.io>"]
|
authors = ["b1n <b1n@b1n.io>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "PumpBin is an Implant Generation Platform."
|
description = "PumpBin is an Implant Generation Platform."
|
||||||
@@ -19,19 +19,20 @@ path = "src/bin/maker.rs"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
rfd = { version = "0.14.1", default-features = false , features = ["gtk3"]}
|
rfd = { version = "0.14.1", default-features = false , features = ["gtk3"]}
|
||||||
dirs = "5.0.1"
|
dirs = "5.0.1"
|
||||||
flatbuffers = "24.3.25"
|
|
||||||
open = "5.1.4"
|
open = "5.1.4"
|
||||||
bincode = { version = "2.0.0-rc.3", default-features = false , features = ["alloc", "derive", "std"]}
|
bincode = { version = "2.0.0-rc.3", default-features = false , features = ["alloc", "derive", "std"]}
|
||||||
anyhow = "1.0.86"
|
anyhow = "1.0.86"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
memchr = "2.7.4"
|
memchr = "2.7.4"
|
||||||
aes-gcm = "0.10.3"
|
capnp = "0.19"
|
||||||
tokio = { version = "1.38.0", default-features = false , features = ["time"]}
|
extism = "1.4.1"
|
||||||
|
serde = { version = "1.0.203", features = ["derive"] }
|
||||||
|
serde_json = "1.0.120"
|
||||||
|
|
||||||
[dependencies.iced]
|
[dependencies.iced]
|
||||||
version = "0.13.0-dev"
|
version = "0.13.0-dev"
|
||||||
git = "https://github.com/iced-rs/iced"
|
git = "https://github.com/iced-rs/iced"
|
||||||
rev = "6c1027af8d54ad21e282337b53097eb196d62c00"
|
rev = "978327f9e7f68d3e5bc280faa0617487d8eabc57"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["advanced", "svg", "tokio", "wgpu", "image"]
|
features = ["advanced", "svg", "tokio", "wgpu", "image"]
|
||||||
|
|
||||||
@@ -44,6 +45,9 @@ winresource = "0.1.17"
|
|||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tempfile = "3.10.1"
|
tempfile = "3.10.1"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
capnpc = "0.19"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
strip = true
|
strip = true
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
|
|||||||
12
build.rs
12
build.rs
@@ -1,4 +1,16 @@
|
|||||||
|
fn build_capnp() {
|
||||||
|
capnpc::CompilerCommand::new()
|
||||||
|
.src_prefix("capnp")
|
||||||
|
.file("capnp/plugin.capnp")
|
||||||
|
.output_path("capnp")
|
||||||
|
.run()
|
||||||
|
.expect("schema compiler command");
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
build_capnp();
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
{
|
{
|
||||||
let mut res = winresource::WindowsResource::new();
|
let mut res = winresource::WindowsResource::new();
|
||||||
|
|||||||
40
capnp/plugin.capnp
Normal file
40
capnp/plugin.capnp
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
@0x96d5aac4519892f3;
|
||||||
|
|
||||||
|
struct Plugin {
|
||||||
|
version @0 : Text;
|
||||||
|
info @1 :PluginInfo;
|
||||||
|
replace @2 :PluginReplace;
|
||||||
|
bins @3 :PluginBins;
|
||||||
|
plugins @4 :PluginPlugins;
|
||||||
|
|
||||||
|
struct PluginInfo{
|
||||||
|
pluginName @0 :Text;
|
||||||
|
author @1 :Text;
|
||||||
|
version @2 :Text;
|
||||||
|
desc @3 :Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PluginReplace {
|
||||||
|
srcPrefix @0 :Data;
|
||||||
|
sizeHolder @1 :Data;
|
||||||
|
maxLen @2 :UInt64;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PluginBins {
|
||||||
|
windows @0 :Bins;
|
||||||
|
linux @1 :Bins;
|
||||||
|
darwin @2 :Bins;
|
||||||
|
|
||||||
|
struct Bins {
|
||||||
|
executable @0 :Data;
|
||||||
|
dynamicLibrary @1 :Data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PluginPlugins {
|
||||||
|
encryptShellcode @0 :Data;
|
||||||
|
formatEncryptedShellcode @1 :Data;
|
||||||
|
formatUrlRemote @2 :Data;
|
||||||
|
uploadFinalShellcodeRemote @3 :Data;
|
||||||
|
}
|
||||||
|
}
|
||||||
1890
capnp/plugin_capnp.rs
Normal file
1890
capnp/plugin_capnp.rs
Normal file
File diff suppressed because it is too large
Load Diff
816
src/bin/maker.rs
816
src/bin/maker.rs
@@ -1,66 +1,163 @@
|
|||||||
#![windows_subsystem = "windows"]
|
#![windows_subsystem = "windows"]
|
||||||
|
|
||||||
use std::{fs, path::PathBuf, usize};
|
use std::{fs, ops::Not, path::PathBuf};
|
||||||
|
|
||||||
|
use anyhow::{anyhow, bail};
|
||||||
use dirs::{desktop_dir, home_dir};
|
use dirs::{desktop_dir, home_dir};
|
||||||
use iced::{
|
use iced::{
|
||||||
advanced::Application,
|
application,
|
||||||
executor,
|
futures::TryFutureExt,
|
||||||
widget::{
|
widget::{
|
||||||
button, column, horizontal_rule, pick_list, radio, row, svg::Handle, text, text_editor,
|
button, column, horizontal_rule, pick_list, radio, row, svg::Handle, text, text_editor,
|
||||||
text_input, Svg,
|
text_input, Column, Svg,
|
||||||
},
|
},
|
||||||
Alignment, Length, Renderer, Task, Theme,
|
Alignment, Length, Size, Task, Theme,
|
||||||
};
|
};
|
||||||
use pumpbin::{
|
use pumpbin::{
|
||||||
error_dialog,
|
plugin::{Plugin, PluginInfo, PluginReplace},
|
||||||
plugin::{Bins, Plugin},
|
utils::{self, error_dialog, message_dialog},
|
||||||
settings, svg_style, ShellcodeSaveType, JETBRAINS_MONO_FONT,
|
|
||||||
};
|
|
||||||
use pumpbin::{
|
|
||||||
plugin::{EncryptType, Platforms},
|
|
||||||
show_message,
|
|
||||||
};
|
};
|
||||||
|
use pumpbin::{style, ShellcodeSaveType};
|
||||||
use rfd::{AsyncFileDialog, MessageLevel};
|
use rfd::{AsyncFileDialog, MessageLevel};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
if let Err(e) = try_main() {
|
||||||
|
error_dialog(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_main() -> anyhow::Result<()> {
|
||||||
|
let size = Size::new(1200.0, 800.0);
|
||||||
|
|
||||||
|
let mut window_settings = utils::window_settings();
|
||||||
|
window_settings.size = size;
|
||||||
|
window_settings.min_size = Some(size);
|
||||||
|
|
||||||
|
application("PumpBin Maker", Maker::update, Maker::view)
|
||||||
|
.settings(utils::settings())
|
||||||
|
.window(window_settings)
|
||||||
|
.theme(Maker::theme)
|
||||||
|
.run()?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
enum ChooseFileType {
|
||||||
|
WindowsExe,
|
||||||
|
WindowsLib,
|
||||||
|
LinuxExe,
|
||||||
|
LinuxLib,
|
||||||
|
DarwinExe,
|
||||||
|
DarwinLib,
|
||||||
|
EncryptShellcodePlugin,
|
||||||
|
FormatEncryptedShellcodePlugin,
|
||||||
|
FormatUrlRemote,
|
||||||
|
UploadFinalShellcodeRemote,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
enum MakerMessage {
|
||||||
|
PluginNameChanged(String),
|
||||||
|
AuthorChanged(String),
|
||||||
|
VersionChanged(String),
|
||||||
|
SrcPrefixChanged(String),
|
||||||
|
MaxLenChanged(String),
|
||||||
|
ShellcodeSaveTypeChanged(ShellcodeSaveType),
|
||||||
|
SizeHolderChanged(String),
|
||||||
|
WindowsExeChanged(String),
|
||||||
|
WindowsLibChanged(String),
|
||||||
|
LinuxExeChanged(String),
|
||||||
|
LinuxLibChanged(String),
|
||||||
|
DarwinExeChanged(String),
|
||||||
|
DarwinLibChanged(String),
|
||||||
|
EncryptShllcodePluginChanged(String),
|
||||||
|
FormatEncryptedShellcodePluginChanged(String),
|
||||||
|
FormatUrlRemotePluginChanged(String),
|
||||||
|
UploadFinalShellcodeRemotePluginChanged(String),
|
||||||
|
DescAction(text_editor::Action),
|
||||||
|
GenerateClicked,
|
||||||
|
GenerateDone(Result<(), String>),
|
||||||
|
ChooseFileClicked(ChooseFileType),
|
||||||
|
ChooseFileDone((Option<String>, ChooseFileType)),
|
||||||
|
B1nClicked,
|
||||||
|
GithubClicked,
|
||||||
|
ThemeChanged(Theme),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Maker {
|
struct Maker {
|
||||||
plugin_name: String,
|
plugin_name: String,
|
||||||
author: String,
|
author: String,
|
||||||
version: String,
|
version: String,
|
||||||
prefix: String,
|
src_prefix: String,
|
||||||
max_len: String,
|
max_len: String,
|
||||||
shellcode_save_type: ShellcodeSaveType,
|
shellcode_save_type: ShellcodeSaveType,
|
||||||
size_holder: String,
|
size_holder: String,
|
||||||
encrypt_type: EncryptType,
|
|
||||||
windows_exe: String,
|
windows_exe: String,
|
||||||
windows_lib: String,
|
windows_lib: String,
|
||||||
linux_exe: String,
|
linux_exe: String,
|
||||||
linux_lib: String,
|
linux_lib: String,
|
||||||
darwin_exe: String,
|
darwin_exe: String,
|
||||||
darwin_lib: String,
|
darwin_lib: String,
|
||||||
|
encrypt_shellcode_plugin: String,
|
||||||
|
format_encrypted_shellcode_plugin: String,
|
||||||
|
format_url_remote_plugin: String,
|
||||||
|
upload_final_shellcode_remote_plugin: String,
|
||||||
desc: text_editor::Content,
|
desc: text_editor::Content,
|
||||||
pumpbin_version: String,
|
pumpbin_version: String,
|
||||||
selected_theme: Theme,
|
selected_theme: Theme,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Maker {
|
||||||
|
fn check_generate(&self) -> anyhow::Result<()> {
|
||||||
|
if self.plugin_name.is_empty() {
|
||||||
|
bail!("Plugin Name is empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.src_prefix.is_empty() {
|
||||||
|
bail!("Prefix is empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
let max_len = self.max_len();
|
||||||
|
if max_len.is_empty() {
|
||||||
|
bail!("Max Len is empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if max_len.parse::<usize>().is_err() {
|
||||||
|
bail!("Max Len numeric only.");
|
||||||
|
};
|
||||||
|
|
||||||
|
if let ShellcodeSaveType::Local = self.shellcode_save_type() {
|
||||||
|
if self.size_holder().is_empty() {
|
||||||
|
bail!("Size Holder is empty.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
anyhow::Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for Maker {
|
impl Default for Maker {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
plugin_name: Default::default(),
|
plugin_name: Default::default(),
|
||||||
author: Default::default(),
|
author: Default::default(),
|
||||||
version: Default::default(),
|
version: Default::default(),
|
||||||
prefix: Default::default(),
|
src_prefix: Default::default(),
|
||||||
max_len: Default::default(),
|
max_len: Default::default(),
|
||||||
shellcode_save_type: ShellcodeSaveType::Local,
|
shellcode_save_type: Default::default(),
|
||||||
size_holder: Default::default(),
|
size_holder: Default::default(),
|
||||||
encrypt_type: EncryptType::None,
|
|
||||||
windows_exe: Default::default(),
|
windows_exe: Default::default(),
|
||||||
windows_lib: Default::default(),
|
windows_lib: Default::default(),
|
||||||
linux_exe: Default::default(),
|
linux_exe: Default::default(),
|
||||||
linux_lib: Default::default(),
|
linux_lib: Default::default(),
|
||||||
darwin_exe: Default::default(),
|
darwin_exe: Default::default(),
|
||||||
darwin_lib: Default::default(),
|
darwin_lib: Default::default(),
|
||||||
|
encrypt_shellcode_plugin: Default::default(),
|
||||||
|
format_encrypted_shellcode_plugin: Default::default(),
|
||||||
|
format_url_remote_plugin: Default::default(),
|
||||||
|
upload_final_shellcode_remote_plugin: Default::default(),
|
||||||
desc: text_editor::Content::new(),
|
desc: text_editor::Content::new(),
|
||||||
pumpbin_version: env!("CARGO_PKG_VERSION").into(),
|
pumpbin_version: env!("CARGO_PKG_VERSION").into(),
|
||||||
selected_theme: Theme::CatppuccinMacchiato,
|
selected_theme: Theme::CatppuccinMacchiato,
|
||||||
@@ -81,8 +178,8 @@ impl Maker {
|
|||||||
&self.version
|
&self.version
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prefix(&self) -> &str {
|
fn src_prefix(&self) -> &str {
|
||||||
&self.prefix
|
&self.src_prefix
|
||||||
}
|
}
|
||||||
|
|
||||||
fn max_len(&self) -> &str {
|
fn max_len(&self) -> &str {
|
||||||
@@ -97,14 +194,6 @@ impl Maker {
|
|||||||
&self.size_holder
|
&self.size_holder
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encrypt_type(&self) -> &EncryptType {
|
|
||||||
&self.encrypt_type
|
|
||||||
}
|
|
||||||
|
|
||||||
fn encrypt_type_mut(&mut self) -> &mut EncryptType {
|
|
||||||
&mut self.encrypt_type
|
|
||||||
}
|
|
||||||
|
|
||||||
fn windows_exe(&self) -> &str {
|
fn windows_exe(&self) -> &str {
|
||||||
&self.windows_exe
|
&self.windows_exe
|
||||||
}
|
}
|
||||||
@@ -129,6 +218,22 @@ impl Maker {
|
|||||||
&self.darwin_lib
|
&self.darwin_lib
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn encrypt_shellcode_plugin(&self) -> &str {
|
||||||
|
&self.encrypt_shellcode_plugin
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_encrypted_shellcode_plugin(&self) -> &str {
|
||||||
|
&self.format_encrypted_shellcode_plugin
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_url_remote_plugin(&self) -> &str {
|
||||||
|
&self.format_url_remote_plugin
|
||||||
|
}
|
||||||
|
|
||||||
|
fn upload_final_shellcode_remote_plugin(&self) -> &str {
|
||||||
|
&self.upload_final_shellcode_remote_plugin
|
||||||
|
}
|
||||||
|
|
||||||
fn desc(&self) -> &text_editor::Content {
|
fn desc(&self) -> &text_editor::Content {
|
||||||
&self.desc
|
&self.desc
|
||||||
}
|
}
|
||||||
@@ -146,399 +251,216 @@ impl Maker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
impl Maker {
|
||||||
enum ChooseFileType {
|
pub fn update(&mut self, message: MakerMessage) -> iced::Task<MakerMessage> {
|
||||||
WindowsExe,
|
|
||||||
WindowsLib,
|
|
||||||
LinuxExe,
|
|
||||||
LinuxLib,
|
|
||||||
DarwinExe,
|
|
||||||
DarwinLib,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
enum MakerMessage {
|
|
||||||
PluginNameChanged(String),
|
|
||||||
AuthorChanged(String),
|
|
||||||
VersionChanged(String),
|
|
||||||
PrefixChanged(String),
|
|
||||||
MaxLenChanged(String),
|
|
||||||
ShellcodeSaveTypeChanged(ShellcodeSaveType),
|
|
||||||
SizeHolderChanged(String),
|
|
||||||
EncryptTypeChanged(EncryptType),
|
|
||||||
XorPassChanged(String),
|
|
||||||
AesKeyChanged(String),
|
|
||||||
AesNonceChanged(String),
|
|
||||||
WindowsExeChanged(String),
|
|
||||||
WindowsLibChanged(String),
|
|
||||||
LinuxExeChanged(String),
|
|
||||||
LinuxLibChanged(String),
|
|
||||||
DarwinExeChanged(String),
|
|
||||||
DarwinLibChanged(String),
|
|
||||||
DescAction(text_editor::Action),
|
|
||||||
GenerateClicked,
|
|
||||||
GenerateDone(Result<(), String>),
|
|
||||||
ChooseFileClicked(ChooseFileType),
|
|
||||||
WindowsExeChooseDone(Result<String, String>),
|
|
||||||
WindowsLibChooseDone(Result<String, String>),
|
|
||||||
LinuxExeChooseDone(Result<String, String>),
|
|
||||||
LinuxLibChooseDone(Result<String, String>),
|
|
||||||
DarwinExeChooseDone(Result<String, String>),
|
|
||||||
DarwinLibChooseDone(Result<String, String>),
|
|
||||||
B1nClicked,
|
|
||||||
GithubClicked,
|
|
||||||
ThemeChanged(Theme),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Application for Maker {
|
|
||||||
type Executor = executor::Default;
|
|
||||||
type Flags = ();
|
|
||||||
type Message = MakerMessage;
|
|
||||||
type Theme = Theme;
|
|
||||||
type Renderer = Renderer;
|
|
||||||
|
|
||||||
fn new(_flags: Self::Flags) -> (Self, iced::Task<Self::Message>) {
|
|
||||||
(Self::default(), Task::none())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn title(&self) -> String {
|
|
||||||
"PumpBin Maker".to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update(&mut self, message: Self::Message) -> iced::Task<Self::Message> {
|
|
||||||
match message {
|
match message {
|
||||||
MakerMessage::PluginNameChanged(x) => {
|
MakerMessage::PluginNameChanged(x) => self.plugin_name = x,
|
||||||
self.plugin_name = x;
|
MakerMessage::AuthorChanged(x) => self.author = x,
|
||||||
Task::none()
|
MakerMessage::VersionChanged(x) => self.version = x,
|
||||||
|
MakerMessage::SrcPrefixChanged(x) => self.src_prefix = x,
|
||||||
|
MakerMessage::MaxLenChanged(x) => self.max_len = x,
|
||||||
|
MakerMessage::ShellcodeSaveTypeChanged(x) => self.shellcode_save_type = x,
|
||||||
|
MakerMessage::SizeHolderChanged(x) => self.size_holder = x,
|
||||||
|
MakerMessage::WindowsExeChanged(x) => self.windows_exe = x,
|
||||||
|
MakerMessage::WindowsLibChanged(x) => self.windows_lib = x,
|
||||||
|
MakerMessage::LinuxExeChanged(x) => self.linux_exe = x,
|
||||||
|
MakerMessage::LinuxLibChanged(x) => self.linux_lib = x,
|
||||||
|
MakerMessage::DarwinExeChanged(x) => self.darwin_exe = x,
|
||||||
|
MakerMessage::DarwinLibChanged(x) => self.darwin_lib = x,
|
||||||
|
MakerMessage::EncryptShllcodePluginChanged(x) => self.encrypt_shellcode_plugin = x,
|
||||||
|
MakerMessage::FormatEncryptedShellcodePluginChanged(x) => {
|
||||||
|
self.format_encrypted_shellcode_plugin = x
|
||||||
}
|
}
|
||||||
MakerMessage::AuthorChanged(x) => {
|
MakerMessage::FormatUrlRemotePluginChanged(x) => self.format_url_remote_plugin = x,
|
||||||
self.author = x;
|
MakerMessage::UploadFinalShellcodeRemotePluginChanged(x) => {
|
||||||
Task::none()
|
self.upload_final_shellcode_remote_plugin = x
|
||||||
}
|
|
||||||
MakerMessage::VersionChanged(x) => {
|
|
||||||
self.version = x;
|
|
||||||
Task::none()
|
|
||||||
}
|
|
||||||
MakerMessage::PrefixChanged(x) => {
|
|
||||||
self.prefix = x;
|
|
||||||
Task::none()
|
|
||||||
}
|
|
||||||
MakerMessage::MaxLenChanged(x) => {
|
|
||||||
self.max_len = x;
|
|
||||||
Task::none()
|
|
||||||
}
|
|
||||||
MakerMessage::ShellcodeSaveTypeChanged(x) => {
|
|
||||||
self.shellcode_save_type = x;
|
|
||||||
Task::none()
|
|
||||||
}
|
|
||||||
MakerMessage::SizeHolderChanged(x) => {
|
|
||||||
self.size_holder = x;
|
|
||||||
Task::none()
|
|
||||||
}
|
|
||||||
|
|
||||||
MakerMessage::EncryptTypeChanged(x) => {
|
|
||||||
self.encrypt_type = x;
|
|
||||||
Task::none()
|
|
||||||
}
|
|
||||||
MakerMessage::XorPassChanged(x) => {
|
|
||||||
if let EncryptType::Xor(xor) = self.encrypt_type_mut() {
|
|
||||||
*xor = x.as_bytes().to_vec();
|
|
||||||
}
|
|
||||||
Task::none()
|
|
||||||
}
|
|
||||||
MakerMessage::AesKeyChanged(x) => {
|
|
||||||
if let EncryptType::AesGcm(aes_gcm) = self.encrypt_type_mut() {
|
|
||||||
*aes_gcm.key_holder_mut() = x.as_bytes().to_vec();
|
|
||||||
}
|
|
||||||
Task::none()
|
|
||||||
}
|
|
||||||
MakerMessage::AesNonceChanged(x) => {
|
|
||||||
if let EncryptType::AesGcm(aes_gcm) = self.encrypt_type_mut() {
|
|
||||||
*aes_gcm.nonce_holder_mut() = x.as_bytes().to_vec();
|
|
||||||
}
|
|
||||||
Task::none()
|
|
||||||
}
|
|
||||||
MakerMessage::WindowsExeChanged(x) => {
|
|
||||||
self.windows_exe = x;
|
|
||||||
Task::none()
|
|
||||||
}
|
|
||||||
MakerMessage::WindowsLibChanged(x) => {
|
|
||||||
self.windows_lib = x;
|
|
||||||
Task::none()
|
|
||||||
}
|
|
||||||
MakerMessage::LinuxExeChanged(x) => {
|
|
||||||
self.linux_exe = x;
|
|
||||||
Task::none()
|
|
||||||
}
|
|
||||||
MakerMessage::LinuxLibChanged(x) => {
|
|
||||||
self.linux_lib = x;
|
|
||||||
Task::none()
|
|
||||||
}
|
|
||||||
MakerMessage::DarwinExeChanged(x) => {
|
|
||||||
self.darwin_exe = x;
|
|
||||||
Task::none()
|
|
||||||
}
|
|
||||||
MakerMessage::DarwinLibChanged(x) => {
|
|
||||||
self.darwin_lib = x;
|
|
||||||
Task::none()
|
|
||||||
}
|
|
||||||
MakerMessage::DescAction(x) => {
|
|
||||||
self.desc_mut().perform(x);
|
|
||||||
Task::none()
|
|
||||||
}
|
}
|
||||||
|
MakerMessage::DescAction(x) => self.desc_mut().perform(x),
|
||||||
MakerMessage::GenerateClicked => {
|
MakerMessage::GenerateClicked => {
|
||||||
if self.plugin_name().is_empty() {
|
if let Err(e) = self.check_generate() {
|
||||||
show_message("Plugin Name is empty.".to_string(), MessageLevel::Error);
|
message_dialog(e.to_string(), MessageLevel::Error);
|
||||||
return Task::none();
|
return Task::none();
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.prefix().is_empty() {
|
let mut plugin = Plugin {
|
||||||
show_message("Prefix is empty.".to_string(), MessageLevel::Error);
|
version: self.pumpbin_version().to_string(),
|
||||||
return Task::none();
|
info: PluginInfo {
|
||||||
}
|
plugin_name: self.plugin_name().to_string(),
|
||||||
|
author: {
|
||||||
if self.max_len().is_empty() {
|
let author = self.author().to_string();
|
||||||
show_message("MaxLen is empty.".to_string(), MessageLevel::Error);
|
if author.is_empty() {
|
||||||
return Task::none();
|
"None".to_string()
|
||||||
}
|
} else {
|
||||||
|
author
|
||||||
let max_len;
|
}
|
||||||
if let Ok(max) = self.max_len().parse::<usize>() {
|
|
||||||
max_len = max;
|
|
||||||
} else {
|
|
||||||
show_message("MaxLen numeric only.".to_string(), MessageLevel::Error);
|
|
||||||
return Task::none();
|
|
||||||
}
|
|
||||||
|
|
||||||
if let ShellcodeSaveType::Local = self.shellcode_save_type() {
|
|
||||||
if self.size_holder().is_empty() {
|
|
||||||
show_message("Size Holder is empty.".to_string(), MessageLevel::Error);
|
|
||||||
return Task::none();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match self.encrypt_type() {
|
|
||||||
EncryptType::None => (),
|
|
||||||
EncryptType::Xor(x) => {
|
|
||||||
if x.is_empty() {
|
|
||||||
show_message("Xor Pass is empty.".to_string(), MessageLevel::Error);
|
|
||||||
return Task::none();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EncryptType::AesGcm(x) => {
|
|
||||||
if x.key_holder().is_empty() {
|
|
||||||
show_message("AesGcm Key is empty.".to_string(), MessageLevel::Error);
|
|
||||||
return Task::none();
|
|
||||||
} else if x.nonce_holder().is_empty() {
|
|
||||||
show_message("AesGcm Nonce is empty.".to_string(), MessageLevel::Error);
|
|
||||||
return Task::none();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let windows_exe_path = PathBuf::from(self.windows_exe());
|
|
||||||
let windows_dll_path = PathBuf::from(self.windows_lib());
|
|
||||||
let windows = match (
|
|
||||||
windows_exe_path.exists() && windows_exe_path.is_file(),
|
|
||||||
windows_dll_path.exists() && windows_dll_path.is_file(),
|
|
||||||
) {
|
|
||||||
(false, false) => None,
|
|
||||||
_ => Some(Bins {
|
|
||||||
executable: if let Ok(bin) = fs::read(&windows_exe_path) {
|
|
||||||
Some(bin)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
},
|
||||||
dynamic_library: if let Ok(bin) = fs::read(&windows_dll_path) {
|
version: {
|
||||||
Some(bin)
|
let version = self.version().to_string();
|
||||||
} else {
|
if version.is_empty() {
|
||||||
None
|
"None".to_string()
|
||||||
|
} else {
|
||||||
|
version
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}),
|
desc: {
|
||||||
|
let desc = self.desc().text();
|
||||||
|
if desc.is_empty() {
|
||||||
|
"None".to_string()
|
||||||
|
} else {
|
||||||
|
desc
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
replace: PluginReplace {
|
||||||
|
src_prefix: self.src_prefix().as_bytes().to_vec(),
|
||||||
|
size_holder: match self.shellcode_save_type() {
|
||||||
|
ShellcodeSaveType::Local => {
|
||||||
|
Some(self.size_holder().as_bytes().to_vec())
|
||||||
|
}
|
||||||
|
ShellcodeSaveType::Remote => None,
|
||||||
|
},
|
||||||
|
max_len: self.max_len().parse().unwrap(),
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let linux_exe_path = PathBuf::from(self.linux_exe());
|
let paths: Vec<(String, ChooseFileType)> = vec![
|
||||||
let linux_dll_path = PathBuf::from(self.linux_lib());
|
(self.windows_exe(), ChooseFileType::WindowsExe),
|
||||||
let linux = match (
|
(self.windows_lib(), ChooseFileType::WindowsLib),
|
||||||
linux_exe_path.exists() && linux_exe_path.is_file(),
|
(self.linux_exe(), ChooseFileType::LinuxExe),
|
||||||
linux_dll_path.exists() && linux_dll_path.is_file(),
|
(self.linux_lib(), ChooseFileType::LinuxLib),
|
||||||
) {
|
(self.darwin_exe(), ChooseFileType::DarwinExe),
|
||||||
(false, false) => None,
|
(self.darwin_lib(), ChooseFileType::DarwinLib),
|
||||||
_ => Some(Bins {
|
(
|
||||||
executable: if let Ok(bin) = fs::read(&linux_exe_path) {
|
self.encrypt_shellcode_plugin(),
|
||||||
Some(bin)
|
ChooseFileType::EncryptShellcodePlugin,
|
||||||
} else {
|
),
|
||||||
None
|
(
|
||||||
},
|
self.format_encrypted_shellcode_plugin(),
|
||||||
dynamic_library: if let Ok(bin) = fs::read(&linux_dll_path) {
|
ChooseFileType::FormatEncryptedShellcodePlugin,
|
||||||
Some(bin)
|
),
|
||||||
} else {
|
(
|
||||||
None
|
self.format_url_remote_plugin(),
|
||||||
},
|
ChooseFileType::FormatUrlRemote,
|
||||||
}),
|
),
|
||||||
};
|
(
|
||||||
|
self.upload_final_shellcode_remote_plugin(),
|
||||||
|
ChooseFileType::UploadFinalShellcodeRemote,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
.into_iter()
|
||||||
|
.map(|(x, y)| (x.to_string(), y))
|
||||||
|
.collect();
|
||||||
|
|
||||||
let darwin_exe_path = PathBuf::from(self.darwin_exe());
|
|
||||||
let darwin_dll_path = PathBuf::from(self.darwin_lib());
|
|
||||||
let darwin = match (
|
|
||||||
darwin_exe_path.exists() && darwin_exe_path.is_file(),
|
|
||||||
darwin_dll_path.exists() && darwin_dll_path.is_file(),
|
|
||||||
) {
|
|
||||||
(false, false) => None,
|
|
||||||
_ => Some(Bins {
|
|
||||||
executable: if let Ok(bin) = fs::read(&darwin_exe_path) {
|
|
||||||
Some(bin)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
dynamic_library: if let Ok(bin) = fs::read(&darwin_dll_path) {
|
|
||||||
Some(bin)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
let plugin = Plugin {
|
|
||||||
plugin_name: self.plugin_name().to_string(),
|
|
||||||
author: match self.author().is_empty() {
|
|
||||||
true => None,
|
|
||||||
false => Some(self.author().to_string()),
|
|
||||||
},
|
|
||||||
version: match self.version().is_empty() {
|
|
||||||
true => None,
|
|
||||||
false => Some(self.version().to_string()),
|
|
||||||
},
|
|
||||||
desc: match self.desc().text().is_empty() {
|
|
||||||
true => None,
|
|
||||||
false => Some(self.desc().text()),
|
|
||||||
},
|
|
||||||
prefix: self.prefix().as_bytes().to_vec(),
|
|
||||||
size_holder: match self.shellcode_save_type() {
|
|
||||||
ShellcodeSaveType::Local => Some(self.size_holder().as_bytes().to_vec()),
|
|
||||||
ShellcodeSaveType::Remote => None,
|
|
||||||
},
|
|
||||||
max_len,
|
|
||||||
encrypt_type: self.encrypt_type().to_owned(),
|
|
||||||
platforms: Platforms {
|
|
||||||
windows,
|
|
||||||
linux,
|
|
||||||
darwin,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let plugin_name = self.plugin_name().to_owned();
|
|
||||||
let make_plugin = async move {
|
let make_plugin = async move {
|
||||||
|
for (path_str, file_type) in paths {
|
||||||
|
if path_str.is_empty().not() {
|
||||||
|
let path = PathBuf::from(path_str);
|
||||||
|
let data = fs::read(path)?;
|
||||||
|
let bin = match file_type {
|
||||||
|
ChooseFileType::WindowsExe => plugin.bins.windows.executable_mut(),
|
||||||
|
ChooseFileType::WindowsLib => {
|
||||||
|
plugin.bins.windows.dynamic_library_mut()
|
||||||
|
}
|
||||||
|
ChooseFileType::LinuxExe => plugin.bins.linux.executable_mut(),
|
||||||
|
ChooseFileType::LinuxLib => plugin.bins.linux.dynamic_library_mut(),
|
||||||
|
ChooseFileType::DarwinExe => plugin.bins.darwin.executable_mut(),
|
||||||
|
ChooseFileType::DarwinLib => {
|
||||||
|
plugin.bins.darwin.dynamic_library_mut()
|
||||||
|
}
|
||||||
|
ChooseFileType::EncryptShellcodePlugin => {
|
||||||
|
plugin.plugins.encrypt_shellcode_mut()
|
||||||
|
}
|
||||||
|
ChooseFileType::FormatEncryptedShellcodePlugin => {
|
||||||
|
plugin.plugins.format_encrypted_shellcode_mut()
|
||||||
|
}
|
||||||
|
ChooseFileType::FormatUrlRemote => {
|
||||||
|
plugin.plugins.format_url_remote_mut()
|
||||||
|
}
|
||||||
|
ChooseFileType::UploadFinalShellcodeRemote => {
|
||||||
|
plugin.plugins.upload_final_shellcode_remote_mut()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
*bin = Some(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let file = AsyncFileDialog::new()
|
let file = AsyncFileDialog::new()
|
||||||
.set_directory(desktop_dir().unwrap_or(".".into()))
|
.set_directory(desktop_dir().unwrap_or(".".into()))
|
||||||
.set_file_name(format!("{}.b1n", plugin_name))
|
.set_file_name(format!("{}.b1n", plugin.info().plugin_name()))
|
||||||
.set_can_create_directories(true)
|
.set_can_create_directories(true)
|
||||||
.set_title("save plugin")
|
.set_title("Save generated plugin")
|
||||||
.save_file()
|
.save_file()
|
||||||
.await
|
.await
|
||||||
.ok_or("Canceled plugin saving.".to_string())?;
|
.ok_or(anyhow!("Canceled the saving of the generated plugin."))?;
|
||||||
|
|
||||||
plugin
|
fs::write(file.path(), plugin.encode_to_vec()?)?;
|
||||||
.write_plugin(file.path())
|
|
||||||
.map_err(|_| "Write plugin failed.".to_string())?;
|
|
||||||
|
|
||||||
Ok(())
|
anyhow::Ok(())
|
||||||
};
|
}
|
||||||
|
.map_err(|e| e.to_string());
|
||||||
|
|
||||||
Task::perform(make_plugin, MakerMessage::GenerateDone)
|
return Task::perform(make_plugin, MakerMessage::GenerateDone);
|
||||||
}
|
}
|
||||||
MakerMessage::GenerateDone(x) => {
|
MakerMessage::GenerateDone(x) => {
|
||||||
match x {
|
match x {
|
||||||
Ok(_) => show_message("Generate done.".to_string(), MessageLevel::Info),
|
Ok(_) => message_dialog("Generate done.".to_string(), MessageLevel::Info),
|
||||||
Err(e) => show_message(e, MessageLevel::Error),
|
Err(e) => message_dialog(e, MessageLevel::Error),
|
||||||
};
|
};
|
||||||
Task::none()
|
|
||||||
}
|
}
|
||||||
MakerMessage::ChooseFileClicked(x) => {
|
MakerMessage::ChooseFileClicked(x) => {
|
||||||
let choose_file = async move {
|
let choose_file = async move {
|
||||||
AsyncFileDialog::new()
|
let file = AsyncFileDialog::new()
|
||||||
.set_directory(home_dir().unwrap_or(".".into()))
|
.set_directory(home_dir().unwrap_or(".".into()))
|
||||||
.set_title("choose file")
|
.set_title("Choose file")
|
||||||
.pick_file()
|
.pick_file()
|
||||||
.await
|
.await
|
||||||
.map(|x| x.path().to_string_lossy().to_string())
|
.map(|x| x.path().to_string_lossy().to_string());
|
||||||
.ok_or("Canceled file selection.".to_string())
|
|
||||||
|
(file, x)
|
||||||
};
|
};
|
||||||
|
|
||||||
Task::perform(
|
return Task::perform(choose_file, MakerMessage::ChooseFileDone);
|
||||||
choose_file,
|
|
||||||
match x {
|
|
||||||
ChooseFileType::WindowsExe => MakerMessage::WindowsExeChooseDone,
|
|
||||||
ChooseFileType::WindowsLib => MakerMessage::WindowsLibChooseDone,
|
|
||||||
ChooseFileType::LinuxExe => MakerMessage::LinuxExeChooseDone,
|
|
||||||
ChooseFileType::LinuxLib => MakerMessage::LinuxLibChooseDone,
|
|
||||||
ChooseFileType::DarwinExe => MakerMessage::DarwinExeChooseDone,
|
|
||||||
ChooseFileType::DarwinLib => MakerMessage::DarwinLibChooseDone,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
MakerMessage::WindowsExeChooseDone(x) => {
|
MakerMessage::ChooseFileDone((path, choose_type)) => {
|
||||||
if let Ok(path) = x {
|
if let Some(path) = path {
|
||||||
self.windows_exe = path;
|
match choose_type {
|
||||||
|
ChooseFileType::WindowsExe => self.windows_exe = path,
|
||||||
|
ChooseFileType::WindowsLib => self.windows_lib = path,
|
||||||
|
ChooseFileType::LinuxExe => self.linux_exe = path,
|
||||||
|
ChooseFileType::LinuxLib => self.linux_lib = path,
|
||||||
|
ChooseFileType::DarwinExe => self.darwin_exe = path,
|
||||||
|
ChooseFileType::DarwinLib => self.darwin_lib = path,
|
||||||
|
ChooseFileType::EncryptShellcodePlugin => {
|
||||||
|
self.encrypt_shellcode_plugin = path
|
||||||
|
}
|
||||||
|
ChooseFileType::FormatEncryptedShellcodePlugin => {
|
||||||
|
self.format_encrypted_shellcode_plugin = path
|
||||||
|
}
|
||||||
|
ChooseFileType::FormatUrlRemote => self.format_url_remote_plugin = path,
|
||||||
|
ChooseFileType::UploadFinalShellcodeRemote => {
|
||||||
|
self.upload_final_shellcode_remote_plugin = path
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Task::none()
|
|
||||||
}
|
|
||||||
MakerMessage::WindowsLibChooseDone(x) => {
|
|
||||||
if let Ok(path) = x {
|
|
||||||
self.windows_lib = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
Task::none()
|
|
||||||
}
|
|
||||||
MakerMessage::LinuxExeChooseDone(x) => {
|
|
||||||
if let Ok(path) = x {
|
|
||||||
self.linux_exe = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
Task::none()
|
|
||||||
}
|
|
||||||
MakerMessage::LinuxLibChooseDone(x) => {
|
|
||||||
if let Ok(path) = x {
|
|
||||||
self.linux_lib = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
Task::none()
|
|
||||||
}
|
|
||||||
MakerMessage::DarwinExeChooseDone(x) => {
|
|
||||||
if let Ok(path) = x {
|
|
||||||
self.darwin_exe = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
Task::none()
|
|
||||||
}
|
|
||||||
MakerMessage::DarwinLibChooseDone(x) => {
|
|
||||||
if let Ok(path) = x {
|
|
||||||
self.darwin_lib = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
Task::none()
|
|
||||||
}
|
}
|
||||||
MakerMessage::B1nClicked => {
|
MakerMessage::B1nClicked => {
|
||||||
if open::that(env!("CARGO_PKG_HOMEPAGE")).is_err() {
|
if open::that(env!("CARGO_PKG_HOMEPAGE")).is_err() {
|
||||||
show_message("Open home failed.".into(), MessageLevel::Error);
|
message_dialog("Open home failed.".into(), MessageLevel::Error);
|
||||||
}
|
}
|
||||||
Task::none()
|
|
||||||
}
|
}
|
||||||
MakerMessage::GithubClicked => {
|
MakerMessage::GithubClicked => {
|
||||||
if open::that(env!("CARGO_PKG_REPOSITORY")).is_err() {
|
if open::that(env!("CARGO_PKG_REPOSITORY")).is_err() {
|
||||||
show_message("Open repo failed.".into(), MessageLevel::Error);
|
message_dialog("Open repo failed.".into(), MessageLevel::Error);
|
||||||
}
|
}
|
||||||
Task::none()
|
|
||||||
}
|
|
||||||
MakerMessage::ThemeChanged(x) => {
|
|
||||||
self.selected_theme = x;
|
|
||||||
Task::none()
|
|
||||||
}
|
}
|
||||||
|
MakerMessage::ThemeChanged(x) => self.selected_theme = x,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view(&self) -> iced::Element<'_, Self::Message, Self::Theme, Self::Renderer> {
|
pub fn view(&self) -> Column<MakerMessage> {
|
||||||
let choose_button = || {
|
let choose_button = || {
|
||||||
button(
|
button(
|
||||||
Svg::new(Handle::from_memory(include_bytes!(
|
Svg::new(Handle::from_memory(include_bytes!(
|
||||||
@@ -548,23 +470,6 @@ impl Application for Maker {
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let pick_list_handle = || pick_list::Handle::Dynamic {
|
|
||||||
closed: pick_list::Icon {
|
|
||||||
font: JETBRAINS_MONO_FONT,
|
|
||||||
code_point: '',
|
|
||||||
size: None,
|
|
||||||
line_height: text::LineHeight::Relative(1.0),
|
|
||||||
shaping: text::Shaping::Basic,
|
|
||||||
},
|
|
||||||
open: pick_list::Icon {
|
|
||||||
font: JETBRAINS_MONO_FONT,
|
|
||||||
code_point: '',
|
|
||||||
size: None,
|
|
||||||
line_height: text::LineHeight::Relative(1.0),
|
|
||||||
shaping: text::Shaping::Basic,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let maker = column![
|
let maker = column![
|
||||||
row![
|
row![
|
||||||
column![
|
column![
|
||||||
@@ -584,11 +489,11 @@ impl Application for Maker {
|
|||||||
.align_items(Alignment::Start),
|
.align_items(Alignment::Start),
|
||||||
column![
|
column![
|
||||||
text("Prefix"),
|
text("Prefix"),
|
||||||
text_input("", self.prefix()).on_input(MakerMessage::PrefixChanged),
|
text_input("", self.src_prefix()).on_input(MakerMessage::SrcPrefixChanged),
|
||||||
]
|
]
|
||||||
.align_items(Alignment::Start),
|
.align_items(Alignment::Start),
|
||||||
column![
|
column![
|
||||||
text("MaxLen"),
|
text("Max Len"),
|
||||||
text_input("", self.max_len()).on_input(MakerMessage::MaxLenChanged),
|
text_input("", self.max_len()).on_input(MakerMessage::MaxLenChanged),
|
||||||
]
|
]
|
||||||
.align_items(Alignment::Start),
|
.align_items(Alignment::Start),
|
||||||
@@ -627,42 +532,6 @@ impl Application for Maker {
|
|||||||
.spacing(20)
|
.spacing(20)
|
||||||
]
|
]
|
||||||
.align_items(Alignment::Start),
|
.align_items(Alignment::Start),
|
||||||
column![
|
|
||||||
text("Encrypt Type"),
|
|
||||||
row![pick_list(
|
|
||||||
EncryptType::all(),
|
|
||||||
Some(self.encrypt_type()),
|
|
||||||
MakerMessage::EncryptTypeChanged
|
|
||||||
)
|
|
||||||
.handle(pick_list_handle())]
|
|
||||||
.push_maybe(match self.encrypt_type() {
|
|
||||||
EncryptType::None => None,
|
|
||||||
EncryptType::Xor(x) => Some(
|
|
||||||
row![
|
|
||||||
text("Pass:"),
|
|
||||||
text_input("", &String::from_utf8_lossy(x))
|
|
||||||
.on_input(MakerMessage::XorPassChanged)
|
|
||||||
]
|
|
||||||
.spacing(10)
|
|
||||||
.align_items(Alignment::Center)
|
|
||||||
),
|
|
||||||
EncryptType::AesGcm(x) => Some(
|
|
||||||
row![
|
|
||||||
text("Key:"),
|
|
||||||
text_input("", &String::from_utf8_lossy(x.key_holder()))
|
|
||||||
.on_input(MakerMessage::AesKeyChanged),
|
|
||||||
text("Nonce:"),
|
|
||||||
text_input("", &String::from_utf8_lossy(x.nonce_holder()))
|
|
||||||
.on_input(MakerMessage::AesNonceChanged)
|
|
||||||
]
|
|
||||||
.spacing(10)
|
|
||||||
.align_items(Alignment::Center)
|
|
||||||
),
|
|
||||||
})
|
|
||||||
.spacing(20)
|
|
||||||
.align_items(Alignment::Center)
|
|
||||||
]
|
|
||||||
.align_items(Alignment::Start),
|
|
||||||
column![
|
column![
|
||||||
text("Windows"),
|
text("Windows"),
|
||||||
row![
|
row![
|
||||||
@@ -713,6 +582,75 @@ impl Application for Maker {
|
|||||||
.spacing(10)
|
.spacing(10)
|
||||||
]
|
]
|
||||||
.align_items(Alignment::Start),
|
.align_items(Alignment::Start),
|
||||||
|
row![
|
||||||
|
column![column![
|
||||||
|
text("Encrypt Shellcode Plug-in"),
|
||||||
|
row![
|
||||||
|
text_input("", self.encrypt_shellcode_plugin())
|
||||||
|
.on_input(MakerMessage::EncryptShllcodePluginChanged),
|
||||||
|
choose_button().on_press(MakerMessage::ChooseFileClicked(
|
||||||
|
ChooseFileType::EncryptShellcodePlugin
|
||||||
|
))
|
||||||
|
]
|
||||||
|
.align_items(Alignment::Center)
|
||||||
|
.spacing(10),
|
||||||
|
]
|
||||||
|
.align_items(Alignment::Start)]
|
||||||
|
.push_maybe(match self.shellcode_save_type() {
|
||||||
|
ShellcodeSaveType::Local => None,
|
||||||
|
ShellcodeSaveType::Remote => Some(column![
|
||||||
|
text("Format Url Remote Plug-in"),
|
||||||
|
row![
|
||||||
|
text_input("", self.format_url_remote_plugin())
|
||||||
|
.on_input(MakerMessage::FormatUrlRemotePluginChanged),
|
||||||
|
choose_button().on_press(MakerMessage::ChooseFileClicked(
|
||||||
|
ChooseFileType::FormatUrlRemote
|
||||||
|
))
|
||||||
|
]
|
||||||
|
.align_items(Alignment::Center)
|
||||||
|
.spacing(10)
|
||||||
|
]),
|
||||||
|
})
|
||||||
|
.width(Length::FillPortion(1))
|
||||||
|
.align_items(Alignment::Center),
|
||||||
|
column![column![
|
||||||
|
text("Format Encrypted Shellcode Plug-in"),
|
||||||
|
row![
|
||||||
|
text_input("", self.format_encrypted_shellcode_plugin())
|
||||||
|
.on_input(MakerMessage::FormatEncryptedShellcodePluginChanged),
|
||||||
|
choose_button().on_press(MakerMessage::ChooseFileClicked(
|
||||||
|
ChooseFileType::FormatEncryptedShellcodePlugin
|
||||||
|
))
|
||||||
|
]
|
||||||
|
.align_items(Alignment::Center)
|
||||||
|
.spacing(10),
|
||||||
|
]
|
||||||
|
.align_items(Alignment::Start)]
|
||||||
|
.push_maybe(match self.shellcode_save_type() {
|
||||||
|
ShellcodeSaveType::Local => None,
|
||||||
|
ShellcodeSaveType::Remote => Some(
|
||||||
|
column![
|
||||||
|
text("Upload Final Shellcode Remote Plug-in"),
|
||||||
|
row![
|
||||||
|
text_input("", self.upload_final_shellcode_remote_plugin())
|
||||||
|
.on_input(
|
||||||
|
MakerMessage::UploadFinalShellcodeRemotePluginChanged
|
||||||
|
),
|
||||||
|
choose_button().on_press(MakerMessage::ChooseFileClicked(
|
||||||
|
ChooseFileType::UploadFinalShellcodeRemote
|
||||||
|
))
|
||||||
|
]
|
||||||
|
.align_items(Alignment::Center)
|
||||||
|
.spacing(10)
|
||||||
|
]
|
||||||
|
.align_items(Alignment::Start)
|
||||||
|
),
|
||||||
|
})
|
||||||
|
.width(Length::FillPortion(1))
|
||||||
|
.align_items(Alignment::Center)
|
||||||
|
]
|
||||||
|
.align_items(Alignment::Center)
|
||||||
|
.spacing(10),
|
||||||
column![
|
column![
|
||||||
text("Description"),
|
text("Description"),
|
||||||
text_editor(self.desc())
|
text_editor(self.desc())
|
||||||
@@ -739,7 +677,7 @@ impl Application for Maker {
|
|||||||
)))
|
)))
|
||||||
.width(30)
|
.width(30)
|
||||||
.height(30)
|
.height(30)
|
||||||
.style(svg_style::svg_primary_base),
|
.style(style::svg::svg_primary_base),
|
||||||
)
|
)
|
||||||
.style(button::text)
|
.style(button::text)
|
||||||
.on_press(MakerMessage::B1nClicked);
|
.on_press(MakerMessage::B1nClicked);
|
||||||
@@ -749,7 +687,7 @@ impl Application for Maker {
|
|||||||
)))
|
)))
|
||||||
.width(30)
|
.width(30)
|
||||||
.height(30)
|
.height(30)
|
||||||
.style(svg_style::svg_primary_base),
|
.style(style::svg::svg_primary_base),
|
||||||
)
|
)
|
||||||
.style(button::text)
|
.style(button::text)
|
||||||
.on_press(MakerMessage::GithubClicked);
|
.on_press(MakerMessage::GithubClicked);
|
||||||
@@ -778,24 +716,10 @@ impl Application for Maker {
|
|||||||
]
|
]
|
||||||
.align_items(Alignment::Center);
|
.align_items(Alignment::Center);
|
||||||
|
|
||||||
column![maker, footer].align_items(Alignment::Center).into()
|
column![maker, footer].align_items(Alignment::Center)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn theme(&self) -> Self::Theme {
|
pub fn theme(&self) -> Theme {
|
||||||
self.selected_theme()
|
self.selected_theme()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
|
||||||
match try_main() {
|
|
||||||
Ok(_) => (),
|
|
||||||
Err(e) => {
|
|
||||||
error_dialog(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn try_main() -> anyhow::Result<()> {
|
|
||||||
Maker::run(settings())?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|||||||
920
src/lib.rs
920
src/lib.rs
File diff suppressed because it is too large
Load Diff
21
src/main.rs
21
src/main.rs
@@ -4,15 +4,16 @@ use std::{fs, ops::Not};
|
|||||||
|
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use dirs::data_dir;
|
use dirs::data_dir;
|
||||||
use iced::advanced::Application;
|
use iced::application;
|
||||||
use pumpbin::{error_dialog, plugin::CONFIG_FILE_PATH, settings, Pumpbin};
|
use pumpbin::{
|
||||||
|
plugin::CONFIG_FILE_PATH,
|
||||||
|
utils::{self, error_dialog},
|
||||||
|
Pumpbin,
|
||||||
|
};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
match try_main() {
|
if let Err(e) = try_main() {
|
||||||
Ok(_) => (),
|
error_dialog(e);
|
||||||
Err(e) => {
|
|
||||||
error_dialog(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,6 +35,10 @@ fn try_main() -> anyhow::Result<()> {
|
|||||||
.set(config_path)
|
.set(config_path)
|
||||||
.map_err(|_| anyhow!("Set CONFIG_FILE_PATH failed."))?;
|
.map_err(|_| anyhow!("Set CONFIG_FILE_PATH failed."))?;
|
||||||
|
|
||||||
Pumpbin::run(settings())?;
|
application("PumpBin", Pumpbin::update, Pumpbin::view)
|
||||||
|
.settings(utils::settings())
|
||||||
|
.window(utils::window_settings())
|
||||||
|
.theme(Pumpbin::theme)
|
||||||
|
.run()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
671
src/plugin.rs
671
src/plugin.rs
@@ -1,104 +1,102 @@
|
|||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
fmt::Display,
|
fs, iter,
|
||||||
fs,
|
ops::Not,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::OnceLock,
|
sync::OnceLock,
|
||||||
};
|
};
|
||||||
|
|
||||||
use aes_gcm::{aead::Aead, Aes256Gcm, Key, KeyInit, Nonce};
|
use anyhow::{anyhow, bail};
|
||||||
use anyhow::anyhow;
|
|
||||||
use bincode::{decode_from_slice, encode_to_vec, Decode, Encode};
|
use bincode::{decode_from_slice, encode_to_vec, Decode, Encode};
|
||||||
|
use capnp::{
|
||||||
|
message::{self, ReaderOptions},
|
||||||
|
serialize_packed,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
plugin_capnp,
|
||||||
|
plugin_system::{
|
||||||
|
run_plugin, EncryptShellcodeInput, EncryptShellcodeOutput, FormatEncryptedShellcodeInput,
|
||||||
|
FormatEncryptedShellcodeOutput, FormatUrlRemoteInput, FormatUrlRemoteOutput, Pass,
|
||||||
|
UploadFinalShellcodeRemoteInput, UploadFinalShellcodeRemoteOutput,
|
||||||
|
},
|
||||||
|
utils, BinaryType, Platform, ShellcodeSaveType,
|
||||||
|
};
|
||||||
|
|
||||||
// 500 MiB
|
|
||||||
const LIMIT: usize = 1024 * 1024 * 500;
|
|
||||||
pub const BINCODE_PLUGIN_CONFIG: bincode::config::Configuration<
|
|
||||||
bincode::config::LittleEndian,
|
|
||||||
bincode::config::Varint,
|
|
||||||
bincode::config::Limit<LIMIT>,
|
|
||||||
> = bincode::config::standard().with_limit();
|
|
||||||
const BINCODE_PLUGINS_CONFIG: bincode::config::Configuration = bincode::config::standard();
|
const BINCODE_PLUGINS_CONFIG: bincode::config::Configuration = bincode::config::standard();
|
||||||
|
|
||||||
pub static CONFIG_FILE_PATH: OnceLock<PathBuf> = OnceLock::new();
|
pub static CONFIG_FILE_PATH: OnceLock<PathBuf> = OnceLock::new();
|
||||||
|
|
||||||
#[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)]
|
#[derive(Debug, Default, Clone)]
|
||||||
pub struct AesGcmPass {
|
pub struct PluginInfo {
|
||||||
key_holder: Vec<u8>,
|
pub plugin_name: String,
|
||||||
nonce_holder: Vec<u8>,
|
pub author: String,
|
||||||
|
pub version: String,
|
||||||
|
pub desc: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AesGcmPass {
|
impl PluginInfo {
|
||||||
pub fn key_holder(&self) -> &[u8] {
|
pub fn plugin_name(&self) -> &str {
|
||||||
&self.key_holder
|
&self.plugin_name
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn key_holder_mut(&mut self) -> &mut Vec<u8> {
|
pub fn author(&self) -> &str {
|
||||||
&mut self.key_holder
|
&self.author
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nonce_holder(&self) -> &[u8] {
|
pub fn version(&self) -> &str {
|
||||||
&self.nonce_holder
|
&self.version
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nonce_holder_mut(&mut self) -> &mut Vec<u8> {
|
pub fn desc(&self) -> &str {
|
||||||
&mut self.nonce_holder
|
&self.desc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)]
|
#[derive(Debug, Default, Clone)]
|
||||||
pub enum EncryptType {
|
pub struct PluginReplace {
|
||||||
None,
|
pub src_prefix: Vec<u8>,
|
||||||
Xor(Vec<u8>),
|
pub size_holder: Option<Vec<u8>>,
|
||||||
AesGcm(AesGcmPass),
|
pub max_len: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for EncryptType {
|
impl PluginReplace {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
pub fn src_prefix(&self) -> &[u8] {
|
||||||
match self {
|
&self.src_prefix
|
||||||
EncryptType::None => write!(f, "None"),
|
}
|
||||||
EncryptType::Xor(_) => write!(f, "Xor"),
|
|
||||||
EncryptType::AesGcm(_) => write!(f, "AesGcm"),
|
pub fn size_holder(&self) -> Option<&Vec<u8>> {
|
||||||
}
|
self.size_holder.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn max_len(&self) -> usize {
|
||||||
|
self.max_len as usize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EncryptType {
|
#[derive(Debug, Default, Clone)]
|
||||||
pub const fn all() -> [EncryptType; 3] {
|
|
||||||
[
|
|
||||||
EncryptType::None,
|
|
||||||
EncryptType::Xor(vec![]),
|
|
||||||
EncryptType::AesGcm(AesGcmPass {
|
|
||||||
key_holder: vec![],
|
|
||||||
nonce_holder: vec![],
|
|
||||||
}),
|
|
||||||
]
|
|
||||||
}
|
|
||||||
pub fn encrypt(&self, path: &Path) -> anyhow::Result<Vec<u8>> {
|
|
||||||
let data = fs::read(path)?;
|
|
||||||
|
|
||||||
match self {
|
|
||||||
EncryptType::None => Ok(data),
|
|
||||||
EncryptType::Xor(x) => Ok(data
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(i, byte)| byte ^ x[i % x.len()])
|
|
||||||
.collect()),
|
|
||||||
EncryptType::AesGcm(x) => {
|
|
||||||
let key = Key::<Aes256Gcm>::from_slice(x.key_holder());
|
|
||||||
let aes = Aes256Gcm::new(key);
|
|
||||||
let nonce = Nonce::from_slice(x.nonce_holder());
|
|
||||||
aes.encrypt(nonce, data.as_slice()).map_err(|e| anyhow!(e))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)]
|
|
||||||
pub struct Bins {
|
pub struct Bins {
|
||||||
pub executable: Option<Vec<u8>>,
|
pub executable: Option<Vec<u8>>,
|
||||||
pub dynamic_library: Option<Vec<u8>>,
|
pub dynamic_library: Option<Vec<u8>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Bins {
|
||||||
|
pub fn is_platform_supported(&self) -> bool {
|
||||||
|
matches!((self.executable(), self.dynamic_library()), (None, None)).not()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn supported_binary_types(&self) -> Vec<BinaryType> {
|
||||||
|
let mut bin_types = Vec::default();
|
||||||
|
if self.executable().is_some() {
|
||||||
|
bin_types.push(BinaryType::Executable);
|
||||||
|
}
|
||||||
|
if self.dynamic_library().is_some() {
|
||||||
|
bin_types.push(BinaryType::DynamicLibrary);
|
||||||
|
}
|
||||||
|
|
||||||
|
bin_types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Bins {
|
impl Bins {
|
||||||
pub fn executable(&self) -> Option<&Vec<u8>> {
|
pub fn executable(&self) -> Option<&Vec<u8>> {
|
||||||
self.executable.as_ref()
|
self.executable.as_ref()
|
||||||
@@ -107,97 +105,424 @@ impl Bins {
|
|||||||
pub fn dynamic_library(&self) -> Option<&Vec<u8>> {
|
pub fn dynamic_library(&self) -> Option<&Vec<u8>> {
|
||||||
self.dynamic_library.as_ref()
|
self.dynamic_library.as_ref()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)]
|
pub fn executable_mut(&mut self) -> &mut Option<Vec<u8>> {
|
||||||
pub struct Platforms {
|
&mut self.executable
|
||||||
pub windows: Option<Bins>,
|
|
||||||
pub linux: Option<Bins>,
|
|
||||||
pub darwin: Option<Bins>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Platforms {
|
|
||||||
pub fn windows(&self) -> Option<&Bins> {
|
|
||||||
self.windows.as_ref()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn linux(&self) -> Option<&Bins> {
|
pub fn dynamic_library_mut(&mut self) -> &mut Option<Vec<u8>> {
|
||||||
self.linux.as_ref()
|
&mut self.dynamic_library
|
||||||
}
|
|
||||||
|
|
||||||
pub fn darwin(&self) -> Option<&Bins> {
|
|
||||||
self.darwin.as_ref()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)]
|
#[derive(Debug, Default, Clone)]
|
||||||
|
pub struct PluginBins {
|
||||||
|
pub windows: Bins,
|
||||||
|
pub linux: Bins,
|
||||||
|
pub darwin: Bins,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PluginBins {
|
||||||
|
pub fn supported_plaforms(&self) -> Vec<Platform> {
|
||||||
|
let mut platforms = Vec::default();
|
||||||
|
if self.windows().is_platform_supported() {
|
||||||
|
platforms.push(Platform::Windows);
|
||||||
|
}
|
||||||
|
if self.linux().is_platform_supported() {
|
||||||
|
platforms.push(Platform::Linux);
|
||||||
|
}
|
||||||
|
if self.darwin().is_platform_supported() {
|
||||||
|
platforms.push(Platform::Darwin);
|
||||||
|
}
|
||||||
|
|
||||||
|
platforms
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_that_binary(&self, platform: Platform, bin_type: BinaryType) -> Vec<u8> {
|
||||||
|
let platform = match platform {
|
||||||
|
Platform::Windows => self.windows(),
|
||||||
|
Platform::Linux => self.linux(),
|
||||||
|
Platform::Darwin => self.darwin(),
|
||||||
|
};
|
||||||
|
|
||||||
|
match bin_type {
|
||||||
|
BinaryType::Executable => platform.executable().unwrap().to_vec(),
|
||||||
|
BinaryType::DynamicLibrary => platform.dynamic_library().unwrap().to_vec(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PluginBins {
|
||||||
|
pub fn windows(&self) -> &Bins {
|
||||||
|
&self.windows
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn linux(&self) -> &Bins {
|
||||||
|
&self.linux
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn darwin(&self) -> &Bins {
|
||||||
|
&self.darwin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone)]
|
||||||
|
pub struct PluginPlugins {
|
||||||
|
pub encrypt_shellcode: Option<Vec<u8>>,
|
||||||
|
pub format_encrypted_shellcode: Option<Vec<u8>>,
|
||||||
|
pub format_url_remote: Option<Vec<u8>>,
|
||||||
|
pub upload_final_shellcode_remote: Option<Vec<u8>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PluginPlugins {
|
||||||
|
pub fn run_encrypt_shellcode(&self, path: &Path) -> anyhow::Result<EncryptShellcodeOutput> {
|
||||||
|
let shellcode = fs::read(path)?;
|
||||||
|
Ok(if let Some(wasm) = self.encrypt_shellcode() {
|
||||||
|
let input = EncryptShellcodeInput { shellcode };
|
||||||
|
let res = run_plugin(wasm, "encrypt_shellcode", &input)?;
|
||||||
|
serde_json::from_slice(res.as_slice())?
|
||||||
|
} else {
|
||||||
|
EncryptShellcodeOutput {
|
||||||
|
encrypted: shellcode,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run_format_encrypted_shellcode(
|
||||||
|
&self,
|
||||||
|
shellcode: &[u8],
|
||||||
|
) -> anyhow::Result<FormatEncryptedShellcodeOutput> {
|
||||||
|
let shellcode = shellcode.to_owned();
|
||||||
|
Ok(if let Some(wasm) = self.format_encrypted_shellcode() {
|
||||||
|
let input = FormatEncryptedShellcodeInput { shellcode };
|
||||||
|
let res = run_plugin(wasm, "format_encrypted_shellcode", &input)?;
|
||||||
|
serde_json::from_slice(res.as_slice())?
|
||||||
|
} else {
|
||||||
|
FormatEncryptedShellcodeOutput {
|
||||||
|
formated_shellcode: shellcode,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run_format_url_remote(&self, url: &str) -> anyhow::Result<FormatUrlRemoteOutput> {
|
||||||
|
let url = url.to_owned();
|
||||||
|
Ok(if let Some(wasm) = self.format_url_remote() {
|
||||||
|
let input = FormatUrlRemoteInput { url };
|
||||||
|
let res = run_plugin(wasm, "format_url_remote", &input)?;
|
||||||
|
serde_json::from_slice(res.as_slice())?
|
||||||
|
} else {
|
||||||
|
FormatUrlRemoteOutput { formated_url: url }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run_upload_final_shellcode_remote(
|
||||||
|
&self,
|
||||||
|
final_shellcode: &[u8],
|
||||||
|
) -> anyhow::Result<UploadFinalShellcodeRemoteOutput> {
|
||||||
|
let final_shellcode = final_shellcode.to_owned();
|
||||||
|
Ok(if let Some(wasm) = self.upload_final_shellcode_remote() {
|
||||||
|
let input = UploadFinalShellcodeRemoteInput { final_shellcode };
|
||||||
|
let res = run_plugin(wasm, "upload_final_shellcode_remote", &input)?;
|
||||||
|
serde_json::from_slice(res.as_slice())?
|
||||||
|
} else {
|
||||||
|
UploadFinalShellcodeRemoteOutput::default()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PluginPlugins {
|
||||||
|
pub fn encrypt_shellcode(&self) -> Option<&Vec<u8>> {
|
||||||
|
self.encrypt_shellcode.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_encrypted_shellcode(&self) -> Option<&Vec<u8>> {
|
||||||
|
self.format_encrypted_shellcode.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_url_remote(&self) -> Option<&Vec<u8>> {
|
||||||
|
self.format_url_remote.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn upload_final_shellcode_remote(&self) -> Option<&Vec<u8>> {
|
||||||
|
self.upload_final_shellcode_remote.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn encrypt_shellcode_mut(&mut self) -> &mut Option<Vec<u8>> {
|
||||||
|
&mut self.encrypt_shellcode
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_encrypted_shellcode_mut(&mut self) -> &mut Option<Vec<u8>> {
|
||||||
|
&mut self.format_encrypted_shellcode
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_url_remote_mut(&mut self) -> &mut Option<Vec<u8>> {
|
||||||
|
&mut self.format_url_remote
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn upload_final_shellcode_remote_mut(&mut self) -> &mut Option<Vec<u8>> {
|
||||||
|
&mut self.upload_final_shellcode_remote
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone)]
|
||||||
pub struct Plugin {
|
pub struct Plugin {
|
||||||
pub plugin_name: String,
|
pub version: String,
|
||||||
pub author: Option<String>,
|
pub info: PluginInfo,
|
||||||
pub version: Option<String>,
|
pub replace: PluginReplace,
|
||||||
pub desc: Option<String>,
|
pub bins: PluginBins,
|
||||||
pub prefix: Vec<u8>,
|
pub plugins: PluginPlugins,
|
||||||
pub size_holder: Option<Vec<u8>>,
|
|
||||||
pub max_len: usize,
|
|
||||||
pub encrypt_type: EncryptType,
|
|
||||||
pub platforms: Platforms,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Plugin {
|
impl Plugin {
|
||||||
pub fn plugin_name(&self) -> &str {
|
pub fn decode_from_slice(data: &[u8]) -> anyhow::Result<Self> {
|
||||||
&self.plugin_name
|
let message = serialize_packed::read_message(data, ReaderOptions::new())?;
|
||||||
|
let plugin = message.get_root::<plugin_capnp::plugin::Reader>()?;
|
||||||
|
|
||||||
|
let info = plugin.get_info()?;
|
||||||
|
let replace = plugin.get_replace()?;
|
||||||
|
let bins = plugin.get_bins()?;
|
||||||
|
let plugins = plugin.get_plugins()?;
|
||||||
|
|
||||||
|
let check_empty = |bin: &[u8]| {
|
||||||
|
if bin.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(bin.to_vec())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
version: plugin.get_version()?.to_string()?,
|
||||||
|
info: PluginInfo {
|
||||||
|
plugin_name: info.get_plugin_name()?.to_string()?,
|
||||||
|
author: info.get_author()?.to_string()?,
|
||||||
|
version: info.get_version()?.to_string()?,
|
||||||
|
desc: info.get_desc()?.to_string()?,
|
||||||
|
},
|
||||||
|
replace: PluginReplace {
|
||||||
|
src_prefix: replace.get_src_prefix()?.to_vec(),
|
||||||
|
size_holder: check_empty(replace.get_size_holder()?),
|
||||||
|
max_len: replace.get_max_len(),
|
||||||
|
},
|
||||||
|
bins: PluginBins {
|
||||||
|
windows: {
|
||||||
|
let platform_bins = bins.get_windows()?;
|
||||||
|
Bins {
|
||||||
|
executable: check_empty(platform_bins.get_executable()?),
|
||||||
|
dynamic_library: check_empty(platform_bins.get_dynamic_library()?),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
linux: {
|
||||||
|
let platform_bins = bins.get_linux()?;
|
||||||
|
Bins {
|
||||||
|
executable: check_empty(platform_bins.get_executable()?),
|
||||||
|
dynamic_library: check_empty(platform_bins.get_dynamic_library()?),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
darwin: {
|
||||||
|
let platform_bins = bins.get_darwin()?;
|
||||||
|
Bins {
|
||||||
|
executable: check_empty(platform_bins.get_executable()?),
|
||||||
|
dynamic_library: check_empty(platform_bins.get_dynamic_library()?),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: PluginPlugins {
|
||||||
|
encrypt_shellcode: check_empty(plugins.get_encrypt_shellcode()?),
|
||||||
|
format_encrypted_shellcode: check_empty(plugins.get_format_encrypted_shellcode()?),
|
||||||
|
format_url_remote: check_empty(plugins.get_format_url_remote()?),
|
||||||
|
upload_final_shellcode_remote: check_empty(
|
||||||
|
plugins.get_upload_final_shellcode_remote()?,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn author(&self) -> Option<&String> {
|
pub fn encode_to_vec(&self) -> anyhow::Result<Vec<u8>> {
|
||||||
self.author.as_ref()
|
let mut message = message::Builder::new_default();
|
||||||
|
let mut plugin = message.init_root::<plugin_capnp::plugin::Builder>();
|
||||||
|
plugin.set_version(self.version());
|
||||||
|
|
||||||
|
let mut info = plugin.reborrow().init_info();
|
||||||
|
let plugin_info = self.info();
|
||||||
|
info.set_plugin_name(plugin_info.plugin_name());
|
||||||
|
info.set_author(plugin_info.author());
|
||||||
|
info.set_version(plugin_info.version());
|
||||||
|
info.set_desc(plugin_info.desc());
|
||||||
|
|
||||||
|
let mut replace = plugin.reborrow().init_replace();
|
||||||
|
let plugin_replace = self.replace();
|
||||||
|
replace.set_src_prefix(plugin_replace.src_prefix());
|
||||||
|
if let Some(size_holder) = plugin_replace.size_holder() {
|
||||||
|
replace.set_size_holder(size_holder);
|
||||||
|
}
|
||||||
|
replace.set_max_len(plugin_replace.max_len() as u64);
|
||||||
|
|
||||||
|
let mut bins = plugin.reborrow().init_bins();
|
||||||
|
if self.bins().windows().is_platform_supported() {
|
||||||
|
let mut builder = bins.reborrow().init_windows();
|
||||||
|
let platform_bins = self.bins().windows();
|
||||||
|
|
||||||
|
if let Some(bin) = platform_bins.executable() {
|
||||||
|
builder.set_executable(bin);
|
||||||
|
}
|
||||||
|
if let Some(bin) = platform_bins.dynamic_library() {
|
||||||
|
builder.set_dynamic_library(bin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if self.bins().linux().is_platform_supported() {
|
||||||
|
let mut builder = bins.reborrow().init_linux();
|
||||||
|
let platform_bins = self.bins().linux();
|
||||||
|
|
||||||
|
if let Some(bin) = platform_bins.executable() {
|
||||||
|
builder.set_executable(bin);
|
||||||
|
}
|
||||||
|
if let Some(bin) = platform_bins.dynamic_library() {
|
||||||
|
builder.set_dynamic_library(bin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if self.bins().darwin().is_platform_supported() {
|
||||||
|
let mut builder = bins.reborrow().init_darwin();
|
||||||
|
let platform_bins = self.bins().darwin();
|
||||||
|
|
||||||
|
if let Some(bin) = platform_bins.executable() {
|
||||||
|
builder.set_executable(bin);
|
||||||
|
}
|
||||||
|
if let Some(bin) = platform_bins.dynamic_library() {
|
||||||
|
builder.set_dynamic_library(bin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut plugins = plugin.reborrow().init_plugins();
|
||||||
|
let plugin_plugins = self.plugins();
|
||||||
|
if let Some(plugin) = plugin_plugins.encrypt_shellcode() {
|
||||||
|
plugins.set_encrypt_shellcode(plugin);
|
||||||
|
}
|
||||||
|
if let Some(plugin) = plugin_plugins.format_encrypted_shellcode() {
|
||||||
|
plugins.set_format_encrypted_shellcode(plugin);
|
||||||
|
}
|
||||||
|
if let Some(plugin) = plugin_plugins.format_url_remote() {
|
||||||
|
plugins.set_format_url_remote(plugin);
|
||||||
|
}
|
||||||
|
if let Some(plugin) = plugin_plugins.upload_final_shellcode_remote() {
|
||||||
|
plugins.set_upload_final_shellcode_remote(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut buf = Vec::new();
|
||||||
|
serialize_packed::write_message(&mut buf, &message)?;
|
||||||
|
|
||||||
|
anyhow::Ok(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn version(&self) -> Option<&String> {
|
pub fn replace_binary(
|
||||||
self.version.as_ref()
|
&self,
|
||||||
}
|
bin: &mut [u8],
|
||||||
|
shellcode_src: String,
|
||||||
|
mut pass: Vec<Pass>,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
let save_type = if self.replace().size_holder().is_some() {
|
||||||
|
ShellcodeSaveType::Local
|
||||||
|
} else {
|
||||||
|
ShellcodeSaveType::Remote
|
||||||
|
};
|
||||||
|
|
||||||
pub fn desc(&self) -> Option<&String> {
|
// replace shellcode src
|
||||||
self.desc.as_ref()
|
let shellcode_src = match save_type {
|
||||||
}
|
ShellcodeSaveType::Local => {
|
||||||
|
let path = Path::new(&shellcode_src);
|
||||||
|
let output = self.plugins().run_encrypt_shellcode(path)?;
|
||||||
|
pass = output.pass().to_vec();
|
||||||
|
|
||||||
pub fn prefix(&self) -> &[u8] {
|
let final_shellcode = self
|
||||||
&self.prefix
|
.plugins()
|
||||||
}
|
.run_format_encrypted_shellcode(output.encrypted())?;
|
||||||
|
|
||||||
pub fn size_holder(&self) -> Option<&Vec<u8>> {
|
final_shellcode.formated_shellcode().to_vec()
|
||||||
self.size_holder.as_ref()
|
}
|
||||||
}
|
ShellcodeSaveType::Remote => {
|
||||||
|
let mut shellcode_src = self
|
||||||
|
.plugins()
|
||||||
|
.run_format_url_remote(&shellcode_src)?
|
||||||
|
.formated_url()
|
||||||
|
.as_bytes()
|
||||||
|
.to_vec();
|
||||||
|
shellcode_src.push(b'\0');
|
||||||
|
|
||||||
pub fn max_len(&self) -> usize {
|
shellcode_src
|
||||||
self.max_len
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
pub fn encrypt_type(&self) -> &EncryptType {
|
if shellcode_src.len() > self.replace().max_len() {
|
||||||
&self.encrypt_type
|
bail!(
|
||||||
}
|
"{} too long.",
|
||||||
|
match save_type {
|
||||||
|
ShellcodeSaveType::Local => "Shellcode",
|
||||||
|
ShellcodeSaveType::Remote => "Shellcode Url",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn platforms(&self) -> &Platforms {
|
utils::replace(
|
||||||
&self.platforms
|
bin,
|
||||||
}
|
self.replace().src_prefix(),
|
||||||
}
|
shellcode_src.as_slice(),
|
||||||
|
self.replace().max_len(),
|
||||||
|
);
|
||||||
|
|
||||||
impl Plugin {
|
// replace pass
|
||||||
pub fn reade_plugin(path: &Path) -> anyhow::Result<Plugin> {
|
for pass in pass {
|
||||||
let buf = fs::read(path)?;
|
let holder = pass.holder();
|
||||||
let (plugin, _) = decode_from_slice(buf.as_slice(), BINCODE_PLUGIN_CONFIG)?;
|
let replace_by = pass.replace_by();
|
||||||
Ok(plugin)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write_plugin(&self, path: &Path) -> anyhow::Result<()> {
|
utils::replace(bin, holder, replace_by, holder.len());
|
||||||
let buf = encode_to_vec(self, BINCODE_PLUGIN_CONFIG)?;
|
}
|
||||||
fs::write(path, buf.as_slice())?;
|
|
||||||
|
// replace size_holder
|
||||||
|
if save_type == ShellcodeSaveType::Local {
|
||||||
|
let size_holder = self.replace().size_holder().unwrap();
|
||||||
|
let shellcode_len_bytes = shellcode_src.len().to_string().as_bytes().to_vec();
|
||||||
|
|
||||||
|
if shellcode_len_bytes.len() > size_holder.len() {
|
||||||
|
bail!("Shellcode size bytes too long.");
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut size_bytes: Vec<u8> = iter::repeat(b'0')
|
||||||
|
.take(size_holder.len() - shellcode_len_bytes.len())
|
||||||
|
.collect();
|
||||||
|
size_bytes.extend_from_slice(shellcode_len_bytes.as_slice());
|
||||||
|
|
||||||
|
utils::replace(bin, size_holder, size_bytes.as_slice(), size_holder.len());
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Plugin {
|
||||||
|
pub fn version(&self) -> &str {
|
||||||
|
&self.version
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn info(&self) -> &PluginInfo {
|
||||||
|
&self.info
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn replace(&self) -> &PluginReplace {
|
||||||
|
&self.replace
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bins(&self) -> &PluginBins {
|
||||||
|
&self.bins
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn plugins(&self) -> &PluginPlugins {
|
||||||
|
&self.plugins
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Encode, Decode, PartialEq, Eq)]
|
#[derive(Debug, Clone, Default, Encode, Decode, PartialEq, Eq)]
|
||||||
pub struct Plugins(pub HashMap<String, Plugin>);
|
pub struct Plugins(HashMap<String, Vec<u8>>);
|
||||||
|
|
||||||
impl Plugins {
|
impl Plugins {
|
||||||
pub fn reade_plugins() -> anyhow::Result<Plugins> {
|
pub fn reade_plugins() -> anyhow::Result<Plugins> {
|
||||||
@@ -224,77 +549,31 @@ impl Plugins {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
pub fn get(&self, name: &str) -> anyhow::Result<Plugin> {
|
||||||
mod test {
|
let buf = self
|
||||||
use std::io::Write;
|
.0
|
||||||
|
.get(name)
|
||||||
|
.ok_or(anyhow!("Get plugin by name failed."))?;
|
||||||
|
|
||||||
use tempfile::NamedTempFile;
|
Plugin::decode_from_slice(buf)
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_plugin() {
|
|
||||||
let plugin = Plugin {
|
|
||||||
plugin_name: "test_plugin".into(),
|
|
||||||
author: Some("b1n".into()),
|
|
||||||
version: Some("0.1.0".into()),
|
|
||||||
desc: Some("test desc".into()),
|
|
||||||
prefix: b"$$SHELLCODE$$".to_vec(),
|
|
||||||
size_holder: Some(b"$$99999$$".to_vec()),
|
|
||||||
max_len: 1024 * 1024,
|
|
||||||
encrypt_type: EncryptType::AesGcm(AesGcmPass {
|
|
||||||
key_holder: b"key".to_vec(),
|
|
||||||
nonce_holder: b"nonce".to_vec(),
|
|
||||||
}),
|
|
||||||
platforms: Platforms {
|
|
||||||
windows: None,
|
|
||||||
linux: None,
|
|
||||||
darwin: None,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let plugin_file = NamedTempFile::new().unwrap();
|
|
||||||
plugin.write_plugin(plugin_file.path()).unwrap();
|
|
||||||
|
|
||||||
let decode_plugin = Plugin::reade_plugin(plugin_file.path()).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(decode_plugin, plugin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
pub fn get_sorted_names(&self) -> Vec<String> {
|
||||||
fn test_xor_encrypt() {
|
let mut names: Vec<String> = self.0.keys().map(|x| x.to_owned()).collect();
|
||||||
let mut plain_text = NamedTempFile::new().unwrap();
|
names.sort();
|
||||||
plain_text.as_file_mut().write_all(b"test").unwrap();
|
names
|
||||||
|
|
||||||
let pass = b"pass";
|
|
||||||
let xor = EncryptType::Xor(pass.to_vec());
|
|
||||||
let encrypted = xor.encrypt(plain_text.path()).unwrap();
|
|
||||||
let decrypted: Vec<u8> = encrypted
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(i, byte)| byte ^ pass[i % pass.len()])
|
|
||||||
.collect();
|
|
||||||
assert_eq!(decrypted.as_slice(), b"test");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
pub fn is_empty(&self) -> bool {
|
||||||
fn test_aes_gcm_encrypt() {
|
self.0.is_empty()
|
||||||
let mut plain_text = NamedTempFile::new().unwrap();
|
}
|
||||||
plain_text.as_file_mut().write_all(b"test").unwrap();
|
|
||||||
|
|
||||||
let pass = AesGcmPass {
|
pub fn insert(&mut self, name: String, plugin: Vec<u8>) {
|
||||||
key_holder: b"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk".to_vec(),
|
self.0.insert(name, plugin);
|
||||||
nonce_holder: b"nnnnnnnnnnnn".to_vec(),
|
}
|
||||||
};
|
|
||||||
let aes_gcm = EncryptType::AesGcm(pass.clone());
|
|
||||||
let encrypted = aes_gcm.encrypt(plain_text.path()).unwrap();
|
|
||||||
|
|
||||||
let aes = Aes256Gcm::new_from_slice(pass.key_holder()).unwrap();
|
pub fn remove(&mut self, name: &str) {
|
||||||
let nonce = Nonce::from_slice(pass.nonce_holder());
|
self.0.remove(name);
|
||||||
let decrypted = aes.decrypt(nonce, encrypted.as_slice()).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(decrypted.as_slice(), b"test");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
99
src/plugin_system.rs
Normal file
99
src/plugin_system.rs
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use extism::{Manifest, Wasm};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
pub fn run_plugin<T: Serialize>(wasm: &[u8], func: &str, input: &T) -> anyhow::Result<Vec<u8>> {
|
||||||
|
let data = Wasm::data(wasm.to_vec());
|
||||||
|
let manifest = Manifest::new([data])
|
||||||
|
.with_timeout(Duration::from_secs(5))
|
||||||
|
.with_allowed_host("*");
|
||||||
|
let mut plugin = extism::Plugin::new(manifest, [], true)?;
|
||||||
|
|
||||||
|
plugin.call::<Vec<u8>, Vec<u8>>(func, serde_json::to_vec(input)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct EncryptShellcodeInput {
|
||||||
|
pub shellcode: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Pass {
|
||||||
|
pub holder: Vec<u8>,
|
||||||
|
pub replace_by: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Pass {
|
||||||
|
pub fn holder(&self) -> &[u8] {
|
||||||
|
&self.holder
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn replace_by(&self) -> &[u8] {
|
||||||
|
&self.replace_by
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct EncryptShellcodeOutput {
|
||||||
|
pub encrypted: Vec<u8>,
|
||||||
|
pub pass: Vec<Pass>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EncryptShellcodeOutput {
|
||||||
|
pub fn encrypted(&self) -> &[u8] {
|
||||||
|
&self.encrypted
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pass(&self) -> &[Pass] {
|
||||||
|
&self.pass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct FormatEncryptedShellcodeInput {
|
||||||
|
pub shellcode: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct FormatEncryptedShellcodeOutput {
|
||||||
|
pub formated_shellcode: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FormatEncryptedShellcodeOutput {
|
||||||
|
pub fn formated_shellcode(&self) -> &[u8] {
|
||||||
|
&self.formated_shellcode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct FormatUrlRemoteInput {
|
||||||
|
pub url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct FormatUrlRemoteOutput {
|
||||||
|
pub formated_url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FormatUrlRemoteOutput {
|
||||||
|
pub fn formated_url(&self) -> &str {
|
||||||
|
&self.formated_url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct UploadFinalShellcodeRemoteInput {
|
||||||
|
pub final_shellcode: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct UploadFinalShellcodeRemoteOutput {
|
||||||
|
pub url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UploadFinalShellcodeRemoteOutput {
|
||||||
|
pub fn url(&self) -> &str {
|
||||||
|
&self.url
|
||||||
|
}
|
||||||
|
}
|
||||||
2
src/style/mod.rs
Normal file
2
src/style/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
pub mod button;
|
||||||
|
pub mod svg;
|
||||||
78
src/utils.rs
Normal file
78
src/utils.rs
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
use std::iter;
|
||||||
|
|
||||||
|
use iced::{
|
||||||
|
advanced::graphics::image::image_rs::ImageFormat,
|
||||||
|
window::{self, Level, Position},
|
||||||
|
Font, Pixels, Settings, Size, Task,
|
||||||
|
};
|
||||||
|
use memchr::memmem;
|
||||||
|
use rand::RngCore;
|
||||||
|
use rfd::{AsyncMessageDialog, MessageButtons, MessageDialog, MessageDialogResult, MessageLevel};
|
||||||
|
|
||||||
|
pub const JETBRAINS_MONO_FONT: Font = Font::with_name("JetBrainsMono NF");
|
||||||
|
|
||||||
|
pub fn error_dialog(error: anyhow::Error) {
|
||||||
|
MessageDialog::new()
|
||||||
|
.set_buttons(MessageButtons::Ok)
|
||||||
|
.set_description(error.to_string())
|
||||||
|
.set_level(MessageLevel::Error)
|
||||||
|
.set_title("PumpBin")
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn message_dialog(message: String, level: MessageLevel) -> Task<MessageDialogResult> {
|
||||||
|
let dialog = AsyncMessageDialog::new()
|
||||||
|
.set_buttons(MessageButtons::Ok)
|
||||||
|
.set_description(message)
|
||||||
|
.set_level(level)
|
||||||
|
.set_title("PumpBin")
|
||||||
|
.show();
|
||||||
|
Task::future(dialog)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn settings() -> Settings {
|
||||||
|
Settings {
|
||||||
|
fonts: vec![include_bytes!("../assets/JetBrainsMonoNerdFont-Regular.ttf").into()],
|
||||||
|
default_font: JETBRAINS_MONO_FONT,
|
||||||
|
default_text_size: Pixels(13.0),
|
||||||
|
antialiasing: true,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn window_settings() -> window::Settings {
|
||||||
|
let size = Size::new(1000.0, 600.0);
|
||||||
|
|
||||||
|
window::Settings {
|
||||||
|
size,
|
||||||
|
position: Position::Centered,
|
||||||
|
min_size: Some(size),
|
||||||
|
visible: true,
|
||||||
|
resizable: true,
|
||||||
|
decorations: true,
|
||||||
|
transparent: false,
|
||||||
|
level: Level::Normal,
|
||||||
|
icon: window::icon::from_file_data(
|
||||||
|
include_bytes!("../logo/icon.png"),
|
||||||
|
Some(ImageFormat::Png),
|
||||||
|
)
|
||||||
|
.ok(),
|
||||||
|
exit_on_close_request: true,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn replace(bin: &mut [u8], holder: &[u8], replace_by: &[u8], max_len: usize) {
|
||||||
|
let mut replace_by = replace_by.to_owned();
|
||||||
|
|
||||||
|
let find = memmem::find_iter(bin, holder).next();
|
||||||
|
if let Some(position) = find {
|
||||||
|
let mut random: Vec<u8> = iter::repeat(b'0')
|
||||||
|
.take(max_len - replace_by.len())
|
||||||
|
.collect();
|
||||||
|
rand::thread_rng().fill_bytes(&mut random);
|
||||||
|
replace_by.extend_from_slice(random.as_slice());
|
||||||
|
|
||||||
|
bin[position..(position + max_len)].copy_from_slice(replace_by.as_slice());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user