前言
这个CMS非常适合入门代码审计的人去学习,因为代码简单且漏洞成因经典,对一些新手有学习价值,
前台注入
从入口开始:/semcms/Templete/default/Include/index.php
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xhTdHBVn-1651041211358)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/490ca1b2038f48148c14ac62455278ef~tplv-k3u1fbpfcp-zoom-1.image)]
跟进web_inc.php,首先包含
1)db_conn.php:建立与数据库的连接,代码量很少也很简单。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AYz9mmf4-1651041211363)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d1132db9178143ccb80c77b8d64d2e15~tplv-k3u1fbpfcp-zoom-1.image)]
2)contorl.php:对$_GET进行全局过滤危险的SQL函数。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KreyJyb9-1651041211366)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ea2ec9fa16b54ce0ab2d03956ffb9e2b~tplv-k3u1fbpfcp-zoom-1.image)]
这个过滤从最简单的角度来说,即mysql<8的情况下,把select禁用了,其实就没办法进行跨表查询,SQL利用造成危害的可能性会大大降低,当然这是一种直接且无需考虑用户体验为原则的暴力做法,点到为止吧。
回到web_inc.php,继续阅读,后面吸引我的地方,在于 89 line一处SQL语句的地方。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m4cHerBL-1651041211368)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/61af3f519dea4aa394d08ce12d8c2db1~tplv-k3u1fbpfcp-zoom-1.image)]
可以看到$Language没有单引号,直接拼接到语句中,且值由POST方式传递,不过这里经过了verify_str函数,导致我没有办法利用select进行子查询,获取到sc_user表的后台管理员用户密码,那么事实真的如此么?
$Language=test_input(verify_str($_POST["languageID"]));
经过verify_str函数处理后,会传入test_input函数,其返回值将会拼接进SQL语句中进行查询。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-78G5yaPL-1651041211372)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1d033faa08ee401ba9e6d4284186b7e5~tplv-k3u1fbpfcp-zoom-1.image)]
test_input里面有个有趣的函数stripslashes,函数的作用就是用于去除反斜杠,举个如图例子
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ItYI7bWs-1651041211373)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/45a327334d0342e18bd012d0528618ba~tplv-k3u1fbpfcp-zoom-1.image)]
那么绕过verify_str思路就水到渠成了。
分析下payload的原理
languageID=-1 uni\on sel\ect 1,concat(user_admin,0x2d,user_ps),3,4,5,6,7,8,9,10,11,12,13,14 from sc_user
un\ion&&sel\ect绕过了verify_str函数的正则匹配,经过test_input的stripslashes去掉反斜杠,最终拼接到数据库中执行的语句,实际上
返回的后台管理员的账号密码信息到$tag_indexmetatit变量中。