2020西湖论剑CTF部分MISC——Write Up

前言

谢谢盖师傅,本文章部分题目参考盖师傅的WP再详细的解释每一步的解题步骤,盖师傅yyds

还有借用了核平师傅的脚本进行解题,核平师傅yyds

Yusapapa

题目地址:http://yusa-papa.7bf48c.challenge.gcsis.cn/

查看题目所给网站的源码,其中有一段注释

在这里插入图片描述


 1. Maybe these texts are really helpful for you
 2. Biometric list is OK!
 3. endow gremlin indulge bison flatfoot fallout goldfish bison hockey
    fracture fracture bison goggles jawbone bison flatfoot gremlin
    glucose glucose fracture flatfoot indoors gazelle gremlin goldfish
    bison guidance indulge keyboard keyboard glucose fracture hockey
    bison gazelle goldfish bison cement frighten gazelle goldfish
    indoors buzzard highchair fallout highchair bison fallout goldfish
    flytrap bison fallout goldfish gremlin indoors frighten fracture
    highchair bison cement fracture goldfish flatfoot gremlin flytrap
    fracture buzzard guidance goldfish freedom buzzard allow crowfoot
    jawbone bison indoors frighten fracture bison involve fallout
    jawbone Burbank indoors frighten fracture bison guidance gazelle
    flatfoot indoors indulge highchair fracture bison hockey frighten
    gremlin indulge flytrap bison flagpole fracture bison indulge hockey
    fracture flytrap bison allow blockade endow indulge hockey fallout
    blockade bison gazelle hockey bison inverse fracture highchair
    jawbone bison gazelle goggles guidance gremlin highchair indoors
    fallout goldfish indoors bison gazelle goldfish bison indoors
    frighten gazelle hockey bison flatfoot frighten fallout glucose
    glucose fracture goldfish freedom fracture blackjack blackjack

直接搜下面那一大堆内容,就可以找到是PGP词汇表,对着表替换一下,得到

59 6F 75 20 63 61 6E 20 73 65 65 20 6D 79 20 63 6F 6C 6C 65 63 74 69 6F 6E 20 70 75 7A 7A 6C 65 73 20 69 6E 20 2F 68 69 6E 74 2E 72 61 72 20 61 6E 64 20 61 6E 6F 74 68 65 72 20 2F 65 6E 63 6F 64 65 2E 70 6E 67 2E 0A 42 79 20 74 68 65 20 77 61 79 2C 74 68 65 20 70 69 63 74 75 72 65 20 73 68 6F 75 64 20 62 65 20 75 73 65 64 20 0A 22 59 75 73 61 22 20 69 73 20 76 65 72 79 20 69 6D 70 6F 72 74 61 6E 74 20 69 6E 20 74 68 69 73 20 63 68 61 6C 6C 65 6E 67 65 21 21

用010导入十六进制得到

在这里插入图片描述

You can see my collection puzzles in /hint.rar and another /encode.png.
By the way,the picture shoud be used 
"Yusa" is very important in this challenge!!

根据给的目录,下载得到hint.rarencode.png,在网站首页源码中还可以发现一个encode.webp,也保存下来

防止时间过长,题目地址可能出现无法访问,我用百度网盘分享一下这三个文件,希望先按照上面的一步一步操作,再拿分享的文件

链接:https://pan.baidu.com/s/1HCFXC3j1DNAdPz7RHKX0Vg 密码:fvev

解webp文件隐写用到stegpy,无密钥直接解,可以得到压缩包密码
工具传送门:https://github.com/Baldanos/Stegpy.git

在这里插入图片描述
压缩包密码:Yus@_yydsstegpy!!

根据题目所给hint,找到一个加密工具:InvisibleSecret

用Unhide Files选项,选择hint.jpg,选择Blowfish加密,密钥为Yusa
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
解得一个加密脚本,在网上找到盖师傅写的根据加密脚本写解密脚本,得到flag,盖师傅yyds

