• 2020首届祥云杯部分wp


    比赛感受

    这次比赛难度很大(应该是我太菜。。。),把我整得怀疑人生,很多题不会,尤其是逆向。最近也有点忙,拖到今天才写好wp。。。大佬轻喷

    Misc

    签到

    直接base64解码得到flag

    进制反转

    压缩包解压失败

    题目提示说到手机,以为用手机就能解压,手机没有出现损坏的提示,但是解压需要密码(其实这里就掉坑了。。。)

    010打开压缩包,先遍历看看有无可疑信息,没有发现,猜测可能为rar伪加密,因为rar的机制,使用伪加密打开会出错,找到第24个字节,将C4改为C0,解压成功

    发现一个音频flag.wav,使用Audacity打开,失败

    使用导入原始数据的方式打开这个音频文件,听不懂,结合提示的反转,可能是倒放,并调节速率

    听起来好像是一首歌,听歌识曲为: 《Too Good At Goodbyes》

    flag就是这个歌名,题目要求大写,flag就是歌名的大写

    到点了

    题目给了三个docx文件,先从第一个文档开始看,打开是这样

    没有什么有效信息,可能被隐藏,勾上隐藏字体看看

    第二个文档被加密,这个应该就是线索

    暴力破解,得到密码为20201024(没有字母,出题人真坑!),打开第二个文档

    因为我不喜欢白色背景,很久前我就把背景设为绿色,好家伙,居然发现图片下面有一行东西(巧了,瞎猫碰见死耗子。。。),复制出来

    AABBAABBBAABBBAAAABBABBABABAAAAABBAAABBBBAABBBAABABABBAAABAAAABAABAABBABAAAAABAA

    培根密码解密得到

    GOODNIGHTSWEETIE
    goodnightsweetie
    

    第三个文档很显然,比其他两个文档大很多,里面可能有其他文件,使用foremost分解

    发现一个压缩包,但是没有分解出来,只分解出两个图片

    使用binwalk分解,分解后得到一大堆东西

    那个4.zip是之前foremost发现的压缩文件,里面是一张bmp文件,尝试 wbs43open

    输入之前培根密码解密得到的两个密码,发现GOODNIGHTSWEETIE,才是真的密码

    xixixi

    题目提示:室友最近沉迷y神,又氪又肝,还ghs。为了他的身体着想,我把他的s图整没了。但我明明删了脚本啊,为什么还能被他发现......8说了,医院的空调真舒服~(真的是沉迷y神。。。)

    解压得到vhd文件,就是虚拟磁盘文件,用window系统自带的磁盘管理附加就可以

    里面是一张图片

    看图片的话,好像是菲谢尔~,除此之外,没有其他信息。。。可能姿势不对

    带音乐家

    题目给了两个文件

    先分析一下decode_it是什么文件类型

    以前看过一个编程语言Veloto就是以这种文件作为源代码的,尝试编译后看看输出什么

    打开压缩包

    注释那里有东西,但是看不到,复制到编辑器

    好家伙,还是看不到,不过能通过光标的移动猜出就是点和横线,摩斯密码,通过光标一个一个测出来,并摩斯密码解密得到信息是

    AESKEY9219232322
    

    压缩包有密码,密码为:Hello, World!,打开里面的文档

    根据前面的信息,这个应该就是AES加密,密钥是9219232322

    在线网站解密得到flag:flag{mU51c_And_ch@ract0rs~}

    charles Sensor

    暂无思路

    Reverse

    re1

    ida载入,搜索字符串,搜到win,定位到引用的函数,反汇编失败,直接卡住。。。

    看看汇编代码,发现判断的函数特别长,而且很多跳转,直接看最后的win那里,因为flag正确的话就会走到这里,根据前面的判断,flag由flag{xxx},xxx就是我们要求出的内容,并且flag长度为32

    这里有很多的字符比较,全部都符合就输出win,那么可以直接爆破出结果,但是要先判断是如何进行加密的,输入32个字符flag{0123456789abcdefghijklmnopqrstuv}进行动态调试,发现

    0被加密为:0xe8
    ...
    9被加密为:0xf1
    a被加密为:0x19 
    ...
    

    计算各自偏移了多少,如下图

    爆破脚本如下:

    a = [0xeb,0xf1,0x19,0xe8,0x1e,0x1e,0xf0,0xec,0xef,0x1e,0xe9,0x1e,0xec,0xec,0xe8,0xec,0x19,0x19,0xee,0x1b,0xef,0xef,0xec,0xea,0x1c,0xea,0xe8,0xeb,0xee,0xeb,0x1d,0xf1]
    
    flag = ""
    
    for i in range(len(a)):
        if 0xe8 <= a[i] <= 0xf1:
            flag += chr(a[i]-184)
        if 0x19 <= a[i] <= (0x19+26):
            flag += chr(a[i]+72)
    
    flag = 'flag{'+flag+'}'
    print(flag)
    

    apk1

    安卓的逆向,环境问题,反汇编失败,待研究

    其他

    暂无思路,怀疑人生

    Crypto

    simpleRsa

    题目给了一个python文件和数据文件,我把相关数据移到python文件

    from Crypto.Util.number import *
    import gmpy2
    
    p, q, r = [getPrime(512) for i in range(3)]
    n = p * q * r
    phi = (p - 1) * (q - 1) * (r - 1)
    d = getPrime(256)
    e = gmpy2.invert(d , phi)
    
    flag = b"flag{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}"  
    
    c = pow(bytes_to_long(flag), e, n)
    
    print(e, n)
    print(c)
    e = 1072295425944136507039938677101442481213519408125148233880442849206353379681989305000570387093152236263203395726974692959819315410781180094216209100069530791407495510882640781920564732214327898099944792714253622047873152630438060151644601786843683746256407925709702163565141004356238879406385566586704226148537863811717298966607314747737551724379516675376634771455883976069007134218982435170160647848549412289128982070647832774446345062489374092673169618836701679 
    n = 1827221992692849179244069834273816565714276505305246103435962887461520381709739927223055239953965182451252194768935702628056587034173800605827424043281673183606478736189927377745575379908876456485016832416806029254972769617393560238494326078940842295153029285394491783712384990125100774596477064482280829407856014835231711788990066676534414414741067759564102331614666713797073811245099512130528600464099492734671689084990036077860042238454908960841595107122933173
    c = 1079929174110820494059355415059104229905268763089157771374657932646711017488701536460687319648362549563313125268069722412148023885626962640915852317297916421725818077814237292807218952574111141918158391190621362508862842932945783059181952614317289116405878741758913351697905289993651105968169193211242144991434715552952340791545323270065763529865010326192824334684413212357708275259096202509042838081150055727650443887438253964607414944245877904002580997866300452
    

    和常见的RSA不一样,n是三个素数相乘。d比较小,造成e很大,很接近n,第一印象是使现成的维纳攻击,但是攻击失败,可能是因为三个素数造成

    转换思路,使用 连分数展开并求其各项渐进分数,来求私钥,代码如下:

    from Crypto.Util.number import *
    e = 1072295425944136507039938677101442481213519408125148233880442849206353379681989305000570387093152236263203395726974692959819315410781180094216209100069530791407495510882640781920564732214327898099944792714253622047873152630438060151644601786843683746256407925709702163565141004356238879406385566586704226148537863811717298966607314747737551724379516675376634771455883976069007134218982435170160647848549412289128982070647832774446345062489374092673169618836701679
    n = 1827221992692849179244069834273816565714276505305246103435962887461520381709739927223055239953965182451252194768935702628056587034173800605827424043281673183606478736189927377745575379908876456485016832416806029254972769617393560238494326078940842295153029285394491783712384990125100774596477064482280829407856014835231711788990066676534414414741067759564102331614666713797073811245099512130528600464099492734671689084990036077860042238454908960841595107122933173
    c = 1079929174110820494059355415059104229905268763089157771374657932646711017488701536460687319648362549563313125268069722412148023885626962640915852317297916421725818077814237292807218952574111141918158391190621362508862842932945783059181952614317289116405878741758913351697905289993651105968169193211242144991434715552952340791545323270065763529865010326192824334684413212357708275259096202509042838081150055727650443887438253964607414944245877904002580997866300452
    def transform(x,y):
        res = []
        while y:
            res.append(x//y)
            x,y = y,x%y
        return res
    
    def continued_fraction(res):
        numerator,denominator = 1,0
        for i in res[::-1]:
            denominator,numerator = numerator,i*numerator+denominator
        return numerator,denominator
    
    def wiener_attack(res):
        print("Attack start...")
        for i in range(1,len(res)):
            ress = res[:i]
            d = continued_fraction(ress)[1]
            m = long_to_bytes(pow(c,d,n))
            if b'flag' in m:
                print(m,"Success!")
                break
    
    res = transform(e,n)
    wiener_attack(res)
    

    more_calc

    题目给了一个python文件,数据也在里面

    import gmpy2
    from Crypto.Util.number import *
    
    flag = b"flag{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}"
    
    p = getStrongPrime(2048)
    for i in range(1, (p+1)//2):
        s += pow(i, p-2, p)
    s = s % p
    q = gmpy2.next_prime(s)
    n = p*q
    e = 0x10001
    c = pow(bytes_to_long(flag), e, n)
    print(p)
    print(c)
    #27405107041753266489145388621858169511872996622765267064868542117269875531364939896671662734188734825462948115530667205007939029215517180761866791579330410449202307248373229224662232822180397215721163369151115019770596528704719472424551024516928606584975793350814943997731939996459959720826025110179216477709373849945411483731524831284895024319654509286305913312306154387754998813276562173335189450448233216133842189148761197948559529960144453513191372254902031168755165124218783504740834442379363311489108732216051566953498279198537794620521800773917228002402970358087033504897205021881295154046656335865303621793069
    #350559186837488832821747843236518135605207376031858002274245004287622649330215113818719954185397072838014144973032329600905419861908678328971318153205085007743269253957395282420325663132161022100365481003745940818974280988045034204540385744572806102552420428326265541925346702843693366991753468220300070888651732502520797002707248604275755144713421649971492440442052470723153111156457558558362147002004646136522011344261017461901953583462467622428810167107079281190209731251995976003352201766861887320739990258601550606005388872967825179626176714503475557883810543445555390014562686801894528311600623156984829864743222963877167099892926717479789226681810584894066635076755996423203380493776130488170859798745677727810528672150350333480506424506676127108526488370011099147698875070043925524217837379654168009179798131378352623177947753192948012574831777413729910050668759007704596447625484384743880766558428224371417726480372362810572395522725083798926133468409600491925317437998458582723897120786458219630275616949619564099733542766297770682044561605344090394777570973725211713076201846942438883897078408067779325471589907041186423781580046903588316958615443196819133852367565049467076710376395085898875495653237178198379421129086523
    

    刚开始卡在求s那里,s就是1开始的逆元累加,我想化简这个式子求出s,但是失败。因为p已知,实际上求明文,题目条件已经可以求出来了(不需要s,q)

    因为 p|n,所以m = c^d mod n 等价于 m = c^d mod p
    因为 p-1 | Fai(n),所以 ed = 1 mod Fai(n) 等价于 ed = 1 mod (p-1)
    又因为e,p已知,可以求出d,然后就可以求出m
    

    完整代码如下:

    from Crypto.Util.number import*
    from gmpy2 import *
    p = 27405107041753266489145388621858169511872996622765267064868542117269875531364939896671662734188734825462948115530667205007939029215517180761866791579330410449202307248373229224662232822180397215721163369151115019770596528704719472424551024516928606584975793350814943997731939996459959720826025110179216477709373849945411483731524831284895024319654509286305913312306154387754998813276562173335189450448233216133842189148761197948559529960144453513191372254902031168755165124218783504740834442379363311489108732216051566953498279198537794620521800773917228002402970358087033504897205021881295154046656335865303621793069
    c = 350559186837488832821747843236518135605207376031858002274245004287622649330215113818719954185397072838014144973032329600905419861908678328971318153205085007743269253957395282420325663132161022100365481003745940818974280988045034204540385744572806102552420428326265541925346702843693366991753468220300070888651732502520797002707248604275755144713421649971492440442052470723153111156457558558362147002004646136522011344261017461901953583462467622428810167107079281190209731251995976003352201766861887320739990258601550606005388872967825179626176714503475557883810543445555390014562686801894528311600623156984829864743222963877167099892926717479789226681810584894066635076755996423203380493776130488170859798745677727810528672150350333480506424506676127108526488370011099147698875070043925524217837379654168009179798131378352623177947753192948012574831777413729910050668759007704596447625484384743880766558428224371417726480372362810572395522725083798926133468409600491925317437998458582723897120786458219630275616949619564099733542766297770682044561605344090394777570973725211713076201846942438883897078408067779325471589907041186423781580046903588316958615443196819133852367565049467076710376395085898875495653237178198379421129086523
    
    e = 0x10001
    d = invert(e,p-1)
    m = pow(c,d,p)
    print long_to_bytes(m)
    

    RSAssss

    题目给了一个python文件和数据文件,我把数据移到python文件那里

    from Crypto.Util.number import *
    from gmpy2 import next_prime
    
    p = getPrime(512)
    q = getPrime(512)
    
    n = p * q * next_prime(p) * next_prime(q)
    e = 0x10001
    
    flag = b"flag{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}"
    cipher = pow(bytes_to_long(flag), e, n)
    
    print(n, cipher)
    n = 8030860507195481656424331455231443135773524476536419534745106637165762909478292141556846892146553555609301914884176422322286739546193682236355823149096731058044933046552926707682168435727800175783373045726692093694148718521610590523718813096895883533245331244650675812406540694948121258394822022998773233400623162137949381772195351339548977422564546054188918542382088471666795842185019002025083543162991739309935972705871943787733784491735500905013651061284020447578230135075211268405413254368439549259917312445348808412659422810647972872286215701325216318641985498202349281374905892279894612835009186944143298761257 
    c = 3304124639719334349997663632110579306673932777705840648575774671427424134287680988314129312593361087606243819528298610131797078262351307396831985397555390640151391138633431951746748156610463582479645561779194981806129898009876517899450840875569675976765155608446799203699927448835004756707151281044859676695533373755798273892503194753948997947653100690841880925445059175494314198605475023939567750409907217654291430615102258523998394231436796902635077995829477347316754739938980814293304289318417443493019704073164585505217658570214989150175123757038125380996050761572021986573934155470641091678664451080065719261207
    

    n是由四个大素数相乘,next_prime(p) * next_prime(q)依次和p和q很接近,尝试工具分解,但是失败(数太大),只能先进行数论分析,下面是费马因子分解

    根据费马因子分解,则有

    \[n = ab = c^2 - d^2 = (c+d)(c-d) \therefore c = \frac{a+b}{2},d = \frac{a-b}{2} \]

    移项可得:d^2 = c^2-n,其中c为大于√n的最小正整数
    

    \[c = \sqrt{n}+i (i∈Z) \]

    假设能找到一个特定的i,使得 c^2-n能被开放,那么就能得到d和c,进而得到因子a,b

    由题可知,这几个素数不会相差很大,因此p1q1,p1q2,p2q1,p2q2都很接近,根据费马因子分解,可求得因子p1q1,p1q2,p2q1,p2q2,gcd(p1q1,p1q2) = p1 
    

    完整代码如下:

    from Crypto.Util.number import *
    from gmpy2 import *
    
    n = 8030860507195481656424331455231443135773524476536419534745106637165762909478292141556846892146553555609301914884176422322286739546193682236355823149096731058044933046552926707682168435727800175783373045726692093694148718521610590523718813096895883533245331244650675812406540694948121258394822022998773233400623162137949381772195351339548977422564546054188918542382088471666795842185019002025083543162991739309935972705871943787733784491735500905013651061284020447578230135075211268405413254368439549259917312445348808412659422810647972872286215701325216318641985498202349281374905892279894612835009186944143298761257
    c = 3304124639719334349997663632110579306673932777705840648575774671427424134287680988314129312593361087606243819528298610131797078262351307396831985397555390640151391138633431951746748156610463582479645561779194981806129898009876517899450840875569675976765155608446799203699927448835004756707151281044859676695533373755798273892503194753948997947653100690841880925445059175494314198605475023939567750409907217654291430615102258523998394231436796902635077995829477347316754739938980814293304289318417443493019704073164585505217658570214989150175123757038125380996050761572021986573934155470641091678664451080065719261207
    e = 0x10001
    
    def fermat_factorization(n):
        factor_list = []
        get_context().precision = 2048
        sqrt_n = int(sqrt(n))
        c = sqrt_n
        while True:
            c += 1
            d_square = c**2 - n
            if is_square(d_square):
                d_square = mpz(d_square)
                get_context().precision = 2048
                d = int(sqrt(d_square))
                factor_list.append([c+d,c-d])
            if len(factor_list)==2:
                break
        return factor_list
    
    factor_list = fermat_factorization(n)
    [X1,Y1] = factor_list[0]
    [X2,Y2] = factor_list[1]
    assert X1*Y1 == n
    assert X2*Y2 == n
    p1 = gcd(X1,X2)
    q1 = X1 // p1
    p2 = gcd(Y1,Y2)
    q2 = Y1 // p2
    
    Fai = (p1-1)*(q1-1)*(p2-1)*(q2-1)
    d = invert(e,Fai)
    print long_to_bytes(pow(c,d,n))
    

    Exposure

    题目给了一个python文件和一个数据文件,我把数据移到python文件那里

    from Crypto.Util.number import *
    import gmpy2
    
    p = getStrongPrime(512)
    q = getStrongPrime(512)
    n = p * q
    phi = (p - 1) * (q - 1)
    e = 7621
    d = gmpy2.invert(e, phi)
    
    flag = b"flag{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}"
    c = pow(bytes_to_long(flag), e, n) 加密
    
    dp = d % (p - 1)   p = 1 mod (p-1)
    print(dp >> 200)
    print(c, e, n)
    
    dp = 1153696846823715458342658568392537778171840014923745253759529432977932183322553944430236879985
    c= 46735962204857190520476434898881001530665718155698898882603422023484998388668858692912250418134186095459060506275961050676051693220280588047233628259880712415593039977585805890920089318643002597837000049626154900908543384761210358835843974072960080857150727010985827690190496793207012355214605393036388807616
    e = 7621
    n = 140376049134934822153964243403031201922239588054133319056483413311963385321279682186354948441840374124640187894619689719746347334298621083485494086361152915457458004998419817456902929318697902819798254427945343361548635794308362823239150919240307072688623000747781103375481834571274423004856276841225675241863
    

    刚开始以为dp泄露攻击,但是注意到dp泄露并不完整,dp右移了200位,只知道dp的高位,恢复dp的话,只需要爆破e次,就能得到p

    对于恢复dp的解法,超出我的知识范畴,详细见以下链接:

    https://github.com/pcw109550/write-up/tree/master/2019/KAPO/Lenstra-Lenstra-Lovasz

    完整代码如下:

    secret = 1153696846823715458342658568392537778171840014923745253759529432977932183322553944430236879985
    c = 46735962204857190520476434898881001530665718155698898882603422023484998388668858692912250418134186095459060506275961050676051693220280588047233628259880712415593039977585805890920089318643002597837000049626154900908543384761210358835843974072960080857150727010985827690190496793207012355214605393036388807616
    e = 7621
    n = 140376049134934822153964243403031201922239588054133319056483413311963385321279682186354948441840374124640187894619689719746347334298621083485494086361152915457458004998419817456902929318697902819798254427945343361548635794308362823239150919240307072688623000747781103375481834571274423004856276841225675241863
    [n, secret, c] = list(map(Integer, [n, secret, c]))
    
    def facorize(e, dp):
    	for i in range(2, e):
    		p = (e * dp - 1 + i) // i
    		if n % p == 0:
    			return p
    	return -1
    
    def recover(secret):
    	F.<x> = PolynomialRing(Zmod(n))
    	d = inverse_mod(e, n)
    	for k in range(1235, e):
    		print('k =',k)
    		f = (secret << 200) + x + (k - 1) * d
    		x0 = f.small_roots(X=2 ** (200 + 1), beta=0.44, epsilon=1/32)
    		if len(x0) != 0:
    			dp = x0[0] + (secret << 200)
    			p = facorize(e, Integer(dp))
    			if p < 0:
    				continue
    			else:
    				return p, dp
    
    if __name__ == "__main__":
    	p, dp = recover(secret)
    	q = n // p
    	assert p * q == n
    	Fai = (p - 1) * (q - 1)
    	d = inverse_mod(e, Fai)
    	flag = bytes.fromhex(hex(pow(c, d, n))[2:])
    	print(flag)
    

    blowfishgame

    题目给了一个python文件(我只给出主要代码)

    bk = 8
    master_key = os.urandom(bk)
    sendIV = os.urandom(bk)
    class Blow_CBC_demo:
        def __init__(self, iv):
            self.key = master_key
            self.iv = iv
    
        def pad(self, message):
            pad_length = bk-len(message)%bk
            return message+chr(pad_length)*pad_length
    
        def unpad(self, message):
            return message[:-ord(message[-1])]
    
        def encrypt(self, message):
            message = self.pad(message)
            blow = Blowfish.new(self.key, Blowfish.MODE_CBC, self.iv)
            ciphertxt = blow.encrypt(message)
            return ciphertxt
    
        def decrypt(self, message):
            blow = Blowfish.new(self.key, Blowfish.MODE_CBC, self.iv)
            plaintxt = blow.decrypt(message)
            plaintxt = self.unpad(plaintxt)
            return plaintxt
    
    def send_enc(message):
        sys.stdout.flush()
        handle = Blow_CBC_demo(sendIV)
        ciphertxt = handle.encrypt(message)
        message = sendIV+ciphertxt
        message = b64encode(message)
        print(message)
        return
    
    def get_enc():
        sys.stdout.flush()
        message = sys.stdin.readline().strip()
        try:
            message = b64decode(message)
            if (len(message) > 600):
                exit(0)
            handle = Blow_CBC_demo(message[:bk])
            plaintxt = handle.decrypt(message[bk:])
            return plaintxt
        except:
            print('Error')
            exit(0)
    
    def send_pl(m):
        sys.stdout.flush()
        print(m)
        sys.stdout.flush()
    
    def get_pl():
        sys.stdout.flush()
        return sys.stdin.readline().strip()
    
    def pad(message):
        pad_length = bk-len(message)%bk
        return message+chr(pad_length)*pad_length
    
    if __name__ == '__main__':
        assert(len(flag) == 42)
        if (not proof_of_work()):
            send_pl("Bye!")
            exit()
        signal.alarm(180)
        send_pl(banner)
        send_enc('Blowfish_w0rld')
        while True:
            try:
                message = get_enc().strip()
                if message.startswith('get_flag'):
                    user = get_pl().strip()
                    blow = Blowfish.new(master_key)
                    send_pl(b64encode(blow.encrypt(pad(user+flag))))
                elif message.startswith('exit'):
                    exit()
                else:
                    send_enc('Invalid command')
            except:
                exit()
    

    暂无思路,对CBC的攻击方式未了解,待了解,也希望大佬不吝赐教

    easy matrix

    题目提示,提到矩阵和高斯消元法,可能和这个有关系,待研究

    Web

    由于本人非web选手,所以web的wp就不写了(其实就是自己不会),可以参考其他师傅的wp

    Pwn

    待更新~

  • 相关阅读:
    程序员的四个阶段
    2010Year Plans
    HttpHandler HttpModule入门篇
    Lucene.net索引文件的并发访问和线程安全性
    stream流写到MemoryStream内存流引发得问题
    ASP.NET 2.0 多文件上传小经验
    HTML 迷魂灯
    如何在Windows下搭建Android开发环境
    利用Lucene.net搭建站内搜索(4)数据检索
    数据加密和解密
  • 原文地址:https://www.cnblogs.com/crfshadow/p/14043770.html
Copyright © 2020-2023  润新知