前言
首先恭喜zysgmzb师傅荣获最想暴打的出题人荣誉,不得不说zys师傅出的misc题的质量确实高!学习!
Signin
程序设计实验作业,但是签到题(听zys说建议把终端字体调小一点并且只需要输入一串来自35年前的神秘秘籍
根据题目描述找到神秘秘籍上上下下左右左右ba,直接输入后得到flag
NCTF{VVelc0m3_T0_NCTF_2022!!!}
只因因
这是什么只因因
得到一个txt
You have the following sequence reads from a genomic clone of the Homo sapiens genome:
Read 1: ATGCGATCTGTGAGCCGAGTCTTTA
Read 2: AACAAAAATGTTGTTATTTTTATTTCAGATG
Read 3: TTCAGATGCGATCTGTGAGCCGAG
Read 4: TGTCTGCCATTCTTAAAAACAAAAATGT
Read 5: TGTTATTTTTATTTCAGATGCGA
Read 6: AACAAAAATGTTGTTATT
Use these six sequence reads to create a sequence contig of this part of the H. sapiens genome.
Go to the BLAST page (http://www.ncbi.nlm.nih.gov/BLAST/) and see if you can identify the gene of which this sequence is a part.
flag内容为查询到的基因名称简写的md5值,包上NCTF{}提交。
根据txt描述在网站的nucleotide blast去搜核苷酸序列
结果翻译一下,有好多智人,都是CFTR基因的片段
md5(CFTR)
NCTF{254e72a3768938792446548561412d43}
qrssssssss
有什么东西掩盖住了zys的双眼,好像在给他指明方向!(flag括号内的内容只有26位)
打开得到一堆二维码
脚本批量读取二维码数据
# -*- coding: utf-8 -*-
from PIL import Image
import pyzbar.pyzbar as pyzbar
import os
def qrcode_parse_content(img_path):
'''
单张图片的二维码解析
'''
img = Image.open(img_path)
#使用pyzbar解析二维码图片内容
barcodes = pyzbar.decode(img)
#打印解析结果,从结果上可以看出,data是识别到的二维码内容,rect是二维码所在的位置
# print(barcodes)
# [Decoded(data=b'http://www.h3blog.com', type='QRCODE', rect=Rect(left=7, top=7, width=244, height=244), polygon=[Point(x=7, y=7), Point(x=7, y=251), Point(x=251, y=251), Point(x=251, y=7)])]
result = []
for barcode in barcodes:
barcode_content = barcode.data.decode('utf-8')
result.append(barcode_content)
return result
def load_imgs(folder):
'''
加载文件夹下的图片
'''
imgs = []
for img_path in os.listdir(folder):
ext = os.path.splitext(img_path)
if len(ext) > 1 and is_img(ext[1]):
imgs.append(img_path)
return imgs
def is_img(ext):
'''
判断文件后缀是否是图片
'''
ext = ext.lower()
if ext == '.jpg':
return True
elif ext == '.png':
return True
elif ext == '.jpeg':
return True
elif ext == '.bmp':
return True
else:
return False
if __name__ == "__main__":
imgs = load_imgs('./') # 打开图片文件夹,我这里是当前程序运行目录
contents = []
# for img in imgs:
# contents.extend(qrcode_parse_content(img))
# print( img)
# file = './result.txt' # 写入文件路径,我这里程序当前运行目录下的result.txt
# with open(file,'w',encoding='utf-8') as f:
# for c in contents:
# f.write(c + '\n')
for img in imgs:
print(qrcode_parse_content(img)[0],end='')
e1b19411bCT3ef91e-T6--5115-b-eNe5-01e-1-0}1a15-0e91e50N15-eTa3-0e}8bC16ee11feeeeb7{ae1eeNbC7Ta1T-5bFb--398a515-NbTfbb-8-7ef-}0C-Te4eF501f{6a51e4be--5-Fb0}Fb-5{b97ef8a-{fa11bC9fee-3-e9N{1-51T1NN01C41883{577-1e-T1603{C{-17-NNeC0f-0C39711514{9117F--6-F-e05a7517C3b4-F{F71f}-1fe70-34-{7805C}b{bCf1f-aT{e3aFe-f-0bT6C17000N78e-76}af7-}4N-907}03187b113T9eaeF--13ebeN71b-C9Te1eF-680-468675F17410674N910F51b1511--80FF565165-19}beT}N17N-1758e-}1a8-4C-0057e-5b7b0}5}{7eaN-{-b}36b}7eb0-606{15b4b01971T-59388-Te351eFC044417af
通过字频统计发现应该是16个flag打乱了顺序
一开始没有思路,后来revenge给了纠错级别LMQH的提示
结合flag内容26位的提示,加上NCTF{}刚好32位,猜测字符位置对应32种纠错类型
测试了几个发现NCTF刚好对应L1,L2,L3,L4
由于网上没有找到读取纠错类型的脚本,只能配合QRbox疯狂手搓一小时
-
一个非预期
可以直接根据图片生成的时间戳来爆破
赛后复现
预期解确实没有现成的函数可以直接识别,用python读取二维码纠错的数据块,识别纠错类型
from PIL import Image
from pyzbar.pyzbar import decode
import os
def maskanalysis(img):
sign=''
for ii in range(510,670,20):
pi=img.getpixel((ii,170))
if(pi==0):
sign+='1'
if(pi==255):
sign+='0'
return sign
def scanqr(img):
decocdeQR = decode(img)
return decocdeQR[0].data.decode('ascii')
qrlist=os.listdir(r"C:\Users\22826\Desktop\qrssssssss_revenge")
flag=[0]*32
masklist=['11000100','11110011','10101010','10011101','00101111','00011000','01000001','01110110','00010010','00100101','01111100','01001011','11111001','11001110','10010111','10100000','01011111','01101000','00110001','00000110','10110100','10000011','11011010','11101101','10001001','10111110','11100111','11010000','01100010','01010101','00001100','00111011']
for i in qrlist:
img=Image.open(r"C:\Users\22826\Desktop\qrssssssss_revenge\{}".format(i))
qrmask=maskanalysis(img)
for j in range(32):
if(masklist[j]==qrmask):
flag[j]=scanqr(img)
print(''.join(flag))
NCTF{737150-eeb-465-e91-110a8fb}
qrssssssss_revenge
同样思路如上题,只是把时间的非预期给去掉了
NCTF{62130783efd44b3692b4ddbecf}
炉边聚会
听说炉石传说快关服了,zys很难过,决定在最后的时间里再组一套卡组玩玩,你能找到藏在里面的flag吗?
打开得到一串base64,根据题目描述搜索发现是炉石的卡组代码
AAEDAZoFKIwGngXIBrwFzgnQBfIHygf0CIgJkAi+BogJ1gjMCPIHtgeeBeAD6AfyB7YHvgbgA+AD4AO2B7wFkgnMCMwI+ga2B/QImgi6BJAIiAn2BOIJAAA=
参考链接:炉石传说卡组代码组成结构分析 - 知乎 (zhihu.com)
队里师傅的脚本:
import base64
from Crypto.Util.number import *
c = "AAEDAZoFKIwGngXIBrwFzgnQBfIHygf0CIgJkAi+BogJ1gjMCPIHtgeeBeAD6AfyB7YHvgbgA+AD4AO2B7wFkgnMCMwI+ga2B/QImgi6BJAIiAn2BOIJAA=="
c=base64.b64decode(c)
a1=''
a2=[]
for i in c:
a1+=(str(bin(i)[2:].zfill(8)))
a1=a1+'0'*4
for j in range(len(a1)//8+1):
a2.append(a1[j*8:(j+1)*8])
a2=a2[7:]
a4=[]
for k in range(len(a2)//2):
a4.append(a2[k*2:(k+1)*2])
a4=a4[:-1]
for i in range(len(a4)):
a5=''
for j in range(8):
l=a4[i][1][j]
if(l=='1'):
a5+=a4[i][1][j:]
break
a5+=a4[i][0][1:]
o=str(int(a5,2))[:-1]
print(long_to_bytes(o))
出题人给的脚本:
fflag=['10001100','00000110','10011110','00000101','11001000','00000110','10111100','00000101','11001110','00001001','11010000','00000101','11110010','00000111','11001010','00000111','11110100','00001000','10001000','00001001','10010000','00001000','10111110','00000110','10001000','00001001','11010110','00001000','11001100','00001000','11110010','00000111','10110110','00000111','10011110','00000101','11100000','00000011','11101000','00000111','11110010','00000111','10110110','00000111','10111110','00000110','11100000','00000011','11100000','00000011','11100000','00000011','10110110','00000111','10111100','00000101','10010010','00001001','11001100','00001000','11001100','00001000','11111010','00000110','10110110','00000111','11110100','00001000','10011010','00001000','10111010','00000100','10010000','00001000','10001000','00001001','11110110','00000100','11100010','00001001','00000000','00000000']
for i in range(40):
flag=fflag[2*i+1]+fflag[2*i][1:-1]+fflag[2*i][-1]
fla=int(flag,2)
fl=fla//10
print(chr(fl),end='')
甚至解法三:
python有个库就叫hearthstone,直接用就好了
from hearthstone.deckstrings import Deck
deck = Deck.from_deckstring('AAEDAZoFKIwGngXIBrwFzgnQBfIHygf0CIgJkAi+BogJ1gjMCPIHtgeeBeAD6AfyB7YHvgbgA+AD4AO2B7wFkgnMCMwI+ga2B/QImgi6BJAIiAn2BOIJAAA=')
for card in deck.cards:
flag_part = int(card[0] / 10)
print(chr(flag_part), end='')
NCTF{HearthStone_C0de_S000_FunnY_ri9ht?}
zystego
文件尾可以找到一个zip,提取出来后爆破密码是114514
flag.txt循环解base64可以得到一个假的flag
NCTF{1t_1s_N0t_th@t_s1mpL3_S0_th1s_1s_A_F@k3_f1a9_L0L}
zip里另一个东西是pgp的私钥
放大图片发现右侧有一段不正常的东西
而图片像素也是不正常的515*512,将这串东西的RGB提取出来,发现全是5的倍数
多次尝试之后发现以除以5后的结果的奇偶,即能否被10整除读取二进制可以得到一个加密脚本
是一个简单的dct算法,末尾给了一个key,猜测是gpg算法的密钥
import secret
丁真 = np.float32(cv2.imread(r"C:\Users\16334\Desktop\fadian.png", 1))
for i in range(64):
for j in range(64):
芝士 = randint(0,2)
小马珍珠 = 丁真[:, :, 芝士]
雪豹 = cv2.dct(小马珍珠[8*i:8*i+8, 8*j:8*j+8])
if(secret[i*64+j] == '1'):
雪豹[7,7] = 20
elif(secret[i*64+j] == '0'):
雪豹[7,7] = -20
小马珍珠[8*i:8*i+8, 8*j:8*j+8] = cv2.idct(雪豹)
丁真[:, :, 芝士] = 小马珍珠
cv2.imwrite(r"C:\Users\16334\Desktop\fd.png", 丁真)
#a gift for you : %$#%$#jhgasdfg76342t........................
尝试打印[7,7]位置可以看出数据有略微偏差
偏差数据最大不超过10,用正负十作为条件根据逻辑写对应的解密脚本
import numpy as np
import cv2
丁真 = np.float32(cv2.imread(r"1.png", 1))
for i in range(64):
for j in range(64):
for 芝士 in range(3):
小马珍珠 = 丁真[:, :, 芝士]
雪豹 = cv2.dct(小马珍珠[8*i:8*i+8, 8*j:8*j+8])
#print(雪豹[7,7])
if(雪豹[7,7] > 10):
print(1,end='')
elif(雪豹[7,7] < -10):
print(0,end='')
#a gift for you : %$#%$#jhgasdfg76342t........................
得到一个zip,解开后得到pgp加密文件
放kali里面直接解
NCTF{zys_1s_s0_V3g3T@13lE_qwq}