赛博空间,攻防之战,此起彼伏
矛与盾的对决,攻与守的碰撞
在这里,我们一起来看
道德黑客使用了哪些杀手锏
正义蓝军如何见招拆招
在攻防对战中,暴力破解是红队外网打点过程中不可或缺的一个重要手段。其成本低,利用简单,攻击收益大,一旦成功,往往等同于获得了通向内网的钥匙。除了加强用户的安全意识,尽可能避免弱口令外,防御者往往会在前端设下层层障碍,提高攻击者暴破密码的门槛。本文讨论了前端加密发展历程以及攻击者绕过思路的发展,并借助playwright框架给出了自动化暴破的新思路和相关示例代码。
为了应对攻击者的暴力破解,防守方通常会采用不同方式进行加密。下面,我们介绍一下攻击者是如何应对不同加密方式的。
对称加密
针对密码暴破,最简单的防御方法是通过前端使用对称加密,如AES和DES,来阻止密码进行明文传输。但这种方式的弊端也显而易见,攻击者可以通过翻看前端js代码,获取加密模式、填充方式、偏移量、数据块大小、密码等解密数据,调试后可以通过编写python脚本对密码字典进行加密。
非对称加密和自定义加密算法
随着密码学的发展,RSA2作为新一代非对称加密算法逐渐被运用到前端加密中,由于公私钥分离,这在一定程度上提高了攻击者调试的门槛。此外,有些开发者会自定义加密函数对密码字段进行加密。作为应对措施,攻击者可提取网页中对密码进行加密的那段JS代码,通过BurpCrypto插件为intruder模块添加processor,把暴破的payload加密。
webpack打包
随着前后端分离的热潮,webpack工具逐渐应用于vue等框架中。webpack除了缩小项目体积,提高加载速度外,还对代码进行了一定程度的混淆,极大降低了前端JS代码的可读性。
攻击者若要对webpack打包的网站进行暴力破解,需要掌握JS断点调试等逆向技术,或挖掘到该网站的sourcemap泄露漏洞,利用.js.map文件来进行逆向还原,这给暴破带来不小的难度。
那么,有没有一种方式可以忽略一切前端加密措施,模拟用户在浏览器手动输入账号密码呢?实际上,在Web自动化测试领域,往往使用Python等脚本语言将以前的人为测试转化为机器测试,极大提高测试效率。我们可以借助pyppeteer、selenium、playwright等Web 浏览器自动化工具来暴破账号密码。
将playwright武装成爆破工具
Playwright 是微软在 2020 年初开源的新一代自动化测试工具,它的功能类似于 Selenium、Pyppeteer 等,都可以驱动浏览器进行各种自动化操作。
使用playwright模拟用户登录操作
Playwright 目前提供了 Python 和 Node.js 的 API,这里我们使用python。
首先,我们导入Playwright库中的sync_playwright模块,用于同步执行Playwright库中的函数。然后,代码定义了一个主函数,用来执行浏览器操作。
在主函数中,首先定义了要访问的URL,以及登录的用户名和密码。然后,使用sync_playwright()函数创建了一个新的浏览器对象,并使用p.chromium.launch(headless=False)函数打开了一个新的浏览器窗口。为了方便观看效果,我们取消了默认的无头浏览器模式。
然后,使用browser.new_context()函数创建了一个新的浏览器上下文,并设置了本地语言为中文和忽略HTTPS错误。随后,使用context.new_page()函数创建了一个新的浏览器页面,并使用page.goto()函数访问了给定的URL。然后,使用page.once()函数注册了一个回调函数,用来处理页面中弹出的对话框。
接下来,代码使用了两个page.locator()函数来填写登录表单中的用户名和密码。最后,使用page.get_by_role()函数找到了页面中的登录按钮,并使用click()方法点击了它,以完成登录操作。通过sleep语句,我们可以更直观地看到效果。
通过响应包特征判断登录是否成功
通过抓包我们可以发现,如果密码不正确,响应包会出现Please enter valid LoginName and Password,我们可以以此为依据判断暴破是否成功。
我们可以定义一个新的函数on_response(),用来处理页面的响应事件。这个函数接收一个参数response,表示页面的响应对象。在函数中,首先使用response.finished()方法确保响应已完成,然后检查响应的URL和请求方法是否与预期的值相等。如果相等,则检查响应的文本内容是否包含特定的关键字,如果不包含,则表示登录成功,打印出相应的消息。之后,我们可以使用page.on()函数注册上面定义的on_response()函数,用来处理页面的响应事件。相关代码如下:
通过前端页面特征判断登录是否成功
对于部分防护严密的网站,往往后端响应包经过加密,此时难以定位响应包特征,因此我们可以通过提取前端页面特征判断是否登录成功,如最常见的标题。如果登录后标题还是带登录页、Login Page等特征,则说明账号或密码错误,跳转回了登录页。
通过OCR技术绕过图形验证码
如果登录界面存在验证码,我们可以使用OCR库或者第三方API帮我们识别验证码结果。这里我们使用国内开发者开发的ddddocr库。
我们首先使用ddddocr.DdddOcr()函数创建了一个新的验证码识别器对象,然后定义了要访问的URL,以及登录的用户名和密码的列表。接下来,我们使用page.locator()函数获取页面上的验证码图片,并使用page.screenshot()函数截取图片并保存到本地。然后,我们使用open()函数打开保存的图片文件,并使用ocr.classification()函数将图片中的验证码识别出来,再使用page.fill()函数将识别出的验证码填入输入框。
通过模拟鼠标操作绕过简易滑块验证码
在实战中,我们经常也会遇到带滑块的验证码,这时就需要我们运用playwright的api模拟鼠标操作,代码如下。
在这段代码中,bounding_box 方法用来获取一个元素(通过 locator 方法查找到的元素)在页面中的位置和大小。我们通过对page.mouse对象进行操作,首先模拟鼠标移动到滑块中心位置,通过down方法按住滑块,然后通过move方法让滑块滑动到最右边,之后再用up方法将鼠标松开,这样我们就模拟了一个正常用户的操作。
随着开发人员安全意识的加强,暴力破解的难度也在逐步提高,可以预见到的是将密码明文传输的网站会越来越少。通过利用web的自动化测试工具,我们可以尽可能模拟真实用户的登录操作来突破前端防御策略。
关于作者:
Lion:青藤红队一队成员,主要研究方向为红蓝对抗和红队武器库开发。
-完-