从哪儿说起呢
很多时候我们都需要去爬取一些网页上的内容,如果运气好是明文内容,那就相对简单了
如果是加密后的内容呢?
相信很多人都遇到过这种情况,如果你还没解决的话,快看看这文章吧
假的开始
目标地址:http://dir.scmor.com/google/
需要内容:谷歌镜像地址
我需要的内容,就是标记处的URL链接
真的开始
第一步:先手动查看链接的内容
1
第一步:先手动查看链接的内容
一共八个网址,其中第一个的地址是:
http://www.acgn.ren/
第二步:在网页源代码中,搜索第一步中的内容
1
第二步:在网页源代码中,搜索第一步中的内容
右键->查看源文件
Ctrl + F 搜索第一步中的域名
通过上面的两步小操作,并没有在源文件中搜索到域名
这时候,我想到下面两个可能:
域名通过ajax获取
域名加密过
第三步:看看需要的内容是通过Ajax获取还是加密内容
1
第三步:看看需要的内容是通过Ajax获取还是加密内容
打开开发者工具,来到netword面板,开启拦截后,F5刷新下网页
下面列表中会出现当前网页发出的每一个请求,如果域名是通过Ajax获取的
那么域名肯定会出现在下面请求中的返回内容中
我要做的就是一个一个点击查看,看看response里面是否包含有我想要的内容,如果有,那么数据就是通过Ajax来获取的
如果没有找到,说明域名可能是进行了加密(除了我上面说到的两种可能,不排除还有其他的可能)
文章中的这个案例,实际上就是将域名进行了加密
所以我们需要的内容是加密的内容
第四步:找出解密函数
1
第四步:找出解密函数
网站中的A标签的代码
1
现在访问
可以看到,在点击链接的时候,会访问visit方法,我在网站引入的JS中找到了visit方法
function visit(url) {
var newTab = window.open('about:blank'); //新建一个标签对象
if(Gword!='') url = strdecode(url); //如果Gword不等于空,则跳转的url等于strdecode函数的返回值
// var newTab = window.open(url);
newTab.location.href = url; //设置标签对象的地址为上面的url(不是参数)
//newTab.location.reload(true);
}
1
2
3
4
5
6
7
functionvisit(url){
varnewTab=window.open('about:blank');//新建一个标签对象
if(Gword!='')url=strdecode(url);//如果Gword不等于空,则跳转的url等于strdecode函数的返回值
// var newTab = window.open(url);
newTab.location.href=url;//设置标签对象的地址为上面的url(不是参数)
//newTab.location.reload(true);
}
我将上面的JS代码进行了注释,可以看到第三行中有个Gword变量,但是在当前函数的代码块中并没有这个变量
所以这个变量值肯定是在其他地方保存着,这样的话又可以用到第三步中的那样,一个一个请求中,查看response中是否包含需要的字符串
按照这样的操作,我在第一个请求中就找到了Gword变量,该变量就存在与网页源代码中
© 2013-2016 由思谋网提供技术支持.
var Gword = "noreply@scmor.com"; run();
var cnzz_protocol = (("https:" == document.location.protocol) ? " https://" : " http://");
document.write(unescape("%3Cspan id='cnzz_stat_icon_5600686'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "s96.cnzz.com/stat.php%3Fid%3D5600686' type='text/javascript'%3E%3C/script%3E"));
1
2
3
4
5
6
7
8
9
10
©2013-2016由思谋网提供技术支持.
varGword="noreply@scmor.com";run();
varcnzz_protocol=(("https:"==document.location.protocol)?" https://":" http://");
document.write(unescape("%3Cspan id='cnzz_stat_icon_5600686'%3E%3C/span%3E%3Cscript src='"+cnzz_protocol+"s96.cnzz.com/stat.php%3Fid%3D5600686' type='text/javascript'%3E%3C/script%3E"));
可以看到第五行Gword的值就是一个邮箱noreply@scmor.com
如果Gword的值不等于空,就进行下面的操作
url = strdecode(url);//参数中的url的值是DycgVRMoFjY/UAlcFldWBzRcCwcpHiYVIhpbUA==
1
url=strdecode(url);//参数中的url的值是DycgVRMoFjY/UAlcFldWBzRcCwcpHiYVIhpbUA==
最终URL的值就是A标签点击跳转的链接,再看下面的函数
就是解密的函数
strdecode函数:
function strdecode(string) {
string = base64decode(string); //base64解码string参数,string参数的值就是上面代码中的那段base64编码后的内容
key = Gword; //key赋值为上面的邮箱noreply@scmor.com
len = key.length; //邮箱的长度
code = '';
for (i = 0; i < string.length; i++) {//循环{string变量长度}次
var k = i % len;//k = i 余 len
var n = string.charCodeAt(i) ^ key.charCodeAt(k);string[i]的ascii数字 ^ key[k]的ascii数字
code += String.fromCharCode()//ascii数字到字母(num)
}
return base64decode(code)//最后将code进行base64解码,即为最终的地址
}
1
2
3
4
5
6
7
8
9
10
11
12
functionstrdecode(string){
string=base64decode(string);//base64解码string参数,string参数的值就是上面代码中的那段base64编码后的内容
key=Gword;//key赋值为上面的邮箱noreply@scmor.com
len=key.length;//邮箱的长度
code='';
for(i=0;i
vark=i%len;//k = i 余 len
varn=string.charCodeAt(i)^key.charCodeAt(k);string[i]的ascii数字^key[k]的ascii数字
code+=String.fromCharCode()//ascii数字到字母(num)
}
returnbase64decode(code)//最后将code进行base64解码,即为最终的地址
}
上面的函数的解密大概逻辑
循环(string变量长度)次
k = i % len(k = i 余 len)
c = (string变量的第i位字符的ascii码) ^ (key变量的第k位字符的ascii码)
code = ascii码到字符(c)
base64解码code变量,并返回
先看看这函数到底能不能解密吧
F12->Console:
>strdecode("DycgVRMoFjY/UAlcFldWBzRcCwcpHiYVIhpbUA==")
<"http://www.acgn.ren/"
1
2
>strdecode("DycgVRMoFjY/UAlcFldWBzRcCwcpHiYVIhpbUA==")
<"http://www.acgn.ren/"
可以看到还真解密出来了~~~
这样基本上就找到了想要的内容了,但是…
这玩意得运行JS才能解密啊,万一我是PHP或Py咋办…
其实我觉得把js解密函数转为Python或者其他语言来写,就OK了
将JS代码转换为Python
JS解密函数
function strdecode(string) {
string = base64decode(string); //base64解码string参数,string参数的值就是上面代码中的那段base64编码后的内容
key = Gword; //key赋值为上面的邮箱noreply@scmor.com
len = key.length; //邮箱的长度
code = '';
for (i = 0; i < string.length; i++) {//循环{string变量长度}次
var k = i % len;//k = i 余 len
var n = string.charCodeAt(i) ^ key.charCodeAt(k);//string[i]的ascii数字 ^ key[k]的ascii数字
code += String.fromCharCode()//ascii数字到字母(num)
}
return base64decode(code)//最后将code进行base64解码,即为最终的地址
}
1
2
3
4
5
6
7
8
9
10
11
12
functionstrdecode(string){
string=base64decode(string);//base64解码string参数,string参数的值就是上面代码中的那段base64编码后的内容
key=Gword;//key赋值为上面的邮箱noreply@scmor.com
len=key.length;//邮箱的长度
code='';
for(i=0;i
vark=i%len;//k = i 余 len
varn=string.charCodeAt(i)^key.charCodeAt(k);//string[i]的ascii数字 ^ key[k]的ascii数字
code+=String.fromCharCode()//ascii数字到字母(num)
}
returnbase64decode(code)//最后将code进行base64解码,即为最终的地址
}
上文中已经把解密的逻辑写出来了,用Python照样写就OK了
import base64
#bse64解码函数(直接返回string类型的)
def base64_decode(string):
byteStr = string.encode(encoding='utf-8')
result = base64.b64decode(byteStr).decode()
return result
#解密函数
def decode(string):
result = base64_decode(string) #base64解码string参数,string参数的值就是上面代码中的那段base64编码后的内容
key = "noreply@scmor.com" #Gword
keyLen = len(key) #Gword长度
code = ''
i = 0
while (i < len(result)):
k = i % keyLen
n = ord(result[i]) ^ ord(key[k])
code += chr(n)
i += 1
return base64_decode(code)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
importbase64
#bse64解码函数(直接返回string类型的)
defbase64_decode(string):
byteStr=string.encode(encoding='utf-8')
result=base64.b64decode(byteStr).decode()
returnresult
#解密函数
defdecode(string):
result=base64_decode(string)#base64解码string参数,string参数的值就是上面代码中的那段base64编码后的内容
key="noreply@scmor.com"#Gword
keyLen=len(key)#Gword长度
code=''
i=0
while(i<len(result)):
k=i%keyLen
n=ord(result[i])^ord(key[k])
code+=chr(n)
i+=1
returnbase64_decode(code)
试试看能不能解密,参数=DycgVRMoFjY/UAlcFldWBzRcCwcpHiYVIhpbUA==
>>> decode('DycgVRMoFjY/UAlcFldWBzRcCwcpHiYVIhpbUA==')
'http://www.acgn.ren/'
1
2
>>>decode('DycgVRMoFjY/UAlcFldWBzRcCwcpHiYVIhpbUA==')
'http://www.acgn.ren/'
这样代码就解处来了
反正无聊在写个加密的
def encode(string):
string = base64.b64encode(string.encode(encoding='utf-8')).decode()
key = "noreply@scmor.com" #key赋值为上面的邮箱noreply@scmor.com
keyLen = len(key) #邮箱的长度
code = ''
i = 0
while (i < len(string )):#循环{string变量长度}次
k = i % keyLen #k = i 余 len
n = ord(key[k]) ^ ord(string [i]) #string[k]的ascii数字 ^ key[i]的ascii数字
code += chr(n) #将ascii码转换为字母
i += 1
return base64.b64encode(code.encode(encoding='utf-8')).decode() #返回加密后的内容
1
2
3
4
5
6
7
8
9
10
11
12
defencode(string):
string=base64.b64encode(string.encode(encoding='utf-8')).decode()
key="noreply@scmor.com"#key赋值为上面的邮箱noreply@scmor.com
keyLen=len(key)#邮箱的长度
code=''
i=0
while(i
k=i%keyLen#k = i 余 len
n=ord(key[k])^ord(string[i])#string[k]的ascii数字 ^ key[i]的ascii数字
code+=chr(n)#将ascii码转换为字母
i+=1
returnbase64.b64encode(code.encode(encoding='utf-8')).decode()#返回加密后的内容
大概逻辑是这样:
a ^ b = c,已知c和b的值,求a? a = c ^ b
本文来自: 蜗蜗侠's Blog-关注网络安全 http://blog.icxun.cn/Python/438.html