Generic Shell Script Compiler with Enhanced Security & Auditing
Empowering Developers โข Securing Shell Scripts โข Open Source Passion
Shc takes a script, which is specified on the command line, and produces C source code. The generated source code is then compiled and linked to produce a stripped binary executable.
Insight:
shcitself is not a compiler such ascc. It rather encodes and encrypts a shell script and generates C source code with an added expiration capability. It then uses the system compiler to compile a stripped binary which behaves exactly like the original script. Upon execution, the compiled binary will decrypt and execute the code with the shell-coption.
Note: The compiled binary will still be dependent on the shell specified in the first line of the shell code (i.e. shebang #!/bin/sh), thus shc does not create completely independent binaries.
First, clone the repository and ensure you have the necessary packages for compiling:
# Clone the repository
git clone https://github.com/alsyundawy/shc.git
cd shc
# Install dependencies
sudo apt-get update
sudo apt-get install build-essential automake autoconf libtool
Then, compile and install from the source:
./autogen.sh
./configure
make
sudo make install
(Note: If make fails due to automakeโs version, ensure you have run ./autogen.sh before running the commands.)
sudo apt-get install shc
sudo add-apt-repository ppa:alsyundawy/ppa
sudo apt-get update
sudo apt-get install shc
Prefer Pre-compiled Binaries? Download a compiled binary package from the Releases Page and copy the
shcbinary to/usr/binandshc.1to/usr/share/man/man1.
# General Usage
shc [options]
# Compile a script into a binary
shc -f script.sh -o binary
# Untraceable binary (prevents strace, ptrace, etc.)
shc -U -f script.sh -o binary
# Untraceable binary, no root required (only sh scripts, no parameters)
shc -H -f script.sh -o binary
-HThis flag is currently in an experimental state and may not work on all systems. This flag only works for the default shell. For example, if you compile a bash script with the -H flag, the resulting executable will only work on systems where the default shell is bash. You may change the default shell, which generally is /bin/sh (often a symlink to bash or dash).
โ ๏ธ Notice: -H does not work with positional parameters (yet).
To run the test suite, simply use:
./configure
make
make test
Temporary directories are generated in ${TMPDIR:-/tmp}/shc.SHELL.OPT.XXXXXX (caps are replaced according to the test). When a test succeeds, the directory is removed; if it fails, it is kept to help with debugging.
Clean up test outputs manually with:
rm -rf ${TMPDIR:-/tmp}/shc.*
_SC_ARG_MAX system configuration parameter limits the length of the arguments to the exec function. With standard options, this limits the maximum length of the runnable script of shc. However, you can now use the -P option which uses a pipe to circumvent this limitation.โ CHECK YOUR RESULTS CAREFULLY BEFORE USING โ
By HARRY DS ALSYUNDAWY - ALSYUNDAWY IT SOLUTION
-V and --version options in src/shc.c to print version and exit, keeping POSIX getopt(3) compatibility without getopt_long.shc -V and --version output to include original author, provider/maintainer, core collaborator, SHC contributors, repository URL, and audit hardening credit.-P/-p pipe runtime by replacing predictable /tmp FIFO names with mkdtemp(3)-backed private temporary directories.open(2), closed descriptors, unlinked FIFO, and removed private temp directory after pipe delivery.snprintf(NULL, 0, ...) allocation to prevent truncation.SKIP_OPTS parsing in test/ttest.sh so empty option is not skipped when SKIP_OPTS is unset.PATH_MAX fallback and feature macro guards for mkdtemp(3), putenv(3), setenv(3), and strict builds in src/shc.c.5.0.8-Hardened-Audit-2026 in configure.ac, src/shc.c, README.md, docs/CHANGELOG.md, docs/DOCNOTE.md.configure.ac.src/Makefile.am.README.md, docs/CHANGELOG.md, docs/DOCNOTE.md to match ChangeLog collaboration notes.Original Credit to @alsyundawy
-P/-p pipe mode by replacing predictable /tmp/%08x FIFO names with mkdtemp(3) private temporary directories.open(2), closed the descriptor, unlinked the FIFO, and removed the private temp directory.test/ttest.sh SKIP_OPTS logic so the default empty option is not skipped accidentally when SKIP_OPTS is unset.char cmd[256] pipe command formatting with dynamically sized snprintf(NULL, 0, ...) allocation to avoid silent truncation.PATH_MAX fallback for stricter compiler/libc compatibility.configure.ac and internal source version to 4.0.4-Hardened-Audit-2026.src/Makefile.am with -Wpedantic and -Wformat=2.Original Credit to @alsyundawy
fork() + execvp() argv vectors for compiler and strip paths.chmod command with chmod(2) to avoid shell expansion and command parsing exposure./tmp/shc_x_<pid>.c and /tmp/shc_x_<pid>.so generation from -H runtime.-H runtime buffer overflow in parent process-name reading with bounded fread() and explicit null termination.fread() error handling in script loader so read failures are not silently treated as EOF.CC, CFLAGS, LDFLAGS, and STRIP while preserving existing environment variable behavior.Makefile.am.-H execution path.ChangeLog and README.md change notes by adding entries in the existing project format only.Original Credit to @alsyundawy
ksh88, ksh93, mksh, pdksh, fish, nu, pwsh, powershell, yash, osh, elvish.#!/usr/bin/env wrapper interpretation with complex parameter chaining.sscanf truncated whitespace-separated shebang options (e.g., env -S bash -e).execvp wrappers causing abnormal behavior on env and sh variants.test/match.set -eu) across all POSIX payload testing scripts (test/match, test/pru.sh).set -Eeuo pipefail) & safe IFS parsing in test/ttest.sh.mktemp template vulnerabilities in test/ttest.sh to prevent predictable temp directories.test/ttest.sh.set -e) in autogen.sh.src/shc.c (removed unused headers, fixed array string missing comma, improved conditional statements).'4.0.3 (Hardened Audit Edition - 15 Jun 2026)'.configure.ac to version 4.0.3-Hardened-Audit-2026.shc.c causing sh: 1: %s: not found error during -H hardened compilation.SKIP_OPTS support to test/ttest.sh; set SKIP_OPTS=-H in CI sanitize job to skip -H tests that are fundamentally incompatible with ASAN LD_PRELOAD injection.Original Credit to @alsyundawy
-P, -p), with $0 forging (big scripts, perl, python) @fabio-brugnara.ash dependency @dviererbe #167-2 to use mmap2 @csersoft #132<> @learnpassword #148Original Credit to @mdeweerd
We welcome your open-source passion! If you want to make pull requests, please target the master branch. The default branch is release, which should contain clean package files ready to be used.
If you want to edit the manual, please edit the man.md file. The CI flow will automatically generate the other manual files from it.
You can also generate these locally with the following commands (requires pandoc):
pandoc -s man.md -t man -o shc.1
# Also run this command to generate the HTML manual
pandoc -s man.md -t html -o man.html
If you change anything related to autotools, ./autogen.sh should be run to regenerate the derived files. Again, the CI flow will generate these automatically.
(You may need to pull after a push because of the changes committed by CI.)
This project is a hardened and heavily audited iteration built upon the incredible foundational work of neurobin. Huge thanks to the original author and the contributors of the neurobin/shc repository.
Developed with โค๏ธ & Passion by Open Source Community