安全开发-web应用-JS-逻辑漏洞
前面我们学习了PHP的开发,学到了一些关于PHP的一些小漏洞捏,同样的我们现在来学习一下js开发捏,他和PHP一样,我们也把他分为原生开发和框架开发
首当其冲的就是使用js搭建文件上传啦,js他也是属于前端语言,一般都用在html上,所以说呢,这部分的环境就不用太复杂了,不过我们现在直接是大杂烩捏
JS原生开发-文件上传
首先使用html开发前端页面
然后用js获取提交数据,用js来判断文件是否正常,然后用php来提交进行后端上传服务器处理
是不是很简单易懂呢
功能实现和php其实差不多,只是换一个语言写而已,大部分流程还是差不多的捏
js用来过滤,php用来提交捏
依旧用老目录,然后创建一个js目录
然后里面开始准备项目咯
首先是upload.html然后是同名的php文件
前端我们就直接使用之前的了
<div class="upload-container"> <h2>上传你的文件</h2> <form action="upload.php" method="post" enctype="multipart/form-data"> <div class="file-input"> <input type="file" id="file" name="fileToUpload" required> </div> <button type="submit" class="submit-btn">上传</button> </form> </div>
只需要啊修改这部分就可以咯,因为我们要用js来获取数据,所以说捏这部分我们就用js来写,至于为什么还有具体用法参考php我里面说的哈,我不再啰嗦了
<script> function checkfilext(file_name) {//检查文件类型 var flag = false; var exts = ['jpg', 'jpeg', 'png', 'gif', 'pdf'];//规定允许上传的文件类型 var index = file_name.lastIndexOf(".");//获取文件名最后一个点的位置 var ext = file_name.substr(index + 1); //获取文件名最后一个点后面的后缀 for(var i = 0; i < exts.length; i++) { if(exts[i] == ext) {//判断后缀是否在前面规定的数组中 flag = true; alert("文件类型正确"); break; } } if(!flag){ alert("又想传木马了是吧,供出去"); location.reload(true); } } </script>
这部分就很简单,只是一个判断后缀的简单过滤
我们来看看效果
可以看到我上传了一个php文件,他就直接弹窗了,我们再看看正常的
也就是说在你提交文件的时候他就判断完了,只要合法他就保留到那个显示文件名的框中,然后就可以正常上传了,而不合法的就直接刷新页面了,不给你提交的机会
既然前端整完了,我们就继续写后端提交
<?php $name = $_FILES['fileToUpload']['name']; //获取上传文件的名称 $type = $_FILES['fileToUpload']['type']; //获取上传文件的类型 $size = $_FILES['fileToUpload']['size']; //获取上传文件的大小 $tmp_name = $_FILES['fileToUpload']['tmp_name']; //获取上传文件的临时存储路径 $error = $_FILES['fileToUpload']['error']; //获取上传文件的错误信息 if(move_uploaded_file($tmp_name, 'uploads/' . $name)){ echo '文件上传成功'; } ?>
依旧老代码,这里其实加上验证也可以,双重验证哈
看看能不能行
可以看到现在他就能正常的上传文件了,而不合法的在一开始就被ban了,但是这就有一个问题
我们知道php是后端语言,正常浏览器访问的时候是不会显示源代码的,也就是说用户并不知道他的文件过滤机制,因为他看不到我们写的是哪种过滤机制,但是现在我们用的js前端写的,用户在源代码中就可以看到过滤机制然后通过这个来绕过我们的检测
浏览器就直接全部都显示了,然后就可以对着代码来分析绕过的方法,这个前端的绕过方法有很多种,我们就演示一个最基础的,你直接自己构建一个表单提交然后修改一下地址就可以了
首先把代码直接copy
把前面的那个事件直接删掉,然后对应的地址就修改成完整的地址,然后直接打开
可以看到他也是能正常使用的,由于我们这里写的php后端没有验证文件后缀,所以他这里直接就上传成功了,也是非常滴危险哈
关于文件上传就说到这里,也没啥,只是从后端验证变成前端验证了而已,几行代码的事
那我们就继续来说登录问题,和前面一样,用php进行账号判断,JS进行登录处理
依旧login.html和logincheck.php
前端代码还是和之前使用的一样,我们主要还是来写js代码
首先我们是要用js来传输数据,所以你要把前端中的from表单去掉,不然还是会用php去接受数据
整体流程就是首先获取登录事件,然后配置ajax请求,然后后端去验证,最后返回判断
这部分要用到JQuery库,这部分还是自己去搜搜看哈
首先网上去搜索一下这个库把他下下来,这里我自己有,我不演示哈,信息搜集这东西使我们学安全最重要的技能哈
也就是这个小东西了,现在我们来使用他
<script src="js/jquery-1.12.4.js"></script> <script> $("button").click(function(){ $.ajax({ type: 'POST', url: 'logincheck.php', data: { username: $(".username").val(), password: $(".password").val() }, success: function(res){ console.log(res);// 打印返回的结果 if(res['infocode'] == 1){//判断是否登录成功 alert("登录成功"); location.href = "upload.html";//跳转到上传页面 }else if(res['infocode'] == 0){ alert("用户名或密码错误"); } }, dataType:'json' }); }); </script>
首先我们先简单构造一下代码,然后php后面也是同样的使用之前的方法验证但是有点小不同
<?php $user=$_POST['username']; //获取用户名 $password=$_POST['password']; //获取密码 $success = array('msg'=> 'ok');//初始化返回值 if($user=="admin" && $password=="123456"){ $success['infocode']=1;//登录成功 }else{ $success['infocode']=0; } echo json_encode($success); //返回json格式数据 ?>
然后来看看结果
可以看到当你输入错误的账号密码的时候,首先通过success接受到数据然后传入到php代码中去判断,如果不符合就给infocode赋值为0然后然后提示错误,再输入正确的看看
当返回值为1的时候就会登录成功,主要的逻辑就是
用户在页面输入用户名和密码;
点击按钮,前端用 jQuery 的 AJAX 向
logincheck.php
发送 POST 请求;后端接收到数据,检查账号密码是否正确;
后端返回 JSON 结果(比如:
{"infocode":1}
);前端根据这个结果判断是否跳转或提示错误
而传统的php验证则是
用户填写表单,点击“登录”按钮;
表单使用
<form method="post" action="logincheck.php">
提交;页面会 整体跳转 到
logincheck.php
;后端判断账号密码是否正确;
使用
echo
输出提示信息,或通过header("Location: xx.php")
进行跳转;登录失败就得返回到登录页,或者重载整个页面。
具体的工作流程参考这个库的手册哈,我都整不太明白
但是其实这也只是引用了一个外部的库,也不是纯原生态的写法,但是架不住他好用呀,原生态太过于复杂了,不是我们该学的了
这里弄完了,我们就来看看他有什么安全问题呢,首先那肯定就是如果我们把这个登录成功的页面跳转写在前端,那用户随便修改一下判断的数据不就随便的进入后台了吗
前面我们知道我们输入错误的时候,前端数据传输到后端的时候,他会判断然后回重洗返回一个json的数据响应,我们把返回包也抓住,再一改,前端不就以为收到的是正确的登录值吗
在这里打开返回包也抓取
现在我们抓住了返回的包,这个时候你再放过去就直接错误了,但是我们偷偷修改一下
看看有什么效果
嘿,你这家伙,随便输入的账号密码也能登录吗,哈吉浏览器你这家伙,给我放了个什么玩意这是,可以看到也是登录成功了,所以说我们最好还是把这个跳转交给后端,而前端就仅仅有个弹窗就够了
echo "<script>location.href='index.html';</script>";
我们再来看看有没有用哈
然后你点击确定,可以发现没有任何反应,还是在这个页面,这时候小黑客来攻击我的服务器,发现哇,居然登录成功力,结果发现只是日到空气了,那很不好了
关于登录的也就差不多了,我们继续来看
商品购买
首先创建一个shop.html文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>目光呆滞</title> </head> <body> 剩余存款:10000元<br> <img src="./images/ew.jpg" ><br> 价格:114514元<br> 数量:<input type="text" name="num" class="num"> <button>买买买</button> </body> </html>
简陋哈简陋
呜呜呜我的马内只够买一个目光呆滞了捏
实现这个简单的效果,然后再创建一个shop.php来完整购买功能
首先前端的数据提交还是跟之前差不多
<script src="js/jquery-1.12.4.js"></script> <script> $("button").click(function(){ $.ajax({ type: 'POST', url: 'shop.php', data: { num: $(".num").val() }, success: function(res){ console.log(res);// 打印返回的结果 if(res['infocode'] == 1){//判断是否登录成功 alert("我是卫视戴尔"); }else if(res['infocode'] == 0){ alert("boom,没钱买个蛋"); } }, dataType:'json' }); }); </script>
然后我们写后端的php
<?php $num = $_POST['num']; //获取表单数据 $success = array('msg'=> 'ok');//初始化返回值 if(114514 >= (114514*$num)){ $success['infocode']=1; }else{ $success['infocode']=0; } echo json_encode($success); //返回json格式数据 ?>
和前面也差不多,只要你的钱够,你就可以目光呆滞孩子
这个效果也是实现了,但是其实这个和上面那个没啥区别,只是相对应的,其实他那个数据中其实应该都是由数据库来显示的,这里不太严谨哈,总的来说,这个业务逻辑的判断啊,最好是不要写在前端的代码中,因为在前端中验证的话,被篡改一下就马上就G了,前端就好好干前端的工作啊(开什么玩笑脸)
所以说啊,粗心不可取捏
这一期就差不多了,很简单对吧,就是看他的触发逻辑是否在前端,如果是,直接抓包一改,随便日
未完待续~~~