欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

****实验Pre1

程序员文章站 2022-04-26 09:39:03
...

赞赏码 & 联系方式 & 个人闲话

****前言

Pre1

1.(一定要看)阅读Python Tutorial

会大致看懂基本语法能完成下个任务就可以了,不要求学会这门语言

http://www.pythondoc.com/pythontutorial3/index.html

 

2.Python实现Base64

搜索Base64算法资料,详细解释该算法。用Python实现它,把自己的学号(字母大写)用Base64编码输出。并且把上面的源代码文件编译成pyc文件。(不要抄袭)

代码:

#Base64的索引与对应字符的关系
Base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
#待编码字符
STR="E41614018"
#转化成list方便处理缺失字节情况
Str=list(STR)
print("明文:  "+STR)
print("Base64:", end='')
#每组三个字符即3*8=24bit,转换为
for i in range(0,len(Str),3):
    a=ord(Str[i])
    #若缺2字节
    if len(Str)-1==i:
        b=0;
    else:
        b=ord(Str[i+1])
    #若缺1or2字节
    if (len(Str)-1==i)|(len(Str)-2==i):
        c=0;
    else:
        c=ord(Str[i+2])

    #拆成4个6bit,计算各自的索引号
    A=  a>>2
    B=((a&0b00000011)<<4)+((b&0b11110000)>>4)
    C=((b&0b00001111)<<2)+((c&0b11000000)>>6)
    D=  c&0b00111111

    #根据索引在Base64寻找,并输出对应字符
    #若缺2字节
    if len(Str)-1==i:
        print(Base64[A]+Base64[B]+'==', end='')
    else:
        #若缺1字节
        if (len(Str)-2==i):
            print(Base64[A]+Base64[B]+Base64[C]+'=', end='')
        else:
            #若不缺字节
            print(Base64[A]+Base64[B]+Base64[C]+Base64[D], end='')
print("\n")

运行结果:

****实验Pre1

输出内容:

明文:  E41614018

Base64:RTQxNjE0MDE4

小结与讨论:

Base64编码算法能够将任意的字节数组数据,通过算法参照“Base64编码索引表”生成只有“大小写英文字母、数字、+、/”(共64个字符)内容表示的字符串数据,即将任意的内容转换为可见的字符串形式。

Base64算法在编码时将数据按照3个字节一组的形式进行处理,每3个字节在编码之后被转换为4个字节。而当数据的长度无法满足3的倍数的情况下,最后的数据需要进行填充操作,即补“=” (这里“=”是填充字符表示没有数据,而不是上述64个字符中包含的字符)。

这里需要注意的是:Base64是编码算法而不是加密算法,只是用来编码字节数组形成字符串的。Base64算法提供了解码功能,并且任何人都可以将Base64的编码结果解码成唯一的原文。

 

3.反编译

找班上学号和你相邻的一位同学要一下上面的pyc文件(不是源代码文件),然后搜索相关反编译工具把pyc反编译成Python源代码,最好能多找几种工具或者途径达到反编译的目的。

①在线反编译平台:https://tool.lu/pyc/:

****实验Pre1

②Python反编译工具---Easy Python Decompiler:

****实验Pre1

 

反编译失败,系统提示:Magic value mismatch魔法值不匹配。这是因为它只支持python2.7与python3.4以下的版本。

③在线反编译平台http://tools.bugscaner.com/decompyle/

****实验Pre1

 

4.Cracking SHA1-Hashed Passwords

去https://www.mysterytwisterc3.org/用组长的学号注册一个账号(字母大写),

注册的时候有个Captcha可能要FQ才能显示,账号密码记住以后课堂要用到。

完成关卡Cracking SHA1-Hashed Passwords

https://www.mysterytwisterc3.org/en/challenges/level-ii/cracking-sha1-hashed-passwords

代码:

import hashlib
import copy

#递归求解1-8的全排列
def permutation(lst,k):
    result = []
    length = len(lst)
    tmp = [0]*k
    def next_num(a,ni=0):
        if ni == k:
            result.append(copy.copy(tmp))
            return
        for lj in a:
            tmp[ni] = lj
            b = a[:]
            b.pop(a.index(lj))
            next_num(b,ni+1)
    c = lst[:]
    next_num(c,0)
    return result

P=permutation([1,2,3,4,5,6,7,8],8)

SS = [[0 for i in range(4)] for i in range(9)]
S = [[0 for i in range(4)] for i in range(9)]
#放入所有可能选择
SS[1][1]="Q"
SS[1][2]="q"
SS[2][1]="W"
SS[2][2]="w"
SS[3][1]="I"
SS[3][2]="i"
SS[4][1]="N"
SS[4][2]="n"

SS[5][1]="%"
SS[5][2]="5"
SS[6][1]="("
SS[6][2]="8"
SS[6][3]="["
SS[7][1]="="
SS[7][2]="0"
SS[7][3]="}"
SS[8][1]="*"
SS[8][2]="+"
SS[8][3]="~"
flag=0;
#print(len(P),len(P[1]))

