Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Script passed as pipe, fix for locks, support for python #153

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
81 changes: 66 additions & 15 deletions src/shc.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ static const char * abstract[] = {
0};

static const char usage[] =
"Usage: shc [-e date] [-m addr] [-i iopt] [-x cmd] [-l lopt] [-o outfile] [-rvDSUHCAB2h] -f script";
"Usage: shc [-e date] [-m addr] [-i iopt] [-x cmd] [-l lopt] [-o outfile] [-rvDSUHPCAB2h] -f script";

static const char * help[] = {
"",
Expand All @@ -86,6 +86,7 @@ static const char * help[] = {
" -U Make binary untraceable [no]",
" -H Hardening : extra security protection [no]",
" Require bourne shell (sh) and parameters are not supported",
" -P Submit script as a pipe [no]",
" -C Display license and exit",
" -A Display abstract and exit",
" -B Compile for busybox",
Expand Down Expand Up @@ -149,6 +150,9 @@ static int MMAP2_flag = 0;
static const char BUSYBOXON_line[] =
"#define BUSYBOXON %d /* Define as 1 to enable work with busybox */\n";
static int BUSYBOXON_flag = 0;
static const char PIPESCRIPT_line[] =
"#define PIPESCRIPT %d /* Define as 1 to submit script as a pipe */\n";
static int PIPESCRIPT_flag = 0;

static const char * RTC[] = {
"",
Expand Down Expand Up @@ -236,13 +240,15 @@ static const char * RTC[] = {
"",
"#include <sys/stat.h>",
"#include <sys/types.h>",
"#include <sys/wait.h>",
"",
"#include <errno.h>",
"#include <stdio.h>",
"#include <stdlib.h>",
"#include <string.h>",
"#include <time.h>",
"#include <unistd.h>",
"#include <fcntl.h>",
"",
"/* 'Alleged RC4' */",
"",
Expand Down Expand Up @@ -622,14 +628,15 @@ static const char * RTC[] = {
"#endif",
" close(0);",
" mine = !open(proc, O_RDWR|O_EXCL);",
" if (!mine && errno != EBUSY)",
" mine = !ptrace(PT_ATTACHEXC, pid, 0, 0);",
" if (mine) {",
" kill(pid, SIGCONT);",
" } else {",
/*" fprintf(stderr, \"%s is being traced!\\n\", argv0);",*/
" if (!mine && errno != EBUSY) {",
" if((mine=2*!ptrace(PT_ATTACHEXC, pid, 0, 0)))wait(0);",
fabio-brugnara marked this conversation as resolved.
Show resolved Hide resolved
" }",
" if (!mine) {",
" perror(argv0);",
" kill(pid, SIGKILL);",
/*" fprintf(stderr, \"%s is being traced!\\n\", argv0);",*/
" } else if(mine>1) {",
" ptrace(PTRACE_DETACH, pid, 0, 0);",
" }",
" _exit(mine);",
" case -1:",
Expand Down Expand Up @@ -714,6 +721,42 @@ static const char * RTC[] = {
"#else",
" varg[j++] = argv[0]; /* My own name at execution */",
"#endif",
" setenv(\"SHC_ARGV0\", argv[0], 1);",
" char pids[16]; snprintf(pids, sizeof(pids), \"%d\", getpid());",
" setenv(\"SHC_PID\", pids, 1);",
" if(PIPESCRIPT && ret) {",
" char tnm[128];",
" int l=100;",
" unsigned r;",
" for(r=getpid(); l--; ) {",
" r = (r*1436856257)%1436856259;",
" sprintf(tnm, \"/tmp/%08x\", r);",
" if(!mkfifo(tnm, S_IWUSR|S_IRUSR)) { break; }",
" }",
" if(l<0) exit(1);",
" if((i=fork())) {",
" waitpid(i, 0, 0);",
" } else if(fork()) {",
" _exit(0);",
" } else {",
" int w,",
" fd;",
" close(0);",
" close(1);",
" close(2);",
" fd = open(tnm, O_WRONLY);",
" unlink(tnm);",
" for(i=0, l=strlen(text); i<l; i+=w) {",
" if((w=l-i)>BUFSIZ) w=BUFSIZ;",
" if((w=write(fd, text+i, w))<0) break;",
" memset(text+i, 0, w);",
" }",
" _exit(0);",
" }",
" varg[j++] = tnm;",
" i = (ret > 1) ? ret : 1;/* Args numbering correction */",
" goto xec;",
" }",
" if (ret && *opts)",
" varg[j++] = opts; /* Options on 1st line of code */",
" if (*inlo)",
Expand All @@ -722,6 +765,7 @@ static const char * RTC[] = {
" if (*lsto)",
" varg[j++] = lsto; /* Option meaning last option */",
" i = (ret > 1) ? ret : 0; /* Args numbering correction */",
"xec:",
" while (i < argc)",
" varg[j++] = argv[i++]; /* Main run-time arguments */",
" varg[j] = 0; /* NULL terminated array */",
Expand Down Expand Up @@ -759,7 +803,7 @@ static const char * RTC[] = {
static int parse_an_arg(int argc, char * argv[])
{
extern char * optarg;
const char * opts = "e:m:f:i:x:l:o:rvDSUHCAB2h";
const char * opts = "e:m:f:i:x:l:o:rvDSUHPCAB2h";
struct tm tmp[1];
time_t expdate;
int cnt, l;
Expand Down Expand Up @@ -823,6 +867,9 @@ static int parse_an_arg(int argc, char * argv[])
case 'U':
TRACEABLE_flag = 0;
break;
case 'P':
PIPESCRIPT_flag = 1;
break;
case 'H':
HARDENING_flag = 1;
break;
Expand Down Expand Up @@ -1005,6 +1052,9 @@ struct {
{ "ash", "-c", "--", "exec '%s' \"$@\"" }, /* Linux */
{ "csh", "-c", "-b", "exec '%s' $argv" }, /* AIX: No file for $0 */
{ "tcsh", "-c", "-b", "exec '%s' $argv" },
{ "python", "-c", "", "import os,sys;os.execv('%s',sys.argv)" },
{ "python2", "-c", "", "import os,sys;os.execv('%s',sys.argv)" },
{ "python3", "-c", "", "import os,sys;os.execv('%s',sys.argv)" },
{ NULL, NULL, NULL, NULL },
};

Expand Down Expand Up @@ -1102,7 +1152,7 @@ char * read_script(char * file)
text[l] = '\0';

/* Check current System ARG_MAX limit. */
if (l > 0.80 * (cnt = sysconf(_SC_ARG_MAX))) {
if (!PIPESCRIPT_flag && l > 0.80 * (cnt = sysconf(_SC_ARG_MAX))) {
fprintf(stderr, "%s: WARNING!!\n"
" Scripts of length near to (or higher than) the current System limit on\n"
" \"maximum size of arguments to EXEC\", could comprise its binary execution.\n"
Expand Down Expand Up @@ -1286,8 +1336,9 @@ int write_C(char * file, char * argv[])
fprintf(o, SETUID_line, SETUID_flag);
fprintf(o, DEBUGEXEC_line, DEBUGEXEC_flag);
fprintf(o, TRACEABLE_line, TRACEABLE_flag);
fprintf(o, PIPESCRIPT_line, PIPESCRIPT_flag);
fprintf(o, HARDENING_line, HARDENING_flag);
fprintf(o, BUSYBOXON_line, BUSYBOXON_flag);
fprintf(o, BUSYBOXON_line, BUSYBOXON_flag);
fprintf(o, MMAP2_line, MMAP2_flag);
for (indx = 0; RTC[indx]; indx++)
fprintf(o, "%s\n", RTC[indx]);
Expand All @@ -1312,12 +1363,12 @@ int make(void)
if (!ldflags)
ldflags = "";

if(!file2){
file2=(char*)realloc(file2,strlen(file)+3);
strcpy(file2,file);
file2=strcat(file2,".x");
if(!file2){
file2=(char*)realloc(file2,strlen(file)+3);
strcpy(file2,file);
file2=strcat(file2,".x");

}
}
sprintf(cmd, "%s %s %s %s.x.c -o %s", cc, cflags, ldflags, file, file2);
if (verbose) fprintf(stderr, "%s: %s\n", my_name, cmd);
if (system(cmd))
Expand Down
5 changes: 5 additions & 0 deletions test/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/python3

import os, sys
print(os.environ["_"])
print(sys.argv)
15 changes: 10 additions & 5 deletions test/ttest.sh
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#!/bin/bash

shells=('/bin/sh' '/bin/dash' '/bin/bash' '/bin/ash' '/bin/ksh' '/bin/zsh' '/usr/bin/tcsh' '/bin/csh' '/usr/bin/rc')
shells=('/bin/sh' '/bin/dash' '/bin/bash' '/bin/ash' '/bin/ksh' '/bin/zsh' '/usr/bin/tcsh' '/bin/csh' '/usr/bin/rc' '/usr/bin/python' '/usr/bin/python2' '/usr/bin/python3')
## Install: sudo apt install dash bash ash ksh zsh tcsh csh rc

check_opts=('' '-r' '-v' '-D' '-S')
check_opts=('' '-r' '-v' '-D' '-S' '-P')

shc=${1-shc}

Expand All @@ -17,12 +17,17 @@ fc=0
echo
echo "== Running tests ..."
for shell in ${shells[@]}; do
[ -x "$shell" ] || continue
for opt in "${check_opts[@]}"; do
tmpd=$(mktemp -d)
tmpf="$tmpd/test.$(basename $shell)"
echo '#!'"$shell
echo 'Hello World fp:'\$1 sp:\$2
" > "$tmpf"
echo '#!'"$shell" >"$tmpf"
if [ ${shell#*pyth} = "$shell" ]; then
echo "echo 'Hello World fp:'\$1 sp:\$2"
else
echo 'import sys'
echo 'sys.stdout.write(("Hello World fp:%s sp:%s" % (sys.argv[1],sys.argv[2]))+"\n")'
fi >> "$tmpf"
"$shc" $opt -f "$tmpf" -o "$tmpd/a.out"
out=$("$tmpd/a.out" first second)
#~ echo " Output: $out"
Expand Down