[CTF] 攻防世界MISC高手区部分题目WriteUp(2)

记录一些有意思的题目

目录索引

7-2

下载解压得到一个文件夹,里面有一堆文件,对所有文件名进行 base64 解码

# coding=utf-8
import os
import base64

for name in os.listdir("/root/桌面/problem"):
    print name
    # 由于文件名不是4的倍数,需要在后面补‘=’
    missing_padding = 4 - len(name) % 4
    if missing_padding:
        name += '=' * missing_padding
    print str(base64.b64decode(name.encode()))

看到输出的信息里只有这个文件解码后不是乱码:YWluaWRleGluZ3podWFuZw
[CTF] 攻防世界MISC高手区部分题目WriteUp(2)
打开文件后看到里面存在一对花括号,那么很有可能这些数字解码后就是flag

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 74 94 22 42 91 23 {82 42 82 52 63 21 42 22 73 21 }00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

这次使用的是9键加密,第一个数字代表9键键盘下的数字,第二个数字代表该数字下的第几个字母。解密后再用一次凯撒加密即可得到 flag

wdflag{ylyoselfve}

ewm

下载解压后得到一个文件夹,打开看到里面是一堆二维码的部分图块,按大小被分为了 small 和 big 两部分,总共两个二维码,可以把图片拖到 word 里拼图,拼完的二维码扫出来就是 flag,而且两组图片拼图的结果都是一样的,这里给一个拼图的脚本(并不能完美的拼出来,但已经可以扫出来了)

import os
from PIL import Image
# 由于二维码并没有被完整的切开,都保留了一部分边缘
# 所以可以遍历所有图片来找到两个边缘符合的图片进行拼图

# 设置已知的图片
def set_image(in_file, x, y):
    code[y][x] = in_file
    file.remove(in_file)

# 找到一张图片的右边一张
def find_right(in_file):
    result = ''
    pixes = Image.open(os.path.join(current_path, in_file)).load()
    # 计算出已知图片的右侧像素值(以二进制存储)
    pix = 0
    for row in range(width):
        r, g, b = pixes[width-1, row]
        pix <<= 1
        if r + g + b > 255:
            pix += 1
    # 用同样的方法在剩下的图片里找到与已知图片边缘相符的图片
    for fi in file:
        pixes = Image.open(os.path.join(current_path, fi)).load()
        pix2 = 0
        for row in range(width):
            r, g, b = pixes[0, row]
            pix2 <<= 1
            if r + g + b > 255:
                pix2 += 1
        if pix == pix2:
            result = fi
            file.remove(fi)
            break
    return result

# 找到一张图片的下边一张
def find_bottom(in_file):
    result = ''
    pixes = Image.open(os.path.join(current_path, in_file)).load()
    pix = 0
    for col in range(width):
        r, g, b = pixes[col, width-1]
        pix <<= 1
        if r+g+b > 255:
            pix += 1
    for fi in file:
        pixes = Image.open(os.path.join(current_path, fi)).load()
        pix2 = 0
        for col in range(width):
            r, g, b = pixes[col, 0]
            pix2 <<= 1
            if r + g + b > 255:
                pix2 += 1
        if pix == pix2:
            result = fi
            file.remove(fi)
            break
    return result


