20155202《网络对抗》Exp8 Web基础
基础问题回答
什么是表单?
- 表单是一个包含表单元素的区域,表单元素是允许用户在表单中(比如:文本域、下拉列表、单选框、复选框等等)输入信息的元素,表单在网页中主要负责数据采集功能,一个表单有三个基本组成部分:表单标签、表单域、表单按钮;
- 表单标签(
- 表单域:包含了文本框、密码框、隐藏域、多行文本框、复选框、单选框、下拉选择框和文件上传框等;
- 表单按钮:包括提交按钮、复位按钮和一般按钮,用于将数据传送到服务器上的CGI脚本或者取消输入,还可以用表单按钮来控制其他定义了处理脚本的处理工作。
浏览器可以解析运行什么语言?
- 支持HTML(超文本标记语言)、XML(可扩展标记语言)以及Python、PHP、JavaScript、ASP等众多脚本语言。
WebServer支持哪些动态语言?
- JavaScript、ASP、PHP、Ruby等脚本语言,ASP基于IIS WEB SERVER,是微软的服务器端脚本技术,PHP基于APACHE WEB SERVER,与ASP有几分类似,都是一种在服务器端执行的嵌入HTML文档的脚本语言。
实践内容
目录
- Web前端:HTML基础
- Web前端:javascipt基础
- Web后端:MySQL基础
- Web后端:PHP基础
- SQL注入
- XSS攻击测试
- 发帖和会话管理的实现
1.Web前端:HTML基础
首先,我们的Web开发是基于Apache服务器进行的,对于Apache的安装,直接用指令sudo apt-get install apache2
就可以,已经安装好Apache,对于Apache使用的端口我们也可以通过sudo vi /etc/apache2/ports.conf
指令来进行修改,使用指令apachectl start
打开Apache服务,使用netstat -aptn
查看一下端口占用
- 在浏览器中输入
localhost:80
进行查看,如图所示,打开了上次实验克隆的网页,说明我们Apache正常工作: cd var/www/html
进入到Apache的工作目录下,vi test1.html
新建一个含有表单的html,这是一个简单的登录页面,代码如下:
<html>
<head>
<title>test</title>
</head>
<body>
<table>
<form method ="POST" action="#" name="frmLogin" >
<tr>
<td>User:</td>
<td><input type="text" name="username" value="zx" size="20" maxlength="20" /></td>
<td> </td>
<td> </td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" name="password" value="20155202" size="20" maxlength="20" /></td>
<td> </td>
<td> </td>
</tr>
<tr>
<td><input type="checkbox" name="zlogin" value="1">auto login</td>
</tr>
<table>
<tr>
<td><input type="submit" name="login" value="login" /></td>
<td><input type="reset" name="rs" value="rest" /></td>
</tr>
</table>
</form>
</table>
</body>
</html>
- 结果如图:
method属性分Post和Get两种,其主要区别有以下几方面:
- Get是用来从服务器上获得数据,而Post是用来向服务器上传递数据;
- Get将表单中数据的按照variable=value的形式,添加到action所指向的URL后面,并且两者使用“?”连接,而各个变量之间使用“&”连接;Post是将表单中的数据放在form的数据体中,按照变量和值相对应的方式,传递到action所指向URL;
- Get是不安全的,因为在传输过程,数据被放在请求的URL中,而如今现有的很多服务器、代理服务器或者用户代理都会将请求URL记录到日志文件中,然后放在某个地方,这样就可能会有一些隐私的信息被第三方看到。另外,用户也可以在浏览器上直接看到提交的数据,一些系统内部消息将会一同显示在用户面前,而Post的所有操作对用户来说都是不可见的;
- Get传输的数据量小,这主要是因为受URL长度限制,而Post可以传输大量的数据,所以在上传文件只能使用Post;
- 使用Post传输的数据,可以通过设置编码的方式正确转化中文;而Get传输的数据却没有变化。
一般用post,因为它更安全
前端会用到javascript
- JavaScript是一种属于网络的脚本语言,已经被广泛用于Web应用开发,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果,通常JavaScript脚本是通过嵌入在HTML中来实现自身的功能的。
下面是上学期 java web 编程时候的代码
实现了一个验证用户名、密码的规则
<html>
<head>
<title>test</title>
</head>
<body>
<table>
<form method ="POST" action="#" name="frmLogin" >
<tr>
<td>user</td>
<td><input type="text" name="username" value="Your name" size="20" maxlength="20" onfocus="if (this.value=='Your name') this.value='';" /></td>
<td> </td>
<td> </td>
</tr>
<tr>
<td>password</td>
<td><input type="password" name="password" value="Your password" size="20" maxlength="20" onfocus="if (this.value=='Your password') this.value='';" /></td>
<td> </td>
<td> </td>
</tr>
<tr>
<td><input type="checkbox" name="zlogin" value="1">auto login</td>
</tr>
<table>
<tr>
<td><input type="submit" name="login" value="login" onClick="return validateLogin()"/></td>
<td><input type="reset" name="rs" value="reset" /></td>
</tr>
</table>
</form>
</table>
<script language="javascript">
function validateLogin(){
var sUserName = document.frmLogin.username.value ;
var sPassword = document.frmLogin.password.value ;
if ((sUserName =="") || (sUserName=="Your name")){
alert("user name");
return false ;
}
if ((sPassword =="") || (sPassword=="Your password")){
alert("password!");
return false ;
}
}
</script>
</body>
</html>
- 效果如下:
提示你是否输入用户名或者密码
接下来是web后台的编写,因为要用到数据库,所以可以用MySQL作为我们的数据库
- 先
/etc/init.d/mysql start
指令开启mysql服务,输入mysql -u root -p
,输入密码,默认密码为password,进入MySQL - 对密码进行修改:输入
use mysql;
,选择mysql数据库;输入update user set password=PASSWORD("20155202") where user='root';
,修改密码;输入flush privileges;
,更新权限;
这里注意在MySQL中输入命令后面都要带一个分号作为命令结束符:
- 尝试一下quit退出去再进来看看是不是已经改好了
- 1.
create database 库名;
建立一个数据库;使用show databases;
查看存在的数据库;使用use 库名;
使用刚刚创建的数据库: - 2.使用
create table 表名 (字段设定列表);
建立数据表,数据表是数据库中一个非常重要的对象,一个数据库中可能包含若干个数据表;使用show tables;
查看存在的数据表: - 3.使用
insert into 表名 values('值1','值2','值3'...);
插入数据;使用select * from 表名;
查询表中的数据: - 还可以在MySQL中增加新用户,使用
grant select,insert,update,delete on 数据库.* to 用户名@登录主机 identified by "密码";
指令,如图所示,增加新用户之后,退出,重新使用新用户名和密码进行登录,登录成功说明增加新用户成功:
后端编程 PHP
- PHP安装
sudo apt-get install php
- PHP(外文名:PHP: Hypertext Preprocessor,中文名:“超文本预处理器”)是一种通用开源脚本语言。语法吸收了C语言、Java和Perl的特点,利于学习,使用广泛,主要适用于Web开发领域。PHP 独特的语法混合了C、Java、Perl以及PHP自创的语法。它可以比CGI或者Perl更快速地执行动态网页。用PHP做出的动态页面与其他的编程语言相比,PHP是将程序嵌入到HTML(标准通用标记语言下的一个应用)文档中去执行,执行效率比完全生成HTML标记的CGI要高许多;PHP还可以执行编译后代码,编译可以达到加密和优化代码运行,使代码运行更快。
- 在/var/www/html目录下新建一个PHP测试文件,简单了解一下它的一些语法:
<?php
echo ($_GET["a"]);
include($_GET["a"]);
echo "This is zx php test page!<br>";
?>
浏览器打开localhost/back.php?a=/etc/passwd
可看到/etc/passwd文件的内容, 注意PHP变量大小写敏感:
- 出现问题,打不开,莫慌,因为我隔天做的,这个原因是一定要先打开Apache服务,我忘了开,apachectl start开启。
- 底部出现我的名字
简单测试完成后,开始利用PHP和MySQL结合之前编的登录网页进行简单的用户身份认证,编写login.php,代码如下所示:
<?php
$uname=($_GET["username"]);
$pwd=($_GET["password"]);
/* echo $uname; */
$query_str="SELECT * FROM zxtable where username='$uname' and password='$pwd';";
/* echo "<br> {$query_str} <br>";*/
$mysqli = new mysqli("127.0.0.1", "root", "20155202", "zx");
/* check connection */
if ($mysqli->connect_errno) {
printf("Connect failed: %s
", $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> Welcome login Mr/Mrs:{$uname} <br> ";
} else {
echo "<br> login failed!!!! <br> " ;
}
/* free result set */
$result->close();
}
$mysqli->close();
?>
- 这里127.0.0.1是本机地址,root是MySQL的用户名,20155202是我之前设置的登录密码,zx是数据库的库名。
- 先将之前编的登录网页的loginhtml代码中form的action属性由
#
改成login.php
,即登录后跳转到login.php,放在/var/www/html目录下,再在火狐浏览器中访问登录页面:localhost:80/login.html
报错Connect failed: Access denied for user 'root'@'localhost'
- 我居然被进程拒绝了,难道是我用户名错了,去看看
- 这时进入/etc/mysql目录下,执行sudo vi debian.cnf或者sudo vimdebian.cnf查看里面的用户名和密码,
然后使用这个文件中的用户名和密码进入mysql,emmm还是被拒绝了 - 我按照网上说的解决办法感觉都不靠谱,于是想既然说我mysql的用户名错了,那我直接去改了mysql用户名得了,再加一个测试数据zxtest进数据库表里:
我还是强啊
- 没改数据库表
- 成功
- copy了一个模板
- 再编一个页面welcome.php,再在login.php中加一行代码header("Refresh:1;url=welcome.php");,实现在登录成功1秒之后跳转到welcome.php页面:
SQL注入
- SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。
- 在用户名输入框中输入' or 1=1#,密码随便输入,这时候的合成后的SQL查询语句为
select * from lxmtable where username='' or 1=1#' and password=''
,#相当于注释符,会把后面的内容都注释掉,而1=1是永真式,所以这个条件肯定恒成立,所以能够成功登陆:
- 还可以通过SQL注入将用户名和密码保存在数据库中,但是得修改一下之前的代码,因为我们之前编的代码中
if ($result = $mysqli->query($query_str))
这条判断语句不允许多条sql语句执行,所以将它改成
if ($result = $mysqli->multi_query($query_str))
便能实现执行多个sql语句,接着在用户名输入框中输入
';insert into zxtable values('xx','5202');#
拆开来看就是
SELECT * FROM zxtable WHERE username='';、insert into zxtable values('xx','5202',);
,接着登录,再去查数据库:
- 发现添加了我们要的用户名,再重新登录,真的狗:
XSS攻击
漏洞原理:
-
XSS又叫CSS (Cross Site Script) ,跨站脚本攻击。它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意的特殊目的。
-
进行测试,在用户名输入框中输入读取/var/www/html目录下的图片:
实验总结与原理:
这次实验我每天做一点,花了好几天,所以时间跨度比较大,而且加上虚拟机反复重启,遇到的问题特别的多,不过我还是被脚本攻击震撼到了,可能由于你这个工程师的代码安全性不高而导致无法估量的损失,如果放在政府部门更加了不得,这次实验也让我领悟了一个生活哲理,所以做什么事情一定要精益求精,否则总会有人挑你的毛病(跑题了),所以好好学习编程,总有金子般的漏洞等待你的发现~~~