from PIL import Image,ImageDraw

hide=Image.open('encode.png').convert('RGB')
R=[]
G=[]
B=[]
a,b = hide.size
for x in range(a):
    for y in range(b):
        R.append(hide.getpixel((x,y))[0] & 1)
        G.append(hide.getpixel((x,y))[1] & 1)
        B.append(hide.getpixel((x,y))[2] & 1)
flag = [r^g^b for r,g,b in zip(R,G,B)]
for i in range(len(flag)):
    if flag[i] == 1:
        flag[i] = 255
en_p = Image.new('L',(a,b),255)
for x in range(a):
    for y in range(b):
        en_p.putpixel((x,y),(flag[y+x*b]))
en_p.save('flag.png')

用python3环境跑脚本得出flag
在这里插入图片描述

指鹿为马

在这里插入图片描述
先输入1拿到题目的py脚本

import numpy as np
from PIL import Image
import math
import operator
import os
import time
import base64
import random

def load_horse():
    data = []
    p = Image.open('./horse.png').convert('L')
    p = np.array(p).reshape(-1)
    p = np.append(p,0)
    data.append(p)
    return np.array(data)

def load_deer():
    data = []
    p = Image.open('./deer.png').convert('L')
    p = np.array(p).reshape(-1)
    p = np.append(p,1)
    data.append(p)
    return np.array(data)

def load_test(pic):
    data = []
    p = Image.open(pic).convert('L')
    p = np.array(p).reshape(-1)
    p = np.append(p,1)
    data.append(p)
    return np.array(data)


def euclideanDistance(instance1, instance2, length):
    distance = 0
    for x in range(length):
        distance += pow((instance1[x] - instance2[x]), 2)
    return math.sqrt(distance)


def getNeighbors(trainingSet, testInstance, k):
    distances = []
    length = len(testInstance) - 1
    for x in range(len(trainingSet)):
        dist = euclideanDistance(testInstance, trainingSet[x], length)
        distances.append((trainingSet[x], dist))
    distances.sort(key=operator.itemgetter(1))
    neighbors = []
    for x in range(k):
        neighbors.append(distances[x][0])
        return neighbors


def getResponse(neighbors):
    classVotes = {
    
    }
    for x in range(len(neighbors)):
        response = neighbors[x][-1]
        if response in classVotes:
            classVotes[response] += 1
        else:
            classVotes[response] = 1
    sortedVotes = sorted(classVotes.items(), key=operator.itemgetter(1), reverse=True)
    return sortedVotes[0][0]


def getAccuracy(testSet, predictions):
    correct = 0
    for x in range(len(testSet)):
        if testSet[x][-1] == predictions[x]:
            correct += 1
    return (correct / float(len(testSet))) * 100.0

def check(pic):
    source_p = Image.open('deer.png')
    try:
        c_p = Image.open(pic)
    except:
        print("Please upload right picture.")
        exit()
    diff_pixel = 0
    a, b = source_p.size
    if c_p.size[0] != a and c_p.size[1] != b:
        print("Please upload right picture size("+str(a)+','+str(b)+')')
        exit()
    for y in range(b):
        for x in range(a):
            diff_pixel += abs(source_p.getpixel((x, y)) - c_p.getpixel((x, y)))
    return diff_pixel

