小编一直在写爬虫,可是写久了之后,发现自己涉及的网站类型不够丰富,很少涉及到数据有加密类型的!所以今天就跟随大佬尝试破解一波js加密。
目标网站:谷歌学术镜像
获取目标:
按照惯例,第一步:查看该url是否在网页源代码里;第二步:如果没在网页源代码里,查看是否为ajax请求,找对应的请求文件看看里面是否有对应的内容;第三步:如果前两步都不成立,则说明数据被加密了,尝试找到对应的解密函数。
第一步:查看网页源代码:
我们点击上图中的第一个“现在访问”,浏览器打开了一个新的标签,获得了对应的url:http://so.hiqq.com.cn/twy/,复制该url,在网页源代码中ctrl + f查找这个url。发现在网页源代码中并没有这个url,说明第一步走不通,我们尝试第二步......第二步我们也发现走不通(肯定嘛,题目都是js加密。)。最后,我们来找找它是怎么加密的。
接下来怎么做呢?找就对了,找什么呢?我也不知道,于是我仔细观察了网页源代码:
以下是格式化后的视图:
autourl即自动生成url,我发现这个autourl刚好跟学术镜像对应上,那么上图那些看不懂的字符是什么呢?难道就是加密后的url???另外autourl是被包含到script里的,这就说明,我们能在js文件里找到。我们就试着找找看。
我们找到了“现在访问这个关键字”,也找到了autourl,仔细看看画红线的句子,
发现是生成一个a标签,而a标签的链接是一个javascript,后面跟了一个点击事件,即当我们点击‘现在访问时’,会触发这个事件,但是这是个怎样的事件呢?这个事件是一个visit函数,而这个visit函数的参数就是autourl的值。然并卵,我怎么知道这个visit函数是什么呢?我们再找找看这个visit函数
function visit(url) {
var newTab = window.open('about:blank');//创建一个新的窗口
if(Gword!='') url = strdecode(url); //如果Gword不为空,则url为调用strdecode函数后的url
// var newTab = window.open(url);
newTab.location.href = url; //将生成的url作为新窗口的url
//newTab.location.reload(true);
}
我将visit这个函数用自己的话写了注释,在这个函数里,有两个地方值得关注,第一个地方:Gword这个参数在这个函数里面没有被定义,所以我们还需要再找找它,第二个地方就是strdecode这个函数,看名字就是一个解密函数,这个函数的函数体我们得再找找。
同样,我将strdecode函数备注好
function strdecode(string) {
string = base64decode(string); //将传入的string参数采用base64解码后,将结果赋予string
key = Gword+'ok'; //key值为Gword+'ok',这里可以确定Gword是一个字符串
len = key.length; //获取key的长度
code = '';
for (i = 0; i < string.length; i++) { //循环次数为string的长度
var k = i % len; //k为i除以len的余数
code += String.fromCharCode(string.charCodeAt(i) ^ key.charCodeAt(k))
} //.fromCharCode():将数字转为一个字符
//.charCodeAt():将字符转换为一个数字
//a^b:二进制上下比较只有位不相等时才取1,否则取零
return base64decode(code)
}
然而此时我们还是没有找到Gword的值,要不去网页源代码里找找看。
嗨呀!事后诸葛亮是真的舒服啊!嘻嘻!!!果然像我们猜的一样,它是一个字符串。现在,让我们来整理一下刚才找到的线索和分析的结果(怎么自己想福尔摩斯呢!)
首先,我们发现,网页里并没有直接的url链接,而我们需要的url链接被加密了,而产生这个链接的a标签里有个visit函数:
即visit这个函数可以生成我们需要的url链接,visit函数的参数就是autourl的值:
但是这个visit函数生成的url链接来自于strdecode这个函数,也就是说,strdecode这个函数能生成我们需要的url链接,strdeocde函数的参数也为autourl的值
最后,我们发现strdecode这个函数解密url链接时还需要一个关键参数Gword。
现在我们在网页源代码里找到了它,然而一顿操作猛如虎之后发现,我不会js!!WTF!!。要不自己用Python写一个解密函数,即用Python翻译strdecode函数。
我们尝试写一写。
def base64_decode(String):
byteStr = String.encode("utf8", "ignore")
result = base64.b64decode(byteStr).decode("utf8", "ignore")
return result
def decode(string):
string = base64_decode(string) #base64解码string参数,string参数的值就是上面代码中的那段base64编码后的内容
key = "link@scmor.com..ok" #Gword
Len = len(key) #Gword长度
code = ''
for i in range(0, len(string)):
k = i % Len
n = ord(string[i]) ^ ord(key[k])
code += chr(n)
return base64_decode(code)
最后贴上完整代码:
import requests
import base64
from lxml import etree
import re
def request(url):
html = requests.get(url)
html.encoding = html.apparent_encoding
return html.text
def parse_content(html):
tree = etree.HTML(html)
script_text = tree.xpath('//script/text()')[0]
securty = re.findall(r'DSE8WyM[a-zA-Z0-9]+=*',script_text)
return securty
def base64_decode(String):
byteStr = String.encode("utf8", "ignore")
result = base64.b64decode(byteStr).decode("utf8", "ignore")
return result
def decode(string):
string = base64_decode(string) #base64解码string参数,string参数的值就是上面代码中的那段base64编码后的内容
key = "link@scmor.com..ok" #Gword
Len = len(key) #Gword长度
code = ''
for i in range(0, len(string)):
k = i % Len
n = ord(string[i]) ^ ord(key[k])
code += chr(n)
return base64_decode(code)
request = request("http://ac.scmor.com/")
security_list = parse_content(request)
for security_text in security_list:
print(decode(security_text))
最后获取到的链接: