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
NOTE Paragraph
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.950
But the really interesting part
was the PerlMonks response.
00:02:08.950 --> 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 functionally 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.635
it also makes your code exploitable.
00:07:54.635 --> 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,
it's 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
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
affectively 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:46.121
CGI.
00:10:46.121 --> 00:10:49.375
But CGI isn't the only way to go.
00:10:49.375 --> 00:10:53.218
Bugzilla developers missed the fact
that their own system
00:10:53.218 --> 00:10:57.723
is also featuring an XMLRPC and a JSONRPC,
00:10:57.723 --> 00:11:05.388
both supporting input of non-scalar data types
like arrays and hashes!
00:11:05.388 --> 00:11:07.048
But I'm not blaming them.
00:11:07.048 --> 00:11:12.492
Yes, they forgot that there are more ways
for 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
than 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.561 --> 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
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.523
Just think how many developers assumed
the exact same thing Bugzilla assumed
00:17:10.523 --> 00:17:15.854
and treated hashes and arrays as secure data types.
00:17:15.854 --> 00:17:17.753
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.725
a list, a file descriptor or a list of file descriptors
00:17:25.725 --> 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:15.077
And to show you how basic and simple that code is,
I'll explain each line.
00:19:15.077 --> 00:19:20.993
The first line just creates a new CGI instance,
so we could get the file from the user.
00:19:20.993 --> 00:19:27.475
The second line checks if a file
has been uploaded in the "file" parameter.
00:19:27.475 --> 00:19:31.909
The third line gets the file descriptor from the CGI module,
00:19:31.909 --> 00:19:37.438
while the forth line loops through the file
and the fifths 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.871
clapping
That's it.
00:19:45.871 --> 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:35.085 --> 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.780
I'm sending a regular request,
nothing happens, just getting the content.
00:20:42.780 --> 00:20:45.713
I know, you can't see the text…
…and…
00:20:45.713 --> 00:20:49.519
when I'm sending my malicious request,
00:20:49.519 --> 00:20:52.795
something interesting will pop up.
00:20:52.901 --> 00:20:54.990
Watch closely! It's gonna be quick.
00:20:55.502 --> 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.611 --> 00:21:18.136
Alright, so… watch closely.
00:21:19.184 --> 00:21:22.772
Ohh, uuh? What was that?
00:21:24.797 --> 00:21:26.799
Let's see it again.
00:21:26.799 --> 00:21:29.528
mocking Uuuuuh?!
00:21:30.340 --> 00:21:37.335
laughter and applause
00:21:37.793 --> 00:21:41.082
Yupp, clearing throat
00:21:41.612 --> 00:21:44.650
… just a second.
00:21:45.410 --> 00:21:46.579
Nice.
00:21:46.714 --> 00:21:49.747
So you're probably asking yourself right now
00:21:49.747 --> 00:21:52.951
"What the fuck did I just see?"
laughter
00:21:52.951 --> 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.820
was me exploiting that five lines
with a remote code execution attack.
00:22:15.820 --> 00:22:20.873
So now that you saw the magic happens,
I think it's time for some explanations.
00:22:20.873 --> 00:22:22.917
The first line, responsible for checking
00:22:22.917 --> 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:34.013
Instead of checking if the "file"
parameter is an uploaded file,
00:22:34.013 --> 00:22:39.540
it checks if one of it values is a file descriptor.
00:22:39.540 --> 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:51.196
laughter
00:22:51.196 --> 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.616 --> 00:23:16.165
Creative fellows those guys are.
00:23:16.165 --> 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.384
But what happens when we try to get
the "file" parameter value?
00:23:26.384 --> 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:41.176
param() returns a list containing all the values we sent:
00:23:41.176 --> 00:23:44.365
the file we've uploaded and our scalar value.
00:23:44.365 --> 00:23:49.521
But the "file" variable
can't contain two values, right?
00:23:49.521 --> 00:23:55.641
So instead of converting
the returned list into an array
00:23:55.641 --> 00:23:59.781
Perl only uses the first element of that list.
00:23:59.781 --> 00:24:05.564
So if we'll send our scalar values
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:20.013
Which means, that $file
is now a regular string!
00:24:20.013 --> 00:24:22.114
in high pitched voice: WAT?
00:24:22.618 --> 00:24:26.127
But what happens to this operator
when we use a string
00:24:26.127 --> 00:24:29.025
instead of a file descriptor?
00:24:29.025 --> 00:24:32.962
Well, the brackets operator
doesn't work with strings, right?
00:24:32.962 --> 00:24:36.958
It works with file descriptors,
why should it work with strings?
00:24:36.958 --> 00:24:39.580
Well, that appears true
00:24:39.580 --> 00:24:42.817
unless that string is "ARGV".
00:24:42.817 --> 00:24:47.644
laughter and applause
00:24:55.860 --> 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.953
In that case the brackets operator, listen closely,
00:25:04.953 --> 00:25:07.988
loops through the script arguments,
00:25:07.988 --> 00:25:12.887
which in CGI comes directly from the
query string instead the command line,
00:25:12.887 --> 00:25:18.844
and it treats them as file paths,
inserting each one into an open() call!
00:25:18.844 --> 00:25:20.497
again laughter
00:25:20.497 --> 00:25:22.655
WAT?
00:25:25.952 --> 00:25:29.485
Yeah, that made sense on 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:40.829
we can display the content
of any file on the server.
00:25:40.829 --> 00:25:42.344
But that's not the end,
as we haven't executed code yet.
00:25:44.674 --> 00:25:49.168
To execute code, we have
to look at the open() function.
00:25:49.168 --> 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.284
open() is responsible for opening
a file descriptor to a given file.
00:26:03.284 --> 00:26:06.544
Unless a "pipe" character is added
00:26:06.544 --> 00:26:09.486
to the end of the string,
laughter
00:26:09.486 --> 00:26:13.819
in that case instead of opening the file,
00:26:13.819 --> 00:26:16.828
it executes it…
applause rising
00:26:16.828 --> 00:26:22.796
…acting as an exec() call!
more applause
00:26:23.096 --> 00:26:29.172
So … when we send our exploit,
00:26:29.172 --> 00:26:34.631
containing our uploaded file,
the "ARGV" malicious scalar value,
00:26:34.631 --> 00:26:38.045
and the ipconfig command followed by a pipe
00:26:38.045 --> 00:26:42.697
this is what we get.
WAT?
00:26:42.697 --> 00:26:46.639
WAT?
applause
00:26:49.585 --> 00:26:56.705
I know, I'm shocked too, but I'm not done yet.
laughter
00:26:56.705 --> 00:27:01.193
Truth be told, I didn't write that code.
00:27:01.193 --> 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.867
But, I'm not blaming CGI.PM developers.
00:27:36.867 --> 00:27:41.365
Nor am I blaming developers
who copied from CGI.PM examples.
00:27:41.365 --> 00:27:47.443
After all, who could have known
that this is what this code will do?
00:27:47.443 --> 00:27:49.657
This is how it could be exploited?
00:27:49.657 --> 00:27:54.961
There's no exec calls,
the file is not saved anywhere,
00:27:54.961 --> 00:27:58.493
and we're only using a "print".
00:27:58.493 --> 00:28:07.823
The sole responsible for this mess,
is the Perl language.
00:28:07.823 --> 00:28:11.722
Perl is the one silently expanding lists,
00:28:11.722 --> 00:28:14.832
Perl is the one mixing up your data types,
00:28:14.832 --> 00:28:20.064
Perl is the one executing user input
with no exec calls,
00:28:20.064 --> 00:28:23.010
Perl is the problem,
00:28:23.010 --> 00:28:26.122
not its developers.
applause rising
00:28:26.122 --> 00:28:32.159
And until this god-damned, bizarre,
dangerous language is fixed,
00:28:32.159 --> 00:28:34.536
you could only
stop
00:28:34.536 --> 00:28:35.629
using
00:28:35.629 --> 00:28:39.867
Perl!
00:28:39.867 --> 00:28:47.005
Thank you!
more applause
00:28:59.485 --> 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.594
Herald: And I have the funny feeling,
we will have some questions now.
00:29:08.594 --> 00:29:12.384
Ok, so we have some microphones here.
Please queue up.
00:29:12.384 --> 00:29:18.469
Please do not shout in, because we need
to record it on the stream.
00:29:18.469 --> 00:29:19.936
Well, here we go.
00:29:19.936 --> 00:29:22.956
And we also have some questions
from the internet, don't we?
00:29:22.956 --> 00:29:27.794
Signal angel: Oh yes, we do!
laughter
00:29:27.794 --> 00:29:30.413
Signal: But before we come
to the technical questions,
00:29:30.413 --> 00:29:33.691
the IRC wants you to know,
what you did to it:
00:29:33.691 --> 00:29:37.135
it felt like there were explosions
and camels everywhere.
00:29:37.135 --> 00:29:39.915
Netanel laughing: That's the point
00:29:39.915 --> 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.843
Netanel: I think Google has it?
more laughter
00:29:49.843 --> 00:29:54.336
Just there search camels.
00:29:54.336 --> 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.239 --> 00:30:28.428
well, how will I phrase it …
00:30:29.184 --> 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:38.071 --> 00:30:40.204
Don't worry, have it right here.
00:30:44.644 --> 00:30:49.480
But really, trusting user input
is always a bad idea
00:30:49.480 --> 00:30:52.071
and most developers know it.
00:30:52.071 --> 00:30:54.521
The problem is, that…
00:30:54.521 --> 00:30:57.498
well, at least from the code
I saw written in Perl,
00:30:57.498 --> 00:31:00.601
and that's a lot of code, trust me
00:31:00.601 --> 00:31:05.154
…is that hashes and arrays
are almost always considered secured
00:31:05.154 --> 00:31:09.543
as they supposedly can't be
created by user input, as I said.
00:31:09.543 --> 00:31:17.966
But, when you're expecting your user input
to be a scalar, a string or even a list
00:31:17.966 --> 00:31:26.256
and instead you get a hash from unexpected
directions, you get confused.
00:31:26.256 --> 00:31:31.149
And you can't always
live in the fear of not knowing
00:31:31.149 --> 00:31:33.963
what data type you're trying to handle.
00:31:33.963 --> 00:31:40.575
Well, not trusting scalar data types
is a wise decision, because it's dangerous.
00:31:40.575 --> 00:31:46.369
But not trusting your hashes,
as well not trusting your arrays?
00:31:46.369 --> 00:31:49.901
What's next? Not trusting your own code?
00:31:49.901 --> 00:31:54.754
You just can't expect anything
to really work as it should.
00:31:54.754 --> 00:31:57.584
When you're writing Perl,
00:31:57.584 --> 00:32:04.629
you are constantly attacked
by all these different directions.
00:32:04.629 --> 00:32:09.029
And even the data type direction is a problem now.
00:32:09.029 --> 00:32:12.962
I hope that answers the question
beside the slide.
00:32:12.962 --> 00:32:16.695
Herald: Well, then we're gonna go over
and start with number one
00:32:16.695 --> 00:32:20.074
Questioner: So thank you for opening our eyes.
00:32:20.074 --> 00:32:24.354
Even I use Perl, I would say,
for cooking and yes …
00:32:24.354 --> 00:32:25.788
Netanel: I remember you
Q: Sorry?
00:32:25.788 --> 00:32:27.377
N: I remember you from the last talk!
Q: No no
00:32:27.377 --> 00:32:31.028
N: Oh, you're new? Oh… smirking
Q: I'm new, I'm new…
00:32:31.028 --> 00:32:36.288
Q: So… I can't say, I'm not guilty of that,
but I still would say yes,
00:32:36.288 --> 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:54.374
and the only thing you can do is always taste.
00:32:54.374 --> 00:32:58.514
And yes, you're maybe right, Perl is a language
00:32:58.514 --> 00:33:02.332
where you never know what comes out,
but it's real cool!
00:33:02.332 --> 00:33:04.903
If you get the right response you can use it,
00:33:04.903 --> 00:33:09.088
if you use it to write web applications
I would agree.
00:33:09.088 --> 00:33:13.464
Web applications, the professional ones
at least, are not for cooking,
00:33:13.464 --> 00:33:18.856
but for doing funny things and
have some fun, I think it's a perfect language.
00:33:18.856 --> 00:33:22.626
N: I think Perl is a lot of fun.
laughter
00:33:22.626 --> 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:36.064
laughter
N: Could you please repeat that? I …
00:33:36.064 --> 00:33:39.995
Q: Was your life ever threatened
while interacting with the Perl community?
00:33:39.995 --> 00:33:43.145
N: Definitely. Definitely,
00:33:43.145 --> 00:33:47.109
I'm getting hate mail every day,
living in fear …
00:33:47.109 --> 00:33:48.928
H: And over to the three please
00:33:48.928 --> 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.436
N: Uh, thank you. Thank you really! Thank you.
applause
00:34:00.436 --> 00:34:07.010
Q: Brilliantly executed, but… ehm…
you spoke about Perl 5 I think
00:34:07.010 --> 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.472
laughter
Q: …so tomorrow Ingo Blechschmidt
00:34:15.472 --> 00:34:20.047
will give a talk about how Perl 6
will make everything better
00:34:20.047 --> 00:34:24.162
and how everyone should start
using Perl 6 and…
00:34:24.162 --> 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.570
So I think some nice folks at Haskell
in IRC are waiting for you Perl developers
00:34:39.570 --> 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.886
H: …sorry, to answer first, where am I… sorry
N: I… no thanks… unclear
00:34:49.886 --> 00:34:55.856
just a quick note about Perl 6.
This talk is all about Perl 5, alright?
00:34:55.856 --> 00:34:59.478
I … Perl 6 came out a couple of days ago and …
00:34:59.478 --> 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:23.415
Herald: I'm looking forward to that already
applause
00:35:23.415 --> 00:35:25.578
Herald pointing to signal angel
00:35:25.578 --> 00:35:31.574
Signal: Yeah… Joerd(?) wants to know:
of course you talked a lot about CGI.PM
00:35:31.574 --> 00:35:37.750
which you know was removed from repository from Perl
even before your talk last year.
00:35:37.750 --> 00:35:43.729
So what about it's replacements
from CPAN like CGI::Simple.
00:35:43.729 --> 00:35:48.505
Netanel: I don't know, I haven't checked it.
When I decided on which modules to check,
00:35:48.505 --> 00:35:55.990
I took CGI.PM because even though it is old,
it is the most popular in the world as of today
00:35:55.990 --> 00:36:03.561
and I took Mojolicious and Catalyst because
they were really popular, too.
00:36:03.561 --> 00:36:08.389
So I didn't take the newest modules,
I take the most popular modules.
00:36:08.389 --> 00:36:14.513
And I think, that's the important
aspect of … deciding.
00:36:14.513 --> 00:36:20.599
Herald: and over to one please
00:36:20.599 --> 00:36:29.133
Questioner: Hi… uhm… part of the Perl community, and…
laughter
00:36:29.133 --> 00:36:33.169
N: Hi!
Q: But I just start with Perl – 5
00:36:33.169 --> 00:36:40.715
N: Uhh… ehm… uhh… didn't you… nhaa…
laughter
00:36:40.715 --> 00:36:44.829
Q: We use Perl for almost every modules
that we have at work
00:36:44.829 --> 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.469
It's a really old language, it's also every language
that we can pick, that has problems.
00:36:59.469 --> 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.881
N: …you're right, you're right.
First of all, you're completely right,
00:37:08.881 --> 00:37:11.958
because a language shouldn't die, it should improve.
00:37:11.958 --> 00:37:17.040
C got critized and it improved.
PHP got critized and it improved.
00:37:17.040 --> 00:37:20.563
Why can't Perl be critized, too?
00:37:20.563 --> 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.684
I don't know, a horde of PerlMonks jumps on you?
00:37:27.684 --> 00:37:32.643
Why don't improve the language?
Don't use it in your work though,
00:37:32.643 --> 00:37:37.766
it's dangerous.
laughter and applause
00:37:39.896 --> 00:37:41.799
H: Then we gonna jump over to five please
00:37:41.799 --> 00:37:49.273
Q: Hi. I'm not a Perl developer,
but I use a lot of Ruby and Python.
00:37:49.273 --> 00:37:51.551
Is this really limited to Perl or
00:37:51.551 --> 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:02.483
some of it also applys to Python.
Specifically the thing
00:38:02.483 --> 00:38:10.127
when you can't specify what data types
your function arguments can get.
00:38:10.127 --> 00:38:16.074
But, what's unique to Perl is that
writing different code
00:38:16.074 --> 00:38:20.517
for different data types in one function
is very, very common.
00:38:20.517 --> 00:38:23.181
You can do it in every language, of course!
00:38:23.181 --> 00:38:28.686
But it is very common only in Perl!
And that is unique about it,
00:38:28.686 --> 00:38:32.881
of course besides the thing
that hashes and arrays are secure.
00:38:32.881 --> 00:38:37.016
That's of course Perls only fault.
00:38:37.016 --> 00:38:40.358
H: Good, than we gonna go over to six please
00:38:40.358 --> 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:54.672
N: Uhm. Both. Laughing.
Did I rant? That was the … right?
00:38:54.672 --> 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.
00:39:02.963 --> 00:39:12.018
Ahh, wat… WAT! Ohh… Yeah, both!
laughter
00:39:12.018 --> 00:39:14.828
H: Ok, do we have another from the internet?
00:39:14.828 --> 00:39:19.290
Signal: Does your exploit
also work in tainted mode?
00:39:19.290 --> 00:39:23.583
N: No, I believe not. No, it doesn't.
00:39:23.583 --> 00:39:26.470
H: And another one
00:39:26.470 --> 00:39:36.487
S: Is there any Perl obfuscated code exploits
like this for Catalyst or Mojolicious?
00:39:36.487 --> 00:39:43.729
N: I've no idea, man maybe.
I didn't check it of course.
00:39:43.729 --> 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:54.675
on CGI.PM, which is again
the most popular CGI library, it did.
00:39:54.675 --> 00:40:01.866
So, maybe the internet
can find more exploits. I know it can.
00:40:01.866 --> 00:40:06.622
H: Bring it on. That's it?
N: That's it?
00:40:06.622 --> 00:40:09.575
Thank you!
00:40:09.575 --> 00:40:11.407
applause
00:40:11.407 --> 00:40:13.084
Herald: Thank you very much!
Netanel: Thank you!
00:40:13.084 --> 00:40:23.033
postroll music