shell加密 與 二進制


shell加密 與 二進制
shell腳本中嵌入二進制文件

20120911

http://hi.baidu.com/coolrainbow/item/ef918856724b4a9e08be1771
【原創】shell腳本中嵌入二進制文件

最近有人問我,一個集群監控軟件的安裝文件特別“詭異”,說腳本里有“亂碼”卻能執行,是怎么回事?我看了才發現這個東西原來是典型的腳本嵌套代碼的模式,這里就講講吧。反正好久沒寫東西了。

某些比較“拽”的單位在發布Linux軟件時以一種特殊的形式發布,即在shell腳本中嵌入二進制字符,從而使腳本變得極其詭異,讓某些初學者感覺驚奇。其實,這個原理戳穿了非常簡單,就是在運行腳本時將二進制代碼導出成一個程序,再執行之就可以。(不過這種行為其實,是違反Linux社區的精神的,像我這種人, 看到什么軟件第一反應都是想搞到其源碼)

1 簡單嵌入程序
原理:通常程序代碼處在腳本的最后位置。腳本運行時,把它導出來執行即可。

例:下面的這個源碼:

include <stdio.h>

include <stdlib.h>

int main(int argc, char** argv)
{
const char* envtagUSER="USER";
printf("Your Username: %s. This is detected by the program %s.\n", getenv(envtagUSER), argv[0]);
return 0;
}

這段代碼可以用來輸出用戶名。當然這僅僅是個例子,實際編程時用shell就可以得到。現在假設我們想把這段代碼嵌入一個名叫dofoo.sh的shell腳本中。首先編譯之:
gcc -Os foo.c -o foo
現在把foo追加到dofoo.sh的末尾:
cat foo >> dofoo.sh # Not > but >> !
打開dofoo.sh,添加代碼:

1 #!/bin/sh
2
3 skip=11
4 prog="/tmp/$0.exe"
5 tail -n +$skip "$0" > $prog
6 chmod u+x $prog
7 $prog
8 rm $prog
9 exit
10
11 ?EFLB
...
18 ....AMIC@data_start@__libc_csu_fini^@_sta

(11行以后用VI看都是亂碼)
看明白了吧!這代碼將腳本中11行以后的東西導入到了/tmp/dofoo.exe這個文件中,添加x權限,執行,然后刪除該文件。

2 加密偽裝
有時候一個shell中的亂碼並不一定是可執行文件,那些東西可能是某種壓縮格式,如bz2,gz等等,或者其他的某種加密形式,程序會先把他們導出來解壓在執行然后刪除,道理是一樣的。有時候,這種解壓程序或者解密程序本身就嵌套在shell腳本里,通常是商業公司干的事。

C調用shell指令

20120910 chenxin
1.自己編寫的調用測試程序
cat server.c
/*

  • server.c
  • Created on: 2012-9-9
  •  Author: uadmin
    

*/

include<stdlib.h>

include<stdio.h>

main()
{
system("pwd");
printf("%s\n","show the system passwd file and shadow file!");
system("./Debug/test.sh");
}
eclipse默認的工作環境是/home/uadmin/workspace/command/,如果--system("./Debug/test.sh");--輸入為system("./test.sh");的話,編譯可以通過,但run的時候會提示找不到二進制可執行文件;

2.網上的例子,測試是否可以將整個腳本的文本文件賦予一個數組變量

include <stdio.h>

include <string.h>

include<unistd.h>

int main(int argc ,char *argv[])
{
char arg[300]="/tmp/testDir/tsh.sh ";
if ( argv[1] != NULL )
{
strcat(arg,argv[1]);

    system(arg);
    printf("\ndone message in program\n");
    return 1;
}
else
{
    printf("Error: Empty input\n");
    return 0;
}

}

shell加密
20121008Chenxin
shc是一個加密shell腳本的工具.它的作用是把shell腳本轉換為一個可執行的二進制文件.

