这次我们讲的是一篇适合新手学习的代码审计,因为是给小白学习的代码审计,所以可以利用黑盒+白盒交叉审计的情况下,更好的帮助小白学习并找出漏洞。
phpstudy
BlueCMS1.6 sp1源码
代码审计工具(Seay源代码审计系统)
一般来说,有一定代码功力的人审计代码,会直接将全文代码通读一遍,并寻找传参进行代码审计,但这是对有一定代码功力的人而言。
而对小白而言,利用黑盒和白盒交叉审计的情况下,更能帮助我们找到漏洞。
我们拿到一个CMS后,可以先寻找功能点,然后将功能点罗列出来,并对其功能点进行不断测试,然后在拿到代码的情况下,我们可以对功能点所对应的传参进行审计,那如果知道了传参的意义,就等于知道代码会去做什么,要去做什么了呢。
①黑盒测试测不出来的地方进行白盒审计
②测试结果进行白盒审计
常见功能简介:
1.代码自动高亮
2.可以自动审计(误报率高)
3.可以快速全局搜索
4.可以定位函数
5可以监控Mysql(插件)
预备工作,做完之后,我们开始进行代码审计、漏洞挖掘
一般我要做一个CMS网站,首先要访问目录中的安装目录,进行安装、注册管理员账号。那我们站在黑客角度上想一想,我们如果知道了一个cms的安装目录路径,那我们是不是能进行二次访问进行重新安装呢?这样的话我们是不是就可以重置管理员账号和密码,登入后台进行getshell呢?
这样我们就可以进行重新安装了,而数据库账号密码,我们可以弄一个虚拟空间数据库,比如注入时用到的香港云。
我们再来看这个网站,一般而言网站有展示类和功能类。
展示类(比如新闻站、门户站)
功能类(比如商城、OA、系统)
我们看到前台有一个注册功能,如果我们可以拿到一个普通用户的权限是不是更加容易渗透测试?测试的点是不是更多?
那么我们去注册一个账户吧!
在注册之前,我们先开下burp,看下提交注册的数据包发往哪里去
发现它通过post方式将参数发送user.php ,我们注意到里面有act传进参数do_reg,我们通过代码审计工具找到user.php
我们发现这里是检查传进来的注册参数是否为空和有没有空格,并且加入一些检查格式
而我们在下面发现sql插入语句
发现它并没有将注册的值进行过滤,而直接插入数据库中。那么这就很有可能存在XSS和sql注入。
我们先通过一个弹窗看看是否有xss,先抓一个包,并对其邮箱进行插入弹窗语句
成功弹窗,这里是一个存储型的XSS。
在插入语句中
"INSERT INTO ".table('user')." (user_id, user_name, pwd, email, reg_time, last_login_time) VALUES ('', '$user_name', md5('$pwd'), '$email', '$timestamp', '$timestamp')";
这里插入没有过滤,由于email变量由一对单引号包着,所以我们试着在邮箱后面加个’,看看是否会报错
发现还是注册成功了,那我们进后台看看
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TvJ4Dx0F-1584426051908)(https://tva1.sinaimg.cn/large/007DFXDhgy1g418wxhl9tj30z50h1wfx.jpg)]
发现’好像被实体化了,就是被\转义了,这好像是php配置中开启了魔术引号,那我们应该想到之前的宽字节注入,在引号前加%df,使其与%5c合并,从而避免’被转义。
发现报错了,那就说明存在注入
尝试使用updatexml的报错
构建下语句:
INSERT INTO blue_user (user_id, user_name, pwd, email, reg_time, last_login_time) VALUES ('', 'allblue1234', md5('allblue1234'), '[email protected]�\' or updatexml(1,concat(0x7e,(SELECT database())),1),1,1)#\'', '1560443115', '1560443115')
发现报错,没有显示我们想要的信息
但我发现放进数据库执行,却能成功(需将%df\ 去掉)
那我们只能通过盲注
INSERT INTO blue_user (user_id, user_name, pwd, email, reg_time, last_login_time) VALUES ('', 'allblue1234', md5('allblue1234'), '[email protected]�\' or sleep(10),1,1)#\'', '1560443115', '1560443115')
以这种格式继续盲注下去。
但我们想到,insert into 是能插入多条数据呢,那我们是不是能通过语句构建,再建立一个用户,然后用子查询填充邮箱处,然后我们登陆这个账号是不是就可以看到邮箱字段里面的内容?
我们先抓包
这样就插入了两组数据,而在第二组数据中的邮箱就是管理员密码
我们执行一下,发现执行失败
因为这里魔术引号会将引号转义,所以我们利用宽字节知识,将其转为16进制编码
allblue2019==>0x616C6C626C756532303139
注册成功,登录
将邮箱值进行md5解密,成功得到管理员密码
我们尝试登录抓包
找到传参的位置,在审计工具查找
发现这里判断了是否为管理员,没有对登录参数进行限制,这可能存在POST注入
post注入,首先尝试着使用万能密码登录
%df') or 1=1#
成功登录
然后登录后修改资料处也存在SQL注入和XSS
我们通过一个普通用户发布了新闻
通过重新注册一个用户对其进行评论
评论成功
那么这可能也存在XSS。
我们评论时先抓个包看看
发现他会将参数send提交到comment.php,那么我们去看一看
intval()
intval() 函数用于获取变量的整数值。
intval() 函数通过使用指定的进制 base 转换(默认是十进制),返回变量 var 的 integer 数值。 intval() 不能用于 object,否则会产生 E_NOTICE 错误并返回 1。
htmlspecialchars()
把预定义的字符 “<” (小于)和 “>” (大于)转换为 HTML 实体
nl2br()
在字符串中的新行(\n)之前插入换行符
所以XSS肯定是没戏了。
这时,我们看到了他在插入的时候,记录了评论用户的ip,我们发现了getip函数,我们定位一下函数
找到了定义的函数,这里有一个getenv,实际上就是获取系统的环境变量
第一个HTTP_CLIENT_IP这个环境变量没有成标准,很多服务器完全没法获取
第二个X-Forwarded-For是个扩展请求头,这个东西可以通过HTTP请求头来修改。
那么我们是不是可以修改X-Forwarder-For的参数,将参数插入到ip中,那么ip的值就会放入sql语句中执行呢?
我们给个分号测试一下
发现成功报错
因为X-Forwarded-For是直接获取的,所以不会出现魔术引号。
这里我们直接用sqlmap 就能直接跑出来了
有时候,管理员在备份数据库的时候,直接默认将备份文件直接放在网站目录下,这样其实是很危险的,很容易被黑客摸出来。
我们登入后台,发现了一个数据库备份,好,那我们将数据库备份
我们到网站目录看一下
发现他的命名规则是备份的年月日,那如果我们拿到一个CMS,知道他的备份目录,是不是可以尝试着爆破一下备份文件
文件包含,首先需要找到包含函数
我们在找到了一个貌似可以控制的include函数,不过需要act参数=pay的时候才能执行
最后在购买充值卡那找到
我们先找到一个能上传图片马的上传点
成功上传
include 'include/payment/'.$_POST['pay']."/index.php";
文件包含的路径
那么我们将木马路径传入到post参数中,那么路径为:
pay=../../data/upload/face_pic/15605135978.jpg
这样的话,包含语句就会变成:
include 'include/payment/../../data/upload/face_pic/15605135978.jpg/index.php";
但是这样的话,后面还有个index。php,他会去加载index.php,会对加载图片马有所影响,那么我们需要将index.php截取掉,这里00截断试过了,php低版本才会存在这样的截断。
在这里我们可以尝试一个字符串截断的方法(Windows的路径不能超过60个字符)在Windows API中,路径的最大长度为MAX_PATH,MAX_PATH被定义为260。
那么我们是不是可以尝试在传参的后面加点进行截断,因为点最后会被windows给处理掉,但是填充了点之后,只会保留包含前面15605093967.png,在传参后的index.php因为路径超过260个字符后的东西都会被舍弃,于是乎我们直接传参后加260个点就可以截断了。