欢迎关注 『网络攻防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/2022 10: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
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>防止SQL注入的登录页面</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>基于layui框架的放sql注入网站</title>
<link rel="stylesheet" href="layui-master/src/css/layui.css">
<link rel="stylesheet" href="layui-master/src/css/modules/code.css">
<script src="layui-master/src/layui.js" type="text/javascript" charset="UTF-8"></script>
<script type="text/javascript">
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 (str.indexOf("#") >= 0) {
mark = "no";
mess += " # ";
}
if (mark == "no") {
alert(mess);
return false;
} else return
return true;
}
</script>
</head>
<body style="font-size:12px">
<table width="382" border="0" align="center" cellpadding="0" cellspacing="0">
<tr>
<td height="99" background="images/login_01.jpg"> </td>
</tr>
<tr>
<td height="160" bgcolor="#FEF7C3">
<table class="layui-table" lay-size="lg" lay-even lay-skin="row" width="300" border="0" align="center"
cellpadding="3" cellspacing="0">
<form method='post' action='login.php' name="form1" onSubmit="Mycheck(form1.username.value)">
<tr>
<td height="22" colspan="2" align="center"> </td>
</tr>
<tr>
<td height="22" align="right">mzh</td>
</tr>
<tr>
<td height="22" align="right">网工191</td>
</tr>
<tr>
<td height="22" align="right">19145120</td>
</tr>
<tr>
<td height="22" align="right">用户</td>
<td height="22"><input name="username" type="text" class="layui-input-inline" id="txt_name"
size="18" maxlength="50"></td>
</tr>
<tr>
<td height="22" align="right">密码:</td>
<td height="22"><input name="passwd" type="password" class="layui-input-inline"
id="txt_passwd" size="19" maxlength="50"></td>
</tr>
<tr>
<td height="22" colspan="2" align="center"><input name="login" type="submit" id="login"
value="登 录"
class="layui-btn layui-btn-radius layui-btn-warm">
<input type="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 -->
<script type="text/javascript">
// <![CDATA[ <-- For SVG support
if ('WebSocket' in window) {
(function () {
function refreshCSS() {
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=' + (new Date()
.valueOf());
}
parent.appendChild(elem);
}
}
var protocol = window.location.protocol === 'http:' ? 'ws://' : 'wss://';
var address = protocol + window.location.host + window.location.pathname + '/ws';
var socket = new WebSocket(address);
socket.onmessage = function (msg) {
if (msg.data == 'reload') window.location.reload();
else if (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验证代码
<?php
session_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
得到了urlhttp://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 += " % ";
}
function refreshCSS() {
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=' + (new Date()
.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;
}
使用正则表达式等方式替换、过滤传入的参数
function refreshCSS() {
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=' + (new Date()
.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文章来源:https://www.toymoban.com/news/detail-471755.html
欢迎关注 『网络攻防CTF』 系列,持续更新中
欢迎关注 『网络攻防CTF』 系列,持续更新中
【网络攻防CTF】草稿(保姆级图文)
【更多内容敬请期待】文章来源地址https://www.toymoban.com/news/detail-471755.html
到了这里,关于网络攻防期末大作业选题:防sql注入的登录网站【网络攻防CTF】(保姆级图文)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!