BJDCTF2020

2024-02-28 20:10:23 浏览数 (2)

MISC

1 签到

一个简单的隐写题目, 压缩包里面有个hello.zip,用winhex打开,可以知道这是一张图片,改成png,打开发现是一个二维码,扫二维码得到flag:xaflag{i_am_a_tupian}

2 藏藏藏

binwalk发现zip压缩包,使用foremost分离然后解压,得到福利.docx,打开里面又一个二维码,扫码得到flag{you are the best!}

3 认真你就输了

解压出来xls,binwalk分离文件得到flag.txt,打开得到flag:flag{M9eVfi2Pcs#}

4 你猜我是个啥

是一个无法打开的zip压缩包,file命令查看发现是个png图片,直接cat即可得到flag.

5 鸡你太美

GIF89a这个文件头丢失,winhex打开,填上4个字节,修复文件头,得到flag

6 纳尼

和上一个题一样,还是缺了4位二进制数,打开winhex修复gif文件头,补充47,49,46,38,然后把 gif 不同帧连起来得到一个base64,Q1RGe3dhemdfYmFvX3FpYW5nX2lzX3NhZH0=解密后得到一段有问题的flag。CTF{wazg_bao_qiang_is_sad}这个实际上有点问题,我怀疑是我输入出错了CTF{wang_bao_qiang_is_sad}

王宝强很悲伤。

7 just a rar

解压出来一个rar名称为 4 位数,爆破得到密码:2016,一张青雉的图片,用 stegsolve 打开使用 Analyse 分析,找到flag {Wadf_123}

8 一叶障目

png 的 CRC 校验问题,图片的宽高被改了导致无法打开,这里有我之前在一个ctf地图平台上找到了一个脚本。

代码语言:javascript复制
import binascii
import struct
import sys
file = input("图片地址:")
fr = open(file,'rb').read()
data: bytearray = bytearray(fr[0x0c:0x1d])
crc32key = eval('0x' str(binascii.b2a_hex(fr[0x1d:0x21]))[2:-1])
#原来的代码: crc32key = eval(str(fr[29:33]).replace('\x','').replace("1b'",'0x').replace("'",''))
n = 4095
for w in range(n):
    width = bytearray(struct.pack('>i', w))
    for h in range(n):
        height = bytearray(struct.pack('>i', h))
        for x in range(4):
            data[x 4] = width[x]
            data[x 8] = height[x]
        crc32result = binascii.crc32(data) & 0xffffffff
        if crc32result == crc32key:
            print(width,height)
            newpic = bytearray(fr)
            for x in range(4):
                newpic[x 16] = width[x]
                newpic[x 20] = height[x]
            fw = open(file '.png','wb')
            fw.write(newpic)
            fw.close

得到flag xaflag{66666}

CRYPTO

1 签到

十六进制转字符串即可得flag BJD{We1c0me_t4_BJDCTF}

2 编码与调制

本题灵感来自2019年第三届i春秋的11月月赛,主要是想对曼切斯特编码进行考察,其中为了提供一下思路,给了一张code的图片作为提示,当然也可以直接自行百度这种编码方式,毕竟他的编码方式也很有特点,仅采用了4种字符,百度一下也可以找到解决方案 编码规则,直接复制的百度百科 在曼彻斯特编码中,每一位的中间有一跳变,位中间的跳变既作时钟信号,又作数据信号;从高到低跳变表示“1”,从低到高跳变表示“0”。还有一种是差分曼彻斯特编码,每位中间的跳变仅提供时钟定时,而用每位开始时有无跳变表示“0”或“1”,有跳变为“0”,无跳变为“1”。 编程思路: 而我们在编程实现时,也很简单只要先将明文转成二进制(也就是先进行NRZ编码),而后对于其中的高电平‘1’,用‘10’替换,低电平‘0’,用‘01’替换,获得一串新的二进制比特流,最后再将其进行16进制封装即可 解码思路: 解码也就是一个逆过程,先将hex转成bin,在一步步替换‘10’为‘1’,‘01’为‘0’ 下面给出解密脚本:

直接放官方的答案吧

代码语言:javascript复制
msg=0x2559659965656a9a65656996696965a6695669a9695a699569666a5a6a6569666a59695a69aa696569666aa6
s=bin(msg)[2:]
r=""
for i in range(len(s)/2):
    if s[i*2:i*2 2] == '10':
        r  = '1'
    else:
        r  = '0'
print(hex(int(r,2))[2:-1].decode('hex'))

**BJD{DifManchestercode} **

3 Polybius

密文:ouauuuoooeeaaiaeauieuooeeiea hint:VGhlIGxlbmd0aCBvZiB0aGlzIHBsYWludGV4dDogMTQ= 首先将hint base64解密查看提示:The length of this plaintext: 14 而后再观察一下发现密文长度时28位,所以猜测是棋盘密码(额,其实题目就已经提示加密方式了) 观察发现一共有五个字母重复出现在密文中,所以可能的加密表是aeiou,但是解出结果会发现是乱码,所以可以尝试爆破,一共也就5!种情况。

代码语言:javascript复制
import itertools
key = []
cipher = "ouauuuoooeeaaiaeauieuooeeiea"
for i in itertools.permutations('aeiou', 5):
    key.append(''.join(i))
for each in key:
    temp_cipher = ""
    result = ""
    for temp in cipher:
        temp_cipher  = str(each.index(temp))          
#这里其实是将字母的表换成数字的表以便后续计算
    for i in range(0,len(temp_cipher),2):
        current_ascii = int(temp_cipher[i])*5 int(temp_cipher[i 1]) 97     
#因为棋盘密码是采用两位一起表示一个字母
        if current_ascii>ord('i'):
            current_ascii =1
        result  = chr(current_ascii)
    if "flag" in result:
        print(each,result)

得到flag **BJD{flagispolybius} **

4 easyrsa

很简单的一个rsa,就是再求取欧拉函数是对于(p-1)(q-1)的获取要先进行一步转换,题中给出了p和q的关系式,及一个求导的过程,化简后可以得出z=p^2 q^2,最后再根据n=p * q,即可得出(p-1)*(q-1) 下面是exp:

代码语言:javascript复制
# -*- coding:utf-8 -*-
#!/usr/bin/python
import gmpy2
from Crypto.Util.number import long_to_bytes
n=15310745161336895413406690009324766200789179248896951942047235448901612351128459309145825547569298479821101249094161867207686537607047447968708758990950136380924747359052570549594098569970632854351825950729752563502284849263730127586382522703959893392329333760927637353052250274195821469023401443841395096410231843592101426591882573405934188675124326997277775238287928403743324297705151732524641213516306585297722190780088180705070359469719869343939106529204798285957516860774384001892777525916167743272419958572055332232056095979448155082465977781482598371994798871917514767508394730447974770329967681767625495394441
z=32115748677623209667471622872185275070257924766015020072805267359839059393284316595882933372289732127274076434587519333300142473010344694803885168557548801202495933226215437763329280242113556524498457559562872900811602056944423967403777623306961880757613246328729616643032628964072931272085866928045973799374711846825157781056965164178505232524245809179235607571567174228822561697888645968559343608375331988097157145264357626738141646556353500994924115875748198318036296898604097000938272195903056733565880150540275369239637793975923329598716003350308259321436752579291000355560431542229699759955141152914708362494482
c=7922547866857761459807491502654216283012776177789511549350672958101810281348402284098310147796549430689253803510994877420135537268549410652654479620858691324110367182025648788407041599943091386227543182157746202947099572389676084392706406084307657000104665696654409155006313203957292885743791715198781974205578654792123191584957665293208390453748369182333152809882312453359706147808198922916762773721726681588977103877454119043744889164529383188077499194932909643918696646876907327364751380953182517883134591810800848971719184808713694342985458103006676013451912221080252735948993692674899399826084848622145815461035
e=65537
p_and_q_square = z   2*n #这个要通过化简一下z就可以发现其中的关系,其实就是简单的导数化简
p_and_q = gmpy2.iroot(p_and_q_square,2)
#(mpz(250474028594377426111821218884061933467907597574578255066146260367094595399741196827532923836761733594976933366636149201492628708413319929361097646526652140204561542573663223469009835925309935515892458499676903149172534494580503088868430625144808189083708827363335045028702993282231537893799541685169911232442), True)
final_p_and_q = 250474028594377426111821218884061933467907597574578255066146260367094595399741196827532923836761733594976933366636149201492628708413319929361097646526652140204561542573663223469009835925309935515892458499676903149172534494580503088868430625144808189083708827363335045028702993282231537893799541685169911232442
Euler_function = n - final_p_and_q   1
d = int(gmpy2.invert(e,Euler_function))
m=pow(c,d,n)
print(long_to_bytes(m))
5 rsa_output

题目描述直接给出,模的相关攻击,再看一下给出的附件,发现两次的N是相同的,所以可以确定是共模攻击

代码语言:javascript复制
from Crypto.Util.number import long_to_bytes
import gmpy2
n = 21058339337354287847534107544613605305015441090508924094198816691219103399526800112802416383088995253908857460266726925615826895303377801614829364034624475195859997943146305588315939130777450485196290766249612340054354622516207681542973756257677388091926549655162490873849955783768663029138647079874278240867932127196686258800146911620730706734103611833179733264096475286491988063990431085380499075005629807702406676707841324660971173253100956362528346684752959937473852630145893796056675793646430793578265418255919376323796044588559726703858429311784705245069845938316802681575653653770883615525735690306674635167111
e1 = 2767

e2 = 3659

message1 = 20152490165522401747723193966902181151098731763998057421967155300933719378216342043730801302534978403741086887969040721959533190058342762057359432663717825826365444996915469039056428416166173920958243044831404924113442512617599426876141184212121677500371236937127571802891321706587610393639446868836987170301813018218408886968263882123084155607494076330256934285171370758586535415136162861138898728910585138378884530819857478609791126971308624318454905992919405355751492789110009313138417265126117273710813843923143381276204802515910527468883224274829962479636527422350190210717694762908096944600267033351813929448599

message2 = 11298697323140988812057735324285908480504721454145796535014418738959035245600679947297874517818928181509081545027056523790022598233918011261011973196386395689371526774785582326121959186195586069851592467637819366624044133661016373360885158956955263645614345881350494012328275215821306955212788282617812686548883151066866149060363482958708364726982908798340182288702101023393839781427386537230459436512613047311585875068008210818996941460156589314135010438362447522428206884944952639826677247819066812706835773107059567082822312300721049827013660418610265189288840247186598145741724084351633508492707755206886202876227
# s & t
gcd, s, t = gmpy2.gcdext(e1, e2)
if s < 0:
    s = -s
    message1 = gmpy2.invert(message1, n)
if t < 0:
    t = -t
    message2 = gmpy2.invert(message2, n)
plain = gmpy2.powmod(message1, s, n) * gmpy2.powmod(message2, t, n) % n
print(plain)
print(long_to_bytes(plain))
8 伏羲六十四卦

套娃题目,这个是哪个人才像出来的?

伏羲六十四卦: 题目中给出了几段描述,大致可以猜测一下可能会有多层加密 首先一开始提到六十四卦,百度一下,可以看到其实是利用六位二进制对文字进行替换,根据其二进制矩阵先构造码表,然后根据码表将密文转成二进制:

代码语言:javascript复制
enc='升随临损巽睽颐萃小过讼艮颐小过震蛊屯未济中孚艮困恒晋升损蛊萃蛊未济巽解艮贲未济观豫损蛊晋噬嗑晋旅解大畜困未济随蒙升解睽未济井困未济旅萃未济震蒙未济师涣归妹大有'
mydisc={'坤': '000000', '剥': '000001', '比': '000010', '观': '000011', '豫': '000100', '晋': '000101', '萃': '000110', '否': '000111', '谦': '001000', '艮': '001001', '蹇': '001010', '渐': '001011', '小过': '001100', '旅': '001101', '咸': '001110', '遁': '001111', '师': '010000', '蒙': '010001', '坎': '010010', '涣': '010011', '解': '010100', '未济': '010101', '困': '010110', '讼': '010111', '升': '011000', '蛊': '011001', '井': '011010', '巽': '011011', '恒': '011100', '鼎': '011101', '大过': '011110', '姤': '011111', '复': '100000', '颐': '100001', '屯': '100010', '益': '100011', '震': '100100', '噬嗑': '100101', '随': '100110', '无妄': '100111', '明夷': '101000', '贲': '101001', '既济': '101010', '家人': '101011', '丰': '101100', '离': '101101', '革': '101110', '同人': '101111', '临': '110000', '损': '110001', '节': '110010', '中孚': '110011', '归妹': '110100', '睽': '110101', '兑': '110110', '履': '110111', '泰': '111000', '大畜': '111001', '需': '111010', '小畜': '111011', '大壮': '111100', '大有': '111101', '夬': '111110', '乾': '111111'}
keys=['坤', '剥', '比', '观', '豫', '晋', '萃', '否', '谦', '艮', '蹇', '渐', '小过', '旅', '咸', '遁', '师', '蒙', '坎', '涣', '解', '未济', '困', '讼', '升', '蛊', '井', '巽', '恒', '鼎', '大过', '姤', '复', '颐', '屯', '益', '震', '噬嗑', '随', '无妄', '明夷', '贲', '既济', '家人', '丰', '离', '革', '同人', '临', '损', '节', '中孚', '归妹', '睽', '兑', '履', '泰', '大畜', '需', '小畜', '大壮', '大有', '夬', '乾']
def decrypt():
    global mingwen
    mingwen=enc
    for each in keys:
        mingwen=mingwen.replace(each,mydisc[each])
    print(mingwen)

第二层:下一步就是将二进制转换成ASCII:

第三层:发现是base64,再解密:发现是一段奇怪的密文,此时附件中的py文件中有提示是加密的源码,分析发现是第四和第五层的加密方式,第四层这里我们可以发现,这里是采用一个偏移量为5并且依次后移一位的加密,这里只要将减换成加即可。

代码语言:javascript复制
enc='n]h]kka[[eiWW_R`bO]]`NMUWWIFXHUCP'
temp=''
offset=5
for i in range(len(enc)):
    temp =chr(ord(enc[i]) offset i)

得到解密后结果: Scodfuvmhityhirfuxfuvziiruvigzkyhv 而后再是第五层:这里采用了仿射密码,根据加密方式写一下解密脚本即可

代码语言:javascript复制
string = 'scodfuvmhityhirfuxfuvziiruvigzkyhv'
b=7
for i in (1,9,21,15,3,7,23,19,11,5,17,25):
    flag = ''
    for k in string:
        flag  = chr(i*((ord(k)-ord('a'))-b)& ord('a'))
    print(i,':',flag)

最终得到flag: 加上格式即可:BJD{bjdcongratulationsongettingtheflag}

0 人点赞