BUUCTF刷题记录

目录

[AFCTF2018]你听过一次一密么?

[AFCTF2018]花开藏宝地 

[AFCTF2018]你听过一次一密么?

题目:

一次一密?新的东西,学习一波:大佬 

Many-Time-Pad 攻击:假设明文有i部分,分别为M1、M2......Mi,对应密文也有i部分,分别对应为C1、C2......Ci。 密钥为k。加密过程为:Ci = Mi ^ k(异或)

根据异或运算的性质,有:

Ci ^ Cj = (Mi ^ k) ^ (Mj ^ k) = Mi ^ Mj ^ k ^ k = Mi ^ Mj(相同为0,不同为1;与0异或等于其本身)

即两密文异或等于对应两明文异或

我们试着用C1与其它密文进行异或,仅打印出字母来:

c = [eval('0x'+ x.strip()) for x in open('C:\\Users\\lenovo\\Desktop\\Problem.txt', 'r').readlines()]
m1 = c[0]
for i in range(1,len(c)):
    temp = hex(m1 ^ c[i])[2:]
    for i in range(0,len(temp),2):
        pd = chr(eval('0x'+temp[i:i+2]))
        if pd.isalpha():
            print(pd,end = '')
        else:
            print('.',end= '')
    print()

得到:

....S....N.U.....A..M.N..
...Ro..I...I....SE....P.I
.E..H...IN..H...........T
..A.H.R.....E....P......E
...RT...E...M....M....A.L
d...V..I..DNEt........K.D
.......I....K..I.ST...TiS
.....f...N.I........M.O..
.........N.I...I.S.I..I..
....K.......o...QA...A...

这样看不出什么规则,来看ASCII码:

#0x20 为空格
#0x20~0x7E 为可打印字符
#0x30~0x39 为数字
#0x41~0x5A 为大写字母A~Z
#0x61~0x7A 为小写字母a~z

发现,小写字母 ^ 空格,得到对应的大写字母;大写字母 ^ 空格,得到对应的小写字母。所以,如果两者异或得到了字母,那么很大可能有一个是空格。对照着上面异或的结果,可以知道,如果结果的某一列出现了很多字母,那么在C1对应的位置大概率就是空格

再来回头看上面 C1 xor 其他密文——也就等于 M1 xor 其他明文的表,如果第 col 列存在大量的英文字母,我们可以猜测 M1[col] 是一个空格。那一列英文字母越多,把握越大。

知道 M1 的 col 位是空格有什么用呢?别忘了异或运算下,x 的逆元是其自身。所以Mi[col]=M1[col]⊕Mi[col]⊕M1[col]=M1[col]⊕Mi[col]⊕0x20

于是,只要知道某个字符串的某一位是空格,我们就可以恢复出所有明文在这一列的值

对于每一条密文Ci,拿去异或其他所有密文。然后去数每一列有多少个英文字符,作为“Mi在这一位是空格”的评分。

这部分还看不太懂,先摘抄着。

代码:

import Crypto.Util.strxor as xo
import libnum, codecs, numpy as np

def isChr(x):
    if ord('a') <= x and x <= ord('z'): return True
    if ord('A') <= x and x <= ord('Z'): return True
    return False

def infer(index, pos):
    if msg[index, pos] != 0:
        return
    msg[index, pos] = ord(' ')
    for x in range(len(c)):
        if x != index:
            msg[x][pos] = xo.strxor(c[x], c[index])[pos] ^ ord(' ')

dat = []

def getSpace():
    for index, x in enumerate(c):
        res = [xo.strxor(x, y) for y in c if x!=y]
        f = lambda pos: len(list(filter(isChr, [s[pos] for s in res])))
        cnt = [f(pos) for pos in range(len(x))]
        for pos in range(len(x)):
            dat.append((f(pos), index, pos))

c = [codecs.decode(x.strip().encode(), 'hex') for x in open('C:\\Users\\lenovo\\Desktop\\Problem.txt', 'r').readlines()]

msg = np.zeros([len(c), len(c[0])], dtype=int)

getSpace()

dat = sorted(dat)[::-1]
for w, index, pos in dat:
    infer(index, pos)

