湖湘杯2019两个密码题wp

  还是自己太菜的原因,这次湖湘杯只做出来4道题,然后5点的时候就放弃了去跟同学出去玩了,当时感觉进前50无望(这次湖湘杯py情况也很严重啊,可惜烽火台只报不封,挺恶心的)。不过无论如何,这次比赛还是有收获的,总结沉淀一下这两道密码学题目吧:

Oracle padding attack

  忘了这个题目是啥了,但是攻击原理就是针对CBC模式的特殊攻击方式,Oracle padding attack。详细原理可以从下面获取(介绍的很详细,强烈推荐):

https://www.freebuf.com/articles/database/151167.html

  下面简单介绍一下利用原理:

  Oracle padding attack的攻击条件还是比较苛刻的:

  1. 在给服务器返回的数据中,iv可控。(iv是对称加密中的偏移向量,不清楚的同学可以详细了解一下CBC等加密模式的原理。)
  2. 在响应数据中,攻击者可以通过报错等方式得知padding是否出错。
  3. 服务器采用对称加密算法,使用CBC模式和PCK#5填充法。(这个填充法就是在最后一组长度不足分组长度的时候,填充剩余多少字节个数,例如16字节分组中最终还剩6个,那就填充6个ascii的6)
  4. 初始的iv已知。

  在服务器解密后,被解密的明文会和iv进行异或(这个是对称加密算法中CBC加密模式的基本原理,这里不懂建议回去复习一下,方便理解),之后会进行去填充处理,一般算法库对这种去填充的实现是:

  1. 检查最后一个字节的ascii值,这里为了方便解释我们假设是6。
  2. 检查后6个字节是不是6。
  3. 如果是6,那么去掉这6个6,否则就报错或提示信息。

  这里注意:上述过程中检查的是被我们解密后,再和初始向量异或后的明文串。如果向服务器返回的iv可控,那么我们就可以通过不断改变iv的方法来通过报错达到被解密的数据串可控的目的,同时也可以任意恢复原文!我们假设分组长度为16,简述这个过程如下:

  1. 控制初始向量,前15个字符串任意,我们控制第16个字符串,从1爆破到255,不报错的那个结果肯定是使密钥解密出的明文串异或后为1。这是我们如果异或真正的初始向量,再异或1就恢复出了明文。这个明文再异或初始向量和我们期望解密的结果,那么这个串解密的结果就可控了。举个例子:假设我们爆破出的最后一个字符是0x20,原本初始向量的值是0x41,那么原本的明文串的最后一个字符就是:0x20 ^ 0x41 ^ 0x01=0x60。假设我们希望服务器解密这个串时最后一个字符是0x02,那么我们就可以调整初始向量为:0x60 ^ 0x41 ^ 0x02=0x23。
  2. 根据第一步,我们已经爆破出了分组中的最后一个明文,先控制最后一个初始向量,使其经解密后结果为0x02,然后我们再控制倒数第二个初始向量,从1爆破到255,那么不报错的那个结果肯定是使密码解密处的明文串异或后为2。这时我们以此类推,爆破倒数第三个。

  原理就是这些,这道题使用脚本攻击如下:

