難読化シェル芸

Obfuscation Shell Script One Liner

難読化シェル芸とは

内部的な動作の手続き内容・構造・データなどを人間が理解しにくい、あるいはそのようになるよう加工されたシェル芸のこと。

例えばこんなの

普通のdateコマンド

date
20161216日 金曜日 21:19:58 JST

難読化dateコマンド

$'\x64\x61\x74\x65'
201734日 土曜日 13:36:21 JST
$(printf "%b" $(printf '%s%x' '\x' $((0x83 ^ 0xe7))))$(ls --help|grep ^G|cut -c53)$(ls --help|grep ^G|cut -c10)$(ls --help|grep ^G|cut -c8)
20161216日 金曜日 21:19:52 JST

難読化の基本

アスキーコードを記述して実行

俺的備忘録 〜なんかいろいろ〜 bashでコマンドをアスキーコードで記述して実行させる

$ echo -n 'date'|xxd
0000000: 6461 7465                                date
$ $'\x64\x61\x74\x65'         # date 16進数表記
201734日 土曜日 13:36:21 JST
$ $'\144\141\164\145'         # date 8進数
201734日 土曜日 13:47:22 JST
$ $'\u0064\u0061\u0074\u0065' # date Unicodeの表記
201734日 土曜日 13:40:16 JST

コマンド置換で文字を生成して実行

`example` または $(example) で文字を出力する。

exampleの部分を複雑にすることで、難読化を図る

`echo d``echo a`$(echo t)$(echo e)
201734日 土曜日 13:44:33 JST

evalを使って実行

コマンド置換と同様。まとめ中

manに載っていないsedのeオプションを使って実行

sedのeオプションは、引数のコマンドを実行してくれるのでこれを利用する。
eオプションは通常、manに載っていない。sedを熟知していないとやはり何しているか解りにくい。

gnu.org の説明
https://www.gnu.org/software/sed/manual/sed.html#sed-commands-list

echo|sed 'e date'
20171029日 日曜日 10:50:50 JST

難読化技法

フェイク(無駄な命令)

例えば、以下は全て無視される。コードの間に入れる事でより複雑な難読化を図ることができる。

