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:17,683
postroll music
523
00:40:17,683 --> 00:40:24,000
subtitles created by c3subtitles.de
in the year 2016. Join, and help us!