1
00:00:01,140 --> 00:00:02,530
The next type of attack we are going to

2
00:00:02,530 --> 00:00:05,180
talk about is an XML Bomb attack, which is

3
00:00:05,180 --> 00:00:07,240
sometimes referred to as the Billion

4
00:00:07,240 --> 00:00:09,700
Laughs attack.. This is a denial of

5
00:00:09,700 --> 00:00:11,420
service attack that has been around since

6
00:00:11,420 --> 00:00:14,090
2002, but still pops up in different

7
00:00:14,090 --> 00:00:16,330
variations every now and then. Most

8
00:00:16,330 --> 00:00:19,250
recently in 2019 is an attack on a YAML

9
00:00:19,250 --> 00:00:22,890
manifest of Kubernetes API servers. We're

10
00:00:22,890 --> 00:00:24,850
just going to cover the XML Bomb version

11
00:00:24,850 --> 00:00:26,680
of this attack, but by understanding the

12
00:00:26,680 --> 00:00:28,910
XML Bomb attack, you'll understand the

13
00:00:28,910 --> 00:00:30,970
principles this whole family of attacks is

14
00:00:30,970 --> 00:00:34,640
based on. So let's take a look. I'm here

15
00:00:34,640 --> 00:00:36,515
on the Wikipedia page for the Billion

16
00:00:36,515 --> 00:00:38,620
Laughs attack, and if I scroll down to

17
00:00:38,620 --> 00:00:40,810
this code example, this will give you a

18
00:00:40,810 --> 00:00:43,630
good idea of how the attack works. This

19
00:00:43,630 --> 00:00:46,230
attack makes use of the same document type

20
00:00:46,230 --> 00:00:48,970
definition, or DTD, capability in XML

21
00:00:48,970 --> 00:00:51,340
documents just like the XML External

22
00:00:51,340 --> 00:00:53,565
Entities attack we talked about earlier,

23
00:00:53,565 --> 00:00:56,280
but it takes on a different form. As you

24
00:00:56,280 --> 00:00:58,640
see, it defines these entities numbered 1

25
00:00:58,640 --> 00:01:01,220
through 9, but notice how each entity

26
00:01:01,220 --> 00:01:04,510
references the entity prior to it. This &

27
00:01:04,510 --> 00:01:07,490
sign syntax in a DTD means go to the other

28
00:01:07,490 --> 00:01:09,440
entity and import it here into this

29
00:01:09,440 --> 00:01:12,520
location. So what happens is you get this

30
00:01:12,520 --> 00:01:15,110
recursive type effect that builds up here

31
00:01:15,110 --> 00:01:16,820
where each of these entities is going to

32
00:01:16,820 --> 00:01:19,420
include 10 copies of the entity before it,

33
00:01:19,420 --> 00:01:20,730
which of course has 10 copies of the

34
00:01:20,730 --> 00:01:23,850
entity before it, and so on. When you get

35
00:01:23,850 --> 00:01:25,180
down here to the bottom, which is the

36
00:01:25,180 --> 00:01:27,410
actual document, you see this is a

37
00:01:27,410 --> 00:01:30,840
reference to the ninth entity, lol9, and

38
00:01:30,840 --> 00:01:32,710
what will happen is that that entity will

39
00:01:32,710 --> 00:01:35,080
get expanded out and you'll end up with 10

40
00:01:35,080 --> 00:01:37,870
to the 9th copies, or 1 billion copies of

41
00:01:37,870 --> 00:01:40,280
the string lol. And that is where this

42
00:01:40,280 --> 00:01:42,180
attack gets its other name, the Billion

43
00:01:42,180 --> 00:01:44,710
Laughs attack, because lol is shorthand

44
00:01:44,710 --> 00:01:47,430
for laughing out loud. So what happens

45
00:01:47,430 --> 00:01:49,330
when an application tries to parse an XML

46
00:01:49,330 --> 00:01:50,990
document like this is the parse is going

47
00:01:50,990 --> 00:01:52,870
to try to expand this string out and build

48
00:01:52,870 --> 00:01:55,190
this very long string, and that's going to

49
00:01:55,190 --> 00:01:57,890
consume a lot of memory. As it turns out,

50
00:01:57,890 --> 00:02:01,040
about 3 GB. When this attack first came

51
00:02:01,040 --> 00:02:03,470
out, consuming 3 GB of memory was more

52
00:02:03,470 --> 00:02:05,590
than sufficient to crash most 32 ‑bit

53
00:02:05,590 --> 00:02:08,730
processes at the time. Today, it would be

54
00:02:08,730 --> 00:02:10,890
easy to include just a few more lines in

