1
00:00:00,000 --> 00:00:08,755
*preroll music*

2
00:00:10,084 --> 00:00:13,459
Herald: And I'm gonna introduce Netanel Rubin.

3
00:00:14,166 --> 00:00:18,640
He has been here last year with a talk 
that he got some bashing for.

4
00:00:19,314 --> 00:00:23,548
This year he's gonna ensure,
it's not the programmer's fault,

5
00:00:23,689 --> 00:00:27,426
it's the language itself. No?

6
00:00:27,507 --> 00:00:29,883
Well, here we go, well here we go.

7
00:00:29,949 --> 00:00:33,598
Netanel, he is working for 
PerimeterX in Tel Aviv,

8
00:00:33,631 --> 00:00:35,491
welcome on stage, your talk!

9
00:00:35,521 --> 00:00:37,634
Netanel: Thank you very much, *applause*

10
00:00:37,674 --> 00:00:41,134
thank you, thank you!

11
00:00:44,747 --> 00:00:52,755
Last year I stood right on this very stage
and I talked about several of Perl's

12
00:00:52,755 --> 00:00:56,411
less thought out "features".

13
00:00:56,411 --> 00:01:04,709
Now, I got some bashing from the Perl community, 
but mainly what happened was,

14
00:01:04,709 --> 00:01:10,291
that the Perl community completely rejected my talk 
claiming that the language

15
00:01:10,291 --> 00:01:16,357
is completely fine and great 
and all of this stuff are just improvements.

16
00:01:17,573 --> 00:01:20,724
It was clear I had to give another talk.

17
00:01:21,421 --> 00:01:29,049
This is why I'm very proud to present 
"Perl Jam 2 – The Camel strikes back"!

18
00:01:29,049 --> 00:01:33,618
*applause*

19
00:01:33,618 --> 00:01:36,188
Thank you

20
00:01:38,065 --> 00:01:45,873
At the last talk, I showed that "lists" are expressions, 
used in… many confusing ways.

21
00:01:45,873 --> 00:01:52,921
I also showed how CGI parameters can create lists, 
directly from user input.

22
00:01:52,921 --> 00:02:00,165
But most importantly, I showed 
that when these two things combine, shit happens.

23
00:02:01,696 --> 00:02:04,066
Great

24
00:02:04,080 --> 00:02:08,949
But the really interesting part 
was the PerlMonks response.

25
00:02:08,949 --> 00:02:16,203
The Perl community…
*laughter*

26
00:02:19,274 --> 00:02:24,451
The Perl community had a long discussion 
at the PerlMonks forum

27
00:02:24,451 --> 00:02:29,475
that started with the words 
"Sad news from Germany".

28
00:02:29,475 --> 00:02:32,231
A bit dramatic, but who am I to judge?

29
00:02:32,231 --> 00:02:38,931
So, after a long, long discussion, 
they came to the unavoidable conclusion

30
00:02:38,931 --> 00:02:47,997
that my talk was, in fact, a "polemic shit", 
and they should all just "piss on it". Wink.

31
00:02:49,717 --> 00:02:55,756
They also realized I'm just a 
"script kiddie preaching to other script kiddies",

32
00:02:55,756 --> 00:03:01,162
and not just any script kiddies, the CCC audience is a

33
00:03:01,162 --> 00:03:06,435
"heterogeneous group of chaotic punks 
who love to see themselves in the hacker

34
00:03:06,435 --> 00:03:18,091
image of Hollywood media". 
*applause and whistling from audience*

35
00:03:18,091 --> 00:03:24,075
What hacker image? 
What are they talking about?

36
00:03:24,075 --> 00:03:26,218
We have no hacker image.

37
00:03:26,310 --> 00:03:34,281
Anyway, it got quite surreal, as in some point 
they even critized

38
00:03:34,281 --> 00:03:41,994
the "crude use of propaganda 
in the camel images". WAT?

39
00:03:42,461 --> 00:03:46,015
*laughing*
*applause*

40
00:03:46,015 --> 00:03:50,737
Propaganda in the camel images. Alright.

41
00:03:50,737 --> 00:03:58,348
Anyway, they completely rejected the entire talk, 
even though the technical points were valid.

42
00:03:58,348 --> 00:04:03,603
They rejected it because of 
some jokes and camel images.

43
00:04:03,603 --> 00:04:12,814
But still, they got so offended they just threw 
lame excuses as to why their language sucks.

44
00:04:12,814 --> 00:04:19,622
Two of these lame excuses were 
repeated over and over again.

45
00:04:19,622 --> 00:04:24,733
The first was that I should 
read the fucking manual, which is funny

46
00:04:24,733 --> 00:04:27,413
because I thought I was the only one who did…

47
00:04:27,413 --> 00:04:29,184
*laughter*

48
00:04:29,184 --> 00:04:30,753
…and the second is that

49
00:04:30,753 --> 00:04:35,378
I'm using the old, ancient Perl, 
and not the new, modern Perl.

50
00:04:35,378 --> 00:04:39,920
*more laughter*

51
00:04:40,811 --> 00:04:46,317
Remember these two points carefully 
as I'll later break them in the presentation.

52
00:04:46,317 --> 00:04:52,167
But, enough with the intro, 
let's start with the new madness.

53
00:04:52,167 --> 00:04:58,788
So, Perl allows declaring variables 
without specifying their data type.

54
00:04:58,788 --> 00:05:03,131
Of course, this functionality exists 
in many dynamic languages,

55
00:05:03,131 --> 00:05:06,884
and is completely fine and very convenient.

56
00:05:06,884 --> 00:05:12,773
But, as usual, Perl took it 
to a whole different level.

57
00:05:12,773 --> 00:05:19,200
Perl went as far as removing 
data type declarations from function arguments.

58
00:05:19,200 --> 00:05:20,854
You can see that in this example,

59
00:05:20,854 --> 00:05:27,760
I'm just receiving two different arguments 
without knowing what type they are.

60
00:05:27,760 --> 00:05:29,760
Let me be clear about that,

61
00:05:29,760 --> 00:05:34,536
you don't get to choose whether you want 
to specify argument data types or not,

62
00:05:34,536 --> 00:05:41,053
you can't specify 
what data types you're expecting to get.

63
00:05:41,053 --> 00:05:44,764
So even if I built a function 
that only works with strings,

64
00:05:44,764 --> 00:05:49,332
I have no way of forcing that 
at the function declaration.