#遍历每一种排列情况
for i in range(len(P)):
    if flag==1:
        break;
    #根据排列组成S
    for j in range(len(P[1])):
        if flag==1:
            break;
        S[j+1]=SS[P[i][j]]
    sha1=""
    #print(S)
    #对于每种排列,每个键又有2、3种选择
    #遍历所有选择
    for a in range(1,4):
        #已经找到则退出
        if flag==1:
            break;
        #遇到为0的选项则跳过该可能
        if S[1][a]==0:
            continue
        for b in range(1,4):
            if flag==1:
                break;
            if S[2][b]==0:
                continue
            for c in range(1,4):
                if flag==1:
                    break;
                if S[3][c]==0:
                    continue
                for d in range(1,4):
                    if flag==1:
                        break;
                    if S[4][d]==0:
                        continue
                    for e in range(1,4):
                        if flag==1:
                            break;
                        if S[5][e]==0:
                            continue
                        for f in range(1,4):
                            if flag==1:
                                break;
                            if S[6][f]==0:
                                continue
                            for g in range(1,4):
                                if flag==1:
                                    break;
                                if S[7][g]==0:
                                    continue
                                for h in range(1,4):
                                    if flag==1:
                                        break;
                                    if S[8][h]==0:
                                        continue
                                    string=S[1][a]+S[2][b]+S[3][c]+S[4][d]+S[5][e]+S[6][f]+S[7][g]+S[8][h]        
                                    #计算sha1值
                                    sha1=hashlib.sha1(string.encode('utf-8'))
                                    #print(sha1.hexdigest())
                                    #若相同则输出对应密码
                                    if sha1.hexdigest()=='67ae1a64661ac8b4494666f58c4822408dd0a3e4':
                                        print('We found it : '+S[1][a]+S[2][b]+S[3][c]+S[4][d]+S[5][e]+S[6][f]+S[7][g]+S[8][h])
                                        print(sha1.hexdigest())
                                        flag=1

运行结果:

****实验Pre1

结果验证:

密码:(Q=win*5

将密码提交到网站上,提示已经成功解题:

****实验Pre1

小结与讨论:

本题我们求解的基本思路还是暴力**。仔细观察题目所给输入密码的键盘图:

****实验Pre1

考虑到题目应是短时间内可解的,所以我们做出如下的假设来减少计算量(后来得出的密码也证明假设是合理的)

(1)真正作为密码输入的应该只有Q、W、5、8、0、I、N、+这8个键(当然每个键会有不同的输入),shift键、方向键和右侧数字键都只做到控制作用,并没有实际的字符输入;

(2)不考虑重复按键的情况,否则该问题将无法求解。

于是,我们可以得到如下思路:

①由于我们未知这8个键的敲击顺序,我们要找出其全排列,易知为8的阶乘种;

②其次对于每一种排列情况又会有不同的字符组合,同一个键,如+键,可以输入“+”、“-”、“*”这3种字符。即使对Q之类的字母键也会有“Q”与“q”的区别,所以我们要对这些不同的字符组合进行遍历;

③对于每一种字符组合我们利用hashlib库来计算其sha1值与我们的目的sha1值进行比较,若相同则说明密码已经找到,即**成功。

 

5.4B58475789E60DBF1A28GD638B556A938134644C8

从前有一个熊孩子入侵了一个网站的数据库,找到了管理员密码,手一抖在数据库中修改了一下:

现在的密码变成4B58475789E60DBF1A28GD638B556A938134644C8

那个熊孩子其实就是我!肿么办求解原始密码!在线等,挺急的。

hint:密码长度为5

代码:

import hashlib
import copy

#递归求解0-4的全排列
def permutation(lst,k):
    result = []
    length = len(lst)
    tmp = [0]*k
    def next_num(a,ni=0):
        if ni == k:
            result.append(copy.copy(tmp))
            return
        for lj in a:
            tmp[ni] = lj
            b = a[:]
            b.pop(a.index(lj))
            next_num(b,ni+1)
    c = lst[:]
    next_num(c,0)
    return result
flag=0;
P=permutation([0,1,2,3,4],5)
#print(P)
#所有字符
SS=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9']

#通过五次循环从字符池中挑选出5个字符(因为题目给出密码为5位)
for a in range(len(SS)-4):
    if flag==1:
        break
    for b in range(1,len(SS)-3):
        if flag==1:
            break
        for c in range(2,len(SS)-2):
            if flag==1:
                break
            for d in range(3,len(SS)-1):
                if flag==1:
                    break
                for e in range(4,len(SS)):
                    if flag==1:
                        break
                    S=SS[a]+SS[b]+SS[c]+SS[d]+SS[e]
                    #对于挑选出的5个字符,进行全排列
                    for i in range(len(P)):
                        s=S[P[i][0]]+S[P[i][1]]+S[P[i][2]]+S[P[i][3]]+S[P[i][4]]
                        sha1=hashlib.sha1(s.encode('utf-8'))
                        #print(sha1.hexdigest())
                        #若相同则输出对应密码
                        if sha1.hexdigest()=='4b58475789e60dbf1a28d638b556a938134644c8':
                            print('We found it : '+s)
                            print(sha1.hexdigest())
                            flag=1
                            break         

运行结果:

****实验Pre1

小结与讨论:

本题的解题思路和第4题相似,首先我们很容易看出字符“G”是多余的,将其去除。接下来就是暴力**了,暴力的方法就是从我们设定的字符池里面挑选出5个字符(因为题目给出密码为5位),再把挑选出的5个字符进行全排列。代码编写时我们利用了上一题的部分代码并进行了修改。

最后求解得密码为:BSWAP。至此,实验顺利完成。

 

相关标签: ****