小白全流程解读代码和自己的思路,欢迎大家一起学习和批评指正。
被骗了,明明是一个web题,进去之后,却发现是一道加密题,正好是短板,难度不大,可以写代码,就放上来了。
一、解析题目
题目已经写的很清楚了,对miwen进行逆向加密加密就可以得到flag,我们先解读一下这个php代码,到底做了什么加密。
function encode($str){ #定义了一个加密方法
$_o=strrev($str); #把str反转,赋值给$_o,比如把“abc”变成了?“cba”
// echo $_o;
for($_0=0;$_0<strlen($_o);$_0++){ #定义了一个for循环,$_0为0(上面是欧,这里是零),条件是当$_0小于$_o的字符长度,完成循环则$_0+=1
$_c=substr($_o,$_0,1); #这里$_0充当了下标的概念,substr(a,b,c)即取a中第b位往后第c段字符,故就是取$_o中第1,2,3,4...个字
$__=ord($_c)+1; #对取到的字符转unicode编码后+1
$_c=chr($__); #转字符
$_=$_.$_c; #新的字符逐个拼接
}
return str_rot13(strrev(base64_encode($_)));#对生成的新字符串base64编码后反转再进行rot13编码
}
二、解题思路
这个算法的逆向在看懂加密思路后就比较清晰了,对密文先进行rot13解密>反转>base64解码>新的字符串逐个获取字符>对每个字符取unicode码后-1>unicode编码转字符,再把所有新字符拼接成新的字符串>最后再次反转
可能用php写解码代码会更快,但php用的不熟练,所以用python写了,重点讲一下rot13解码的方法。
import base64
s = "a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws"
def rot13_decode(list):
new_list=""
for a in list:
if a.isalpha():
b=ord(a.upper())-ord("A") #取每位进行大写转换便于后面的位数运算
b=(b-13)%26 #取其向后移动13位的字码位
b=chr(b+ord("A"))if a.isupper() else chr(b+ord("a")) #三目运算符,作比较,如果前面的a本来就是大写,则直接得到变换后的大写字母,如果前面的是小写,则需要把变换的位数加上小写a的ASII码,这一步是对刚才字母大写的恢复
else:
b=a
new_list+=b
return new_list
list1=base64.b64decode(rot13_decode(s)[::-1]).decode('utf-8') # base64.b64decode解码的结果是字节,需要进行编码成字符串
#print(list1)
list2=""
for n in list1:
n=chr(ord(n)-1)
list2+=n
final_list=list2[::-1]
print(final_list)
三、rot13加密
rot13加密解密用的都是一套公示,rot13加密只针对大写小字母,把字母看做一张表的话,就是a-z或者A-Z,rot13就是把字母向前移动13位,大小写不敏感,也就是不改变大小写,比如小写a,前移动13位就是a,也就是z,y,x,w,v,u,t,s,r,q,p,o,n。n正好a向后移动13位的字母,大写同理。
所以思路就是把原文中的每个字母提取出来,转换成ASCII码,然后对ASCII的数值-13,但单纯的把ASCII码-13的话,大写的a就变成了小写的N,所以需要大小写字母内部形成闭环,这里用到的办法就是取模,(x-13)%26,b的ASCII吗是98,减去a的ASCII码后是等于1,1-13=-12,-12%26=14,24+ord(“a”)=111,111对应的字母是o,大写字母同理。
为了减少工作量,先将所有字母大写, 大小字母在rot13加密中,结果也是互为大小写,最后再将ASCII码转成字符时添加判断,如果原字符是大写,则直接转成大写字母,如果原字符小写,则转成大写字母后再进行小写操作。
以上就是rot13代码块的解读,也有注释,代码比较粗糙,见怪莫怪。