把我的骨灰随身携带 紧急的时候 扬了吧 如果顺风就让我再抱抱你 如果逆风就让我再保护你一次吧!
验证码重放
这个比较没用的属于,但是学习阶段,逻辑很重要。CMS开始审计,相信看的应该都是后台登录的地方。
/admin/cms_login.php
<?php
require_once('../system/inc.php');
if(isset($_POST['submit'])){
if ($_SESSION['verifycode'] != $_POST['verifycode']) {
alert_href('验证码错误','cms_login.php');
}
null_back($_POST['a_name'],'请输入用户名');
null_back($_POST['a_password'],'请输入密码');
null_back($_POST['verifycode'],'请输入验证码');
$a_name = $_POST['a_name'];
$a_password = $_POST['a_password'];
$sql = 'select * from xtcms_manager where m_name = "'.$a_name.'" and m_password = "'.md5($a_password).'"';
$result = mysql_query($sql);
if(!! $row = mysql_fetch_array($result)){
setcookie('admin_name',$row['m_name']);
setcookie('admin_password',$row['m_password']);
header('location:cms_welcome.php');
}else{
alert_href('用户名或密码错误','cms_login.php');
}
}
?>
因为看到是数据库查询直接拼接的语句,这里原本以为可以试试注入或者万能密码,再细看,看到后面还有cookie验证,而且不是查询过后直接与传参的数据做对比的,逻辑行不通。
所以还是看看验证码吧。
可以看出验证码是从session中获取的
if ($_SESSION['verifycode'] != $_POST['verifycode']) {
alert_href('验证码错误','cms_login.php');
}
如果与验证码匹配,则进行用户名和密码的验证,如果验证码不对,直接跳转回登陆界面。
跟随验证码到system/verifycode.php
<?php
session_start();
$image = imagecreate(50, 34);
$bcolor = imagecolorallocate($image, 0, 0, 0);
$fcolor = imagecolorallocate($image, 255, 255, 255);
$str = '0123456789';
$rand_str = '';
for ($i = 0; $i < 4; $i++){
$k = mt_rand(1, strlen($str));
$rand_str .= $str[$k - 1];
}
$_SESSION['verifycode'] = $rand_str; //将生成的验证码保存在SESSION中....
imagefill($image, 0, 0, $bcolor);
imagestring($image, 7, 7, 10, $rand_str, $fcolor);
header('content-type:image/png');
imagepng($image);
?>
无论是在登录处,还是在这个生成验证码的文件中,都没有设置session
过期的时间。
在登录的html代码中还有这里
<img src="../system/verifycode.php" onclick="javascript:this.src='../system/verifycode.php?'+Math.random()" style="cursor:pointer;" alt="点击更换" title="点击更换" />
与它绑定的是一个JS点击事件,所以说只要不点击(重新加载JS),就不会刷新验证码。就可以进行用户名和密码暴力破解。
在burp suite中不会重新加载JS,所以可以使用intruder模块进行暴力破解。
其中setcookie()
有关于验证码的漏洞:
- 查看cookie的是否设置了过期时间
- 查看验证码验证的次数有没有限制
- 登陆限制(现在很多登录处设置三次登录机会)
XSS
反射XSS
<?php
$flid1 = $_GET['m'];
if ($flid1 == "") {
$flid1 = '/dongman/list.php?rank=rankhot&page=1';
}
include 'system/360.php';
....
....
<?php echo getPageHtml($page, $fenye, 'dongman.php?m=' . $yourneed . '&page='); ?><li><a>共<?php echo $fenye; ?>页</a></li>
传入:"><script>alert(/xss/)</script>
没有经过什么过滤就直接回显在前端了。正好闭合前面的href="
,然后后面的部分成功执行反弹xss经典弹窗。
弹窗效果
存储型XSS
先看一些知识
/[\x7f-\xff]+(?:\s*[\x7f-\xff]+)*/
# 这是一个正则表达式,它主要是匹配过滤掉中文字符,看下图
//判断有一个空格以上但是又不能全部是空的字符串
if (!ctype_space($_POST['content']) && !empty($_POST['content'])) {
//匹配数字字母下划线空格中文 数量不能超过10个字
if (!preg_match("/[\x7f-\xff]+(?:\s*[\x7f-\xff]+)*/", $_POST['content'])) {
echo "<script>alert('内容填写不合法!');location.href='book.php'</script>";
die;
}
} else {
echo "<script>alert('内容填写不合法!');location.href='book.php'</script>";
die;
}
其中!ctype_space()
PHP中的ctype_space()函数检查空格字符。如果文本中的每个字符都产生某种空白,则返回TRUE,否则返回FALSE。除空白字符外,还包括制表符,垂直制表符,换行符,回车符和换页符。
意思即为输入的字符串在检查过后,可以存在空格,但是又不能全部是空格,同时又限制了必须输入不为空的内容。
所以逻辑是:昵称和留言内容必须是中文字符。但是使用的正则中。
只要存在中文字符就行,没有设置为全为中文字符。而且也没有了其他方式的过滤。
而且这个$sql = 'insert into xtcms_book ('.$str[0].') values ('.$str[1].')';
还是将数据写入了数据库中,所以即为存储型XSS
防护处理
变量进行htmlspecialchars
处理
htmlspecialchars()
函数把预定义的字符转换为 HTML 实体。
预定义的字符是:
& (和号)成为 &
" (双引号)成为 "
' (单引号)成为 '
< (小于)成为 <
> (大于)成为 >
$message = htmlspecialchars( $message );
$name = htmlspecialchars( $name );
标签事件白名单处理
SQL注入
vlist.php
(前台注入)
<?php
if (isset($_GET['cid'])) {
if ($_GET['cid'] != 0){
$sql = 'select * from xtcms_vod where d_parent in ('.$_GET['cid'].') order by d_id desc';
$pager = page_handle('page',24,mysql_num_rows(mysql_query($sql)));
$result = mysql_query($sql.' limit '.$pager[0].','.$pager[1].'');
}else(....)
....
}
可以看到SQL语句是拼接的,直接将$_GET['cid']
直接拼接到SQL语句中了。
没有过滤,直接拼接的SQL语句,存在注入的可能性是非常大的。
/admin/cms_usergroup_edit.php
(后台注入)
同样是直接拼接SQL语句,所以可以发现在代码审计时,注入漏洞,要针对这种SQL语句多关注一些。同样的地方还有许多。过滤也有很多,绕过暂时不写,CTF中有很多。
一般加控制语句都是在$_GET[‘cid’]后面就加一些自写的过滤函数或者正则匹配,白名单或者黑名单进行过滤。
防护
<?php
/*强制类型转换*/
$id=intval($_GET['id']); //因查询ID为整数 所以可以强制转换为整数
/*转义特殊字符 加上引号 (字符串类型)*/
$id=$pdo->quote($_GET['name']);
/*预处理语句*/
$stmt =$pdo->prepare("SELECT id, name FROM users WHERE id=?;");
$stmt->execute([$_GET['id']]);//简单的预处理 完整使用方法见PHP手册
?>
强制转换输入内容的类型
将特殊字符进行转义
预处理,使用PDO::prepare 预处理SQL语句,有效防止SQL注入
PDO::quote 转义特殊字符并加上引号
- 本文链接:https://m0re.top/posts/7c1c73bc/
- 版权声明:本博客所有文章除特别声明外,均默认采用 许可协议。
您可以点击下方按钮切换对应评论系统,
Valineutterances