#enconding:utf-8
'''@Author: b0ring@MySite: https://unnamebao.github.io/@Date:     2019-11-10 12:02:53@Version:   1.0.0
'''import socket
import base64
import codecsdef num2str(i):return ("%02x"%i).encode()def postfix_str(postfix,iv,index):res_ = b""for i in range(int(len(postfix)/2)):res_ = num2str(int(postfix[len(postfix) - (i+1)*2:len(postfix)-i*2],16)^int(iv[32-(i+1)*2:32-i*2],16)^index) + res_return res_def brute_one(IV,encryp_text,client,index,postfix):for i in range(256):if index == 0:if i == IV[-1]:continueif i == 0:print("[*] append:",postfix_str(postfix,IV,index))iv = b"41"*(16-index) + num2str(i) + postfix_str(postfix,IV,index)data_to_send = iv + encryp_text + b'\n'client.send(data_to_send)data_respond = client.recv(1024)# print(i,int(iv[32-index*2:32-index*2+2],16)^int(IV[32-index*2:32-index*2+2],16),data_respond)if b"padding error" in data_respond:continueelse:return num2str(i^int(IV[32-index*2:32-index*2+2],16)^index)if __name__ == "__main__":client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)client.connect(('183.129.189.62', 13706))data = client.recv(1024)print(data)c = data.decode().split("\n")[0].replace("Hey, new! Your passport is ","")[:64]IV= c[:32].encode()encryp_text = c[32:].encode()print("[*] IV:",IV)print(type(IV))postfix = b""for index in range(0,16):one = brute_one(IV,encryp_text,client,index+1,postfix)postfix = one + postfixprint("[*] postfix:",postfix)print('-----------------------------')payload = b""admin = b"Admin"for i in range(5):payload += num2str(admin[i] ^ int(postfix[i*2:i*2+2],16) ^ int(IV[i*2:i*2+2],16))for i in range(5,16):payload += num2str(11 ^ int(postfix[i*2:i*2+2],16) ^ int(IV[i*2:i*2+2],16))print(type(payload))print(payload)print(len(payload))payload += encryp_text + b'\n'client.send(payload)print(client.recv(1024))

Easy RSA

  首先看一下题目吧:

from Crypto.Util.number import *
import libnum
import gmpy2flag = open("flag.txt","rb").read()
m=libnum.s2n(flag)
p=getPrime(1024)
q=getPrime(1024)
n=p*q
e=65537
c=pow(m,e,n)
phi=(p-1)*(q-1)
d=gmpy2.invert(e,phi)
dp=d%(p-1)
print dp,n,e,c#84373069210173690047629226878686144017052129353931011112880892379361035492516066159394115482289291025932915787077633999791002846189004408043685986856359812230222233165493645074459765748901898518115384084258143483508823079115319711227124403284267559950883054402576935436305927705016459382628196407373896831725 22000596569856085362623019573995240143720890380678581299411213688857584612953014122879995808816872221032805734151343458921719334360194024890377075521680399678533655114261000716106870610083356478621445541840124447459943322577740268407217950081217130055057926816065068275999620502766866379465521042298370686053823448099778572878765782711260673185703889168702746195779250373642505375725925213796848495518878490786035363094086520257020021547827073768598600151928787434153003675096254792245014217044607440890694190989162318846104385311646123343795149489946251221774030484424581846841141819601874562109228016707364220840611 65537 14874271064669918581178066047207495551570421575260298116038863877424499500626920855863261194264169850678206604144314318171829367575688726593323863145664241189167820996601561389159819873734368810449011761054668595565217970516125181240869998009561140277444653698278073509852288720276008438965069627886972839146199102497874818473454932012374251932864118784065064885987416408142362577322906063320726241313252172382519793691513360909796645028353257317044086708114163313328952830378067342164675055195428728335222242094290731292113709866489975077052604333805889421889967835433026770417624703011718120347415460385182429795735

  我们从中提取一些信息:

m = flag # m中的值是flag的明文串
n = p * q # 这个很清晰 学过RSA应该理解
e = 65537 # 提醒下,65537是个质数,虽然好像是不是质数无所谓
c = pow(m,e,n) # 这里就是典型的RSA加密了,如果已知d,可以通过 m = pow(c,d,n)解出明文,其中,(e,n)是公钥,d是私钥。
phi = (p-1)*(q-1) # 这里计算了n的欧拉函数,解释一下,欧拉函数是小于一个数有多少与其互质的数,质数的欧拉函数就是自身减一,而两个质数相乘的数,它的欧拉函数就是两个质数相加减一相乘
d = gmpy2.invert(e,phi) # 这里就是求同余phi下与e互质的数,就是私钥d
dp = d % (p-1) # 就是d对(p-1)求余

  梳理一下:

e,c,n已知,dp = d % (p-1)已知,求m

  这个地方涉及到一个原理:

对于任意因子a、b(不需要是质数),x=a∗bx=a*bx=a∗b,如果c≡mmodxc \equiv m \mod xc≡mmodx,那么 c≡mmodac \equiv m \mod ac≡mmoda和c≡mmodbc \equiv m \mod bc≡mmodb 都成立。
举个例子来理解: 16≡1mod1516 \equiv 1 \mod 1516≡1mod15
那么 16≡1mod316 \equiv 1 \mod 316≡1mod3,16≡1mod516 \equiv 1 \mod 516≡1mod5

  而我们知道,d和e在同余phi下是互逆的,所以:

