把代码藏起来!Shell和Perl脚本加密与可执行文件编译技术

文摘   2024-10-23 09:00   广东  

点击上方【蓝字】关注博主

 未加密的脚本代码面临着潜在的盗用和篡改风险,甚至可能导致敏感信息泄露。为此,本文探讨了多种有效的脚本加密与编译技术,涵盖了 Shell 和 Perl 脚本的保护方法。通过使用流行工具如 SHC 和 PAR::Packer,以及加密算法如 Crypt::CBC,有效提高源代码的安全性与隐私保护。

01

背景

脚本编程已经成为了软件开发和自动化工作中的重要组成部分。无论是Shell脚本、Perl脚本还是其他脚本语言,它们的灵活性和高效性使得程序员能够快速实现功能并处理复杂任务。然而,随着脚本代码的广泛应用,代码的安全性与保护需求也随之上升。

脚本代码保护的主要原因:

  • 未加密的脚本代码容易被他人复制、篡改乃至重新发布,导致知识产权的丧失。

  • 脚本中包括数据库连接信息、API密钥等敏感数据,未经保护可能导致信息泄露。

  • 经过加密或编译的脚本能够增强用户对软件的信任,减少由于安全问题引发的恐慌。

02

Shell脚本加密与编译方法

2.1、使用shc工具

什么是SHC?
SHC(Shell Script Compiler)是一个开源工具,用于将Shell脚本编译成可执行文件,它将代码转换为C语言程序,然后再编译成二进制文件,以保护源代码。其主要目的是提供一个简单的方式来保护Shell脚本代码,防止未经授权的访问和篡改。SHC 对脚本进行加密处理,使其内容难以被直接读取,从而提高代码的安全性。

SHC的功能:

  • SHC将Shell脚本编译成二进制可执行文件,这一过程会将原始的可读脚本变为机器代码,从而隐藏脚本的实现细节。

  • SHC在编译过程中会对脚本内容进行预处理和加密,使得即使是获得了二进制文件的人,也难以还原出脚本的源代码。

  • SHC主要针对Linux/Unix系统,SHC的命令行界面友好,用户只需输入简单的命令即可完成编译过程,不需要复杂的配置。

安装SHC:可以通过包管理器(如apt、yum)或者从源码编译安装SHC。

  1. 从源代码编译安装:

    # 安装了必要的编译工具和库。包括 `gcc`(GNU C编译器)和 `make` 工具:
    sudo apt-get update
    sudo apt-get install build-essential

    # 访问 SHC 的 GitHub 仓库,下载最新的源代码压缩包,或通过 `git` 克隆仓库。
    git clone https://github.com/neurobin/shc.git
    cd shc
    # 编译 SHC:
    make
    # 安装 SHC,将编译的二进制文件移动到 `/usr/local/bin` 目录(或其他合适的目录):
    sudo cp shc /usr/local/bin/
    # 检查 SHC 是否安装成功:
    shc -h
  2. 使用包管理器安装(推荐):

    # Ubuntu/Debian:
    sudo apt-get install shc
    # CentOS/RHEL
    sudo yum install epel-release
    sudo yum install shc

以下是编译示例:

脚本(hello.sh):

#!/bin/bash

# 检查是否为root用户
if [ "$EUID" -ne 0 ]; then
echo "请以管理员权限运行此脚本(使用sudo)!"
exit 1
fi

# 显示系统信息
echo "-----------------------------"
echo "系统信息"
echo "-----------------------------"
echo "当前用户: $(whoami)"
echo "系统时间: $(date)"
echo "操作系统版本: $(lsb_release -d | cut -f2)"

# 列出当前目录文件
echo "-----------------------------"
echo "当前目录中的文件:"
ls -1

# 用户选择文件
read -p "请选择一个文件以查看其内容 (输入文件名): " file_name

# 检查文件是否存在
if [ -f "$file_name" ]; then
echo "-----------------------------"
echo "文件内容: $file_name"
cat "$file_name"

# 将输出重定向到日志文件
echo "日志保存到 log.txt"
{
echo "文件内容: $file_name"
cat "$file_name"
} > log.txt

else
echo "文件不存在!"
fi

编译脚本

shc -f hello.sh

将生成两个文件:hello.sh.x(可执行文件)和hello.sh.x.c(C源文件)。

执行编译文件

./hello.sh.x

2.2、加密与编码

gzipzip 等工具可以压缩脚本文件,从而在一定程度上增加其安全性,但并不能完全加密。推荐使用base64编码或openssl加密,更安全。

