赣CTF复现

目录

Crypto

不明来信1

不明来信2

ezRSA

燕子 燕子 没有你我怎么活啊

XOR

嗷嗷嗷

rsa

Steam

Paillier

Reserve

py?python!

easy_upx

easy_xor

try_reverse_it

Ezmaze

BrownFox

find_flag


Crypto

不明来信1

题目

解题分析:

一开始真的不知道这是什么,感觉出来了这串数据有规律,但是没有见过这种密码,在结束之后看了wp才了解到。

云影密码:有1,2,4,8这四个数字,可以通过加法来用这四个数字表示0-9中的任何一个数字,例如 0=28, 也就是0=2+8,同理7=124, 9=18。这样之后再用1-26来表示26个英文字母(a/A,b/B,....,z/Z),就有了密文与明文之间的对应关系。引入0来作为间隔,以免出现混乱。所以云影密码又叫“01248密码”

对应写出脚本即可解密。

解密代码:

def yunying(c):
    list=c.split("0")
    flag=""
    for i in list:
        sum=0
        for j in i:
            sum+=int(j)#j是str型,一定要转为int型才能加
        flag+=chr(sum+64)#字母A的acsll码为65,字母a的acsll码为97
    print(flag.lower()[::-1])#转为小写,更好看出答案
c="882014080880180120410804880482041081201824028802014880140120180482"
yunying(c)

答案:flag{niceubrokenthecipher}

需要注意如果得到的不是正确答案,可以逆序看一下。

云影密码所转化为的字符串可能是大写字母可能是小写字母,那么就都需要尝试一下,但是写代码的时候结果输出转为小写字母会更容易观察。

python代码中不熟悉的函数:

split()函数是字符串类型 (str) 的一个方法,它接受一个字符串作为分隔符,用于将原字符串分割成若干个子字符串,并返回一个包含分割结果的列表

函数语法:str.split(sep, maxsplit)

str表示要分隔的字符串

sep表示可指定的分隔符,若未指定则默认空格为分隔符,是个字符串

maxsplit限制最大分割次数,若未指定则全部分割

不明来信2

题目:

解题分析:

看到一大串的字符串,直接丢到词频分析网站中分析

网站:quipqiup - cryptoquip and cryptogram solver

得到

good programmers already know that if they want to optimize the performance of their code they need to focus on the bottlenecks improvements in other places wont yield results the same is true of security systems flag is welcome to cryptography but you need to replace spaces with underscores to get the final correct flag you need to improve the weakest areas and if theres a backdoor that can evade your security measures it doesnt matter how fantastic your cryptographic algorithms are

答案:flag{welcome_to_cryptography}

ezRSA

题目:

解题分析:

根据题目很明显是RSA密码

RSA:公钥(e,n),私钥(n,d)

则由题目有:

n=567493820483 直接网站分解可得p = 836761  q = 678203

e=31

d=146449627231

c=(307560071638,239326676862,0,247490407109,182290374773,425320511222,

12801158368,166767571795,182290374773,425320511222,182290374773,425320511222,182105678525,263197593323,387021519693,261474474619,263197593323,0,425320511222,261474474619)

由rsa解出flag=[5,11,0,6,8,18,19,7,8,18,8,18,21,4,17,24,4,0,18,24]

说实话一开始看到这个还以为不是这样求的,想着将密文的全部片段合并求解,

结果为b'n^-\xdf\xd4'肯定是错的。

那么回到上面的flag,flag列表中的数据都比较小且在26以内,试一下转为字符串(+97转为acsll码),得到答案

解密代码:

from Crypto.Util.number import *
from gmpy2 import *

n=567493820483
e=31
d=146449627231
c=(307560071638,239326676862,0,247490407109,182290374773,
   425320511222,12801158368,166767571795,182290374773,425320511222,182290374773,425320511222,
   182105678525,263197593323,387021519693,261474474619,263197593323,0,425320511222,261474474619)
p = 836761
q = 678203

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

list=[]
for i in c:
    m1=pow(i,d,n)
    list.append(m1)
for i in list:
    print(chr(i+97),end="")
#输出结果:flagisthisisveryeasy

得到答案:flag{this_is_very_easy}

燕子 燕子 没有你我怎么活啊

题目:

解题分析:

根据提示可以知道是维吉尼亚密码

维吉尼亚密码:一种使用多表替换的替换密码,是在凯撒密码的基础上扩展出来的多表密码。维吉尼亚密码引入“密钥”的概念,即根据密钥来决定用哪一行的密码表来进行替换,以此来对抗字频统计。。

加密原理:由密钥k确定对应字母的移位次数(密钥不足则进行循环使用)

举例:(可根据字母表进行解密,也可以使用网站解密)

密钥: key

明文: hello

密文: rijvs

主要问题是如何找到密钥,我就卡在了这里 

看了wp之后才知道根据题目的“燕子 燕子 没有你我怎么活啊”,可以得到密钥:yanzi

(主要是密钥的寻找)

然后根据网站解密得到:2RmC5owpPF8ZiraAujJu7i5brGbe

网站:维吉尼亚加密/解密 - Bugku CTF

扔去测试一下错误,说明做到这里还没有结束,观察得到的字符串,比较像base58编码,解码试一下,得到flag

答案:flag{we1c0me_t0_ctf}

XOR

题目:

from flag import flag

def encrypt(x, y):
        key='gctf'
        result=''
        for i in range(len(x)):
                result+=chr(ord(x[i])^ord(y[i])^ord(key[i%3]))
        return result
x = flag
y = flag[1:] + flag[0]

enc = open('flag.enc', 'wb')
enc.write(encrypt(x, y))
enc.close()

解密分析:

python的文件操作:

enc = open('flag.enc', 'wb')#打开文件,并需要写入字节数据

enc.write(encrypt(x, y))     #写入字节数据
enc.close()                        #关闭文件

可以参考这篇,写的很详细:Python文件操作(一篇就足够了!) - 知乎

加密原理:flag[i]^flag[i+1]^key[i%4]=result

主要是flag[i]^flag[i+1]如何解开,这里形成了一个闭环。

可以直接爆破flag前面两个字符然后解出,或者试一下一些可能的字符

(这里纠结好久,主要是题目给的代码有点问题,应该是key%4,难受了,怀疑了自己解的步骤有问题都没怀疑题目有问题)

解密代码:

尝试一些字符,比如这道题可以是flag,xor(但是最好还是掌握通法爆破)

enc = open('flag.enc', 'r')
data = enc.read()
enc.close()
c=list(data)
key = 'gctf'

cipher = []
for i in range(len(c)):
    cipher.append(ord(c[i])^ord(key[i%4]))
print(cipher)
print(ord('f')^ord('l'))
print(ord('l')^ord('a'))
print(ord("f"))
print(ord("l"))

flag_cipher = [10, 13, 6, 28, 35, 23, 29, 13, 22, 26, 12, 25, 19, 27, 0, 23, 120, 92, 62]
flag=[102,108]
for j in range(1,len(flag_cipher)):
    flag.append(flag[j]^flag_cipher[j])
for j in range(0,len(flag)):
    print(chr(flag[j]),end="")
# print(''.join([chr(i) for i in flag]))
#输出结果:flag{XOR_IS_FUNNY!}C

join():用于将序列中的元素以指定的字符连接成一个新的字符串。它是字符串对象的一个方法,可以用于字符串、列表、元组等可迭代对象。

语法:str.join(iterable)

其中,str是用于连接的字符,iterable是一个可迭代对象,例如字符串、列表、元组等。

举例:

s = ('a', 'b', 'c')

result = '- '.join(s)

print(result)

输出结果为:

a-b-c

爆破:

key='gctf'
c = 'Kb}stvujvi`f~+3qy! hd~".~::mnrzDtikqyxtxtq?J'#从文件中读出的数据,即密文
cipher = []
for i in range(len(c)):
    cipher.append(ord(c[i])^ord(key[i%4]))
flag=[]
for i in range(32,126):
    for j in range(32,126):
        if i^j==cipher[0] :
            flag.append(chr(i) + chr(j))#将两个连接在一起作为一个字符串加入列表中,这里要构造二维的列表
for i in range(1,len(cipher)):
    for j in range(len(flag)):
        temp=cipher[i]^ord(flag[j][i])#二维列表,a[j][-1]等价于a[j][i]
        flag[j]+=chr(temp)
for j in range(0,len(flag)):
    print(flag[j])
#输出结果:Congratulations,you find it:flag{XOR_IS_FUNNY!}C

答案:flag{XOR_IS_FUNNY!}

嗷嗷嗷

题目:

解密分析:

直接复制搜索,可以知道这是一种密码:兽音,直接搜索解密网站即可

网站:兽音译者在线编码解码 - 兽音翻译咆哮体加密解密 (iiilab.com)

解出:苏吕褚朱余钱金余褚吕金赵余姜李华邹余蒋陶魏韩

观察可以看出是一堆姓氏,很明显也是一种密码,直接搜索解密网站即可

网站:百家姓加密解密在线工具 (caoniang.com)

答案:flag{Flag_1s_als0_v3ry_cute}

rsa

题目:

from Crypto.Util.number import *
import gmpy2

p = getPrime(512)
q = getPrime(512)
r = getPrime(512)
n = p * q * r
f_n = (p - 1) * (q - 1) * (r - 1)
d = getPrime(256)
e = gmpy2.invert(d , f_n)

flag = b"flag{xxxxxxxxxxxxxxxxxxxx}"

c = pow(bytes_to_long(flag), e, n)

print(e, n)
print(c)

# 415663722847119501833901036020337649286869553178470949684914705843796651140700144434861486763917501739091844433381082048590451982934616516131741631401922983423453073859583028850435927656354158384973360788342759127234564348793548075822396665803389477784576477799456182406336455101082812091609551547952831229978208785376326322530652745800585697455557575692420931273950097269773615591268429655583458034884433629808687620628082328708314012620874159605214353006317909 
# 823839634562061818205442815667231354881921097320654333642174676258516051774966417964805967899280740083016271542253494314141517956806741590491708829841141416140204833449451710656170522576992538875595531814650463102031051883566396055134181006108875777286598034585564523117887285223475900839918723461043435259032929105639223371773725102828885604172408378084272645218955569710389386187653232751456097257861106279813571701438998228620559861430750883817308547356566031
# 160293877284503002632281244442262204508286858574517498651884352001311032599991073597036699426299403251608166752740179431655705010000950763949493503233601312101482677840835488934943360645195268270252256619017328002017286144462008480908715058301726588957545660202951494853489190433205834167429983021625548299064087345658615552397602540339852246322466472218451419068648463301136719875579168004211787892571976115764279764725064759126744732493376557446868137404463012

解密分析:

观察代码,可以看到e很大(p,q也很大),那么很明显是维纳攻击(求解主要是利用连分数来把d解出来)

原理:

ed ≡ 1 % phi 即 ed=1 + k*phi

左右同除以d*phi,有:e/phi - k/d = 1 /d*phi---------①

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

因为p,q很大,则p*q>>p+q,则phi≈n

那么①式可以写成e/n-k/d=1/d*phi

由d*phi很大,则1/d*phi很小,那么e/n与k/d无限接近

用数论中连分数对e/n展开,得到的一串分数的分母很有可能是d

解密步骤:

1.对e,n用辗转相除法转为连分数形式

2.求连分数的渐进分数

3.根据条件找出符合的d

4.m=pow(c,d,n)

这篇博客写的很详细:RSA--维纳攻击--代码和题目分析-CSDN博客

