easyxor

核心加密算法convert就是四个shift,写个逆就行,flag被分为两部分,前半部分用OFB模式加密,后半部分用CBC模式加密,由于CBC模式的缺陷,当我们只考虑最后一块时,将倒数第二块作为iv,凭借flag的格式做判断即可爆破出key,再利用OFB模式的漏洞,结合key与已知的flag格式即可逆推出iv,此时iv和key尽知,直接解密即可

from Crypto.Util.number import bytes_to_long, long_to_bytes
from random import randint, getrandbitsdef shift(m, k, c):if k < 0:return m ^ m >> (-k) & creturn m ^ m << k & cdef unshift(value, k, mask, bits=64):if(k == 0):return value ^ value & masktmp = valueif k < 0:for _ in range(bits // (-k)):tmp = value ^ tmp >> (-k) & maskelse:for _ in range(bits // k):tmp = value ^ tmp << k & maskassert shift(tmp, k, mask) == valuereturn tmpdef convert(m, key):c_list = [0x37386180af9ae39e, 0xaf754e29895ee11a, 0x85e1a429a2b7030c, 0x964c5a89f6d3ae8c]for t in range(4):m = shift(m, key[t], c_list[t])return mdef unconvert(m, key):tmp = mc_list = [0x37386180af9ae39e, 0xaf754e29895ee11a, 0x85e1a429a2b7030c, 0x964c5a89f6d3ae8c]for t in range(3,-1,-1):m = unshift(m, key[t], c_list[t])assert convert(m, key) == tmpreturn mdef decrypt(c, k, iv, mode='CBC'):cipher = []for i in range(0,len(c),16):cipher.append(int(c[i:i+16],16))groups = []if mode == 'CBC':cipher = cipher[::-1]last = cipher[0]for eve in (cipher[1:] + [iv]):cur_c = lastcur = unconvert(cur_c, k)groups.append(cur ^ eve)last = evegroups = groups[::-1]elif mode == 'OFB':last = ivfor eve in cipher:cur_c = convert(last, k)groups.append(cur_c ^ eve)last = cur_celse:print('Not supported now!')m = b''for i in groups:m += long_to_bytes(i)assert len(m) % 8 == 0return mflag = b'ByteCTF{'
padding = bytes_to_long(flag)
cipher = '89b8aca257ee2748f030e7f6599cbe0cbb5db25db6d3990d3b752eda9689e30fa2b03ee748e0da3c989da2bba657b912'
cipher1, cipher2 = cipher[:len(cipher) // 2], cipher[len(cipher) // 2:]
c_list = []
for i in range(0,len(cipher2),16):c_list.append(int(cipher2[i:i+16],16))def get_key():for a in range(-32,33):for b in range(-32,33):for c in range(-32,33):for d in range(-32,33):try:plain = decrypt(cipher2[-16:],[a,b,c,d],c_list[-2])if(plain.endswith(b'$$$') and plain.strip(b'$').endswith(b'}')):print(a,b,c,d,plain)return [a,b,c,d]except:continuekey = get_key()
# key = [-12, 26, -3, -31]
# print(cipher1)
c_list = []
for i in range(0,len(cipher1),16):c_list.append(int(cipher1[i:i+16],16))
E = (padding ^ c_list[0])
iv = unconvert(E, key)
# print(iv)
flag = b''
flag += (decrypt(cipher1, key, iv, mode='OFB'))
flag += (decrypt(cipher2, key, iv))print(flag.strip(b'$'))# ByteCTF{5831a241s-f30980q535af-2156547475u2t}

JustDecrypt

AES_CFB模式,只提供解密,并且使用了不安全的unpad函数,虽然iv不知道,但是iv并不会影响后续的解密,所以我们可以通过提交一个固定块来保证iv不变,但是由于有unpad的存在,我们需要知道我们解密后的结果,就需要一个至少大于256长度的尾来保证我们想要的东西不会被删掉,这里我们称为padding,所以我们先给服务器打两个过去,一来检测一下是否可用,二来调整一下服务器的iv值

接下来我们需要伪造目标字符串,根据每次的返回值算出该位密位应该是多少,逐位修改一下即可,最后计算一下padding最后一位的数值,将后面多余的部分利用unpad删掉即可


from Crypto.Util.number import bytes_to_long, long_to_bytes
from pwn import *
import hashlibPOST = '39.105.181.182'
HOST = 30001
r = remote(POST,HOST)
# context.log_level = 'debug'table = '1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'
def passpow():rev = r.recvuntil("sha256(XXXX+")suffix = r.recv(28).decode()r.recvuntil(" == ")res = r.recv(64).decode()def f(x):hashresult = hashlib.sha256((x+suffix).encode()).hexdigest()if hashresult == res:return 1else:return 0prefix = util.iters.mbruteforce(f,table,4,'upto')r.recvuntil("XXXX > ")r.sendline(str(prefix))def talk(msg):r.recvuntil("hex > ")r.sendline(msg)r.recvuntil("hex: \n")plain = r.recvline(False)# print(plain)plain = long_to_bytes(int(plain.decode(),16))return plaindef xor(a,b):assert len(a) == len(b)return bytes([i ^ j for (i,j) in zip(a,b)])aim = b"Hello, I'm a Bytedancer. Please give me the flag!"
passpow()
padding = b''
for i in range(256):padding += hex(i)[2:].zfill(2).encode()
# print(padding)
# print(cipher)
plain = talk(padding*2)
# print(plain)
# plain = talk(padding)
# print(plain)
if len(plain) <= 32:r.close()exit()
# plain = talk(b'\x00'*32 + padding)[:32]
payload = bytearray(b'\x00' * 16 * 4)
plain = plain[256:256+32]
# print(plain)for i in range(len(aim)):payload[i] = aim[i] ^ plain[i]# print(payload.hex().encode())plain = talk(payload.hex().encode() + padding)# print(plain)padnum = len(payload.hex().encode()) + len(payload) - len(plain)
padnum //= 2
# print(padnum)
length = len(plain) - len(aim)
length = length // 16
length *= 16
padding = long_to_bytes(int((padding[length*2:]).decode(),16))
payload = payload + padding
plain = talk(payload.hex())
# print(plain)
length = len(payload) - len(plain)
payload[-1] = payload[-1] ^ length ^ (len(payload) - len(aim))
plain = talk(payload.hex())
print(plain)r.recvlines(2)
flag = r.recvline(False).strip()
print(flag)
r.close()
# r.interactive()

abusedkey

阅读理解题,先从协议二构造 Qc=hc⋅QsQ_c = h_c \cdot Q_sQc​=hc​⋅Qs​ ,此时返回的两个点满足 Ys⋅hs==YcY_s \cdot h_s == Y_cYs​⋅hs​==Yc​ ,所以直接爆破 πs\pi_sπs​ 即可

再打协议一,令 Tc=−PcT_c=-P_cTc​=−Pc​ ,此时 Kcs=ds⋅TcK_cs = d_s \cdot T_cKc​s=ds​⋅Tc​ ,直接解密即可


from Crypto.Util.number import long_to_bytes
from random import getrandbits, randint
from Crypto.Cipher import AES
from hashlib import sha256
from tqdm import tqdm
from curve import *
import requestsdef talk(mode, msg):host = 'http://39.105.181.182:30000'if mode == 11:url = host + '/abusedkey/server/msg11'elif mode == 13:url = host + '/abusedkey/server/msg13'elif mode == 21:url = host + '/abusedkey/server/msg21'elif mode == 23:url = host + '/abusedkey/ttp/msg23'elif mode == 25:url = host + '/abusedkey/server/msg25'return requests.get(url,data=msg).textdef H(msg):return int(sha256(msg).hexdigest(), 16)pi_C = b'\xFF\xFF'
Curve = curve()def get_hint():r_c = randint(0,Curve.p)R_c = Curve.G * r_ch_c = H(pi_C)Q_c = h_c * R_csid2 = getrandbits(256)sid2 = hex(sid2)[2:].zfill(64)msg21 = sid2msg22 = talk(21,msg21)Q_s = msg22msg23 = str(Q_c) + Q_smsg24 = (talk(23,msg23))# print(msg24)# print(len(msg24))# print(len(msg23))Y_c, Y_s = msg24[:128], msg24[128:]# print(Y_c, Y_s)Y_c, Y_s = Point(int(Y_c[:64],16), int(Y_c[64:],16)), Point(int(Y_s[:64],16), int(Y_s[64:],16))msg25 = sid2 + str(Y_c)msg26 = talk(25,msg25)print(msg26)msg26 = long_to_bytes(int(msg26,16))# print(msg26)iv, cipher, tag = msg26[:12], msg26[12:-16], msg26[-16:]Z_cs = r_c * Y_ssk2 = long_to_bytes(H(long_to_bytes(Z_cs.x)))aes = AES.new(sk2, AES.MODE_GCM, iv)hint = aes.decrypt_and_verify(cipher, tag)print(hint)returndef get_pis():sid2 = getrandbits(256)sid2 = hex(sid2)[2:].zfill(64)msg21 = sid2msg22 = talk(21,msg21)Q_s = Point(int(msg22[:64],16), int(msg22[64:],16))h_c = H(pi_C)Q_c = h_c * Q_smsg23 = str(Q_c) + str(Q_s)msg24 = talk(23,msg23)# print(msg24)Y_c, Y_s = msg24[:128], msg24[128:]Y_c, Y_s = Point(int(Y_c[:64],16), int(Y_c[64:],16)), Point(int(Y_s[:64],16), int(Y_s[64:],16))# print(Y_c)# print(Y_s)for i in tqdm(range(0xffff + 1)):h_s = H(b'\x00' * (2 - len(long_to_bytes(i))) + long_to_bytes(i))if(Y_s * h_s == Y_c):# print(i)return long_to_bytes(i)pi_s = get_pis()
# pi_s = long_to_bytes(36727)
h_s = H(pi_s)# check pi_s
sid2 = getrandbits(256)
sid2 = hex(sid2)[2:].zfill(64)
msg21 = sid2
msg22 = talk(21,msg21)
Q_s = Point(int(msg22[:64],16), int(msg22[64:],16))
h_c = H(pi_C)
Q_c = h_c * Curve.G
Q_s = h_s * Curve.G
msg23 = str(Q_c) + str(Q_s)
msg24 = talk(23,msg23)
# print(msg24)
Y_c, Y_s = msg24[:128], msg24[128:]
Y_c, Y_s = Point(int(Y_c[:64],16), int(Y_c[64:],16)), Point(int(Y_s[:64],16), int(Y_s[64:],16))
assert(Y_c == Y_s)# solve
d_s = H(pi_s)
P_cx = int('b5b1b07d251b299844d968be56284ef32dffd0baa6a0353baf10c90298dfd117', 16)
P_cy = int('ea62978d102a76c3d6747e283091ac5f2b4c3ba5fc7a906fe023ee3bc61b50fe', 16)
P_c = Point(P_cx, P_cy)
T_c = Point(P_cx, -P_cy % Curve.p)
sid1 = getrandbits(256)
sid1 = hex(sid1)[2:].zfill(64)
msg11 = sid1
msg12 = talk(11,msg11)
msg13 = sid1 + str(T_c)
msg14 = talk(13,msg13)
# print(msg14)
msg14 = long_to_bytes(int(msg14,16))
iv, cipher, tag = msg14[:12], msg14[12:-16], msg14[-16:]
K_cs = d_s * T_c
sk1 = long_to_bytes(H(long_to_bytes(K_cs.x)))
# print(sk1, iv, cipher, tag)
cip = AES.new(sk1, AES.MODE_GCM, iv)
plaintext = cip.decrypt_and_verify(cipher, tag)
print(plaintext)

Overheard

HNP问题

依次提交ga,ga+1,ga+2...g^{a},g^{a+1},g^{a+2}...ga,ga+1,ga+2... 可得gab,g(a+1)b,g(a+2)b...g^{ab},g^{(a+1)b},g^{(a+2)b}...gab,g(a+1)b,g(a+2)b...

构造如下格子即可得出

from pwn import *
from random import*
p = 62606792596600834911820789765744078048692259104005438531455193685836606544743
g = 5
sh=remote("39.105.38.192","30000")
print(sh.recv().decode())
sh.sendline(b"1")
a=int(sh.recvuntil(b"\n",drop=True).decode())
print(sh.recv())
sh.sendline(b"2")
sh.recvuntil(b"$ ",drop=True)
b=int(sh.recvuntil(b"\n",drop=True).decode())sh.sendline(b"3")
sh.sendline(str(a).encode())
sh.recvuntil(b"Bob: ")
r=(int(sh.recvuntil(b"\n").decode()))
sh.recvuntil(b"exit\n")cnt=0
B=[]
A=[]
for i in range(1,15):sh.sendline(b"3")sh.sendline(str(a*pow(g,i,p)%p).encode())sh.recvuntil(b"Bob: ")B.append(int(sh.recvuntil(b"\n").decode()))A.append(pow(b,i,p))sh.recvuntil(b"exit\n")
M=[]
s=16
k=1
for i in range(s):l=[0]*sl[i]=p*kif(i==s-2):for j in range(s-2):l[j]=A[j]*kif(i==s-1):for j in range(s-2):l[j]=B[j]*kM.append(l)
M[-2][-2]=1
M[-1][-1]=2**60
m=M.copy()
m[-2][-2]=1/2^189
m=matrix(QQ,m)
print(m.LLL()[0][-1]//m[-1][-1]==1)
print(m.LLL()[0][-2]*2^189)
print(r)
sh.sendline(b'4')
sh.sendline(str(abs(m.LLL()[0][-2]*2^189)%p).encode())
print(sh.recvall())

ByteCTF 2021(Crypto部分)相关推荐

  1. SWPU新生赛2021 Crypto部分WriteUp

    第一波放题 crypto1 直接谷歌搜e1e2 = 3087 n = p*q,找到striving的博客,不愧是密码神 由于striving的旧博客域名已过期,因此就不放密码神的博客了 c1= 463 ...

  2. 深入了解区块链的漏洞之1:介绍篇

    在这个系列里,我们将一起学习一篇论文:https://arxiv.org/pdf/2110.12162.pdf 这篇文章作者对区块链的脆弱性,采用独特地方法论,进行深入的探讨.为我们理解或梳理区块链的 ...

  3. 【Linux系统管理】05 常用命令 06 vim编辑器

    一.命令的基本格式 1.1 命令的提示符 [root@localhost ~]# []:这是提示符的分隔符号,没有特殊含义. root:显示的是当前的登录用户,现在使用的是root用户登录. @:分隔 ...

  4. Deltix Round, Spring 2021 E. Crypto Lights 组合数学 + 推公式

    传送门 文章目录 题意: 思路: 题意: 给你nnn个灯,每次可以打开一个灯,当连续的kkk个灯有至少两个灯开着的时候停止,问最终期望能打开多少灯. 思路: 由于不想打latexlatexlatex, ...

  5. Crypto.com宣布将在2021年1月19日下架XRP

    据官方消息,瑞波币(XRP)将从其美国市场APP中下架并暂停交易.从2021年1月19日18点开始,美国客户将无法在Crypto.com应用程序中存入XRP,但提款不会受到影响. 文章链接:https ...

  6. 【ByteCTF 2022】Crypto Writeup

    ByteCTF 2022 密码 Crypto writeup Choose_U_flag Compare Card Shark 文章目录 1. Choose_U_flag 题目分析 初始化参数 加密过 ...

  7. [SWPUCTF] 2021新生赛之Crypto篇刷题记录(11)

    [SWPUCTF] 2021新生赛之Crypto篇刷题记录① [SWPUCTF 2021 新生赛]crypto6 [SWPUCTF 2021 新生赛]ez_caesar [SWPUCTF 2021 新 ...

  8. 2021【陇原战“疫”】crypto部分writeup

    这次BUUCTF月赛对我来说确实还行了,不会太难,也能学到东西,主要想说说比特翻转攻击的问题,最近这种题碰的特别多,CBC的,CFB的,GCM的,各种各样的AES模式的攻击问题,从最基本的CBC开始, ...

  9. 2021安全范儿高校挑战赛ByteCTF线上赛部分Writeup

    文章目录 MISC-Checkin MISC-Survey MISC-HearingNotBelieving MISC-frequently WEB-double sqli MISC题目附件自取 链接 ...

最新文章

  1. 【转】Python3 (入门6) 库的打包与安装
  2. 无需用眼,大脑直接成像,失明的人也能重新「看见」|Science
  3. Linux命令中的rpm安装命令
  4. 坚持是一件很难的事情
  5. windows运行linux脚本命令大全,查看和运行 Windows PowerShell 脚本
  6. [LeetCode]Distinct Subsequences,解题报告
  7. MapReduce之join操作
  8. python keyboard库_python利用 keyboard 库记录键盘事件
  9. 谷粒商城:17.商城业务 — Nginx搭建域名访问
  10. MATLAB数据拟合学习总结
  11. 缠中说禅图解分析示范
  12. 代理服务器(Proxy)
  13. 基于指纹识别技术的身份认证系统的设计与实现
  14. 计算机大二学生个人总结报告,计算机学生大二第二学期自我总结计划自我总结计划.doc...
  15. Lae程序员小漫画(二),仅供一乐
  16. 雷达回波视频预测核心问题及关键技术纪要
  17. Service pack
  18. 北大核心2020_【北大核心】中国人力资源开发2020年度重点选题
  19. 看周鸿祎麻辣点评中国互联网公司
  20. 计算机实验圆述职报告,实验员个人述职报告(三)

热门文章

  1. VMware发布新版vSphere6.5虚拟化平台,助力企业数字化转型
  2. python量化投资培训清华大学深研院_GitHub - CatsJuice/quantitative-investment-learning: 使用Python进行量化投资的学习报告...
  3. ML之回归预测:利用Lasso、ElasticNet、GBDT等算法构建集成学习算法AvgModelsR对国内某平台上海2020年6月份房价数据集【12+1】进行回归预测(模型评估、模型推理)
  4. ML之xgboost:基于xgboost(5f-CrVa)算法对HiggsBoson数据集(Kaggle竞赛)训练实现二分类预测(基于训练好的模型进行新数据预测)
  5. AI机器人:机器人语音文本智能交互之自定义软件——实现模拟中本聪与V神跨时空畅谈
  6. Python语言学习:python语言的特点、入门、基础用法之详细攻略
  7. 第八九章 正态分布与超越正态
  8. python thrift demo
  9. XJOI 3629 非严格次小生成树(pqq的礼物)
  10. phpcms黄页,不能选择行业。解决办法