65
00:05:49,332 --> 00:05:51,318
Now that's annoying.

66
00:05:51,318 --> 00:05:57,394
But, the real kicker 
is how this feature is used.

67
00:05:57,444 --> 00:06:03,828
Apparently, it is very common to write 
two completely different blocks of code,

68
00:06:03,828 --> 00:06:07,675
one that handles scalar types, 
like strings or ints,

69
00:06:07,675 --> 00:06:13,217
and one that handles non-scalar types, 
like arrays or hashes.

70
00:06:13,217 --> 00:06:15,338
Let me repeat that:

71
00:06:15,338 --> 00:06:23,796
Writing multiple code, for multiple data-types, 
in one function, is a Perl standard.

72
00:06:23,796 --> 00:06:31,782
And that's sad. You shouldn't write redundant code 
because the language lacks the capability

73
00:06:31,782 --> 00:06:35,971
of letting you decide 
which cases you don't want to handle.

74
00:06:35,971 --> 00:06:40,493
By the way, Python doesn't let you 
declare your function argument data types too,

75
00:06:40,493 --> 00:06:45,723
but unlike Perl, writing redundant code 
to cover that up

76
00:06:45,723 --> 00:06:49,726
is definitely not the standard.

77
00:06:49,726 --> 00:06:54,723
Anyway, sad as this may be, 
this Perl convention is not dangerous.

78
00:06:54,723 --> 00:06:56,894
The dangerous part begins

79
00:06:56,894 --> 00:07:02,956
when hashes and arrays 
are considered as "secure" data types,

80
00:07:02,956 --> 00:07:07,738
mainly because they can't be created 
by user input.

81
00:07:07,738 --> 00:07:10,374
This results in this kind of code,

82
00:07:10,374 --> 00:07:14,187
where if the function argument 
is a hash, for example,

83
00:07:14,187 --> 00:07:18,708
it is used un-escaped in dangerous functions.

84
00:07:18,708 --> 00:07:25,661
Hashes, specifically, are considered so secure, 
that even if you use "taint mode",

85
00:07:25,661 --> 00:07:28,293
which is some kind of safe mode for Perl,

86
00:07:28,293 --> 00:07:33,532
hash keys are not tainted, meaning 
that, even if you use safe mode,

87
00:07:33,532 --> 00:07:36,719
they can be still used in dangerous functions

88
00:07:36,719 --> 00:07:41,639
without any validation, 
as opposed to other data types.

89
00:07:41,639 --> 00:07:46,619
Now this kind of code appears a lot 
in Perl applications,

90
00:07:46,619 --> 00:07:49,759
and apart from the many bugs 
this method can cause,

91
00:07:49,759 --> 00:07:54,395
it also makes your code exploitable.

92
00:07:54,395 --> 00:07:58,369
So we know function arguments are of unknown data type.

93
00:07:58,369 --> 00:08:03,073
And we know developers treat hashes and arrays 
as "secure" data types,

94
00:08:03,073 --> 00:08:06,603
inserting their values into dangerous functions.

95
00:08:06,603 --> 00:08:09,140
But this practices isn't something

96
00:08:09,140 --> 00:08:14,056
that was created a long time ago, 
and found only on redundant code.

97
00:08:14,056 --> 00:08:20,341
Because of how the language is built, 
its supposedly restriction-less type of developing,

98
00:08:20,341 --> 00:08:26,688
even now it is the natural way to code 
when you're using Perl.

99
00:08:26,688 --> 00:08:31,185
And that's the real problem: 
Perl is like a shotgun,

100
00:08:31,185 --> 00:08:36,552
with one trigger you know about 
and a dozen that you don't.

101
00:08:36,552 --> 00:08:40,821
So for now, we know 
that if we'll somehow manage

102
00:08:40,821 --> 00:08:46,051
to create these "secure" data types, 
with our user input,

103
00:08:46,051 --> 00:08:49,010
we could exploit the code.

104
00:08:49,010 --> 00:08:53,997
So the only question remaining really 
is what are we gonna exploit?

105
00:08:53,997 --> 00:08:58,185
And the answer, again, 
is Bugzilla.

106
00:08:58,185 --> 00:09:02,768
*laughter*

107
00:09:03,178 --> 00:09:08,713
Like every other Perl project, 
Bugzilla is heavily using functions

108
00:09:08,713 --> 00:09:13,277
that treat scalar and non-scalar 
argument types very differently.

109
00:09:13,277 --> 00:09:17,404
This is one of them: the load_from_DB function is responsible

110
00:09:17,404 --> 00:09:21,541
for extracting object specific data 
out of the database.

111
00:09:21,541 --> 00:09:28,945
Like I just said, it treats scalars, 
and in this case hashes, very differently.

112
00:09:28,945 --> 00:09:34,146
If the function argument is a hash, 
it takes one of its values

113
00:09:34,146 --> 00:09:39,845
and inserts it as is, un-escaped, 
into an SQL statement.

114
00:09:39,845 --> 00:09:44,598
Again, because hashes 
are considered secure,

115
00:09:44,598 --> 00:09:47,807
so there's no point of escaping them.

116
00:09:47,807 --> 00:09:50,919
On the other hand, 
if the argument is a scalar,

117
00:09:50,919 --> 00:09:55,798
it converts it into an integer 
and only then use it in an SQL statement.

118
00:09:55,798 --> 00:09:59,020
Because scalar values are not secure.

119
00:09:59,020 --> 00:10:00,680
hashes: secure

120
00:10:00,680 --> 00:10:03,064
scalar: not secure

121
00:10:03,064 --> 00:10:06,241
This means that if we could control 
the function argument entirely,

122
00:10:06,241 --> 00:10:10,964
including its data type, 
we could control the SQL query,

123
00:10:10,964 --> 00:10:14,405
effectively exploiting an SQL injection attack,

124
00:10:14,405 --> 00:10:17,720
by inserting a hash 
containing that specific value.

125
00:10:17,720 --> 00:10:21,234
But…

126
00:10:21,234 --> 00:10:26,862
CGI input doesn't allow hashes, right?

127
00:10:26,862 --> 00:10:32,339
The whole Perl security module 
is built on that assumption.

128
00:10:32,339 --> 00:10:37,314
The problem is that, like us, 
developers are assuming

129
00:10:37,314 --> 00:10:42,487
CGI input is the only input method available.

