初学代码审计之任意文件删除

首先漏洞产生于某phpcms后台a*******e.php中

 1 if ($_REQUEST['act'] =='update') {
 2     /* 权限判断 */
 3     admin_priv('article_manage');
 4 
 5     /*检查文章名是否相同*/
 6     $is_only = $exc->is_only('title', $_POST['title'], $_POST['id'], "cat_id = '$_POST[article_cat]'");
 7 
 8     if (!$is_only) {
 9         sys_msg(sprintf($_LANG['title_exist'], stripslashes($_POST['title'])), 1);
10     }
11 
12 
13     if (empty($_POST['cat_id'])) {
14         $_POST['cat_id'] = 0;
15     }
16 
17     /* 取得文件地址 */
18     $file_url = '';
19     if (empty($_FILES['file']['error']) || (!isset($_FILES['file']['error']) && isset($_FILES['file']['tmp_name']) && $_FILES['file']['tmp_name'] != 'none')) {
20         // 检查文件格式
21         if (!check_file_type($_FILES['file']['tmp_name'], $_FILES['file']['name'], $allow_file_types)) {
22             sys_msg($_LANG['invalid_file']);
23         }
24 
25         // 复制文件
26         $res = upload_article_file($_FILES['file']);
27         if ($res != false) {
28             $file_url = $res;
29         }
30     }
31 
32     if ($file_url == '') {
33         $file_url = $_POST['file_url'];
34     }
35 
36     /* 计算文章打开方式 */
37     if ($file_url == '') {
38         $open_type = 0;
39     } else {
40         $open_type = $_POST['FCKeditor1'] == '' ? 1 : 2;
41     }
42 
43     /* 如果 file_url 跟以前不一样,且原来的文件是本地文件,删除原来的文件 */
44     $sql = "SELECT file_url FROM " . $ecs->table('article') . " WHERE article_id = '$_POST[id]'";
45     $old_url = $db->getOne($sql);
46     if ($old_url != '' && $old_url != $file_url && strpos($old_url, 'http://') === false && strpos($old_url, 'https://') === false) {
47         @unlink(ROOT_PATH . $old_url);
48     }
49 
50     if ($exc->edit("title='$_POST[title]', cat_id='$_POST[article_cat]', article_type='$_POST[article_type]', is_open='$_POST[is_open]', author='$_POST[author]', author_email='$_POST[author_email]', keywords ='$_POST[keywords]', file_url ='$file_url', open_type='$open_type', content='$_POST[FCKeditor1]', link='$_POST[link_url]', description = '$_POST[description]'", $_POST['id'])) {
51         $link[0]['text'] = $_LANG['back_list'];
52         $link[0]['href'] = 'article.php?act=list&' . list_link_postfix();
53 
54         $note = sprintf($_LANG['articleedit_succeed'], stripslashes($_POST['title']));
55         admin_log($_POST['title'], 'edit', 'article');
56 
57         clear_cache_files();
58 
59         sys_msg($note, 0, $link);
60     } else {
61         die($db->error());
62     }
63 }

漏洞产生于47行,跟进$old_url参数

1 $sql = "SELECT file_url FROM " . $ecs->table('article') . " WHERE article_id = '$_POST[id]'";
2 $old_url = $db->getOne($sql);

可以看到第一行首先存在sql注入,此处只看$old_url,那么在数据库中看一下此参数具体是什么。

可以看到查询的是这个表中的 file_url 字段。

 1 if ($_REQUEST['act'] == 'insert') {
 2     /* 权限判断 */
 3     admin_priv('article_manage');
 4 
 5     /*检查是否重复*/
 6     $is_only = $exc->is_only('title', $_POST['title'], 0, " cat_id ='$_POST[article_cat]'");
 7 
 8     if (!$is_only) {
 9         sys_msg(sprintf($_LANG['title_exist'], stripslashes($_POST['title'])), 1);
10     }
11 
12     /* 取得文件地址 */
13     $file_url = '';
14     if ((isset($_FILES['file']['error']) && $_FILES['file']['error'] == 0) || (!isset($_FILES['file']['error']) && isset($_FILES['file']['tmp_name']) && $_FILES['file']['tmp_name'] != 'none')) {
15         // 检查文件格式
16         if (!check_file_type($_FILES['file']['tmp_name'], $_FILES['file']['name'], $allow_file_types)) {
17             sys_msg($_LANG['invalid_file']);
18         }
19 
20         // 复制文件
21         $res = upload_article_file($_FILES['file']);
22         if ($res != false) {
23             $file_url = $res;
24         }
25     }
26 
27     if ($file_url == '') {
28         $file_url = $_POST['file_url'];
29     }
30 
31     /* 计算文章打开方式 */
32     if ($file_url == '') {
33         $open_type = 0;
34     } else {
35         $open_type = $_POST['FCKeditor1'] == '' ? 1 : 2;
36     }
37 
38     /*插入数据*/
39     $add_time = gmtime();
40     if (empty($_POST['cat_id'])) {
41         $_POST['cat_id'] = 0;
42     }
43     $sql = "INSERT INTO ".$ecs->table('article')."(title, cat_id, article_type, is_open, author, ".
44                 "author_email, keywords, content, add_time, file_url, open_type, link, description) ".
45             "VALUES ('$_POST[title]', '$_POST[article_cat]', '$_POST[article_type]', '$_POST[is_open]', ".
46                 "'$_POST[author]', '$_POST[author_email]', '$_POST[keywords]', '$_POST[FCKeditor1]', ".
47                 "'$add_time', '$file_url', '$open_type', '$_POST[link_url]', '$_POST[description]')";
48     $db->query($sql);
49 
50     /* 处理关联商品 */
51     $article_id = $db->insert_id();
52     $sql = "UPDATE " . $ecs->table('goods_article') . " SET article_id = '$article_id' WHERE article_id = 0";
53     $db->query($sql);
54 
55     $link[0]['text'] = $_LANG['continue_add'];
56     $link[0]['href'] = 'article.php?act=add';
57 
58     $link[1]['text'] = $_LANG['back_list'];
59     $link[1]['href'] = 'article.php?act=list';
60 
61     admin_log($_POST['title'], 'add', 'article');
62 
63     clear_cache_files(); // 清除相关的缓存文件
64 
65     sys_msg($_LANG['articleadd_succeed'], 0, $link);
66 }

观察43~47行,其中插入的所有值都可控,所以此处可以插入一条数据,将file_url设置为需要删除的任意文件。此处已删除install.lock为例

抓包将file_url的值修改为接下来要删除的文件。此时查看数据库:

然后修改post_id=7的话,$old_url='data/install.lock',然后在将file_url修改成为不同于old_url的值

可以看到此处将file_url随意修改一下就可以了。然后就会将install.lock删除。

删除成功。

猜你喜欢

转载自www.cnblogs.com/Spec/p/10635580.html