55
00:02:10,890 --> 00:02:12,840
this attack and make this process use up

56
00:02:12,840 --> 00:02:15,320
even more memory, but even if the attack

57
00:02:15,320 --> 00:02:17,630
is executed just as it is, it is still

58
00:02:17,630 --> 00:02:19,170
going to consume a lot of memory on your

59
00:02:19,170 --> 00:02:21,240
server and really slow things down or

60
00:02:21,240 --> 00:02:24,440
potentially even crash your application.

61
00:02:24,440 --> 00:02:25,890
Let's take a look at how this works in

62
00:02:25,890 --> 00:02:27,970
code, and to do that I've written this

63
00:02:27,970 --> 00:02:29,820
simple console program that is going to

64
00:02:29,820 --> 00:02:33,350
read in and parse an XML file. Even though

65
00:02:33,350 --> 00:02:35,310
I'm parsing an XML file off of disk, the

66
00:02:35,310 --> 00:02:37,150
same principles would apply no matter

67
00:02:37,150 --> 00:02:40,330
where this XML came from. The code up here

68
00:02:40,330 --> 00:02:42,480
is what actually reads the file and uses

69
00:02:42,480 --> 00:02:45,400
the XmlReader to parse it into our XML

70
00:02:45,400 --> 00:02:47,440
document. And then down here at the

71
00:02:47,440 --> 00:02:49,290
bottom, I'm printing out some stats as

72
00:02:49,290 --> 00:02:52,380
well as the content of the XML. If I

73
00:02:52,380 --> 00:02:55,710
switch over to my XmlBomb.txt file, you'll

74
00:02:55,710 --> 00:02:57,900
see that same XML as before that we saw on

75
00:02:57,900 --> 00:03:00,950
the Wikipedia page. But for this demo, I'm

76
00:03:00,950 --> 00:03:02,400
going to come down here and change this

77
00:03:02,400 --> 00:03:05,810
lol9 in the body to lol3, so we're only

78
00:03:05,810 --> 00:03:08,000
going to get 10 to the 3rd, or 1000

79
00:03:08,000 --> 00:03:09,820
expansion to this string, but that's going

80
00:03:09,820 --> 00:03:12,580
to be enough to show us what's going on.

81
00:03:12,580 --> 00:03:13,670
So I'm going to save this, and I'm going

82
00:03:13,670 --> 00:03:17,780
to run it. And now you can see how those

83
00:03:17,780 --> 00:03:19,280
references in the document type

84
00:03:19,280 --> 00:03:22,430
definition, the XML document, works. Those

85
00:03:22,430 --> 00:03:24,410
three lines got expanded out, and as you

86
00:03:24,410 --> 00:03:26,560
can see, I have a string that fills up

87
00:03:26,560 --> 00:03:30,010
almost my entire console window. If I went

88
00:03:30,010 --> 00:03:31,780
back to my XML document and I changed the

89
00:03:31,780 --> 00:03:34,550
value here in the document to lol4, I

90
00:03:34,550 --> 00:03:37,020
would get 10 console windows full of data.

91
00:03:37,020 --> 00:03:39,610
If I changed it to lol5, that would be 100

92
00:03:39,610 --> 00:03:42,850
consoles worth of data, and so on. And so

93
00:03:42,850 --> 00:03:44,830
to that effect, let's live a little bit

94
00:03:44,830 --> 00:03:46,940
dangerously here, and I'm going to change

95
00:03:46,940 --> 00:03:50,500
this to lol7. And so now this time I

96
00:03:50,500 --> 00:03:52,920
should get a bunch more data. And I'm

97
00:03:52,920 --> 00:03:55,940
going to run this again. And now you can

98
00:03:55,940 --> 00:03:58,270
see my console window kind of go crazy

99
00:03:58,270 --> 00:04:00,120
here, and it's printing out this very,

100
00:04:00,120 --> 00:04:02,530
very long string of 10 to the 7th, or 10

101
00:04:02,530 --> 00:04:05,490
million copies of lol. So you can see the

102
00:04:05,490 --> 00:04:07,550
exponential type growth that's going on

103
00:04:07,550 --> 00:04:09,350
here, and you can really kind of see how

104
00:04:09,350 --> 00:04:11,050
this attack works. It's building this

105
00:04:11,050 --> 00:04:12,730
really, really long string, which is going

106
00:04:12,730 --> 00:04:14,930
to use a lot of memory. And that's the

107
00:04:14,930 --> 00:04:16,900
goal of this attack. By consuming a lot of

108
00:04:16,900 --> 00:04:19,140
memory, the attacker can either crash the

109
00:04:19,140 --> 00:04:21,200
application process or exhaust all the