130
00:10:42,487 --> 00:10:45,581
CGI.

131
00:10:45,581 --> 00:10:48,545
But CGI isn't the only way to go.

132
00:10:48,545 --> 00:10:52,978
Bugzilla developers missed the fact 
that their own system

133
00:10:52,978 --> 00:10:57,723
is also featuring an XMLRPC and a JSONRPC,

134
00:10:57,723 --> 00:11:05,048
both supporting input of non-scalar data types 
like arrays and hashes!

135
00:11:05,048 --> 00:11:06,498
But I'm not blaming them.

136
00:11:06,498 --> 00:11:12,492
Yes, they forgot that there are more ways 
for a user to input than CGI,

137
00:11:12,492 --> 00:11:16,697
but still, they're just the product 
of how Perl programming is taught,

138
00:11:16,697 --> 00:11:20,679
filled with false assumptions and inconsistencies.

139
00:11:20,679 --> 00:11:25,983
Expecting anything but this kind 
of security problems is just naive.

140
00:11:25,983 --> 00:11:28,547
But back to the vulnerability.

141
00:11:28,547 --> 00:11:30,429
If we'll use one of these RPCs,

142
00:11:30,429 --> 00:11:34,136
sending our input parameter with a malicious hash,

143
00:11:34,136 --> 00:11:37,204
instead of just a regular numeric parameter,

144
00:11:37,204 --> 00:11:39,991
we will be able to exploit the SQL injection!

145
00:11:39,991 --> 00:11:44,428
So, if we'll send this regular request, 
using the JSONRPC interface,

146
00:11:44,428 --> 00:11:48,611
the number 1 will be used 
as the ID of a bug to extract,

147
00:11:48,611 --> 00:11:51,272
but if we'll send this request,

148
00:11:51,272 --> 00:11:53,993
where instead of an integer we'll supply a hash,

149
00:11:53,993 --> 00:11:57,365
then suddenly we will be able 
to inject any SQL we'd like

150
00:11:57,365 --> 00:12:03,016
into that statement, effectively 
compromising the entire database.

151
00:12:03,121 --> 00:12:07,048
Now when you look at this request, you realize

152
00:12:07,048 --> 00:12:11,396
that this is not a sophisticated vulnerability.

153
00:12:11,396 --> 00:12:20,859
All I did was just change the input data type 
from scalar in this case to a hash,

154
00:12:20,859 --> 00:12:24,980
and that's it, the system is compromised.

155
00:12:24,980 --> 00:12:29,072
It was so heavily built on the assumption

156
00:12:29,072 --> 00:12:32,223
that hashes are secure, that it offered me

157
00:12:32,223 --> 00:12:36,676
almost unlimited access security wise.

158
00:12:36,676 --> 00:12:41,659
The funny thing about that is, that 
although it's so simple,

159
00:12:41,659 --> 00:12:45,970
the attack has existed for over 5 years.

160
00:12:45,970 --> 00:12:48,912
That's the year I was born in.

161
00:12:48,912 --> 00:12:55,087
So, we now proved this "unknown-argument-type" feature

162
00:12:55,087 --> 00:12:58,232
is a huge source for problems.

163
00:12:58,232 --> 00:13:02,901
We also know writing different code 
to handle different data types

164
00:13:02,901 --> 00:13:06,953
just causes a lot of false assumptions.

165
00:13:06,953 --> 00:13:13,534
But most importantly, treating non-scalar 
data types such as hashes as "secure",

166
00:13:13,534 --> 00:13:17,354
just because they supposedly can't be created by the user,

167
00:13:17,354 --> 00:13:22,955
is very, very, BAD. Just ask Bugzilla.

168
00:13:22,955 --> 00:13:30,145
But the shocking part really, is that, again, 
this is the Perl Standard!

169
00:13:30,145 --> 00:13:33,892
You're not expected to use it, you have to

170
00:13:33,892 --> 00:13:36,645
as you don't have any other choice.

171
00:13:36,645 --> 00:13:43,829
This security mess 
is a fundamental part of the language.

172
00:13:43,829 --> 00:13:51,777
The problem is that creating non-scalar data types 
is impossible in some cases.

173
00:13:51,777 --> 00:13:54,914
We can't rely that some kind of RPC

174
00:13:54,914 --> 00:13:58,859
will exist in the code 
and support different data types,

175
00:13:58,859 --> 00:14:05,031
and we can't create data types 
using regular user input… Right?

176
00:14:05,031 --> 00:14:06,937
Well, let's have a look at

177
00:14:06,937 --> 00:14:10,526
how different CGI modules 
handle different kind of input.

178
00:14:10,526 --> 00:14:13,917
First, we'll take the most trivial scenario.

179
00:14:13,917 --> 00:14:17,807
A single valued parameter, 
something that looks like this request,

180
00:14:17,807 --> 00:14:22,210
where the "foo" parameter 
is assigned the string "bar".

181
00:14:22,210 --> 00:14:26,819
In this case, a scalar is created on all three CGI modules,

182
00:14:26,819 --> 00:14:31,198
which doesn't really help us, 
but is pretty much what we've expected.

183
00:14:31,198 --> 00:14:32,914
It is secure.

184
00:14:32,914 --> 00:14:37,846
But what happens if instead of 
sending a single-valued parameter,

185
00:14:37,846 --> 00:14:42,377
we'll send a multi-valued parameter, 
like in this request?

186
00:14:42,377 --> 00:14:46,032
Now things are starting to get complicated.

187
00:14:46,032 --> 00:14:50,551
On CGI.PM, as we already know, 
a list is created,

188
00:14:50,551 --> 00:14:55,013
which is very useful for us, 
but not what we're after.

189
00:14:55,013 --> 00:15:01,847
Let's have a look at 
what the "new" Perl modules are creating.

190
00:15:01,847 --> 00:15:09,987
We'll see that both of them are returning 
arrays containing our values.

191
00:15:09,987 --> 00:15:14,549
Arrays! WAT?

192
00:15:14,549 --> 00:15:19,278
I thought you can't create 
these kind of data types with regular input,

193
00:15:19,278 --> 00:15:22,442
after all, they're considered safe.

194
00:15:22,442 --> 00:15:24,236
But let's continue.

195
00:15:24,236 --> 00:15:27,637
What happens if instead of sending a regular value,

