2020-2021-2 20181312 【网络对抗技术】Exp8 Web综合
Exp8 Web综合
序言
Web前端
- 编程言语:html/css/javascript(js)
- 运行环境:浏览器
- 编程用途:在浏览器内部的动态,美观展示形式
Web后端
- 编程语言:PHP/JSP/.NET...
- 运行环境:应用服务器/中间件
- 编程用途:对前端提交的数据进行处理并返回相应的HTML网页内容
SQL注入
- 通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。
- 就是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。
XSS攻击
- 跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆。故将跨站脚本攻击缩写为XSS。
- XSS是一种经常出现在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。攻击者利用XSS漏洞旁路掉访问控制——例如同源策略(same origin policy)。这种类型的漏洞由于被骇客用来编写危害性更大的phishing攻击而变得广为人知。
CSRF攻击
- Cross Site Request Forgery跨站请求伪造
- CSRF就是冒名登录。跨站请求伪造的核心本质是窃取用户的Session,或者说Cookie,因为目前主流情况Session都是存在Cookie中。攻击者并不关心被害者具体帐号和密码,因为一旦用户进行了登录,Session就是用户的唯一凭证。只要攻击者能够得到Session,就可以伪装成被害者进入服务器。
- 主要是当访问网站A时输入用户名和密码,在通过验证后,网站A产生Cookie信息并返回,此时登录网站A成功,可正常发送请求到网站A。在未退出网站A前,若访问另一个网站B,网站B可返回一些攻击性代码并请求访问网站A;因此在网站B的请求下,向网站A发出请求。但网站A不知道该请求恶意的,因此还是会执行该恶意代码。
一、实验内容
-
Web前端HTML
能正常安装、启停Apache。理解HTML,理解表单,理解GET与POST方法,编写一个含有表单的HTML。
-
Web前端javascipt
理解JavaScript的基本功能,理解DOM。
在1的基础上,编写JavaScript验证用户名、密码的规则,在用户点击登陆按钮后回显“欢迎+输入的用户名”。
尝试注入攻击:利用回显用户名注入HTML及JavaScript。
-
Web后端MySQL基础
正常安装、启动MySQL,建库、创建用户、修改密码、建表。
-
Web后端PHP
编写PHP网页,连接数据库,进行用户认证。
-
最简单的SQL注入和XSS攻击测试
-
选做Webgoat或类似平台的SQL注入、XSS、CSRF攻击各一例
二、实验过程
2.1 Web前端HTML
输入service apache2 start
启动Apache服务,如果没有任何错误提示,即表明成功开启
浏览器中输入127.0.0.1,可以看到
cd /var/www/html
进入Apache目录下,新建一个含有表单的html文件login.html,把如下代码粘贴进去
<!DOCTYPE html>
<html>
<style>
body {
margin: 0;
padding: 0;
background: url('https://s1.ax1x.com/2020/04/08/GfAC5V.jpg') no-repeat;
height: 100%;
width: 100%;
overflow: hidden;
background-size: 100%;
font-family: 宋体;
}
.sign-div {
width: 300px;
padding: 20px;
text-align: center;
background: url(bg02.jpg);
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
overflow: hidden;
}
.sign-div h1 {
margin-top: 100px;
color: #fff;
font-size: 40px;
}
.sign-div input {
display: block;
width: 100%;
padding: 0 16px;
height: 44px;
text-align: center;
box-sizing: border-box;
outline: none;
border: none;
font-family: 'montserrat', sans-serif;
}
.sign-text {
margin: 4px;
background: rgba(255, 255, 255, 5);
border-radius: 6px;
}
.sign-btn {
margin-top: 50px;
margin-bottom: 20px;
background: #487eb0;
color: #fff;
border-radius: 44px;
cursor: pointer;
transition: 0.8s;
}
.sign-btn:hover {
transform: scale(0.96);
}
.sign-div a {
text-decoration: none;
color: #fff;
font-family: 'montserrat', sans-serif;
font-size: 14px;
padding: 10px;
transition: 0.8s;
display: block;
}
.sign-div a:hover {
background: rgba(0, 0, 0, 0.3);
}
</style>
<head>
<meta charset="UTF-8" />
<title>用户登录</title>
</head>
<body>
<div class="sign-div">
<form name="login" action="网页.html" method="post">
<h1>用户登录</h1>
<input class="sign-text" type="text/email" name="username" placeholder="账号" />
<input class="sign-text" type="password" name="password" placeholder="密码" />
<input class="sign-btn" type="submit" onClick="return validateLogin()" value="登录" />
<a id="forget_pwd" href="http://www.baidu.com/">
忘记密码?
</a>
<a id="register" href="注册.html">创建新账号</a>
</form>
</div>
</body>
</html>
在浏览器中输入/var/www/html/login.html
打开网页
2.2 Web前端javascipt
对上述代码添加用户名、密码验证规则
<script language="javascript">
function validateLogin() {
var sUserName = document.login.username.value;
var sPassword = document.login.password.value;
if (sUserName == "") {
alert("用户名不能为空!");
return false;
}
if (sPassword == "") {
alert("密码不能为空!");
return false;
}
}
</script>
刷新一下该网页,不输入用户名密码,点击登入,可以看到
输入用户名,不输入密码,点击登入,可以看到
2.3 Web后端MySQL基础
输入service mysql start
启动MySQL,如果没有任何错误提示,即表明成功开启
输入mysql -u root -p
使用root权限进入,默认密码为password
2.3.1 建库
show databases; 查看root下数据库信息
create database xieyi; 创建名为xieyi的数据库
show databases; 再次查看root下数据库信息
2.3.2 建表
use xieyi; 使用新创建的数据库
create table logininfo (username VARCHAR(20),passward VARCHAR(20)); 建立名为logininfo的数据库表,并设置两个变长字符串字段username和password
show tables; 查看表信息
insert into logininfo values('xieyi','20181312'); 在表中插入一条记录
select * from logininfo; 查询表中的数据
2.3.3 修改密码
use mysql; 选择使用mysql这个数据库
select user, password, host from user; 查看当前用户信息
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('root'); 修改密码,新密码设置为root
select user, password, host from user; 再次查看当前用户信息
exit 退出数据库
这时我们使用新密码登录mysql -u root -p
2.3.4 创建用户
grant select,insert,update,delete on xieyi.* to xy@localhost identified by "20181312";
这里on 接数据库名,.*表示该数据库下所有表,to 接用户名,@后可以是localhost,也可以是远程登录方式的IP,by 后引号内为密码。
mysql -u xy -p
使用新的用户名和密码进行登录
2.4 Web后端PHP
利用PHP和MySQL,结合前面编写的登录网页进行登录身份认证。
编写xylogin.php代码放入/var/www/html
下:
<?php
$uname = $_POST['username'];
$pwd = $_POST['password'];
echo $uname;
$query_str = "SELECT * FROM logininfo where username='$uname' and passward='$pwd';";//这里的查询语句中passward是由于之前建表时输入出错导致的
$mysqli = new mysqli('127.0.0.1', 'xy', '20181312', 'xieyi');//addr,username,password,dbname
/* check connection */
if ($mysqli->connect_errno) {
printf("Connect failed: %s\n", $mysqli->connect_error);
exit();
}
echo ' connection ok!';
/* Select queries return a resultset */
if ($result = $mysqli->query($query_str)) {
if ($result->num_rows > 0) {
echo "<br> {$uname}:Welcome login!! <br> ";
} else {
echo '<br> login failed!!!! <br> ';
}
/* free result set */
$result->close();
}
$mysqli->close();
?>
将之前的login.html中的action
设为login.php
在浏览器输入127.0.0.1/login.html
访问自己的登录界面
输入正确用户名和密码登入,可以看到
输入正确的用户名和错误的密码,可以看到
2.5 最简单的SQL注入和XSS攻击测试
2.5.1 SQL注入
在浏览器输入127.0.0.1/login.html
访问自己的登入页面
在用户名输入框输入' or 1=1#
,密码任意输入,点击登入
可以看到登入成功
在这里,合成的SQL查询语句为select * from users where username='' or 1=1 ;# and password=password('输入值')
,#后都是注释,1=1是永真语句,恒等于true,所以任意输入password都能登入成功,与此同时,把1=1
这个地方换成任意恒为true的语句都能产生同等效果。
2.5.2 XSS攻击测试
选取一张图片放入/var/www/html
目录下,命名为1.jpg
在浏览器输入127.0.0.1/login.html
访问自己的登入页面
输入同户名<img src="1.jpg"/>
,密码任意输入,点击登入可以读取到图片
这张图比较大,我将其缩小可以看到全貌
改为原大小时,在左下角可以看到登入信息。
2.6 选做WebGoat或类似平台的SQL注入、XSS、CSRF攻击各一例
WebGoat是OWASP组织研制出的用于进行web漏洞实验的应用平台,用来说明web应用中存在的安全漏洞。其运行在带有java虚拟机的平台之上,并提供了一系列web安全学习的教程,来指导用户利用这些漏洞进行攻击。
WebGoat运行在带有java虚拟机的平台之上,目前提供的训练课程有很多,包含了XSS、线程安全、SQL注入、访问控制、隐藏字段、Cookie等。
2.6.1 WebGoat环境搭建
下载jar包:webgoat-server-8.0.0.M26.jar
WebGoat默认使用8080端口,所以开启前先用netstat -tupln | grep 8080
查看端口是否被占用,如果被占用,用kill 进程号
终止占用8080端口的进程。
因为WebGoat运行java平台之上,所以使用java -version
查看jdk版本
java -jar webgoat-server-8.0.0.M26.jar
加载jar包
浏览器中输入http://127.0.0.1:8080/WebGoat
打开WebGoat注册界面,先注册后登录即可。
2.6.2 SQL注入
String SQL injection
题目描述
"SELECT * FROM user_data WHERE first_name = 'John' AND last_name = '" + lastName + "'";
,输入是lastName。
题目要求
在不需要知道任何用户名的情况下,得到整张表的内容。
题目分析
上述查询语句简化为SELECT * FROM user_data WHERE first_name = 'John' AND last_name = '
+ 输入
+ ';
AND优先于OR运算,所以前面部分不论是什么,最终都是一个0/1,只需要OR上一个true,最终就是true
输入部分填写的内容只要最后是类似OR true
即可。但是,注意到输入的前面有个'
后面也有一个'
,所以得到最终的输入为:' OR '1'='1
运行结果
2.6.3 XSS攻击
Reflected XSS
方法
确定哪个字段易受XSS的影响,验证服务器端的所有输入总是一种很好的做法。 当HTTP响应中使用未经验证的用户输入时,可能会发生XSS;
在反射的XSS攻击中,攻击者可以用攻击脚本制作一个URL,并将其发布到另一个网站,发送电子邮件,或者以其他方式让受害者点击它;
一个简单的方法来确定一个字段是否容易受到XSS攻击,就是使用alert.()或console.log()方法,用其中一个找出哪个领域是脆弱的。
题目描述
题目分析
当我点击Update Cart时,可以看到页面上输出,初步确认卡号字段存在xss。
然后直接注入<script>alert(20181312);</script>
发现成功。
2.6.4 CSRF攻击
Basic Get CSRF Exercise
题目描述
题目分析
题目要求我们换个源点击这个提交,那么就用Burp的proxy抓个包,把Referer修改一下,就得到了flag,然后把得到的flag填到下面的Confirm Flag Value中,就OK了。
如下修改Referer中的8080为9080,点击send可以得到右侧内容
将flag:33087 submit,可以看到显示正确!
三、回答一些问题
3.1 什么是表单?
表单在网页中主要负责数据采集功能,然后将采集的数据传送到后台。
一个表单有三个基本组成部分:
表单标签:这里面包含了处理表单数据所用CGI程序的URL以及数据提交到服务器的方法。
表单域:包含了文本框、密码框、隐藏域、多行文本框、复选框、单选框、下拉选择框和文件上传框等。
表单按钮:包括提交按钮、复位按钮和一般按钮;用于将数据传送到服务器上的CGI脚本或者取消输入,还可以用表单按钮来控制其他定义了处理脚本的处理工作。
3.2 浏览器可以解析运行什么语言?
浏览器可以解析运行HTML、PHP、JavaScript、ASP等众多脚本语言。
3.3 WebServer支持哪些动态语言?
WebServer支持JavaScript、ASP、PHP、Ruby、.NET等脚本语言。
3.4 防范注入攻击的方法有哪些
防范SQL注入攻击
- 使用正则表达式过滤传入的参数。
- 关闭或删除不必要的交互式提交表单页面。
- jsp中调用函数检查是否包函非法字符,做好规范的校验工作,比如搜索框不能输入非法字符、限制输入的长度等。
- 使用prepared statements语句绑定变量来执行SQL字符串。没有使用prepared statements语句绑定变量可能很容易受到攻击。
防范XSS攻击
- 特征匹配方式,在所有提交的信息中都进行匹配检查。对于这种类型的XSS攻击,采用的模式匹配方法一般会需要对“javascript”这个关键字进行检索,一旦发现提交信息中包含“javascript”,就认定为XSS攻击;
- 对所有用户提交内容进行可靠的输入验证,包括对URL、查询关键字、HTTP头、POST数据等,仅接受指定长度范围内、采用适当格式、采用所预期的字符的内容提交,对其他的一律过滤;
- 实现Session标记(session tokens)、CAPTCHA系统或者HTTP引用头检查,以防功能被第三方网站所执行。HTTP-only Cookie: 禁止 JavaScript 读取某些敏感 Cookie,攻击者完成 XSS 注入后也无法窃取此 Cookie;
- 使用验证码:防止脚本冒充用户提交危险操作。
防范CSRF攻击
- 验证请求中的Token,每一个网页包含一个web server产生的token, 提交时,也将该token提交到服务器,服务器进行判断,如果token不对,就判定位CSRF攻击。将敏感操作又get改为post,然后在表单中使用token. 尽量使用post也有利于防御CSRF攻击。
- 验证 Referer,因为伪造的请求一般是从第三方网站发起的,所以第一个防御方法就是判断 referer 头,如果不是来自本网站的请求,就判定为CSRF攻击。但是该方法只能防御跨站的csrf攻击,不能防御同站的csrf攻击(虽然同站的csrf更难)。
- 添加加随机验证,每一个重要的post提交页面,使用一个验证码,因为第三方网站是无法获得验证码的。还有使用手机验证码,比如转账是使用的手机验证码。
四、问题与解决办法
在2.3.3修改root用户密码这一步中,我发现如下这句SQL语句会报错
update user set password=PASSWORD("root") where user='root'; 修改root用户密码为root
于是我查询了一些资料,在Stack Overflow上发现了解答
MySQL是基于MariaDB的,在MariaDB-10.4+版本中,mysql.user已经不是一个表而是一个视图了,旧博客给的更新密码的SQL语句已经不再适用了,官方文档给出了最新的与认证相关的修改机制,我们可以使用SET PASSWORD或者ALTER USER去管理用户认证相关内容。
SET PASSWORD
ALTER USER