1 00:00:00,000 --> 00:00:08,755 *preroll music* 2 00:00:10,084 --> 00:00:13,459 Herald: And I'm gonna introduce Netanel Rubin. 3 00:00:14,166 --> 00:00:18,640 He has been here last year with a talk that he got some bashing for. 4 00:00:19,314 --> 00:00:23,548 This year he's gonna ensure, it's not the programmer's fault, 5 00:00:23,689 --> 00:00:27,426 it's the language itself. No? 6 00:00:27,507 --> 00:00:29,883 Well, here we go, well here we go. 7 00:00:29,949 --> 00:00:33,598 Netanel, he is working for PerimeterX in Tel Aviv, 8 00:00:33,631 --> 00:00:35,491 welcome on stage, your talk! 9 00:00:35,521 --> 00:00:37,634 Netanel: Thank you very much, *applause* 10 00:00:37,674 --> 00:00:41,134 thank you, thank you! 11 00:00:44,747 --> 00:00:52,755 Last year I stood right on this very stage and I talked about several of Perl's 12 00:00:52,755 --> 00:00:56,411 less thought out "features". 13 00:00:56,411 --> 00:01:04,709 Now, I got some bashing from the Perl community, but mainly what happened was, 14 00:01:04,709 --> 00:01:10,291 that the Perl community completely rejected my talk claiming that the language 15 00:01:10,291 --> 00:01:16,357 is completely fine and great and all of this stuff are just improvements. 16 00:01:17,573 --> 00:01:20,724 It was clear I had to give another talk. 17 00:01:21,421 --> 00:01:29,049 This is why I'm very proud to present "Perl Jam 2 – The Camel strikes back"! 18 00:01:29,049 --> 00:01:33,618 *applause* 19 00:01:33,618 --> 00:01:36,188 Thank you 20 00:01:38,065 --> 00:01:45,873 At the last talk, I showed that "lists" are expressions, used in… many confusing ways. 21 00:01:45,873 --> 00:01:52,921 I also showed how CGI parameters can create lists, directly from user input. 22 00:01:52,921 --> 00:02:00,165 But most importantly, I showed that when these two things combine, shit happens. 23 00:02:01,696 --> 00:02:04,066 Great 24 00:02:04,080 --> 00:02:08,949 But the really interesting part was the PerlMonks response. 25 00:02:08,949 --> 00:02:16,203 The Perl community… *laughter* 26 00:02:19,274 --> 00:02:24,451 The Perl community had a long discussion at the PerlMonks forum 27 00:02:24,451 --> 00:02:29,475 that started with the words "Sad news from Germany". 28 00:02:29,475 --> 00:02:32,231 A bit dramatic, but who am I to judge? 29 00:02:32,231 --> 00:02:38,931 So, after a long, long discussion, they came to the unavoidable conclusion 30 00:02:38,931 --> 00:02:47,997 that my talk was, in fact, a "polemic shit", and they should all just "piss on it". Wink. 31 00:02:49,717 --> 00:02:55,756 They also realized I'm just a "script kiddie preaching to other script kiddies", 32 00:02:55,756 --> 00:03:01,162 and not just any script kiddies, the CCC audience is a 33 00:03:01,162 --> 00:03:06,435 "heterogeneous group of chaotic punks who love to see themselves in the hacker 34 00:03:06,435 --> 00:03:18,091 image of Hollywood media". *applause and whistling from audience* 35 00:03:18,091 --> 00:03:24,075 What hacker image? What are they talking about? 36 00:03:24,075 --> 00:03:26,218 We have no hacker image. 37 00:03:26,310 --> 00:03:34,281 Anyway, it got quite surreal, as in some point they even critized 38 00:03:34,281 --> 00:03:41,994 the "crude use of propaganda in the camel images". WAT? 39 00:03:42,461 --> 00:03:46,015 *laughing* *applause* 40 00:03:46,015 --> 00:03:50,737 Propaganda in the camel images. Alright. 41 00:03:50,737 --> 00:03:58,348 Anyway, they completely rejected the entire talk, even though the technical points were valid. 42 00:03:58,348 --> 00:04:03,603 They rejected it because of some jokes and camel images. 43 00:04:03,603 --> 00:04:12,814 But still, they got so offended they just threw lame excuses as to why their language sucks. 44 00:04:12,814 --> 00:04:19,622 Two of these lame excuses were repeated over and over again. 45 00:04:19,622 --> 00:04:24,733 The first was that I should read the fucking manual, which is funny 46 00:04:24,733 --> 00:04:27,413 because I thought I was the only one who did… 47 00:04:27,413 --> 00:04:29,184 *laughter* 48 00:04:29,184 --> 00:04:30,753 …and the second is that 49 00:04:30,753 --> 00:04:35,378 I'm using the old, ancient Perl, and not the new, modern Perl. 50 00:04:35,378 --> 00:04:39,920 *more laughter* 51 00:04:40,811 --> 00:04:46,317 Remember these two points carefully as I'll later break them in the presentation. 52 00:04:46,317 --> 00:04:52,167 But, enough with the intro, let's start with the new madness. 53 00:04:52,167 --> 00:04:58,788 So, Perl allows declaring variables without specifying their data type. 54 00:04:58,788 --> 00:05:03,131 Of course, this functionality exists in many dynamic languages, 55 00:05:03,131 --> 00:05:06,884 and is completely fine and very convenient. 56 00:05:06,884 --> 00:05:12,773 But, as usual, Perl took it to a whole different level. 57 00:05:12,773 --> 00:05:19,200 Perl went as far as removing data type declarations from function arguments. 58 00:05:19,200 --> 00:05:20,854 You can see that in this example, 59 00:05:20,854 --> 00:05:27,760 I'm just receiving two different arguments without knowing what type they are. 60 00:05:27,760 --> 00:05:29,760 Let me be clear about that, 61 00:05:29,760 --> 00:05:34,536 you don't get to choose whether you want to specify argument data types or not, 62 00:05:34,536 --> 00:05:41,053 you can't specify what data types you're expecting to get. 63 00:05:41,053 --> 00:05:44,764 So even if I built a function that only works with strings, 64 00:05:44,764 --> 00:05:49,332 I have no way of forcing that at the function declaration. 65 00:05:49,332 --> 00:05:51,318 Now that's annoying. 66 00:05:51,318 --> 00:05:57,394 But, the real kicker is how this feature is used. 67 00:05:57,444 --> 00:06:03,828 Apparently, it is very common to write two completely different blocks of code, 68 00:06:03,828 --> 00:06:07,675 one that handles scalar types, like strings or ints, 69 00:06:07,675 --> 00:06:13,217 and one that handles non-scalar types, like arrays or hashes. 70 00:06:13,217 --> 00:06:15,338 Let me repeat that: 71 00:06:15,338 --> 00:06:23,796 Writing multiple code, for multiple data-types, in one function, is a Perl standard. 72 00:06:23,796 --> 00:06:31,782 And that's sad. You shouldn't write redundant code because the language lacks the capability 73 00:06:31,782 --> 00:06:35,971 of letting you decide which cases you don't want to handle. 74 00:06:35,971 --> 00:06:40,493 By the way, Python doesn't let you declare your function argument data types too, 75 00:06:40,493 --> 00:06:45,723 but unlike Perl, writing redundant code to cover that up 76 00:06:45,723 --> 00:06:49,726 is definitely not the standard. 77 00:06:49,726 --> 00:06:54,723 Anyway, sad as this may be, this Perl convention is not dangerous. 78 00:06:54,723 --> 00:06:56,894 The dangerous part begins 79 00:06:56,894 --> 00:07:02,956 when hashes and arrays are considered as "secure" data types, 80 00:07:02,956 --> 00:07:07,738 mainly because they can't be created by user input. 81 00:07:07,738 --> 00:07:10,374 This results in this kind of code, 82 00:07:10,374 --> 00:07:14,187 where if the function argument is a hash, for example, 83 00:07:14,187 --> 00:07:18,708 it is used un-escaped in dangerous functions. 84 00:07:18,708 --> 00:07:25,661 Hashes, specifically, are considered so secure, that even if you use "taint mode", 85 00:07:25,661 --> 00:07:28,293 which is some kind of safe mode for Perl, 86 00:07:28,293 --> 00:07:33,532 hash keys are not tainted, meaning that, even if you use safe mode, 87 00:07:33,532 --> 00:07:36,719 they can be still used in dangerous functions 88 00:07:36,719 --> 00:07:41,639 without any validation, as opposed to other data types. 89 00:07:41,639 --> 00:07:46,619 Now this kind of code appears a lot in Perl applications, 90 00:07:46,619 --> 00:07:49,759 and apart from the many bugs this method can cause, 91 00:07:49,759 --> 00:07:54,395 it also makes your code exploitable. 92 00:07:54,395 --> 00:07:58,369 So we know function arguments are of unknown data type. 93 00:07:58,369 --> 00:08:03,073 And we know developers treat hashes and arrays as "secure" data types, 94 00:08:03,073 --> 00:08:06,603 inserting their values into dangerous functions. 95 00:08:06,603 --> 00:08:09,140 But this practices isn't something 96 00:08:09,140 --> 00:08:14,056 that was created a long time ago, and found only on redundant code. 97 00:08:14,056 --> 00:08:20,341 Because of how the language is built, its supposedly restriction-less type of developing, 98 00:08:20,341 --> 00:08:26,688 even now it is the natural way to code when you're using Perl. 99 00:08:26,688 --> 00:08:31,185 And that's the real problem: Perl is like a shotgun, 100 00:08:31,185 --> 00:08:36,552 with one trigger you know about and a dozen that you don't. 101 00:08:36,552 --> 00:08:40,821 So for now, we know that if we'll somehow manage 102 00:08:40,821 --> 00:08:46,051 to create these "secure" data types, with our user input, 103 00:08:46,051 --> 00:08:49,010 we could exploit the code. 104 00:08:49,010 --> 00:08:53,997 So the only question remaining really is what are we gonna exploit? 105 00:08:53,997 --> 00:08:58,185 And the answer, again, is Bugzilla. 106 00:08:58,185 --> 00:09:02,768 *laughter* 107 00:09:03,178 --> 00:09:08,713 Like every other Perl project, Bugzilla is heavily using functions 108 00:09:08,713 --> 00:09:13,277 that treat scalar and non-scalar argument types very differently. 109 00:09:13,277 --> 00:09:17,404 This is one of them: the load_from_DB function is responsible 110 00:09:17,404 --> 00:09:21,541 for extracting object specific data out of the database. 111 00:09:21,541 --> 00:09:28,945 Like I just said, it treats scalars, and in this case hashes, very differently. 112 00:09:28,945 --> 00:09:34,146 If the function argument is a hash, it takes one of its values 113 00:09:34,146 --> 00:09:39,845 and inserts it as is, un-escaped, into an SQL statement. 114 00:09:39,845 --> 00:09:44,598 Again, because hashes are considered secure, 115 00:09:44,598 --> 00:09:47,807 so there's no point of escaping them. 116 00:09:47,807 --> 00:09:50,919 On the other hand, if the argument is a scalar, 117 00:09:50,919 --> 00:09:55,798 it converts it into an integer and only then use it in an SQL statement. 118 00:09:55,798 --> 00:09:59,020 Because scalar values are not secure. 119 00:09:59,020 --> 00:10:00,680 hashes: secure 120 00:10:00,680 --> 00:10:03,064 scalar: not secure 121 00:10:03,064 --> 00:10:06,241 This means that if we could control the function argument entirely, 122 00:10:06,241 --> 00:10:10,964 including its data type, we could control the SQL query, 123 00:10:10,964 --> 00:10:14,405 effectively exploiting an SQL injection attack, 124 00:10:14,405 --> 00:10:17,720 by inserting a hash containing that specific value. 125 00:10:17,720 --> 00:10:21,234 But… 126 00:10:21,234 --> 00:10:26,862 CGI input doesn't allow hashes, right? 127 00:10:26,862 --> 00:10:32,339 The whole Perl security module is built on that assumption. 128 00:10:32,339 --> 00:10:37,314 The problem is that, like us, developers are assuming 129 00:10:37,314 --> 00:10:42,487 CGI input is the only input method available. 130 00:10:42,487 --> 00:10:45,581 CGI. 131 00:10:45,581 --> 00:10:48,545 But CGI isn't the only way to go. 132 00:10:48,545 --> 00:10:52,978 Bugzilla developers missed the fact that their own system 133 00:10:52,978 --> 00:10:57,723 is also featuring an XMLRPC and a JSONRPC, 134 00:10:57,723 --> 00:11:05,048 both supporting input of non-scalar data types like arrays and hashes! 135 00:11:05,048 --> 00:11:06,498 But I'm not blaming them. 136 00:11:06,498 --> 00:11:12,492 Yes, they forgot that there are more ways for a user to input than CGI, 137 00:11:12,492 --> 00:11:16,697 but still, they're just the product of how Perl programming is taught, 138 00:11:16,697 --> 00:11:20,679 filled with false assumptions and inconsistencies. 139 00:11:20,679 --> 00:11:25,983 Expecting anything but this kind of security problems is just naive. 140 00:11:25,983 --> 00:11:28,547 But back to the vulnerability. 141 00:11:28,547 --> 00:11:30,429 If we'll use one of these RPCs, 142 00:11:30,429 --> 00:11:34,136 sending our input parameter with a malicious hash, 143 00:11:34,136 --> 00:11:37,204 instead of just a regular numeric parameter, 144 00:11:37,204 --> 00:11:39,991 we will be able to exploit the SQL injection! 145 00:11:39,991 --> 00:11:44,428 So, if we'll send this regular request, using the JSONRPC interface, 146 00:11:44,428 --> 00:11:48,611 the number 1 will be used as the ID of a bug to extract, 147 00:11:48,611 --> 00:11:51,272 but if we'll send this request, 148 00:11:51,272 --> 00:11:53,993 where instead of an integer we'll supply a hash, 149 00:11:53,993 --> 00:11:57,365 then suddenly we will be able to inject any SQL we'd like 150 00:11:57,365 --> 00:12:03,016 into that statement, effectively compromising the entire database. 151 00:12:03,121 --> 00:12:07,048 Now when you look at this request, you realize 152 00:12:07,048 --> 00:12:11,396 that this is not a sophisticated vulnerability. 153 00:12:11,396 --> 00:12:20,859 All I did was just change the input data type from scalar in this case to a hash, 154 00:12:20,859 --> 00:12:24,980 and that's it, the system is compromised. 155 00:12:24,980 --> 00:12:29,072 It was so heavily built on the assumption 156 00:12:29,072 --> 00:12:32,223 that hashes are secure, that it offered me 157 00:12:32,223 --> 00:12:36,676 almost unlimited access security wise. 158 00:12:36,676 --> 00:12:41,659 The funny thing about that is, that although it's so simple, 159 00:12:41,659 --> 00:12:45,970 the attack has existed for over 5 years. 160 00:12:45,970 --> 00:12:48,912 That's the year I was born in. 161 00:12:48,912 --> 00:12:55,087 So, we now proved this "unknown-argument-type" feature 162 00:12:55,087 --> 00:12:58,232 is a huge source for problems. 163 00:12:58,232 --> 00:13:02,901 We also know writing different code to handle different data types 164 00:13:02,901 --> 00:13:06,953 just causes a lot of false assumptions. 165 00:13:06,953 --> 00:13:13,534 But most importantly, treating non-scalar data types such as hashes as "secure", 166 00:13:13,534 --> 00:13:17,354 just because they supposedly can't be created by the user, 167 00:13:17,354 --> 00:13:22,955 is very, very, BAD. Just ask Bugzilla. 168 00:13:22,955 --> 00:13:30,145 But the shocking part really, is that, again, this is the Perl Standard! 169 00:13:30,145 --> 00:13:33,892 You're not expected to use it, you have to 170 00:13:33,892 --> 00:13:36,645 as you don't have any other choice. 171 00:13:36,645 --> 00:13:43,829 This security mess is a fundamental part of the language. 172 00:13:43,829 --> 00:13:51,777 The problem is that creating non-scalar data types is impossible in some cases. 173 00:13:51,777 --> 00:13:54,914 We can't rely that some kind of RPC 174 00:13:54,914 --> 00:13:58,859 will exist in the code and support different data types, 175 00:13:58,859 --> 00:14:05,031 and we can't create data types using regular user input… Right? 176 00:14:05,031 --> 00:14:06,937 Well, let's have a look at 177 00:14:06,937 --> 00:14:10,526 how different CGI modules handle different kind of input. 178 00:14:10,526 --> 00:14:13,917 First, we'll take the most trivial scenario. 179 00:14:13,917 --> 00:14:17,807 A single valued parameter, something that looks like this request, 180 00:14:17,807 --> 00:14:22,210 where the "foo" parameter is assigned the string "bar". 181 00:14:22,210 --> 00:14:26,819 In this case, a scalar is created on all three CGI modules, 182 00:14:26,819 --> 00:14:31,198 which doesn't really help us, but is pretty much what we've expected. 183 00:14:31,198 --> 00:14:32,914 It is secure. 184 00:14:32,914 --> 00:14:37,846 But what happens if instead of sending a single-valued parameter, 185 00:14:37,846 --> 00:14:42,377 we'll send a multi-valued parameter, like in this request? 186 00:14:42,377 --> 00:14:46,032 Now things are starting to get complicated. 187 00:14:46,032 --> 00:14:50,551 On CGI.PM, as we already know, a list is created, 188 00:14:50,551 --> 00:14:55,013 which is very useful for us, but not what we're after. 189 00:14:55,013 --> 00:15:01,847 Let's have a look at what the "new" Perl modules are creating. 190 00:15:01,847 --> 00:15:09,987 We'll see that both of them are returning arrays containing our values. 191 00:15:09,987 --> 00:15:14,549 Arrays! WAT? 192 00:15:14,549 --> 00:15:19,278 I thought you can't create these kind of data types with regular input, 193 00:15:19,278 --> 00:15:22,442 after all, they're considered safe. 194 00:15:22,442 --> 00:15:24,236 But let's continue. 195 00:15:24,236 --> 00:15:27,637 What happens if instead of sending a regular value, 196 00:15:27,637 --> 00:15:31,883 we'll try and upload a file in that parameter? 197 00:15:31,883 --> 00:15:35,229 Now things are really getting out of hand, 198 00:15:35,229 --> 00:15:44,409 because CGI.PM now returns a file descriptor, and Catalyst and Mojolicious returns a hash. 199 00:15:44,409 --> 00:15:46,384 WAT? 200 00:15:46,384 --> 00:15:54,012 We just exploited the most popular Perl project in the world 201 00:15:54,012 --> 00:15:58,226 because they assumed hashes can't be created by the user, 202 00:15:58,226 --> 00:16:02,984 and now we're finding out that not only we can create hashes, 203 00:16:02,984 --> 00:16:05,477 it is a god-damned feature?! 204 00:16:05,477 --> 00:16:07,161 That's insane! 205 00:16:07,161 --> 00:16:11,504 The whole Perl security standard is built on that assumption 206 00:16:11,504 --> 00:16:14,954 that users can't create non-scalar data-types 207 00:16:14,954 --> 00:16:19,867 and now suddenly these are features? 208 00:16:19,867 --> 00:16:27,693 But let's send a multi-file upload request as in several files in the same parameter. 209 00:16:27,693 --> 00:16:34,183 Watch closely, because this is where it gets ridiculous. 210 00:16:34,183 --> 00:16:39,426 Now, CGI.PM returns a list of File Descriptors, 211 00:16:39,426 --> 00:16:42,551 Catalyst returns a list of Hashes 212 00:16:42,551 --> 00:16:49,282 and Mojolicious returns an Array of Objects! WAT?! 213 00:16:49,282 --> 00:16:53,340 *laughter and applause* 214 00:16:53,444 --> 00:16:58,105 Almost any Perl project in the world 215 00:16:58,105 --> 00:17:03,470 uses one of these modules for parsing CGI input. 216 00:17:03,470 --> 00:17:10,522 Just think how many developers assumed the exact same thing Bugzilla assumed 217 00:17:10,522 --> 00:17:15,854 and treated hashes and arrays as secure data types. 218 00:17:15,854 --> 00:17:17,752 So if you're using CGI.PM, 219 00:17:18,380 --> 00:17:21,268 instead of the expected scalar value you could be getting 220 00:17:21,268 --> 00:17:25,724 a list, a file descriptor or a list of file descriptors 221 00:17:25,724 --> 00:17:27,644 and if you're using Catalyst 222 00:17:27,644 --> 00:17:30,895 you could receive a scalar, an array, a hash or a list, 223 00:17:30,895 --> 00:17:35,375 which is basically any data type. 224 00:17:36,320 --> 00:17:39,425 So expecting your function… yeah 225 00:17:40,089 --> 00:17:44,091 *audience chuckling* 226 00:17:45,943 --> 00:17:53,997 So expecting your function arguments to be of a specific data type is false. 227 00:17:53,997 --> 00:18:00,119 Expecting hashes and arrays to be secure is also false. 228 00:18:00,119 --> 00:18:02,972 Expecting scalar only user input 229 00:18:02,972 --> 00:18:06,833 is a major false. 230 00:18:06,833 --> 00:18:13,156 And to be honest, it seems that in Perl expecting is false! 231 00:18:13,156 --> 00:18:17,337 *laughter and applause* 232 00:18:21,422 --> 00:18:25,923 You just can't expect anything 233 00:18:25,923 --> 00:18:32,455 even the most basic of things such as what data type your variable is made of. 234 00:18:32,455 --> 00:18:35,761 You just don't know. 235 00:18:37,870 --> 00:18:42,934 But I felt all of these points will go un-noticed 236 00:18:42,934 --> 00:18:48,632 without an extreme example of Perl's absurdity. 237 00:18:48,632 --> 00:18:52,599 So I found an extreme example. 238 00:18:52,599 --> 00:18:55,249 One that will clearly show 239 00:18:55,249 --> 00:18:59,204 the ridiculous nature of the language. 240 00:18:59,204 --> 00:19:00,898 And this is it: 241 00:19:00,898 --> 00:19:06,829 All this code does is print an uploaded file's content. 242 00:19:06,829 --> 00:19:14,517 And to show you how basic and simple that code is, I'll explain each line. 243 00:19:14,517 --> 00:19:20,363 The first line just creates a new CGI instance, so we could get the file from the user. 244 00:19:20,363 --> 00:19:26,785 The second line checks if a file has been uploaded in the "file" parameter. 245 00:19:26,785 --> 00:19:31,549 The third line gets the file descriptor from the CGI module, 246 00:19:31,549 --> 00:19:37,438 while the fourth line loops through the file and the fifth prints it. 247 00:19:37,438 --> 00:19:44,459 That's it. Again: all this code does is get a file and print it. 248 00:19:44,459 --> 00:19:45,521 *clapping* That's it. 249 00:19:45,521 --> 00:19:52,126 A user has uploaded a file to the server and the server is just returning its content. 250 00:19:52,126 --> 00:19:55,683 It's not saving it anywhere, it's not moving it anywhere, 251 00:19:55,683 --> 00:19:58,771 it just prints its content. 252 00:19:58,771 --> 00:20:03,519 There should be absolutely nothing dangerous in this code, 253 00:20:03,519 --> 00:20:07,087 it contains literally five lines. 254 00:20:07,087 --> 00:20:09,830 Yet, it's demo time. 255 00:20:09,830 --> 00:20:12,332 *laughter* 256 00:20:12,412 --> 00:20:15,020 So trust me, you don't need to see the text, 257 00:20:15,020 --> 00:20:19,820 all you need to see is that when I'm sending a regular request nothing happens. 258 00:20:19,820 --> 00:20:23,585 When I send it now, nothing happens, I'm just getting the file content. 259 00:20:23,585 --> 00:20:26,240 We're having fun, you don't see the burp… 260 00:20:26,240 --> 00:20:30,425 Now, nice. Okay. 261 00:20:30,425 --> 00:20:34,184 So… …L't me just… 262 00:20:34,685 --> 00:20:37,182 …I have no idea where my mouse is, okay. 263 00:20:37,388 --> 00:20:38,323 So… 264 00:20:39,181 --> 00:20:42,230 I'm sending a regular request, nothing happens, just getting the content. 265 00:20:42,230 --> 00:20:46,073 I know, you can't see the text… …and… 266 00:20:46,073 --> 00:20:49,519 when I'm sending my malicious request, 267 00:20:49,519 --> 00:20:51,901 something interesting will pop up. 268 00:20:51,901 --> 00:20:54,990 Watch closely! It's gonna be quick. 269 00:20:55,092 --> 00:20:56,684 Ready? 270 00:20:58,270 --> 00:21:00,520 Oh, you haven't seen it, it's on the different screen. 271 00:21:00,520 --> 00:21:06,641 Just a second… oh… duplicate… 272 00:21:07,809 --> 00:21:09,236 (from audience): … magnify it! 273 00:21:09,236 --> 00:21:11,781 Netanel: I'll magnify you! 274 00:21:11,781 --> 00:21:14,247 *laughter* 275 00:21:14,421 --> 00:21:18,136 Alright, so… watch closely. 276 00:21:18,894 --> 00:21:22,772 Ohh, uuh? What was that? 277 00:21:24,467 --> 00:21:26,559 Let's see it again. 278 00:21:26,559 --> 00:21:29,528 *mocking* Uuuuuh?! 279 00:21:30,340 --> 00:21:36,495 *laughter and applause* 280 00:21:36,893 --> 00:21:40,442 Yupp, *clearing throat* 281 00:21:40,752 --> 00:21:44,650 … just a second. 282 00:21:44,800 --> 00:21:46,084 Nice. 283 00:21:46,084 --> 00:21:49,277 So you're probably asking yourself right now 284 00:21:49,277 --> 00:21:52,411 "What the fuck did I just see?" *laughter* 285 00:21:52,411 --> 00:21:55,814 "Was that a terminal screen?" 286 00:21:55,814 --> 00:22:00,237 And the answer is … "Yes" Yes, it was, 287 00:22:00,237 --> 00:22:04,468 specifically the "ipconfig" command output. 288 00:22:04,468 --> 00:22:07,414 Or in other words: What you just saw 289 00:22:07,414 --> 00:22:15,370 was me exploiting that five lines with a remote code execution attack. 290 00:22:15,370 --> 00:22:20,513 So now that you saw the magic happens, I think it's time for some explanations. 291 00:22:20,513 --> 00:22:22,487 The first line, responsible for checking 292 00:22:22,487 --> 00:22:26,221 if a file has been uploaded in the "file" parameter, 293 00:22:26,221 --> 00:22:29,956 doesn't exactly do as it says. 294 00:22:29,956 --> 00:22:33,803 Instead of checking if the "file" parameter is an uploaded file, 295 00:22:33,803 --> 00:22:39,230 it checks if one of its values is a file descriptor. 296 00:22:39,230 --> 00:22:45,110 Let me clarify that, instead of checking if the parameter is only a file, 297 00:22:45,110 --> 00:22:48,981 it checks if the parameter is also a file. 298 00:22:48,981 --> 00:22:50,476 *laughter* 299 00:22:50,476 --> 00:22:52,842 Meaning that uploading a file 300 00:22:52,842 --> 00:22:57,023 and assigning another scalar value to the same parameter 301 00:22:57,023 --> 00:23:00,147 will still work and bypass the check! 302 00:23:00,147 --> 00:23:01,460 WAT? 303 00:23:01,460 --> 00:23:06,435 *more laughter and applause* 304 00:23:12,066 --> 00:23:15,715 Creative fellows those guys are. 305 00:23:15,715 --> 00:23:22,137 So now we can assign the "file" parameter both a regular file and a scalar value. 306 00:23:22,137 --> 00:23:26,224 But what happens when we try to get the "file" parameter value? 307 00:23:26,224 --> 00:23:31,183 In a regular request, it should return the uploaded file descriptor, 308 00:23:31,183 --> 00:23:35,821 but now that we're adding another value to that parameter, 309 00:23:35,821 --> 00:23:40,596 param() returns a list containing all the values we sent: 310 00:23:40,596 --> 00:23:44,365 the file we've uploaded and our scalar value. 311 00:23:44,365 --> 00:23:49,191 But the "file" variable can't contain two values, right? 312 00:23:49,191 --> 00:23:55,221 So instead of converting the returned list into an array 313 00:23:55,221 --> 00:23:59,331 Perl only uses the first element of that list. 314 00:23:59,331 --> 00:24:05,564 So if we'll send our scalar value before we send our file, 315 00:24:05,564 --> 00:24:09,989 the $file variable will be assigned our scalar value 316 00:24:09,989 --> 00:24:14,308 instead of the uploaded file descriptor. 317 00:24:14,308 --> 00:24:19,623 Which means, that $file is now a regular string! 318 00:24:19,623 --> 00:24:22,114 *in high pitched voice:* WAT? 319 00:24:23,178 --> 00:24:26,127 But what happens to this operator when we use a string 320 00:24:26,127 --> 00:24:28,565 instead of a file descriptor? 321 00:24:28,565 --> 00:24:32,962 Well, the brackets operator doesn't work with strings, right? 322 00:24:32,962 --> 00:24:36,548 It works with file descriptors, why should it work with strings? 323 00:24:36,548 --> 00:24:39,200 Well, that appears true 324 00:24:39,200 --> 00:24:42,817 unless that string is "ARGV". 325 00:24:42,817 --> 00:24:47,644 *laughter and applause* 326 00:24:55,470 --> 00:24:57,627 That's not a crazy part. 327 00:24:57,627 --> 00:24:59,763 *more laughter* 328 00:24:59,763 --> 00:25:04,693 In that case the brackets operator, listen closely, 329 00:25:04,693 --> 00:25:07,668 loops through the script arguments, 330 00:25:07,668 --> 00:25:12,487 which in CGI comes directly from the query string instead the command line, 331 00:25:12,487 --> 00:25:18,844 and it treats them as file paths, inserting each one into an open() call! 332 00:25:18,844 --> 00:25:19,977 *again laughter* 333 00:25:19,977 --> 00:25:22,655 WAT? 334 00:25:25,632 --> 00:25:29,485 Yeah, that made sense in some point, I guess. 335 00:25:29,485 --> 00:25:32,487 All of this basically means that now, 336 00:25:32,487 --> 00:25:35,874 instead of displaying our own uploaded file content, 337 00:25:35,874 --> 00:25:39,749 we can display the content of any file on the server. 338 00:25:39,749 --> 00:25:43,334 But that's not the end, as we haven't executed code yet. 339 00:25:44,214 --> 00:25:48,808 To execute code, we have to look at the open() function. 340 00:25:48,808 --> 00:25:56,676 Again, this is the function being called with the ARGV values as file paths. 341 00:25:56,676 --> 00:26:03,054 open() is responsible for opening a file descriptor to a given file. 342 00:26:03,054 --> 00:26:05,874 Unless a "pipe" character is added 343 00:26:05,874 --> 00:26:09,036 to the end of the string, *laughter* 344 00:26:09,036 --> 00:26:13,259 and in that case instead of opening the file, 345 00:26:13,259 --> 00:26:16,228 it executes it… *applause rising* 346 00:26:16,228 --> 00:26:22,146 …acting as an exec() call! *more applause* 347 00:26:22,576 --> 00:26:28,512 So … when we send our exploit, 348 00:26:28,512 --> 00:26:34,631 containing our uploaded file, the "ARGV" malicious scalar value, 349 00:26:34,631 --> 00:26:37,635 and the ipconfig command followed by a pipe 350 00:26:37,635 --> 00:26:42,487 this is what we get. WAT? 351 00:26:42,487 --> 00:26:46,639 WAT? *applause* 352 00:26:49,165 --> 00:26:56,365 I know, I'm shocked too, but I'm not done yet. *laughter* 353 00:26:56,365 --> 00:27:00,723 Truth be told, I didn't write that code. 354 00:27:00,723 --> 00:27:06,159 Remember that PerlMonks told me that I should read their fucking manual? 355 00:27:06,159 --> 00:27:10,660 *more laughter* Guess where that code came from: 356 00:27:10,660 --> 00:27:22,979 the official CGI documentation! *big applause and audience whistling* 357 00:27:32,545 --> 00:27:36,347 But, I'm not blaming CGI.PM developers. 358 00:27:36,347 --> 00:27:41,365 Nor am I blaming developers who copied from CGI.PM examples. 359 00:27:41,365 --> 00:27:46,913 After all, who could have known that this is what this code will do? 360 00:27:46,913 --> 00:27:49,237 This is how it could be exploited? 361 00:27:49,237 --> 00:27:54,311 There's no exec calls, the file is not saved anywhere, 362 00:27:54,311 --> 00:27:58,163 and we're only using a "print". 363 00:27:58,163 --> 00:28:07,333 The sole responsible for this mess, is the Perl language. 364 00:28:07,333 --> 00:28:11,412 Perl is the one silently expanding lists, 365 00:28:11,412 --> 00:28:14,552 Perl is the one mixing up your data types, 366 00:28:14,552 --> 00:28:19,884 Perl is the one executing user input with no exec calls, 367 00:28:19,884 --> 00:28:22,800 Perl is the problem, 368 00:28:22,800 --> 00:28:25,502 not its developers. *applause rising* 369 00:28:25,502 --> 00:28:31,879 And until this god-damned, bizarre, dangerous language is fixed, 370 00:28:31,879 --> 00:28:34,216 you could only stop 371 00:28:34,216 --> 00:28:35,319 using 372 00:28:35,319 --> 00:28:40,207 Perl! 373 00:28:40,207 --> 00:28:47,005 Thank you! *more applause* 374 00:28:59,025 --> 00:29:02,754 Herald: So I guess we have some time for questions now. 375 00:29:02,754 --> 00:29:04,348 *laughter* Netanel: Maybe 376 00:29:04,348 --> 00:29:08,174 Herald: And I have the funny feeling, we will have some questions now. 377 00:29:08,174 --> 00:29:12,924 Ok, so we have some microphones here. Please queue up. 378 00:29:12,924 --> 00:29:17,959 Please do not shout in, because we need to record it on the stream. 379 00:29:17,959 --> 00:29:19,156 Well, here we go. 380 00:29:19,156 --> 00:29:22,776 And we also have some questions from the internet, don't we? 381 00:29:22,776 --> 00:29:27,274 Signal Angel: Oh yes, we do! *laughter* 382 00:29:27,274 --> 00:29:30,143 Signal: But before we come to the technical questions, 383 00:29:30,143 --> 00:29:33,411 the IRC wants you to know, what you did to it: 384 00:29:33,411 --> 00:29:37,425 it felt like there were explosions and camels everywhere. 385 00:29:37,425 --> 00:29:39,575 Netanel *laughing*: That's the point 386 00:29:39,575 --> 00:29:44,622 Signal: And incidently they want to know, if you have a list of those camel pics somewhere? 387 00:29:46,402 --> 00:29:49,663 Netanel: I think Google has it? *more laughter* 388 00:29:49,663 --> 00:29:53,796 Just there search camels. 389 00:29:53,796 --> 00:29:59,224 Signal: So for the first question. Opello(?) wants to know, 390 00:29:59,224 --> 00:30:04,293 if the take-away is, that Perl project authors so shouldn't trust input 391 00:30:04,293 --> 00:30:10,437 and instead verify types with REF and always use prepared SQL statements? 392 00:30:13,616 --> 00:30:20,628 Netanel: That's a good question. The take-away should be… *laughter* 393 00:30:24,039 --> 00:30:28,428 well, how will I phrase it … 394 00:30:29,424 --> 00:30:32,734 I think I have a slide … somewhere … *more laughter* 395 00:30:32,734 --> 00:30:36,303 Oh wait, where's my slide? 396 00:30:37,631 --> 00:30:40,204 Don't worry, have it right here. 397 00:30:44,224 --> 00:30:49,080 But really, trusting user input is always a bad idea 398 00:30:49,080 --> 00:30:51,831 and most developers know it. 399 00:30:51,831 --> 00:30:54,211 The problem is, that… 400 00:30:54,211 --> 00:30:57,178 well, at least from the code I saw written in Perl, 401 00:30:57,178 --> 00:31:00,091 and that's a lot of code, trust me 402 00:31:00,091 --> 00:31:04,794 …is that hashes and arrays are almost always considered secured 403 00:31:04,794 --> 00:31:09,143 as they supposedly can't be created by user input, as I said. 404 00:31:09,143 --> 00:31:18,196 But, when you're expecting your user input to be a scalar, a string or even a list 405 00:31:18,196 --> 00:31:25,846 and instead you get a hash from unexpected directions, you get confused. 406 00:31:25,846 --> 00:31:30,779 And you can't always live in the fear of not knowing 407 00:31:30,779 --> 00:31:33,613 what data type you're trying to handle. 408 00:31:33,613 --> 00:31:40,075 Well, not trusting scalar data types is a wise decision, because it's dangerous. 409 00:31:40,075 --> 00:31:46,119 But not trusting your hashes, as well not trusting your arrays? 410 00:31:46,119 --> 00:31:49,581 What's next? Not trusting your own code? 411 00:31:49,581 --> 00:31:54,274 You just can't expect anything to really work as it should. 412 00:31:54,274 --> 00:31:56,444 When you're writing Perl, 413 00:31:56,444 --> 00:32:03,899 you are constantly attacked by all these different directions. 414 00:32:03,899 --> 00:32:08,579 And even the data type direction is a problem now. 415 00:32:08,579 --> 00:32:12,652 I hope that answered the question beside the slide. 416 00:32:12,652 --> 00:32:16,335 Herald: Well, then we're gonna go over and start with number one. 417 00:32:16,335 --> 00:32:19,494 Questioner: So thank you for opening our eyes. 418 00:32:19,494 --> 00:32:24,254 Even I use Perl, I would say, for cooking and yes … 419 00:32:24,254 --> 00:32:25,718 Netanel: I remember you Q: Sorry? 420 00:32:25,718 --> 00:32:27,377 N: I remember you from the last talk! Q: No no 421 00:32:27,377 --> 00:32:30,508 N: Oh, you're new? Oh… *smirking* Q: I'm new, I'm new… 422 00:32:30,508 --> 00:32:36,068 Q: So… I can't say, I'm not guilty of that, but I still would say yes, 423 00:32:36,068 --> 00:32:39,508 Perl is a bit like cooking with my mum. 424 00:32:39,508 --> 00:32:46,315 Sometimes I put something into… the… with the boiling thing… 425 00:32:46,315 --> 00:32:50,864 and sometimes she, sometimes I go away, sometimes she go away 426 00:32:50,864 --> 00:32:53,894 and the only thing you can do is always taste. 427 00:32:53,894 --> 00:32:57,814 And yes, you're maybe right, Perl is a language 428 00:32:57,814 --> 00:33:01,822 where you never know what comes out, but it's real cool! 429 00:33:01,822 --> 00:33:04,583 If you get the right response you can use it, 430 00:33:04,583 --> 00:33:08,678 if you use it to write web applications I would agree. 431 00:33:08,678 --> 00:33:12,864 Web applications, the professional ones at least, are not for cooking, 432 00:33:12,864 --> 00:33:18,466 but for doing funny things and have some fun, I think it's a perfect language. 433 00:33:18,466 --> 00:33:22,296 N: I think Perl is a lot of fun. *laughter* 434 00:33:22,296 --> 00:33:26,633 I completely agree on that. *laughing* 435 00:33:26,633 --> 00:33:29,144 Herald: Then we're gonna go over to two. 436 00:33:29,144 --> 00:33:33,741 Question: Was your life ever threatened while interacting with the Perl community? 437 00:33:33,741 --> 00:33:35,794 *laughter* N: Could you please repeat that? I … 438 00:33:35,794 --> 00:33:39,545 Q: Was your life ever threatened while interacting with the Perl community? 439 00:33:39,545 --> 00:33:42,515 N: Definitely. Definitely, 440 00:33:42,515 --> 00:33:46,729 I'm getting hate mail every day, living in fear … 441 00:33:46,729 --> 00:33:48,648 H: And over to the three, please. 442 00:33:48,648 --> 00:33:53,261 Q: I think I speak for all of us, when I thank you for this wonderful talk, 443 00:33:53,261 --> 00:34:00,086 N: Uh, thank you. Thank you really! Thank you. *applause* 444 00:34:00,086 --> 00:34:06,660 Q: Brilliantly executed, but… ehm… you spoke about Perl 5 I think. 445 00:34:06,660 --> 00:34:11,155 N: Yes, you are absolutely right. Q: As some of you might know, this christmas… 446 00:34:11,155 --> 00:34:15,032 *laughter* Q: …so tomorrow Ingo Blechschmidt 447 00:34:15,032 --> 00:34:20,047 is going to give a talk about how Perl 6 will make everything better 448 00:34:20,047 --> 00:34:24,161 and how everyone should start using Perl 6 and… 449 00:34:24,161 --> 00:34:27,893 N: It also craps rainbows Q: Yeah, of course… 450 00:34:27,893 --> 00:34:31,391 Q: My personal comment is: wouldn't it have happened 451 00:34:31,391 --> 00:34:33,945 with a statically typed language? 452 00:34:33,945 --> 00:34:39,450 So I think some nice folks at Haskell in IRC are waiting for you Perl developers 453 00:34:39,450 --> 00:34:44,753 to please come, join us … Thank you! N: *smirking* 454 00:34:44,753 --> 00:34:46,456 *Herald and Netanel start speaking simultaneously* 455 00:34:46,456 --> 00:34:49,446 H: …sorry, to answer first, where am I… sorry N: Ah, no..., I am not answering, just... 456 00:34:49,446 --> 00:34:55,526 just a quick note about Perl 6. This talk is all about Perl 5, alright? 457 00:34:55,526 --> 00:35:01,108 I … Perl 6 came out a couple of days ago and … 458 00:35:01,108 --> 00:35:06,848 ...from …at least from what I saw, Perl 6 is to Perl as… 459 00:35:06,848 --> 00:35:11,932 C++ is to C. It's the same name, but it's a whole different language. 460 00:35:11,932 --> 00:35:17,311 So yes, this is Perl 5. Maybe I'll come back next year about Perl 6? 461 00:35:17,311 --> 00:35:19,051 *laughter* Who knows? 462 00:35:19,051 --> 00:35:22,175 Herald: I'm looking forward to that already. *applause* 463 00:35:22,175 --> 00:35:25,128 *Herald pointing to Signal Angel* 464 00:35:25,128 --> 00:35:31,104 Signal: Yeah… Joerd(?) wants to know: of course you talked a lot about CGI.PM 465 00:35:31,104 --> 00:35:37,290 which you know was removed from repository from Perl even before your talk last year. 466 00:35:37,290 --> 00:35:43,399 So what about it's replacements from CPAN like CGI::Simple. 467 00:35:43,399 --> 00:35:48,265 Netanel: I don't know, I haven't checked it. When I decided on which modules to check, 468 00:35:48,265 --> 00:35:55,610 I took CGI.PM because even though it is old, it is the most popular in the world as of today 469 00:35:55,610 --> 00:36:03,161 and I took Mojolicious and Catalyst because they were really popular, too. 470 00:36:03,161 --> 00:36:08,129 So I didn't take the newest modules, I take the most popular modules. 471 00:36:08,129 --> 00:36:15,973 And I think, that's the important aspect of … deciding. 472 00:36:17,693 --> 00:36:20,869 Herald: And over to one, please. 473 00:36:20,869 --> 00:36:29,013 Questioner: Hi… I'm… part of the Perl community, and… *laughter* 474 00:36:29,013 --> 00:36:33,169 N: Hi! Q: But I just start with Perl – 5 475 00:36:33,169 --> 00:36:40,315 N: Uhh… ehm… uhh… didn't you… nhaa… *laughter* 476 00:36:40,315 --> 00:36:44,329 Q: We use Perl for almost every module that we have at work 477 00:36:44,329 --> 00:36:47,314 and this worked really fine. N: …yeah… 478 00:36:47,314 --> 00:36:51,920 Q: And I don't know why you're picking Perl as language to attack. 479 00:36:51,920 --> 00:36:59,099 It's a really old language, it's also every language that we can pick, that has problems. 480 00:36:59,099 --> 00:37:05,027 But it doesn't mean this has to die or stop using it. So I don't know why… 481 00:37:05,027 --> 00:37:08,561 N: …you're right, you're right. First of all, you're completely right, 482 00:37:08,561 --> 00:37:11,958 because a language shouldn't die, it should improve. 483 00:37:11,958 --> 00:37:16,880 C got critized and it improved. PHP got critized and it improved. 484 00:37:16,880 --> 00:37:20,163 Why can't Perl be critized, too? 485 00:37:20,163 --> 00:37:24,238 Why is it like a code, when you say something bad about Perl, then, 486 00:37:24,238 --> 00:37:27,254 I don't know, a horde of PerlMonks jumps on you? 487 00:37:27,254 --> 00:37:32,553 Why don't improve the language? Don't use it in your work though, 488 00:37:32,553 --> 00:37:37,766 it's dangerous. *laughter and applause* 489 00:37:39,506 --> 00:37:42,109 H: Then we're gonna jump over to five, please. 490 00:37:42,109 --> 00:37:48,513 Q: Hi. I'm not a Perl developer, but I use a lot of Ruby and Python. 491 00:37:48,513 --> 00:37:51,061 Is this really limited to Perl or 492 00:37:51,061 --> 00:37:54,169 does this apply to more or less any dynamic language? 493 00:37:54,169 --> 00:37:58,640 N: As I said in one of the first few slides, 494 00:37:58,640 --> 00:38:03,613 some of it also applies to Python. Specifically the thing 495 00:38:03,613 --> 00:38:09,867 when you can't specify what data types your function arguments can get. 496 00:38:09,867 --> 00:38:15,954 But, what's unique to Perl is that writing different code 497 00:38:15,954 --> 00:38:20,247 for different data types in one function is very, very common. 498 00:38:20,247 --> 00:38:23,181 You can do it in every language, of course! 499 00:38:23,181 --> 00:38:28,276 But it is very common only in Perl! And that is unique about it, 500 00:38:28,276 --> 00:38:32,501 of course besides the thing that hashes and arrays are secure. 501 00:38:32,501 --> 00:38:37,116 That's of course Perls only fault. 502 00:38:37,116 --> 00:38:40,098 H: Good, then we're gonna go over to six, please. 503 00:38:40,098 --> 00:38:47,295 Q: Hey! Did you say WAT more while preparing this talk or while holding it? 504 00:38:47,295 --> 00:38:56,782 N: Uhm. Both. *Laughing*. Did I rant? That was the … right? 505 00:38:56,782 --> 00:39:00,911 Q: Did you say it more while preparing it or while holding it? 506 00:39:00,911 --> 00:39:02,963 N: I'm missing your word, man, can you... 507 00:39:02,963 --> 00:39:11,468 Ahh, wat… WAT! Ohh… Yeah, both! *laughter* 508 00:39:11,468 --> 00:39:14,828 H: Ok, do we have another from the internet? 509 00:39:14,828 --> 00:39:19,420 Signal: Does your exploit also work in tainted mode? 510 00:39:19,420 --> 00:39:23,663 N: No, I believe not. No, it doesn't. 511 00:39:24,473 --> 00:39:26,680 H: And another one... 512 00:39:26,680 --> 00:39:35,537 S: Is there any Perl obfuscated code exploits like this for Catalyst or Mojolicious? 513 00:39:36,137 --> 00:39:39,437 *someone chuckling in audience* 514 00:39:39,437 --> 00:39:43,409 N: I've no idea, man, maybe. I didn't check it of course. 515 00:39:43,409 --> 00:39:48,082 I didn't check every module for every exploit, I ever want to create, but 516 00:39:48,082 --> 00:39:55,075 on CGI.PM, which is again the most popular CGI library, it did. 517 00:39:55,075 --> 00:40:02,566 So, maybe the internet can find more exploits. I know it can. 518 00:40:02,566 --> 00:40:06,622 H: Bring it on. That's it? N: That's it? 519 00:40:06,622 --> 00:40:07,775 Thank you! 520 00:40:07,775 --> 00:40:09,157 *applause* 521 00:40:09,157 --> 00:40:12,404 Herald: Thank you very much! Netanel: Thank you! 522 00:40:12,404 --> 00:40:23,033 *postroll music*