ASISCTF

20 篇文章 2 订阅

warm up

题目代码如下图所示,我们会发现整个加密过程如下所示,先在flag后面加上p长度的随机字符,然后选择pow(s,i,p)的结果选择字符重新连接字符串实现加密

#!/usr/bin/env python3

from Crypto.Util.number import *
import string
from secret import is_valid, flag

def random_str(l):
	rstr = ''
	for _ in range(l):
		rstr += string.printable[:94][getRandomRange(0, 93)]
	return rstr

def encrypt(msg, nbit):
	l, p = len(msg), getPrime(nbit)
	rstr = random_str(p - l)
	msg += rstr
	while True:
		s = getRandomNBitInteger(1024)
		if is_valid(s, p):
			break
	enc = msg[0]
	for i in range(p-1):
		enc += msg[pow(s, i, p)]
	return enc

nbit = 15
enc = encrypt(flag, nbit)
print(f'enc = {enc}')

我们发现pow(s,i,p)=2,那么pow(s,2*i,p)=4,所以如果相差一倍的位置上的字符是I和{,我们可以确定i,2*i,从而对s求解,当算出s后即将源字符串还原。由于s和p较小,可以使用爆破s的方式,发现还原字符串开头为ASIS{且flag为规定字符即可找到s和答案

import gmpy2
import string
quanbu=string.ascii_letters + string.digits+"_-]+.!?|"
f=open("output.txt","r")
enc=f.read()
f.close()
enc=enc[7:]
p=len(enc)+1
print(p)

for i in range(len(enc)):
	if enc[i]=="I" and enc[(2*i)%(p-1)]=="{":
		print(i)


i=10778//2
#i=3758//2
ini=gmpy2.invert(i,p-1)
s2=pow(2,ini,p)


s=[]
for zhong in range(p):
	zhongjian=pow(zhong,2,p)
	if zhongjian==s2:
		s.append(zhong)
print(s)


flag=["A"]*p
for j in range(p-1):
	ms=pow(s[0],j,p)
	flag[ms]=enc[j]
if flag[1]=="S" and flag[2]=="I" and flag[3]=="S" and flag[4]=="{":
	print(flag[:30])


flag=["A"]*p
for j in range(p-1):
	ms=pow(s[1],j,p)
	flag[ms]=enc[j]
if flag[1]=="S" and flag[2]=="I" and flag[3]=="S" and flag[4]=="{":
	print(flag[:30])

Spiritual

题目给了nc的接口,其中给出椭圆曲线的p和椭圆曲线的阶,计算当模p^k的时候椭圆曲线的阶是多少。我们发现在sage中椭圆曲线函数有一个extension_degree函数可以快速计算这样的问题,但我们并不知道椭圆曲线的参数,无法还原椭圆曲线,所以我们借助set_order函数强行赋值给椭圆曲线阶,从而完成后面的计算

p = 126479891943345541230373341807457340927

k = 126479891943345541240647426557172181202

n=7

E = EllipticCurve(GF(p),[10000,10000])
E.set_order(k,num_checks=0)
print(E.order(extension_degree=n))

Madras

题目如下,给出一组方程结果,求解方程后即可使用RSA通用求解方式计算

#!/usr/bin/env python3

from Crypto.Util.number import *
from flag import FLAG

def gentuple(nbit):
	a, b, c = [getPrime(nbit // 3) for _ in '012']
	return a, b, c

def encrypt(msg, params):
	a, b, c = params
	e, n = 65537, a * b * c
	m = bytes_to_long(msg)
	assert m < n
	enc = pow(m, e, n)
	return enc

nbit = 513
a, b, c = gentuple(nbit)
enc = encrypt(FLAG, (a, b, c))

print(f'a*b + c = {a*b + c}')
print(f'b*c + a = {b*c + a}')
print(f'c*a + b = {c*a + b}')
print(f'enc % a = {enc % a}')
print(f'enc % b = {enc % b}')
print(f'enc % c = {enc % c}')
print(f'enc     = {enc}')

这里我们使用sage做求解,再解RSA

n1=4553352994596121904719118095314305574744898996748617662645730434291671964711800262656927311612741715902
n2=4414187148384348278031172865715942397786003125047353436418952679980677617016484927045195450392723110402
n3=2621331497797998680087841425011881226283342008022511638116013676175393387095787512291008541271355772802
a, b, c = var('a b c')
print(solve([a*b+c-n1,b*c+a-n2,c*a+b-n3],a,b,c))
import gmpy2
a = 1644376501336761869533914527999140316946467005479211
b = 2769045283056871559108237639832652911114008081576651
c = 1594118801665580510615541222527591707834932058213541
n1 = 4553352994596121904719118095314305574744898996748617662645730434291671964711800262656927311612741715902
n2 = 4414187148384348278031172865715942397786003125047353436418952679980677617016484927045195450392723110402
n3 = 2621331497797998680087841425011881226283342008022511638116013676175393387095787512291008541271355772802
n4 = 1235691098253903868470929520042453631250042769029968
n5 = 2235727505835415157472856687960365216626058343546572
n6 = 1197976933648163722609601772402895844093866589777721
enc     = 6238548897897912462708514382106387305984378113132192980353695746912882399991285268937548949835500837749446265632471076030233510866260067177632747513323223

assert a*b+c==n1
assert b*c+a==n2
assert c*a+b==n3
assert enc%a==n4
assert enc%b==n5
assert enc%c==n6

print(gmpy2.is_prime(a))
print(gmpy2.is_prime(b))
print(gmpy2.is_prime(c))
n=a*b*c
phi=(a-1)*(b-1)*(c-1)
e=65537
d=gmpy2.invert(e,phi)
m=pow(enc,d,n)
print(hex(m)[2:].decode("hex"))

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值