站内搜索

搜索
热搜: 活动 交友 discuz

七一资源网

Linux shell加密解密方法(gzexe、shc)

365

主题

0

回帖

371

积分

首席执行官-CEO

UID
1
金叶子
6
在线时间
76 小时
注册时间
2023-10-27
最后登录
2024-11-23
发表于 2023-11-7 03:47:55 | 显示全部楼层 |阅读模式
一、系统自带gzexe

gzexe无需安装任何软件,是linux自带的功能,只需要执行命令即可,我们可以利用wget将文件放在root目录下,也可以通过sftp放在root目录,也可以直接利用cd命令选择任意目录

加密方法

假如说我们当前目录下有个脚本名字叫test.sh
那我们就执行下面的方法进行加密

gzexe test.sh
此时在目录下就会产生一个test.sh~文件,改文件是源文件,test.sh是加密后的文件
(注意:执行加密的文件跟执行源文件没有区别)

解密方法

假如说我们这个脚本名字叫test.sh
那我们就执行如下命令进行解密

gzexe -d test.sh
同上,在目录下就会产生一个test.sh~文件,改文件是源文件,test.sh是加密后的文件

二、shc加密软件

shc是linux的一款加密脚本的插件,东西比较安全,shc官网:http://www.datsi.fi.upm.es/%7Efrosal/

安装方法

执行如下脚本安装shc

wget https://www.datsi.fi.upm.es/%7Efrosal/sources/shc-3.8.9.tgz

tar vxf shc-3.8.9.tgz

cd shc-3.8.9

mkdir -p /usr/local/man/man1

make install

如果不执行mkdir -p /usr/local/man/man1将会报如下错误

