本题通过特定的脚本将flag写进了一张图片,我们的目标则是比对两张图片得到flag,
先来看看隐写的代码
虽然用了随机数,但是用了种子
将图片的R,G,B分别提取的到三张图片上,然后通过对每一个像素的RGB异或上r1,r2,r3,其中r1,r2可控,r3由flag构成,所以未知,本体的最终目的就是解出r3,
由于异或可逆,我们很容易能得到乱序后的r3,所以如何回到乱序前才是本题的重点
这里尝试一个例子
在seed确定的情况下,random.shuffle()的打乱顺序遵循一定规律,在代码中作为第几个random被调用直接决定了它会被怎么打乱,在本题中random.shuffle()就是第3个random,所以我们可以定义一个顺序的列表也在第三个random时被打乱
最后通过这个列表来对乱序的r3列表排序
得到正确的r3,r3是由flag和后面的巴拉巴拉拼接而成的,直接读前几位即可得到flag
题目给了一个.pyc文件,量有点大,有点吃内存,建议在跑之前清一下内存,不然可能会报MemoryError
跑出来后python代码变量名会非常的长,难以看清它到底想干啥,所以这里可以考虑修一下代码,替换一下变量,修好后的代码部分大概就长这样
直接看一眼运行结果:
老谜语人了,也不懂啥意思,那就再看看他在序列化之前是啥吧
输出很长,这里不做粘贴,但是可以很明显的看出这是在套娃,有很多的\n(总不能自己一个个去回车吧,呜呜呜),直接输出到新文件
得到相似的代码,把乱码部分清一下,继续输出到新文件就能看到flag辣
当然这道题还有一个比较高级的解法,可以用gdb直接调试出来
但俺就是个不懂二进制的带菜鸡,所以这里不做细述,感兴趣的大佬们可以自行尝试
random.seed(
793211
)
cat
=
Image.
open
(
'1.png'
)
cat1
=
Image.new(
'L'
, cat.size)
cat2
=
Image.new(
'L'
, cat.size)
cat3
=
Image.new(
'L'
, cat.size)
x, y
=
cat.size
bits
=
x
*
y
r1, r2
=
pbl(bits), pbl(bits)
r3
=
FLAG
+
n2b(random.getrandbits((bits
-
len
(FLAG))
*
8
))
r3
=
list
(r3)
random.shuffle(r3)
for
i
in
range
(x):
for
j
in
range
(y):
pix
=
cat.getpixel((i, j))
cat1.putpixel((i, j), pix[
0
] ^ r1[i
*
y
+
j])
cat2.putpixel((i, j), pix[
1
] ^ r2[i
*
y
+
j])
cat3.putpixel((i, j), pix[
2
] ^ r3[i
*
y
+
j])
img
=
Image.new(
'RGB'
, cat.size)
img.putdata([(p1,
0
, p3)
for
p1, p3
in
zip
(cat1.getdata(), cat3.getdata())])
img.save(
'xx.png'
)
cat
=
Image.
open
(
'1.png'
)
cat1
=
Image.new(
'L'
, cat.size)
cat2
=
Image.new(
'L'
, cat.size)
cat3
=
Image.new(
'L'
, cat.size)
x, y
=
cat.size
bits
=
x
*
y
r1, r2
=
pbl(bits), pbl(bits)
r3
=
FLAG
+
n2b(random.getrandbits((bits
-
len
(FLAG))
*
8
))
r3
=
list
(r3)
random.shuffle(r3)
for
i
in
range
(x):
for
j
in
range
(y):
pix
=
cat.getpixel((i, j))
cat1.putpixel((i, j), pix[
0
] ^ r1[i
*
y
+
j])
cat2.putpixel((i, j), pix[
1
] ^ r2[i
*
y
+
j])
cat3.putpixel((i, j), pix[
2
] ^ r3[i
*
y
+
j])
img
=
Image.new(
'RGB'
, cat.size)
img.putdata([(p1,
0
, p3)
for
p1, p3
in
zip
(cat1.getdata(), cat3.getdata())])
img.save(
'xx.png'
)
import
random
random.seed(
1
)
a
=
[i
for
i
in
range
(
10
)]
random.shuffle(a)
print
(a)
random.shuffle(a)
print
(a)
import
random
random.seed(
1
)
a
=
[i
for
i
in
range
(
10
)]
random.shuffle(a)
print
(a)
random.shuffle(a)
print
(a)
gg
=
[i
for
i
in
range
(
27918
)]
random.shuffle(gg)
gg
=
[i
for
i
in
range
(
27918
)]
random.shuffle(gg)
result
=
[i
for
_, i
in
sorted
(
zip
(gg,r3))]
result
=
[i
for
_, i
in
sorted
(
zip
(gg,r3))]
import
random
from
PIL
import
Image
from
Crypto.Util.number
import
long_to_bytes as n2b
random.seed(
793211
)
def
pbl(bits):
num
=
random.getrandbits(bits)
bins
=
[]
while
num:
bins.append(num &
1
)
num >>
=
1
while
len
(bins) !
=
bits:
bins.append(
0
)
return
bins
cat
=
Image.
open
(
'1.png'
)
cat1
=
Image.new(
'L'
, cat.size)
cat2
=
Image.new(
'L'
, cat.size)
cat3
=
Image.new(
'L'
, cat.size)
xcat
=
Image.
open
(
'xx.png'
)
xcat1
=
Image.new(
'L'
, cat.size)
xcat2
=
Image.new(
'L'
, cat.size)
xcat3
=
Image.new(
'L'
, cat.size)
x, y
=
cat.size
bits
=
x
*
y
r1, r2
=
pbl(bits), pbl(bits)
r3
=
[
0
]
*
((x
-
1
)
*
y
+
y )
for
i
in
range
(x):
for
j
in
range
(y):
pix
=
cat.getpixel((i, j))
xpix
=
xcat.getpixel((i,j))
r3[i
*
y
+
j]
=
pix[
2
] ^ xpix[
2
]
a
=
n2b(random.getrandbits((bits
-
28
)
*
8
))
gg
=
[i
for
i
in
range
(
27918
)]
random.shuffle(gg)
result
=
[i
for
_, i
in
sorted
(
zip
(gg,r3))]
fin
=
""
i
=
0
while
result[i] !
=
125
:
fin
=
fin
+
chr
(result[i])
i
=
i
+
1
print
(fin
+
'}'
)
import
random
from
PIL
import
Image
from
Crypto.Util.number
import
long_to_bytes as n2b
random.seed(
793211
)
def
pbl(bits):
num
=
random.getrandbits(bits)
bins
=
[]
while
num:
bins.append(num &
1
)
num >>
=
1
while
len
(bins) !
=
bits:
bins.append(
0
)
return
bins
cat
=
Image.
open
(
'1.png'
)
cat1
=
Image.new(
'L'
, cat.size)
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!