记录我的第一次代码审计之旅(一)
郑重鸣谢 阿信!!!!!
一、 环境
环境嘛!!就是semcms
,随便上网搜一下,丢到网站根目录里去就好了,开始会让配置数据库,也超简单的说!!就不赘述了,需者自取
SEMCMS::: http://www.sem-cms.com/xiazai.html
二、审计发现
我个人对sql注入比较熟一点,所以一上来就先找的sql注入的点!!中途碰了几次壁也去找了找XSS漏洞提升了提升自信。
2.1 vuln1:前台语言配置sql注入漏洞
我拿到项目后,第一件事其实先在前端熟悉了一下整个业务,然后再到后台看项目的目录结构进一步熟悉
可以看到命名已经很明显了
edit | images | include | install | templete | zVODSK_Admin |
---|---|---|---|---|---|
一眼看不出来做什么的,进去看了看,很多的js、css文件,对我们作用不大 | 一看就是存放网站用的图片的 | 包含文件,那么这里面就有可能有一些重要的内容,如网页的通用框架、校验类等 | 安装app时使用的文件 | 这里面其实放的是前台的文件 | 后台管理相关的文件 |
ok基本的结构熟悉了之后,用phpstorm打开我们的项目,然后我做的第一件事就是去看了他的参数校验规则
这个contrl.php
就是,我们看看它怎么写的
最上面
if (isset($_GET)){$GetArray=$_GET;}else{$GetArray='';} //get
foreach ($GetArray as $value){ //get
verify_str($value);
}
如果有通过get
方法传的参数,则对每一个参数值调用verify_str
函数,那我们看看这个函数怎么写的
function verify_str($str) {
if(inject_check_sql($str)) {
exit('Sorry,You do this is wrong! (.-.)');
}
return $str;
}
就收一个参数$str
,然后调用inject_check_sql
函数,如果返回值为真,则显示错误信息,否则返回该字符串,那我们继续跟进inject_check_sql
函数
function inject_check_sql($sql_str) {
return preg_match('/select|insert|=|%|<|between|update|\'|\*|union|into|load_file|outfile/i',$sql_str);
}
该函数使用了preg_match
,表示如果我们传入的字符串中出现第一个参数中列出的字符串,那么返回true,否则返回false。可以注意到'
被过滤掉了,双引号没有,那么这个时候想,如果某一条sql语句使用双引号闭合或者干脆是数字,是不是就可以越过这一点了?select、union、update
也被过滤了,哭了,很明显可以利用的语句不多了,我们再看看有没有其他漏网之鱼,我们知道报错注入有一个函数为extractvalue
,没有被过滤,database() user datadir basedir
这些都没有被过滤,那么立足于这个,我们就可以在一定程度上搞事情了。
首先我们要找到一条闭合符为数字或者双引号的语句,或者闭合符为单引号但开发者没有对数据进行校验,且要满足通过post方式传参!!
我们直接全局搜索
select.*from.*where
眼尖的我看到了一句
select * from sc_tagandseo where languageID=$Language
很明显这里的参数为数字,这就满足了一个条件了,我们再看看$language
哪儿来的,直接双击定位到该语句的位置,我发现了
看到没有language
是通过post
传参的,但是我又注意到,$language
除了通过verify_str
校验,还经过了另一个函数test_input
校验,我们跟进去看看这个函数
首先替换了%
,然后去字符串首尾空格,解转义,实体编码。说实话这些过滤是针对XSS的,对我们sql注入毛的影响都没有,至于引号,我们的语句中都不会出现,它也没有办法实体编码,这我就放心了,那么接下来就是看看我们的sql语句是在哪个页面执行了。
这是一个配置类文件,看看它在哪被包含,这个文件中包含了大量的配置类信息,我猜它几乎在每一个页面都有,我们随便打开一个文件
然后我们在浏览器中访问这个文件
然后配置代理,使用bp抓包,把抓到的包发到重发器
然后像上图那样鼠标右击request
部分,修改请求方式为POST
,这里注意我踩了坑,我开始是直接手工将GET
改成POST
的,一直没有成功,浪费了很多时间!!!!
然后加上请求体
欸,大功告成,然后我就狗带了
直接报服务器内部错误,这谁惹得起!!!!
反正我觉得我的思路没有问题,没跑出来肯定不是我的锅!!!
2.2 vuln2:后台类别添加页sql注入漏洞
还是首先全局搜索sql语句,找数字型的,或者没有应用校验规则的,这里我直接贴我找到的一处:
这条sql语句在checifno
这个函数中,要执行要满足需\$fl=f
,我们要注入要满足$biao,$ziduan,$str
至少一个可控,我们看看哪儿调用了这个函数
找到一条满足条件的,跟过去
然后我们看看$PID
哪儿来的,继续跟
post
传参,经过test_input
函数,你以为这就完了?还没有,我们再看看这条sql要执行需要满足的其他条件。
我就直接总结了:
$CF=category
$Class=add
$category_name不为空
继续跟,首先看$CF怎么来的
get方式传参
再看$Class
一样get方式传参
再看$category_name
post
方式传参,test_input
函数过滤。
幸运的是这几个参数都在一个文件里面
然后看哪个文件使用了它
继续,看哪个使用了上面的文件
搞定,我们访问这个页面,其实是后台主页面,然后发送到bp,修改请求方式为POST,添加url参数与请求体如下
等待十秒后成功返回数据
我们试一下可以拿数据不
结果是可以的,注意语句中不能出现引号,会被实体编码!!!
2.3 vuln3:后台登录页面密码可爆破
直接bp抓包,爆破就行了,巨简单,没有一秒我就跑出来了
2.4 vuln4:后台登录页面忘记密码验证码可爆破
输入用户名,点击忘记密码,输入绑定的邮箱,点击发送验证码,随便填一个验证码,点击确认,
这里因为配有配置邮箱相关信息,所以会报错,不过验证码已经成功生成了,是一个四位数字
正常不报错会跳转到输入验证码的界面,这里我们直接访问
注意这里第一个input框是只读的,我们需要审查元素找到它,然后把只读属性去掉,填入刚才接受验证码的邮箱,然后填入新密码,随便输一个验证码,使用bp抓包发送到爆破模块
去除它自己加的所有payload位置,只在uyzm字段添加!!在payload选项卡这样设置
然后点击开始攻击
验证码为6217
然后使用新密码654321登录成功
2.5 vuln5:后台登录地址显示处反射型XSS
我在进行黑盒测试的时候,发现有这么个东西。
这个竟然有我的ip,那么我的ip能从哪里来呢?
http请求头!!client-ip x-forward-ip x-real-ip remote-addr
字段
然后我就试了cliten-ip
字段,我把他改成1234登录了一次
然后
嗯就是他,我们再看这个值在源代码中式怎么展示的,审查元素
看到了吗,被<span>
标签包围了,那么我准备构造这样的payload
123</span><img src οnerrοr=alert(document.cookie)>
然后他就
2.5 vuln6:用户名明文与密码直接存储在cookie中
看这个
cookie的值为
PHPSESSID=tv7i242svjma2sptqlf598cip3; scusername=%E6%80%BB%E8%B4%A6%E5%8F%B7; scuser=c33367701511b4f6020ec61ded352059; scuserqx=74%2C76%2C77%2C87%2C88%2C75%2C78%2C79%2C80%2C81%2C82%2C83%2C84%2C89%2C100%2Cen
让我们猜猜这几个字段什么意思
字段 | scusername | scuser | scuserqx |
---|---|---|---|
值 | %E6%80%BB%E8%B4%A6%E5%8F%B7 | c33367701511b4f6020ec61ded352059 | 74%2C76%2C77%2C87%2C88%2C75%2C78%2C79%2C80%2C81%2C82%2C83%2C84%2C89%2C100%2C |
解密 | 总账号 | 654321 | %2c是逗号,这是一串啥??? |
这密码就这么明晃晃得放着啊!!!!