首页
社区
课程
招聘
[原创]【HWS】两道好玩的misc
2022-8-2 16:10 8784

[原创]【HWS】两道好玩的misc

2022-8-2 16:10
8784

random

本题通过特定的脚本将flag写进了一张图片,我们的目标则是比对两张图片得到flag,

 

先来看看隐写的代码

1
random.seed(793211)

虽然用了随机数,但是用了种子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
cat = Image.open('1.png')
cat1 = Image.new('L', cat.size)   #根据1.png的尺寸  #三个图层
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))   #像素的RGB值
        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')

将图片的R,G,B分别提取的到三张图片上,然后通过对每一个像素的RGB异或上r1,r2,r3,其中r1,r2可控,r3由flag构成,所以未知,本体的最终目的就是解出r3,

 

由于异或可逆,我们很容易能得到乱序后的r3,所以如何回到乱序前才是本题的重点

 

这里尝试一个例子

1
2
3
4
5
6
7
8
9
import random
random.seed(1)
a=[i for i in range(10)]
random.shuffle(a)
print(a)
#[6, 8, 9, 7, 5, 3, 0, 4, 1, 2]
random.shuffle(a)
print(a)
#[5, 1, 9, 0, 3, 2, 6, 4, 8, 7]

在seed确定的情况下,random.shuffle()的打乱顺序遵循一定规律,在代码中作为第几个random被调用直接决定了它会被怎么打乱,在本题中random.shuffle()就是第3个random,所以我们可以定义一个顺序的列表也在第三个random时被打乱

1
2
gg = [i for i in range(27918)]
random.shuffle(gg)

最后通过这个列表来对乱序的r3列表排序

1
result = [i for _, i in sorted(zip(gg,r3))]

得到正确的r3,r3是由flag和后面的巴拉巴拉拼接而成的,直接读前几位即可得到flag

Final exp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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)   #根据1.png的尺寸  #三个图层
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 + '}')

whatisthis

题目给了一个.pyc文件,量有点大,有点吃内存,建议在跑之前清一下内存,不然可能会报MemoryError

1
uncompyle6 /whatisthis.cpython-38.pyc > /1.py

跑出来后python代码变量名会非常的长,难以看清它到底想干啥,所以这里可以考虑修一下代码,替换一下变量,修好后的代码部分大概就长这样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def rR(key):
    wW = list(range(256))
    Ud = 0
    for kk in range(256):
        Ud = (Ud + wW[kk] + ord(key[kk % len(key)])) % 256
        wW[kk], wW[Ud] = wW[Ud], wW[kk]
    return wW
def QL(p):
    Qa = rR('h0lyduck')
    kR = []
    kk = Ud = 0
    for Fb in p:
        kk = (kk + 1) % 256
        Ud = (Ud + Qa[kk]) % 256
        Qa[kk], Qa[Ud] = Qa[Ud], Qa[kk]
        VI = (Qa[kk] + Qa[Ud]) % 256
        ff = Qa[VI]
        kR.append(Fb ^ ff)
    return kR
exec(marshal.loads(bytearray(QL(ys))))

直接看一眼运行结果:

1
2
3
4
5
Traceback (most recent call last):
Welcome to NotDefined World
    There is a flag in here
  File 'Can you', line 1, in <find it?>
NameError: name 'Not Defined' is not defined

老谜语人了,也不懂啥意思,那就再看看他在序列化之前是啥吧

1
print(bytearray(QL(ys)))

输出很长,这里不做粘贴,但是可以很明显的看出这是在套娃,有很多的\n(总不能自己一个个去回车吧,呜呜呜),直接输出到新文件

1
2
3
4
5
f = open("next.py", "w")
bytearray((QL(ys)))
str = bytearray((QL(ys))).decode('utf-8', 'ignore')
f.write(str)
f.close()

得到相似的代码,把乱码部分清一下,继续输出到新文件就能看到flag辣

 

当然这道题还有一个比较高级的解法,可以用gdb直接调试出来

但俺就是个不懂二进制的带菜鸡,所以这里不做细述,感兴趣的大佬们可以自行尝试


[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

上传的附件:
收藏
点赞5
打赏
分享
最新回复 (1)
雪    币: 6329
活跃值: (10544)
能力值: ( LV12,RANK:400 )
在线值:
发帖
回帖
粉丝
Nameless_a 5 2022-8-2 16:59
2
0
火钳刘明
游客
登录 | 注册 方可回帖
返回