使用base64编码将脚本内容进行 base64 编码,并在运行时解码执行:

# 编码
base64 hello.sh > hello_base64.txt

# 解码并执行
base64 -d hello_base64.txt | bash

使用 openssl 工具对脚本进行对称或非对称加密,然后在运行时解密。例如:

# 加密
openssl aes-256-cbc -salt -in hello.sh -out hello.sh.enc

# 解密并执行
openssl aes-256-cbc -d -in hello.sh.enc | bash
03

Perl脚本加密与编译方法

3.1、PAR::Packer工具

PAR::Packer 是一个 Perl 模块,主要用于将 Perl 脚本及其所有依赖打包成可执行的二进制文件。

功能与特点:

  1. 将 Perl 脚本和所有依赖的库打包成一个单独的可执行文件

  2. 它会分析 Perl 脚本,自动识别所用到的模块,并将这些模块打包在内,确保在目标环境中运行时可以找到。

  3. 打包后的可执行文件可以在没有安装 Perl 的环境中运行

安装并使用:

# 以使用 CPAN 安装:
cpan PAR::Packer

# 打包Perl脚本
pp -o hello.pxf hello.pl

脚本(task_manager.pl):

#!/usr/bin/perl
use strict;
use warnings;
use JSON;
use File::Slurp;
use Data::Dumper;

# 数据文件
my $data_file = "tasks.json";

# 初始化任务列表
my $tasks = -e $data_file ? from_json(read_file($data_file)) : [];

sub save_tasks {
write_file($data_file, to_json($tasks, { pretty => 1 }));
}

sub display_tasks {
print "当前任务列表:\n";
foreach my $index (0..$#$tasks) {
my $status = $tasks->[$index]->{done} ? '[X]' : '[ ]';
print "$status $index: $tasks->[$index]->{task}\n";
}
}

sub add_task {
print "输入任务: ";
my $task = <STDIN>;
chomp($task);
push @$tasks, { task => $task, done => 0 };
save_tasks();
print "任务已添加!\n";
}

sub complete_task {
print "输入完成的任务编号: ";
my $index = <STDIN>;
chomp($index);
if (defined $tasks->[$index]) {
$tasks->[$index]->{done} = 1;
save_tasks();
print "任务已标记为完成!\n";
} else {
print "所输入的任务编号无效!\n";
}
}

sub main {
while (1) {
print "\n选择操作:\n";
print "1. 查看任务\n";
print "2. 添加任务\n";
print "3. 完成任务\n";
print "4. 退出\n";
print "输入选项: ";

my $choice = <STDIN>;
chomp($choice);

if ($choice == 1) {
display_tasks();
} elsif ($choice == 2) {
add_task();
} elsif ($choice == 3) {
complete_task();
} elsif ($choice == 4) {
last;
} else {
print "无效的选项, 请重试.\n";
}
}
}

main();

注意,上面的脚本要按照必要的 perl 模块:

cpan JSON File::Slurp

打包脚本:

pp -o task_manager task_manager.pl

运行可执行文件:

./task_manager

PAR::Packer 提供了许多选项。例如,可以指定特定的 Perl 版本、添加图标、捆绑资源文件等。

pp -o hello --gui --icon myicon.ico hello.pl

3.2、perlcc编译器

perlcc 是 Perl 语言的一个编译器,它可以将 Perl 脚本编译成 C 代码,然后进一步编译成可执行的二进制文件。它是 Perl 的一部分,但使用的并不多。

功能:

  1. perlcc 首先将 Perl 源代码转换为 C 代码,然后使用系统的 C 编译器(如 gcc)将其编译为可执行的二进制文件。

  2. 一定程度的代码保护将 Perl 代码编译为二进制形式可以使得用户更难直接查看源代码,虽然这并不是真正的安全措施。

局限性:

  1. 并非所有 Perl 模块或语法都能被成功编译。perlcc 可能无法处理某些复杂的 Perl 特性或者特定模块,从而导致编译失败。

  2. 在很多情况下,生成的 C 代码的执行效率可能并没有显著提高。

  3. perlcc 在现代 Perl 版本上的维护和更新较少,某些功能可能不再被支持,导致其在当今 Perl 编程环境中的使用率较低。

  4. 编译后的程序可能仍然需要一些 Perl 库的支持,上述库必须在目标机器上可用或者与程序一起打包。

编译过程示例: 继续使用前面的task_manager.pl

perlcc -o task_manager task_manager.pl

使用 -d 选项可以在编译时显示调试信息:

perlcc -d -o hello hello.pl