def main():
    while 1:
        print('-' * 134)
        print('''      ____       __            _          _   _                _                              _   _            _                         
     |  __ \     / _|          | |        | | | |              | |                            | | | |          | |                        
     | |__) |___| |_ ___ _ __  | |_ ___   | |_| |__   ___    __| | ___  ___ _ __    __ _ ___  | |_| |__   ___  | |__   ___  _ __ ___  ___ 
     |  _  // _ \  _/ _ \ '__| | __/ _ \  | __| '_ \ / _ \  / _` |/ _ \/ _ \ '__|  / _` / __| | __| '_ \ / _ \ | '_ \ / _ \| '__/ __|/ _ \\
     | | \ \  __/ ||  __/ |    | || (_) | | |_| | | |  __/ | (_| |  __/  __/ |    | (_| \__ \ | |_| | | |  __/ | | | | (_) | |  \__ \  __/
     |_|  \_\___|_| \___|_|     \__\___/   \__|_| |_|\___|  \__,_|\___|\___|_|     \__,_|___/  \__|_| |_|\___| |_| |_|\___/|_|  |___/\___|
    ''')
        print('-'*134)
        print('\t1.show source code')
        print('\t2.give me the source pictures')
        print('\t3.upload picture')
        print('\t4.exit')
        choose = input('>')
        if choose == '1':
            w = open('run.py','r')
            print(w.read())
            continue
        elif choose == '2':
            print('this is horse`s picture:')
            h = base64.b64encode(open('horse.png','rb').read())
            print(h.decode())
            print('-'*134)
            print('this is deer`s picture:')
            d = base64.b64encode(open('deer.png', 'rb').read())
            print(d.decode())
            continue
        elif choose == '4':
            break
        elif choose == '3':
            print('Please input your deer picture`s base64(Preferably in png format)')
            pic = input('>')
            try:
                pic = base64.b64decode(pic)
            except:
                exit()
            if b"<?php" in pic or b'eval' in pic:
                print("Hacker!!This is not WEB,It`s Just a misc!!!")
                exit()
            salt = str(random.getrandbits(15))
            pic_name = 'tmp_'+salt+'.png'
            tmp_pic = open(pic_name,'wb')
            tmp_pic.write(pic)
            tmp_pic.close()
            if check(pic_name)>=100000:
                print('Don`t give me the horse source picture!!!')
                os.remove(pic_name)
                break
            ma = load_horse()
            lu = load_deer()
            k = 1
            trainingSet = np.append(ma, lu).reshape(2, 5185)
            testSet = load_test(pic_name)
            neighbors = getNeighbors(trainingSet, testSet[0], k)
            result = getResponse(neighbors)
            if repr(result) == '0':
                os.system('clear')
                print('Yes,I want this horse like deer,here is your flag encoded by base64')
                flag = base64.b64encode(open('flag','rb').read())
                print(flag.decode())
                os.remove(pic_name)
                break
            else:
                print('I want horse but not deer!!!')
                os.remove(pic_name)
                break
        else:
            print('wrong choose!!!')
            break
    exit()

if __name__=='__main__':
    main()

在输入2 拿到两个图片的base64值

