目录
XXE(外部实体注入攻击)
web373
web374
web375
web376
web377
web378
知识点
XXE(外部实体注入攻击)
XXE这几关有个前提flag在根目录下文件名为flag
web373
loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);//加载 XML 文件并进行解析
$creds = simplexml_import_dom($dom);//换了一种方式
$ctfshow = $creds->ctfshow;//将xmlctfshow标签里面的内容赋值个ctfshow这个变量
echo $ctfshow;//输出这个值
}
highlight_file(__FILE__);
这一看源码和我刚学习XXE看的那篇源码一样
通过伪协议input获取post中的数据流然后
libxml_服务器托管网disable_entity_loader(false);启用 libxml 实体加载器功能,允许 XML 解析器加载外部实体
LIBXML_NOENT
表示禁止实体扩展xml自带实体比如< >不能使用以及内部实体(大概率是)
LIBXML_DTDLOAD
表示允许加载外部 DTD
多了不说既然有回显那就简单了
payload
]>
&tzy;
web374
loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
}
highlight_file(__FILE__);
这就没有回显了(blind xxe)可以使用外带数据通道提取数据
没有回显记住口诀xml获取dtddtd中放base64读取文件和带数据
既然没有回显那就把数据带出来吧
payload
%remote;%int;%send;
]>
vpstest.dtd
">
vps上nc -lvv进行监听
第一种方式
vpstest.dtd
">
常见index.php文件用于接受q参数
这道题才是正规的一点没有报错做的很爽
使用web-4观心wp的不正规方式试一下根本就不行因为数据包根本就没有返回报错信息那个wp的方式恰巧报错信息等信息能返回恰巧能输出flag设置error_reporting(0);就不会返回报错信息了
web375
<?php error_reporting(0);
libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');
if(preg_match('/loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
}
highlight_file(__FILE__);
过滤了xml的证明 (我记得学习基础的时候说必须要写但是做题的时候发现不需要写,就算必须写有两种方式绕过双引号变成单引号,在xml和version多加一个空格都是可以的)
和上面题同理
使用一个不同的方式吧(原理都是一个意思) 为什么要绕一圈呢,就是因为在请求的时候默认不允许将本地文件发送到dtd文件间接的影响了我们的请求所以要套一层
也就是说将dtd引过来之后首先解析第一层实体定义内容为另一个实体定义继续解析另一个实体定义从而达到了发送请求如果不这样套一层直接放入xml系统默认是不允许得,这也能解释为什么要用参数实体因为调用dtd是在内部dtd中调用的内部dtd只能使用参数实体的方式
我是将读本地文件和请求vps都放到dtd中xml只放引用dtd的
很多都是请求vps的放入dtd中xml中放读本地文件和引用dtd的
payload
%myurl;
]>
vpsdtd文件
">
%dtd;
%vps;
成功之前是监听的请求中的参数这次是监听请求的路径一个意思都能监听到
web376
<?php error_reporting(0);
libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');
if(preg_match('/loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
}
highlight_file(__FILE__);
比上一题多一个/i大小写没区别同理
web377
<?php error_reporting(0);
libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');
if(preg_match('/loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
}
highlight_file(__FILE__);
过滤了http看别人的wp说是使用utf-16编码就能绕过我就手动将payload(和上一题一样的)进行utf-16就是不行必须使用python发包发包前进行utf-16编码而且就算用python进行utf-16编码手动发送也不行必须也要让python发包才可以(我估计是啥如果进行特定编码方式然后发包估计还有增加请求头类似这种python发包可以自动补全)
能编码简单理解就是(我的理解)input获取到数据后先绕过正则然后在操作xml的时候这个对象就能识别出是xml因为xml支持utf-16这时哪怕在xml声明编码方式为utf-8这也无所谓 这声明的只是xml内容为utf-8但是整体过来是utf-16这个对象是能识别出来的然后看到这个声明为utf-8后再将内容设为utf-8的编码方式
其余同理
python代码为
import requests
url = 'http://fdccab41-0e0d-48fa-89af-21ce8bffa466服务器托管网.challenge.ctf.show/'
payload = '''
%myurl;
]>
'''
payload = payload.encode('utf-16')
rep = requests.post(url=url, data=payload)
web378
通过这个数据就知道这是xml数据服务器后端肯定会使用xml解析这个数据
源码中也能看出来
function doLogin(){
//不为空就行
var username = $("#username").val();
var password = $("#password").val();
if(username == "" || password == ""){
alert("Please enter the username and password!");
return;
}
//定义一下数据
var data = "" + username + "" + password + "";
使用异步发送请求
$.ajax({
type: "POST",
url: "doLogin",
contentType: "application/xml;charset=utf-8",//告诉服务器我的数据类型
data: data,
dataType: "xml",//接收的数据类型为
anysc: false,
success: function (result) {
从返回的 XML 数据中获取名为 "code" 的元素的值。
var code = result.getElementsByTagName("code")[0].childNodes[0].nodeValue;
var msg = result.getElementsByTagName("msg")[0].childNodes[0].nodeValue;
if(code == "0"){
$(".msg").text(msg + " login fail!");
//如果code为1显示登录成功
}else if(code == "1"){
$(".msg").text(msg + " login success!");
}else{
$(".msg").text("error:" + msg);
}
},
//在 AJAX 请求失败时执行 当发生错误时,会在页面上显示 errorThrown + ':' + textStatus,即显示异常信息和错误状态描述
error: function (XMLHttpRequest,textStatus,errorThrown) {
$(".msg").text(errorThrown + ':' + textStatus);
}
});
}
contentType: “application/xml;charset=utf-8”,//告诉服务器我的数据类型
X-Requested-With: XMLHttpRequest这是告诉服务器我是ajax进行异步通信数据可能是xml也可能是json(这俩大概率) 都有可能
发送的是xml数据回来的也是xml数据(其实回来的不用管)服务器肯定是解析xml
传入paylaod
我想使用这种方法但是不好使估计是在服务器设置了不允许进行使用外部DTD
%remote;%int;%send;
]>
">
好好观察一下源码发现$(“.msg”).text(msg + ” loginfail!”);
随便登录一下账户名admin密码123456显示adminloginfail这个msg就是用户名
这个msg是从服务器返回的xml数据中提取的那么服务器的msg肯定是从我们上传的xml中提取的
那么直接就能将&xxe输出也就是flag的内容我看大佬说这是特别标准的xxe估计这种很常见
]>
&xxe;
知识点
为什么是外部实体注入为什么要引入外部呢也是我之前迷茫的地方
举个例子比如
xml文件
%myurl;
]>
dtd文件
">
%dtd;
%vps;
直接写成不也行嘛
xml文件
">
%vps;
]>
这里注意参数实体引用%file;
必须放在外部文件里,因为根据这条规则。在内部DTD里,参数实体引用只能和元素同级而不能直接出现在元素声明内部 (必须是双层嵌套哦)
如果放在外部%myurl引用dtd文件 %dtd引用另一个实体引用 %vps再引用我们的请求这样是可以的虽然最终也是在内部dtd中但是两者就是不一样
还有一点就是在声明的内部中%要进行实体编码因为%这种不符合xml的符号必须要进行实体编码
也就是说%dtd不允许有和xml冲突的字符在值里面
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net