*** Installing shc and shc.1 on /usr/local *** ?Do you want to continue? y install -c -s shc /usr/local/bin/ install -c -m 644 shc.1 /usr/local/man/man1/ install: target `/usr/local/man/man1/’ is not a directory: No such file or directory make: *** [install] Error 1

shc常用参数:

-e date (指定过期日期)

-m message (指定过期提示的信息)

-f script_name(指定要编译的shell的路径及文件名)

-r Relax security. (可以相同操作系统的不同系统中执行)

-v Verbose compilation(编译的详细情况)

加密方法

假如说我们这个脚本名字叫test.sh

那我们就执行如下命令进行加密

shc -v -f test.sh
-v 是现实加密过程

-f 后面跟需要加密的文件

abc.sh.x为加密后的二进制文件,赋予执行权限后,可直接执行。更改名字mv vpsps.sh.x vpspscom.sh

abc.sh.x.c 是c源文件。基本没用,可以删除

过期加密法

另shc还提供了一种设定有效执行期限的方法,过期时间,如:

# shc -e 14/09/2016 -m -f test.sh
选项“-e”指定过期时间,格式为“日/月/年”;选项“-m”指定过期后执行此Shell程序的提示信息。

如果在过期后执行,则会有如下提示:

# ./abc.sh.x

./abc.sh.x: has expired!(文件已经过期)

使用以上方法要注意,需防止用户更改系统时间,可以通过在程序中加入自动更新系统时间的命令来解决此问题。测试都已通过!

解密方法

利用unshc来解密
网址:https://github.com/yanncam/UnSHc/

unshc使用方法

将unshc wget或者上传到任意目录
然后可执行如下命令查看帮助

./unshc.sh -h
执行下面的命令进行解密(此过程可能耗时有点长,需耐心等待)

./unshc.sh script.sh.x -o script_decrypted.sh
script.sh.x文件为经过加密的二进制文件 script_decrypted.sh文件为解密后shell脚本

github.com/yanncam/UnSHc/blob/master/release/0.8/unshc-v0.8.sh

可以将下面的代码保存成unshc.sh文件即可,给可执行权限后(chmod 777 unshc.sh),直接使用
  1. #!/bin/bash
  2. ###################
  3. # Author: Luiz Otavio Duarte a.k.a. (LOD)
  4. #  11/03/08 - v0.1
  5. # Updated: Yann CAM v0.2 - yann.cam@gmail.com | www.asafety.fr
  6. #  06/27/13 - v0.2
  7. #  -- Adding new objdump format (2.22) to retrieve data (especially on Ubuntu distribution)
  8. #  -- Patch few regex with sorted address list
  9. # Updated: Yann CAM v0.3 - yann.cam@gmail.com | www.asafety.fr
  10. #  18/11/15 - v0.3
  11. #  -- Adapt script for new architecture
  12. #  -- Clean and optimize functions
  13. #  -- Add an (unsigned long) cast in shc C source code
  14. # Updated: Yann CAM v0.4 - yann.cam@gmail.com | www.asafety.fr
  15. #  14/12/15 - v0.4
  16. #  -- Comment specific return statement in C source
  17. # Updated: Yann CAM v0.5 - yann.cam@gmail.com | www.asafety.fr
  18. #  15/12/15 - v0.5
  19. #  -- Patch extract arc4 function to keep the latest offset only
  20. # Updated: Yann CAM v0.6 - yann.cam@gmail.com | www.asafety.fr
  21. #  16/12/15 - v0.6
  22. #  -- Add bash script options (getopts)
  23. # Updated: Yann CAM v0.7 - yann.cam@gmail.com | www.asafety.fr
  24. #  07/28/16 - v0.7
  25. #  -- Add support of multiple ARC4 offsets auto-retrieved by script (iterate over each one), specialy for huge bash file encrypted
  26. #  -- Force .sh extension to decrypted file, for initial file without extension (prevent rewrite of original file)
  27. # Updated: Yann CAM v0.8 - yann.cam@gmail.com | www.asafety.fr
  28. #  01/23/17 - v0.8
  29. #  -- Adjust grep for retrieve PWD_SIZE in OBJDUMP to ignore movb instruction (https://github.com/yanncam/UnSHc/issues/12)
  30. ###################
  31. # Tested on :
  32. #  Ubuntu 14.04.3 LTS x86_64
  33. #    Linux server 3.13.0-61-generic #100-Ubuntu SMP Wed Jul 29 11:21:34 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
  34. #    Linux version 3.13.0-61-generic (buildd@lgw01-50) (gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) ) #100-Ubuntu SMP Wed Jul 29 11:21:34 UTC 2015
  35. #
  36. #  CentOS release 6.6 (Final) x86_64
  37. #    Linux server 2.6.32-504.23.4.el6.x86_64 #1 SMP Tue Jun 9 20:57:37 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
  38. #    Linux version 2.6.32-504.23.4.el6.x86_64 (mockbuild@c6b9.bsys.dev.centos.org) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-11) (GCC) ) #1 SMP Tue Jun 9 20:57:37 UTC 2015
  39. #
  40. #  Debian 7.8 i686
  41. #    Linux server 3.2.0-4-686-pae #1 SMP Debian 3.2.68-1+deb7u2 i686 GNU/Linux
  42. #    Linux version 3.2.0-4-686-pae (debian-kernel@lists.debian.org) (gcc version 4.6.3 (Debian 4.6.3-14) ) #1 SMP Debian 3.2.68-1+deb7u2
  43. ###################
  44. VERSION="0.8"

  45. OBJDUMP=`which objdump`
  46. GREP=`which grep`
  47. CUT=`which cut`
  48. SHRED=`which shred`
  49. UNIQ=`which uniq`
  50. SORT=`which sort`
  51. GCC=`which gcc`
  52. WC=`which wc`
  53. AWK=`which awk`
  54. SED=`which sed`
  55. TR=`which tr`
  56. HEAD=`which head`
  57. TAIL=`which tail`

  58. BINARY=""
  59. TMPBINARY=$(mktemp /tmp/XXXXXX)
  60. DUMPFILE=""
  61. STRINGFILE=""
  62. CALLFILE=$(mktemp /tmp/XXXXXX)
  63. CALLADDRFILE=$(mktemp /tmp/XXXXXX)
  64. CALLSIZEFILE=$(mktemp /tmp/XXXXXX)

  65. declare -A LISTOFCALL

  66. # Variable to know the index of variables.
  67. # This var is to loop on each 14 arc4() call with ordered args.
  68. j=0

  69. # Simple usage help / man
  70. function usage(){
  71.         printf "[*] Usage : $0 [OPTIONS] <file.sh.x>\n"
  72.         printf "\t -h | --help                          : print this help message\n"
  73.         printf "\t -a OFFSET | --arc4 OFFSET            : specify the arc4() offset arbitrarily (without 0x prefix)\n"
  74.         printf "\t -d DUMPFILE | --dumpfile DUMPFILE    : provide an object dump file (objdump -D script.sh.x > DUMPFILE)\n"
  75.         printf "\t -s STRFILE | --stringfile STRFILE    : provide a string dump file (objdump -s script.sh.x > STRFILE)\n"
  76.         printf "\t -o OUTFILE | --outputfile OUTFILE    : indicate the output file name\n\n"
  77.         printf "[*] e.g : \n"
  78.         printf "\t$0 script.sh.x\n"
  79.         printf "\t$0 script.sh.x -o script_decrypted.sh\n"
  80.         printf "\t$0 script.sh.x -a 400f9b\n"
  81.         printf "\t$0 script.sh.x -d /tmp/dumpfile -s /tmp/strfile\n"
  82.         printf "\t$0 script.sh.x -a 400f9b -d /tmp/dumpfile -s /tmp/strfile -o script_decrypted.sh\n"
  83. }

  84. # Clean all temp file created for this script
  85. function clean(){
  86.         $SHRED -zu -n 1 $DUMPFILE $CALLFILE $CALLADDRFILE $CALLSIZEFILE $STRINGFILE $TMPBINARY ${TMPBINARY}.c >/dev/null 2>&1
  87. }

  88. # Clean error exit function after cleaning temp file
  89. function exit_error(){
  90.         clean
  91.         exit 1;
  92. }

  93. # Check the availability of basic commands usefull for this script
  94. function check_binaries() {
  95.         if [ ! -x ${OBJDUMP} ]; then
  96.                 echo "[-] Error, cannot execute or find objdump binary"
  97.                 exit_error
  98.         fi
  99.         if [ ! -x ${GREP} ]; then
  100.                 echo "[-] Error, cannot execute or find grep binary"
  101.                 exit_error
  102.         fi
  103.         if [ ! -x ${CUT} ]; then
  104.                 echo "[-] Error, cannot execute or find cut binary"
  105.                 exit_error
  106.         fi
  107.         if [ ! -x ${SHRED} ]; then
  108.                 echo "[-] Error, cannot execute or find shred binary"
  109.                 exit_error
  110.         fi
  111.         if [ ! -x ${UNIQ} ]; then
  112.                 echo "[-] Error, cannot execute or find uniq binary"
  113.                 exit_error
  114.         fi
  115.         if [ ! -x ${SORT} ]; then
  116.                 echo "[-] Error, cannot execute or find sort binary"
  117.                 exit_error
  118.         fi
  119.         if [ ! -x ${GCC} ]; then
  120.                 echo "[-] Error, cannot execute or find gcc binary"
  121.                 exit_error
  122.         fi
  123.         if [ ! -x ${WC} ]; then
  124.                 echo "[-] Error, cannot execute or find wc binary"
  125.                 exit_error
  126.         fi
  127. }

  128. # Create dump files of encrypted script
  129. function generate_dump() {
  130.         # DUMPFILE dump to retrive arc4 address, address and size of each arc4 arguments and pwd
  131.         $OBJDUMP -D $BINARY > "$DUMPFILE"
  132.         # STRINGFILE dump to retrieve pwd and arc4 argument
  133.         $OBJDUMP -s $BINARY > "$STRINGFILE"
  134. }

  135. # Find out the most called function. This function is arc4() and there are 14 calls.
  136. # Update 27/06/2013 : Regexps updated to match new objdump format and retrieve the $CALLADDR from his number of call (bug initial with "sort")
  137. # Update 16/11/2015 : Adding new architecture support
  138. # Update 28/07/2016 : Adding multiple ARC4 offsets support (loop on each candidate)
  139. function extract_arc4_call_addr(){
  140.         TAILNUMBER=$1
  141.         CALLADDRS=$($GREP -Eo "call.*[0-9a-f]{6,}" $DUMPFILE | $GREP -Eo "[0-9a-f]{6,}" | $SORT | $UNIQ -c | $SORT | $GREP -Eo "(14).*[0-9a-f]{6,}" | $GREP -Eo "[0-9a-f]{6,}")
  142.         TAILMAX=`wc -l <<< "$CALLADDRS"`
  143.         CALLADDR=$(echo $CALLADDRS | $SED "s/ /\n/g" | $TAIL -n $TAILNUMBER | $HEAD -n 1)
  144.         if [[ -z "$CALLADDR" || $TAILNUMBER -gt $TAILMAX ]]; then
  145.            echo "[-] Unable to define arc4() call address..."
  146.            exit_error
  147.         fi
  148.         echo "[+] ARC4 address call candidate : [0x$CALLADDR]"
  149. }

  150. # Extract each args values of arc4 calls
  151. function extract_variables_from_binary(){
  152.         echo "[*] Extracting each args address and size for the 14 arc4() calls with address [0x$CALLADDR]..."
  153.         # Initialize the number of line before CALLADDR to looking for addresses of args
  154.         i=2
  155.         # Retrieve ordered list of address var and put it to $CALLADDRFILE
  156.         while [[ $($WC -l < $CALLADDRFILE) -ne 14 ]]; do
  157.                 $GREP -B $i "call.*$CALLADDR" $DUMPFILE | $GREP -v "$CALLADDR" | $GREP -Eo "(0x[0-9a-f]{6,})" > $CALLADDRFILE
  158.                 i=$(($i + 1))
  159.                 if [ $i -eq 10 ]; then
  160.                         echo "[-] Unable to extract addresses of 14 arc4 args with ARC4 address call [0x$CALLADDR]..."
  161.                         return;
  162.                 fi
  163.         done

  164.         # Initialize the number of line before CALLADDR to looking for sizes of args
  165.         i=3
  166.         # Retrieve ordered list of size var and append it to $CALLSIZEFILE
  167.         while [[ $($WC -l < $CALLSIZEFILE) -ne 14 ]]; do
  168.                 $GREP -B $i "call.*$CALLADDR" $DUMPFILE | $GREP -v "$CALLADDR" | $GREP -Eo "(0x[0-9a-f]+,)" | $GREP -Eo "(0x[0-9a-f]+)" | $GREP -Ev "0x[0-9a-f]{6,}" > $CALLSIZEFILE
  169.                 i=$(($i + 1))
  170.                 if [ $i -eq 10 ]; then
  171.                         echo "[-] Unable to extract sizes of 14 arc4 args with ARC4 address call [0x$CALLADDR]..."
  172.                         return;
  173.                 fi
  174.         done

  175.         # For each full address in $CALLADDRFILE and corresponding size in $CALLSIZEFILE
  176.         IFS=$'\n' read -d '' -r -a LISTOFADDR < $CALLADDRFILE
  177.         IFS=$'\n' read -d '' -r -a LISTOFSIZE < $CALLSIZEFILE
  178.         for (( x = 0; x < ${#LISTOFADDR[*]}; x = x+1 ))
  179.         do
  180.                 i=${LISTOFADDR[$x]}
  181.                 NBYTES=${LISTOFSIZE[$x]}
  182.         echo -e "\t[$x] Working with var address at offset [$i] ($NBYTES bytes)"
  183.         # Some diferences in assembly.
  184.         # We can have:
  185.         #  mov <adr>,%eax
  186.         #  push 0x<hex>
  187.         #  push %eax
  188.         #  call $CALLADDR
  189.         #
  190.         #  or
  191.         #
  192.         #  push 0x<hex>
  193.         #  push 0x<adr>
  194.         #  call $CALLADDR
  195.         #
  196.         # UPDATE 27/06/2013 :
  197.         # Adding support of objdump format
  198.         # New format supported (Debian 7 x86) :
  199.         #
  200.         #  movl   $0x<hex>,0x4(%esp)
  201.         #
  202.         #  movl   $0x<adr>,(%esp)
  203.         #  call   $CALLADDR
  204.         #
  205.         # UPDATE 18/11/2015 :
  206.         # Adding support of objdump format
  207.         # Ubuntu 14.04 LTS x86_64
  208.         #
  209.         #  mov    $0x<hex>,%esi
  210.         #  mov    $0x<adr>,%edi
  211.         #  callq  $CALLADDR <fork@plt+0x23b>
  212.         #

  213.         # Key is the address with the variable content.
  214.         KEY=$(echo $i | $CUT -d 'x' -f 2)

  215.         # A 2 bytes variable (NBYTES > 0) can be found like this: (in STRINGFILE)
  216.         # ---------------X
  217.         # X---------------
  218.         #
  219.         # So we need 2 lines from STRINGFILE to make it all correct. So:
  220.         NLINES=$(( ($NBYTES / 16) +2 ))

  221.         # All line in STRINGFILE starts from 0 to f. So LASTBIT tells me the index in the line to start recording.
  222.         let LASTBYTE="0x${KEY:$((${#KEY}-1))}"

  223.         # Grep all lines needed from STRINGFILE, merge lines.
  224.         STRING=$( $GREP -A $(($NLINES-1)) -E "^ ${KEY:0:$((${#KEY}-1))}0 " $STRINGFILE | $AWK '{ print $2$3$4$5}' | $TR '\n' 'T' | $SED -e "s:T::g")

  225.         # Change string to begin in the line index.
  226.         STRING=${STRING:$((2*$LASTBYTE))}
  227.         # Cut the string to the number off bytes of the variable.
  228.         STRING=${STRING:0:$(($NBYTES * 2))}

  229.         # We need to convert to a \x??\x?? structure so:
  230.         FINALSTRING=""
  231.         for ((i = 0; i < $((${#STRING} /2 )); i++)); do
  232.                         FINALSTRING="${FINALSTRING}\x${STRING:$(($i * 2)):2}"
  233.         done

  234.         define_variable
  235.    done
  236. }

  237. # arc4 function is called 14 times in the C code.
  238. # Each call is done with the same args sequence even if their declaration is randomized :
  239. # msg1, date, shll, inlo, xecc, lsto, tst1, chk1, msg2, rlax, opts, text, tst2 and chk2.
  240. function define_variable() {
  241.    case "$j" in
  242.    0)   VAR_MSG1=$FINALSTRING
  243.                 VAR_MSG1_Z=$NBYTES;;
  244.    1)   VAR_DATE=$FINALSTRING
  245.                 VAR_DATE_Z=$NBYTES;;
  246.    2)   VAR_SHLL=$FINALSTRING
  247.                 VAR_SHLL_Z=$NBYTES;;
  248.    3)   VAR_INLO=$FINALSTRING
  249.                 VAR_INLO_Z=$NBYTES;;
  250.    4)   VAR_XECC=$FINALSTRING
  251.                 VAR_XECC_Z=$NBYTES;;
  252.    5)   VAR_LSTO=$FINALSTRING
  253.                 VAR_LSTO_Z=$NBYTES;;
  254.    6)   VAR_TST1=$FINALSTRING
  255.                 VAR_TST1_Z=$NBYTES;;
  256.    7)   VAR_CHK1=$FINALSTRING
  257.                 VAR_CHK1_Z=$NBYTES;;
  258.    8)   VAR_MSG2=$FINALSTRING
  259.                 VAR_MSG2_Z=$NBYTES;;
  260.    9)   VAR_RLAX=$FINALSTRING
  261.                 VAR_RLAX_Z=$NBYTES;;
  262.    10)  VAR_OPTS=$FINALSTRING
  263.                 VAR_OPTS_Z=$NBYTES;;
  264.    11)  VAR_TEXT=$FINALSTRING
  265.                 VAR_TEXT_Z=$NBYTES;;
  266.    12)  VAR_TST2=$FINALSTRING
  267.                 VAR_TST2_Z=$NBYTES;;
  268.    13)  VAR_CHK2=$FINALSTRING
  269.                 VAR_CHK2_Z=$NBYTES;;
  270.    esac
  271.    j=$(($j + 1))
  272. }


  273. # The password is used in the key function right before first call to arc4.
  274. # So we need the previous call just before the first "call ARC4_CALLADDR" and its args.
  275. # Update 27/06/2013 : Add new objdump format
  276. # Update 18/11/2015 : Simplify extraction
  277. # Update 23/01/2017 : Ignore movb instruction
  278. function extract_password_from_binary(){
  279.         echo "[*] Extracting password..."
  280.         KEY_ADDR=""
  281.         KEY_SIZE=""

  282.         # Initialize the number of line before CALLADDR to watch
  283.         i=5
  284.         while [[ ( -z "$KEY_ADDR" ) || ( -z "$KEY_SIZE" ) ]]; do
  285.                 $GREP -B $i -m 1 "call.*$CALLADDR" $DUMPFILE | $GREP -v $CALLADDR > $CALLFILE
  286.                 #cat $CALLFILE
  287.                 # Adjust these two next line to grep right addr & size value (depending on your architecture)
  288.                 KEY_ADDR=$($GREP -B 3 -m 1 "call" $CALLFILE | $GREP mov | $GREP -oE "0x[0-9a-z]{6,}+" | $HEAD -n 1)
  289.                 KEY_SIZE=$($GREP -B 3 -m 1 "call" $CALLFILE | $GREP mov | $GREP -v $KEY_ADDR | $GREP -v movb | $GREP -oE "0x[0-9a-z]+" | $HEAD -n 1)
  290.                 i=$(($i + 1))
  291.                 if [ $i -eq 10 ]; then
  292.                         echo "[-] Error, function call previous first call of arc4() hasn't been identified..."
  293.                         exit_error
  294.                 fi
  295.         done
  296.         echo -e "\t[+] PWD address found : [$KEY_ADDR]"
  297.         echo -e "\t[+] PWD size found : [$KEY_SIZE]"

  298.         # Defining the address without 0x.
  299.         KEY=$(echo $KEY_ADDR | $CUT -d 'x' -f 2)
  300.         # Like the other NLINES
  301.         NLINES=$(( ($KEY_SIZE / 16) +2 ))
  302.         # Like the other LASTBYTE
  303.         LASTBYTE="0x${KEY:$((${#KEY}-1))}"
  304.         # Extract PWD from STRINGFILE
  305.         STRING=$( $GREP -A $(($NLINES-1)) -E "^ ${KEY:0:$((${#KEY}-1))}0 " $STRINGFILE | $AWK '{ print $2$3$4$5}' | $TR '\n' 'T' | $SED -e "s:T::g")
  306.         STRING=${STRING:$((2*$LASTBYTE))}
  307.         STRING=${STRING:0:$(($KEY_SIZE * 2))}
  308.         # Encode / rewrite PWD in the \x??\x?? format
  309.         FINALSTRING=""
  310.         for ((i=0;i<$((${#STRING} /2 ));i++)); do
  311.                 FINALSTRING="${FINALSTRING}\x${STRING:$(($i * 2)):2}"
  312.         done
  313.         VAR_PSWD=$FINALSTRING
  314. }

  315. # This function append a generic engine for decrypt from shc project. With out own new variables extracted.
  316. # Rather than execute the source code decrypted, it's printed in stdout.
  317. function generic_file(){
  318. cat > ${TMPBINARY}.c << EOF
  319. #define msg1_z $VAR_MSG1_Z
  320. #define date_z $VAR_DATE_Z
  321. #define shll_z $VAR_SHLL_Z
  322. #define inlo_z $VAR_INLO_Z
  323. #define xecc_z $VAR_XECC_Z
  324. #define lsto_z $VAR_LSTO_Z
  325. #define tst1_z $VAR_TST1_Z
  326. #define chk1_z $VAR_CHK1_Z
  327. #define msg2_z $VAR_MSG2_Z
  328. #define rlax_z $VAR_RLAX_Z
  329. #define opts_z $VAR_OPTS_Z
  330. #define text_z $VAR_TEXT_Z
  331. #define tst2_z $VAR_TST2_Z
  332. #define chk2_z $VAR_CHK2_Z
  333. #define pswd_z $KEY_SIZE
  334. static char msg1 [] = "$VAR_MSG1";
  335. static char date [] = "$VAR_DATE";
  336. static char shll [] = "$VAR_SHLL";
  337. static char inlo [] = "$VAR_INLO";
  338. static char xecc [] = "$VAR_XECC";
  339. static char lsto [] = "$VAR_LSTO";
  340. static char tst1 [] = "$VAR_TST1";
  341. static char chk1 [] = "$VAR_CHK1";
  342. static char msg2 [] = "$VAR_MSG2";
  343. static char rlax [] = "$VAR_RLAX";
  344. static char opts [] = "$VAR_OPTS";
  345. static char text [] = "$VAR_TEXT";
  346. static char tst2 [] = "$VAR_TST2";
  347. static char chk2 [] = "$VAR_CHK2";
  348. static char pswd [] = "$VAR_PSWD";
  349. #define      hide_z     4096
  350. /* rtc.c */
  351. #include <sys/stat.h>
  352. #include <sys/types.h>
  353. #include <errno.h>
  354. #include <stdio.h>
  355. #include <stdlib.h>
  356. #include <string.h>
  357. #include <time.h>
  358. #include <unistd.h>
  359. /* 'Alleged RC4' */
  360. static unsigned char stte[256], indx, jndx, kndx;
  361. /*
  362. * Reset arc4 stte.
  363. */
  364. void stte_0(void)
  365. {
  366.         indx = jndx = kndx = 0;
  367.         do {
  368.                 stte[indx] = indx;
  369.         } while (++indx);
  370. }
  371. /*
  372. * Set key. Can be used more than once.
  373. */
  374. void key(void * str, int len)
  375. {
  376.         unsigned char tmp, * ptr = (unsigned char *)str;
  377.         while (len > 0) {
  378.                 do {
  379.                         tmp = stte[indx];
  380.                         kndx += tmp;
  381.                         kndx += ptr[(int)indx % len];
  382.                         stte[indx] = stte[kndx];
  383.                         stte[kndx] = tmp;
  384.                 } while (++indx);
  385.                 ptr += 256;
  386.                 len -= 256;
  387.         }
  388. }
  389. /*
  390. * Crypt data.
  391. */
  392. void arc4(void * str, int len)
  393. {
  394.         unsigned char tmp, * ptr = (unsigned char *)str;
  395.         while (len > 0) {
  396.                 indx++;
  397.                 tmp = stte[indx];
  398.                 jndx += tmp;
  399.                 stte[indx] = stte[jndx];
  400.                 stte[jndx] = tmp;
  401.                 tmp += stte[indx];
  402.                 *ptr ^= stte[tmp];
  403.                 ptr++;
  404.                 len--;
  405.         }
  406. }
  407. /* End of ARC4 */
  408. /*
  409. * Key with file invariants.
  410. */
  411. int key_with_file(char * file)
  412. {
  413.         struct stat statf[1];
  414.         struct stat control[1];
  415.         if (stat(file, statf) < 0)
  416.                 return -1;
  417.         /* Turn on stable fields */
  418.         memset(control, 0, sizeof(control));
  419.         control->st_ino = statf->st_ino;
  420.         control->st_dev = statf->st_dev;
  421.         control->st_rdev = statf->st_rdev;
  422.         control->st_uid = statf->st_uid;
  423.         control->st_gid = statf->st_gid;
  424.         control->st_size = statf->st_size;
  425.         control->st_mtime = statf->st_mtime;
  426.         control->st_ctime = statf->st_ctime;
  427.         key(control, sizeof(control));
  428.         return 0;
  429. }
  430. void rmarg(char ** argv, char * arg)
  431. {
  432.         for (; argv && *argv && *argv != arg; argv++);
  433.         for (; argv && *argv; argv++)
  434.                 *argv = argv[1];
  435. }
  436. // Update 18/11/2015 : Update "mask" casting from "unsigned" to "unsigned long".
  437. int chkenv(int argc)
  438. {
  439.         char buff[512];
  440.         unsigned mask, m;
  441.         int l, a, c;
  442.         char * string;
  443.         extern char ** environ;
  444.         mask  = (unsigned long)chkenv;
  445.         mask ^= (unsigned)getpid() * ~mask;
  446.         sprintf(buff, "x%x", mask);
  447.         string = getenv(buff);
  448.         l = strlen(buff);
  449.         if (!string) {
  450.                 /* 1st */
  451.                 sprintf(&buff[l], "=%u %d", mask, argc);
  452.                 putenv(strdup(buff));
  453.                 return 0;
  454.         }
  455.         c = sscanf(string, "%u %d%c", &m, &a, buff);
  456.         if (c == 2 && m == mask) {
  457.                 /* 3rd */
  458.                 rmarg(environ, &string[-l - 1]);
  459.                 return 1 + (argc - a);
  460.         }
  461.         return -1;
  462. }
  463. char * xsh(int argc, char ** argv)
  464. {
  465.         char * scrpt;
  466.         int ret, i, j;
  467.         char ** varg;
  468.         stte_0();
  469.         key(pswd, pswd_z);
  470.         arc4(msg1, msg1_z);
  471.         arc4(date, date_z);
  472.         //if (date[0] && date[0]<time(NULL))
  473.         //        return msg1;
  474.         arc4(shll, shll_z);
  475.         arc4(inlo, inlo_z);
  476.         arc4(xecc, xecc_z);
  477.         arc4(lsto, lsto_z);
  478.         arc4(tst1, tst1_z);
  479.         key(tst1, tst1_z);
  480.         arc4(chk1, chk1_z);
  481.         if ((chk1_z != tst1_z) || memcmp(tst1, chk1, tst1_z))
  482.                 return tst1;
  483.         ret = chkenv(argc);
  484.         arc4(msg2, msg2_z);
  485.         if (ret < 0)
  486.                 return msg2;
  487.         varg = (char **)calloc(argc + 10, sizeof(char *));
  488.         if (!varg)
  489.                 return 0;
  490.         if (ret) {
  491.                 arc4(rlax, rlax_z);
  492.                 if (!rlax[0] && key_with_file(shll))
  493.                         return shll;
  494.                 arc4(opts, opts_z);
  495.                 arc4(text, text_z);
  496.                 printf("%s",text);
  497.                 return 0;
  498.                 /*arc4(tst2, tst2_z);
  499.                 key(tst2, tst2_z);
  500.                 arc4(chk2, chk2_z);
  501.                 if ((chk2_z != tst2_z) || memcmp(tst2, chk2, tst2_z))
  502.                         return tst2;
  503.                 if (text_z < hide_z) {
  504.                         scrpt = malloc(hide_z);
  505.                         if (!scrpt)
  506.                                 return 0;
  507.                         memset(scrpt, (int) ' ', hide_z);
  508.                         memcpy(&scrpt[hide_z - text_z], text, text_z);
  509.                 } else {
  510.                         scrpt = text;
  511.                 }*/
  512.         } else {
  513.                 if (*xecc) {
  514.                         scrpt = malloc(512);
  515.                         if (!scrpt)
  516.                                 return 0;
  517.                         sprintf(scrpt, xecc, argv[0]);
  518.                 } else {
  519.                         scrpt = argv[0];
  520.                 }
  521.         }
  522.         j = 0;
  523.         varg[j++] = argv[0];            /* My own name at execution */
  524.         if (ret && *opts)
  525.                 varg[j++] = opts;       /* Options on 1st line of code */
  526.         if (*inlo)
  527.                 varg[j++] = inlo;       /* Option introducing inline code */
  528.         varg[j++] = scrpt;              /* The script itself */
  529.         if (*lsto)
  530.                 varg[j++] = lsto;       /* Option meaning last option */
  531.         i = (ret > 1) ? ret : 0;        /* Args numbering correction */
  532.         while (i < argc)
  533.                 varg[j++] = argv[i++];  /* Main run-time arguments */
  534.         varg[j] = 0;                    /* NULL terminated array */
  535.         execvp(shll, varg);
  536.         return shll;
  537. }
  538. int main(int argc, char ** argv)
  539. {
  540.         argv[1] = xsh(argc, argv);
  541.         return 1;
  542. }
  543. EOF
  544. }

  545. ##########################################
  546. ## Starting
  547. echo " _   _       _____ _   _      "
  548. echo "| | | |     /  ___| | | |     "
  549. echo "| | | |_ __ \ \`--.| |_| | ___ "
  550. echo "| | | | '_ \ \`--. \  _  |/ __|"
  551. echo "| |_| | | | /\__/ / | | | (__ "
  552. echo " \___/|_| |_\____/\_| |_/\___|"
  553. echo
  554. echo "--- UnSHc - The shc decrypter."
  555. echo "--- Version: $VERSION"
  556. echo "------------------------------"
  557. echo "UnSHc is used to decrypt script encrypted with SHc"
  558. echo "Original idea from Luiz Octavio Duarte (LOD)"
  559. echo "Updated and modernized by Yann CAM"
  560. echo "- SHc   : [http://www.datsi.fi.upm.es/~frosal/]"
  561. echo "- UnSHc : [https://www.asafety.fr/unshc-the-shc-decrypter/]"
  562. echo "------------------------------"
  563. echo

  564. if [ $# -lt 1 ]; then
  565.         echo "[?] Type -h or --help for how to use it"
  566.         clean
  567.         exit 0
  568. fi

  569. # Check the availability of each command needed in this script.
  570. check_binaries

  571. OPTS=$( getopt -o h,a:,d:,s:,o: -l help,arc4:,dumpfile:,stringfile:,outputfile: -- "$@" )
  572. if [ $? != 0 ]; then
  573.         exit_error;
  574. fi

  575. while [ "$#" -gt 0 ] ; do
  576.         case "$1" in
  577.                 -h|--help)
  578.                         usage;
  579.                         clean;
  580.                         exit 0;;
  581.                 -a|--arc4)
  582.                         echo "[+] ARC4() offset function call address specified [0x$2]";
  583.                         CALLADDR=$2;
  584.                         shift 2;;
  585.                 -d|--dumpfile)
  586.                         echo "[+] Object dump file specified [$2]";
  587.                         DUMPFILE=$2;
  588.                         shift 2;;
  589.                 -s|--stringfile)
  590.                         echo "[+] String dump file specified [$2]";
  591.                         STRINGFILE=$2;
  592.                         shift 2;;
  593.                 -o|--outputfile)
  594.                         echo "[+] Output file name specified [$2]";
  595.                         OUTPUTFILE=$2;
  596.                         shift 2;;
  597.                 -*)
  598.                         echo "[-] Unknown option: [$1]" >&2;
  599.                         exit_error;;
  600.                 --)
  601.                         shift;
  602.                         break;;
  603.                 *)
  604.                         echo "[*] Input file name to decrypt [$1]";
  605.                         BINARY=$1
  606.                         shift 1;;
  607.         esac
  608. done

  609. if [ ! -e $BINARY ]; then
  610.         echo "[-] Error, File [$BINARY] not found."
  611.         exit_error
  612. fi
  613. if [ -z "$DUMPFILE" ]; then
  614.          DUMPFILE=$(mktemp /tmp/XXXXXX)
  615. else
  616.         if [ ! -e $DUMPFILE ]; then
  617.                 echo "[-] Object dump file [$DUMPFILE] not found."
  618.                 exit_error;
  619.         fi
  620. fi
  621. if [ -z "$STRINGFILE" ]; then
  622.          STRINGFILE=$(mktemp /tmp/XXXXXX)
  623. else
  624.         if [ ! -e $STRINGFILE ]; then
  625.                 echo "[-] String dump file [$STRINGFILE] not found."
  626.                 exit_error;
  627.         fi
  628. fi

  629. # Fill DUMPFILE and STRINGFILE from objdump of the *.sh.x encrypted script
  630. generate_dump

  631. # Find out the most called function. This function is arc4() and there are 14 calls.
  632. # Then retrieve the data used in each CALLADDR call
  633. c=1
  634. if [ -z "$CALLADDR" ]; then
  635.         # Case when ARC4 offset is unknown and there are multiple candidate
  636.         while [[ $($WC -l < $CALLSIZEFILE) -ne 14 ]]; do
  637.                 extract_arc4_call_addr "$c"
  638.                 extract_variables_from_binary
  639.                 c=$(($c + 1))
  640.         done
  641. else
  642.         # Case when the ARC4 address is already defined and passed throught args
  643.         extract_variables_from_binary
  644. fi

  645. # Retrieve PWD from function call just before the first CALLADDR call
  646. extract_password_from_binary

  647. # Create a C source code to decrypt *.sh.x file with previously extracted data
  648. generic_file

  649. # Compile C source code to decrypt *.sh.x file
  650. $GCC -o $TMPBINARY ${TMPBINARY}.c >/dev/null 2>&1

  651. echo "[*] Executing [$TMPBINARY] to decrypt [${BINARY}]"

  652. chmod +x $TMPBINARY
  653. if [ -z "$OUTPUTFILE" ]; then
  654.         echo "[*] Retrieving initial source code in [${BINARY%.sh.x}.sh]"
  655.         $TMPBINARY > ${BINARY%.sh.x}.sh
  656. else
  657.         echo "[*] Retrieving initial source code in [$OUTPUTFILE]"
  658.         $TMPBINARY > $OUTPUTFILE
  659. fi

  660. echo "[*] All done!"
  661. clean
  662. exit 0
复制代码


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

企业
关于我们 加入我们
友情链接 媒体合作
联系我们 QQ群
官方
新浪微博 腾讯微博
百度贴吧 人人主页
脸书 推特
下载
安卓客户端 苹果客户端 桌面客户端
反馈
意见建议 用户使用协议
帮助
更多
捐助本站
安卓客户端

安卓客户端

苹果客户端

苹果客户端

Powered by Discuz! X3.4 © 2001-2013 Discuz Team.