Return to Video

Netanel Rubin: The Perl Jam 2

  • 0:00 - 0:09
    preroll music
  • 0:10 - 0:13
    Herald: And I'm gonna introduce Netanel Rubin.
  • 0:14 - 0:19
    He has been here last year with a talk
    that he got some bashing for.
  • 0:19 - 0:24
    This year he's gonna ensure,
    it's not the programmer's fault,
  • 0:24 - 0:27
    it's the language itself. No?
  • 0:28 - 0:30
    Well, here we go, well here we go.
  • 0:30 - 0:34
    Netanel, he is working for
    PerimeterX in Tel Aviv,
  • 0:34 - 0:35
    welcome on stage, your talk!
  • 0:36 - 0:38
    Netanel: Thank you very much, applause
  • 0:38 - 0:41
    thank you, thank you!
  • 0:45 - 0:53
    Last year I stood right on this very stage
    and I talked about several of Perl's
  • 0:53 - 0:56
    less thought out "features".
  • 0:56 - 1:05
    Now, I got some bashing from the Perl community,
    but mainly what happened was,
  • 1:05 - 1:10
    that the Perl community completely rejected my talk
    claiming that the language
  • 1:10 - 1:16
    is completely fine and great
    and all of this stuff are just improvements.
  • 1:18 - 1:21
    It was clear I had to give another talk.
  • 1:21 - 1:29
    This is why I'm very proud to present
    "Perl Jam 2 – The Camel strikes back"!
  • 1:29 - 1:34
    applause
  • 1:34 - 1:36
    Thank you
  • 1:38 - 1:46
    At the last talk, I showed that "lists" are expressions,
    used in… many confusing ways.
  • 1:46 - 1:53
    I also showed how CGI parameters can create lists,
    directly from user input.
  • 1:53 - 2:00
    But most importantly, I showed
    that when these two things combine, shit happens.
  • 2:02 - 2:04
    Great
  • 2:04 - 2:09
    But the really interesting part
    was the PerlMonks response.
  • 2:09 - 2:16
    The Perl community…
    laughter
  • 2:19 - 2:24
    The Perl community had a long discussion
    at the PerlMonks forum
  • 2:24 - 2:29
    that started with the words
    "Sad news from Germany".
  • 2:29 - 2:32
    A bit dramatic, but who am I to judge?
  • 2:32 - 2:39
    So, after a long, long discussion,
    they came to the unavoidable conclusion
  • 2:39 - 2:48
    that my talk was, in fact, a "polemic shit",
    and they should all just "piss on it". Wink.
  • 2:50 - 2:56
    They also realized I'm just a
    "script kiddie preaching to other script kiddies",
  • 2:56 - 3:01
    and not just any script kiddies, the CCC audience is a
  • 3:01 - 3:06
    "heterogeneous group of chaotic punks
    who love to see themselves in the hacker
  • 3:06 - 3:18
    image of Hollywood media".
    applause and whistling from audience
  • 3:18 - 3:24
    What hacker image?
    What are they talking about?
  • 3:24 - 3:26
    We have no hacker image.
  • 3:26 - 3:34
    Anyway, it got quite surreal, as in some point
    they even critized
  • 3:34 - 3:42
    the "crude use of propaganda
    in the camel images". WAT?
  • 3:42 - 3:46
    laughing
    applause
  • 3:46 - 3:51
    Propaganda in the camel images. Alright.
  • 3:51 - 3:58
    Anyway, they completely rejected the entire talk,
    even though the technical points were valid.
  • 3:58 - 4:04
    They rejected it because of
    some jokes and camel images.
  • 4:04 - 4:13
    But still, they got so offended they just threw
    lame excuses as to why their language sucks.
  • 4:13 - 4:20
    Two of these lame excuses were
    repeated over and over again.
  • 4:20 - 4:25
    The first was that I should
    read the fucking manual, which is funny
  • 4:25 - 4:27
    because I thought I was the only one who did…
  • 4:27 - 4:29
    laughter
  • 4:29 - 4:31
    …and the second is that
  • 4:31 - 4:35
    I'm using the old, ancient Perl,
    and not the new, modern Perl.
  • 4:35 - 4:40
    more laughter
  • 4:41 - 4:46
    Remember these two points carefully
    as I'll later break them in the presentation.
  • 4:46 - 4:52
    But, enough with the intro,
    let's start with the new madness.
  • 4:52 - 4:59
    So, Perl allows declaring variables
    without specifying their data type.
  • 4:59 - 5:03
    Of course, this functionality exists
    in many dynamic languages,
  • 5:03 - 5:07
    and is completely fine and very convenient.
  • 5:07 - 5:13
    But, as usual, Perl took it
    to a whole different level.
  • 5:13 - 5:19
    Perl went as far as removing
    data type declarations from function arguments.
  • 5:19 - 5:21
    You can see that in this example,
  • 5:21 - 5:28
    I'm just receiving two different arguments
    without knowing what type they are.
  • 5:28 - 5:30
    Let me be clear about that,
  • 5:30 - 5:35
    you don't get to choose whether you want
    to specify argument data types or not,
  • 5:35 - 5:41
    you can't specify
    what data types you're expecting to get.
  • 5:41 - 5:45
    So even if I built a function
    that only works with strings,
  • 5:45 - 5:49
    I have no way of forcing that
    at the function declaration.
  • 5:49 - 5:51
    Now that's annoying.
  • 5:51 - 5:57
    But, the real kicker
    is how this feature is used.
  • 5:57 - 6:04
    Apparently, it is very common to write
    two completely different blocks of code,
  • 6:04 - 6:08
    one that handles scalar types,
    like strings or ints,
  • 6:08 - 6:13
    and one that handles non-scalar types,
    like arrays or hashes.
  • 6:13 - 6:15
    Let me repeat that:
  • 6:15 - 6:24
    Writing multiple code, for multiple data-types,
    in one function, is a Perl standard.
  • 6:24 - 6:32
    And that's sad. You shouldn't write redundant code
    because the language lacks the capability
  • 6:32 - 6:36
    of letting you decide
    which cases you don't want to handle.
  • 6:36 - 6:40
    By the way, Python doesn't let you
    declare your function argument data types too,
  • 6:40 - 6:46
    but unlike Perl, writing redundant code
    to cover that up
  • 6:46 - 6:50
    is definitely not the standard.
  • 6:50 - 6:55
    Anyway, sad as this may be,
    this Perl convention is not dangerous.
  • 6:55 - 6:57
    The dangerous part begins
  • 6:57 - 7:03
    when hashes and arrays
    are considered as "secure" data types,
  • 7:03 - 7:08
    mainly because they can't be created
    by user input.
  • 7:08 - 7:10
    This results in this kind of code,
  • 7:10 - 7:14
    where if the function argument
    is a hash, for example,
  • 7:14 - 7:19
    it is used un-escaped in dangerous functions.
  • 7:19 - 7:26
    Hashes, specifically, are considered so secure,
    that even if you use "taint mode",
  • 7:26 - 7:28
    which is some kind of safe mode for Perl,
  • 7:28 - 7:34
    hash keys are not tainted, meaning
    that, even if you use safe mode,
  • 7:34 - 7:37
    they can be still used in dangerous functions
  • 7:37 - 7:42
    without any validation,
    as opposed to other data types.
  • 7:42 - 7:47
    Now this kind of code appears a lot
    in Perl applications,
  • 7:47 - 7:50
    and apart from the many bugs
    this method can cause,
  • 7:50 - 7:54
    it also makes your code exploitable.
  • 7:54 - 7:58
    So we know function arguments are of unknown data type.
  • 7:58 - 8:03
    And we know developers treat hashes and arrays
    as "secure" data types,
  • 8:03 - 8:07
    inserting their values into dangerous functions.
  • 8:07 - 8:09
    But this practices isn't something
  • 8:09 - 8:14
    that was created a long time ago,
    and found only on redundant code.
  • 8:14 - 8:20
    Because of how the language is built,
    its supposedly restriction-less type of developing,
  • 8:20 - 8:27
    even now it is the natural way to code
    when you're using Perl.
  • 8:27 - 8:31
    And that's the real problem:
    Perl is like a shotgun,
  • 8:31 - 8:37
    with one trigger you know about
    and a dozen that you don't.
  • 8:37 - 8:41
    So for now, we know
    that if we'll somehow manage
  • 8:41 - 8:46
    to create these "secure" data types,
    with our user input,
  • 8:46 - 8:49
    we could exploit the code.
  • 8:49 - 8:54
    So the only question remaining really
    is what are we gonna exploit?
  • 8:54 - 8:58
    And the answer, again,
    is Bugzilla.
  • 8:58 - 9:03
    laughter
  • 9:03 - 9:09
    Like every other Perl project,
    Bugzilla is heavily using functions
  • 9:09 - 9:13
    that treat scalar and non-scalar
    argument types very differently.
  • 9:13 - 9:17
    This is one of them: the load_from_DB function is responsible
  • 9:17 - 9:22
    for extracting object specific data
    out of the database.
  • 9:22 - 9:29
    Like I just said, it treats scalars,
    and in this case hashes, very differently.
  • 9:29 - 9:34
    If the function argument is a hash,
    it takes one of its values
  • 9:34 - 9:40
    and inserts it as is, un-escaped,
    into an SQL statement.
  • 9:40 - 9:45
    Again, because hashes
    are considered secure,
  • 9:45 - 9:48
    so there's no point of escaping them.
  • 9:48 - 9:51
    On the other hand,
    if the argument is a scalar,
  • 9:51 - 9:56
    it converts it into an integer
    and only then use it in an SQL statement.
  • 9:56 - 9:59
    Because scalar values are not secure.
  • 9:59 - 10:01
    hashes: secure
  • 10:01 - 10:03
    scalar: not secure
  • 10:03 - 10:06
    This means that if we could control
    the function argument entirely,
  • 10:06 - 10:11
    including its data type,
    we could control the SQL query,
  • 10:11 - 10:14
    effectively exploiting an SQL injection attack,
  • 10:14 - 10:18
    by inserting a hash
    containing that specific value.
  • 10:18 - 10:21
    But…
  • 10:21 - 10:27
    CGI input doesn't allow hashes, right?
  • 10:27 - 10:32
    The whole Perl security module
    is built on that assumption.
  • 10:32 - 10:37
    The problem is that, like us,
    developers are assuming
  • 10:37 - 10:42
    CGI input is the only input method available.
  • 10:42 - 10:46
    CGI.
  • 10:46 - 10:49
    But CGI isn't the only way to go.
  • 10:49 - 10:53
    Bugzilla developers missed the fact
    that their own system
  • 10:53 - 10:58
    is also featuring an XMLRPC and a JSONRPC,
  • 10:58 - 11:05
    both supporting input of non-scalar data types
    like arrays and hashes!
  • 11:05 - 11:06
    But I'm not blaming them.
  • 11:06 - 11:12
    Yes, they forgot that there are more ways
    for a user to input than CGI,
  • 11:12 - 11:17
    but still, they're just the product
    of how Perl programming is taught,
  • 11:17 - 11:21
    filled with false assumptions and inconsistencies.
  • 11:21 - 11:26
    Expecting anything but this kind
    of security problems is just naive.
  • 11:26 - 11:29
    But back to the vulnerability.
  • 11:29 - 11:30
    If we'll use one of these RPCs,
  • 11:30 - 11:34
    sending our input parameter with a malicious hash,
  • 11:34 - 11:37
    instead of just a regular numeric parameter,
  • 11:37 - 11:40
    we will be able to exploit the SQL injection!
  • 11:40 - 11:44
    So, if we'll send this regular request,
    using the JSONRPC interface,
  • 11:44 - 11:49
    the number 1 will be used
    as the ID of a bug to extract,
  • 11:49 - 11:51
    but if we'll send this request,
  • 11:51 - 11:54
    where instead of an integer we'll supply a hash,
  • 11:54 - 11:57
    then suddenly we will be able
    to inject any SQL we'd like
  • 11:57 - 12:03
    into that statement, effectively
    compromising the entire database.
  • 12:03 - 12:07
    Now when you look at this request, you realize
  • 12:07 - 12:11
    that this is not a sophisticated vulnerability.
  • 12:11 - 12:21
    All I did was just change the input data type
    from scalar in this case to a hash,
  • 12:21 - 12:25
    and that's it, the system is compromised.
  • 12:25 - 12:29
    It was so heavily built on the assumption
  • 12:29 - 12:32
    that hashes are secure, that it offered me
  • 12:32 - 12:37
    almost unlimited access security wise.
  • 12:37 - 12:42
    The funny thing about that is, that
    although it's so simple,
  • 12:42 - 12:46
    the attack has existed for over 5 years.
  • 12:46 - 12:49
    That's the year I was born in.
  • 12:49 - 12:55
    So, we now proved this "unknown-argument-type" feature
  • 12:55 - 12:58
    is a huge source for problems.
  • 12:58 - 13:03
    We also know writing different code
    to handle different data types
  • 13:03 - 13:07
    just causes a lot of false assumptions.
  • 13:07 - 13:14
    But most importantly, treating non-scalar
    data types such as hashes as "secure",
  • 13:14 - 13:17
    just because they supposedly can't be created by the user,
  • 13:17 - 13:23
    is very, very, BAD. Just ask Bugzilla.
  • 13:23 - 13:30
    But the shocking part really, is that, again,
    this is the Perl Standard!
  • 13:30 - 13:34
    You're not expected to use it, you have to
  • 13:34 - 13:37
    as you don't have any other choice.
  • 13:37 - 13:44
    This security mess
    is a fundamental part of the language.
  • 13:44 - 13:52
    The problem is that creating non-scalar data types
    is impossible in some cases.
  • 13:52 - 13:55
    We can't rely that some kind of RPC
  • 13:55 - 13:59
    will exist in the code
    and support different data types,
  • 13:59 - 14:05
    and we can't create data types
    using regular user input… Right?
  • 14:05 - 14:07
    Well, let's have a look at
  • 14:07 - 14:11
    how different CGI modules
    handle different kind of input.
  • 14:11 - 14:14
    First, we'll take the most trivial scenario.
  • 14:14 - 14:18
    A single valued parameter,
    something that looks like this request,
  • 14:18 - 14:22
    where the "foo" parameter
    is assigned the string "bar".
  • 14:22 - 14:27
    In this case, a scalar is created on all three CGI modules,
  • 14:27 - 14:31
    which doesn't really help us,
    but is pretty much what we've expected.
  • 14:31 - 14:33
    It is secure.
  • 14:33 - 14:38
    But what happens if instead of
    sending a single-valued parameter,
  • 14:38 - 14:42
    we'll send a multi-valued parameter,
    like in this request?
  • 14:42 - 14:46
    Now things are starting to get complicated.
  • 14:46 - 14:51
    On CGI.PM, as we already know,
    a list is created,
  • 14:51 - 14:55
    which is very useful for us,
    but not what we're after.
  • 14:55 - 15:02
    Let's have a look at
    what the "new" Perl modules are creating.
  • 15:02 - 15:10
    We'll see that both of them are returning
    arrays containing our values.
  • 15:10 - 15:15
    Arrays! WAT?
  • 15:15 - 15:19
    I thought you can't create
    these kind of data types with regular input,
  • 15:19 - 15:22
    after all, they're considered safe.
  • 15:22 - 15:24
    But let's continue.
  • 15:24 - 15:28
    What happens if instead of sending a regular value,
  • 15:28 - 15:32
    we'll try and upload a file in that parameter?
  • 15:32 - 15:35
    Now things are really getting out of hand,
  • 15:35 - 15:44
    because CGI.PM now returns a file descriptor,
    and Catalyst and Mojolicious returns a hash.
  • 15:44 - 15:46
    WAT?
  • 15:46 - 15:54
    We just exploited
    the most popular Perl project in the world
  • 15:54 - 15:58
    because they assumed hashes can't be created by the user,
  • 15:58 - 16:03
    and now we're finding out
    that not only we can create hashes,
  • 16:03 - 16:05
    it is a god-damned feature?!
  • 16:05 - 16:07
    That's insane!
  • 16:07 - 16:12
    The whole Perl security standard is built on that assumption
  • 16:12 - 16:15
    that users can't create non-scalar data-types
  • 16:15 - 16:20
    and now suddenly these are features?
  • 16:20 - 16:28
    But let's send a multi-file upload request
    as in several files in the same parameter.
  • 16:28 - 16:34
    Watch closely, because this is where it gets ridiculous.
  • 16:34 - 16:39
    Now, CGI.PM returns a list of File Descriptors,
  • 16:39 - 16:43
    Catalyst returns a list of Hashes
  • 16:43 - 16:49
    and Mojolicious returns an Array of Objects! WAT?!
  • 16:49 - 16:53
    laughter and applause
  • 16:53 - 16:58
    Almost any Perl project in the world
  • 16:58 - 17:03
    uses one of these modules
    for parsing CGI input.
  • 17:03 - 17:11
    Just think how many developers assumed
    the exact same thing Bugzilla assumed
  • 17:11 - 17:16
    and treated hashes and arrays as secure data types.
  • 17:16 - 17:18
    So if you're using CGI.PM,
  • 17:18 - 17:21
    instead of the expected scalar value you could be getting
  • 17:21 - 17:26
    a list, a file descriptor or a list of file descriptors
  • 17:26 - 17:28
    and if you're using Catalyst
  • 17:28 - 17:31
    you could receive a scalar, an array, a hash or a list,
  • 17:31 - 17:35
    which is basically any data type.
  • 17:36 - 17:39
    So expecting your function… yeah
  • 17:40 - 17:44
    audience chuckling
  • 17:46 - 17:54
    So expecting your function arguments
    to be of a specific data type is false.
  • 17:54 - 18:00
    Expecting hashes and arrays to be secure is also false.
  • 18:00 - 18:03
    Expecting scalar only user input
  • 18:03 - 18:07
    is a major false.
  • 18:07 - 18:13
    And to be honest, it seems that in Perl expecting is false!
  • 18:13 - 18:17
    laughter and applause
  • 18:21 - 18:26
    You just can't expect anything
  • 18:26 - 18:32
    even the most basic of things
    such as what data type your variable is made of.
  • 18:32 - 18:36
    You just don't know.
  • 18:38 - 18:43
    But I felt all of these points will
    go un-noticed
  • 18:43 - 18:49
    without an extreme example of Perl's absurdity.
  • 18:49 - 18:53
    So I found an extreme example.
  • 18:53 - 18:55
    One that will clearly show
  • 18:55 - 18:59
    the ridiculous nature of the language.
  • 18:59 - 19:01
    And this is it:
  • 19:01 - 19:07
    All this code does is print an uploaded file's content.
  • 19:07 - 19:15
    And to show you how basic and simple that code is,
    I'll explain each line.
  • 19:15 - 19:20
    The first line just creates a new CGI instance,
    so we could get the file from the user.
  • 19:20 - 19:27
    The second line checks if a file
    has been uploaded in the "file" parameter.
  • 19:27 - 19:32
    The third line gets the file descriptor from the CGI module,
  • 19:32 - 19:37
    while the fourth line loops through the file
    and the fifth prints it.
  • 19:37 - 19:44
    That's it. Again: all this code does
    is get a file and print it.
  • 19:44 - 19:46
    clapping
    That's it.
  • 19:46 - 19:52
    A user has uploaded a file to the server
    and the server is just returning its content.
  • 19:52 - 19:56
    It's not saving it anywhere,
    it's not moving it anywhere,
  • 19:56 - 19:59
    it just prints its content.
  • 19:59 - 20:04
    There should be absolutely
    nothing dangerous in this code,
  • 20:04 - 20:07
    it contains literally five lines.
  • 20:07 - 20:10
    Yet, it's demo time.
  • 20:10 - 20:12
    laughter
  • 20:12 - 20:15
    So trust me, you don't need to see the text,
  • 20:15 - 20:20
    all you need to see is that
    when I'm sending a regular request nothing happens.
  • 20:20 - 20:24
    When I send it now, nothing happens,
    I'm just getting the file content.
  • 20:24 - 20:26
    We're having fun, you don't see the burp…
  • 20:26 - 20:30
    Now, nice. Okay.
  • 20:30 - 20:34
    So…
    …L't me just…
  • 20:35 - 20:37
    …I have no idea where my mouse is, okay.
  • 20:37 - 20:38
    So…
  • 20:39 - 20:42
    I'm sending a regular request,
    nothing happens, just getting the content.
  • 20:42 - 20:46
    I know, you can't see the text…
    …and…
  • 20:46 - 20:50
    when I'm sending my malicious request,
  • 20:50 - 20:52
    something interesting will pop up.
  • 20:52 - 20:55
    Watch closely! It's gonna be quick.
  • 20:55 - 20:57
    Ready?
  • 20:58 - 21:01
    Oh, you haven't seen it, it's on the different screen.
  • 21:01 - 21:07
    Just a second… oh… duplicate…
  • 21:08 - 21:09
    (from audience): … magnify it!
  • 21:09 - 21:12
    Netanel: I'll magnify you!
  • 21:12 - 21:14
    laughter
  • 21:14 - 21:18
    Alright, so… watch closely.
  • 21:19 - 21:23
    Ohh, uuh? What was that?
  • 21:24 - 21:27
    Let's see it again.
  • 21:27 - 21:30
    mocking Uuuuuh?!
  • 21:30 - 21:36
    laughter and applause
  • 21:37 - 21:40
    Yupp, clearing throat
  • 21:41 - 21:45
    … just a second.
  • 21:45 - 21:46
    Nice.
  • 21:46 - 21:49
    So you're probably asking yourself right now
  • 21:49 - 21:52
    "What the fuck did I just see?"
    laughter
  • 21:52 - 21:56
    "Was that a terminal screen?"
  • 21:56 - 22:00
    And the answer is … "Yes"
    Yes, it was,
  • 22:00 - 22:04
    specifically the "ipconfig" command output.
  • 22:04 - 22:07
    Or in other words: What you just saw
  • 22:07 - 22:15
    was me exploiting that five lines
    with a remote code execution attack.
  • 22:15 - 22:21
    So now that you saw the magic happens,
    I think it's time for some explanations.
  • 22:21 - 22:22
    The first line, responsible for checking
  • 22:22 - 22:26
    if a file has been uploaded in the "file" parameter,
  • 22:26 - 22:30
    doesn't exactly do as it says.
  • 22:30 - 22:34
    Instead of checking if the "file"
    parameter is an uploaded file,
  • 22:34 - 22:39
    it checks if one of its values is a file descriptor.
  • 22:39 - 22:45
    Let me clarify that, instead of checking
    if the parameter is only a file,
  • 22:45 - 22:49
    it checks if the parameter is also a file.
  • 22:49 - 22:50
    laughter
  • 22:50 - 22:53
    Meaning that uploading a file
  • 22:53 - 22:57
    and assigning another scalar value to the same parameter
  • 22:57 - 23:00
    will still work and bypass the check!
  • 23:00 - 23:01
    WAT?
  • 23:01 - 23:06
    more laughter and applause
  • 23:12 - 23:16
    Creative fellows those guys are.
  • 23:16 - 23:22
    So now we can assign the "file" parameter
    both a regular file and a scalar value.
  • 23:22 - 23:26
    But what happens when we try to get
    the "file" parameter value?
  • 23:26 - 23:31
    In a regular request, it should return
    the uploaded file descriptor,
  • 23:31 - 23:36
    but now that we're adding another value to that parameter,
  • 23:36 - 23:41
    param() returns a list containing all the values we sent:
  • 23:41 - 23:44
    the file we've uploaded and our scalar value.
  • 23:44 - 23:49
    But the "file" variable
    can't contain two values, right?
  • 23:49 - 23:55
    So instead of converting
    the returned list into an array
  • 23:55 - 23:59
    Perl only uses the first element of that list.
  • 23:59 - 24:06
    So if we'll send our scalar value
    before we send our file,
  • 24:06 - 24:10
    the $file variable will be assigned
    our scalar value
  • 24:10 - 24:14
    instead of the uploaded file descriptor.
  • 24:14 - 24:20
    Which means, that $file
    is now a regular string!
  • 24:20 - 24:22
    in high pitched voice: WAT?
  • 24:23 - 24:26
    But what happens to this operator
    when we use a string
  • 24:26 - 24:29
    instead of a file descriptor?
  • 24:29 - 24:33
    Well, the brackets operator
    doesn't work with strings, right?
  • 24:33 - 24:37
    It works with file descriptors,
    why should it work with strings?
  • 24:37 - 24:39
    Well, that appears true
  • 24:39 - 24:43
    unless that string is "ARGV".
  • 24:43 - 24:48
    laughter and applause
  • 24:55 - 24:58
    That's not a crazy part.
  • 24:58 - 25:00
    more laughter
  • 25:00 - 25:05
    In that case the brackets operator, listen closely,
  • 25:05 - 25:08
    loops through the script arguments,
  • 25:08 - 25:12
    which in CGI comes directly from the
    query string instead the command line,
  • 25:12 - 25:19
    and it treats them as file paths,
    inserting each one into an open() call!
  • 25:19 - 25:20
    again laughter
  • 25:20 - 25:23
    WAT?
  • 25:26 - 25:29
    Yeah, that made sense in some point, I guess.
  • 25:29 - 25:32
    All of this basically means that now,
  • 25:32 - 25:36
    instead of displaying
    our own uploaded file content,
  • 25:36 - 25:40
    we can display the content
    of any file on the server.
  • 25:40 - 25:43
    But that's not the end,
    as we haven't executed code yet.
  • 25:44 - 25:49
    To execute code, we have
    to look at the open() function.
  • 25:49 - 25:57
    Again, this is the function being called
    with the ARGV values as file paths.
  • 25:57 - 26:03
    open() is responsible for opening
    a file descriptor to a given file.
  • 26:03 - 26:06
    Unless a "pipe" character is added
  • 26:06 - 26:09
    to the end of the string,
    laughter
  • 26:09 - 26:13
    and in that case instead of opening the file,
  • 26:13 - 26:16
    it executes it…
    applause rising
  • 26:16 - 26:22
    …acting as an exec() call!
    more applause
  • 26:23 - 26:29
    So … when we send our exploit,
  • 26:29 - 26:35
    containing our uploaded file,
    the "ARGV" malicious scalar value,
  • 26:35 - 26:38
    and the ipconfig command followed by a pipe
  • 26:38 - 26:42
    this is what we get.
    WAT?
  • 26:42 - 26:47
    WAT?
    applause
  • 26:49 - 26:56
    I know, I'm shocked too, but I'm not done yet.
    laughter
  • 26:56 - 27:01
    Truth be told, I didn't write that code.
  • 27:01 - 27:06
    Remember that PerlMonks told me
    that I should read their fucking manual?
  • 27:06 - 27:11
    more laughter
    Guess where that code came from:
  • 27:11 - 27:23
    the official CGI documentation!
    big applause and audience whistling
  • 27:33 - 27:36
    But, I'm not blaming CGI.PM developers.
  • 27:36 - 27:41
    Nor am I blaming developers
    who copied from CGI.PM examples.
  • 27:41 - 27:47
    After all, who could have known
    that this is what this code will do?
  • 27:47 - 27:49
    This is how it could be exploited?
  • 27:49 - 27:54
    There's no exec calls,
    the file is not saved anywhere,
  • 27:54 - 27:58
    and we're only using a "print".
  • 27:58 - 28:07
    The sole responsible for this mess,
    is the Perl language.
  • 28:07 - 28:11
    Perl is the one silently expanding lists,
  • 28:11 - 28:15
    Perl is the one mixing up your data types,
  • 28:15 - 28:20
    Perl is the one executing user input
    with no exec calls,
  • 28:20 - 28:23
    Perl is the problem,
  • 28:23 - 28:26
    not its developers.
    applause rising
  • 28:26 - 28:32
    And until this god-damned, bizarre,
    dangerous language is fixed,
  • 28:32 - 28:34
    you could only
    stop
  • 28:34 - 28:35
    using
  • 28:35 - 28:40
    Perl!
  • 28:40 - 28:47
    Thank you!
    more applause
  • 28:59 - 29:03
    Herald: So I guess
    we have some time for questions now.
  • 29:03 - 29:04
    laughter
    Netanel: Maybe
  • 29:04 - 29:08
    Herald: And I have the funny feeling,
    we will have some questions now.
  • 29:08 - 29:13
    Ok, so we have some microphones here.
    Please queue up.
  • 29:13 - 29:18
    Please do not shout in, because we need
    to record it on the stream.
  • 29:18 - 29:19
    Well, here we go.
  • 29:19 - 29:23
    And we also have some questions
    from the internet, don't we?
  • 29:23 - 29:27
    Signal Angel: Oh yes, we do!
    laughter
  • 29:27 - 29:30
    Signal: But before we come
    to the technical questions,
  • 29:30 - 29:33
    the IRC wants you to know,
    what you did to it:
  • 29:33 - 29:37
    it felt like there were explosions
    and camels everywhere.
  • 29:37 - 29:40
    Netanel laughing: That's the point
  • 29:40 - 29:45
    Signal: And incidently they want to know,
    if you have a list of those camel pics somewhere?
  • 29:46 - 29:50
    Netanel: I think Google has it?
    more laughter
  • 29:50 - 29:54
    Just there search camels.
  • 29:54 - 29:59
    Signal: So for the first question.
    Opello(?) wants to know,
  • 29:59 - 30:04
    if the take-away is, that Perl project authors
    so shouldn't trust input
  • 30:04 - 30:10
    and instead verify types with REF
    and always use prepared SQL statements?
  • 30:14 - 30:21
    Netanel: That's a good question. The take-away should be…
    laughter
  • 30:24 - 30:28
    well, how will I phrase it …
  • 30:29 - 30:33
    I think I have a slide … somewhere …
    more laughter
  • 30:33 - 30:36
    Oh wait, where's my slide?
  • 30:38 - 30:40
    Don't worry, have it right here.
  • 30:44 - 30:49
    But really, trusting user input
    is always a bad idea
  • 30:49 - 30:52
    and most developers know it.
  • 30:52 - 30:54
    The problem is, that…
  • 30:54 - 30:57
    well, at least from the code
    I saw written in Perl,
  • 30:57 - 31:00
    and that's a lot of code, trust me
  • 31:00 - 31:05
    …is that hashes and arrays
    are almost always considered secured
  • 31:05 - 31:09
    as they supposedly can't be
    created by user input, as I said.
  • 31:09 - 31:18
    But, when you're expecting your user input
    to be a scalar, a string or even a list
  • 31:18 - 31:26
    and instead you get a hash from unexpected
    directions, you get confused.
  • 31:26 - 31:31
    And you can't always
    live in the fear of not knowing
  • 31:31 - 31:34
    what data type you're trying to handle.
  • 31:34 - 31:40
    Well, not trusting scalar data types
    is a wise decision, because it's dangerous.
  • 31:40 - 31:46
    But not trusting your hashes,
    as well not trusting your arrays?
  • 31:46 - 31:50
    What's next? Not trusting your own code?
  • 31:50 - 31:54
    You just can't expect anything
    to really work as it should.
  • 31:54 - 31:56
    When you're writing Perl,
  • 31:56 - 32:04
    you are constantly attacked
    by all these different directions.
  • 32:04 - 32:09
    And even the data type direction is a problem now.
  • 32:09 - 32:13
    I hope that answered the question
    beside the slide.
  • 32:13 - 32:16
    Herald: Well, then we're gonna go over
    and start with number one.
  • 32:16 - 32:19
    Questioner: So thank you for opening our eyes.
  • 32:19 - 32:24
    Even I use Perl, I would say,
    for cooking and yes …
  • 32:24 - 32:26
    Netanel: I remember you
    Q: Sorry?
  • 32:26 - 32:27
    N: I remember you from the last talk!
    Q: No no
  • 32:27 - 32:31
    N: Oh, you're new? Oh… smirking
    Q: I'm new, I'm new…
  • 32:31 - 32:36
    Q: So… I can't say, I'm not guilty of that,
    but I still would say yes,
  • 32:36 - 32:40
    Perl is a bit like cooking with my mum.
  • 32:40 - 32:46
    Sometimes I put something into…
    the… with the boiling thing…
  • 32:46 - 32:51
    and sometimes she, sometimes I go away,
    sometimes she go away
  • 32:51 - 32:54
    and the only thing you can do is always taste.
  • 32:54 - 32:58
    And yes, you're maybe right, Perl is a language
  • 32:58 - 33:02
    where you never know what comes out,
    but it's real cool!
  • 33:02 - 33:05
    If you get the right response you can use it,
  • 33:05 - 33:09
    if you use it to write web applications
    I would agree.
  • 33:09 - 33:13
    Web applications, the professional ones
    at least, are not for cooking,
  • 33:13 - 33:18
    but for doing funny things and
    have some fun, I think it's a perfect language.
  • 33:18 - 33:22
    N: I think Perl is a lot of fun.
    laughter
  • 33:22 - 33:27
    I completely agree on that. laughing
  • 33:27 - 33:29
    Herald: Then we're gonna go over to two.
  • 33:29 - 33:34
    Question: Was your life ever threatened
    while interacting with the Perl community?
  • 33:34 - 33:36
    laughter
    N: Could you please repeat that? I …
  • 33:36 - 33:40
    Q: Was your life ever threatened
    while interacting with the Perl community?
  • 33:40 - 33:43
    N: Definitely. Definitely,
  • 33:43 - 33:47
    I'm getting hate mail every day,
    living in fear …
  • 33:47 - 33:49
    H: And over to the three, please.
  • 33:49 - 33:53
    Q: I think I speak for all of us,
    when I thank you for this wonderful talk,
  • 33:53 - 34:00
    N: Uh, thank you. Thank you really! Thank you.
    applause
  • 34:00 - 34:07
    Q: Brilliantly executed, but… ehm…
    you spoke about Perl 5 I think.
  • 34:07 - 34:11
    N: Yes, you are absolutely right.
    Q: As some of you might know, this christmas…
  • 34:11 - 34:15
    laughter
    Q: …so tomorrow Ingo Blechschmidt
  • 34:15 - 34:20
    is going to give a talk about how Perl 6
    will make everything better
  • 34:20 - 34:24
    and how everyone should start
    using Perl 6 and…
  • 34:24 - 34:28
    N: It also craps rainbows
    Q: Yeah, of course…
  • 34:28 - 34:31
    Q: My personal comment is:
    wouldn't it have happened
  • 34:31 - 34:34
    with a statically typed language?
  • 34:34 - 34:39
    So I think some nice folks at Haskell
    in IRC are waiting for you Perl developers
  • 34:39 - 34:45
    to please come, join us … Thank you!
    N: smirking
  • 34:45 - 34:46
    Herald and Netanel start speaking simultaneously
  • 34:46 - 34:49
    H: …sorry, to answer first, where am I… sorry
    N: Ah, no..., I am not answering, just...
  • 34:49 - 34:56
    just a quick note about Perl 6.
    This talk is all about Perl 5, alright?
  • 34:56 - 35:01
    I … Perl 6 came out a couple of days ago and …
  • 35:01 - 35:07
    ...from …at least from what I saw,
    Perl 6 is to Perl as…
  • 35:07 - 35:12
    C++ is to C. It's the same name,
    but it's a whole different language.
  • 35:12 - 35:17
    So yes, this is Perl 5.
    Maybe I'll come back next year about Perl 6?
  • 35:17 - 35:19
    laughter
    Who knows?
  • 35:19 - 35:22
    Herald: I'm looking forward to that already.
    applause
  • 35:22 - 35:25
    Herald pointing to Signal Angel
  • 35:25 - 35:31
    Signal: Yeah… Joerd(?) wants to know:
    of course you talked a lot about CGI.PM
  • 35:31 - 35:37
    which you know was removed from repository from Perl
    even before your talk last year.
  • 35:37 - 35:43
    So what about it's replacements
    from CPAN like CGI::Simple.
  • 35:43 - 35:48
    Netanel: I don't know, I haven't checked it.
    When I decided on which modules to check,
  • 35:48 - 35:56
    I took CGI.PM because even though it is old,
    it is the most popular in the world as of today
  • 35:56 - 36:03
    and I took Mojolicious and Catalyst because
    they were really popular, too.
  • 36:03 - 36:08
    So I didn't take the newest modules,
    I take the most popular modules.
  • 36:08 - 36:16
    And I think, that's the important
    aspect of … deciding.
  • 36:18 - 36:21
    Herald: And over to one, please.
  • 36:21 - 36:29
    Questioner: Hi… I'm… part of the Perl community, and…
    laughter
  • 36:29 - 36:33
    N: Hi!
    Q: But I just start with Perl – 5
  • 36:33 - 36:40
    N: Uhh… ehm… uhh… didn't you… nhaa…
    laughter
  • 36:40 - 36:44
    Q: We use Perl for almost every module
    that we have at work
  • 36:44 - 36:47
    and this worked really fine.
    N: …yeah…
  • 36:47 - 36:52
    Q: And I don't know why you're picking Perl as language to attack.
  • 36:52 - 36:59
    It's a really old language, it's also every language
    that we can pick, that has problems.
  • 36:59 - 37:05
    But it doesn't mean this has to die or
    stop using it. So I don't know why…
  • 37:05 - 37:09
    N: …you're right, you're right.
    First of all, you're completely right,
  • 37:09 - 37:12
    because a language shouldn't die, it should improve.
  • 37:12 - 37:17
    C got critized and it improved.
    PHP got critized and it improved.
  • 37:17 - 37:20
    Why can't Perl be critized, too?
  • 37:20 - 37:24
    Why is it like a code, when you say
    something bad about Perl, then,
  • 37:24 - 37:27
    I don't know, a horde of PerlMonks jumps on you?
  • 37:27 - 37:33
    Why don't improve the language?
    Don't use it in your work though,
  • 37:33 - 37:38
    it's dangerous.
    laughter and applause
  • 37:40 - 37:42
    H: Then we're gonna jump over to five, please.
  • 37:42 - 37:49
    Q: Hi. I'm not a Perl developer,
    but I use a lot of Ruby and Python.
  • 37:49 - 37:51
    Is this really limited to Perl or
  • 37:51 - 37:54
    does this apply to more or less
    any dynamic language?
  • 37:54 - 37:59
    N: As I said in one of the first few slides,
  • 37:59 - 38:04
    some of it also applies to Python.
    Specifically the thing
  • 38:04 - 38:10
    when you can't specify what data types
    your function arguments can get.
  • 38:10 - 38:16
    But, what's unique to Perl is that
    writing different code
  • 38:16 - 38:20
    for different data types in one function
    is very, very common.
  • 38:20 - 38:23
    You can do it in every language, of course!
  • 38:23 - 38:28
    But it is very common only in Perl!
    And that is unique about it,
  • 38:28 - 38:33
    of course besides the thing
    that hashes and arrays are secure.
  • 38:33 - 38:37
    That's of course Perls only fault.
  • 38:37 - 38:40
    H: Good, then we're gonna go over to six, please.
  • 38:40 - 38:47
    Q: Hey! Did you say WAT more
    while preparing this talk or while holding it?
  • 38:47 - 38:57
    N: Uhm. Both. Laughing.
    Did I rant? That was the … right?
  • 38:57 - 39:01
    Q: Did you say it more
    while preparing it or while holding it?
  • 39:01 - 39:03
    N: I'm missing your word, man, can you...
  • 39:03 - 39:11
    Ahh, wat… WAT! Ohh… Yeah, both!
    laughter
  • 39:11 - 39:15
    H: Ok, do we have another from the internet?
  • 39:15 - 39:19
    Signal: Does your exploit
    also work in tainted mode?
  • 39:19 - 39:24
    N: No, I believe not. No, it doesn't.
  • 39:24 - 39:27
    H: And another one...
  • 39:27 - 39:36
    S: Is there any Perl obfuscated code exploits
    like this for Catalyst or Mojolicious?
  • 39:36 - 39:39
    someone chuckling in audience
  • 39:39 - 39:43
    N: I've no idea, man, maybe.
    I didn't check it of course.
  • 39:43 - 39:48
    I didn't check every module
    for every exploit, I ever want to create, but
  • 39:48 - 39:55
    on CGI.PM, which is again
    the most popular CGI library, it did.
  • 39:55 - 40:03
    So, maybe the internet
    can find more exploits. I know it can.
  • 40:03 - 40:07
    H: Bring it on. That's it?
    N: That's it?
  • 40:07 - 40:08
    Thank you!
  • 40:08 - 40:09
    applause
  • 40:09 - 40:12
    Herald: Thank you very much!
    Netanel: Thank you!
  • 40:12 - 40:18
    postroll music
  • 40:18 - 40:24
    subtitles created by c3subtitles.de
    in the year 2016. Join, and help us!
Title:
Netanel Rubin: The Perl Jam 2
Description:

more » « less
Video Language:
English
Duration:
40:24

English subtitles

Revisions