一.XXE
1.概述
XXE -"xml external entity injection"
既"xml外部实体注入漏洞"。
概括一下就是"攻击者通过向服务器注入指定的xml实体内容,从而让服务器按照指定的配置进行执行,导致问题"
也就是说服务端接收和解析了来自用户端的xml数据,而又没有做严格的安全控制,从而导致xml外部实体注入。
现在很多语言里面对应的解析xml的函数默认是禁止解析外部实体内容的,从而也就直接避免了这个漏洞。
以PHP为例,在PHP里面解析xml用的是libxml,其在≥2.9.0的版本中,默认是禁止解析xml外部实体内容的。
那么什么是xml呢?
XML是可扩展的标记语言(eXtensible Markup Language),设计用来进行数据的传输和存储, 结构是树形结构,有标签构成,这点很像HTML语言。但是XML和HTML有明显区别如下:
XML 被设计用来传输和存储数据。
HTML 被设计用来显示数据。
2.过关
看提示我们需要了解这些基础知识
第一部分:XML声明部分
<?xml version="1.0"?>
第二部分:文档类型定义 DTD
<!DOCTYPE note[
<!--定义此文档是note类型的文档-->
<!ENTITY entity-name SYSTEM "URI/URL">
<!--外部实体声明-->
]>
第三部分:文档元素
<note>
<to>Dave</to>
<from>Tom</from>
<head>Reminder</head>
<body>You are a good man</body>
</note>
其中,DTD(Document Type Definition,文档类型定义),用来为 XML 文档定义语法约束,可以是内部申明也可以使引用外部DTD。
XML中对数据的引用称为实体,实体中有一类叫外部实体,用来引入外部资源,有SYSTEM和PUBLIC两个关键字,表示实体来自本地计算机还是公共计算机,外部实体的引用可以借助各种协议,比如如下的三种
file:///path/to/file.ext
http://url
php://filter/read=convert.base64-encode/resource=conf.php
回到题目,随意输入123
简单判断一下内部实体,输入:
<?xml version="1.0"?>
<!DOCTYPE ANY [
<!ENTITY xxe "菜鸟" > ]>
<a>&xxe;</a>
发现有回显
查看本地文件(外部实体),输入:
<?xml version="1.0"?>
<!DOCTYPE ANY [
<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini"> ]>
<a>&xxe;</a>
同样有回显
原理就是通过输入其他XML代码来获取相关信息,其他例如远程代码执行、xxe联动ssrf、探测内网端口(需要用到虚拟机)的相关代码还需以后深度学习!
查看源码:
发现第49行simplexml_load_string()函数中使用了LIBXML_NOENT参数,导致外部实体可以被解析,才造成了xxe漏洞
二.URL重定向
1.概述
不安全的url跳转
不安全的url跳转问题可能发生在一切执行了url地址跳转的地方。
如果后端采用了前端传进来的(可能是用户传参,或者之前预埋在前端页面的url地址)参数作为了跳转的目的地,而又没有做判断的话
就可能发生"跳错对象"的问题。
url跳转比较直接的危害是:
-->钓鱼,既攻击者使用漏洞方的域名(比如一个比较出名的公司域名往往会让用户放心的点击)做掩盖,而最终跳转的确实钓鱼网站
2.过关
进入题目,发现有四句话,分别点一下
第一句和第二句都没反应,第三句返回到了URL重定向概述界面
第四句,有回显,如下,还发现url多了个“url=i”
F12查看前段代码,发现了原因,其他的都是空白,唯有第四句有内容
我们将url后面的内容修改一下,比如构造payload:
127.0.0.1/pk/vul/urlredirect/urlredirect.php?url=http://www.baidu.com
成功跳转到百度!
利用这个漏洞,我们可以上传其他的恶意url,让其跳转!
查看源码:
用户可控的参数没有被好好过滤(通过GET请求获取前端传进来的url,判断一下,当url参数的值不为i时,就会跳转到url值表示的页面,这就存在着问题。)
三.SSRF
1.概述
SSRF(Server-Side Request Forgery:服务器端请求伪造)
其形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能,但又没有对目标地址做严格过滤与限制
导致攻击者可以传入任意的地址来让后端服务器对其发起请求,并返回对该目标地址请求的数据
数据流:攻击者----->服务器---->目标地址
根据后台使用的函数的不同,对应的影响和利用方法又有不一样
PHP中下面函数的使用不当会导致SSRF:
file_get_contents()
fsockopen()
curl_exec()
如果一定要通过后台服务器远程去对用户指定("或者预埋在前端的请求")的地址进行资源请求,则请做好目标地址的过滤。
2.SSRF(curl)
进入题目,让我们了解一下curl函数
那就“浅浅”地了解一下吧!
curl_close() 关闭一个cURL会话。
curl_copy_handle() 复制一个cURL句柄和它的所有选项。
curl_errno() 返回最后一次的错误号。
curl_error() 返回一个保护当前会话最近一次错误的字符串。
curl_escape() 返回转义字符串,对给定的字符串进行URL编码。
curl_exec() 执行一个cURL会话。
curl_file_create() 创建一个 CURLFile 对象。
curl_getinfo() 获取一个cURL连接资源句柄的信息。
curl_init() 初始化一个cURL会话。
curl_multi_add_handle() 向curl批处理会话中添加单独的curl句柄。
curl_multi_close() 关闭一组cURL句柄。
curl_multi_exec() 运行当前 cURL 句柄的子连接。
curl_multi_getcontent() 如果设置了CURLOPT_RETURNTRANSFER,则返回获取的输出的文本流。
curl_multi_info_read() 获取当前解析的cURL的相关传输信息。
curl_multi_init() 返回一个新cURL批处理句柄。
curl_multi_remove_handle() 移除curl批处理句柄资源中的某个句柄资源。
curl_multi_select() 等待所有cURL批处理中的活动连接。
curl_multi_setopt() 设置一个批处理cURL传输选项。
curl_multi_strerror() 返回描述错误码的字符串文本。
curl_pause() 暂停及恢复连接。
curl_reset() 重置libcurl的会话句柄的所有选项。
curl_setopt_array() 为cURL传输会话批量设置选项。
curl_setopt() 设置一个cURL传输选项。
curl_share_close() 关闭cURL共享句柄。
curl_share_init() 初始化cURL共享句柄。
curl_share_setopt() 设置一个共享句柄的cURL传输选项。
curl_strerror() 返回错误代码的字符串描述。
curl_unescape() 解码URL编码后的字符串。
curl_version() 获取cURL版本信息。
回到题目
点击那句话,出现了一首诗,还发现清楚地显示了url
因此,我们可以利用curl支持的多种协议来探测服务器内网信息:
这里只展示file协议和http/https协议,如:
file协议
查看本地文件:?url=file:///c:/windows/win.ini
又又又又把ini文件搞出来了!
http/https协议
这是我之前用phpstudy-pro创建出的一个网站
将url改为内网上的其他主机, (使用http协议)端口为80
http://127.0.0.1/pk/vul/ssrf/ssrf_curl.php?url=http://127.0.0.1:80
成功回显Hello world
3.SSRF(file_get_content)
看起来和上关差不多,看提示说要我们了解一下 file_get_content()相关函数的用法
那就再“浅浅”地了解一下哇!
file_get_contents() 函数将指定 URL 的文件读入一个字符串并返回。
该函数是用于把文件的内容读入到一个字符串中的首选方法。如果服务器操作系统支持,还会使用内存映射技术来增强性能。
函数结构: file_get_contents(path,include_path,context,start,max_length)
path:要读取的路径或链接。
include_path:是否在路径中搜索文件,搜索则设为 1,默认为 false。
context:修改流的行为,如超时时间,GET / POST 等。
start:开始读文件的位置。
max_length:读取文件的字节数。
file_get_contents 和 curl 区别:
curl 支持更多协议,有http、https、ftp、gopher、telnet、dict、file、ldap;模拟 Cookie 登录,爬取网页;FTP 上传下载。
fopen / file_get_contents 只能使用 GET 方式获取数据。
curl 可以进行 DNS 缓存,同一个域名下的图片或其它资源只需要进行一次DNS查询。
curl 相对来说更加快速稳定,访问量高的时候首选 curl,缺点就是相对于 file_get_contents 配置繁琐一点,file_get_contents 适用与处理小访问的应用。
回到题目
再点击那句话,同样出现了一首诗,不同的是,上面的“url”变为了“file”
还是先file协议进行文件读取:
本地文件 payload:?file=file:///c:/windows/win.ini
又又又又把ini文件弄出来了!
再来试试将file改为内网上的其他主机, (使用http协议)端口为80
payload:http://127.0.0.1/pk/vul/ssrf/ssrf_fgc.php?file=http://127.0.0.1/
Hello World!
同理,还有利用其他的协议就以上两题对url/file进行修改,来得到我们想要的信息!