print('\n'.join([''.join([chr(c) for c in x]) for x in msg]))

不知道为什么报了Only byte strings of equal length can be xored的错误😶,菜鸟无奈

得到:

Dear Friend, T%is tim< I u
nderstood my m$stake 8nd u
sed One time p,d encr ptio
n scheme, I he,rd tha- it 
is the only en.ryptio7 met
hod that is ma9hemati:ally
 proven to be #ot cra:ked 
ever if the ke4 is ke)t se
cure, Let Me k#ow if  ou a
gree with me t" use t1is e
ncryption sche e alwa s...

进行修正,T%is->This,tim<->time......,得到明文:

Dear Friend, This time I u
nderstood my mistake and u
sed One time pad encryptio
n scheme, I heard that it 
is the only encryption met
hod that is mathematically
 proven to be not cracked 
ever if the key is kept se
cure, Let Me know if you a
gree with me to use this e
ncryption scheme always...

取一行与密文对应异或即得到密钥key:

ming = 'Dear Friend, This time I '.encode()#删去最后一个,不然不等长
mi = b'%\x03\x02\x06F==911U_\x7f\x1d\x06\x1d@R\x11\x1a\x19TN.]'
#print(len(ming),len(mi))
flag = xo.strxor(ming,mi)
print(flag)

得到flag:afctf{OPT_1s_Int3rest1ng}

总结

代码水平太烂了,多练吧。

思路代码参考:

https://www.ruanx.net/many-time-pad/

http://t.csdn.cn/T0FQe

[AFCTF2018]花开藏宝地 

给了5个压缩包和一个题面:

根据提示,依次爆破得到内容。

第一位提示生日,那从1900000开始

第二位提示名字,且标出了小,那肯定是小写字符串了 

第三位同理,只不过是大写

第四位说锁坏了,个人觉得意思就是没加密,直接压缩得到,大佬们说是伪加密😶

第五位提示隐身,tar里头是个空文件,不晓得怎么得到真正的数据,回看题面,只要搜集3份就可以获得宝藏的地址。我想着应该不要都知道吧,试一试。

解密过后,得到4组数据:

x1 = 305345133911395218573790903508296238659147802274031796643017539011648802808763162902335644195648525375518941848430114497150082025133000033835083076541927530829557051524161069423494451667848236452337271862085346869364976989047180532167560796470067549915390773271207901537847213882479997325575278672917648417868759077150999044891099206133296336190476413164240995177077671480352739572539631359
m1 = 347051559622463144539669950096658163425646411435797691973701513725701575100810446175849424000000075855070430240507732735393411493866540572679626172742301366146501862670272443070970511943485865887494229487420503750457974262802053722093905126235340380261828593508455621667309946361705530667957484731929151875527489478449361198648310684702574627199321092927111137398333029697068474762820813413

x2 = 152012681270682340051690627924586232702552460810030322267827401771304907469802591861912921281833890613186317787813611372838066924894691892444503039545946728621696590087591246339208248647926966446848123290344911662916758039134817404720512465817867255277476717353439505243247568126193361558042940352204093381260402400739429050280526212446967632582771424597203000629197487733610187359662268583
m2 = 347051559622463144539669950096658163425646411435797691973701513725701575100810446175849424000000075855070430240507732735393411493866540572679626172742301366146501862670272443070970511943485865887494229487420503750457974262802053722093905126235340380261828593508455621667309946361705530667957484731929151875527489478449361198648310684702574627199321092927111137398333029697068474762820818553

x3 = 40952412095267791829743119118333311932687870987919948671780408726886151430242690997238831410249436653299224291445012397813221016909468630372862610415470277301591535416193017906909638241212666990959976187895288689640250810487806568164431359887246760313154046201720715301307811951233077581047872827004824833876458687145628724339714212107812941785880896399800008924818580623979723496070665230
m3 = 347051559622463144539669950096658163425646411435797691973701513725701575100810446175849424000000075855070430240507732735393411493866540572679626172742301366146501862670272443070970511943485865887494229487420503750457974262802053722093905126235340380261828593508455621667309946361705530667957484731929151875527489478449361198648310684702574627199321092927111137398333029697068474762820819351