if __name__ == '__main__':
	# 读取所有拼图文件
    current_path = r"C:\Users\28919\Desktop\big"  # r"C:\Users\28919\Desktop\small"
    file = [name for name in os.listdir(current_path)]
	# 计算拼图的大小
    n = int(len(file) ** 0.5)
	# 创建储存图片的数组
    code = [['' for i in range(n)] for i in range(n)]
	# 设置单张图片的边长
    width = 51
    # width = 42

    fail = False
	# 给出3个定位点,让脚本根据已知的图片进行拼图
    set_image('ebb9e03faca4_big.jpg', 0, 0)
    set_image('be557e464b98_big.jpg', 4, 0)
    set_image('13d9bb15c1c5_big.jpg', 0, 4)
	# 由于存在多张边缘相似的图片,对small进行拼图的时候需要多给一个数据
	# 但还是不能完美拼出来,但是拼出的结果可以扫出flag
    # set_image('f56e68b804ae_small.jpg', 0, 0)
    # set_image('dee457f4f9e0_small.jpg', 5, 0)
    # set_image('8e92d38c074c_small.jpg', 0, 5)
    # set_image('bb57a891b8c1_small.jpg', 0, 1)

    for y in range(n):
        if fail:
            break
        for x in range(n):
        	# 对未知的图片进行查找
            if code[y][x] == '':
                print('Find%d,%d' % (x, y))
                if x == 0:
                	# 如果是最左边的图片需要通过上方的图片来拼图
                    code[y][0] = find_bottom(code[y-1][0])
                else:
                	# 通过左边的图片进行拼图
                    code[y][x] = find_right(code[y][x-1])
                # 找不到就直接退出
                if code[y][x] == '':
                    fail = True
                    break
                else:
                    for i in code:
                        print(i)
    if fail:
        print('拼图失败!')
	# 根据已找到的图片拼出最终的图片
    image = Image.new('RGB', (n*width, n*width), (255, 255, 255))
    for y in range(n):
        for x in range(n):
            if code[y][x] != '':
                p = Image.open(os.path.join(current_path, code[y][x]))
                image.paste(p, (width * x, width * y))
    image.save(r'C:\Users\28919\Desktop\flag.png')

脚本拼图的结果:
[CTF] 攻防世界MISC高手区部分题目WriteUp(2)
[CTF] 攻防世界MISC高手区部分题目WriteUp(2)

flag{g00d_g00d_study_1jf8988}

Mysterious-GIF

下载得一个 gif 文件,分帧看看不到什么异常,丢到 kali 里用 binwalk 跑一遍
[CTF] 攻防世界MISC高手区部分题目WriteUp(2)
发现有一个 zip 文件,用 foremost 命令分离出来,得到一个 temp.zip 文件
[CTF] 攻防世界MISC高手区部分题目WriteUp(2)
这压缩包里就一个256字节的文件却占用112K的空间,明显不对劲,再用 binwalk 命令跑一下
[CTF] 攻防世界MISC高手区部分题目WriteUp(2)
发现有一堆文件,再把它们分离出来(这里用binwalk分离的话可以自动解压),得到 partaa.enc 到 partke.enc 共计265个文件,enc文件是RSA加密后的文件,所以还需要找到私钥进行解密

先来了解一下 gif 的文件结构 https://blog.csdn.net/xlvector/article/details/589214
以 0x21FE 开头的注释扩展 (Comment Extension) 可以记录一些信息,我们在 010Editor 里搜索 21FE 看到有一些16进制字符
[CTF] 攻防世界MISC高手区部分题目WriteUp(2)
21FE后的80表示注释的长度,gif 的每一帧都有一个这样的注释,可以一个个将其复制出来,也可以在 kali 里用 strings 命令跑出来(最后一行开头的8是多余的,需要删掉)
[CTF] 攻防世界MISC高手区部分题目WriteUp(2)
16进制转为字符串,给它加个文件头即可得到RSA的私钥

