首先漏洞产生于某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删除。
删除成功。