110
00:04:21,200 --> 00:04:23,595
physical memory on a server, thereby

111
00:04:23,595 --> 00:04:26,640
causing a denial of service attack. Unlike

112
00:04:26,640 --> 00:04:28,420
a conventional denial of service attack

113
00:04:28,420 --> 00:04:29,770
where you can have many, many clients

114
00:04:29,770 --> 00:04:31,180
that's going to flood the application with

115
00:04:31,180 --> 00:04:33,580
requests, this attack can require just a

116
00:04:33,580 --> 00:04:36,380
handful of requests. So what do we do to

117
00:04:36,380 --> 00:04:38,420
prevent and protect our applications from

118
00:04:38,420 --> 00:04:41,460
this sort of behavior? Once again, just

119
00:04:41,460 --> 00:04:43,510
like the XML External Entities attack we

120
00:04:43,510 --> 00:04:46,000
just talked about, this attack relies upon

121
00:04:46,000 --> 00:04:48,360
the document type definition capability in

122
00:04:48,360 --> 00:04:51,290
the XML parsers. And as we talked about

123
00:04:51,290 --> 00:04:54,690
before in modern versions of .NET, the XML

124
00:04:54,690 --> 00:04:56,620
parsers are configured by default to

125
00:04:56,620 --> 00:04:58,960
prohibit the inclusion of document type

126
00:04:58,960 --> 00:05:02,540
definitions in your XML. If we go back and

127
00:05:02,540 --> 00:05:04,730
take a look at my unsafe program, you'll

128
00:05:04,730 --> 00:05:06,160
notice that I had to set this

129
00:05:06,160 --> 00:05:08,640
DtdProcessing property to Parse in order

130
00:05:08,640 --> 00:05:11,420
to demonstrate the attack. But by default,

131
00:05:11,420 --> 00:05:13,550
this is set to Prohibit, which protects

132
00:05:13,550 --> 00:05:16,330
you. So your first line of defense is to

133
00:05:16,330 --> 00:05:18,210
make sure that you're using a version of

134
00:05:18,210 --> 00:05:21,360
.NET later than 4.5.2 or any version of

135
00:05:21,360 --> 00:05:24,490
.NET Core. However, if you do need to

136
00:05:24,490 --> 00:05:26,630
include an XML document that includes a

137
00:05:26,630 --> 00:05:28,900
document type definition, you have two

138
00:05:28,900 --> 00:05:32,040
avenues to secure this process. First, we

139
00:05:32,040 --> 00:05:34,160
could set the DtdProcessing property to

140
00:05:34,160 --> 00:05:35,890
Ignore, and that would tell the parser

141
00:05:35,890 --> 00:05:40,040
simply to disregard the DTD protecting us.

142
00:05:40,040 --> 00:05:41,600
If we do have to parse and use the

143
00:05:41,600 --> 00:05:43,650
document type definition, then we have

144
00:05:43,650 --> 00:05:45,780
another property we could use to protect

145
00:05:45,780 --> 00:05:48,580
us. The MaxCharactersFromEntities property

146
00:05:48,580 --> 00:05:50,480
specifies the maximum value that can be

147
00:05:50,480 --> 00:05:52,730
expanded from entities, and by default

148
00:05:52,730 --> 00:05:55,610
this is set to 10 million. So anything

149
00:05:55,610 --> 00:05:58,030
that tries to expand past that limit, then

150
00:05:58,030 --> 00:05:59,990
an exception will be thrown and parsing

151
00:05:59,990 --> 00:06:01,560
the document will fail, but the

152
00:06:01,560 --> 00:06:04,700
application will be saved. As you can see,

153
00:06:04,700 --> 00:06:07,250
to make my application vulnerable, I had

154
00:06:07,250 --> 00:06:09,930
to manually set this property. If you do

155
00:06:09,930 --> 00:06:11,530
need a higher limit, this property is

156
00:06:11,530 --> 00:06:14,090
there for you, but the intent here is to

157
00:06:14,090 --> 00:06:16,550
limit how much data could be expanded and

158
00:06:16,550 --> 00:06:18,120
protect us from these exponential

159
00:06:18,120 --> 00:06:21,960
expansions in an XML Bomb type attack. So

160
00:06:21,960 --> 00:06:24,110
again, today most of us are secure by

161
00:06:24,110 --> 00:06:26,930
default due to how .NET is configured. But

162
00:06:26,930 --> 00:06:29,350
if you do need to support an XML file with

163
00:06:29,350 --> 00:06:31,610
document type definitions in it, there are

164
00:06:31,610 --> 00:06:37,000
secure ways to do so that you can protect yourself and your applications.

