安全矩阵

 找回密码
 立即注册
搜索
查看: 912|回复: 0

从一次简单的开发引申出的一些安全问题

[复制链接]

260

主题

275

帖子

1065

积分

金牌会员

Rank: 6Rank: 6

积分
1065
发表于 2022-9-12 22:53:44 | 显示全部楼层 |阅读模式
本帖最后由 luozhenni 于 2022-9-12 22:53 编辑


从一次简单的开发引申出的一些安全问题
原文链接:从一次简单的开发引申出的一些安全问题
w0w 衡阳信安 2022-09-12 06:00 发表于山东
前言
这周啥也没干,就去看了看开发,为以后的代码审计铺垫铺垫。毕竟开发过,审计代码的时候才不会憨憨傻傻的。之前审计过两个cms,当时真的是,审的人都快麻了,害。果然还是要有写开发的功底,再去审计才不会那么吃力。接下来这四个方面,是我从那个开发的小系统中,简单提取的四个方面,分别涉及sql注入,CSRF,XSS等等。(开发能力欠缺,各位师傅将就看)
sql注入
sql注入嘛,一个成型的网站,基本上都是跑不了使用MYSQL的,所以sql注入的存在极为广泛,waf一个挡不住,就可能存在sql注入。
index.php
  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>index</title>
  6. </head>
  7. <body>
  8.         <table>
  9.             <form  action="sql.php" method="post">
  10.             查询
  11.             <p><input type="username" name="username"></p>
  12.             <p><input type="submit" name="submit" value="提交"></p>
  13.         </table>
  14. </body>
复制代码

sql.php
  1. <?php
  2. error_reporting(0);
  3. header ("Content-Type:text/html;charset=utf-8");
  4. include '../upload/config.php';
  5. $username=$_POST['username'];
  6. $sql="select * from user where username='{$username}'";
  7. $row=mysql_query($sql);
  8. $rst=mysql_fetch_assoc($row);
  9. echo "{$rst['username']}用户存在";
  10. ?>
复制代码


这种是查询的注入,但是一般的这里都会有waf,所以我们可以尝试别的情况下注入,比如
insert/delete
  1. <?php
  2. error_reporting(0);
  3. header ("Content-Type:text/html;charset=utf-8");
  4. include '../upload/config.php';
  5. $username=$_POST['username'];
  6. $sql="insert into haha(name) values ('{$username}')";
  7. $row=mysql_query($sql);
  8. if ($row) {
  9.     echo "用户插入成功";
  10. }

  11. ?>
复制代码

这种就可以报错注入或者盲注了

文件上传
index.php
  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>index</title>
  6. </head>
  7. <body>
  8.         <table>
  9.             <form enctype="multipart/form-data" action="upload.php" method="post">
  10.             <p><input type="file" name="file"></p>
  11.             <p><input type="submit" name="submit" value="提交"></p>
  12.         </table>
  13. </body>
复制代码


其中enctype="multipart/form-data" 在文件上传的时候是不可或缺的。
upload.php
  1. <?php
  2. //print_r($_FILES);
  3. // exit();
  4. header ("Content-Type:text/html;charset=utf-8");
  5. if (isset($_POST['submit'])) {
  6.     $name=$_FILES['file']['name'];
  7.     $path=$_FILES['file']['tmp_name'];
  8.     $newpath='upload/'.time().$name;
  9.     if (move_uploaded_file($path,$newpath)) {
  10.         echo '保存成功,路径为<br/>'.$newpath;
  11.     }
  12. }

  13. ?>
复制代码