查看 perlcc 的更多选项和功能,可以使用以下命令:

perlcc -h

perlcc 在现代 Perl 版本上可能没有得到良好的维护和支持,因此在实际开发中,并不是很推荐使用它。

3.3、加密与解密技术

使用 Crypt::CBC 模块可以实现对数据的加密和解密。Crypt::CBC 提供了基于块密码的加密和模式(例如,CBC 模式),常用的加密算法包括 AES、DES 等。

安装 Crypt::CBC

cpan Crypt::CBC

使用 Crypt::CBC 模块加密一个 Perl 脚本,涉及到定义一个加密的过程并将脚本本身保存为一个密文,然后可以在运行时解密并执行。这种做法只是为了保护源代码,这并不是一种绝对的安全措施,因为熟悉 Perl 的人仍然可以通过逆向工程等手段获取原始代码。

继续使用前面的task_manager.pl来展示了如何使用 Crypt::CBC 加密一个 Perl 脚本,并在运行时解密并执行。

需要使用一个 Perl 脚本来加密 task_manager.pl。保存以下代码为 encrypt_script.pl,这段代码将加密并保存原始脚本:

#!/usr/bin/perl
use strict;
use warnings;
use Crypt::CBC;
use MIME::Base64;
use File::Slurp;

# 配置加密参数
my $key = '*********'; # 选择一个合适的密钥
my $cipher = Crypt::CBC->new(
-key => $key,
-cipher => 'Crypt::AES',
);

# 读取原始脚本
my $script = read_file('task_manager.pl');

# 加密脚本
my $ciphertext = $cipher->encrypt_hex($script);
write_file('hello_encrypted.pl', $ciphertext);

print "Script encrypted and saved to hello_encrypted.pl\n";

运行此脚本会生成一个名为 hello_encrypted.pl 的文件,里面保存了加密后的内容。

perl task_manager.pl

然后需要一个解密和执行的脚本。如下代码,保存为 run_encrypted.pl

#!/usr/bin/perl
use strict;
use warnings;
use Crypt::CBC;
use MIME::Base64;
use File::Slurp;

# 配置加密参数
my $key = '******'; # 确保与加密时的密钥一致
my $cipher = Crypt::CBC->new(
-key => $key,
-cipher => 'Crypt::AES',
);

# 读取加密脚本
my $ciphertext = read_file('hello_encrypted.pl');

# 解密
my $decrypted = $cipher->decrypt_hex($ciphertext);

# 执行解密后的脚本
eval $decrypted;
if ($@) {
die "Error executing decrypted script: $@";
}

运行解密并执行的脚本:

perl run_encrypted.pl
04

总结

脚本加密和编译技术为确保源代码安全性提供了有效的手段。本文详细介绍了使用流行工具和方法对 Shell 脚本和 Perl 脚本进行加密和编译的步骤,旨在帮助开发者保护自己的代码和敏感信息。

通过使用 shc 工具,我们能够将 Shell 脚本编译成二进制格式,使源代码不易被读取和篡改。同时,利用 base64 编码和 openssl 加密等方法,进一步增强了脚本在存储和传输过程中的安全性。

在 Perl 方面,PAR::Packer 允许开发者将脚本及其依赖项打包成独立的可执行文件,极大地方便了在不同环境中的运行,而 perlcc 虽然提供了一定的代码保护,但在实际使用中存在局限性。

不仅如此,利用 Crypt::CBC 等模块直接加密 Perl 脚本,展现了如何在执行时动态解密,进一步提升了代码的防护能力。尽管这种方法不能完全防止逆向工程,但无疑提升了代码的安全性与隐私保护水平。

相关工具与资源链接:

  • SHC(Shell Script Compiler): GitHub 地址(https://github.com/neurobin/shc)

  • PAR::PackerCPAN 文档(https://metacpan.org/pod/PAR::Packer)

  • Crypt::CBCCPAN 文档(https://metacpan.org/pod/Crypt::CBC)

  • OpenSSLOpenSSL 网站(https://www.openssl.org/)

  • Perl 文档Perl 官方文档(https://www.perl.org/docs.html)

公众号: Lion 莱恩呀

微信号: 关注获取

扫码关注 了解更多内容

点个 在看 你最好看

Lion 莱恩呀
专注分享高性能服务器后台开发技术知识,涵盖多个领域,包括C/C++、Linux、网络协议、设计模式、中间件、云原生、数据库、分布式架构等。目标是通过理论与代码实践的结合,让世界上看似难以掌握的技术变得易于理解与掌握。
 最新文章