196
00:15:27,637 --> 00:15:31,883
we'll try and upload a file in that parameter?

197
00:15:31,883 --> 00:15:35,229
Now things are really getting out of hand,

198
00:15:35,229 --> 00:15:44,409
because CGI.PM now returns a file descriptor, 
and Catalyst and Mojolicious returns a hash.

199
00:15:44,409 --> 00:15:46,384
WAT?

200
00:15:46,384 --> 00:15:54,012
We just exploited 
the most popular Perl project in the world

201
00:15:54,012 --> 00:15:58,226
because they assumed hashes can't be created by the user,

202
00:15:58,226 --> 00:16:02,984
and now we're finding out 
that not only we can create hashes,

203
00:16:02,984 --> 00:16:05,477
it is a god-damned feature?!

204
00:16:05,477 --> 00:16:07,161
That's insane!

205
00:16:07,161 --> 00:16:11,504
The whole Perl security standard is built on that assumption

206
00:16:11,504 --> 00:16:14,954
that users can't create non-scalar data-types

207
00:16:14,954 --> 00:16:19,867
and now suddenly these are features?

208
00:16:19,867 --> 00:16:27,693
But let's send a multi-file upload request 
as in several files in the same parameter.

209
00:16:27,693 --> 00:16:34,183
Watch closely, because this is where it gets ridiculous.

210
00:16:34,183 --> 00:16:39,426
Now, CGI.PM returns a list of File Descriptors,

211
00:16:39,426 --> 00:16:42,551
Catalyst returns a list of Hashes

212
00:16:42,551 --> 00:16:49,282
and Mojolicious returns an Array of Objects! WAT?!

213
00:16:49,282 --> 00:16:53,340
*laughter and applause*

214
00:16:53,444 --> 00:16:58,105
Almost any Perl project in the world

215
00:16:58,105 --> 00:17:03,470
uses one of these modules 
for parsing CGI input.

216
00:17:03,470 --> 00:17:10,522
Just think how many developers assumed 
the exact same thing Bugzilla assumed

217
00:17:10,522 --> 00:17:15,854
and treated hashes and arrays as secure data types.

218
00:17:15,854 --> 00:17:17,752
So if you're using CGI.PM,

219
00:17:18,380 --> 00:17:21,268
instead of the expected scalar value you could be getting

220
00:17:21,268 --> 00:17:25,724
a list, a file descriptor or a list of file descriptors

221
00:17:25,724 --> 00:17:27,644
and if you're using Catalyst

222
00:17:27,644 --> 00:17:30,895
you could receive a scalar, an array, a hash or a list,

223
00:17:30,895 --> 00:17:35,375
which is basically any data type.

224
00:17:36,320 --> 00:17:39,425
So expecting your function… yeah

225
00:17:40,089 --> 00:17:44,091
*audience chuckling*

226
00:17:45,943 --> 00:17:53,997
So expecting your function arguments 
to be of a specific data type is false.

227
00:17:53,997 --> 00:18:00,119
Expecting hashes and arrays to be secure is also false.

228
00:18:00,119 --> 00:18:02,972
Expecting scalar only user input

229
00:18:02,972 --> 00:18:06,833
is a major false.

230
00:18:06,833 --> 00:18:13,156
And to be honest, it seems that in Perl expecting is false!

231
00:18:13,156 --> 00:18:17,337
*laughter and applause*

232
00:18:21,422 --> 00:18:25,923
You just can't expect anything

233
00:18:25,923 --> 00:18:32,455
even the most basic of things 
such as what data type your variable is made of.

234
00:18:32,455 --> 00:18:35,761
You just don't know.

235
00:18:37,870 --> 00:18:42,934
But I felt all of these points will 
go un-noticed

236
00:18:42,934 --> 00:18:48,632
without an extreme example of Perl's absurdity.

237
00:18:48,632 --> 00:18:52,599
So I found an extreme example.

238
00:18:52,599 --> 00:18:55,249
One that will clearly show

239
00:18:55,249 --> 00:18:59,204
the ridiculous nature of the language.

240
00:18:59,204 --> 00:19:00,898
And this is it:

241
00:19:00,898 --> 00:19:06,829
All this code does is print an uploaded file's content.

242
00:19:06,829 --> 00:19:14,517
And to show you how basic and simple that code is, 
I'll explain each line.

243
00:19:14,517 --> 00:19:20,363
The first line just creates a new CGI instance, 
so we could get the file from the user.

244
00:19:20,363 --> 00:19:26,785
The second line checks if a file 
has been uploaded in the "file" parameter.

245
00:19:26,785 --> 00:19:31,549
The third line gets the file descriptor from the CGI module,

246
00:19:31,549 --> 00:19:37,438
while the fourth line loops through the file 
and the fifth prints it.

247
00:19:37,438 --> 00:19:44,459
That's it. Again: all this code does 
is get a file and print it.

248
00:19:44,459 --> 00:19:45,521
*clapping*
That's it.

249
00:19:45,521 --> 00:19:52,126
A user has uploaded a file to the server 
and the server is just returning its content.

250
00:19:52,126 --> 00:19:55,683
It's not saving it anywhere, 
it's not moving it anywhere,

251
00:19:55,683 --> 00:19:58,771
it just prints its content.

252
00:19:58,771 --> 00:20:03,519
There should be absolutely 
nothing dangerous in this code,

253
00:20:03,519 --> 00:20:07,087
it contains literally five lines.

254
00:20:07,087 --> 00:20:09,830
Yet, it's demo time.

255
00:20:09,830 --> 00:20:12,332
*laughter*

256
00:20:12,412 --> 00:20:15,020
So trust me, you don't need to see the text,

257
00:20:15,020 --> 00:20:19,820
all you need to see is that 
when I'm sending a regular request nothing happens.

258
00:20:19,820 --> 00:20:23,585
When I send it now, nothing happens,
I'm just getting the file content.

259
00:20:23,585 --> 00:20:26,240
We're having fun, you don't see the burp…

260
00:20:26,240 --> 00:20:30,425
Now, nice. Okay.

261
00:20:30,425 --> 00:20:34,184
So…
…L't me just…

262
00:20:34,685 --> 00:20:37,182
…I have no idea where my mouse is, okay.

263
00:20:37,388 --> 00:20:38,323
So…

264
00:20:39,181 --> 00:20:42,230
I'm sending a regular request, 
nothing happens, just getting the content.