这就是最简单的文件上传了,没有任何过滤,传入别的类型的文件还会报错。
从CTF来讲,一般正经的只靠文件上传的题目已经很少了。所以拓展来将,最近遇到的比较有新意的题目就是网刃杯的那道文件上传。
当时题目提示的是sql,我懵了一下,文件上传还能和sql注入扯到一起,这不瞎搞。后来的一周,我看了点开发的东西,我发现,一般后台有文件上传的功能的时候,一般都会把文件名写入到数据库中。到这里我茅塞顿开,许多的安全问题都是源自开发。
index.php
  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>index</title>
  6. </head>
  7. <body>
  8.         <table>
  9.             <form enctype="multipart/form-data" action="upload.php" method="post">
  10.             <p><input type="file" name="file"></p>
  11.             <p><input type="submit" name="submit" value="提交"></p>
  12.         </table>
  13. </body>
复制代码
config.php
  1. <?php
  2. mysql_connect('localhost','root','root');
  3. mysql_query('set names utf-8');
  4. mysql_select_db('img');
  5. ?>
复制代码

upload.php
  1. <?php
  2. //print_r($_FILES);
  3. // exit();

  4. header ("Content-Type:text/html;charset=utf-8");
  5. //error_reporting(0);
  6. include 'config.php';
  7. $move=false;
  8. $rst=false;

  9. if (isset($_POST['submit'])) {
  10.     $name=$_FILES['file']['name'];
  11.     $path=$_FILES['file']['tmp_name'];
  12.     $size=$_FILES['file']['size'];
  13.     $newpath='upload/'.time().$name;
  14.     $move=move_uploaded_file($path,$newpath);

  15.     $sql="insert into cname(name,path,size) values('{$name}','{$newpath}','{$size}')";
  16.     //echo $sql;
  17.     $rst=mysql_query($sql);
  18.     $selectsql="select * from cname where name='{$name}'";
  19.     //echo $selectsql;
  20.     $selectrst=mysql_query($selectsql);
  21.     $selectrow=mysql_fetch_assoc($selectrst);

  22.     //print_r($selectrow);

  23.     if ($move&&$rst) {
  24.         echo "文件{$selectrow['name']}已经存储到数据库<br/>并且图片存储的位置是".$newpath;
  25.     }


  26. }
  27. ?>
复制代码
ps:写sql语句的时候一定要带单引号........我麻了

这里假装我对上传的文件进行了过滤,已经无法通过文件上传shell,但是这里我们通过文件名,文件大小,文件路径都可以进行SQL注入。//这里我写了那么明显,就没有注入。
接下来就是写waf了
  1. //前端waf
  2. <script type="text/javascript">
  3.     function checkFile() {
  4.         var file = document.getElementsByName('upload_file')[0].value;
  5.         if (file == null || file == "") {
  6.             alert("请选择要上传的文件!");
  7.             return false;
  8.         }
  9.         //定义允许上传的文件类型
  10.         var allow_ext = ".jpg|.png|.gif";
  11.         //提取上传文件的类型
  12.         var ext_name = file.substring(file.lastIndexOf("."));
  13.         //判断上传文件类型是否允许上传
  14.         if (allow_ext.indexOf(ext_name) == -1) {
  15.             var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name;
  16.             alert(errMsg);
  17.             return false;
  18.         }
  19.     }
  20. </script>
  21. //由于js太菜,抄的upload-labs的
  22. 但是前端过滤也没啥用
复制代码
后端过滤的话
  1. <?php
  2. //print_r($_FILES);
  3. // exit();
  4. header ("Content-Type:text/html;charset=utf-8");
  5. if (isset($_POST['submit'])) {
  6.     $name=$_FILES['file']['name'];
  7.     $path=$_FILES['file']['tmp_name'];
  8.     $type=$_FILES['file']['type'];
  9.     $newpath='upload/'.time().$name;
  10.     $file_name=trim($_FILES['file']['name']); //去空处理
  11.     $file_name=strchr($file_name,'.'); //将.后面的字符串赋值
  12.     $file_name=strtolower($file_name);//转为小写
  13.     $whitetype=['image/jpeg','image/png','image/gif'];
  14.     $white=['.gif','.png','.jpg'];
  15.     foreach ($whitetype as $key => $value1) {
  16.         //echo $value1;
  17.         foreach ($white as $key => $value2) {
  18.             //echo $value2;
  19.             //echo $file_name;
  20.             if ($type==$value1) {
  21.                 if ($file_name==$value2) {
  22.                     if (move_uploaded_file($path, $newpath)) {
  23.                         echo "上传成功";
  24.                     }
  25.                 }

  26.             }

  27.         }

  28.     }
  29. }   
  30. ?>
