WEBVTT
00:00:00.000 --> 00:00:08.755
preroll music
00:00:10.084 --> 00:00:13.459
Herald: And I'm gonna introduce Netanel Rubin.
00:00:14.166 --> 00:00:18.640
He has been here last year with a talk
that he got some bashing for.
00:00:19.314 --> 00:00:23.548
This year he's gonna ensure,
it's not the programmer's fault,
00:00:23.689 --> 00:00:27.426
it's the language itself. No?
00:00:27.507 --> 00:00:29.883
Well, here we go, well here we go.
00:00:29.949 --> 00:00:33.598
Netanel, he is working for
PerimeterX in Tel Aviv,
00:00:33.631 --> 00:00:35.491
welcome on stage, your talk!
00:00:35.521 --> 00:00:37.634
Netanel: Thank you very much, applause
00:00:37.674 --> 00:00:41.134
thank you, thank you!
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
00:00:52.755 --> 00:00:56.411
less thought out "features".
00:00:56.411 --> 00:01:04.709
Now, I got some bashing from the Perl community,
but mainly what happened was,
00:01:04.709 --> 00:01:10.291
that the Perl community completely rejected my talk
claiming that the language
00:01:10.291 --> 00:01:16.357
is completely fine and great
and all of this stuff are just improvements.
00:01:17.573 --> 00:01:20.724
It was clear I had to give another talk.
00:01:21.421 --> 00:01:29.049
This is why I'm very proud to present
"Perl Jam 2 – The Camel strikes back"!
00:01:29.049 --> 00:01:33.618
applause
00:01:33.618 --> 00:01:36.188
Thank you
00:01:38.065 --> 00:01:45.873
At the last talk, I showed that "lists" are expressions,
used in… many confusing ways.
00:01:45.873 --> 00:01:52.921
I also showed how CGI parameters can create lists,
directly from user input.
00:01:52.921 --> 00:02:00.165
But most importantly, I showed
that when these two things combine, shit happens.
00:02:01.696 --> 00:02:04.066
Great
00:02:04.080 --> 00:02:08.949
But the really interesting part
was the PerlMonks response.
00:02:08.949 --> 00:02:16.203
The Perl community…
laughter
00:02:19.274 --> 00:02:24.451
The Perl community had a long discussion
at the PerlMonks forum
00:02:24.451 --> 00:02:29.475
that started with the words
"Sad news from Germany".
00:02:29.475 --> 00:02:32.231
A bit dramatic, but who am I to judge?
00:02:32.231 --> 00:02:38.931
So, after a long, long discussion,
they came to the unavoidable conclusion
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.
00:02:49.717 --> 00:02:55.756
They also realized I'm just a
"script kiddie preaching to other script kiddies",
00:02:55.756 --> 00:03:01.162
and not just any script kiddies, the CCC audience is a
00:03:01.162 --> 00:03:06.435
"heterogeneous group of chaotic punks
who love to see themselves in the hacker
00:03:06.435 --> 00:03:18.091
image of Hollywood media".
applause and whistling from audience
00:03:18.091 --> 00:03:24.075
What hacker image?
What are they talking about?
00:03:24.075 --> 00:03:26.218
We have no hacker image.
00:03:26.310 --> 00:03:34.281
Anyway, it got quite surreal, as in some point
they even critized
00:03:34.281 --> 00:03:41.994
the "crude use of propaganda
in the camel images". WAT?
00:03:42.461 --> 00:03:46.015
laughing
applause
00:03:46.015 --> 00:03:50.737
Propaganda in the camel images. Alright.
00:03:50.737 --> 00:03:58.348
Anyway, they completely rejected the entire talk,
even though the technical points were valid.
00:03:58.348 --> 00:04:03.603
They rejected it because of
some jokes and camel images.
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.
00:04:12.814 --> 00:04:19.622
Two of these lame excuses were
repeated over and over again.
00:04:19.622 --> 00:04:24.733
The first was that I should
read the fucking manual, which is funny
00:04:24.733 --> 00:04:27.413
because I thought I was the only one who did…
00:04:27.413 --> 00:04:29.184
laughter
00:04:29.184 --> 00:04:30.753
…and the second is that
00:04:30.753 --> 00:04:35.378
I'm using the old, ancient Perl,
and not the new, modern Perl.
00:04:35.378 --> 00:04:39.920
more laughter
00:04:40.811 --> 00:04:46.317
Remember these two points carefully
as I'll later break them in the presentation.
00:04:46.317 --> 00:04:52.167
But, enough with the intro,
let's start with the new madness.
00:04:52.167 --> 00:04:58.788
So, Perl allows declaring variables
without specifying their data type.
00:04:58.788 --> 00:05:03.131
Of course, this functionality exists
in many dynamic languages,
00:05:03.131 --> 00:05:06.884
and is completely fine and very convenient.
00:05:06.884 --> 00:05:12.773
But, as usual, Perl took it
to a whole different level.
00:05:12.773 --> 00:05:19.200
Perl went as far as removing
data type declarations from function arguments.
00:05:19.200 --> 00:05:20.854
You can see that in this example,
00:05:20.854 --> 00:05:27.760
I'm just receiving two different arguments
without knowing what type they are.
00:05:27.760 --> 00:05:29.760
Let me be clear about that,
00:05:29.760 --> 00:05:34.536
you don't get to choose whether you want
to specify argument data types or not,
00:05:34.536 --> 00:05:41.053
you can't specify
what data types you're expecting to get.
00:05:41.053 --> 00:05:44.764
So even if I built a function
that only works with strings,
00:05:44.764 --> 00:05:49.332
I have no way of forcing that
at the function declaration.
00:05:49.332 --> 00:05:51.318
Now that's annoying.
00:05:51.318 --> 00:05:57.394
But, the real kicker
is how this feature is used.
00:05:57.444 --> 00:06:03.828
Apparently, it is very common to write
two completely different blocks of code,
00:06:03.828 --> 00:06:07.675
one that handles scalar types,
like strings or ints,
00:06:07.675 --> 00:06:13.217
and one that handles non-scalar types,
like arrays or hashes.
00:06:13.217 --> 00:06:15.338
Let me repeat that:
00:06:15.338 --> 00:06:23.796
Writing multiple code, for multiple data-types,
in one function, is a Perl standard.
00:06:23.796 --> 00:06:31.782
And that's sad. You shouldn't write redundant code
because the language lacks the capability
00:06:31.782 --> 00:06:35.971
of letting you decide
which cases you don't want to handle.
00:06:35.971 --> 00:06:40.493
By the way, Python doesn't let you
declare your function argument data types too,
00:06:40.493 --> 00:06:45.723
but unlike Perl, writing redundant code
to cover that up
00:06:45.723 --> 00:06:49.726
is definitely not the standard.
00:06:49.726 --> 00:06:54.723
Anyway, sad as this may be,
this Perl convention is not dangerous.
00:06:54.723 --> 00:06:56.894
The dangerous part begins
00:06:56.894 --> 00:07:02.956
when hashes and arrays
are considered as "secure" data types,
00:07:02.956 --> 00:07:07.738
mainly because they can't be created
by user input.
00:07:07.738 --> 00:07:10.374
This results in this kind of code,
00:07:10.374 --> 00:07:14.187
where if the function argument
is a hash, for example,
00:07:14.187 --> 00:07:18.708
it is used un-escaped in dangerous functions.
00:07:18.708 --> 00:07:25.661
Hashes, specifically, are considered so secure,
that even if you use "taint mode",
00:07:25.661 --> 00:07:28.293
which is some kind of safe mode for Perl,
00:07:28.293 --> 00:07:33.532
hash keys are not tainted, meaning
that, even if you use safe mode,
00:07:33.532 --> 00:07:36.719
they can be still used in dangerous functions
00:07:36.719 --> 00:07:41.639
without any validation,
as opposed to other data types.
00:07:41.639 --> 00:07:46.619
Now this kind of code appears a lot
in Perl applications,
00:07:46.619 --> 00:07:49.759
and apart from the many bugs
this method can cause,
00:07:49.759 --> 00:07:54.395
it also makes your code exploitable.
00:07:54.395 --> 00:07:58.369
So we know function arguments are of unknown data type.
00:07:58.369 --> 00:08:03.073
And we know developers treat hashes and arrays
as "secure" data types,
00:08:03.073 --> 00:08:06.603
inserting their values into dangerous functions.
00:08:06.603 --> 00:08:09.140
But this practices isn't something
00:08:09.140 --> 00:08:14.056
that was created a long time ago,
and found only on redundant code.
00:08:14.056 --> 00:08:20.341
Because of how the language is built,
its supposedly restriction-less type of developing,
00:08:20.341 --> 00:08:26.688
even now it is the natural way to code
when you're using Perl.
00:08:26.688 --> 00:08:31.185
And that's the real problem:
Perl is like a shotgun,
00:08:31.185 --> 00:08:36.552
with one trigger you know about
and a dozen that you don't.
00:08:36.552 --> 00:08:40.821
So for now, we know
that if we'll somehow manage
00:08:40.821 --> 00:08:46.051
to create these "secure" data types,
with our user input,
00:08:46.051 --> 00:08:49.010
we could exploit the code.
00:08:49.010 --> 00:08:53.997
So the only question remaining really
is what are we gonna exploit?
00:08:53.997 --> 00:08:58.185
And the answer, again,
is Bugzilla.
00:08:58.185 --> 00:09:02.768
laughter
00:09:03.178 --> 00:09:08.713
Like every other Perl project,
Bugzilla is heavily using functions
00:09:08.713 --> 00:09:13.277
that treat scalar and non-scalar
argument types very differently.
00:09:13.277 --> 00:09:17.404
This is one of them: the load_from_DB function is responsible
00:09:17.404 --> 00:09:21.541
for extracting object specific data
out of the database.
00:09:21.541 --> 00:09:28.945
Like I just said, it treats scalars,
and in this case hashes, very differently.
00:09:28.945 --> 00:09:34.146
If the function argument is a hash,
it takes one of its values
00:09:34.146 --> 00:09:39.845
and inserts it as is, un-escaped,
into an SQL statement.
00:09:39.845 --> 00:09:44.598
Again, because hashes
are considered secure,
00:09:44.598 --> 00:09:47.807
so there's no point of escaping them.
00:09:47.807 --> 00:09:50.919
On the other hand,
if the argument is a scalar,
00:09:50.919 --> 00:09:55.798
it converts it into an integer
and only then use it in an SQL statement.
00:09:55.798 --> 00:09:59.020
Because scalar values are not secure.
00:09:59.020 --> 00:10:00.680
hashes: secure
00:10:00.680 --> 00:10:03.064
scalar: not secure
00:10:03.064 --> 00:10:06.241
This means that if we could control
the function argument entirely,
00:10:06.241 --> 00:10:10.964
including its data type,
we could control the SQL query,
00:10:10.964 --> 00:10:14.405
effectively exploiting an SQL injection attack,
00:10:14.405 --> 00:10:17.720
by inserting a hash
containing that specific value.
00:10:17.720 --> 00:10:21.234
But…
00:10:21.234 --> 00:10:26.862
CGI input doesn't allow hashes, right?
00:10:26.862 --> 00:10:32.339
The whole Perl security module
is built on that assumption.
00:10:32.339 --> 00:10:37.314
The problem is that, like us,
developers are assuming
00:10:37.314 --> 00:10:42.487
CGI input is the only input method available.
00:10:42.487 --> 00:10:45.581
CGI.
00:10:45.581 --> 00:10:48.545
But CGI isn't the only way to go.
00:10:48.545 --> 00:10:52.978
Bugzilla developers missed the fact
that their own system
00:10:52.978 --> 00:10:57.723
is also featuring an XMLRPC and a JSONRPC,
00:10:57.723 --> 00:11:05.048
both supporting input of non-scalar data types
like arrays and hashes!
00:11:05.048 --> 00:11:06.498
But I'm not blaming them.
00:11:06.498 --> 00:11:12.492
Yes, they forgot that there are more ways
for a user to input than CGI,
00:11:12.492 --> 00:11:16.697
but still, they're just the product
of how Perl programming is taught,
00:11:16.697 --> 00:11:20.679
filled with false assumptions and inconsistencies.
00:11:20.679 --> 00:11:25.983
Expecting anything but this kind
of security problems is just naive.
00:11:25.983 --> 00:11:28.547
But back to the vulnerability.
00:11:28.547 --> 00:11:30.429
If we'll use one of these RPCs,
00:11:30.429 --> 00:11:34.136
sending our input parameter with a malicious hash,
00:11:34.136 --> 00:11:37.204
instead of just a regular numeric parameter,
00:11:37.204 --> 00:11:39.991
we will be able to exploit the SQL injection!
00:11:39.991 --> 00:11:44.428
So, if we'll send this regular request,
using the JSONRPC interface,
00:11:44.428 --> 00:11:48.611
the number 1 will be used
as the ID of a bug to extract,
00:11:48.611 --> 00:11:51.272
but if we'll send this request,
00:11:51.272 --> 00:11:53.993
where instead of an integer we'll supply a hash,
00:11:53.993 --> 00:11:57.365
then suddenly we will be able
to inject any SQL we'd like
00:11:57.365 --> 00:12:03.016
into that statement, effectively
compromising the entire database.
00:12:03.121 --> 00:12:07.048
Now when you look at this request, you realize
00:12:07.048 --> 00:12:11.396
that this is not a sophisticated vulnerability.
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,
00:12:20.859 --> 00:12:24.980
and that's it, the system is compromised.
00:12:24.980 --> 00:12:29.072
It was so heavily built on the assumption
00:12:29.072 --> 00:12:32.223
that hashes are secure, that it offered me
00:12:32.223 --> 00:12:36.676
almost unlimited access security wise.
00:12:36.676 --> 00:12:41.659
The funny thing about that is, that
although it's so simple,
00:12:41.659 --> 00:12:45.970
the attack has existed for over 5 years.
00:12:45.970 --> 00:12:48.912
That's the year I was born in.
00:12:48.912 --> 00:12:55.087
So, we now proved this "unknown-argument-type" feature
00:12:55.087 --> 00:12:58.232
is a huge source for problems.
00:12:58.232 --> 00:13:02.901
We also know writing different code
to handle different data types
00:13:02.901 --> 00:13:06.953
just causes a lot of false assumptions.
00:13:06.953 --> 00:13:13.534
But most importantly, treating non-scalar
data types such as hashes as "secure",
00:13:13.534 --> 00:13:17.354
just because they supposedly can't be created by the user,
00:13:17.354 --> 00:13:22.955
is very, very, BAD. Just ask Bugzilla.
00:13:22.955 --> 00:13:30.145
But the shocking part really, is that, again,
this is the Perl Standard!
00:13:30.145 --> 00:13:33.892
You're not expected to use it, you have to
00:13:33.892 --> 00:13:36.645
as you don't have any other choice.
00:13:36.645 --> 00:13:43.829
This security mess
is a fundamental part of the language.
00:13:43.829 --> 00:13:51.777
The problem is that creating non-scalar data types
is impossible in some cases.
00:13:51.777 --> 00:13:54.914
We can't rely that some kind of RPC
00:13:54.914 --> 00:13:58.859
will exist in the code
and support different data types,
00:13:58.859 --> 00:14:05.031
and we can't create data types
using regular user input… Right?
00:14:05.031 --> 00:14:06.937
Well, let's have a look at
00:14:06.937 --> 00:14:10.526
how different CGI modules
handle different kind of input.
00:14:10.526 --> 00:14:13.917
First, we'll take the most trivial scenario.
00:14:13.917 --> 00:14:17.807
A single valued parameter,
something that looks like this request,
00:14:17.807 --> 00:14:22.210
where the "foo" parameter
is assigned the string "bar".
00:14:22.210 --> 00:14:26.819
In this case, a scalar is created on all three CGI modules,
00:14:26.819 --> 00:14:31.198
which doesn't really help us,
but is pretty much what we've expected.
00:14:31.198 --> 00:14:32.914
It is secure.
00:14:32.914 --> 00:14:37.846
But what happens if instead of
sending a single-valued parameter,
00:14:37.846 --> 00:14:42.377
we'll send a multi-valued parameter,
like in this request?
00:14:42.377 --> 00:14:46.032
Now things are starting to get complicated.
00:14:46.032 --> 00:14:50.551
On CGI.PM, as we already know,
a list is created,
00:14:50.551 --> 00:14:55.013
which is very useful for us,
but not what we're after.
00:14:55.013 --> 00:15:01.847
Let's have a look at
what the "new" Perl modules are creating.
00:15:01.847 --> 00:15:09.987
We'll see that both of them are returning
arrays containing our values.
00:15:09.987 --> 00:15:14.549
Arrays! WAT?
00:15:14.549 --> 00:15:19.278
I thought you can't create
these kind of data types with regular input,
00:15:19.278 --> 00:15:22.442
after all, they're considered safe.
00:15:22.442 --> 00:15:24.236
But let's continue.
00:15:24.236 --> 00:15:27.637
What happens if instead of sending a regular value,
00:15:27.637 --> 00:15:31.883
we'll try and upload a file in that parameter?
00:15:31.883 --> 00:15:35.229
Now things are really getting out of hand,
00:15:35.229 --> 00:15:44.409
because CGI.PM now returns a file descriptor,
and Catalyst and Mojolicious returns a hash.
00:15:44.409 --> 00:15:46.384
WAT?
00:15:46.384 --> 00:15:54.012
We just exploited
the most popular Perl project in the world
00:15:54.012 --> 00:15:58.226
because they assumed hashes can't be created by the user,
00:15:58.226 --> 00:16:02.984
and now we're finding out
that not only we can create hashes,
00:16:02.984 --> 00:16:05.477
it is a god-damned feature?!
00:16:05.477 --> 00:16:07.161
That's insane!
00:16:07.161 --> 00:16:11.504
The whole Perl security standard is built on that assumption
00:16:11.504 --> 00:16:14.954
that users can't create non-scalar data-types
00:16:14.954 --> 00:16:19.867
and now suddenly these are features?
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.
00:16:27.693 --> 00:16:34.183
Watch closely, because this is where it gets ridiculous.
00:16:34.183 --> 00:16:39.426
Now, CGI.PM returns a list of File Descriptors,
00:16:39.426 --> 00:16:42.551
Catalyst returns a list of Hashes
00:16:42.551 --> 00:16:49.282
and Mojolicious returns an Array of Objects! WAT?!
00:16:49.282 --> 00:16:53.340
laughter and applause
00:16:53.444 --> 00:16:58.105
Almost any Perl project in the world
00:16:58.105 --> 00:17:03.470
uses one of these modules
for parsing CGI input.
00:17:03.470 --> 00:17:10.522
Just think how many developers assumed
the exact same thing Bugzilla assumed
00:17:10.522 --> 00:17:15.854
and treated hashes and arrays as secure data types.
00:17:15.854 --> 00:17:17.752
So if you're using CGI.PM,
00:17:18.380 --> 00:17:21.268
instead of the expected scalar value you could be getting
00:17:21.268 --> 00:17:25.724
a list, a file descriptor or a list of file descriptors
00:17:25.724 --> 00:17:27.644
and if you're using Catalyst
00:17:27.644 --> 00:17:30.895
you could receive a scalar, an array, a hash or a list,
00:17:30.895 --> 00:17:35.375
which is basically any data type.
00:17:36.320 --> 00:17:39.425
So expecting your function… yeah
00:17:40.089 --> 00:17:44.091
audience chuckling
00:17:45.943 --> 00:17:53.997
So expecting your function arguments
to be of a specific data type is false.
00:17:53.997 --> 00:18:00.119
Expecting hashes and arrays to be secure is also false.
00:18:00.119 --> 00:18:02.972
Expecting scalar only user input
00:18:02.972 --> 00:18:06.833
is a major false.
00:18:06.833 --> 00:18:13.156
And to be honest, it seems that in Perl expecting is false!
00:18:13.156 --> 00:18:17.337
laughter and applause
00:18:21.422 --> 00:18:25.923
You just can't expect anything
00:18:25.923 --> 00:18:32.455
even the most basic of things
such as what data type your variable is made of.
00:18:32.455 --> 00:18:35.761
You just don't know.
00:18:37.870 --> 00:18:42.934
But I felt all of these points will
go un-noticed
00:18:42.934 --> 00:18:48.632
without an extreme example of Perl's absurdity.
00:18:48.632 --> 00:18:52.599
So I found an extreme example.
00:18:52.599 --> 00:18:55.249
One that will clearly show
00:18:55.249 --> 00:18:59.204
the ridiculous nature of the language.
00:18:59.204 --> 00:19:00.898
And this is it:
00:19:00.898 --> 00:19:06.829
All this code does is print an uploaded file's content.
00:19:06.829 --> 00:19:14.517
And to show you how basic and simple that code is,
I'll explain each line.
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.
00:19:20.363 --> 00:19:26.785
The second line checks if a file
has been uploaded in the "file" parameter.
00:19:26.785 --> 00:19:31.549
The third line gets the file descriptor from the CGI module,
00:19:31.549 --> 00:19:37.438
while the fourth line loops through the file
and the fifth prints it.
00:19:37.438 --> 00:19:44.459
That's it. Again: all this code does
is get a file and print it.
00:19:44.459 --> 00:19:45.521
clapping
That's it.
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.
00:19:52.126 --> 00:19:55.683
It's not saving it anywhere,
it's not moving it anywhere,
00:19:55.683 --> 00:19:58.771
it just prints its content.
00:19:58.771 --> 00:20:03.519
There should be absolutely
nothing dangerous in this code,
00:20:03.519 --> 00:20:07.087
it contains literally five lines.
00:20:07.087 --> 00:20:09.830
Yet, it's demo time.
00:20:09.830 --> 00:20:12.332
laughter
00:20:12.412 --> 00:20:15.020
So trust me, you don't need to see the text,
00:20:15.020 --> 00:20:19.820
all you need to see is that
when I'm sending a regular request nothing happens.
00:20:19.820 --> 00:20:23.585
When I send it now, nothing happens,
I'm just getting the file content.
00:20:23.585 --> 00:20:26.240
We're having fun, you don't see the burp…
00:20:26.240 --> 00:20:30.425
Now, nice. Okay.
00:20:30.425 --> 00:20:34.184
So…
…L't me just…
00:20:34.685 --> 00:20:37.182
…I have no idea where my mouse is, okay.
00:20:37.388 --> 00:20:38.323
So…
00:20:39.181 --> 00:20:42.230
I'm sending a regular request,
nothing happens, just getting the content.
00:20:42.230 --> 00:20:46.073
I know, you can't see the text…
…and…
00:20:46.073 --> 00:20:49.519
when I'm sending my malicious request,
00:20:49.519 --> 00:20:51.901
something interesting will pop up.
00:20:51.901 --> 00:20:54.990
Watch closely! It's gonna be quick.
00:20:55.092 --> 00:20:56.684
Ready?
00:20:58.270 --> 00:21:00.520
Oh, you haven't seen it, it's on the different screen.
00:21:00.520 --> 00:21:06.641
Just a second… oh… duplicate…
00:21:07.809 --> 00:21:09.236
(from audience): … magnify it!
00:21:09.236 --> 00:21:11.781
Netanel: I'll magnify you!
00:21:11.781 --> 00:21:14.247
laughter
00:21:14.421 --> 00:21:18.136
Alright, so… watch closely.
00:21:18.894 --> 00:21:22.772
Ohh, uuh? What was that?
00:21:24.467 --> 00:21:26.559
Let's see it again.
00:21:26.559 --> 00:21:29.528
mocking Uuuuuh?!
00:21:30.340 --> 00:21:36.495
laughter and applause
00:21:36.893 --> 00:21:40.442
Yupp, clearing throat
00:21:40.752 --> 00:21:44.650
… just a second.
00:21:44.800 --> 00:21:46.084
Nice.
00:21:46.084 --> 00:21:49.277
So you're probably asking yourself right now
00:21:49.277 --> 00:21:52.411
"What the fuck did I just see?"
laughter
00:21:52.411 --> 00:21:55.814
"Was that a terminal screen?"
00:21:55.814 --> 00:22:00.237
And the answer is … "Yes"
Yes, it was,
00:22:00.237 --> 00:22:04.468
specifically the "ipconfig" command output.
00:22:04.468 --> 00:22:07.414
Or in other words: What you just saw
00:22:07.414 --> 00:22:15.370
was me exploiting that five lines
with a remote code execution attack.
00:22:15.370 --> 00:22:20.513
So now that you saw the magic happens,
I think it's time for some explanations.
00:22:20.513 --> 00:22:22.487
The first line, responsible for checking
00:22:22.487 --> 00:22:26.221
if a file has been uploaded in the "file" parameter,
00:22:26.221 --> 00:22:29.956
doesn't exactly do as it says.
00:22:29.956 --> 00:22:33.803
Instead of checking if the "file"
parameter is an uploaded file,
00:22:33.803 --> 00:22:39.230
it checks if one of its values is a file descriptor.
00:22:39.230 --> 00:22:45.110
Let me clarify that, instead of checking
if the parameter is only a file,
00:22:45.110 --> 00:22:48.981
it checks if the parameter is also a file.
00:22:48.981 --> 00:22:50.476
laughter
00:22:50.476 --> 00:22:52.842
Meaning that uploading a file
00:22:52.842 --> 00:22:57.023
and assigning another scalar value to the same parameter
00:22:57.023 --> 00:23:00.147
will still work and bypass the check!
00:23:00.147 --> 00:23:01.460
WAT?
00:23:01.460 --> 00:23:06.435
more laughter and applause
00:23:12.066 --> 00:23:15.715
Creative fellows those guys are.
00:23:15.715 --> 00:23:22.137
So now we can assign the "file" parameter
both a regular file and a scalar value.
00:23:22.137 --> 00:23:26.224
But what happens when we try to get
the "file" parameter value?
00:23:26.224 --> 00:23:31.183
In a regular request, it should return
the uploaded file descriptor,
00:23:31.183 --> 00:23:35.821
but now that we're adding another value to that parameter,
00:23:35.821 --> 00:23:40.596
param() returns a list containing all the values we sent:
00:23:40.596 --> 00:23:44.365
the file we've uploaded and our scalar value.
00:23:44.365 --> 00:23:49.191
But the "file" variable
can't contain two values, right?
00:23:49.191 --> 00:23:55.221
So instead of converting
the returned list into an array
00:23:55.221 --> 00:23:59.331
Perl only uses the first element of that list.
00:23:59.331 --> 00:24:05.564
So if we'll send our scalar value
before we send our file,
00:24:05.564 --> 00:24:09.989
the $file variable will be assigned
our scalar value
00:24:09.989 --> 00:24:14.308
instead of the uploaded file descriptor.
00:24:14.308 --> 00:24:19.623
Which means, that $file
is now a regular string!
00:24:19.623 --> 00:24:22.114
in high pitched voice: WAT?
00:24:23.178 --> 00:24:26.127
But what happens to this operator
when we use a string
00:24:26.127 --> 00:24:28.565
instead of a file descriptor?
00:24:28.565 --> 00:24:32.962
Well, the brackets operator
doesn't work with strings, right?
00:24:32.962 --> 00:24:36.548
It works with file descriptors,
why should it work with strings?
00:24:36.548 --> 00:24:39.200
Well, that appears true
00:24:39.200 --> 00:24:42.817
unless that string is "ARGV".
00:24:42.817 --> 00:24:47.644
laughter and applause
00:24:55.470 --> 00:24:57.627
That's not a crazy part.
00:24:57.627 --> 00:24:59.763
more laughter
00:24:59.763 --> 00:25:04.693
In that case the brackets operator, listen closely,
00:25:04.693 --> 00:25:07.668
loops through the script arguments,
00:25:07.668 --> 00:25:12.487
which in CGI comes directly from the
query string instead the command line,
00:25:12.487 --> 00:25:18.844
and it treats them as file paths,
inserting each one into an open() call!
00:25:18.844 --> 00:25:19.977
again laughter
00:25:19.977 --> 00:25:22.655
WAT?
00:25:25.632 --> 00:25:29.485
Yeah, that made sense in some point, I guess.
00:25:29.485 --> 00:25:32.487
All of this basically means that now,
00:25:32.487 --> 00:25:35.874
instead of displaying
our own uploaded file content,
00:25:35.874 --> 00:25:39.749
we can display the content
of any file on the server.
00:25:39.749 --> 00:25:43.334
But that's not the end,
as we haven't executed code yet.
00:25:44.214 --> 00:25:48.808
To execute code, we have
to look at the open() function.
00:25:48.808 --> 00:25:56.676
Again, this is the function being called
with the ARGV values as file paths.
00:25:56.676 --> 00:26:03.054
open() is responsible for opening
a file descriptor to a given file.
00:26:03.054 --> 00:26:05.874
Unless a "pipe" character is added
00:26:05.874 --> 00:26:09.036
to the end of the string,
laughter
00:26:09.036 --> 00:26:13.259
and in that case instead of opening the file,
00:26:13.259 --> 00:26:16.228
it executes it…
applause rising
00:26:16.228 --> 00:26:22.146
…acting as an exec() call!
more applause
00:26:22.576 --> 00:26:28.512
So … when we send our exploit,
00:26:28.512 --> 00:26:34.631
containing our uploaded file,
the "ARGV" malicious scalar value,
00:26:34.631 --> 00:26:37.635
and the ipconfig command followed by a pipe
00:26:37.635 --> 00:26:42.487
this is what we get.
WAT?
00:26:42.487 --> 00:26:46.639
WAT?
applause
00:26:49.165 --> 00:26:56.365
I know, I'm shocked too, but I'm not done yet.
laughter
00:26:56.365 --> 00:27:00.723
Truth be told, I didn't write that code.
00:27:00.723 --> 00:27:06.159
Remember that PerlMonks told me
that I should read their fucking manual?
00:27:06.159 --> 00:27:10.660
more laughter
Guess where that code came from:
00:27:10.660 --> 00:27:22.979
the official CGI documentation!
big applause and audience whistling
00:27:32.545 --> 00:27:36.347
But, I'm not blaming CGI.PM developers.
00:27:36.347 --> 00:27:41.365
Nor am I blaming developers
who copied from CGI.PM examples.
00:27:41.365 --> 00:27:46.913
After all, who could have known
that this is what this code will do?
00:27:46.913 --> 00:27:49.237
This is how it could be exploited?
00:27:49.237 --> 00:27:54.311
There's no exec calls,
the file is not saved anywhere,
00:27:54.311 --> 00:27:58.163
and we're only using a "print".
00:27:58.163 --> 00:28:07.333
The sole responsible for this mess,
is the Perl language.
00:28:07.333 --> 00:28:11.412
Perl is the one silently expanding lists,
00:28:11.412 --> 00:28:14.552
Perl is the one mixing up your data types,
00:28:14.552 --> 00:28:19.884
Perl is the one executing user input
with no exec calls,
00:28:19.884 --> 00:28:22.800
Perl is the problem,
00:28:22.800 --> 00:28:25.502
not its developers.
applause rising
00:28:25.502 --> 00:28:31.879
And until this god-damned, bizarre,
dangerous language is fixed,
00:28:31.879 --> 00:28:34.216
you could only
stop
00:28:34.216 --> 00:28:35.319
using
00:28:35.319 --> 00:28:40.207
Perl!
00:28:40.207 --> 00:28:47.005
Thank you!
more applause
00:28:59.025 --> 00:29:02.754
Herald: So I guess
we have some time for questions now.
00:29:02.754 --> 00:29:04.348
laughter
Netanel: Maybe
00:29:04.348 --> 00:29:08.174
Herald: And I have the funny feeling,
we will have some questions now.
00:29:08.174 --> 00:29:12.924
Ok, so we have some microphones here.
Please queue up.
00:29:12.924 --> 00:29:17.959
Please do not shout in, because we need
to record it on the stream.
00:29:17.959 --> 00:29:19.156
Well, here we go.
00:29:19.156 --> 00:29:22.776
And we also have some questions
from the internet, don't we?
00:29:22.776 --> 00:29:27.274
Signal Angel: Oh yes, we do!
laughter
00:29:27.274 --> 00:29:30.143
Signal: But before we come
to the technical questions,
00:29:30.143 --> 00:29:33.411
the IRC wants you to know,
what you did to it:
00:29:33.411 --> 00:29:37.425
it felt like there were explosions
and camels everywhere.
00:29:37.425 --> 00:29:39.575
Netanel laughing: That's the point
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?
00:29:46.402 --> 00:29:49.663
Netanel: I think Google has it?
more laughter
00:29:49.663 --> 00:29:53.796
Just there search camels.
00:29:53.796 --> 00:29:59.224
Signal: So for the first question.
Opello(?) wants to know,
00:29:59.224 --> 00:30:04.293
if the take-away is, that Perl project authors
so shouldn't trust input
00:30:04.293 --> 00:30:10.437
and instead verify types with REF
and always use prepared SQL statements?
00:30:13.616 --> 00:30:20.628
Netanel: That's a good question. The take-away should be…
laughter
00:30:24.039 --> 00:30:28.428
well, how will I phrase it …
00:30:29.424 --> 00:30:32.734
I think I have a slide … somewhere …
more laughter
00:30:32.734 --> 00:30:36.303
Oh wait, where's my slide?
00:30:37.631 --> 00:30:40.204
Don't worry, have it right here.
00:30:44.224 --> 00:30:49.080
But really, trusting user input
is always a bad idea
00:30:49.080 --> 00:30:51.831
and most developers know it.
00:30:51.831 --> 00:30:54.211
The problem is, that…
00:30:54.211 --> 00:30:57.178
well, at least from the code
I saw written in Perl,
00:30:57.178 --> 00:31:00.091
and that's a lot of code, trust me
00:31:00.091 --> 00:31:04.794
…is that hashes and arrays
are almost always considered secured
00:31:04.794 --> 00:31:09.143
as they supposedly can't be
created by user input, as I said.
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
00:31:18.196 --> 00:31:25.846
and instead you get a hash from unexpected
directions, you get confused.
00:31:25.846 --> 00:31:30.779
And you can't always
live in the fear of not knowing
00:31:30.779 --> 00:31:33.613
what data type you're trying to handle.
00:31:33.613 --> 00:31:40.075
Well, not trusting scalar data types
is a wise decision, because it's dangerous.
00:31:40.075 --> 00:31:46.119
But not trusting your hashes,
as well not trusting your arrays?
00:31:46.119 --> 00:31:49.581
What's next? Not trusting your own code?
00:31:49.581 --> 00:31:54.274
You just can't expect anything
to really work as it should.
00:31:54.274 --> 00:31:56.444
When you're writing Perl,
00:31:56.444 --> 00:32:03.899
you are constantly attacked
by all these different directions.
00:32:03.899 --> 00:32:08.579
And even the data type direction is a problem now.
00:32:08.579 --> 00:32:12.652
I hope that answered the question
beside the slide.
00:32:12.652 --> 00:32:16.335
Herald: Well, then we're gonna go over
and start with number one.
00:32:16.335 --> 00:32:19.494
Questioner: So thank you for opening our eyes.
00:32:19.494 --> 00:32:24.254
Even I use Perl, I would say,
for cooking and yes …
00:32:24.254 --> 00:32:25.718
Netanel: I remember you
Q: Sorry?
00:32:25.718 --> 00:32:27.377
N: I remember you from the last talk!
Q: No no
00:32:27.377 --> 00:32:30.508
N: Oh, you're new? Oh… smirking
Q: I'm new, I'm new…
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,
00:32:36.068 --> 00:32:39.508
Perl is a bit like cooking with my mum.
00:32:39.508 --> 00:32:46.315
Sometimes I put something into…
the… with the boiling thing…
00:32:46.315 --> 00:32:50.864
and sometimes she, sometimes I go away,
sometimes she go away
00:32:50.864 --> 00:32:53.894
and the only thing you can do is always taste.
00:32:53.894 --> 00:32:57.814
And yes, you're maybe right, Perl is a language
00:32:57.814 --> 00:33:01.822
where you never know what comes out,
but it's real cool!
00:33:01.822 --> 00:33:04.583
If you get the right response you can use it,
00:33:04.583 --> 00:33:08.678
if you use it to write web applications
I would agree.
00:33:08.678 --> 00:33:12.864
Web applications, the professional ones
at least, are not for cooking,
00:33:12.864 --> 00:33:18.466
but for doing funny things and
have some fun, I think it's a perfect language.
00:33:18.466 --> 00:33:22.296
N: I think Perl is a lot of fun.
laughter
00:33:22.296 --> 00:33:26.633
I completely agree on that. laughing
00:33:26.633 --> 00:33:29.144
Herald: Then we're gonna go over to two.
00:33:29.144 --> 00:33:33.741
Question: Was your life ever threatened
while interacting with the Perl community?
00:33:33.741 --> 00:33:35.794
laughter
N: Could you please repeat that? I …
00:33:35.794 --> 00:33:39.545
Q: Was your life ever threatened
while interacting with the Perl community?
00:33:39.545 --> 00:33:42.515
N: Definitely. Definitely,
00:33:42.515 --> 00:33:46.729
I'm getting hate mail every day,
living in fear …
00:33:46.729 --> 00:33:48.648
H: And over to the three, please.
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,
00:33:53.261 --> 00:34:00.086
N: Uh, thank you. Thank you really! Thank you.
applause
00:34:00.086 --> 00:34:06.660
Q: Brilliantly executed, but… ehm…
you spoke about Perl 5 I think.
00:34:06.660 --> 00:34:11.155
N: Yes, you are absolutely right.
Q: As some of you might know, this christmas…
00:34:11.155 --> 00:34:15.032
laughter
Q: …so tomorrow Ingo Blechschmidt
00:34:15.032 --> 00:34:20.047
is going to give a talk about how Perl 6
will make everything better
00:34:20.047 --> 00:34:24.161
and how everyone should start
using Perl 6 and…
00:34:24.161 --> 00:34:27.893
N: It also craps rainbows
Q: Yeah, of course…
00:34:27.893 --> 00:34:31.391
Q: My personal comment is:
wouldn't it have happened
00:34:31.391 --> 00:34:33.945
with a statically typed language?
00:34:33.945 --> 00:34:39.450
So I think some nice folks at Haskell
in IRC are waiting for you Perl developers
00:34:39.450 --> 00:34:44.753
to please come, join us … Thank you!
N: smirking
00:34:44.753 --> 00:34:46.456
Herald and Netanel start speaking simultaneously
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...
00:34:49.446 --> 00:34:55.526
just a quick note about Perl 6.
This talk is all about Perl 5, alright?
00:34:55.526 --> 00:35:01.108
I … Perl 6 came out a couple of days ago and …
00:35:01.108 --> 00:35:06.848
...from …at least from what I saw,
Perl 6 is to Perl as…
00:35:06.848 --> 00:35:11.932
C++ is to C. It's the same name,
but it's a whole different language.
00:35:11.932 --> 00:35:17.311
So yes, this is Perl 5.
Maybe I'll come back next year about Perl 6?
00:35:17.311 --> 00:35:19.051
laughter
Who knows?
00:35:19.051 --> 00:35:22.175
Herald: I'm looking forward to that already.
applause
00:35:22.175 --> 00:35:25.128
Herald pointing to Signal Angel
00:35:25.128 --> 00:35:31.104
Signal: Yeah… Joerd(?) wants to know:
of course you talked a lot about CGI.PM
00:35:31.104 --> 00:35:37.290
which you know was removed from repository from Perl
even before your talk last year.
00:35:37.290 --> 00:35:43.399
So what about it's replacements
from CPAN like CGI::Simple.
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,
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
00:35:55.610 --> 00:36:03.161
and I took Mojolicious and Catalyst because
they were really popular, too.
00:36:03.161 --> 00:36:08.129
So I didn't take the newest modules,
I take the most popular modules.
00:36:08.129 --> 00:36:15.973
And I think, that's the important
aspect of … deciding.
00:36:17.693 --> 00:36:20.869
Herald: And over to one, please.
00:36:20.869 --> 00:36:29.013
Questioner: Hi… I'm… part of the Perl community, and…
laughter
00:36:29.013 --> 00:36:33.169
N: Hi!
Q: But I just start with Perl – 5
00:36:33.169 --> 00:36:40.315
N: Uhh… ehm… uhh… didn't you… nhaa…
laughter
00:36:40.315 --> 00:36:44.329
Q: We use Perl for almost every module
that we have at work
00:36:44.329 --> 00:36:47.314
and this worked really fine.
N: …yeah…
00:36:47.314 --> 00:36:51.920
Q: And I don't know why you're picking Perl as language to attack.
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.
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…
00:37:05.027 --> 00:37:08.561
N: …you're right, you're right.
First of all, you're completely right,
00:37:08.561 --> 00:37:11.958
because a language shouldn't die, it should improve.
00:37:11.958 --> 00:37:16.880
C got critized and it improved.
PHP got critized and it improved.
00:37:16.880 --> 00:37:20.163
Why can't Perl be critized, too?
00:37:20.163 --> 00:37:24.238
Why is it like a code, when you say
something bad about Perl, then,
00:37:24.238 --> 00:37:27.254
I don't know, a horde of PerlMonks jumps on you?
00:37:27.254 --> 00:37:32.553
Why don't improve the language?
Don't use it in your work though,
00:37:32.553 --> 00:37:37.766
it's dangerous.
laughter and applause
00:37:39.506 --> 00:37:42.109
H: Then we're gonna jump over to five, please.
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.
00:37:48.513 --> 00:37:51.061
Is this really limited to Perl or
00:37:51.061 --> 00:37:54.169
does this apply to more or less
any dynamic language?
00:37:54.169 --> 00:37:58.640
N: As I said in one of the first few slides,
00:37:58.640 --> 00:38:03.613
some of it also applies to Python.
Specifically the thing
00:38:03.613 --> 00:38:09.867
when you can't specify what data types
your function arguments can get.
00:38:09.867 --> 00:38:15.954
But, what's unique to Perl is that
writing different code
00:38:15.954 --> 00:38:20.247
for different data types in one function
is very, very common.
00:38:20.247 --> 00:38:23.181
You can do it in every language, of course!
00:38:23.181 --> 00:38:28.276
But it is very common only in Perl!
And that is unique about it,
00:38:28.276 --> 00:38:32.501
of course besides the thing
that hashes and arrays are secure.
00:38:32.501 --> 00:38:37.116
That's of course Perls only fault.
00:38:37.116 --> 00:38:40.098
H: Good, then we're gonna go over to six, please.
00:38:40.098 --> 00:38:47.295
Q: Hey! Did you say WAT more
while preparing this talk or while holding it?
00:38:47.295 --> 00:38:56.782
N: Uhm. Both. Laughing.
Did I rant? That was the … right?
00:38:56.782 --> 00:39:00.911
Q: Did you say it more
while preparing it or while holding it?
00:39:00.911 --> 00:39:02.963
N: I'm missing your word, man, can you...
00:39:02.963 --> 00:39:11.468
Ahh, wat… WAT! Ohh… Yeah, both!
laughter
00:39:11.468 --> 00:39:14.828
H: Ok, do we have another from the internet?
00:39:14.828 --> 00:39:19.420
Signal: Does your exploit
also work in tainted mode?
00:39:19.420 --> 00:39:23.663
N: No, I believe not. No, it doesn't.
00:39:24.473 --> 00:39:26.680
H: And another one...
00:39:26.680 --> 00:39:35.537
S: Is there any Perl obfuscated code exploits
like this for Catalyst or Mojolicious?
00:39:36.137 --> 00:39:39.437
someone chuckling in audience
00:39:39.437 --> 00:39:43.409
N: I've no idea, man, maybe.
I didn't check it of course.
00:39:43.409 --> 00:39:48.082
I didn't check every module
for every exploit, I ever want to create, but
00:39:48.082 --> 00:39:55.075
on CGI.PM, which is again
the most popular CGI library, it did.
00:39:55.075 --> 00:40:02.566
So, maybe the internet
can find more exploits. I know it can.
00:40:02.566 --> 00:40:06.622
H: Bring it on. That's it?
N: That's it?
00:40:06.622 --> 00:40:07.775
Thank you!
00:40:07.775 --> 00:40:09.157
applause
00:40:09.157 --> 00:40:12.404
Herald: Thank you very much!
Netanel: Thank you!
00:40:12.404 --> 00:40:17.683
postroll music
00:40:17.683 --> 00:40:24.000
subtitles created by c3subtitles.de
in the year 2016. Join, and help us!