第四题:雪碧图 - 样式干扰
1、前言
久违的第四题终于要出炉了,这篇博客比我预想的完成时间要快,主要是没想到这次解题过程还比较顺利,竟然在没有参考其他大佬答案的前提下,自己摸索出来了,对我来说算是一个可喜可贺的小突破啊,虽然是道简单级别的题,但凭自己实力破解还是有点成就感的,算是逆向之路的一个小里程碑。好,那就不扯犊子了,进入主题!
2、题目理解
猿人学的题好就好在每道题都告诉你是什么类型的加密,这样我们开局就知道大致的破解方向,省去了前期的摸索阶段。题目类型很明确写了是css加密,也就是通过设置网页样式的形式来进行加密,所以我们突破口就是看看是用了什么形式的css加密。
3、解析过程
3.1、初窥门径
按常规套路,首先还是先打开页面看看数据形式,这里可以观察到这些数字的显示样式很明显有点怪异:
这里可以看出,跟之前的其他题目的都不一样,鼠标放上去背景会白底高亮显示,而且发现数字排列看起来有些不均匀,也没法复制。
对准数字,点击右键,发现提示在新标签页中打开图片,也就是说这些数字是以图片形式呈现的!另外在地址栏可以看到这个图片的url跟以前访问其他资源明显不一样,这串路径里有个很明显的字眼:base64
,难道是某种给图片地址加密的骚操作?
搜一搜谷歌百度啥的,发现所谓的
data:image/png;base64
其实是一种经过base64
编码后的内联图像,通过将图片直接嵌入到网页中,从而不用再从外部文件载入,也就是浏览器不必单独向服务器查询图像数据,可以使页面加载更快。总而言之这是一种有别于传统加载形式,将图片嵌入html的方法。
好的,那么既然知道了它是把图片加密了,那么我们肯定能把图片还原回来,这里我试了下找个图片编码在本地
base64
解码,并另存为图片,发现果然可以还原回来,然而这并没有什么卵用,题目要的是数字加和结果,只有数字对应的图片还是没法解决根本问题。于是机智的我想到了ocr,这种简单的图片那还不是分分钟给识别出来!直到想起来参赛注意事项里明确规定了只有第八题可以用ocr,这就有点尴尬。
# 图片还原
ha='iVBORw0KGgoAAAANSUhEUgAAABQAAAAdCAYAAACqhkzFAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAMTSURBVEhLrZY/TBNRHMe/bY82LeGA0Dp4NTGYqO1gdKEMwmQcGh38M5CQlGDSwWiMAwwYg2iCJsZJQ9CJ0ETsQMJgwuagLIUFXIAFXNoYcqDloLRXrq3v7v3aXktbSPCTXO77fZRvf/feu9+r5dz5iwX8R+oESigMPka6/wb2vSJUBx+1QoVD3kTz7DScb+f4YBVHA6U+ZKLPsON1IE9DtbDLP9AxEIawRgOEle4cKYSD+ZeQq8IcKquMXTbyOllPL7aiEWgSDRCmQAnahyHsiGQZruUvkIKXcObyFeM62zcOd1ylvwJ5MYDkuxA5Tjlw8A2S12iyGM7YODrujsFqfqTFCJw9L+CWyTPS3QPIBMgwKFBC9n4AaW4AdQVtQxEy1czBObkIJznAi9TDO6SLgVIYqt9QBq5YFEKCTC2momg2VXngD5bmnAc+uIqUIXQUOL/X3hJl5mHfUEgzPJ04pMUxAnN+CYeG1UlAmCLZANtqAk2kARG5m1zxQI9paWUZAsmGsArLnxOh0ZSxwCBypjwo2zQPxzCTgJ2kTtbbZ9zZ/7pRKO8WOOWqrX9iePyJiqnNGgTTuhRhgT5o5kc+JaeosDYssHbpx+OtXEziSIWqx0fqOFpg7ns2Zd24s8B1WE0V5h2mJW/ELTc0kjo2Zcm4s8ClikCIlR+si59tZpL66yosc2U8clM8bhgDkfVFUzuqR569rqXOqG7CPsOlEWiJJSraUaa/i3Q9upC94CHNCtr4WXoN+aJMzcFlakd73eGG5wnuhZHykmZ1tnx9TboYqDfNWLxoWDvqhfK+h0w1Pcg87cUBOavMmu1HMoxShuXJNNpNi7N3ewLJTyEUzIdQIIT0wgQ7EcmzxWifZMcEOZ3KY3Qwgp3RQOnbOfqJx5XGtlSOS4aK1tlHEIcXyHNsrW0dY6SBFX0ufShc70S21OwE5AR+lb+ZVfb5OVpGviGTTkHeSmBfScJqtdX55SAFoY0OsMXxISM6SvvNrshwrS7A9WoENupyv+O/oGm831sslno/RU6OsvsHu3+3yQH/AOyW6SvqnweCAAAAAElFTkSuQmCC'
print(base64.b64decode(ha))
with open('D:\yuan_8.png','wb') as f:
f.write(base64.b64decode(ha))
虽然上面一同分析只是解锁了一个新的小知识点,但还是要相信他对后面的分析还是有点作用的。
3.2、深入探究
3.2.1、确定原理
继续往下走,发现我们还没观察过xhr请求呢,先看看返回的数据到底是什么样的再说,可以看到通过http://match.yuanrenxue.com/api/match/4
这个接口,我们顺利的拿到了返回的数据,观察一下发现这里的info
字段里包含了请求的所有对应的数字图片,另外还包含了key、value
等字段,想来有可能在图片渲染的过程中用到。
首选还是分析一下
info
里的这串html
代码是什么形式的,这里我把他复制出来,粘贴到编译器了并格式化看了一下,可以看出这里每个td
节点内应该都是包含了一组图片,也就是页面时最后对应的那串数字:
这里试着运行一下这段
html
,发现最后显示的是这么一串鬼东西,无论是从上面的代码,还是最后浏览器渲染返回的结果都跟我们在题目数据请求渲染页面的看到的不太一样,一个是数字位数,另一个是数字顺序,比如我这里第一个区域的数字应该是6081
,但很明显这里掺杂了其他的干扰数字。
那么这里有必要搞清楚是通过什么形式改变了数字显示的顺序以及内容?这里我试着选中图片,并通过右键检查元素,想看看原始网页里图片是以什么形式嵌入展示的,不得不说chrome浏览器用着确实比较顺手!在
Elements
中一下就看到了所有图片样式设置。
一眼可以明显看到有些图片节点的
style
属性设置为display: none
,这就很好理解了,通过对照这些参数设置,明显发现这十几个图片节点中只有6081这四个图片节点没有该属性,此外left: 11.5px
这个属性就是控制图片坐标偏移的参数,经过几次调试观察,发现px
为正的图片向右偏移,为负的是向左偏移,为零的则位置不变!
3.2.2、逆向破解
以上基本确定了这个css加密的原理,但现在还有两个问题没搞清,那就是网页到底是通过什么来判断某些图片style
属性为display: none
的呢,其次是图片跟数字对应的关系是否有相应的关联逻辑?
首先对于第一点,回头再观察一下之前请求数据接口返回的info
里,每个图片对应的除了压缩编码、样式偏移设置以外,还有个class="img_number "
的属性节点,这里也是在一番观察后,发现在所有图片列表里,img_number
的值只有两类,其中一类对应的是在网页中display
属性为none
的图片,另一类则是正常显示出来的图片。
那么接下来就要找一下这个img_number
的生成逻辑,这里题目没有设置比较复杂,通过设置xhr断点,并在调用栈里往下逐层查看