复制代码

说实话,写成这样我觉得就没有办法绕过了

编辑

白名单yyds

后台权限
在后台开发过程中,还是需要权限的把控,不然人家随便访问你的后台,开玩笑??
  1. <?php
  2. if (!$_SESSION['id']) {
  3.     echo "<script>loaction='login.php'</script>";
  4.     exit();
  5. }
  6. ?>
复制代码

后台的每个页面必需要这个段语句。不然直接都能非用户访问了
而且前后台sesson内的信息不能相同,不然就会,前台依旧能访问后台。
这里我简单的写了一个后台的登录功能
index.php
  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>index</title>
  6. </head>
  7. <body>
  8.         <table>
  9.             <form  action="check.php" method="post">
  10.                 username
  11.             <p><input type="username" name="username"></p>
  12.             password
  13.             <p><input type="password" name="password"></p>
  14.             <p><input type="submit" name="submit" value="提交"></p>
  15.         </table>
  16. </body>
复制代码
check.php
  1. <?php
  2. error_reporting(0);
  3. session_start();
  4. include '../upload/config.php';
  5. $username=$_POST['username'];
  6. $password=$_POST['password'];
  7. $sql="select * from user where username='{$username}' and password='{$password}' and isadmin='1'";
  8. //echo $sql;
  9. $rst=mysql_query($sql);
  10. $row=mysql_fetch_assoc($rst);
  11. if ($row) {
  12.     $_SESSION['admin_username']=$username;
  13.     echo "<script>location='admin.php'</script>";
  14. }

  15. ?>
复制代码
admin.php
  1. <?php
  2. session_start();
  3. if (!$_SESSION['admin_username']) {
  4.     echo "<script>loaction='index.php'</script>";
  5.     exit();
  6. }
  7. echo "登陆成功";
  8. ?>
复制代码
到这里,除了sql注入之外,其实显现了另外的一种漏洞,CSRF
编辑
这里我换了个浏览器登录,却不会跳转到index.php很怪
编辑

可以看到,替换掉cookie就能达到登陆成功的效果

用户评论
index.php
  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>index</title>
  6. </head>
  7. <body>
  8.         <table>
  9.             <form  action="comment.php"  method="post">
  10.             <p>评论</p>
  11.             <p><input type="text" name="text"></p>
  12.             <p><input type="submit" name="submit" value="提交"></p>
  13.         </table>
  14. </body>
复制代码
comment.php
  1. <?php
  2. include '../upload/config.php';
  3. if (isset($_POST['submit'])) {
  4.     $comment=$_POST['text'];
  5.     $sql="insert into comment(text) values('{$comment}')";
  6.     $row=mysql_query($sql);
  7.     if ($row) {
  8.         echo "<script>location='show.php'</script>";
  9. }
  10. }
  11. ?>
复制代码
show.php
  1. <?php
  2. include '../upload/config.php';
  3. if (isset($_POST['submit'])) {
  4.     $comment=$_POST['text'];
  5.     $sql="insert into comment(text) values('{$comment}')";
  6.     $row=mysql_query($sql);
  7.     if ($row) {
  8.         echo "<script>location='show.php'</script>";
  9. }
  10. }
  11. ?>
复制代码
经典XSS
编辑
总结
经此开发,我算是明白了,许多安全都是在开发的时候都存在的。开发的时候,不紧要实现一些需求功能,还要防止出现安全问题。
来源:先知(https://xz.aliyun.com/t/11327)


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-3-29 08:17 , Processed in 0.014477 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表