前言

这次是代表SU参加强网杯国际赛,属于是我第一次参加这种大型赛事,这种模式的体验机会确实少,长见识了!

给大家贴几张图片感受一下:




和常规的CTF大赛不同的是,分了互联网赛道、车联网赛道和人工智能赛道,CTF只能算是互联网赛道的”门槛资格赛“,可以看出整体更偏向对固件、设备、模型的攻击,所以难度也很高!(直接被打烂了,日不了一点车)

因为只把CTF资格赛的杂项AK了,所以贴下题解。

Misc1.Git gud

下载附件得到一张图片attachment.png

图片上半部分有黑点+透明,大概率是提取alpha透明度。

用zsteg也能分析出来,有一段“VegetableThenManyPractice”的密文

搓个脚本提取:

from PIL import Image


img = Image.open('attachment.png')


width,height = img.size
#width,height = 284,77


print(width,height)


flag = ""
for y in range(0,height):
    for x in range(0,width):


        rgb = img.getpixel((x,y))


        alpha = chr(rgb[3])


        if alpha != 255:


            flag += alpha
        else:
            pass


print(flag)

刚开始是没有想到alpha透明度的,以为和01二进制有关,然后发现把getpixel的RGB打印出来是4位RGBA类型的,且透明度的数值基本都能转换ascii,所以将其提取。

将密文保存到文本里,分析这段密文就可以了。

这段密文重复Vegetable、Then、Many、Practice四个单词,一开始以为是词频分析,但是提取之后查看频率发现不是。

那4个为一组的密文可能的就是4进制

分别替换这4个单词为0 1 2 3,然后将4进制转换成10进制,再转换为Hex,最后Hex转文字。

脚本:

import binascii


cipher = "VegetableThenManyPracticeThenManyThenManyThenManyPracticeVegetableThenManyVegetableThenThenManyThenPracticeThenPracticeManyPracticeThenManyVegetableThenVegetablePracticeThenPracticeVegetablePracticeThenManyVegetablePracticeVegetableVegetableThenManyThenManyVegetablePracticeVegetablePracticeVegetablePracticeVegetableManyVegetablePracticeVegetableThenVegetablePracticeThenPracticeVegetablePracticeThenVegetableVegetablePracticeVegetableVegetableVegetablePracticeThenManyVegetablePracticeThenThenVegetablePracticeManyThenThenManyThenVegetableVegetablePracticeThenVegetableThenManyVegetablePracticeVegetablePracticeManyVegetableVegetablePracticeVegetableThenThenManyThenVegetableVegetablePracticeThenVegetableThenManyVegetableThenVegetablePracticeThenVegetableThenManyVegetableManyVegetablePracticeVegetableManyVegetablePracticeThenManyVegetablePracticeVegetableManyThenManyThenManyVegetablePracticeThenThenVegetablePracticeVegetableVegetableVegetablePracticeVegetableManyVegetablePracticeVegetableThenThenPracticePracticeThen"
cipher = cipher.replace('Vegetable','0').replace('Then','1').replace('Many','2').replace('Practice','3')


bindata = int(cipher,4)
print(bindata)


flag = binascii.unhexlify(hex(bindata)[2:])
print(flag)

运行脚本得到FLAG

FLAG: flag{a760f321740659d4c81d4a4b262f5021}

Misc2.cyberpic

下载附件得到文件flag.png 但是打不开

直接Winhex分析

看到IEND一眼就可以分析出来文件字节是被反转了

搓个脚本还原:

content = open('flag.png','rb').read() 
with open('flag2.png','wb') as f: 
    f.write(content[::-1])

反转还原得到图片:

这图片看着很怪有莫名其妙的白条,就和上一道题一样,肯定是某种加密,但是先用stegsolve分析看看有没有什么lsb隐写:

调了最低位分析发现真的有一段密文:

密文:P0TK3KmCts9MZ1iohH04mgZXPz30FSRlQEaK6drCbH68jX92ul0Giv/sRw9QbCBr

这个密文就很像AES或者DES等对称密码,大概率是AES了,所以要找Key,这个时候Key大概率就是跟这个白条有关系了

两道题其实很像,这道题也是提取01,只不过这道题脑洞有点大。之前尝试过提取频率发现不是确定就是提取01二进制。

脚本: (这里高度384是白条的部分,测试出来的高度)

from PIL import Image


img = Image.open('flag2.png')


width = 5
height = 384


data = ""


for y in range(height):


    rgb = img.getpixel((width,y))


    if rgb == (255,255,255):


        data += "1"


    else:


        data += "0"

print(data)
print(len(data))

# 000000111111000000000111000000111111000000000111000000111111000111000000000000111111000111000111000000111111000000000111000000111111000111000000000000111111000000000111000000111111111000000111000000111111000000000111000000111111111000000111000000111111111000000000000000111111000000000111000000111111000000000000000111111000111000000000000111111000000111000111000111111000111111111000
# 384

拿到这段0和1如果直接转换那肯定是出不了的,所以这里就是脑洞大的部分。

因为之前提取过白条和黑条出现的频率,通过频率分析能发现黑白条出现的数量都是3 6 9 12 15这种3的倍数

from PIL import Image




img = Image.open('flag2.png')




width = 5
height = 384




data = ""
ls = []


for y in range(height):




    rgb = img.getpixel((width,y))


    if rgb == (255,255,255):




        data += "1"
        ls.append(1)




    else:


        ls.append(0)
        data += "0"


ls2 = []


start = 0
End = 0
for i in range(len(ls)):
    try:
        if ls[i] != ls[i+1]:


            End += 1
            ls2.append(len(ls[start:End]))
            start = End


        else:
            End += 1
    except:
        pass
print(ls2)


# [6, 6, 9, 3, 6, 6, 9, 3, 6, 6, 3, 3, 12, 6, 3, 3, 3, 3, 6, 6, 9, 3, 6, 6, 3, 3, 12, 6, 9, 3, 6, 9, 6, 3, 6, 6, 9, 3, 6, 9, 6, 3, 6, 9, 15, 6, 9, 3, 6, 6, 15, 6, 3, 3, 12, 6, 6, 3, 3, 3, 3, 6, 3, 9]

所以猜想二进制是每3位取1个,最后转ascii。

脚本提取:

from PIL import Image


img = Image.open('flag2.png')


width = 5
height = 384 #384是图片有白条的高度部分


data = ""


for y in range(height):


    rgb = img.getpixel((width,y))
    #取白条为1,其余为0
    if rgb == (255,255,255):


        data += "1"


    else:


        data += "0"


bindata = ""


for i in range(0,len(data),3):


    bindata += data[i]


for i in range(0,len(bindata),8):


    print(chr(int(bindata[i:i+8],2)),end='')

# 1145141919810hen

运行得到Key:1145141919810hen
注意刚开始我这里高度写的是381,得到的key是1145141919810he7,后面发现解不出来不对,所以高度多加上3 得到了这个最终Key。

最后用Key解AES密文就可以得到FLAG了 模式选择AES

FLAG: flag{9103d33366cc1193c81f55a06e34c5d2}