1,shadow
给了个shadow文件,这怎么跑到密码来了,不能把XX科计划生育的事给发给科技啊。
这东西在字典里,可以到网上查,但能查到的都是收费的,虽然知道他们没关系但还是怀疑。
john ./shadow --wordlist=../rockyou.txt
2,神秘数字
给了两个文本,一个是624个32位整数,另一个是一段文本,查看字符集确认是base58,但是解不出来,确实也没有其它提示了。
9fLcV9rEB7WS1BonaSDpub31bRozXPoVsjgCmi8gKuLMVDRx3GyqTGe3YaDehfcAr7fPt5xBRHspLJ8PeRM8ohs2hqjaQ9sQ1EZUsztwaPgw3cV1A2aSTpzKgkFj1EnDbuh52NahmLLf9Mrx85RJr5xV2tLgBYhfHkQVHPmFGnuyonXhUbUkPnDFiNrkB2AkzXUpiKRT8Psd57somBHJS36rbWypYsx7JvHRU9vWibiZnzQwQ4kAGeK2m4KADrHcd9vJob4zee9k7ei3Ds4uUvEemtPeemgXKnNKwCKZyJHdie1kmLSmzsaR6GzLoUjNQMJdvsdn
结束后官方给了WP,需要从一个码表有误的网站解码。atoolbox 而且是收费的,不然不让复制。要起办法。
这个编码是数字+小写+大写,标准的是数字+大写+小写。然后再base64得到flag的获取方法。
3,rsa
这题不用吐了,标准的共模攻击。加爆破+猜
0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476
7bef46892e7303636fad0bb2975da5b0
import hashlib
import sympy
from Crypto.Util.number import *
from flag import flag
secret_num = getPrime(1024)
p = sympy.nextprime(secret_num)
q = sympy.nextprime(p)
n = p*q
m = flag
m = bytes_to_long(m)
e1 = 17
e2 = 65537
c1 = pow(m,e1,n)
c2 = pow(m,e2,n)
print n
print c1
print c2
n =12622648226794437295285907715762273160549087287783658715433355393025103668786180214038006849500776774955412380742459324006617080478804955132885687228100852031784150270109946115760987774854414774879643952106987239541070722320295025654949956155324716751662451624675477770097132348128377971943616883883313692371471120068901341190286880410670181284790989548228297641097964702001648507680975713714781930981124394188481464693751302710866150827426941991523756578810062515497384310871640128790631773890386667863215444345943725898569505408739667927699190839817903000960737335900289022204305630893889255273492308856691612161453
c1 =2069817252169840045015233339777890938397404774452927054186544254633859908615441861276763444658161327904603750928901292769983775503527880348562979695379934993187252637741358745246989832877105166016097003572421755605863516529582202420112357783221635888465536470497363083940105005935276165963216472168263366130808251146999523133577491145098527077233137877877027109311035035671564412042969175668380088327398042035465653633077870674942794115509745623674779846077714081036650228362060648791805388523075632410344086018912810103618539991849663881708919974783925084360038112104938306143765782496409687895819712123472738464336
c2 = 5087870545271817892640623219878569622782838058554451886307068019741033367393482500332766660439373681437895962896678234299233939047660216837107894214270761986845870567085871666644457160123482278412075275526620613319748656723191454892670184643710957543552460627337741843912742922187912221836410737381570519383270086517384851023761375547365872991949738286176016608725099456615174326849134394823221186336322970507429065797411311177974378238281712502321889632322183653487323908861220567268830214508524179487689485210084598788941173955011442134645908452204449597117270958745019355253449645779959760831461621261753617565147
前边给了几个数字,没有提示,还好猜到第2行是md5.
先共模攻击得到明文,里边有3个问号,然后爆破。与md5比较。第1行4个始终不清楚是啥。
>>> rsa_gong_N_def(e1,e2,c1,c2,n)
e1,e2: 17 65537
mpz: (mpz(1), mpz(30841), mpz(-8))
13040004482820197264152094887458696112783771834143493211256752080158180123828231599327425661
>>> long_to_bytes(13040004482820197264152094887458696112783771834143493211256752080158180123828231599327425661)
b'flag{6b820?60a1bdd02210c?ff16e4?20164}'
#爆破其中的问号,用前边的md5确认
from hashlib import md5
v = 'flag{6b820?60a1bdd02210c?ff16e4?20164}'.split('?')
dic = '0123456789abcdef'
for i in dic:
for j in dic:
for k in dic:
f = v[0]+i+v[1]+j+v[2]+k+v[3]
if md5(f.encode()).hexdigest() == '7bef46892e7303636fad0bb2975da5b0':
print(f)
#flag{6b820b60a1bdd02210c3ff16e4220164}
4,chao
有500行代码,0解,WP说 SM2+SM3+SM4 确实厉害,不过这题我没看,毕竟7小时比赛500行代码。
5,ADFGVX
显然是ADFGVX编码,按码表中序号分行列对换成6个字符。不过代码写得很长。
from flag import flag
from random import choice
import re
class ADFGVX():
def __init__(self, key='ph0qg64mea1yl2nofdxkr3cvs5zw7bj9uti8', keyword='GERMAN'):
self.key = [k.upper() for k in key]
self.keyword = keyword
def remove_punctuation(self, text, filter='[^A-Z0-9]'):
return re.sub(filter,'',text.upper())
def encipher_char(self, ch, size=6, chars='ADFGVX'):
row = (int)(self.key.index(ch)/size)
col = (self.key.index(ch) % size)
return chars[row] + chars[col]
def encipher_string(self, string):
string = self.remove_punctuation(string)
ret = ''
for c in range(0,len(string)):
ret += self.encipher_char(string[c])
return ret
def sortind(self, word):
t1 = [(word[i],i) for i in range(len(word))]
t2 = [(k[1],i) for i,k in enumerate(sorted(t1))]
return [q[1] for q in sorted(t2)] #返回word里字母的序号
#string从keyword在序号取,间隔7
def encipher_sortind(self,string):
string = self.remove_punctuation(string)
ret = ''
ind = self.sortind(self.keyword)
for i in range(len(self.keyword)):
ret += string[ind.index(i)::len(self.keyword)]
return ret
def decipher_sortind(self, string):
ret = ''
ind = self.sortind(self.keyword)
for i in range(len(self.keyword)):
ret += string[ind.index(i)::len(self.keyword)]
return ret
def encipher(self,string):
step1 = self.encipher_string(string) #ADFGUX的两位表示key
step2 = self.encipher_sortind(step1)
return step2
def decipher(self, step2):
step1 = self.decipher_sortind(step2)
string= self.decipher_string(step1)
return string
def getKeyword(x):
key = ''.join([choice('abcdefghijklmnopqrstuvwxyz') for i in range(x)])
for i in key:
if key.count(i)!=1:
return getKeyword(x)
return key
'''
keyword = getKeyword(7)
enc = ADFGVX('ph0qg64mea1yl2nofdxkr3cvs5zw7bj9uti8',keyword)
print enc.encipher(keyword)
print enc.encipher('flag'+flag[5:-1])
# output
# XAGDFGVGXXXGAX
# DXVGGVGGVGVFXAFVFXFFXFVFFFVFDVVGADGVAVGDAAVXGDGXGXDFVFDAVADAXAAFFVFXXGVX
'''
代码也很长,不过确实没有可作的了,一点点看。代码写得很乱,不过理一下得到对应的加密方法。
这里的keyword实际上并不关心是哪个字符,只需要这7个字符的顺序的序号,所以keyword只需要爆破0-6的组合就行,这个量很小。
1,ADFGVX加密
2,按keyword的序号表依将取值间隔7个[i::7]
然后弄个解密程序爆破
cod1 = 'ADFGVX'
key='ph0qg64mea1yl2nofdxkr3cvs5zw7bj9uti8'
#加密等效
def enc(s, ttt):
enc1 = ''.join([cod1[key.index(i)//6]+cod1[key.index(i)%6] for i in s])
enc2 = ''.join([enc1[i::7] for i in ttt])
return enc2
def dec(s, ttt):
a = ['']*len(s)
ti = 0
i = 0
while True:
if ti>=len(s):
break
k = ttt[i]
for j in range(k,len(s),7):
a[j]= s[ti]
ti+=1
i+=1
if i>=7:
break
ss = ''.join([key[(cod1.index(a[i]))*6+cod1.index(a[i+1])] for i in range(0,len(a),2)])
#print(ss)
return ss
import itertools
for v in itertools.permutations([0,1,2,3,4,5,6]):
ss = dec('DXVGGVGGVGVFXAFVFXFFXFVFFFVFDVVGADGVAVGDAAVXGDGXGXDFVFDAVADAXAAFFVFXXGVX',v)
if ss.startswith('flag'):
print(ss, v)
'''
flag{fb0dd5203c02cf7c60dc99330b5bfa66} OK
flag{fdgdn590w30nc17iq0dc99330758fth6}
'''
6,数字华容道
这是个逆向题,不过逆向没有难度,很容易看到是数字华容道。有终盘,要恢复用的串(这个串是程序的移法:程序把空格向左右上下移,真实的移法是空格边上的块向空格移,所以这个方向是反的)。
这实际是个编程的题,中途相遇法。时间有限写得也很乱。
end = [5,1,0,2,9,6,3,8,13,15,10,11,14,4,7,12]
#end = [2,3,4,0,1,5,6,7,10,11,12,8,9,13,14,15]
used = []
stat = []
ok = False
def move(box,row,col,way,ss,ub):
global ok
if ok: return False
if way == 0:
if col==0: return False #0123 left,right,up,down
v1 = row*4+col-1
if way == 1:
if col==3: return False
v1 = row*4+col+1
if way == 2:
if row==0: return False
v1 = row*4+col-4
if way == 3:
if row==3: return False
v1 = row*4+col+4
tmp = [i for i in box]
v2 = row*4+col
tmp[v1],tmp[v2] = tmp[v2],tmp[v1]
if tmp not in used and tmp not in ub:
used.append(tmp)
stat.append(ss+str(way))
return True
sta = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0]
used1=[sta.copy()]
stat1=['X']
used2=[end.copy()]
stat2=['E']
i=0
ok = False
for i in range(17):
print(i)
used = []
stat = []
for j,b in enumerate(used1):
ss = stat1[j]
k = b.index(0)
row,col = k//4,k%4
for way in range(4):
move(b,row,col,way,ss,used1)
used1 = used.copy()
stat1 = stat.copy()
for b in used1:
if b in used2:
print(1,b, used1.index(b), stat1[used1.index(b)], stat2[used2.index(b)])
ok = True
break
if ok: break
used = []
stat = []
for j,b in enumerate(used2):
ss = stat2[j]
k = b.index(0)
row,col = k//4,k%4
for way in range(4):
move(b,row,col,way,ss,used2)
used2 = used.copy()
stat2 = stat.copy()
for b in used2:
if b in used1:
print(2,b, used2.index(b), stat1[used1.index(b)], stat2[used2.index(b)])
a2 = stat1[used1.index(b)][1:]
a1 = stat2[used2.index(b)][1:][::-1]
c = ''.join(['$%@#'[int(i)] for i in a2])+''.join(['%$#@'[int(i)] for i in a1])
print(c)
ok = True
break
if ok: break
运行很久,不过这不是槽点。机子慢,内存大点很快点。
槽点是这个串不是提交用的,输入程序中,提示是md5(input),要作md5,这也正常,不正常的是:
md5(b'%#$#$#%@$#$@@%%#$@$@%%#%@$##%#\n').hexdigest()
'74e65379eb7cebc973a741756a8f441c'
需要有个回车,还好我猜出来了。