d∗e≡1modphid*e \equiv 1 \mod phid∗e≡1modphi
d∗e≡1mod(p−1)∗(q−1)d*e \equiv 1 \mod (p-1)*(q-1)d∗e≡1mod(p−1)∗(q−1)
d∗e≡1mod(p−1)d*e \equiv 1 \mod (p-1)d∗e≡1mod(p−1)
dp∗e≡1mod(p−1)dp*e \equiv 1 \mod (p-1)dp∗e≡1mod(p−1)

  因此,(dp∗e−1)(dp*e - 1)(dp∗e−1)一定是(p-1)的倍数,且p是素数。而且,我们又知道,dp<(p−1)dp < (p-1)dp<(p−1),因此遍历1~65537,一定可以找到一个数,使(dp∗e−1)≡0mod(p−1)(dp*e - 1) \equiv 0 \mod (p-1)(dp∗e−1)≡0mod(p−1)

  使用脚本如下:

#enconding:utf-8
'''@Author: b0ring@MySite: https://unnamebao.github.io/@Date:     2019-11-10 12:36:18@Version:   1.0.0
'''import Crypto.Util.number as number
def fastpow(Co, CoCo, CoCoCo):CoCoCoCo = 1while CoCo != 0:if (CoCo & 1) == 1:CoCoCoCo = (CoCoCoCo * Co) % CoCoCoCoCo >>= 1Co = (Co * Co) % CoCoCoreturn CoCoCoCodef gcd(num_1,num_2):p,q=max(num_1,num_2),min(num_1,num_2)if q == 0:return pr = p%qreturn gcd(q,r)def EX_GCD(a,b,arr): #扩展欧几里得if b == 0:arr[0] = 1arr[1] = 0return ag = EX_GCD(b, a % b, arr)t = arr[0]arr[0] = arr[1]arr[1] = t - int(a // b) * arr[1]return gdef ModReverse(a,n):arr = [0,1,]gcd = EX_GCD(a,n,arr)if gcd == 1:return (arr[0] % n + n) % nelse:return -1dp = 84373069210173690047629226878686144017052129353931011112880892379361035492516066159394115482289291025932915787077633999791002846189004408043685986856359812230222233165493645074459765748901898518115384084258143483508823079115319711227124403284267559950883054402576935436305927705016459382628196407373896831725
n = 22000596569856085362623019573995240143720890380678581299411213688857584612953014122879995808816872221032805734151343458921719334360194024890377075521680399678533655114261000716106870610083356478621445541840124447459943322577740268407217950081217130055057926816065068275999620502766866379465521042298370686053823448099778572878765782711260673185703889168702746195779250373642505375725925213796848495518878490786035363094086520257020021547827073768598600151928787434153003675096254792245014217044607440890694190989162318846104385311646123343795149489946251221774030484424581846841141819601874562109228016707364220840611
e = 65537
c = 14874271064669918581178066047207495551570421575260298116038863877424499500626920855863261194264169850678206604144314318171829367575688726593323863145664241189167820996601561389159819873734368810449011761054668595565217970516125181240869998009561140277444653698278073509852288720276008438965069627886972839146199102497874818473454932012374251932864118784065064885987416408142362577322906063320726241313252172382519793691513360909796645028353257317044086708114163313328952830378067342164675055195428728335222242094290731292113709866489975077052604333805889421889967835433026770417624703011718120347415460385182429795735# tmp1 = (dp * e) -1for i in range(65537)[::-1]:if (dp*e-1)%i == 0 and number.isPrime((dp*e-1)//i + 1):p = (dp*e-1)//i + 1break
q = n // p
phi = (p-1)*(q-1)
d = ModReverse(e,phi)
m = fastpow(c,d,n)
print(number.long_to_bytes(m))

  当然了,这里可以这样用是因为e比较小,那么如果e很大怎么办呢?其实我们已知e和dp在同余(p-1)下是互逆的,那么:

