目录
欢迎关注 『网络攻防CTF』 系列,持续更新中
欢迎关注 『网络攻防CTF』 系列,持续更新中
1. 结合mysql数据库设计一个web登录页面
数据库sql搭建
另存为
sql_test.sql
文件导入即可
/*
Navicat Premium Data Transfer
Source Server : localhost
Source Server Type : MySQL
Source Server Version :50734
Source Host : localhost:3306
Source Schema : sql_test
Target Server Type : MySQL
Target Server Version :50734
File Encoding :65001
Date:13/05/202210:15:53*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS =0;-------------------------------- Table structure for user
------------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`username` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`pwd` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-------------------------------- Records of user
------------------------------
INSERT INTO `user` VALUES ('admin','admin');
SET FOREIGN_KEY_CHECKS =1;
项目结构如下:
为了美观引用了layui框架(也可以没有,只是样式)
Login.html效果图如下:
输入用户名密码测试登陆。
html代码
layui文件可以在gitee官网上下载
https://gitee.com/sentsin/layui
<!DOCTYPEhtml><html><head><metahttp-equiv="Content-Type"content="text/html; charset=gb2312"><title>防止SQL注入的登录页面</title><metaname="viewport"content="width=device-width, initial-scale=1, maximum-scale=1"><title>基于layui框架的放sql注入网站</title><linkrel="stylesheet"href="layui-master/src/css/layui.css"><linkrel="stylesheet"href="layui-master/src/css/modules/code.css"><scriptsrc="layui-master/src/layui.js"type="text/javascript"charset="UTF-8"></script><scripttype="text/javascript">functionMycheck(str){var mess ="不允许输入的字符:\r\n";var mark ="yes";if(str.indexOf(";")>=0){
mark ="no";
mess +=" ; ";}if(str.indexOf("&")>=0){
mark ="no";
mess +=" & ";}if(str.indexOf("<")>=0){
mark ="no";
mess +=" < ";}if(str.indexOf(">")>=0){
mark ="no";
mess +=" > ";}if(str.indexOf("--")>=0){
mark ="no";
mess +=" -- ";}if(str.indexOf("/")>=0){
mark ="no";
mess +=" / ";}if(str.indexOf("%")>=0){
mark ="no";
mess +=" % ";}if(str.indexOf("'")>=0){
mark ="no";
mess +=" ' ";}if(str.indexOf("#")>=0){
mark ="no";
mess +=" # ";}if(mark =="no"){alert(mess);returnfalse;}elsereturnreturntrue;}</script></head><bodystyle="font-size:12px"><tablewidth="382"border="0"align="center"cellpadding="0"cellspacing="0"><tr><tdheight="99"background="images/login_01.jpg"> </td></tr><tr><tdheight="160"bgcolor="#FEF7C3"><tableclass="layui-table"lay-size="lg"lay-evenlay-skin="row"width="300"border="0"align="center"cellpadding="3"cellspacing="0"><formmethod='post'action='login.php'name="form1"onSubmit="Mycheck(form1.username.value)"><tr><tdheight="22"colspan="2"align="center"> </td></tr><tr><tdheight="22"align="right">mzh</td></tr><tr><tdheight="22"align="right">网工191</td></tr><tr><tdheight="22"align="right">19145120</td></tr><tr><tdheight="22"align="right">用户</td><tdheight="22"><inputname="username"type="text"class="layui-input-inline"id="txt_name"size="18"maxlength="50"></td></tr><tr><tdheight="22"align="right">密码:</td><tdheight="22"><inputname="passwd"type="password"class="layui-input-inline"id="txt_passwd"size="19"maxlength="50"></td></tr><tr><tdheight="22"colspan="2"align="center"><inputname="login"type="submit"id="login"value="登 录"class="layui-btn layui-btn-radius layui-btn-warm"> <inputtype="reset"name="Submit2"value="重 置"class="layui-btn layui-btn-radius layui-btn-warm"></td></tr></form></table></td></tr></table><!-- Code injected by live-server --><scripttype="text/javascript">// <![CDATA[<-- For SVG support
if('WebSocket'in window){(function(){functionrefreshCSS(){var sheets =[].slice.call(document.getElementsByTagName("link"));var head = document.getElementsByTagName("head")[0];for(var i =0; i < sheets.length;++i){var elem = sheets[i];var parent = elem.parentElement || head;
parent.removeChild(elem);var rel = elem.rel;if(elem.href &&typeof rel !="string"|| rel.length ==0|| rel.toLowerCase()=="stylesheet"){var url = elem.href.replace(/(&|\?)_cacheOverride=\d+/,'');
elem.href = url +(url.indexOf('?')>=0?'&':'?')+'_cacheOverride='+(newDate().valueOf());}
parent.appendChild(elem);}}var protocol = window.location.protocol ==='http:'?'ws://':'wss://';var address = protocol + window.location.host + window.location.pathname +'/ws';var socket =newWebSocket(address);
socket.onmessage=function(msg){if(msg.data =='reload') window.location.reload();elseif(msg.data =='refreshcss')refreshCSS();};if(sessionStorage &&!sessionStorage.getItem('IsThisFirstTime_Log_From_LiveServer')){
console.log('Live reload enabled.');
sessionStorage.setItem('IsThisFirstTime_Log_From_LiveServer',true);}})();}else{
console.error('Upgrade your browser. This Browser is NOT supported WebSocket for Live-Reloading.');}// ]]></script></body></html>
php验证代码
<?phpsession_start();//开启session对话,必须在html前//post方法获取表单用户名,密码$username=$_POST['username'];$passwd=$_POST['passwd'];//连接数据库$link=mysqli_connect('localhost','root','123456','sql_test');if(!$link){die("连接失败:".mysqli_connect_error());}//检查用户名密码是否在数据库里已保存注册$sql='select * from user where username="'.$username.'"and pwd="'.$passwd.'"';$result=mysqli_query($link,$sql);$rows=mysqli_fetch_array($result);//查询数据表每一行if($rows){//数据库中查到用户名,密码匹配$_SESSION['username']=$username;//保存session数据,全局变量echo'
######################登陆成功###################
';}else{echo'
######################用户名或密码错误######################
';}?>
2. 能够防住简单注入和宽字节注入
简单注入
注入用户名
19145120mzh' or 1=1#'
密码随意输入
这里检查是否含有特殊的
'
引号字符,防止了注入,具体代码在html的js部分
if (str.indexOf("'") >= 0) {
mark = "no";
mess += " ' ";
}
双拼注入
类似单注入,同样成功防止了注入。
注入用户名
19145120mzh' 'oorr 1=1#'
密码随意输入
这里检查是否含有特殊的
'
引号字符,防止了注入,具体代码在html的js部分
if (str.indexOf("'") >= 0) {
mark = "no";
mess += " ' ";
}
宽字节注入
首先输入测试用户密码得到格式标准化的url
我这里随便输入了用户
mzh
密码
123
得到了url
http://127.0.0.1:5500/login.html?username=mzh&pwd=123&login=%E7%99%BB+%E5%BD%95
在url后面添加
%df%27%20or%201=1%23
注入代码
把url改为
http://127.0.0.1:5500/login.html?txt_name=mzh&txt_passwd=123%df%27%20or%201=1%23&login=%E7%99%BB+%E5%BD%95
追加的
%df%27%20or%201=1%23
表示url编码的
空格or空格1=1#
(这里的空格就是空格,一个字符,我这么写是为了方便大家理解)
常用的理解。%df一般是用来转换编码的
%df’(浏览器自动进行url编码%27)->%df%27
下图登录失败了,宽字节注入也失败了。
因为我们的js检查了url
if(str.indexOf("%")>=0){
mark ="no";
mess +=" % ";}
functionrefreshCSS(){var sheets =[].slice.call(document.getElementsByTagName("link"));var head = document.getElementsByTagName("head")[0];for(var i =0; i < sheets.length;++i){var elem = sheets[i];var parent = elem.parentElement || head;
parent.removeChild(elem);var rel = elem.rel;if(elem.href &&typeof rel !="string"|| rel.length ==0|| rel.toLowerCase()=="stylesheet"){var url = elem.href.replace(/(&|\?)_cacheOverride=\d+/,'');
elem.href = url +(url.indexOf('?')>=0?'&':'?')+'_cacheOverride='+(newDate().valueOf());}
parent.appendChild(elem);}}
3. 能够基本防住手动注入和sqlmap攻击(测试案例)
防止手动注入
随便输入异常符号都无法成功的注入
select * from news where id=http://……?id=1
因为是post的方法,并且js对url处理,url也被锁死。
哪怕我在url中注入正确的用户名admin和密码admin都无法成功注入,哪怕是异常字符也会被过滤掉。
防御sqlmap攻击
url已经隐藏,无法通过url进行注入攻击了。
4. 能够防止sql注入原因分析
使用js代码分析、处理并屏蔽客户端上的不安全字符,过滤字符串
功能介绍:检查是否包含“
\ \
”、“
/
” “
%
” "
'
"等字符。
function Mycheck(str) {
var mess = "不允许输入的字符:\r\n";
var mark = "yes";
if (str.indexOf(";") >= 0) {
mark = "no";
mess += " ; ";
}
if (str.indexOf("&") >= 0) {
mark = "no";
mess += " & ";
}
if (str.indexOf("<")>= 0) {
mark = "no";
mess += " < ";
}
if (str.indexOf(">") >= 0) {
mark = "no";
mess += " > ";
}
if (str.indexOf("--") >= 0) {
mark = "no";
mess += " -- ";
}
if (str.indexOf("/") >= 0) {
mark = "no";
mess += " / ";
}
if (str.indexOf("%") >= 0) {
mark = "no";
mess += " % ";
}
if (str.indexOf("'") >= 0) {
mark = "no";
mess += " ' ";
}
if (mark == "no") {
alert(mess);
return false;
} else return
return true;
}
使用正则表达式等方式替换、过滤传入的参数
functionrefreshCSS(){var sheets =[].slice.call(document.getElementsByTagName("link"));var head = document.getElementsByTagName("head")[0];for(var i =0; i < sheets.length;++i){var elem = sheets[i];var parent = elem.parentElement || head;
parent.removeChild(elem);var rel = elem.rel;if(elem.href &&typeof rel !="string"|| rel.length ==0|| rel.toLowerCase()=="stylesheet"){var url = elem.href.replace(/(&|\?)_cacheOverride=\d+/,'');
elem.href = url +(url.indexOf('?')>=0?'&':'?')+'_cacheOverride='+(newDate().valueOf());}
parent.appendChild(elem);}}
使用php的sql过滤设置
(其实类似我前面的js代码转化过滤)
打开magic_quotes_gpc来防止SQL注入。php.ini中有一个设置:magic_quotes_gpc = Off这个默认是关闭的,如果它打开后将自动把用户提交对sql的查询进行转换,比如把 ’ 转为 '等,对于防止sql注射有重大作用。
如果magic_quotes_gpc=Off,则使用addslashes()函数。
总结
大家喜欢的话,给个👍,点个关注!继续跟大家分享敲代码过程中遇到的问题!
版权声明:
发现你走远了@mzh原创作品,转载必须标注原文链接
Copyright 2022 mzh
Crated:2022-3-6
欢迎关注 『网络攻防CTF』 系列,持续更新中
欢迎关注 『网络攻防CTF』 系列,持续更新中
【网络攻防CTF】草稿(保姆级图文)
【更多内容敬请期待】
版权归原作者 发现你走远了 所有, 如有侵权,请联系我们删除。