265
00:20:42,230 --> 00:20:46,073
I know, you can't see the text…
…and…

266
00:20:46,073 --> 00:20:49,519
when I'm sending my malicious request,

267
00:20:49,519 --> 00:20:51,901
something interesting will pop up.

268
00:20:51,901 --> 00:20:54,990
Watch closely! It's gonna be quick.

269
00:20:55,092 --> 00:20:56,684
Ready?

270
00:20:58,270 --> 00:21:00,520
Oh, you haven't seen it, it's on the different screen.

271
00:21:00,520 --> 00:21:06,641
Just a second… oh… duplicate…

272
00:21:07,809 --> 00:21:09,236
(from audience): … magnify it!

273
00:21:09,236 --> 00:21:11,781
Netanel: I'll magnify you!

274
00:21:11,781 --> 00:21:14,247
*laughter*

275
00:21:14,421 --> 00:21:18,136
Alright, so… watch closely.

276
00:21:18,894 --> 00:21:22,772
Ohh, uuh? What was that?

277
00:21:24,467 --> 00:21:26,559
Let's see it again.

278
00:21:26,559 --> 00:21:29,528
*mocking* Uuuuuh?!

279
00:21:30,340 --> 00:21:36,495
*laughter and applause*

280
00:21:36,893 --> 00:21:40,442
Yupp, *clearing throat*

281
00:21:40,752 --> 00:21:44,650
… just a second.

282
00:21:44,800 --> 00:21:46,084
Nice.

283
00:21:46,084 --> 00:21:49,277
So you're probably asking yourself right now

284
00:21:49,277 --> 00:21:52,411
"What the fuck did I just see?"
*laughter*

285
00:21:52,411 --> 00:21:55,814
"Was that a terminal screen?"

286
00:21:55,814 --> 00:22:00,237
And the answer is … "Yes"
Yes, it was,

287
00:22:00,237 --> 00:22:04,468
specifically the "ipconfig" command output.

288
00:22:04,468 --> 00:22:07,414
Or in other words: What you just saw

289
00:22:07,414 --> 00:22:15,370
was me exploiting that five lines 
with a remote code execution attack.

290
00:22:15,370 --> 00:22:20,513
So now that you saw the magic happens, 
I think it's time for some explanations.

291
00:22:20,513 --> 00:22:22,487
The first line, responsible for checking

292
00:22:22,487 --> 00:22:26,221
if a file has been uploaded in the "file" parameter,

293
00:22:26,221 --> 00:22:29,956
doesn't exactly do as it says.

294
00:22:29,956 --> 00:22:33,803
Instead of checking if the "file" 
parameter is an uploaded file,

295
00:22:33,803 --> 00:22:39,230
it checks if one of its values is a file descriptor.

296
00:22:39,230 --> 00:22:45,110
Let me clarify that, instead of checking 
if the parameter is only a file,

297
00:22:45,110 --> 00:22:48,981
it checks if the parameter is also a file.

298
00:22:48,981 --> 00:22:50,476
*laughter*

299
00:22:50,476 --> 00:22:52,842
Meaning that uploading a file

300
00:22:52,842 --> 00:22:57,023
and assigning another scalar value to the same parameter

301
00:22:57,023 --> 00:23:00,147
will still work and bypass the check!

302
00:23:00,147 --> 00:23:01,460
WAT?

303
00:23:01,460 --> 00:23:06,435
*more laughter and applause*

304
00:23:12,066 --> 00:23:15,715
Creative fellows those guys are.

305
00:23:15,715 --> 00:23:22,137
So now we can assign the "file" parameter 
both a regular file and a scalar value.

306
00:23:22,137 --> 00:23:26,224
But what happens when we try to get 
the "file" parameter value?

307
00:23:26,224 --> 00:23:31,183
In a regular request, it should return 
the uploaded file descriptor,

308
00:23:31,183 --> 00:23:35,821
but now that we're adding another value to that parameter,

309
00:23:35,821 --> 00:23:40,596
param() returns a list containing all the values we sent:

310
00:23:40,596 --> 00:23:44,365
the file we've uploaded and our scalar value.

311
00:23:44,365 --> 00:23:49,191
But the "file" variable 
can't contain two values, right?

312
00:23:49,191 --> 00:23:55,221
So instead of converting 
the returned list into an array

313
00:23:55,221 --> 00:23:59,331
Perl only uses the first element of that list.

314
00:23:59,331 --> 00:24:05,564
So if we'll send our scalar value 
before we send our file,

315
00:24:05,564 --> 00:24:09,989
the $file variable will be assigned 
our scalar value

316
00:24:09,989 --> 00:24:14,308
instead of the uploaded file descriptor.

317
00:24:14,308 --> 00:24:19,623
Which means, that $file 
is now a regular string!

318
00:24:19,623 --> 00:24:22,114
*in high pitched voice:* WAT?

319
00:24:23,178 --> 00:24:26,127
But what happens to this operator 
when we use a string

320
00:24:26,127 --> 00:24:28,565
instead of a file descriptor?

321
00:24:28,565 --> 00:24:32,962
Well, the brackets operator 
doesn't work with strings, right?

322
00:24:32,962 --> 00:24:36,548
It works with file descriptors, 
why should it work with strings?

323
00:24:36,548 --> 00:24:39,200
Well, that appears true

324
00:24:39,200 --> 00:24:42,817
unless that string is "ARGV".

325
00:24:42,817 --> 00:24:47,644
*laughter and applause*

326
00:24:55,470 --> 00:24:57,627
That's not a crazy part.

327
00:24:57,627 --> 00:24:59,763
*more laughter*

328
00:24:59,763 --> 00:25:04,693
In that case the brackets operator, listen closely,

329
00:25:04,693 --> 00:25:07,668
loops through the script arguments,

330
00:25:07,668 --> 00:25:12,487
which in CGI comes directly from the 
query string instead the command line,

331
00:25:12,487 --> 00:25:18,844
and it treats them as file paths, 
inserting each one into an open() call!

332
00:25:18,844 --> 00:25:19,977
*again laughter*

333
00:25:19,977 --> 00:25:22,655
WAT?

334
00:25:25,632 --> 00:25:29,485
Yeah, that made sense in some point, I guess.

335
00:25:29,485 --> 00:25:32,487
All of this basically means that now,

336
00:25:32,487 --> 00:25:35,874
instead of displaying 
our own uploaded file content,