一、安裝:
wget http://www.datsi.fi.upm.es/~frosal/sources/shc-3.8.9.tgz
tar zxvf shc-3.8.9.tgz
cd shc-3.8.9
make && make install
make報錯處理
make: *** No rule to make target shc.c', needed by shc'. Stop.
cat makefile
shc: shc.c
$(CC) $(CFLAGS) $@.c -o $@
找不到shc.c文件,處理方法:
mv shc-3.8.9.c shc.c

二、使用
shc -r -f script-name 注意:要有-r選項, -f 后跟要加密的腳本名.
運行后會生成兩個文件,script-name.x 和 script-name.x.c
script-name.x是加密后的可執行的二進制文件.
./script-name 即可運行.
script-name.x.c是生成script-name.x的原文件(c語言)
shc Version 3.8.9, Generic Script Compiler
shc Copyright (c) 1994-2012 Francisco Rosales frosal@fi.upm.es
shc Usage: shc [-e date] [-m addr] [-i iopt] [-x cmnd] [-l lopt] [-rvDTCAh] -f script
-e %s Expiration date in dd/mm/yyyy format [none] #設置過期時間
-m %s Message to display upon expiration ["Please contact your provider"] #過期信息提示
-f %s File name of the script to compile #加密腳本名稱
-i %s Inline option for the shell interpreter i.e: -e
-x %s eXec command, as a printf format i.e: exec('%s',@ARGV);
-l %s Last shell option i.e: --
-r Relax security. Make a redistributable binary #在系統通用
-v Verbose compilation #詳細匯編
-D Switch ON debug exec calls [OFF]
-T Allow binary to be traceable [no]
-C Display license and exit #顯示許可證並退出
-A Display abstract and exit #顯示摘要和退出
-h Display help and exit #顯示幫助和退出

三、實例
shc -e 31/8/2012 -m ExpireTime:31/8/2012 -v -r -f test.sh
測試腳本每次都自動放入后台,且提示stoped;
通過以下方式可以成功:
shc -T -f test.sh

四、靜態編譯
4.1動態庫
查看
file scriptname.x
scriptname.bash.x: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped
注意:dynamically linked(uses shared libs)使用的是動態鏈接庫,不能跨平台使用
可以使用ldd查看具體使用的庫
ldd scriptname.x
如:ldd mysql_backup.bash.x
linux-vdso.so.1 => (0x00007fff019ff000)
libc.so.6 => /lib64/libc.so.6 (0x0000003a3c200000)
/lib64/ld-linux-x86-64.so.2 (0x0000003a3ba00000)
普通動態編譯:
shc -T -vrf test.sh

4.2靜態庫編譯方式
CFLAGS=... shc -r -f scriptname
CFLAGS中指定:-static選項等
CFLAGS=-static shc -T -f test.sh
執行靜態編譯無法通過,報錯如下:
CFLAGS=-static shc -T -f test.sh
/usr/bin/ld: cannot find -lc
collect2: ld returned 1 exit status
解決方法:
yum install -y glibc-static libstdc++-static
之后,運行編譯命令,生成的test.sh.x文件由原先的9K變為671K;
雖然靜態編譯成功,但放到其他機器上運行,運行結果仍然不正常,本機輸出正常,其他機器上輸出結果亂碼(這種情況有概率發生,不是每次都這樣)

解決方法:利用 CFLAGS=-static shc -T -vrf test.sh 生成的test.sh.c源碼文件,再手動通過gcc編譯:
gcc -static -o static_test test.sh.x.c
生成的static_test 文件,則可以放到其他系統上執行;

正常情況執行如下:
CFLAGS=-static shc -T -vrf test.sh
就會生成可執行文件,在Centos6.2下編譯后,在ubuntu11.10上執行沒有問題,在SUSE上不行(提示 FATAL: kernel too old Segmentation fault ),模式版本太低;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM