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

待更新~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM