昨天一个比赛,让我吐吐槽

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'

需要有个回车,还好我猜出来了。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值