難読化シェル芸¶
Obfuscation Shell Script One Liner
- 難読化シェル芸
- 難読化シェル芸とは
- 難読化の基本
- 難読化技法
- 記号難読化
- Unicode結合文字難読化
- Unicodeゼロ幅スペース難読化
- アンチデバック技法(耐タンパー性の確保)
- 難読化シェル芸ツール
- もっとすげぇ難読化シェル芸ツール
- 難読化解除ツール
- Memo
難読化シェル芸とは¶
内部的な動作の手続き内容・構造・データなどを人間が理解しにくい、あるいはそのようになるよう加工されたシェル芸のこと。
例えばこんなの
普通のdateコマンド
date
2016年 12月 16日 金曜日 21:19:58 JST
難読化dateコマンド
$'\x64\x61\x74\x65'
2017年 3月 4日 土曜日 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)
2016年 12月 16日 金曜日 21:19:52 JST
難読化の基本¶
アスキーコードを記述して実行¶
俺的備忘録 〜なんかいろいろ〜 bashでコマンドをアスキーコードで記述して実行させる
$ echo -n 'date'|xxd
0000000: 6461 7465 date
$ $'\x64\x61\x74\x65' # date 16進数表記
2017年 3月 4日 土曜日 13:36:21 JST
$ $'\144\141\164\145' # date 8進数
2017年 3月 4日 土曜日 13:47:22 JST
$ $'\u0064\u0061\u0074\u0065' # date Unicodeの表記
2017年 3月 4日 土曜日 13:40:16 JST
コマンド置換で文字を生成して実行¶
`example` または $(example) で文字を出力する。
exampleの部分を複雑にすることで、難読化を図る
`echo d``echo a`$(echo t)$(echo e)
2017年 3月 4日 土曜日 13:44:33 JST
コマンドの間に無視される文字を挟み込む¶
''''''''''''''''''''''''''''''''''''''''''''''''''d''''''''''''''''''''''''''''''''''''''''''''''''''a''''''''''''''''''''''''''''''''''''''''''''''''''t''''''''''''''''''''''''''''''''''''''''''''''''''e''''''''''''''''''''''''''''''''''''''''''''''''''
Sat Sep 21 20:00:59 JST 2019
d""a$()t``e
Sun Apr 19 10:43:58 JST 2020
無駄なブレース展開¶
$ echo {{{{{{{{{a..c},},},},},},},},}
a b c
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'
2017年 10月 29日 日曜日 10:50:50 JST
難読化技法¶
フェイク(無駄な命令)¶
例えば、以下は全て無視される。コードの間に入れる事でより複雑な難読化を図ることができる。
$(:;:;:;:;:;:;)
$(: poweroff :;)
$(: rm -rf /* ;)
以下の条件で後続のコマンドが実行されるため、さらに難読化に利用できる
: date # dateは実行されない
$(:) date # dateは実行される
2017年 10月 2日 月曜日 20:06:55 JST
`:` date # dateは実行される
2017年 10月 2日 月曜日 20:07:03 JST
フェイク(前半処理の無視)¶
処理結果をパイプで渡しても、それを使わなければ実質、無視できる処理となる。
以下は、前半処理を無視して、dateを実行する例
$ echo hoge |grep hoge|date
2018年 11月 4日 日曜日 17:20:12 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
うんこ
スペースを使わない¶
IFS変数がスペースの代わりとして使える。
$ date$IFS'+%s' 1546743417
計算による文字の難読化¶
ASCIIコードを計算して出力することによって難読化する
vの出力
echo $(printf "%b" $(printf '%s%x' '\x' $((0x15 ^ 0x63))))
v
Aの出力
printf '%X\n' $((0x5 * 2))
A
ハッシュ値から必要な文字を得る¶
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)
1
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の文字を得ることができる。
サンプリングシェル芸¶
上記(システムが普遍的に抱えている不変な情報から文字を得る)の発展した形をシェル芸の上田先生がまとめてくださいました嬉しい
サンプリングシェル芸
https://b.ueda.tech/?page=sampling_shellgei
難読化シェル芸の手法の一つに、思わぬところから文字を拾って(サンプリングして)コマンドの文字列にするというものがあります。音楽のサンプリングみたいなものです。文字を拾う方法にもいろいろあるので、まとめてみました。
パイプレス¶
パイプを使用しないことで難読性を高める
パイプをキーで入力せずとも、アスキーコードから呼び出して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
SJIS文字コードのダメ文字を利用したパイプ難読化¶
文字コードのSJISには、その文字を構成するバイト(2Byte目)に制御文字を含んているものがある
これらはダメ文字と呼ばれ、Linuxで扱う時は注意が必要でした。大きくは、以下の2種類があります
- 2byte目が0x5c \ のダメ文字
- ― ソ Ы Ⅸ 噂 浬 欺 圭 構 蚕 十 申 曾 箪 貼 能 表 暴 予 禄 兔 喀 媾 彌 拿 杤 歃 濬 畚 秉 綵 臀 藹 觸 軆 鐔 饅 鷭 纊 犾 偆 砡
- 2byte目が0x7c | のダメ文字
- - ポ л 榎 掛 弓 芸 鋼 旨 楯 酢 掃 竹 倒 培 怖 翻 慾 處 嘶 斈 忿 掟 桍 毫 烟 痞 窩 縹 艚 蛞 諫 轎 閖 驂 黥 僴 礰 埈 蒴
SJISのポは"|"が含まれているポ系ダメ文字であり、難読化に応用できる
$ eval $(__=$(nkf -sLux <(echo ポ));echo echo ZGF0ZQo=${__:1}base64 -d${__:1}bash)
awk芸によるコマンド機能の代替¶
awkで一般的によく使われるコマンド機能を代替して、読みにくくする。
ただawkに関しては、注意深く読めば読解できる点に注意が必要。
AWK 一行野郎百裂拳 - 日本 GNU AWK ユーザー会 - No-ip.org
sed芸によるコマンド機能の代替¶
sedで一般的によく使われるコマンド機能を代替して、読みにくくする。
もぅわからん。
tacの代替¶
$ echo abcd|grep -o .|sed '1!G;h;$!d'
d
c
b
a
touchの代替¶
$ sed 'w filename' /dev/null
treeの代替¶
Qiita - tree コマンドが無い環境で tree コマンドを実現
$ find . | sort | sed '1d;s/^\.//;s/\/\([^/]*\)$/|--\1/;s/\/[^/|]*/| /g'
|--a
| |--b
| | |--c
| | | |--d
Vimシェル芸によるコマンド機能の代替¶
深淵
その他、普通のコマンドの使い方をしない¶
echoの代替¶
$ basename 'Hello World'
Hello World
$ date +'Hello World'
Hello World
$ expr 'Hello World'
Hello World
catの代替¶
$ echo "$(<hoge.txt)"
$ curl file:/%65%74%63/%70%61%73%73%77%64 # cat /etc/passwd と同じ
curlは、更にURLエンコードにより難読化できる
lsの代替¶
echo *
printf %s *
tacの代替¶
seq 10 | dc -f- -ef
dcコマンドを読める人は少ない
記号難読化¶
以下、参照
ここから隊長さんが究極の難読化に昇華してくれた。いまやJavaScriptやPowerShellの最先端の難読化手法に追いついている。以下
超・記号オンリー難読化シェル芸¶
これにより難読化シェル芸の、難読化手法の一つが完成するに至った。歴史的瞬間。
数字・英字を全く使わない記号難読化¶
不可能と思われていた完全記号化がなんと完成…!!
記号と英字2文字だけでbash - Ryoto Saito's Blog
https://www.ryotosaito.com/blog/?p=178
記号だけでシェルは操れた - Ryoto Saito's Blog
https://www.ryotosaito.com/blog/?p=194
全く別のアプローチによる完全記号難読化¶
新たなる刺客
34C3 CTF: minbashmaxfun - writeup
https://hack.more.systems/writeup/2017/12/30/34c3ctf-minbashmaxfun/
その驚くべき手法
$ ${!#}<<<${!#}\<\<\<\$\'\\${##}$#${##}\'
これは、以下と等価
$ bash <<< bash \<\<\< \$\'\\${##}$#${##}\'
そして、以下とも等価
$ bash <<< $'\101'
これは最終的にAを実行することと等価
$ A -bash: A: コマンドが見つかりません
この考えに基づけば、全ての数字・アルファベットを生成することができる
ポイントは ${!#} と ${##} の特殊変数
以下の内容となっている
$ echo ${!#} # 34C3 CTFの環境では"bash"が返ってきたようです。若干の環境依存があります。 -bash $ echo ${##} 1
これは、以下のように解釈できます。
- ${#変数名}は、格納されている文字列の長さを返す。
- ${#} は引数の数(ワンライナーだと0になります)
- よって、${##}は、"0"という文字の長さ1を返す。
- ${!} は最後にバックグラウンドで行ったコマンドのプロセス番号(バックグラウンドで実行していなければ空)
- よって ${!#} は ${0} と等価となる。
驚くべき手法です。これまでに考えてきた手法と組み合わせることもできます。
この点はまだまだ研究の余地がありそうです!
難読化シェル芸に使えそうなテクニック集¶
神 of 神
hiro氏作の難読化シェル芸の解読
https://hackmd.io/@EjC746Q1REWEpEC57LOAXA/rJ4niQJfr
たいちょーの雑記 - 難読化dateコレクション-3-$[]利用
https://xztaityozx.hatenablog.com/entry/2020/01/16/224643
難読化シェル芸の解読
https://qiita.com/eggplants/items/3994a502ce2659b4a17f
Unicode結合文字難読化¶
echo "d͜͜͏̘̣͔͙͎͎̘̜̫̗͍͚͓͜͜͏̘̣͔͙͎͎a͜͜͏̘̣͔͙͎͎t̜ͪ̅̍̅͂͊e " |tr -cd 'a-z'|bash
2018年 3月 18日 日曜日 17:06:41 JST
Unicodeゼロ幅スペース難読化¶
アンチデバック技法(耐タンパー性の確保)¶
思いついたんだけど、公開していいか、悩んでいる。
難読化シェル芸ツール¶
手動により難読化しても良いが、ツールを作ってみた。
インストール¶
シェルスクリプトなのでダウンロード&実行権限付与で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
もっとすげぇ難読化シェル芸ツール¶
隊長さん作成のツール
xztaityozx/nandokuka 難読化シェル芸は砕けない
https://github.com/xztaityozx/nandokuka
0x6d61さん作成のツール
0x6d61/obfsh.rb 難読化shell芸を手助けするscript
https://gist.github.com/0x6d61/7ebfe4393ba3a3564313b48684e7b7fb
node-bash-obfuscate
https://www.npmjs.com/package/bash-obfuscate
難読化解除ツール¶
Flerken
https://github.com/We5ter/Flerken/blob/master/README.md
Windows (CMD and Powershell) and Linux (Bash) commandsが対象。WebUIもある。
Memo¶
PowerShellとJavaScriptは別ページにした方がいいかもなー。情報量が多い。
PORTSWIGGER - Unearthing Z͌̈́̾a͊̈́l͊̿g̏̉͆o̾̚̚S̝̬ͅc̬r̯̼͇ͅi̼͖̜̭͔p̲̘̘̹͖t̠͖̟̹͓͇ͅ with visual fuzzing
https://portswigger.net/blog/unearthing-zalgoscript-with-visual-fuzzing
IPアドレスの難読化 - おふとん
https://ohuton.hatenadiary.jp/entry/2018/09/24/232419
自己追記によるFizzBuzz
https://zenn.dev/yamaya/articles/da9131540dc12a
JavaScriptの難読化¶
Qiita - JS記号プログラミング入門
https://qiita.com/acid_chicken/items/eeb0b42a1ecbba0c49e3
Qiita - ウェブアプリをソースごとパクる業者に対する対策
https://qiita.com/kacchan6@github/items/d8576ab6b3c16cf670ca
Qiita - 本格JavaScript記号プログラミング(1) 6種類の記号だけでJavaScriptを書こう
https://qiita.com/Tatamo/items/24099958b90cbed61d67
JavaScriptの難読化技術を探る
https://monpoke1.hatenablog.com/entry/2018/12/06/020115#参考
プログラミングLT 記号プログラミングのスライド
https://docs.google.com/presentation/d/1Bqu_si3o0Lol8k9MvVx443R9zaJF7Qtq-_jutw2wYrc/edit?usp=sharing
PowerShellの難読化¶
セキュリティコンサルタントの日誌から - PowerShellの難読化について
http://www.scientia-security.org/entry/2017/11/13/224035
PowerShell難読化の基礎 (1)
http://binary-pulsar.azurewebsites.net/2018/09/01/ps-obfuscate-pt1/
PowerShell難読化の基礎 (2)
http://binary-pulsar.azurewebsites.net/2018/09/08/ps-obfuscate-pt2/
PowerShell難読化の基礎 (3)
http://binary-pulsar.azurewebsites.net/2018/09/14/ps-obfuscate-pt3/
PowerShellの難読化解除 - Binary Pulsar
http://binary-pulsar.azurewebsites.net/2018/09/19/ps-deobfuscate/
DbgShell - A PowerShell Front-End For The Windows Debugger Engine
https://www.kitploit.com/2018/10/dbgshell-powershell-front-end-for.html
PowerShellの難読化解除
https://binary-pulsar.hatenablog.jp/entry/2018/09/19/000000
難読化PowerShell芸入門
https://www.slideshare.net/xztaityozx/powershell-162881333
『PowerShellを使用したファイルレス・マルウェアが届いたので、コミケの原稿書きながら、難読化スクリプトの読解手順を動画にしてみました。』
一進一退!じあんちゃん じあんちゃん対PowerShellの巻 (ギャル語でマルウェア解説してみた)
https://www.youtube.com/watch?v=Z6j_bz1Lo8U
『PowerShellを使用したファイルレス・マルウェアが届いたので、コミケの原稿書きながら、難読化スクリプトの読解手順を動画にしてみました。』
Powershellスクリプトの難読化解除ツール
https://github.com/R3MRUM/PSDecode
その他の言語¶
Ruby とすてきな難読化
http://d.hatena.ne.jp/ku-ma-me/touch/20091215/p1
sh で brainfuck
http://ya.maya.st/d/201208a.html#s20120809_1
難読化の話(超!?入門編)その1
https://www.netagent.co.jp/study/blog/hard/20180726.html
難読化の話(超!?入門編)その2
https://www.netagent.co.jp/study/blog/hard/20181122.html
難読化の話(超!?入門編)その3 前編
https://www.netagent.co.jp/study/blog/hard/20190214.html
えあーの雑記録(仮) - 【C/C++】#defineで日本語も使えるので「#define 斉藤」してみた
https://airscarlet.com/programming_cpp_japanese_define/