(转码网站https://tool.jisuapi.com/base642pic.html

马的base64

iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAAAAABwhuybAAAFeElEQVR4nO2Xy28TVxTGvzN2ZpLYIY5dkgImIU4I2DFqQqiaqGpL2gXqv8AC2lUX/BFl032lSpWqblqpGyQ2LQhERQhUDSqk4ZnEtHnxCATn4TjP8fOeLmZszzPEUpeclefeM7/z3e/OfRh4G/9n+Dtk907v7jnKh42vc6690u5BTe/u1FsFyEPVgGoaqkAbw+pR5+m5689dq+5QxApSWjuO/DhbGoRgU6dcv7E7UH1472EUw2fuFDVS8e+UKblmX3JXoHBfiEKAOJjSClPOOpTOp2k3kCG19aN3IADA08habGyZk7nxRN2bFTWc8AuEWiWADtG8AIAF1ZLNrZ77SwynqIAa19cpHpMZgLddmcsTCpmwBACFZLGcFQ69TKoaivPragVKxl/9Z/YI/WlxRiVtoKC1qyoAtJzyAgAx66+LrWdPNu2KGL2n/el6vaFZntogzUBS8wCALXUPA2CQXl0KBPbdXtFfN5gdPxt68M210lNTNFj6mSxooJdWX5ibB3w20JEv9vLMqyeFUlJDtEX7pb4kSZIInFi3rTZuOWIdWuTLfUJiVNxjpUuZFwA8xwVAUzNYvTvgs03ZoYRqAsW+CgnAh3rDWL3t8tMCULMfAD0H8CxzbH+NQQ4A9jeYQF3fHR1LE/fXdHkMNaWD8kyGwAAKaQBIpkJBWRsf1YeCEgOSvmtqrW3fnxTp+2kiYov21alNAkDL1zLWQdW2xQMMcX1eKwoA9edPFjnQG2AWVg+CsSAA8LSNg8w/N1cq7ksA8P7nAuBAT4CJyDwz3HC0BcCLaRsHwModtZztBYC4XwDgpt6RJY/gBo+JVNslL6/N+f12Tl59PRczgXQsN937SRY43StM+d5ION9nx5DILSeWyqvQCwDjmz4GQBt/LQIYOqqYX5FqXTaPgz3p5flSEgDcveohgDyXRwFgctK2NbNzCA50HJYNoO2vL2xJ0uYv51UAyA5btyH3YBz4WPtEdXt8J7p5fGxbe1DO9QmXFx0i98NdA8gcvecUp2bnkB59m4XLSTsxUcUpye0H4AbKVeES2Bd2BWGyGklSozuoKknat+hSuSpJtAMod8NdkvPtxq1w4pFbD684XtuMZ78n3Fx+u7hWdKxMuZnNQFuNvcMI6vqk8h1yIzuBqHB58XgKDiTDAChSKyrheMJT4cpvOULqWX4nRZKX4Walzslf/bVAABw0WW9sBX222OFKTdlLV3Sj7SQLSEoOaQtfdMet0yalLo6UzmE7yaZoQ99BVItJxE8uJgCQv0ySjSm7u/kTide3bq0DQEenftmZHTvVZCC5ghjQ55S5sD1//552UwsNKAwAtPBHMnk2UCG5gho8QPbWGoGLanpxKau1Kv26iumRNYzCQLKCvB5NudzvFdL4BctqoN4IA6Dio9EMYCJZpka0HNNaYt0C6rB1VUXeAwBSR25rJ/joz6ul784AKqYBeD/o8QCQB+sgjScsnOCAAkBKDz0snYujQ6U+o6KHrwio6WsuCbppEaQMBBmgV9dmy84o7WScFz3SQwuE4sMlQD5ZB2li0syhnggDmP7d8D8i1i2gzllBSA0tiNGxAhCNOzjU3gOQeHBjzaBxsA7SZAKwzlrqRsu/RUAerBM2QcEBhUkdfVw0tEVjAupw1g7CygrgLEjpDzHSf84Zl4U8WCekSa2g0wfpKKgzwsgMvzC1RbvLghz3bEeH/B5QbtVaECVBTiD507KDO0c0LpC5mXUFxQyCDWG7XmqCJvQnu0dGBw2RXWPaNO1R0bhAplzQDup2FpSYZYhtW8GSIDtIcRaErBUdMwmyexSLOQqyhdkhh//9n/kEOQiyRfwYpKyhoA00PgU8frMg5C8JWp94c97bqMR/qKdMxhtIpukAAAAASUVORK5CYII=

鹿的base64

iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAAAAABwhuybAAAEXUlEQVR4nO2XS2xbRRSG/5l7b/xSb2wnDqbBSdU0FcQUmsRZVCAkorZJumkrFWEkWLJgyZINC5bsQQKEVAkhNRKJRKWqjUiFEAgUkYRQtYQ+ZCc4jzbk4dgkaWzfOSwSP+7D9r3Jtmc198ycz/+ZmTMzBp6Zc2N959wAXGdjDEDTxY6DggJfXT8FoOv7L/wArox/xG2FmUcpHsUNwKO4FYB3QNABQaCKyGi39pc9kKzT8p/Yb3pdfkhNSvTtpvu/2eLoQBfPfjkNAGh7+bTqlYIfs8aGha9XHYOkUyd7pgFAes/L8iIHldIzo4/scSpB2mPRpWYAwLtwK1EAINZW8jY5utQmzr8Uv5YB+MKnf9uNtwTdGbt8uWtW8tG4c44OVPiWBqJRiELSOUcHQvbqw4FjDR4qHBbU/mane0MJy+e2Z7VDgFj3W01ZhZFGL4bGx2wvVzG63IzF/TMjZwYYh0Dh1k2HpHKtxeIqJZcfaqRpRPLgkGI3cM9KqcXiKjHCfoWSPIiamviQd3KuspyL4FhcJcALLyuRampiJ4Y+OFMxL0VFvXGVAOpTTkg2NQktcGm5YsNxAGCxd/wAQIH+SElu3XkSgV6jotbXsptySNKfafXnCWGpvN1kANB+JzraLxnH1SVJFZMkA0BWcvlebTAfqSQPSjef1tJkAG0pA17F6mgm+XxoLCUseqxB9AveCO5lxhViABVjifd13vlzYctUepVZASiVCGsMKQAg2j8JCrDtmaelgYzl0umcEcQiR4jf/ax8TuzvI0qn9xrJxCsaoC3Pl9MjOdRiToUI5A8vlL6NJbP73bYQgrfplpCE2Qig1vejVUH46Z4EUIvfzrVIR989WRW0el0AcEdscADRfEmtBsKNJQ6g1WvrphYdxTIxgx7c5gCpYVuSwHtc1UDaaIYBUti4UayNwoFqIExMcQCyTZBbrQrKjhYA8cRWYQCSUhWEHxKySM7ZU1SqDdmiK/XNlfUnebsgVAfRyPNHWJljyJFZ/4IVCKnp/nK0K6iP3NmwDxK3OyNFkgi+rp/H3amUVYz123dlZL3UwbjevLE2+yDcu5ood+lTI48lyTI1ALPLvd3HJQBM7EqGsuOntUVTQI1FDn8YIIAt/2xYNmrpyUvB4pf2+d2aigAUCADY6o/GA7vVxRtEs8Fp74+G3hjn+X/WioDQwUEAWG5+bW9W+IXYYUBguflFAgBqjEftgaosB9u6NskAgPzHgZqTvR9Q5VnKVh4tsT4C9t9m9RSxjV+tSSKhZYcny3LrKGLp4T+sO9YXgcwwSk+kOorYxJTZ6eMAJXcAbN7IFDXVS23H7JLaGNjW3p2+W8r7AMvf/BwBqU2D9wCgdheQSxrvT+cgXwRgj1eMbuegVpUgEqY94RgkHeNg60smv2NQcwuB5syL6RjU7gLbmjP7nYJ8EQCpjLmjVokwTtxY+y80guUTpBtTD7Q95iF23+icBnb+1Y95UEPMM6uw/wEb7IPCRqC/gwAAAABJRU5ErkJggg==

输入3,提示输入图片:Please input your deer picture`s base64(Preferably in png format)

经过代码审阅,发现题目的要求是要你输入一张图片(这里称为test)的base64编码,通过他的条件就会得到flag。

我们发现在传入马和鹿和test时,load_horse(),load_deer(),load_test(),图片的尾部会被添加一个值,除了马是0,其他两张都是1,这是重点!!

在看输入图片后的判断流程,第一个条件check(),check()的作用是将test和鹿的像素差的绝对值相加,如果大于10w就不通过。第二个条件getNeighbors(),比较test和马和鹿的像素的欧式距离。如果test和马的欧氏距离最近才能通过。getResponse()的作用就是判断图片的尾部是否为0(感觉这代码也是作者从其他地方扒拉过来的,图片对抗)。

所以我们就理清思路了,我们要输入一张test,test的总像素差和鹿不能超过10w,并且和马的欧式距离最近。真是“指鹿为马”啊。

一开始我是想用PS将两个图片叠加再一起的,可是一直过不了,还尝试了几次不同比例叠加,也不行,听说有大佬用PS过了。我还是交给脚本吧···,我的思路是在鹿的基础上将马的像素点一个一个加上去,直到满足两个条件就停止。这个脚本我借用大佬的脚本核平先生,大佬yyds

from PIL import Image

ma = Image.open('./horse.png').convert('L')
print(ma)
print(ma.size)
print(ma.getpixel((0, 70)))
lu = Image.open('./deer.png').convert('L')
luandma = Image.open('./deer.png').convert('L')
for i in range(72):
    for j in range(72):
        px = ma.getpixel((i, j))
        luandma.putpixel((i,j),px)
        diff_pixel = 0
        distance1 = 0
        distance2 = 0
        for y in range(72):
            for x in range(72):
                distance1 += pow(abs(lu.getpixel((x, y)) - luandma.getpixel((x, y))), 2)
                distance2 += pow(abs(ma.getpixel((x, y)) - luandma.getpixel((x, y))), 2)
                diff_pixel += abs(lu.getpixel((x, y)) - luandma.getpixel((x, y)))
        if diff_pixel <= 100000 and distance1 > distance2:
            print("ok")
            luandma.save('done.png')
            exit()

脚本跑完后得出一张图,果然是两个图合在一起,第一次见

在这里插入图片描述
把图片进行转换base64


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

输入3 然后把合成图片的base64输入

在这里插入图片描述
然后base64转码成txt后发现里面还有图片的base64,再转,才是最后的flag

在这里插入图片描述

在这里插入图片描述

Barbar

在这里插入图片描述
分离附件二维码后的压缩包,可以得到一个加密的压缩包,提示密钥32位,无法爆破
在这里插入图片描述
在这里插入图片描述

扫码可以发现在密和码之间还藏有其他信息,这是很明显的零宽度字符隐写

在这里插入图片描述

然后用微信扫一下,把输出框里面的所以字符复制到这个网站进行解码https://yuanfux.github.io/zero-width-web/

在这里插入图片描述

在这里插入图片描述
这个就是压缩包密码

YcfVgMBUraXftwO6Cp92YBGAbyRyWNOO

在这里插入图片描述
在这里插入图片描述

解压得到一个坏了的qrcode和一个word文档,先看word文档,里面内容没有什么隐写的地方,所以想到把后缀改成zip,依次查看里面的文件,在document.xml这个文件里可以发现一大串base64,复制的时候把所有的&#xA都要删掉

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

转码发现是个png,转成png是一个aztec码,扫码可得

在这里插入图片描述
经扫描得出

扫描工具网站https://demo.dynamsoft.com/dbr_wasm/barcode_reader_javascript.html

进来这个网站扫描前必须选中SETTINGS进行设置添加阿兹台克代码才能识别出来
在这里插入图片描述

di`f {
    
    e1c64e14db14c6bb8faabab5bd7be1dc}

在这里插入图片描述

再看那个损坏的qrcode,只缺少了三个定位码,用PS补全即可扫出来,但是扫码并不能得到任何有用信息,也没有零宽隐写。

在这里插入图片描述
在这里插入图片描述
所以需要转换思路,观察这个损坏的二维码的图案,实际上是一种基于颜色和像素的编程语言:piet

这种编程语言有在线的解释器,搜索npiet即可找到:npiet

上传图片,选择最下面的那个选项

在这里插入图片描述

在input string处输入通过aztec码得到的那串和flag极为相似的字符串,点击运行,即可得到flag
在这里插入图片描述
在这里插入图片描述

flag{
    
    f2d76g36fd16cbb6abaaf8db57cbd1ed}

猜你喜欢

转载自blog.csdn.net/weixin_47598409/article/details/109079125