对于任意一个数r,re∗dp≡rmodpr^{e*dp} \equiv r \mod pre∗dp≡rmodp
为什么呢?因为根据欧拉定理,我们有:
rϕ(p)≡1modpr^{ \phi(p) } \equiv 1 \mod prϕ(p)≡1modp
又因为p是素数,ϕ(p)=p−1\phi(p) = p-1ϕ(p)=p−1
e∗dp≡1mod(p−1)e * dp \equiv 1 \mod (p-1)e∗dp≡1mod(p−1)
re∗dp=rn∗ϕ(p)+1≡1∗rmodpr^{e*dp} = r^{n*\phi(p)+1} \equiv 1*r \mod pre∗dp=rn∗ϕ(p)+1≡1∗rmodp
因此
rdp∗e−r=n∗pr^{dp*e} - r = n*prdp∗e−r=n∗p

  也就是说,对于任意的r,我们可以利用rn∗dp−rr^{n*dp} -rrn∗dp−r来找到p的一个倍数,再使用扩展欧几里得算法去求其与n的最大公因数,就可以算出p了,脚本具体步骤如下:

#enconding:utf-8
'''@Author: b0ring@MySite: https://unnamebao.github.io/@Date:     2019-11-10 12:36:18@Version:   1.0.0
'''import Crypto.Util.number as number
def fastpow(Co, CoCo, CoCoCo):CoCoCoCo = 1while CoCo != 0:if (CoCo & 1) == 1:CoCoCoCo = (CoCoCoCo * Co) % CoCoCoCoCo >>= 1Co = (Co * Co) % CoCoCoreturn CoCoCoCodef gcd(num_1,num_2):p,q=max(num_1,num_2),min(num_1,num_2)if q == 0:return pr = p%qreturn gcd(q,r)def EX_GCD(a,b,arr): #扩展欧几里得if b == 0:arr[0] = 1arr[1] = 0return ag = EX_GCD(b, a % b, arr)t = arr[0]arr[0] = arr[1]arr[1] = t - int(a // b) * arr[1]return gdef ModReverse(a,n):arr = [0,1,]gcd = EX_GCD(a,n,arr)if gcd == 1:return (arr[0] % n + n) % nelse:return -1dp = 84373069210173690047629226878686144017052129353931011112880892379361035492516066159394115482289291025932915787077633999791002846189004408043685986856359812230222233165493645074459765748901898518115384084258143483508823079115319711227124403284267559950883054402576935436305927705016459382628196407373896831725
n = 22000596569856085362623019573995240143720890380678581299411213688857584612953014122879995808816872221032805734151343458921719334360194024890377075521680399678533655114261000716106870610083356478621445541840124447459943322577740268407217950081217130055057926816065068275999620502766866379465521042298370686053823448099778572878765782711260673185703889168702746195779250373642505375725925213796848495518878490786035363094086520257020021547827073768598600151928787434153003675096254792245014217044607440890694190989162318846104385311646123343795149489946251221774030484424581846841141819601874562109228016707364220840611
e = 65537
c = 14874271064669918581178066047207495551570421575260298116038863877424499500626920855863261194264169850678206604144314318171829367575688726593323863145664241189167820996601561389159819873734368810449011761054668595565217970516125181240869998009561140277444653698278073509852288720276008438965069627886972839146199102497874818473454932012374251932864118784065064885987416408142362577322906063320726241313252172382519793691513360909796645028353257317044086708114163313328952830378067342164675055195428728335222242094290731292113709866489975077052604333805889421889967835433026770417624703011718120347415460385182429795735mp = fastpow(e,e*dp,n)-e
p = gcd(mp,n)
q = n // p
phi = (p-1)*(q-1)
d = ModReverse(e,phi)
m = fastpow(c,d,n)
print(number.long_to_bytes(m))

