19css加密css加密-雪碧图-数据干扰-md5-图片识别-css位置偏移-ob混淆-debuger
@ -0,0 +1,7 @@
|
|||||||
|
_0x32aef8['exSuS']($, '.odd')['text']('')['append'](datas);
|
||||||
|
|
||||||
|
|
||||||
|
var _0x20c24d = '.' + _0x124e6b(btoa(data['key'] + data['value'])['replace'](/=/g, ''));
|
||||||
|
|
||||||
|
// 'bzds2IWwijoIAmB0rxs8'
|
||||||
|
|
After Width: | Height: | Size: 57 KiB |
After Width: | Height: | Size: 65 KiB |
After Width: | Height: | Size: 6.2 KiB |
After Width: | Height: | Size: 98 KiB |
After Width: | Height: | Size: 154 KiB |
After Width: | Height: | Size: 43 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 18 KiB |
@ -0,0 +1,70 @@
|
|||||||
|
from parsel import Selector
|
||||||
|
import base64
|
||||||
|
import requests
|
||||||
|
import hashlib
|
||||||
|
import ddddocr
|
||||||
|
|
||||||
|
ocr = ddddocr.DdddOcr(beta=True)
|
||||||
|
|
||||||
|
|
||||||
|
def md5_value(key):
|
||||||
|
input_name = hashlib.md5()
|
||||||
|
input_name.update(key.encode("utf-8"))
|
||||||
|
sign = (input_name.hexdigest()).lower()
|
||||||
|
return sign
|
||||||
|
|
||||||
|
|
||||||
|
def challenge19(page):
|
||||||
|
url = "https://www.python-spider.com/api/challenge19"
|
||||||
|
payload = f"page={page}"
|
||||||
|
session = requests.session()
|
||||||
|
headers = {
|
||||||
|
'content-type': 'application/x-www-form-urlencoded; charset=UTF-8'
|
||||||
|
}
|
||||||
|
session.headers = headers
|
||||||
|
response = session.request("POST", url, headers=headers, data=payload)
|
||||||
|
return response.json()
|
||||||
|
|
||||||
|
|
||||||
|
def run():
|
||||||
|
data_num = 0
|
||||||
|
for page in range(1, 101):
|
||||||
|
response_json = challenge19(page)
|
||||||
|
print(response_json)
|
||||||
|
info = response_json.get('info')
|
||||||
|
key = response_json.get('key')
|
||||||
|
value = response_json.get('value')
|
||||||
|
encode_str = base64.encodebytes((key + value).encode('utf8'))
|
||||||
|
res_md5 = md5_value(str(encode_str, 'utf-8').replace('=', '').rstrip())
|
||||||
|
info_sel = Selector(info)
|
||||||
|
info_list = info_sel.xpath('//td[@class="info"]').extract()
|
||||||
|
|
||||||
|
for info in info_list:
|
||||||
|
info_sel = Selector(info)
|
||||||
|
img_list = info_sel.xpath('//img').extract()
|
||||||
|
num = 0
|
||||||
|
my_list = []
|
||||||
|
for img in img_list:
|
||||||
|
if res_md5 in img:
|
||||||
|
continue
|
||||||
|
img_sel = Selector(img)
|
||||||
|
style_num = int(img_sel.xpath('//img/@style').extract_first().replace('left:', '').replace('px', ''))
|
||||||
|
src = img_sel.xpath('//img/@src').extract_first().replace('data:image/png;base64,', '')
|
||||||
|
src_num = ocr.classification(src)
|
||||||
|
|
||||||
|
my_list.append({
|
||||||
|
'src': src_num,
|
||||||
|
'style': style_num + num,
|
||||||
|
})
|
||||||
|
num += 9
|
||||||
|
my_list = sorted(my_list, key=lambda e: e.__getitem__('style'))
|
||||||
|
res_num = ''
|
||||||
|
for item in my_list:
|
||||||
|
res_num += item.get('src')
|
||||||
|
print(f'页数{page}:{res_num}')
|
||||||
|
data_num += int(res_num)
|
||||||
|
print(data_num)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
run()
|
@ -0,0 +1,80 @@
|
|||||||
|
# 知识点:md5,图片识别,css位置偏移,ob混淆,debuger
|
||||||
|
|
||||||
|
## 解题思路
|
||||||
|
|
||||||
|
### 一、display: none解决思路
|
||||||
|
|
||||||
|
查看请求地址,这里有2个`debuger`直接过掉
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
发现接口challenge19中info字段是一段html
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
分析内容,发现用数字图片的方式显示内容
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
<td class=\"info\">
|
||||||
|
<img src="xxxx" class="img_number 4a13ebc2e96b2381156dba12ff80cff7" style="left:-18px">
|
||||||
|
<img src="xxxx" class="img_number 752587204b02938c83c72e8417fe35b5" style="left:0px">
|
||||||
|
<img src="xxxx" class="img_number 752587204b02938c83c72e8417fe35b5" style="left:9px">
|
||||||
|
<img src="xxxx" class="img_number 752587204b02938c83c72e8417fe35b5" style="left:-9px">
|
||||||
|
<img src="xxxx" class="img_number 752587204b02938c83c72e8417fe35b5" style="left:0px">
|
||||||
|
<img src="xxxx" class="img_number 4a13ebc2e96b2381156dba12ff80cff7" style="left:9px">
|
||||||
|
</td>
|
||||||
|
|
||||||
|
查看审查元素,在审查元素中的html增加了`display: none;`css样式,但是这段代码不在接口challenge19返回结果中
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
html断点调试
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
进入断点可以找到这样一段js代码
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
其中的`datas`就是接口challenge19返回的html
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
利用控制台的打印改写js代码,如下,不难理解这就是jquery语法,将`datas`渲染到`class odd`中
|
||||||
|
|
||||||
|
$('.odd')['text']('')['append'](datas);
|
||||||
|
|
||||||
|
仔细查看这时的变量`datas`还是没有添加`display: none;`内容
|
||||||
|
|
||||||
|
下面开始单步调试......单步调试....单步调试,找到如下图这段js代码
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
简单翻译一下
|
||||||
|
|
||||||
|
var _0x20c24d = '.' + _0x124e6b(btoa(data['key'] + data['value'])['replace'](/=/g, ''));
|
||||||
|
|
||||||
|
发现`data['key'] + data['value']`就是接口challenge19返回的内容
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
`btoa`就是base64编码,
|
||||||
|
|
||||||
|
`_0x124e6b`就是md5加密,而且没有魔改过
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
返回的加密结果`4a13ebc2e96b2381156dba12ff80cff7`和html中`class="img_number`存在类似,这里就可以猜测如果`_0x124e6b`
|
||||||
|
加密后的值和`class="img_number`值相同,那么该img标签是`display: none;`
|
||||||
|
|
||||||
|
### 二、css位置偏移
|
||||||
|
|
||||||
|
css位置偏移如下,4张图片从上至下分别用`left=`+0,+9,+18,+27,得出的结果在把图片排序
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 三、图片识别
|
||||||
|
|
||||||
|
ocr = ddddocr.DdddOcr(beta=True)
|
||||||
|
src_num = ocr.classification(src)
|