python解二元二次方程_BUUCTF平台Crytpo部分Writeup

[BJDCTF 2nd]rsa1

题目链接(buu平台)

题解

首先拿到题目靶机。nc交互获取得到题目数据

得到的条件有

e

p^2+q^2

p-q

c

明显是一个rsa加密。要去求解这个题目。因为求解rsa嘛。我们本质上肯定是想通过最基础的rsa解密去求解的。也就是我们要获取到私钥d以及公钥n。

这边我们通过去求解p和q的值。来求解rsa加密。

根据已知信息

假设

p^2+q^2=a

p-q=b

其中a、b已知

即求解二元二次方程

求解方程可以使用z3-solver进行求解

安装方法如下

找到官网

下载对应系统的第三方库文件

例如我是windows系统,我下载的就是

z3_solver-4.8.8.0-py2.py3-none-win_amd64.whl

然后pip安装这个z3-solver库

pip install z3_solver-4.8.8.0-py2.py3-none-win_amd64.whl

然后求解出p和q的值进行一个基础的rsa解密就好了。

题解exp如下

import z3

import gmpy2

from Crypto.Util.number import *

#公钥e

e=11630623

#p^2+q^2

p2q2=159091823893455582874061921154612415267326476512949054956396980727282756099500423604620855106680518280081561541640137584218141965305223222299378169087637728170419037951685924289388185840842033127708318792414241966337535836497572877344724131756911624967860755193905135911797719211253029463146921655068409851682

#p-q

p_q=-1028057512734526688756255253926193308887656904740633132866508165158161555923213681694346079000723418169221377228338798941679856716917764591264729224439880

#密文c

c=c=16828607056351898528593346827961041518302251064718691085202163294074947863618526294699466675783765349214251854122505153854940088340991317516413847467861967618764774324129650766830916741676747137720500142976165361634620558308099053963312274170652756789297267286419176164695159543581037737967947118601658126996

#使用z3对二元二次方程进行求解

s=z3.Solver()

#定义两个变量

p,q=z3.Ints("p q")

#添加方程

s.add(p*p+q*q==p2q2)

s.add(p-q==p_q)

s.add(p>0)

arr=[]

#校验是否有解

if s.check()==z3.sat:

arr=s.model()

print(arr)

#得到p,q

q = 9418055170543903468662169278295577389409276234772590476185014016803075309886254123445652979884992724665244226628125328356664293030046148360676450649936611

p = 8389997657809376779905914024369384080521619330031957343318505851644913753963040441751306900884269306496022849399786529414984436313128383769411721425496731

#简单验证一下

assert(p*p+q*q==p2q2)

assert(p-q==p_q)

#rsa基础解密

n=p*q

phi=(p-1)*(q-1)

d=gmpy2.invert(e,phi)

m=pow(c,d,n)

flag=long_to_bytes(m)

print(flag)

EasyProgram

题目链接(buu平台)

拿到题目下载附件,得到两个文件

file.txt

用python读入字节流,判断长度为38.长度为38我们知道flag{}加上中间32位md5值就是一个标准的flag.也就先判断file.txt存放的是flag的密文

附件.txt

一个加密算法,大概是类似伪代码之类的。也比较容易看懂

get buf unsign s[256]

get buf t[256]

we have key:whoami

we have flag:????????????????????????????????

for i:0 to 256

set s[i]:i

for i:0 to 256

set t[i]:key[(i)mod(key.lenth)]

for i:0 to 256

set j:(j+s[i]+t[i])mod(256)

swap:s[i],s[j]

for m:0 to 38

set i:(i + 1)mod(256)

set j:(j + S[i])mod(256)

swap:s[i],s[j]

set x:(s[i] + (s[j]mod(256))mod(256))

set flag[m]:flag[m]^s[x]

fprint flagx to file

简单的把代码理一下,改成python的实现

key="whoami"

flag="flag{test_test_test_test_test_test_te}"

s=[]

t=[]

flag_enc=""

for i in range(256):

s.append(i)

for i in range(256):

t.append(ord(key[i%len(key)]))

j=0

for i in range(256):

j=(j+s[i]+t[i])%256

tmp=s[i]

s[i]=s[j]

s[j]=tmp

i=0

j=0

for m in range(38):

i=(i+1)%256

j=(j+s[i])%256

tmp=s[i]

s[i]=s[j]

s[j]=tmp

x=(s[i]+s[j]%256)%256

flag_enc+=chr(ord(flag[m])^s[x])

print(flag_enc)

简单分析一下,就是一个最简单的流密码,可以把前面的操作看作生成了一个密钥流。这个密钥流明显是固定的(也就是说和加密的明文无关)。那就很简单,异或解密就可以了。

题解exp如下:

f=open("file.txt","rb")

st=f.read()

print(len(st))

flag_enc=st

key="whoami"

s=[]

t=[]

flag=""

for i in range(256):

s.append(i)

for i in range(256):

t.append(ord(key[i%len(key)]))

j=0

for i in range(256):

j=(j+s[i]+t[i])%256

tmp=s[i]

s[i]=s[j]

s[j]=tmp

i=0

j=0

for m in range(38):

i=(i+1)%256

j=(j+s[i])%256

tmp=s[i]

s[i]=s[j]

s[j]=tmp

x=(s[i]+s[j]%256)%256

flag+=chr(flag_enc[m]^s[x])

print(flag)

[AFCTF2018]可怜的RSA

题目链接(buu平台)

拿到附件:

flag.enc

public.key

就明显是拿到两个附件,一个是RSA加密的密钥文件,还有一个是flag加密后的密文的文件。

这边的话一种就是常规的用openssl,个人不太喜欢用。python能解决的问题我一般就python解决了。这边用到python的Crypto库,是做CTF密码学非常常用的一个库。

pip install pycrypto

安装好这个Crypto库

然后导入Crypto.PublicKey.RSA

用RSA模块的import_key函数将我们的publickey读入,拿到RSA加密的公钥n和e的具体参数

from Crypto.PublicKey import RSA

f=open("public.key","r")

key=RSA.import_key(f.read())

f.close()

e=key.e

n=key.n

然后发现n可以分解,直接在线网站http://factordb.com/把n给分解了,得到公钥n的两个因子。

然后就是常规的RSA求解私钥

这边因为flag.enc是RSA的PKCS1_OAEP加密得来的。所以我们这边也是给生成一个私钥文件。

在做到这边的时候,如何导出一个私钥文件。找了一下百度上的方法。都是先generate后给参数分别赋值的。但是我发现我并不行,试了一下python3和python2下的Crypto库都得到一个报错

Exception has occurred: AttributeError

can't set attribute

也就是现在无法通过这么直接赋值了。

这种情况的话,可以去看下python调用的Crypto库里面的RSA模块的一个底层的实现。

发现有一个construct函数,传入一个rsa_components参数,是一个元组型的数据,也就是tuple类型的,分别是(n,e,d,p,q)

phi=(p-1)*(q-1)

d=gmpy2.invert(e,phi)

rsa_components=(n,e,int(d),p,q)

arsa=RSA.construct(rsa_components)

arsa.exportKey()

然后导出的私钥,对加密后的密文,使用PKCS1_OAEP模块进行解密即可。

题解exp如下

from Crypto.PublicKey import RSA

from Crypto.Cipher import PKCS1_OAEP

f=open("public.key","r")

key=RSA.import_key(f.read())

f.close()

e=key.e

n=key.n

import base64

from Crypto.Util.number import *

import gmpy2

p= 3133337

q=25478326064937419292200172136399497719081842914528228316455906211693118321971399936004729134841162974144246271486439695786036588117424611881955950996219646807378822278285638261582099108339438949573034101215141156156408742843820048066830863814362379885720395082318462850002901605689761876319151147352730090957556940842144299887394678743607766937828094478336401159449035878306853716216548374273462386508307367713112073004011383418967894930554067582453248981022011922883374442736848045920676341361871231787163441467533076890081721882179369168787287724769642665399992556052144845878600126283968890273067575342061776244939

print(p*q==n)

f=open("flag.enc","r")

c_base64=f.read().strip("\n")

c_bytes=base64.b64decode(c

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值