SSRF && XXE && 远程代码执行 && 反序列化漏洞
作者: 分类: 网络安全 发布于: 2024-07-09 12:00:23 浏览:202 评论(0)
SSRF && XXE && 远程代码执行 && 反序列化漏洞
SSRF漏洞
漏洞简介
SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统。
漏洞原理
SSRF形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目地址做过滤与限制。
通过控制功能中的发起请求的服务来当作跳板攻击内网中其他服务。比如,通过控制前台的请求远程地址加载的响应,来让请求数据由远程的URL域名修改为请求本地、或者内网的IP地址及服务,来造成对内网系统的攻击。
漏洞危害
- 扫描内网开放服务
- 向内部任意主机的任意端口发送payload来攻击内网服务
- DOS攻击(请求大文件,始终保持连接Keep-Alive Always)
- 攻击内网的web应用,例如直接SQL注入、XSS攻击等
- 利用file、gopher、dict协议读取本地文件、执行命令等
检测与绕过
漏洞检测
假设一个漏洞场景:某网站有一个在线加载功能可以把指定的远程图片加载到本地,功能链接如下:
http://www.xxx.com/image.php?image=http://www.xxc.com/a.jpg
那么网站请求的大概步骤应该是类似以下:
用户输入图片地址->请求发送到服务端解析->服务端请求链接地址的图片数据->获取请求的数据加载到前台显示。
这个过程中可能出现问题的点就在于请求发送到服务端的时候,系统没有效验前台给定的参数是不是允许访问的地址域名,例如,如上的链接可以修改为:
http://www.xxx.com/image.php?image=http://127.0.0.1:22
如上请求时则可能返回请求的端口banner。如果协议允许,甚至可以使用其他协议来读取和执行相关命令。例如:
http://www.xxx.com/image.php?image=file:///etc/passwd (读取linux第三文件)
http://www.xxx.com/image.php?image=dict://127.0.0.1:22/data:data2 (dict可以向服务端口请求data data2)
http://www.xxx.com/image.php?image=gopher://127.0.0.1:2233/_test (向2233端口发送数据test,同样可以发送POST请求)
......
对于不同语言实现的web系统可以使用的协议也存在不同的差异,其中:
php:
http、https、file、gopher、phar、dict、ftp、ssh、telnet...
java:
http、https、file、ftp、jar、netdoc、mailto...
判断漏洞是否存在的重要前提是,请求是服务器发起的,以上链接即使存在并不一定代表这个请求是服务器发起的。因此前提不满足的情况下,不需要考虑SSRF。
http://www.xxx.com/image.php?image=http://www.xxc.com/a.jpg
前端获取链接后,是由js来获取对应参数交由window.location来处理相关的请求,或者加载到当前的iframe框架中,此时并不存在SSRF ,因为请求是本地发起,并不能产生攻击服务端内网的需求。
漏洞出现点
分享
通过url 地址分享文章,例如如下地址:
http://share.magedu.com/index.php?url=http://127.0.0.1
通过url参数的获取来实现点击链接的时候跳到指定的分享文章。如果在此功能中没有对目标地址的范围做过滤与限制则就存在着SSRF漏洞。
图片加载与下载
通过URL地址加载或下载图片
http://image.magedu.com/image.php?image=http://127.0.0.1
图片加载存在于很多的编辑器中,编辑器上传图片处,有的是加载本地图片到服务器内,还有一些采用加载远程图片的形式,本地文章加载了设定好的远程图片服务器上的图片地址,如果没对加载的参数做限制可能造成SSRF。
图片、文章收藏功能
http://title.magedu.com/title?title=http://title.magedu.com/as52ps63de
例如title参数是文章的标题地址,代表了一个文章的地址链接,请求后返回文章是否保存、收藏的返回信息。如果保存、收藏功能采用了此种形式保存文章,则在没有限制参数的形式下可能存在SSRF。
利用参数中的关键字来查找
例如以下的关键字:
share
wap
url
link
src
source
target
u
3g
display
sourceURl
imageURL
domain
...
漏洞绕过
部分存在漏洞,或者可能产生SSRF的功能中做了白名单或者黑名单的处理,来达到阻止对内网服务和资源的攻击和访问。因此想要达到SSRF的攻击,需要对请求的参数地址做相关的绕过处理,常见的绕过方式如下:
限制为http://www.xxx.com 域名时
可以尝试采用http基本身份认证的方式绕过,http://www.xxx.com@www.xxc.com。 在对@解析域名中,不同的处理函数存在处理差异,例如: http://www.aaa.com@www.bbb.com@www.ccc.com,在PHP的parse_url中会识别www.ccc.com,而libcurl则识别为www.bbb.com。
限制请求IP不为内网地址
即限制访问所有内网IP,可采用短网址绕过,短网址-短链接生成
也可以使用在线进制转换 , 127转换16进制为7f,系统中表示16进制前面要加0x,8进制前加0
可以将127.0.0.1采用进制转换
八进制:0177.0.0.1
十六进制:0x7f.0.0.1
十进制:2130706433
哪一种进制可以绕过需要我们进行尝试,和程序后端的处理逻辑有关系
其他绕过形式可以查看:https://www.secpulse.com/archives/65832.html
漏洞防御
- 设置URL白名单或者黑名单内网IP
- 过滤返回信息,验证远程服务器对请求的响应是比较容易的方法。如果web应用是去获取某一种类型的文件。那么在把返回结果展示给用户之前先验证返回的信息是否符合标准;
- 禁用不需要的协议,仅仅允许http和https请求,可以防止类似于file:///,gopher://,ftp:// 等引起的问题。
XXE漏洞
漏洞简介
XXE:XML External Entity 即外部实体,从安全角度理解成XML External Entity attack(外部实体注入攻击)。由于程序在解析输入的XML数据时,解析了攻击者伪造的外部实体而产生的。
例如PHP中的simplexml_load默认情况下会解析外部实体,有XXE漏洞的标志性函数是simplexml_load_string()。
XML外部实体
XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD(文档类型定义)、文档元素。
主要看一下[DTD-实体],首先让我们了解一下基本的PAYLOAD结构:
XML 文档声明,在文档的第一行
XML 文档类型定义,即DTD,XXE 漏洞所在的地方
XML 文档元素
DTD(文档类型定义)的作用是定义 XML 文档的合法构建模块。DTD 可以在 XML 文档内声明,也可以外部引用。
内部声明DTD <!DOCTYPE 根元素 [元素声明]>
外部声明DTD <!DOCTYPE 根元素 SYSTEM "文件名">
<!DOCTYPE note SYSTEM "Note.dtd">
或者<!DOCTYPE 根元素 PUBLIC "public_ID" "文件名">
内部声明DTD
<?xml version="1.0"?> //xml声明
<!DOCTYPE note [
<!ELEMENT note (to,from,heading,body)> //定义了note元素,并且note元素下面有4个子元素
<!ELEMENT to (#PCDATA)> //定义了子元素to,后面的(#PCDATA)意思是to元素里面的字符串内容不会被解析
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]> //从<!DOCTYPE...到}>,是DTD文档的定义
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
外部声明DTD
<?xml version="1.0"?>
<!DOCTYPE note SYSTEM "note.dtd">
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
这个note.dtd的内容就是:
<!DOCTYPE note [
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
DTD实体是用于定义引用普通文本或特殊字符的快捷方式的变量,可以内部声明或外部引用
内部声明实体 <!DOCTYPE 实体名称 "实体的值">
引用外部实体 <!DOCTYPE 实体名称 SYSTEM "URL">
或者 <!DOCTYPE 实体名称 PUBLIC "public_ID" "URL">
内部声明实体
<?xml version="1.0"?>
<!DOCTYPE note[ <!ELEMENT note (name)> <!ENTITY hack3r "Hu3sky"> ]>
<note>
<name>&hack3r;</name>
</note>
外部声明实体
外部实体用来引用外部资源,有两个关键字SYSTEM和PUBLIC两个,表示实体来自本地计算机还是公共计算机,外部实体的利用会用到协议如下:
不同语言下支持的协议:
正因为外部实体支持的http、file等协议,那么就有可能通过引用外部实体进行远程文件读取。
危害
当允许引用外部实体时,通过构造恶意内容,可导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等危害。
读取任意文件
PHP中可以通过FILE协议、HTTP协议和FTP协议读取文件,还可利用PHP伪协议。
<?xml version="1.0"?>
<!DOCTYPE test[
<!ENTITY f SYSTEM "file:///etc/passwd">
]>
<hhh>&f;</hhh>
执行系统命令
这种情况很少发生,但在配置不当/开发内部应用情况下(PHP expect模块被加载到了易受攻击的系统或处理XML的内部应用程序上),攻击者能够通过XXE执行代码。
<?xml version="1.0"?>
<!DOCTYPE test[
<!ENTITY f SYSTEM "expect://id">
]>
<hhh>&f;</hhh>
漏洞防御
使用开发语言提供的禁用外部实体的方法
//php:
libxml_disable_entity_loader(true);
//java:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
//Python:
from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
过滤用户提交的XML数据
过滤关键词: <!DOCTYPE 和 <!ENTITY,或者 SYSTEM 和 PUBLIC
RCE远程代码执行
简介
RCE英文全称:remote command/code execute,分为 远程命令执行ping 和 远程代码执行eval。
RCE漏洞,可以让攻击者直接向后台服务器远程注入操作系统命令或者代码,从而控制后台系统。
Ping是Windows、Unix和Linux系统下的一个命令。ping也属于一个通信协议,是TCP/IP协议的一部分。利用“ping”命令可以检查网络是否连通,可以很好地帮助我们分析和判定网络故障。应用格式:ping空格IP地址,如:
ping 127.0.0.1
远程命令执行
出现原因:因为应用系统从设计上需要给用户提供指定的远程命令操作的接口。
比如常见的路由器、防火墙、入侵检测等设备的web管理界面上,一般会给用户提供一个ping操作的web界面,用户从web界面输入目标IP,提交后,后台会对该IP地址进行一次ping测试,并返回测试结果。而如果设计者在完成该功能时,没有做严格的安全控制,则可能会导致攻击者通过该接口提交“意想不到”的命令,从而控制整个后台服务器。
例如:如今很多甲方企业的自动化运维平台,大量的系统操作会通过“自动化运维”平台进行操作,其中往往会出现远程系统命令执行的漏洞。
远程代码执行
出现原因:因为需求设计,后台有时候会把用户的输入作为代码的一部分进行执行,也造成了远程代码执行漏洞,不管是使用了代码执行的函数,还是使用了不安全的反序列化等等。
防御
如果需要给前端用户提供操作类的API接口,一定需要对接口的输入的内容进行严格的判断,比如实施严格的白名单是一个好的方法。
反序列化漏洞
序列化:把对象转换为字节序列的过程称为对象的序列化。
反序列化:把字节序列恢复为对象的过程称为对象的反序列化。
在反序列化时,存在用户可控的参数,并且在读取反序列化内容时存在危险的调用函数,则存在反序列化漏洞。
为什么要序列化
在进行浏览器访问的时候,我们看到的文本、图片、音频、视频等都是通过二进制序列进行传输的,那么如果我们需要将代码对象进行传输的时候,是不是也应该先将对象进行序列化?答案是肯定的,我们需要先将代码对象进行序列化,然后通过网络,IO进行传输,当到达目的地之后,再进行反序列化获取到我们想要的对象,最后完成通信。
为什么没有序列化漏洞?
因为序列化是把对象转换为字节序列,这里的对象通常就是指我们自己编写的代码,那当然不会有问题;而反序列化是接收其他地方传过来的内容再转换成对象,其他地方的输入是不可信的。
检测方法
反序列化漏洞有非常多的利用工具,可自行去网上寻找使用。下图就给出了一种反序列化的利用工具:
漏洞修复
-
过滤反序列化的内容
-
只反序列化可信来源的数据
转载时请注明出处及相应链接。
本文永久链接: http://www.baigei.com/articles/ssrf-xxe-rce