337
00:25:35,874 --> 00:25:39,749
we can display the content 
of any file on the server.

338
00:25:39,749 --> 00:25:43,334
But that's not the end, 
as we haven't executed code yet.

339
00:25:44,214 --> 00:25:48,808
To execute code, we have 
to look at the open() function.

340
00:25:48,808 --> 00:25:56,676
Again, this is the function being called 
with the ARGV values as file paths.

341
00:25:56,676 --> 00:26:03,054
open() is responsible for opening 
a file descriptor to a given file.

342
00:26:03,054 --> 00:26:05,874
Unless a "pipe" character is added

343
00:26:05,874 --> 00:26:09,036
to the end of the string,
*laughter*

344
00:26:09,036 --> 00:26:13,259
and in that case instead of opening the file,

345
00:26:13,259 --> 00:26:16,228
it executes it…
*applause rising*

346
00:26:16,228 --> 00:26:22,146
…acting as an exec() call!
*more applause*

347
00:26:22,576 --> 00:26:28,512
So … when we send our exploit,

348
00:26:28,512 --> 00:26:34,631
containing our uploaded file, 
the "ARGV" malicious scalar value,

349
00:26:34,631 --> 00:26:37,635
and the ipconfig command followed by a pipe

350
00:26:37,635 --> 00:26:42,487
this is what we get.
WAT?

351
00:26:42,487 --> 00:26:46,639
WAT?
*applause*

352
00:26:49,165 --> 00:26:56,365
I know, I'm shocked too, but I'm not done yet. 
*laughter*

353
00:26:56,365 --> 00:27:00,723
Truth be told, I didn't write that code.

354
00:27:00,723 --> 00:27:06,159
Remember that PerlMonks told me 
that I should read their fucking manual?

355
00:27:06,159 --> 00:27:10,660
*more laughter*
Guess where that code came from:

356
00:27:10,660 --> 00:27:22,979
the official CGI documentation!
*big applause and audience whistling*

357
00:27:32,545 --> 00:27:36,347
But, I'm not blaming CGI.PM developers.

358
00:27:36,347 --> 00:27:41,365
Nor am I blaming developers 
who copied from CGI.PM examples.

359
00:27:41,365 --> 00:27:46,913
After all, who could have known 
that this is what this code will do?

360
00:27:46,913 --> 00:27:49,237
This is how it could be exploited?

361
00:27:49,237 --> 00:27:54,311
There's no exec calls, 
the file is not saved anywhere,

362
00:27:54,311 --> 00:27:58,163
and we're only using a "print".

363
00:27:58,163 --> 00:28:07,333
The sole responsible for this mess, 
is the Perl language.

364
00:28:07,333 --> 00:28:11,412
Perl is the one silently expanding lists,

365
00:28:11,412 --> 00:28:14,552
Perl is the one mixing up your data types,

366
00:28:14,552 --> 00:28:19,884
Perl is the one executing user input 
with no exec calls,

367
00:28:19,884 --> 00:28:22,800
Perl is the problem,

368
00:28:22,800 --> 00:28:25,502
not its developers.
*applause rising*

369
00:28:25,502 --> 00:28:31,879
And until this god-damned, bizarre, 
dangerous language is fixed,

370
00:28:31,879 --> 00:28:34,216
you could only 
stop

371
00:28:34,216 --> 00:28:35,319
using

372
00:28:35,319 --> 00:28:40,207
Perl!

373
00:28:40,207 --> 00:28:47,005
Thank you!
*more applause*

374
00:28:59,025 --> 00:29:02,754
Herald: So I guess 
we have some time for questions now.

375
00:29:02,754 --> 00:29:04,348
*laughter*
Netanel: Maybe

376
00:29:04,348 --> 00:29:08,174
Herald: And I have the funny feeling, 
we will have some questions now.

377
00:29:08,174 --> 00:29:12,924
Ok, so we have some microphones here. 
Please queue up.

378
00:29:12,924 --> 00:29:17,959
Please do not shout in, because we need 
to record it on the stream.

379
00:29:17,959 --> 00:29:19,156
Well, here we go.

380
00:29:19,156 --> 00:29:22,776
And we also have some questions 
from the internet, don't we?

381
00:29:22,776 --> 00:29:27,274
Signal Angel: Oh yes, we do!
*laughter*

382
00:29:27,274 --> 00:29:30,143
Signal: But before we come 
to the technical questions,

383
00:29:30,143 --> 00:29:33,411
the IRC wants you to know, 
what you did to it:

384
00:29:33,411 --> 00:29:37,425
it felt like there were explosions 
and camels everywhere.

385
00:29:37,425 --> 00:29:39,575
Netanel *laughing*: That's the point

386
00:29:39,575 --> 00:29:44,622
Signal: And incidently they want to know, 
if you have a list of those camel pics somewhere?

387
00:29:46,402 --> 00:29:49,663
Netanel: I think Google has it? 
*more laughter*

388
00:29:49,663 --> 00:29:53,796
Just there search camels.

389
00:29:53,796 --> 00:29:59,224
Signal: So for the first question. 
Opello(?) wants to know,

390
00:29:59,224 --> 00:30:04,293
if the take-away is, that Perl project authors 
so shouldn't trust input

391
00:30:04,293 --> 00:30:10,437
and instead verify types with REF 
and always use prepared SQL statements?

392
00:30:13,616 --> 00:30:20,628
Netanel: That's a good question. The take-away should be… 
*laughter*

393
00:30:24,039 --> 00:30:28,428
well, how will I phrase it …

394
00:30:29,424 --> 00:30:32,734
I think I have a slide … somewhere … 
*more laughter*

395
00:30:32,734 --> 00:30:36,303
Oh wait, where's my slide?

396
00:30:37,631 --> 00:30:40,204
Don't worry, have it right here.

397
00:30:44,224 --> 00:30:49,080
But really, trusting user input 
is always a bad idea

398
00:30:49,080 --> 00:30:51,831
and most developers know it.

399
00:30:51,831 --> 00:30:54,211
The problem is, that…

400
00:30:54,211 --> 00:30:57,178
well, at least from the code 
I saw written in Perl,

401
00:30:57,178 --> 00:31:00,091
and that's a lot of code, trust me

402
00:31:00,091 --> 00:31:04,794
…is that hashes and arrays 
are almost always considered secured

