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