$(:;:;:;:;:;:;)
$(: poweroff :;)
$(: rm -rf /* ;)

以下の条件で後続のコマンドが実行されるため、さらに難読化に利用できる

: date # dateは実行されない

$(:) date # dateは実行される
2017102日 月曜日 20:06:55 JST

`:` date # dateは実行される
2017102日 月曜日 20:07:03 JST

base64によるエンコード

base64にエンコードすることで、どのような命令かわからないようにする。

dateの難読化

$(echo ZGF0ZQ==|base64 -d)

ちなみに例のアレ(:(){ :|:& };:)は、こんな感じ(実行厳禁!!)

$(echo OigpeyA6fDomIH07Og==|base64 -d)

日本語base64難読化シェル芸

たいちょー氏の難読化シェル芸LTスライド
https://www.slideshare.net/xztaityozx/ss-76402430

"うんこ"からコマンドを錬成するのが最近のトレンド

うんこでEmacsを起動するのできた
https://twitter.com/sh_takuma/status/869007508643258368

うんこでVimを起動するのできた
https://twitter.com/grethlen/status/869162016362987520

https://www.slideshare.net/xztaityozx/base64-77639861

破壊的難読化シェル芸

https://www.slideshare.net/xztaityozx/ss-79171721

ダブルシンク難読化シェル芸

https://www.slideshare.net/xztaityozx/ss-80555814/

base64からのシーザー暗号

古典暗号(ROT13)を使って難読化

echo 44TT44XG44TGPt== |tr A-Za-z N-ZA-Mn-za-m|base64 -d
うんこ

ROT47で暗号化すると数字も暗号化の対象になって偽装できるのでなお良い

echo "ccvvccz%ccv%r8ll"|tr '!-~' 'P-~!-O'|base64 -d
うんこ

計算による文字の難読化

ASCIIコードを計算して出力することによって難読化する。

vの出力

echo $(printf "%b" $(printf '%s%x' '\x' $((0x15 ^ 0x63))))
v

ハッシュ値から必要な文字を得る

MD5等のハッシュ値を出力することで、0123456789abcdefABCDEFの文字を得ることができる。

Fの出力

$(echo -n |md5sum|cut -c10|tr a-z A-Z)
F

コマンドで同じ結果になる部分から文字を得る

例えばpwdコマンドの最初に1文字目は、必ず'/'になる。

echo $(pwd|cut -c1)
/

date '+%s' の最初の1文字目は、必ず1になる(と思って差し支えない。UNIX通算秒なので)。

echo $(date '+%s'|cut -c1)

lsのヘルプには、通常以下の文字列が含まれるため、これを利用できる。

ls --help|grep ^G
GNU coreutils online help: <http://www.gnu.org/software/coreutils/>

helpの出力

echo $(ls --help|grep ^G|cut -c22-25)
help

man asciiから文字列を得る

調査中

システムが普遍的に抱えている不変な情報から文字を得る

これが難読化に対しては最も有用では
実行してみるまで、どんな文字列になるか非常に解りにくい。
しかし、どのようなLinuxディストリビューションでも同じ値を抱えているものというのは、意外に見つからない。

私が発見したものは以下になる。おそらく、この文字列は、どのLinuxディストリビューションでも変わらない。

xxd /bin/ls|head -1
0000000: 7f45 4c46 0201 0100 0000 0000 0000 0000  .ELF............

ここから、.:01456cfELFの文字を得ることができる。

パイプレス

パイプを使用しないことで難読性を高める

A. 割りと死ななかった

パイプをキーで入力せずとも、アスキーコードから呼び出してevalで実行すればよいということか…

$ seq 100 |head -n 8 |tail -n 5 |sed 2,4d
4
8
$ sed 2,4d <(tail -n 5 <(head -n8 <(seq 10)))
4
8
$ eval $(echo -e seq 100 "\0174" head -n 8 "\0174" tail -n 5 "\0174" sed 2,4d)
4
8

awk芸によるコマンド機能の代替

awkで一般的によく使われるコマンド機能を代替して、読みにくくする。
ただawkに関しては、注意深く読めば読解できる点に注意が必要。

AWK 一行野郎百裂拳 - 日本 GNU AWK ユーザー会 - No-ip.org

sed芸によるコマンド機能の代替

sedで一般的によく使われるコマンド機能を代替して、読みにくくする。
もぅわからん。

tacの代替

第27回sedこわいシェル芸勉強会 Q8

sed '1!G;h;$!d'

touchの代替

sed 'w a' aa と実行すれば...

sed 'w filename' /dev/null

treeの代替

Qiita - tree コマンドが無い環境で tree コマンドを実現

find . | sort | sed '1d;s/^\.//;s/\/\([^/]*\)$/|--\1/;s/\/[^/|]*/|  /g'

Vimシェル芸によるコマンド機能の代替

深淵

その他、普通のコマンドの使い方をしない

echoの代替

Hello Worldコレクション

$ basename 'Hello World'
Hello World
$ date +'Hello World' 
Hello World

lsの代替

echo *
printf %s *

アンチデバック技法(耐タンパー性の確保)

思いついたんだけど、公開していいか、悩んでいる。

難読化シェル芸ツール

手動により難読化しても良いが、ツールを作ってみた。

インストール

NandokukaShellGei.sh

シェルスクリプトなのでダウンロード&実行権限付与でOK

wget https://raintrees.net/attachments/download/391/NandokukaShellGei.sh
chmod u+x NandokukaShellGei.sh

動作環境

一般的なLinuxディストリビューションで、だいたい動くと思う。
以下で動くことを確認した。

  • CentOS7
  • KaliLinux

ただコマンドの組み合わせによっては、なんか不具合がおきたりする。原因は調べてない。

Macで動くかは、ちょっと自信ない。

実行例

$ ./20161216_NandokukaShellGei.sh "echo HelloWorld"
e       ls --help|grep ^G|cut -c8
c       ls --help|grep ^G|cut -c5
h       ls --help|grep ^G|cut -c22
o       ls --help|grep ^G|cut -c6
        xxd /bin/ls|head -1|cut -c9
H       ls --help|grep ^G|cut -c22|tr a-z A-Z
e       ls --help|grep ^G|cut -c8
l       ls --help|grep ^G|cut -c12
l       ls --help|grep ^G|cut -c12
o       ls --help|grep ^G|cut -c6
W       ls --help|grep ^G|cut -c36|tr a-z A-Z
o       ls --help|grep ^G|cut -c6
r       ls --help|grep ^G|cut -c7
l       ls --help|grep ^G|cut -c12
d       echo -n|md5sum|cut -c1

$(ls --help|grep ^G|cut -c8)$(ls --help|grep ^G|cut -c5)$(ls --help|grep ^G|cut -c22)$(ls --help|grep ^G|cut -c6)$(xxd /bin/ls|head -1|cut -c9)$(ls --help|grep ^G|cut -c22|tr a-z A-Z)$(ls --help|grep ^G|cut -c8)$(ls --help|grep ^G|cut -c12)$(ls --help|grep ^G|cut -c12)$(ls --help|grep ^G|cut -c6)$(ls --help|grep ^G|cut -c36|tr a-z A-Z)$(ls --help|grep ^G|cut -c6)$(ls --help|grep ^G|cut -c7)$(ls --help|grep ^G|cut -c12)$(echo -n|md5sum|cut -c1)
$
$ #以下、出力されたコードをコピペ 
$ $(ls --help|grep ^G|cut -c8)$(ls --help|grep ^G|cut -c5)$(ls --help|grep ^G|cut -c22)$(ls --help|grep ^G|cut -c6)$(xxd /bin/ls|head -1|cut -c9)$(ls --help|grep ^G|cut -c22|tr a-z A-Z)$(ls --help|grep ^G|cut -c8)$(ls --help|grep ^G|cut -c12)$(ls --help|grep ^G|cut -c12)$(ls --help|grep ^G|cut -c6)$(ls --help|grep ^G|cut -c36|tr a-z A-Z)$(ls --help|grep ^G|cut -c6)$(ls --help|grep ^G|cut -c7)$(ls --help|grep ^G|cut -c12)$(echo -n|md5sum|cut -c1)
HelloWorld

HTJSA{DGFDIHJKH}ASQQMXBKUXXSdfgeOGCYTSAADSGUFTu}IUYTPDGHSGJUOUO}ASDGFSGJKHLQZSN}

Memo

PowerShellは別ページにした方がいいかもなー。情報量が多い。

セキュリティコンサルタントの日誌から - PowerShellの難読化について
http://www.scientia-security.org/entry/2017/11/13/224035

NandokukaShellGei.sh Magnifier - 難読化シェル芸ツール ver 0.2 (3.484 KB) kanata, 2016/12/16 23:37

クリップボードから画像を追加 (サイズの上限: 100 MB)