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!