湖湘杯2019两个密码题wp相关推荐

  1. 2019湖湘杯 misc3 之miscmisc

    ** 2019湖湘杯 misc3 之miscmisc* 明文攻击 关于LSB图片隐写的解法 word字符隐藏显示 zip加密文件破解 作为CTF小白,对于CTF一如既往的热爱,一个人报名了今年的湖湘杯 ...

  2. 2020湖湘杯部分writeup

    周末打了湖湘杯,把做题过程记录一下,大家交流学习. 下面的链接里有题目,可以下来看看. https://download.csdn.net/download/jameswhite2417/130819 ...

  3. 湖湘杯2021-pwn-final部分复现

    第一次参加awd+,虽然成绩不是很好(大佬太多被打烂了),有很多收获,awd+赛制中可以通过攻击和防御两个手段来得分,攻击的话就是类似于正常的ctf,只不过如果成功攻击后,平台会使用官方的exp来去打 ...

  4. slax9Linux中文,湖湘杯-WriteUp | CN-SEC 中文网

    Web 题目名字不重要反正题挺简单的 解题思路 非预期,DASFLAG变量在phpinfo里显示出来了 NewWebsite 解题思路 http://47.111.104.169:56200/?r=c ...

  5. 2020湖湘杯 wp

    2020湖湘杯 wp web 题目名字不重要反正题挺简单的 NewWebsite misc misc2(题目名忘了.....) 总结 昨天打了下湖湘杯,签到选手上线. web 题目名字不重要反正题挺简 ...

  6. 2020湖湘杯-CTF-MISC-颜文字

    2020HXB-CTF-MISC-颜文字 颜文字 题目分析 开始 1.题目 2.流量分析 3.html分析 4.base64隐写 5.snow隐写 6.摩尔斯 结语 每天一题,只能多不能少 颜文字 题 ...

  7. 2020湖湘杯-CRYPTO-LFSRXOR

    2020HXB-CRYPTO-LFSRXOR LFSRXOR 题目分析 开始 1.题目 2.数学理论 3.回到题目 (1)源代码 (2)LFSR分析 (3)content原文分析 4.破解 5.get ...

  8. 2018湖湘杯海选复赛Writeup

    2018湖湘杯Writeup 0x01 签到题 0x02 MISC Flow 0x03 WEB Code Check 0x04 WEB Readflag 0x05 WEB XmeO 0x06 Reve ...

  9. 2021湖湘杯 Hideit Writeup

    2021湖湘杯 Hideit AAA : immortal 动态调试 直接x64dbg动调找到了关键的加密代码分别是xxtea 和 chacha20,直接动调从中拿出各种参数然后写代码进行解密.其实一 ...

最新文章

  1. 【C++】explicit关键字
  2. ICRA2019 | 用于移动设备的双目立体匹配
  3. 检查PHP会话是否已经开始
  4. php 教程 字符联接,PHP字符串的连接_PHP教程
  5. 图文并茂,详细讲解UML类图符号、各种关系说明以及举例
  6. Spring event 使用完全指南
  7. 软件项目管理0813:法律合规
  8. My new iMac 27
  9. mysql数据库表复用_MySQL 数据库之表操作
  10. 产品新人如何快速成长?
  11. SVG 教程 (七)SVG 实例,SVG 参考手册
  12. Docker Compose学习之docker-compose.yml编写规则 及 实战案例
  13. html5录音支持pc和Android、ios部分浏览器,微信也是支持的,JavaScript getUserMedia
  14. 【前端】【cornerstone】cornerstone.js如何编辑图像/加载已有图像数据(以画直线为例)
  15. 加密算法-MD5算法
  16. oracle完全删除表空间
  17. 【BZOJ4325】NOIP2015 斗地主 搜索+剪枝
  18. 字节跳动《算法中文手册》高清版.pdf
  19. 公差与配合查询计算过程讲解
  20. linux chmod 777 dev,linux命令中chmod 777 以及drwxr-xr-x分别代表什么意思

热门文章

  1. 财务金融工具-生成收付款计划
  2. 如何对待新事物_面对新事物,我们该如何做选择?
  3. 全国计算机应用基础统考成绩查询,网络教育统考成绩查询的方法有哪些
  4. 数据仓库的概念与设计
  5. python浏览器插件下载_Python Editor 5.0.0.3
  6. 手机发射功率技术分析
  7. 你能清洗西雅图所有的窗户吗?
  8. 鸿蒙窍什么意思,庄子南华_04.人间世:德荡乎名知出乎争
  9. 解决Safari在线观看视频卡顿的问题
  10. 正则-生成验证规则神器