プロジェクト

全般

プロフィール

ZeroWidthSpace » 履歴 » バージョン 1

kanata, 2025/04/13 14:02

1 1 kanata
# ZeroWidthSpace
2
3
{{rawhtml(<canvas id="map"></canvas><script src="/javascripts/pagemap.min.js"></script><script>pagemap(document.querySelector("#map"));</script>)}}
4
5
{{toc}}
6
7
{{rawhtml(<iframe src="//www.slideshare.net/slideshow/embed_code/key/xsLdg6etgkh9K6" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/kanata1/unicode-104771309" title="Unicodeゼロ幅文字 難読化シェル芸" target="_blank">Unicodeゼロ幅文字 難読化シェル芸</a> </strong> from <strong><a href="https://www.slideshare.net/kanata1" target="_blank">kanata -</a></strong> </div>)}}
8
9
10
# 動機 : 先日こういう話題があった
11
12
{{rawhtml(<blockquote class="embedly-card"><h4><a href="http://developer.cybozu.co.jp/akky/2018/04/leaker-detection-by-zero-width-characters/">ゼロ幅文字にエンコードした隠し情報で、文書をリークしたメンバーを特定</a></h4><p>とある会員制掲示板からの文書の流出に困った運営者が、 ユニコードの見えない文字「ゼロ幅文字(Zero-Width characters)」を使って流出させたユーザーを特定した、という話 が出ていました。 ...</p></blockquote><script async src="//cdn.embedly.com/widgets/platform.js" charset="UTF-8"></script>)}}
13
14
* 要約
15
 * 競技ビデオゲームのチームが、プライベートの掲示板を利用
16
 * 外部の掲示板にコピペしているやつがいた
17
 * 見た目がわからない文字を仕込んで犯人を特定
18
19
# 原理 : Unicodeゼロ幅スペースを仕込んだ
20
21
## ゼロ幅スペース([Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%BC%E3%83%AD%E5%B9%85%E3%82%B9%E3%83%9A%E3%83%BC%E3%82%B9))
22
23
コンピュータの組版に用いられる非表示文字で、文書処理システムに対して語の切れ目を示すのに用いる
24
25
[めっちゃ種類ある](http://anti.rosx.net/etc/memo/002_space.html)
26
27
U+034F , U+200B , U+200C , U+200D , U+200E , U+200F , U+2028 , U+2029 , U+202A , U+202B , U+202C , U+202D , U+202E , U+2061 , U+2062 , U+2063 , U+FEFF
28
29
# いろんな事に(難読化シェル芸)に使えるんじゃ・・・!
30
31
[元ネタ](https://github.com/umpox/zero-width-detection/blob/071dfd52aede7510952b05840ffec7f8a940e6cb/src/utils/usernameToZeroWidth.js)に習って4種類を使う ⇒ 4進数で表現できる!
32
33
| CodePoint | 名称       | デコード時 |
34
|-----------|-----------|------------|
35
| U+200B    | ゼロ幅空白                     | 0
36
| U+200C    | ゼロ幅非接合子(筆記体の時の制御) | 1
37
| U+200D    | ゼロ幅接合子(筆記体の時の制御)   | 2
38
| U+FEFF    | ゼロ幅のノーブレークスペース     | 3
39
40
## ゼロ幅スペースにエンコード
41
42
1. 文字を16進数に変換(xxd)
43
2. 16進数を4進数に変換(bc)
44
3. 0 1 2 3 をゼロ幅スペースに置換(sed)
45
46
```bash
47
ZWS1=$'\u200b'
48
ZWS2=$'\u200c'
49
ZWS3=$'\u200d'
50
ZWS4=$'\ufeff'
51
52
echo "unko" |xxd -p|tr a-z A-Z \
53
  |sed 's/^/obase=4; ibase=16; &/g'|bc \
54
  |sed s/0/$ZWS1/g |sed s/1/$ZWS2/g \
55
  |sed s/2/$ZWS3/g |sed s/3/$ZWS4/g 
56
```
57
58
## 仕込んだゼロ幅スペースのデコード
59
60
1. ゼロ幅スペースを 0 1 2 3 に置換(sed)
61
2. 16進数に変換(bc)
62
3. バイナリに変換(xxd)
63
64
```bash
65
ZWS1=$'\u200b'
66
ZWS2=$'\u200c'
67
ZWS3=$'\u200d'
68
ZWS4=$'\ufeff'
69
70
echo '‌‌‌‌‍‍‌‍‍‌‍​​‍‍' \
71
  |sed s/$ZWS1/0/g |sed s/$ZWS2/1/g \
72
  |sed s/$ZWS3/2/g |sed s/$ZWS4/3/g \
73
  |sed 's/^/obase=16; ibase=4; &/g'|bc|xxd -ps -r
74
```
75
76
※ echo '' の''にはゼロ幅スペース入ってる
77
78
# Twitter用 Unicodeゼロ幅スペースぶっ込みツール に作り直した
79
80
TwitterやSNSで使える種類が限られていることがわかった。
81
82
{{rawhtml(<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">こんどTwitter対応やってみます <a href="https://twitter.com/hashtag/%E3%82%B7%E3%82%A7%E3%83%AB%E8%8A%B8?src=hash&amp;ref_src=twsrc%5Etfw">#シェル芸</a> <a href="https://twitter.com/hashtag/%E3%81%99%E3%81%BF%E3%81%BE%E3%81%9B%E3%82%93%E5%8B%95%E3%81%8F%E3%81%A3%E3%81%A6%E8%A8%80%E3%81%A3%E3%81%A6%E5%8B%95%E3%81%8D%E3%81%BE%E3%81%9B%E3%82%93%E3%81%A7%E3%81%97%E3%81%9F%E8%A8%B1%E3%81%97%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84%E3%81%AA%E3%82%93%E3%81%A7%E3%82%82%E3%81%97%E3%81%BE%E3%81%99%E3%81%8B%E3%82%89?src=hash&amp;ref_src=twsrc%5Etfw">#すみません動くって言って動きませんでした許してくださいなんでもしますから</a> <a href="https://t.co/gUjAI3x9wt">https://t.co/gUjAI3x9wt</a></p>&mdash; kanata (@kanata201612) <a href="https://twitter.com/kanata201612/status/1016273710846697472?ref_src=twsrc%5Etfw">2018年7月9日</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>)}}
83
84
調査してTwitter用に良さそうな4種類のゼロ幅スペースを確認する
85
86
{{rawhtml(<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">結果、Twitterに仕込んでも大丈夫そうなゼロ幅スペース <a href="https://twitter.com/hashtag/%E3%82%B7%E3%82%A7%E3%83%AB%E8%8A%B8?src=hash&amp;ref_src=twsrc%5Etfw">#シェル芸</a><br><br>U+200B<br>U+200C<br>U+200D<br>U+2062<br><br>もうちょっと確認してみよう</p>&mdash; kanata (@kanata201612) <a href="https://twitter.com/kanata201612/status/1018409987654053889?ref_src=twsrc%5Etfw">2018年7月15日</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> )}}
87
88
[シェル芸bot](https://twitter.com/minyoruminyon)氏のことも考慮して、割と真面目に作り直した
89
90
## Instration
91
92
ファイルダウンロードして実行権限をつけるだけ
93
94
```bash
95
$ wget https://raintrees.net/attachments/download/486/zws
96
$ chmod u+x ./zws
97
```
98
99
### 最新版について
100
101
現在、githubにて最新版を管理しています。インタフェースをbase64と全く同じに修正(してもらい)ました。
102
https://github.com/kanata2003/ZeroWidthSpace
103
104
### 動作環境
105
106
ただのシェルスクリプトなので、だいたいの環境(Linux,Mac,Unix)で動くのでは
107
108
以下で、動作確認しました。
109
110
* CentOS Linux release 7.2.1511 x86_64
111
112
## Usage
113
114
### エンコード
115
116
実行すると '' が出力されるが間にゼロ幅スペースが詰まっている
117
118
```bash
119
./zws unko
120
'‌⁢‌‌​​‍‍‌‍⁢‍​​‍‍‌‍‍⁢​​‍‍‌‍⁢⁢​​‍‍'
121
```
122
123
パイプ経由でもできる
124
125
```bash
126
echo "unko"|./zws
127
'‌⁢‌‌​​‍‍‌‍⁢‍​​‍‍‌‍‍⁢​​‍‍‌‍⁢⁢​​‍‍'
128
```
129
130
ちなみにTwitterでは、ゼロ幅スペースはアスキー文字と同等に数えられるらしく、140文字ではなく280文字までいけた
131
エンコードサイズが280文字を超えるとWARNINGを出すようにしている(エンコード自体はする)
132
133
```bash
134
./zws aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
135
[WARN] This encoded size over 280 characters. You can not tweet. Now 285 characters.
136
'‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌‌‍​‌​​‍‍'
137
```
138
139
[シェル芸bot](https://twitter.com/minyoruminyon)氏はゼロ幅スペースを普通にマルチバイト文字として数える(140文字制限)ので、bot氏に処理をお願いする時は140文字までの制限を意識する必要がございます
140
141
ゼロ幅スペースの文字数を数えるには wc -m コマンドで数えることができます
142
143
```bash
144
./zws 'I hava an apple'|wc -m
145
67
146
```
147
148
この短めの文で67文字も使うのでTwitterにはあまり長い文字列が仕込めません
149
150
### デコード
151
152
base64コマンドっぽいインタフェースにした
153
ゼロ幅スペース以外の文字があっても、そこは無視してデコードする
154
155
```bash
156
./zws -d 'this is a pen‌⁢‌‌​​‍‍‌‍⁢‍​​‍‍‌‍‍⁢​​‍‍‌‍⁢⁢​​‍‍'
157
unko
158
```
159
160
もちろんパイプ経由でもいける
161
162
```bash
163
echo '‌⁢‌‌​​‍‍‌‍⁢‍​​‍‍‌‍‍⁢​​‍‍‌‍⁢⁢​​‍‍'|./zws -d
164
unko
165
```
166
167
# 使えるシュチュエーション
168
## このシェル芸を実行したのは誰だ!
169
170
```bash
171
./zws -d 'echo unko⁢‍‌⁢‍‍‌⁢‍​​‌⁢‍​⁢‍​​‌‍‍‌⁢⁢‍​⁢‍​​‌‍‌‍‌​​‍‍'
172
私です
173
```
174
## 裏手順を隠しておく
175
176
```bash
177
./zws -d 'stop.sh #アプリを停止、yを入力‌⁢​​‌‍‍⁢‌‍‍‌‌‍⁢​‌‍⁢​​‍​​‌‍​‌‌⁢​​‌‍⁢​‌‍‍‌​​‍‍'
178
pkill apli
179
```
180
181
## 呪いを込めておく
182
183
```bash
184
./zws -d 'Start.sh #アプリ起動⁢‍‌‌‍⁢‍​‍⁢​​⁢‍​⁢‍​​‍‍​‍‍⁢‍​⁢‍​​‌‍‌⁢⁢⁢‍​⁢‍​​‌‍​‌​​​‍‍'
185
帰りたい
186
```
187
188
## 暗号的やり取り
189
190
実はTwitterはゼロ幅スペースが使えます
191
192
他のSNSでも使えそう(未確認)
193
194
```bash
195
./zws -d '草⁢‍‌⁢‍​‍‌‍⁢‍‌⁢‍‌‌‍‍​⁢‍⁢​‍⁢‍​⁢‍​​‌‍‍​​⁢‍​⁢‍​​‌‍‌⁢‍​​‍‍'
196
特売だぞ
197
```
198
199
## 難読化シェル芸
200
201
echoと見せかけたdateの実行
202
203
```bash
204
echo 'echo unko‌‍‌​‌‍​‌‌⁢‌​‌‍‌‌​​‍‍'|./zws -d|bash
205
2018年  7月 16日 月曜日 10:26:37 JST
206
```
207
208
# 他の実装
209
210
* ExcelのVBAで[風柳](https://twitter.com/furyutei)さんが実装しています
211
212
[Excel][VBA] ゼロ幅スペースを利用した情報隠蔽の試み
213
https://gist.github.com/furyutei/6bba0eaf5e0bcb4ae1ee30f916cfcb04
214
215
* 短縮URLのサービスで実装されています
216
217
Zero Width Shortener
218
https://zws.im/