-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDdMNbL5qVWiCQrX2w69q/7y3ShIPueptxfAwRQbROre30c6Uw/oK8weZTx44m0ALouhV46KcQJkhrqg8Oy3s5Y5FV1wCK766u2WLwVrWMIUJG1jDDrRvYPIcQ5UqCp5EDQCioRMGcUZEg2uvl142LDBAaeOLzFM4e2JczS+0r85mPRrCSxjLKLaLwIIQnZXIpXSURV/wjhwWR1fJGG8Q+ucEApaXscNCUF44bPm4HPCJ/0mrDCTWH/Y2CPVJkNk+o0V7VOtHKsML4NCNAJH44W/IRwJntNW+N8HrgpRkFughmNjcwlEkrtUKG1sRCy//WhuDunV2phSRQvHotBZvydAgMBAAECggEBAJyaN3mlkunw+aq7pKUagv6CzdBGyd9JxDyApk1K7OI8TBhsFM/3tBFeA1Y/Av+uhCLrygrkBye/ic7/+05o8S9+egMkRXNHKAuyR3gRikwYvxEKcJgjZZLRFVyAY7/lGv4wNBh3bIPDfF1Dg9szYnkwIH9lLEFyemM74AiAYlcqdVdZIE/bq2Z4JO0t9HCgHZNfQ7JdRfejNJQVYUD01Qu5dMtOR4eIMdbWkhbVXw2TE0H7xQxtjwT6zUrpqEvvO7e3FHEsBIX65VRXRLbv9OoayJxcRqX8eJkRi4L/Yzo4KTpEmkduJLXsFwt3aqQTbjZHXOlTT4NEdsH2p0TsCAECgYEA/e1bszO0a1+cBaDQjQO+Pv9BsJFDB3o1LGuUHMNS8FDpn3J46UkYyk52vIa0v4TcjqSSHNIvXW0TDEUkbNFA1HpUxVxlw0Bieeh8Bg3HfXyQBhXvdTD7k0lsDmMEo4UPKYS6D5cYWyrwhd5nCD0LrxebgO75RxL5QEIE+4CVIQkCgYEA3v8R/XKRVJPE4aEeg7pQ4uTvcFxjENNexxf6K4xpY4Lf9clIvdecRhC2t1HdR+xSulU/RSaRrzHcw3xg+L1uO0s1t5S7f3nu3aihIXkcgGSqXCZ1VHzBmeC40TVsfAybs7qJ0xY6T5q8Mnx2Ob5Z3lIGuyhjeVatFII2Sdz2J/UCgYEAteA15zQojSPNH+bgmbBNqtev2GUjSo7I2UkwrC1nEYQS4cbfPdDCdd0fhMdDXU4vn+fWU9hkXpmKpCY+AccblVUNtNMKfIB4SHMxqjBia8o1anZ5rknoV8WmJOPdZbYfdxB/KD2ED4DBCFGVILyAyuew1PfWCodXiiP/Z5jgt+kCgYEArsxqoa0o1o9uiR7u+HsX5INoXT9OOGY3qQDWjURnaCWywMujRYy5ZwK690AooLRStNUV33K4SAhh8KqSqOh0e+4ckWb5Apfl8cK5a6+v88T09X8AAdY5PBG3Teb+vs5zTpMublTCKJw2YazGT8UyVN8ff53NO9QBoE3hmEyod/ECgYA9k0xyCJzcveKdxry6pjQxk9FZz3AtEp1ocV5VowagV+ONez/HccF8GJO8BDqlP6XkcLUtsnp6tYReEICIHKw5C+fwAXlFItm09aEVTXw+xzLJb2Sr6gATPWM5qVaubxfsb5mXH/wD9iCLhJSorK0RHZktPbEs5ytDsqBHd5PFFw==
-----END PRIVATE KEY-----

然后脚本解密所有文件并输出就得到flag了

# coding=utf-8
import os
import Crypto.PublicKey.RSA
import Crypto.Cipher.PKCS1_v1_5
path = r"F:\ShareFile\_out.gif.extracted"
# 读取所有文件
file = [name for name in os.listdir(path)]
flag = b''
# 载入私钥
cipher = Crypto.Cipher.PKCS1_v1_5.new(Crypto.PublicKey.RSA.importKey(open(r'F:\ShareFile\private.txt','rb').read()))
for fi in file:
    message = open(os.path.join(path,fi),'rb').read()
    flag += cipher.decrypt(message,b'rsa')
open(r'F:\ShareFile\flag.jpg','wb').write(flag)

[CTF] 攻防世界MISC高手区部分题目WriteUp(2)

FelicityIsFun

上一篇:S3cCTF-gyy-Writeup


下一篇:“干掉”HackTheBox里面的Writeup