• 如果您想对本站表示支持,请随手点击一下广告即可~
  • 本站致力于提供原创、优秀的技术文章~
  • 有任何疑问或建议 均可以在站点右侧栏处 通过各种方式联系站长哦~
  • CTF – RootMe解题报告 [Web-Server : PHP type juggling]

    渗透测试 EXP 51阅读 0评论

    挑战入口:Root-Me(https://www.root-me.org/en/Challenges/Web-Server/PHP-type-juggling)
      分类目录:Link to …(http://exp-blog.com/2019/01/02/pid-2597/12/)

    前置知识

    这题无法在网页上解题,推荐用 Burp Suite

    题目提示是 PHP loose comparison ,即 PHP 得弱类型判定,相关知识点可以查看这几篇文章:

    而其中与这挑战相关的漏洞主要有 3 个:

    • == 的弱类型比较
    • strcmp() 函数漏洞
    • 0e 开头的 MD5 (其实用不到,只是混淆项)

    题目分析

    开启挑战后,页面只要求输入账号和密码:

    点击 Authentication source code 后可查看页面源码:

    很明显,只要能令 auth['data']['login'] == USER!strcmp(auth['data']['password'], PASSWORD_SHA256) 这两个条件为真,就可以令网页打印 $FLAG

    而条件中的 $USER$PASSWORD_SHA256 是定义在 secret.php 文件里面的常量,我们查看不到。唯一可以确认的是这两个常量的类型都是字符串 ,而且 $PASSWORD_SHA256MD5

    而我们可以控制的输入点是 $auth['data']['login']$auth['data']['password']

    利用这两个输入点,我们可以逐一构造 payload 控制条件判定。

    利用 == 弱类型比较

    首先是条件 auth['data']['login'] == USER

    由于 $USER字符串 类型,因此只需令 $auth['data']['login'] 的值为 数字 0 即可使得这个条件判定为真。

    这是因为 PHP 在比较 数字 == 字符串 时,会把字符串解析成数字 0 。

    利用 strcmp() 函数漏洞

    接下来是条件 !strcmp(auth['data']['password'], PASSWORD_SHA256)

    注意到题目特意在前面加了一个 ! 取反,换言之我们的目的是令 strcmp 的返回值为 0

    在正常情况下,当且仅当 strcmp 所比较的两个字符串相同时,才会返回 0 。

    但是我们不知道 $PASSWORD_SHA256 的值,所以只能从非正常情况下考虑。

    所谓的非正常情况,是指当 strcmp两个参数不全是字符串的情况:

    • 当 PHP 版本低于 5.2 时,会将两个参数先转换成字符串类型再比较
    • 当 PHP 版本高于 5.3.3 时,若一个参数是数组,另一个参数是字符串时,除了抛出异常,还会返回 0
    • 当 PHP 版本高于 5.5 后,如果任意一个参数不是字符串类型,直接返回 null

    从出题角度去考虑,只有第二个情况可以被我们利用,因此猜测题目的 PHP 版本应该是 5.3.3 。

    于是,不妨令 $auth['data']['password'] 的值为数组 []

    构造 payload

    结合前面分析,最终我们尝试构造这样的 payload :

    Your login 输入 0 ,在 Your password 输入 [] 。但是不起任何作用。

    使用 Burp Suite 捕获刚才的请求,发现我们输入的参数被转换成 Json :

    明显两个输入的参数都被转换成了字符串,甚至 [] 还被加密成 MD5 ,这样自然无法使我们的 payload 生效。

    于是直接在 Burp Suite 修改 Json 的参数,即构造真正的 payload 如下 (注意类型分别是数字数组):

    成功控制条件,得到 flag ,完成挑战:

    附:关于 0e 开头的 MD5 漏洞

    0e 其实是科学计数法的开头,例如 0e2 表示 0 x 10^2

    而当使用 == 比较 MD5 字符串,若恰好 MD5 是以 0e 开头,就会被判定为数字类型,可以用来绕过某些情况。

    虽然这题的 password 用 MD5 加密,但其实是混淆项,因为比较 MD5 使用的是 strcmp() 函数而非 == 操作符。


    转载请注明:EXP 技术分享博客 » CTF – RootMe解题报告 [Web-Server : PHP type juggling]

    喜欢 (1) 分享 (0)
    发表我的评论
    取消评论

    表情

    Hi,您需要填写昵称和邮箱!

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址