403
00:31:04,794 --> 00:31:09,143
as they supposedly can't be 
created by user input, as I said.

404
00:31:09,143 --> 00:31:18,196
But, when you're expecting your user input 
to be a scalar, a string or even a list

405
00:31:18,196 --> 00:31:25,846
and instead you get a hash from unexpected 
directions, you get confused.

406
00:31:25,846 --> 00:31:30,779
And you can't always 
live in the fear of not knowing

407
00:31:30,779 --> 00:31:33,613
what data type you're trying to handle.

408
00:31:33,613 --> 00:31:40,075
Well, not trusting scalar data types 
is a wise decision, because it's dangerous.

409
00:31:40,075 --> 00:31:46,119
But not trusting your hashes, 
as well not trusting your arrays?

410
00:31:46,119 --> 00:31:49,581
What's next? Not trusting your own code?

411
00:31:49,581 --> 00:31:54,274
You just can't expect anything 
to really work as it should.

412
00:31:54,274 --> 00:31:56,444
When you're writing Perl,

413
00:31:56,444 --> 00:32:03,899
you are constantly attacked 
by all these different directions.

414
00:32:03,899 --> 00:32:08,579
And even the data type direction is a problem now.

415
00:32:08,579 --> 00:32:12,652
I hope that answered the question 
beside the slide.

416
00:32:12,652 --> 00:32:16,335
Herald: Well, then we're gonna go over 
and start with number one.

417
00:32:16,335 --> 00:32:19,494
Questioner: So thank you for opening our eyes.

418
00:32:19,494 --> 00:32:24,254
Even I use Perl, I would say, 
for cooking and yes …

419
00:32:24,254 --> 00:32:25,718
Netanel: I remember you
Q: Sorry?

420
00:32:25,718 --> 00:32:27,377
N: I remember you from the last talk! 
Q: No no

421
00:32:27,377 --> 00:32:30,508
N: Oh, you're new? Oh… *smirking*
Q: I'm new, I'm new…

422
00:32:30,508 --> 00:32:36,068
Q: So… I can't say, I'm not guilty of that, 
but I still would say yes,

423
00:32:36,068 --> 00:32:39,508
Perl is a bit like cooking with my mum.

424
00:32:39,508 --> 00:32:46,315
Sometimes I put something into…
the… with the boiling thing…

425
00:32:46,315 --> 00:32:50,864
and sometimes she, sometimes I go away, 
sometimes she go away

426
00:32:50,864 --> 00:32:53,894
and the only thing you can do is always taste.

427
00:32:53,894 --> 00:32:57,814
And yes, you're maybe right, Perl is a language

428
00:32:57,814 --> 00:33:01,822
where you never know what comes out, 
but it's real cool!

429
00:33:01,822 --> 00:33:04,583
If you get the right response you can use it,

430
00:33:04,583 --> 00:33:08,678
if you use it to write web applications 
I would agree.

431
00:33:08,678 --> 00:33:12,864
Web applications, the professional ones 
at least, are not for cooking,

432
00:33:12,864 --> 00:33:18,466
but for doing funny things and 
have some fun, I think it's a perfect language.

433
00:33:18,466 --> 00:33:22,296
N: I think Perl is a lot of fun. 
*laughter*

434
00:33:22,296 --> 00:33:26,633
I completely agree on that. *laughing*

435
00:33:26,633 --> 00:33:29,144
Herald: Then we're gonna go over to two.

436
00:33:29,144 --> 00:33:33,741
Question: Was your life ever threatened 
while interacting with the Perl community?

437
00:33:33,741 --> 00:33:35,794
*laughter*
N: Could you please repeat that? I …

438
00:33:35,794 --> 00:33:39,545
Q: Was your life ever threatened 
while interacting with the Perl community?

439
00:33:39,545 --> 00:33:42,515
N: Definitely. Definitely,

440
00:33:42,515 --> 00:33:46,729
I'm getting hate mail every day, 
living in fear …

441
00:33:46,729 --> 00:33:48,648
H: And over to the three, please.

442
00:33:48,648 --> 00:33:53,261
Q: I think I speak for all of us, 
when I thank you for this wonderful talk,

443
00:33:53,261 --> 00:34:00,086
N: Uh, thank you. Thank you really! Thank you.
*applause*

444
00:34:00,086 --> 00:34:06,660
Q: Brilliantly executed, but… ehm… 
you spoke about Perl 5 I think.

445
00:34:06,660 --> 00:34:11,155
N: Yes, you are absolutely right.
Q: As some of you might know, this christmas…

446
00:34:11,155 --> 00:34:15,032
*laughter*
Q: …so tomorrow Ingo Blechschmidt

447
00:34:15,032 --> 00:34:20,047
is going to give a talk about how Perl 6 
will make everything better

448
00:34:20,047 --> 00:34:24,161
and how everyone should start 
using Perl 6 and…

449
00:34:24,161 --> 00:34:27,893
N: It also craps rainbows
Q: Yeah, of course…

450
00:34:27,893 --> 00:34:31,391
Q: My personal comment is: 
wouldn't it have happened

451
00:34:31,391 --> 00:34:33,945
with a statically typed language?

452
00:34:33,945 --> 00:34:39,450
So I think some nice folks at Haskell 
in IRC are waiting for you Perl developers

453
00:34:39,450 --> 00:34:44,753
to please come, join us … Thank you!
N: *smirking*

454
00:34:44,753 --> 00:34:46,456
*Herald and Netanel start speaking simultaneously*

455
00:34:46,456 --> 00:34:49,446
H: …sorry, to answer first, where am I… sorry
N: Ah, no..., I am not answering, just...

456
00:34:49,446 --> 00:34:55,526
just a quick note about Perl 6. 
This talk is all about Perl 5, alright?

457
00:34:55,526 --> 00:35:01,108
I … Perl 6 came out a couple of days ago and …

458
00:35:01,108 --> 00:35:06,848
...from …at least from what I saw, 
Perl 6 is to Perl as…

459
00:35:06,848 --> 00:35:11,932
C++ is to C. It's the same name, 
but it's a whole different language.

460
00:35:11,932 --> 00:35:17,311
So yes, this is Perl 5. 
Maybe I'll come back next year about Perl 6?

461
00:35:17,311 --> 00:35:19,051
*laughter*
Who knows?

462
00:35:19,051 --> 00:35:22,175
Herald: I'm looking forward to that already.
*applause*