x4 = 100459779913520540098065407420629954816677926423356769524759072632219106155849450125185205557491138357760494272691949199099803239098119602186117878931534968435982565071570831032814288620974807498206233914826253433847572703407678712965098320122549759579566316372220959610814573945698083909575005303253205653244238542300266460559790606278310650849881421791081944960157781855164700773081375247
m4 = 347051559622463144539669950096658163425646411435797691973701513725701575100810446175849424000000075855070430240507732735393411493866540572679626172742301366146501862670272443070970511943485865887494229487420503750457974262802053722093905126235340380261828593508455621667309946361705530667957484731929151875527489478449361198648310684702574627199321092927111137398333029697068474762820820091

搞不懂了,看了大佬的wp后,知道了新的东西:门限方案。而门限方案有很多种,这一题的题目花开(bloom)提示是bloom门限方案,参考大佬脚本吧:

a1 =100459779913520540098065407420629954816677926423356769524759072632219106155849450125185205557491138357760494272691949199099803239098119602186117878931534968435982565071570831032814288620974807498206233914826253433847572703407678712965098320122549759579566316372220959610814573945698083909575005303253205653244238542300266460559790606278310650849881421791081944960157781855164700773081375247
d1 =347051559622463144539669950096658163425646411435797691973701513725701575100810446175849424000000075855070430240507732735393411493866540572679626172742301366146501862670272443070970511943485865887494229487420503750457974262802053722093905126235340380261828593508455621667309946361705530667957484731929151875527489478449361198648310684702574627199321092927111137398333029697068474762820820091
a2 =305345133911395218573790903508296238659147802274031796643017539011648802808763162902335644195648525375518941848430114497150082025133000033835083076541927530829557051524161069423494451667848236452337271862085346869364976989047180532167560796470067549915390773271207901537847213882479997325575278672917648417868759077150999044891099206133296336190476413164240995177077671480352739572539631359
d2 =347051559622463144539669950096658163425646411435797691973701513725701575100810446175849424000000075855070430240507732735393411493866540572679626172742301366146501862670272443070970511943485865887494229487420503750457974262802053722093905126235340380261828593508455621667309946361705530667957484731929151875527489478449361198648310684702574627199321092927111137398333029697068474762820813413
a3 = 152012681270682340051690627924586232702552460810030322267827401771304907469802591861912921281833890613186317787813611372838066924894691892444503039545946728621696590087591246339208248647926966446848123290344911662916758039134817404720512465817867255277476717353439505243247568126193361558042940352204093381260402400739429050280526212446967632582771424597203000629197487733610187359662268583
d3 =347051559622463144539669950096658163425646411435797691973701513725701575100810446175849424000000075855070430240507732735393411493866540572679626172742301366146501862670272443070970511943485865887494229487420503750457974262802053722093905126235340380261828593508455621667309946361705530667957484731929151875527489478449361198648310684702574627199321092927111137398333029697068474762820818553

dd = d1*d2*d3
t1 = pow(dd//d1,d1-2,d1)
assert(t1*d2*d3%d1 == 1)
t2 = pow(dd//d2,d2-2,d2)
assert(t2*d1*d3%d2 == 1)
t3 = pow(dd//d3,d3-2,d3)
assert(t3*d2*d1%d3 == 1)
s = a1*t1*d2*d3+a2*t2*d1*d3+a3*t3*d1*d2
p = 80804238007977405688648566160504278593148666302626415149704905628622876270862865768337953835725801963142685182510812938072115996355782396318303927020705623120652014080032809421180400984242061592520733710243483947230962631945045134540159517488288781666622635328316972979183761952842010806304748313326215619695085380586052550443025074501971925005072999275628549710915357400946408857
s %= dd
# print(hex(s))
s %= p
s = hex(s)[2:]
flag = list(bytearray.fromhex(s))
for i in flag:
    print(chr(i),end="")
A treasure map is a map that marks the location of buried treasure, a lost mine, a valuable secret or a hidden locale. So flag is afctf{1sn't_s0_int3Resting}.

果然只需要3组数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值