辗转相除法:如何理解辗转相除法(欧几里得算法)的原理_辗转相除法的原理-CSDN博客

解密代码:

from Crypto.Util.number import *
import gmpy2

def zanzhuan(x,y):#求连分数,用辗转相除法求
    result=[]
    while y:
        result.append(x//y)
        x,y=y,x%y
    return result

def getjianjin(c):#计算渐进分数
    z=0#分子
    m=1#分母
    #难点在这里,会比较难理解一点,可以套数据写个推导
    for i in c[::-1]:#这里需要逆序读取,循环计算
        z,m=m,i*m+z
    return z,m

def jianjin(s):#求连分数的渐进分数
    list=[]
    for i in range(1,len(s)):
        list.append(getjianjin(s[0:i]))#这里循环截取连分数,返回截取的片段计算完的分子分母
    return list
def wienerAttack(e,n):
    lfs=zanzhuan(e,n)#求连分数
    jfs=jianjin(lfs)#求连分数的渐进分数
    for d,k in jfs:#在求出的渐进分数中寻找符合条件的d
        if d.bit_length()==256 and isPrime(d):
            return d


e=415663722847119501833901036020337649286869553178470949684914705843796651140700144434861486763917501739091844433381082048590451982934616516131741631401922983423453073859583028850435927656354158384973360788342759127234564348793548075822396665803389477784576477799456182406336455101082812091609551547952831229978208785376326322530652745800585697455557575692420931273950097269773615591268429655583458034884433629808687620628082328708314012620874159605214353006317909
n=823839634562061818205442815667231354881921097320654333642174676258516051774966417964805967899280740083016271542253494314141517956806741590491708829841141416140204833449451710656170522576992538875595531814650463102031051883566396055134181006108875777286598034585564523117887285223475900839918723461043435259032929105639223371773725102828885604172408378084272645218955569710389386187653232751456097257861106279813571701438998228620559861430750883817308547356566031
c=160293877284503002632281244442262204508286858574517498651884352001311032599991073597036699426299403251608166752740179431655705010000950763949493503233601312101482677840835488934943360645195268270252256619017328002017286144462008480908715058301726588957545660202951494853489190433205834167429983021625548299064087345658615552397602540339852246322466472218451419068648463301136719875579168004211787892571976115764279764725064759126744732493376557446868137404463012

d = wienerAttack(e, n)
print(d)
m=pow(c, d, n)
print(long_to_bytes(m))

答案:flag{Th1s_1s_RSA_!!!}


Steam

题目:

from Crypto.Util.number import *
flag = b'flag{********************************}'
m = bytes_to_long(flag)
length = m.bit_length()
a = getPrime(length)
S = getPrime(length)
n = getPrime(length)
t = getPrime(length)
b = m

output = []
for i in range(10):
    S = (a*S+b)%n
    output.append(S)

assert 1283353 ** a % t == 1646994922609

print("t = ",t)
print("n = ",n)
print("output1 = ",output[8])
print("output2 = ",output[9])

'''
t =  12225532690513870203267250076718585416468850716351148461573770246644148932785381160548154208
n =  15069560986812671423389855905299497263899242487326531657625082794620173330793469294263125247
output1 =  12575853029635294113203056894127324462858776834205174000199737245346996421736964134226900184
output2 =  14870060211553305146872181720797620536355345764081082411923267627078911503118833508727656446
'''

解密分析:

根据题目知道是流密码(虽然我看不出来,提示之后才知道,主要是没学过),搜索引擎出动

流密码加密过程是使用初始密钥产生一个伪随机的密码流,为了防止密钥穷举,使用和明文信息一样长的密钥(无限)流进行加密,连续地处理输入元素序列(通常是用密码流和输入序列做异或运算),产生对应的连续输出序列(密文)。而解密过程则是采用和加密过程同样的伪随机流产生器算法对初始密钥产生一个相同的伪随机密码流,与密文序列做异或运算,得到明文序列。

流密码只是一类密码的统称,它包括了RC4等其他密码。但大致加密流程是上述这样的。

那么对于这道题就直接分析代码,首先可以根据断言函数

assert 1283353 ** a % t == 1646994922609  找出a

一开始我是直接爆破,爆破出a=2,然后就直接用a=2去求明文,也是爆破,结果爆破不出来,还没意识到是a的问题,一直纠结。看了wp之后才理解了。

令x=1283353

因为前面爆破出来了a的一个取值为2,那么有 x^a % t = x ^ 2 % t

x ^ a ≡ x ^2 % t (考点在这里)

这里利用欧拉定理

则x ^ (a-2) ≡ 1 % t 所以a-2=t-1即a=t+1

有:a=2 或者 a=t+1

套a=t+1进去即可求得m

output9 = (a * output8 + m) %n

这里测试了一下output9和n的大小,n>output9

则上式左右同时模n有:

output9 (a * output8 + m) %n

则m=(output9 - a * output8) % n

但是这里出题人数据出的有点问题,t不是素数,所以不能用欧拉定理

解密代码:

from Crypto.Util.number import *
from gmpy2 import *
from bytes import *
t = 12225532690513870203267250076718585416468850716351148461573770246644148932785381160548154208
n = 15069560986812671423389855905299497263899242487326531657625082794620173330793469294263125247
output8 =  12575853029635294113203056894127324462858776834205174000199737245346996421736964134226900184 #[8]
output9 =  14870060211553305146872181720797620536355345764081082411923267627078911503118833508727656446 #[9]

a=t+1

m=(output9-a*output8)%n
print(long_to_bytes(m))

答案:flag{I_miss_you_in_the_password_group}

Paillier

题目:

from Crypto.Util.number import getStrongPrime,GCD,bytes_to_long
from random import randint
flag = b"flag{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}"

def gen(bits):
    while True:
        try:
            p = getStrongPrime(bits//2)
            q = getStrongPrime(bits//2)
            phi = (p-1)*(q-1)
            assert GCD(p*q, phi) == 1
            break
        except:
            pass
    return p,q,phi

p,q,phi = gen(4096)
relation = pow(1949*p+2023,q,p*q)
e = bytes_to_long(flag)
n = p*p*q*q
m1 = p*q+1
m2 = randint(1,p*q)
c = pow(m1,e,n)* pow(m2,p*q,n) % n
print("pq = {}".format(p*q))
print("c = {}".format(c))
print("r = {}".format(relation))

'''
pq = 887166447166908657875261838189880924598502010532802594357792586479405303600293352901354250661651440173678984721449155150569658414460907308207395217714073465789336037528820384504682261383134149950924711017705469385976843630755333653594133550138203226251679035220402593639286098419533450127641841763263532739412752119921519469031603370689902166613111442258053360353675972164543765953155296693017036110089750056317512700539251460392822501685118151651053736001643529228257725093507504777106651318771022545536494424257325948545285947224480124270824469387763520021373564659726071920334664660638427287881128656621366437992161335475097156562366370189800926486827773369343875911013941727458484733579779987518689440390273061310030122477970154371634800517544286207542226893322249504677426768230905352021685624446085667741447943553776127246344767559462950127895715194772578266968627117192022319478447762288841148942606807267300592648345050432191106211660661975538486044324700532413628992123771986347580132637422985487775324215641630120399614206165620577557862498513625751023336154441276494811321027022075968666161204083601567420981354579585765518249333579931543871485722588207836569306920651159678633890501000411112337862727032796320667777700319
c = 323104572733056013022232486209795669816554834535601387232962336629170655850534314377617934197680759290559846935490656186083677314089429656804856335524692075372743032084131018452000127872246514430829438658543559900140854007878840361748526203998984411050117562232641090277061058838906587509258636800528603847445547938034130054858336906785685848654335600709939262479353368034082193509323294933603918116246340737911157061443282270207463561100105917304203916088760871308885091672255249534049979791578470331222906455224561104349847184035127559402743918823029257506812576223379821894308066258672451450683594036743320085094677256410814502550655295926629672064365774405226858361305878063559587655891732644666454675632155044600750031081929026668466076685284598678742892932867210546631035960182133659630156881113022786923840772277637984504620005258267988782585233487278808988499952500666966183475724382298888144869080055552509548958121952081310193858529205985575007298889289790765815033496387498756584008120132476400313134104152939600449003563325993472159269768874300428981316261923218359164567470793117504689390632939710978810213641551906532978338823420643316330940655937653381016347565948025800066537335606068590806366669159147613711722595108296517617501238810649394361783540984360800550967481778102693631148620612637261218694331865911082095074229724430736357231772418893822475389129656619563049190656052129978019794093431436182978689680711258096125364181724391940048059864568248424963697192515512824691745481055455041139683413323952422427478777508144913712466493631443481419743104115445055749214481472907347853218242035572752088863088586911967851839927488620703519887745185151057205452839656630428557432359081706642582626204620845683585079921271665513783694464226345490553425440395759713327751129225092651115897387818479920067054499945516535962600590291917909490839859244827186125356914569157371884400578544778284972543551747588182070545253302203256753412353635427924783586240203437409666455087583421435122682650900629397086322568717200715965469262221264526732434570241278318691467047049198011699661747618071924145079600200541539074616415662717381866674259250430391417176197430011943435148240516180992711773089637192808600745460407977081932525387006733024417765527436291902428861034477361566763013627884956795260111032669808711172167596733104788142220562239131262895357318086602746992514123306314802937058268304296208812601925747707823346394747245244912555520062443004568349
r = 865637930492121361886040660958095287735652100059804297239549862305074524342882218036407756195501660137614332514449671726516318012272921644431634990397955755452418355435210702607050281478215501241593800950428265623124851502962706192747580206650440857460514057532387723966581671187821458771271495725813359545478050364573058316741586000836455350643646322854627450464873523811391446102913520775230108952542654623489324912508319173605941525541092868775740020238758970696523358855304171551467374093410916441923038159303426071896161802348155237253703136258350379905869362756354512195103530352494848068900430088690695486537882796843627424321556255359200236642772594700472060253927288260231875214517350548531219877990850510060538710218821389338975073365997691494936004212511479970247940758562853029615691559463499722174608861686562660451587690321371941877852557365507747135748755958542470652752809719469470047161978745121481217418159340152676451489205085786136051301309021641406617183846328887808447131843851965391259692686700087792622136451415147478524493146973717710487616252332933063236185679743903001346951192734414668183345639614973815042497781198548651467636425872167027265577291998910747253383240028130114553850989967444499041336167318

解密分析:

首先根据题目可以知道是Paillier加密,搜索一下了解一下基本原理

这里给出两种方法(可能机理是一样的,但是我还没弄太懂)

一.(推导)

由r= (1949*p+2023)^q mod n

根据二项式定理:

有r=Cq0  * (1949*p)^0 * 2023^q + Cq1  * (1949*p)^1 * 2023^(q-1) +.........

则对上式左右模p有:r ≡  2023^q (mod p)----------①

再根据欧拉定理

有2023 ^ (p-1) = 1 mod p 即 1= 2023 ^ (p-1) mod p

2023= 2023 ^ p mod p-----------②

则有:2023^q (mod p) = (2023 ^ p mod p)^ q (mod p) = 2023 ^ (p*q) (mod p)

2023 ^ (p*q) ≡ 2023^q (mod p)≡ r

设 r mod p =  2023^q  mod p = 2023 ^ (p*q)  mod p =t 

则有:r=k1*p + t

          2023 ^ (p*q) = k2*p + t 

则  2023 ^ (p*q) - r = (k2-k1)*p ----------③

所以有gcd(2023 ^ (p*q) - r , p*q) = p(这里可以求出p)

可能  2023 ^ (p*q) - r的数据会很大,无法运行出来,于是这里需要mod pq

                即gcd(2023 ^ (p*q) mod pq - r , r) = p

再由上面代码给的加密:c ≡ ( (pq+1)^e mod n * m2^pq mod n) mod n

                                           ≡ ((pq+1)^e * m2^pq) mod n     (n=p*q*p*q)

根据泰勒展开式

同理可得:c ≡ ((1+epq) * m2^pq) mod n

令phi1 = p*(p-1)*q*(q-1)  ,   phi = (p-1)*(q-1)  ,在上式左右同时phi的次方

有:c ^ phi m2^phi1 * (1+epq)^phi mod n

由前面的欧拉定理有(m2是1到pq之间取的随机数):  m2 ^ phi1  = 1 mod n

则    c ^ phi  (1+epq)^phi mod n

                   ≡ (1+phi*e*pq) mod n (泰勒展开式)

                   ≡ 1+(phi*e*pq) mod n 

                   ≡  1+(phi*e) mod n * (pq mod n)

                     1+(phi*e) mod n *pq     (pq<n)

那么e  ≡ (c ^ phi -1) // pq ) * (phi)-1  (mod n)

解密代码:

from Crypto.Util.number import *
from gmpy2 import *


n = 887166447166908657875261838189880924598502010532802594357792586479405303600293352901354250661651440173678984721449155150569658414460907308207395217714073465789336037528820384504682261383134149950924711017705469385976843630755333653594133550138203226251679035220402593639286098419533450127641841763263532739412752119921519469031603370689902166613111442258053360353675972164543765953155296693017036110089750056317512700539251460392822501685118151651053736001643529228257725093507504777106651318771022545536494424257325948545285947224480124270824469387763520021373564659726071920334664660638427287881128656621366437992161335475097156562366370189800926486827773369343875911013941727458484733579779987518689440390273061310030122477970154371634800517544286207542226893322249504677426768230905352021685624446085667741447943553776127246344767559462950127895715194772578266968627117192022319478447762288841148942606807267300592648345050432191106211660661975538486044324700532413628992123771986347580132637422985487775324215641630120399614206165620577557862498513625751023336154441276494811321027022075968666161204083601567420981354579585765518249333579931543871485722588207836569306920651159678633890501000411112337862727032796320667777700319
c = 323104572733056013022232486209795669816554834535601387232962336629170655850534314377617934197680759290559846935490656186083677314089429656804856335524692075372743032084131018452000127872246514430829438658543559900140854007878840361748526203998984411050117562232641090277061058838906587509258636800528603847445547938034130054858336906785685848654335600709939262479353368034082193509323294933603918116246340737911157061443282270207463561100105917304203916088760871308885091672255249534049979791578470331222906455224561104349847184035127559402743918823029257506812576223379821894308066258672451450683594036743320085094677256410814502550655295926629672064365774405226858361305878063559587655891732644666454675632155044600750031081929026668466076685284598678742892932867210546631035960182133659630156881113022786923840772277637984504620005258267988782585233487278808988499952500666966183475724382298888144869080055552509548958121952081310193858529205985575007298889289790765815033496387498756584008120132476400313134104152939600449003563325993472159269768874300428981316261923218359164567470793117504689390632939710978810213641551906532978338823420643316330940655937653381016347565948025800066537335606068590806366669159147613711722595108296517617501238810649394361783540984360800550967481778102693631148620612637261218694331865911082095074229724430736357231772418893822475389129656619563049190656052129978019794093431436182978689680711258096125364181724391940048059864568248424963697192515512824691745481055455041139683413323952422427478777508144913712466493631443481419743104115445055749214481472907347853218242035572752088863088586911967851839927488620703519887745185151057205452839656630428557432359081706642582626204620845683585079921271665513783694464226345490553425440395759713327751129225092651115897387818479920067054499945516535962600590291917909490839859244827186125356914569157371884400578544778284972543551747588182070545253302203256753412353635427924783586240203437409666455087583421435122682650900629397086322568717200715965469262221264526732434570241278318691467047049198011699661747618071924145079600200541539074616415662717381866674259250430391417176197430011943435148240516180992711773089637192808600745460407977081932525387006733024417765527436291902428861034477361566763013627884956795260111032669808711172167596733104788142220562239131262895357318086602746992514123306314802937058268304296208812601925747707823346394747245244912555520062443004568349
r = 865637930492121361886040660958095287735652100059804297239549862305074524342882218036407756195501660137614332514449671726516318012272921644431634990397955755452418355435210702607050281478215501241593800950428265623124851502962706192747580206650440857460514057532387723966581671187821458771271495725813359545478050364573058316741586000836455350643646322854627450464873523811391446102913520775230108952542654623489324912508319173605941525541092868775740020238758970696523358855304171551467374093410916441923038159303426071896161802348155237253703136258350379905869362756354512195103530352494848068900430088690695486537882796843627424321556255359200236642772594700472060253927288260231875214517350548531219877990850510060538710218821389338975073365997691494936004212511479970247940758562853029615691559463499722174608861686562660451587690321371941877852557365507747135748755958542470652752809719469470047161978745121481217418159340152676451489205085786136051301309021641406617183846328887808447131843851965391259692686700087792622136451415147478524493146973717710487616252332933063236185679743903001346951192734414668183345639614973815042497781198548651467636425872167027265577291998910747253383240028130114553850989967444499041336167318

p=gcd(n,pow(2023,n,n)-r)#这里需要再mod p*q
q=n // p

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

e=(((pow(c,phi,N)-1)// n )* invert(phi,N) )%n #这里也需要再mod p*q限制长度
print(long_to_bytes(e))

二.Paillier算法

直接套解密过程,代码如下:

from Crypto.Util.number import *
from gmpy2 import *


n = 887166447166908657875261838189880924598502010532802594357792586479405303600293352901354250661651440173678984721449155150569658414460907308207395217714073465789336037528820384504682261383134149950924711017705469385976843630755333653594133550138203226251679035220402593639286098419533450127641841763263532739412752119921519469031603370689902166613111442258053360353675972164543765953155296693017036110089750056317512700539251460392822501685118151651053736001643529228257725093507504777106651318771022545536494424257325948545285947224480124270824469387763520021373564659726071920334664660638427287881128656621366437992161335475097156562366370189800926486827773369343875911013941727458484733579779987518689440390273061310030122477970154371634800517544286207542226893322249504677426768230905352021685624446085667741447943553776127246344767559462950127895715194772578266968627117192022319478447762288841148942606807267300592648345050432191106211660661975538486044324700532413628992123771986347580132637422985487775324215641630120399614206165620577557862498513625751023336154441276494811321027022075968666161204083601567420981354579585765518249333579931543871485722588207836569306920651159678633890501000411112337862727032796320667777700319
c = 323104572733056013022232486209795669816554834535601387232962336629170655850534314377617934197680759290559846935490656186083677314089429656804856335524692075372743032084131018452000127872246514430829438658543559900140854007878840361748526203998984411050117562232641090277061058838906587509258636800528603847445547938034130054858336906785685848654335600709939262479353368034082193509323294933603918116246340737911157061443282270207463561100105917304203916088760871308885091672255249534049979791578470331222906455224561104349847184035127559402743918823029257506812576223379821894308066258672451450683594036743320085094677256410814502550655295926629672064365774405226858361305878063559587655891732644666454675632155044600750031081929026668466076685284598678742892932867210546631035960182133659630156881113022786923840772277637984504620005258267988782585233487278808988499952500666966183475724382298888144869080055552509548958121952081310193858529205985575007298889289790765815033496387498756584008120132476400313134104152939600449003563325993472159269768874300428981316261923218359164567470793117504689390632939710978810213641551906532978338823420643316330940655937653381016347565948025800066537335606068590806366669159147613711722595108296517617501238810649394361783540984360800550967481778102693631148620612637261218694331865911082095074229724430736357231772418893822475389129656619563049190656052129978019794093431436182978689680711258096125364181724391940048059864568248424963697192515512824691745481055455041139683413323952422427478777508144913712466493631443481419743104115445055749214481472907347853218242035572752088863088586911967851839927488620703519887745185151057205452839656630428557432359081706642582626204620845683585079921271665513783694464226345490553425440395759713327751129225092651115897387818479920067054499945516535962600590291917909490839859244827186125356914569157371884400578544778284972543551747588182070545253302203256753412353635427924783586240203437409666455087583421435122682650900629397086322568717200715965469262221264526732434570241278318691467047049198011699661747618071924145079600200541539074616415662717381866674259250430391417176197430011943435148240516180992711773089637192808600745460407977081932525387006733024417765527436291902428861034477361566763013627884956795260111032669808711172167596733104788142220562239131262895357318086602746992514123306314802937058268304296208812601925747707823346394747245244912555520062443004568349
r = 865637930492121361886040660958095287735652100059804297239549862305074524342882218036407756195501660137614332514449671726516318012272921644431634990397955755452418355435210702607050281478215501241593800950428265623124851502962706192747580206650440857460514057532387723966581671187821458771271495725813359545478050364573058316741586000836455350643646322854627450464873523811391446102913520775230108952542654623489324912508319173605941525541092868775740020238758970696523358855304171551467374093410916441923038159303426071896161802348155237253703136258350379905869362756354512195103530352494848068900430088690695486537882796843627424321556255359200236642772594700472060253927288260231875214517350548531219877990850510060538710218821389338975073365997691494936004212511479970247940758562853029615691559463499722174608861686562660451587690321371941877852557365507747135748755958542470652752809719469470047161978745121481217418159340152676451489205085786136051301309021641406617183846328887808447131843851965391259692686700087792622136451415147478524493146973717710487616252332933063236185679743903001346951192734414668183345639614973815042497781198548651467636425872167027265577291998910747253383240028130114553850989967444499041336167318

p=gcd(n,pow(2023,n,n)-r)#这里需要再mod p*q
q=n // p

N=n*n
phi=(p-1)*(q-1)
g=n+1

lcm=(p-1)*(q-1)//gcd(p-1,q-1)
Lc=(pow(c,lcm,N)-1)//n
Lg=(pow(g,lcm,N)-1)//n
m=(Lc*invert(Lg,n)) % n
print(long_to_bytes(m))

参考于这两篇文章,写的很详细:

同态加密之Paillier算法_paillier同态加密-CSDN博客

经典同态加密算法(加法与乘法)_加法同态-CSDN博客

答案:flag{i_10ve_crypto!}

Reserve

py?python!

题目:

def encrypt(data, key):
    encrypted_data = []
    key_len = len(key)
    for i in range(len(data)):
        encrypted_data.append(ord(data[i]) ^ ord(key[i % key_len]))
    return encrypted_data[::-1]


data = [19, 78,6 , 68, 17, 36, 23,63, 55, 0, 57, 15, 42, 32, 88, 51, 38, 41, 95, 3, 40, 71, 43, 15, 93, 29, 40, 43, 12, 96
, 55, 20, 15, 21, 21,54]
key = "Python"
flag = input("请输入flag")
encrypted_data = encrypt(flag, key)
if encrypted_data == data:
    print("Good!You find it")
else:
    print("Sorry,Try again")

解题分析:

分析代码,加密过程其实很简单:

flag与key(长度不够,循环进行)进行异或,最后反向传回数据即为data

对应写出解密过程即可

解题代码:

def decrypt(data, key):
    decrypted_data = []
    key_len = len(key)
    for i in range(len(data)):
        decrypted_data.append(chr(data[i] ^ ord(key[i % key_len])))
    for i in decrypted_data:
        print(i,end="")


data = [19, 78,6 , 68, 17, 36, 23,63, 55, 0, 57, 15, 42, 32, 88, 51, 38, 41, 95, 3, 40, 71, 43, 15, 93, 29, 40, 43, 12, 96
, 55, 20, 15, 21, 21,54]
data=data[::-1]
key = "Python"
decrypt(data, key)

答案:flag{Y0u_@r3_R3@l1y_G0OD_@t_Pyth0n!}

easy_upx

解题分析:

根据题目可以知道是需要脱壳的,先拿去查一下

然后脱壳用ida打开

main函数没有其他操作,也没有关于flag的信息,这里有点不知道怎么处理了,按shift+F12查看字符串也找不到有用的信息,这里点到了Hex_View块看到了flag,试一下成功解出(纯属运气好眼力好,自个都不知道为啥)

看了wp之后懂了一点吧(ノД`)

按Tab键去看汇编代码,下面那两串数字就是flag,按R识别为字符串

这里要注意这里是小端存储,需要逆序

答案:flag{UXP_yyds!}

easy_xor

解题分析:

反编译的代码其实很简单

加密过程:Str即flag 与 i 进行异或得到的密文为Str2

主要难到我的是Str2数据的问题:Str2是QWORD类型,i64表示int64型(8字节),也就是C语言中的long long型,这样写即可:*(unsigned long long*)(这个记住)

此外需要注意V6也是Str2的部分,可以进行更改Str2的数组大小观察出,即题目给出了Str2的部分,对应写出解密代码即可

解题代码:

#include <stdio.h>
#include <string.h>
int main(){
	char Str[21];
	char Str2[21];
	*(unsigned long long*) Str2 = 0x6E6E717F64636D66;
	printf(Str2);
  	strcpy(&Str2[8], "{V;xSLQi|pun");
  	for ( int i = 0; i < strlen(Str2); ++i )
    	Str[i] =Str2[i]^i;
	puts(Str);
	return 0;
}

答案:flag{this_1s_A_flag}

try_reverse_it

解题分析:

首先查一下发现有壳,脱壳

观察代码,可以发现是RC4加密

和常规的比起来稍微改了一点,对应着改动一下即可求解

解题代码:

#include <stdio.h>
#include <string.h>
void swap(unsigned char* a,unsigned char* b){
    unsigned char t;
    t=*a;
    *a=*b;
    *b=t;
}
int  main()
{
	unsigned char data[] ={108, 248, 144, 255, 139, 24, 229, 118, 181, 251,
  80, 245, 44, 95, 243, 16,203, 62, 234, 154, 200, 55, 45, 79, 204, 143,
  33, 41, 23, 6, 202, 103};
  	char key[] ="let's_revers_it";         
  	int v4 = strlen(key);
 	unsigned char T[256];
  	unsigned char s[256];
  	int i3=255;
  	for (int i = 0; i < 256; ++i )
  	{
    	s[i3--]= i;
    	T[i] = key[i%strlen(key)];            // key填充T盒
  	}
  	int j;
  	int  t,n;
	unsigned char z;
  	for ( int i = 0; i < 256; ++i )                   // 对S盒进行打乱
  	{
    	z = s[i];
    	t = (z + T[i] + t) % 256;
    	s[i] = s[t];
    	s[t] = z;
  	}
  	int i1 = 0;
  	int j1 = 0;
  	unsigned char v13;
  	for ( int k = 0; k < 32; ++k )
  	{
    	i1 = (i1 + 1) % 256;
    	v13 = s[i1];
    	j1 = (v13 + j1) % 256;
    	s[i1] = s[j1];
    	s[j1] = v13;  // 交换
    	data[k] ^= s[(v13 + s[i1])%256];//问题在这,需要模256才行                        
  	}
  	const char* data2 = (const char*)data;
	puts(data2);
     return  0;
}

答案:flag{Y0u_5eem_1ike4pro_revers3r}

Ezmaze

解题分析:

一开始拿到手是有点蒙的,直接搜索了一下题目名字,才意识到这是一道迷宫题,那么直接根据1迷宫题的步骤来就行

这里需要注意一点的是:需要进行中文字符识别

结合上面的代码有:

“1”是墙,“@”是起点,“#”是终点

a-左 d-右 w-上 s-下

那么可以把迷宫图画出来

答案:flag{dssdsdssa}

BrownFox

解题分析:

加密原理就是Input经过to_fox加密后放入enc中,然后enc和data相同,即密文为data

接下来深究细节(毕竟题目不是这么简单的)

所以密文为(这里有一个需要特别注意的点)

这里直接shift+F12提取数据即可,注意要删掉会被覆盖的数据

所以可以得到密文为"b0cxq0r0i1qfAbkjrfixbxrxrjrfuoAoijk0rfbjk0ujq1rfrjk0qbqbk1AA"

然后跟进加密过程:

加密具体操作:      

v6 = Input[i] >> 3; //把Input[i]右移3位,即取Input[i]的高5位


enc[2 * i] = fox[Input[i] & 7];//取Input[i]的低3位

-->原理:a& 1 =a

7的二进制为0111,则Input[i] & 0111 保留Input[i]的低3位数值不变


result = fox[v6 & 0x1F];//a[i]&0x1f是一个按位与运算,0x1f换成二进制为00011111

即保留v6的低5位,即取Input[i]的高5位

上面化简即为:
 enc[2*i]=fox[input[i] &7] 低3位
 enc[2*i +1 ] =fox[input[i]>>3] 高5位

那么解密的话求出低3位和高5位拼接在一起即可(按位或)

那么现在最关键的是找到fox数组,我们这里需要跟进improve_fox()函数:

这里有一系列操作,可以linux远程调试得到fox="Aquickbrownf0xj1mps2ve3th4lazyd5g"

(但是我不会,等我补一下再回来)

解题代码:

#include<stdio.h>
#include<string.h>
char enc[]="b0cxq0r0i1qfAbkjrfixbxrxrjrfuoAoijk0rfbjk0ujq1rfrjk0qbqbk1AA";
char fox[34]="Aquickbrownf0xj1mps2ve3th4lazyd5g";
int search(char x){
	for(int i=0;i<34;i++){
		if(x==fox[i])
			return i;
	}
}

int main(){
	char flag[30];
    for ( int i = 0; i != 30; i++ )
    {
      flag[i]=(search(enc[2 * i]) &7 | search(enc[2*i +1 ]) <<3);
      printf("%c",flag[i]);
    }
	
    return 0;
}

答案:flag{Y0u_know_B@se_very_we11}

find_flag

解题分析:

跟入加密过程可以发现是一个很标准的Tea加密算法,且是对flag每8个字节为一组进行加密

直接可以对应写出解密代码

解密代码:

#include<stdio.h>
#include<string.h>
#include <stdint.h>
void decipher(uint32_t *v, uint32_t *k) {
    unsigned int i;    
    uint32_t v0=v[0], v1=v[1];
    int delta=1640531527;
    int sum=-32*delta;
    for (int i=0; i <=31; i++) {
        v1 -= (v0 + sum) ^ (k[2] + 16 * v0) ^ ((v0 >> 5) + k[3]);
        v0 -= (v1 + sum) ^ (*k + 16 * v1) ^ ((v1 >> 5) + k[1]);
        sum += delta;
        
    }
    v[0]=v0; v[1]=v1;
}
 
int main()
{
	unsigned char data[40] ={
  0xF6, 0xD1, 0x6A, 0xFF, 0x55, 0xB2, 0x7B, 0xB3, 0x98, 0x27, 
  0x98, 0xDB, 0x03, 0xB9, 0x3D, 0x08, 0xBD, 0x68, 0x9B, 0xD3, 
  0x18, 0x06, 0x18, 0xE7, 0xC5, 0x43, 0xCE, 0x82, 0xFE, 0x82, 
  0xD1, 0xA1, 0x74, 0xA8, 0x26, 0x47, 0x8C, 0x3C, 0xE0, 0x6A};
    uint32_t k[4]={18,52,86,120};
	for ( int i = 0; i <= 4; ++i )
		decipher((unsigned int*)&data[i*8], k);
	printf("%s",data);
    return 0;
}

解出答案:flag{You_found_the_flag!But_is_a_FAKE~}

如果输出有乱码,可以把data数组变大一点,加上0

拿去测试一下发现不行,这是假的flag

一般来说可以往上面去找是否对于flag有改动,或者按x交叉引用查看一下

此外,可以找一下TlsCallback()函数,这个函数是在main函数之前执行的,做一些初始化操作

我们点开文件运行的时候弹出了两句please,按理来说应该只有一句,所以这里猜测在main函数之前还有其他操作

那么这里我们对flag和data按x交叉引用查看一下

可以看到在main函数之前对flag还有其他操作,跟过去

这里经计算Buffer="Right/n"应该是8位,但给出的明显不对,这里需要按y修改一下数组大小

(Realdata=v4,这里改了一下名字,v4是真正的密文)

由上面memcmp()函数的比较可以知道Realdata的长度为40,则Realdata数组大小也不正确,这里同样按y修改一下,然后动态调试得到Realdata数组

unsigned char data[40] ={
        0x6b,0x79,0x1f,0x9f,0x78,0x73,0xaf,0xe4,0xd5,0xdf,
        0xfc,0x72,0xe0,0xff,0x57,0x4a,0x7,0xba,0x72,0x16,
        0xe6,0x7b,0x5,0xaa,0x8e,0x1f,0x17,0x9e,0x4f,0x3e,
        0x15,0xdd,0x59,0x9e,0x7,0x41,0xdd,0x78,0x75,0x80};

跟进加密函数:很明显的Tea加密,但是有魔改(k值固定),对应编写解密代码即可。

解密代码:

#include<stdio.h>
#include<string.h>
#include <stdint.h>
void decipher(uint32_t *v, uint32_t *k) {
    unsigned int i;    
    uint32_t v0=v[0], v1=v[1];
    int delta=1640531527;
    int sum=-32*delta;
    for (int i=0; i <=31; i++) {
        v1 -= (v0 + sum) ^ (k[2] + 16 * v0) ^ ((v0 >> 5) + k[3]);
        v0 -= (v1 + sum) ^ (*k + 16 * v1) ^ ((v1 >> 5) + k[1]);
        sum += delta;
        
    }
    v[0]=v0; v[1]=v1;
}
 
int main()
{
	unsigned char data[40] ={
		0x6b,0x79,0x1f,0x9f,0x78,0x73,0xaf,0xe4,0xd5,0xdf,
		0xfc,0x72,0xe0,0xff,0x57,0x4a,0x7,0xba,0x72,0x16,
		0xe6,0x7b,0x5,0xaa,0x8e,0x1f,0x17,0x9e,0x4f,0x3e,
		0x15,0xdd,0x59,0x9e,0x7,0x41,0xdd,0x78,0x75,0x80};
    uint32_t k[4]={137,118,84,50};
	for ( int i = 0; i <= 4; ++i )
		decipher((unsigned int*)&data[i*8], k);
	printf("%s",data);
    return 0;
}

补充C语言中一些数据类型:(ida反汇编出来的一些数据类型看都没看过,都不知道是什么意思,这里搜索了一下)

具体的可以参考这篇博客:浅析C语言之uint8_t / uint16_t / uint32_t /uint64_t-CSDN博客

答案:flag{W0w!You_F1nd_mE!_coNgr@tulAt1ons!}

  • 19
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值