463
00:35:22,175 --> 00:35:25,128
*Herald pointing to Signal Angel*

464
00:35:25,128 --> 00:35:31,104
Signal: Yeah… Joerd(?) wants to know: 
of course you talked a lot about CGI.PM

465
00:35:31,104 --> 00:35:37,290
which you know was removed from repository from Perl 
even before your talk last year.

466
00:35:37,290 --> 00:35:43,399
So what about it's replacements 
from CPAN like CGI::Simple.

467
00:35:43,399 --> 00:35:48,265
Netanel: I don't know, I haven't checked it. 
When I decided on which modules to check,

468
00:35:48,265 --> 00:35:55,610
I took CGI.PM because even though it is old, 
it is the most popular in the world as of today

469
00:35:55,610 --> 00:36:03,161
and I took Mojolicious and Catalyst because 
they were really popular, too.

470
00:36:03,161 --> 00:36:08,129
So I didn't take the newest modules, 
I take the most popular modules.

471
00:36:08,129 --> 00:36:15,973
And I think, that's the important 
aspect of … deciding.

472
00:36:17,693 --> 00:36:20,869
Herald: And over to one, please.

473
00:36:20,869 --> 00:36:29,013
Questioner: Hi… I'm… part of the Perl community, and…
*laughter*

474
00:36:29,013 --> 00:36:33,169
N: Hi!
Q: But I just start with Perl – 5

475
00:36:33,169 --> 00:36:40,315
N: Uhh… ehm… uhh… didn't you… nhaa…
*laughter*

476
00:36:40,315 --> 00:36:44,329
Q: We use Perl for almost every module 
that we have at work

477
00:36:44,329 --> 00:36:47,314
and this worked really fine. 
N: …yeah…

478
00:36:47,314 --> 00:36:51,920
Q: And I don't know why you're picking Perl as language to attack.

479
00:36:51,920 --> 00:36:59,099
It's a really old language, it's also every language 
that we can pick, that has problems.

480
00:36:59,099 --> 00:37:05,027
But it doesn't mean this has to die or 
stop using it. So I don't know why…

481
00:37:05,027 --> 00:37:08,561
N: …you're right, you're right. 
First of all, you're completely right,

482
00:37:08,561 --> 00:37:11,958
because a language shouldn't die, it should improve.

483
00:37:11,958 --> 00:37:16,880
C got critized and it improved. 
PHP got critized and it improved.

484
00:37:16,880 --> 00:37:20,163
Why can't Perl be critized, too?

485
00:37:20,163 --> 00:37:24,238
Why is it like a code, when you say 
something bad about Perl, then,

486
00:37:24,238 --> 00:37:27,254
I don't know, a horde of PerlMonks jumps on you?

487
00:37:27,254 --> 00:37:32,553
Why don't improve the language? 
Don't use it in your work though,

488
00:37:32,553 --> 00:37:37,766
it's dangerous. 
*laughter and applause*

489
00:37:39,506 --> 00:37:42,109
H: Then we're gonna jump over to five, please.

490
00:37:42,109 --> 00:37:48,513
Q: Hi. I'm not a Perl developer, 
but I use a lot of Ruby and Python.

491
00:37:48,513 --> 00:37:51,061
Is this really limited to Perl or

492
00:37:51,061 --> 00:37:54,169
does this apply to more or less 
any dynamic language?

493
00:37:54,169 --> 00:37:58,640
N: As I said in one of the first few slides,

494
00:37:58,640 --> 00:38:03,613
some of it also applies to Python. 
Specifically the thing

495
00:38:03,613 --> 00:38:09,867
when you can't specify what data types 
your function arguments can get.

496
00:38:09,867 --> 00:38:15,954
But, what's unique to Perl is that 
writing different code

497
00:38:15,954 --> 00:38:20,247
for different data types in one function 
is very, very common.

498
00:38:20,247 --> 00:38:23,181
You can do it in every language, of course!

499
00:38:23,181 --> 00:38:28,276
But it is very common only in Perl! 
And that is unique about it,

500
00:38:28,276 --> 00:38:32,501
of course besides the thing 
that hashes and arrays are secure.

501
00:38:32,501 --> 00:38:37,116
That's of course Perls only fault.

502
00:38:37,116 --> 00:38:40,098
H: Good, then we're gonna go over to six, please.

503
00:38:40,098 --> 00:38:47,295
Q: Hey! Did you say WAT more 
while preparing this talk or while holding it?

504
00:38:47,295 --> 00:38:56,782
N: Uhm. Both. *Laughing*. 
Did I rant? That was the … right?

505
00:38:56,782 --> 00:39:00,911
Q: Did you say it more 
while preparing it or while holding it?

506
00:39:00,911 --> 00:39:02,963
N: I'm missing your word, man, can you...

507
00:39:02,963 --> 00:39:11,468
Ahh, wat… WAT! Ohh… Yeah, both!
*laughter*

508
00:39:11,468 --> 00:39:14,828
H: Ok, do we have another from the internet?

509
00:39:14,828 --> 00:39:19,420
Signal: Does your exploit 
also work in tainted mode?

510
00:39:19,420 --> 00:39:23,663
N: No, I believe not. No, it doesn't.

511
00:39:24,473 --> 00:39:26,680
H: And another one...

512
00:39:26,680 --> 00:39:35,537
S: Is there any Perl obfuscated code exploits 
like this for Catalyst or Mojolicious?

513
00:39:36,137 --> 00:39:39,437
*someone chuckling in audience*

514
00:39:39,437 --> 00:39:43,409
N: I've no idea, man, maybe. 
I didn't check it of course.

515
00:39:43,409 --> 00:39:48,082
I didn't check every module 
for every exploit, I ever want to create, but

516
00:39:48,082 --> 00:39:55,075
on CGI.PM, which is again 
the most popular CGI library, it did.

517
00:39:55,075 --> 00:40:02,566
So, maybe the internet 
can find more exploits. I know it can.

518
00:40:02,566 --> 00:40:06,622
H: Bring it on. That's it?
N: That's it?

519
00:40:06,622 --> 00:40:07,775
Thank you!

520
00:40:07,775 --> 00:40:09,157
*applause*

521
00:40:09,157 --> 00:40:12,404
Herald: Thank you very much!
Netanel: Thank you!

522
00:40:12,404 --> 00:40:23,033
*postroll music*
