 Hello everybody, my name is Robert. I work for Pagely. I don't know if you guys know Pagely, but it's a routine work-press hosting provider I help their security handle their security and their privacy concerns Part of my job there is I investigate a lot of problems on our customer sites And sometimes those are hacks and sometimes those hacks me are because of vulnerabilities and plugins So hopefully you crowd will be able to be writing better more secure plug-in code when this is done And we don't get the hacks I'm kind of curious the crowd here or you guys raise your hand if you are a plug-in developer or interested in any plug-in developer And who is everybody else? So why are you here? Yeah, I'm a product manager and I want to get some background knowledge for security and I think I can pick up enough, but I won't Go ahead now And you? I have just one to learn in the future Okay, so developer product manager, sorry This is it or this talk workshop is gonna be writing code We're gonna take breaks so you can write code if you need to go to the bathroom, whatever It's okay. You can just go but we're gonna be Somebody here has their own plug-in. I'm assuming you're gonna be investigating these things that I'm pointing out in your own plugins But if anybody needs a plug-in, I have Copies of a very popular plugins right here so you can audit somebody else's code if you'd like is there anybody would like one of these I Like it back. I got four to hang around Pass those out They think the blue tag is Mac formatted so it'd be faster copies and the yellow see if it works. Tell me if I have a reverse The plug-in repo is about 30 gigabytes everybody if you did not know this it takes a very long time That's why I've condensed it down to about two gigabytes of data that you can copy over so it may take a few minutes Well, this is it. This is about me I work in a also previous to page Lee I worked as the head of security a dream host and I was a security researcher for a company called trust wave During my time at trust wave. I was writing exploits for WordPress and getting those patches rolled into core and for many plugins The Workshop's gonna be really basic and do the introductions right now. We're in the USB disks are out there So you guys are preparing your your workspace Generally, what you're gonna want to do is have your laptop open so you can look through code And I can show you guys how to dig through code, but however you do it is best and then you go through just four basic examples of various vulnerabilities such as object injection cross-experimenting SQL injection I Know it's called authentication at endpoints But it's basically protecting your endpoints from attack and then some notes on my experiences of a security researcher side and WordPress hosting employee Things on how is the best way to handle security concerns? And if there are any of the plug-in authors here you guys handle security issues in your plugin Who wants to admit it nobody? Was it a pleasurable experience or Is not fun. Yeah, I'm gonna have to clarify too. I'm a nice guy I'm super happy guy, and if I write you about your plug-in Sorry, but I mean only love only love is coming from me towards the reporting of vulnerability But from your end I understand it's scary and very very very negative emotion feelings So yeah, we're gonna I said we're gonna live code So is those USB disks are they moving fast enough? Yeah, the blue one is Mac only the yellow ones are fat 32 format, so you can use it all into or Linux A blue is fine. Okay, good. Maybe I had to reverse Also the request because we're gonna be looking at live plugins if they are not your plug-in Team did you need to tell me if you actually find a vulnerability as important actually you know to find the author of the plug-in No, there's nobody's gonna walk away from here I please ask that nobody walk away with a vulnerability in a plug-in not being reported You can also set up WordPress if you want if you want to do proof of concepts I'm not gonna go that deep during this, but if you have questions on how to do validation of a Vulnerability writing a proof of concept we can get into that for that You're gonna need to have a WordPress install that you can work on it should be your WordPress install not somebody else's Well, you can also set up a VM if you want so again Keep going through those USB. Are the USB things at least moving fast enough or they're still stuck with one person Who had raise your hand if you have a USB disk, okay? Is it slow or? All right Slow They said some of them are fast and you have a choice on them I think I have like a 16 gig tar ball the whole thing You might not want to copy that one right now. We need to just copy the two-day for gate folder. All right, but yeah, this is a We're gonna get going You're shortly We're gonna stop talk about my favorite vulnerability. This is a vulnerability that's been an issue For the last year or so with WordPress and plugins. It's not a very popular one So I'm actually gonna start with a really high-end stuff. This is called PHP object injection I want to hear well people use Object objects in PHP all the time right your code bases to use objects. It's a great way to handle your data Classify data. Just be a simple thing like an array the problem with object injection how it works is that you plug in developers? Unfortunately are choosing to store an array. Let's say they collected a list of data. So an array object and Let's say it's a shopping cart site So you you just have a list of the things in some of the shopping cart you stored it in either your custom object or just let's think of it as an array and You want to store that with a session for the user, right? So maybe and I've seen this a lot Maybe you store that object of PHP as a function called serialize and it changes the object from actually being an object and PHP Into just a string almost human readable and then you can store that data that string serialized object in Let's say a cookie you can give it to the browser and the problem is You'll how it normally functions is that the browser source is cookie with this array in it Basically, it's stored serialized and you get the data back via the cookie or maybe a post or get request or some of the data format data and then you put that serialized string into a Back into PHP to recreate that object as it existed before it's a really fancy way to do this. It's very convenient the problem is You can read what's on the screen. This is officially if PHP dot-net's Description of serialized and un-serialized is they do not pass untrusted user input into un-serialized Because when you get the data back from the browser and you expect it to be an array or serialized array And you'll be creating that array that seems like it's fine The problem is that object that array could be anything because you gave it to the browser and the browser can just change it It could become a different array It could become an actual object that's a part of WordPress or it could become a bit because you're accepting the serialized string from the browser And creates any sort of object class it basically the browser wants or in some cases the attacker wants and That can do unexpected things in code because well your code was expecting an array a list But instead you got an object that was used to make a SQL query or in the beginning of the object is created during the Wake-up call it does a pain back to another file system somewhere. Maybe your code base you wrote an object in PHP that does Like a delete action or a user management action and when it gets created it it runs these commands right away So the problem there is that it's user inputted data So the user inputted data from the browser basically comes in back and see your code your code the second it creates the object It just runs something unexpectedly totally different in the perfect world in 99% of the time The array comes goes to the browser and comes back as an array But an attack world the object can come back as any sort of thing and they can do very bad things from there I know another thing problem about this is that PHP has released their exploits in PHP itself that You can use You can overload the object creation when you've passes it through unsealized again to try to recreate the object You can overload it and they see PHP will do remote code execution. It will crash You can exhaust resources things like that and PHP officially says it's this is their official statement The fixed work is very easy exactly what they explain here. It's use JSON JSON encode and decode the example of an array list A JSON is perfect for that. It makes a lot more sense than the serialized string So we're gonna go This is the common stuff or object injection whenever I have to talk to developers the developer thinks I'll just serialize this object. It's so convenient to use this function An attacker says here's an object. I want PHP to create and they'll create any object in your code base at once or attack PHP well bad objects makes PHP crash and I for the last year keep having to clean this up And I've written a lot of plug-in authors About these problems and luckily most of them have been very understanding and have been applying patches This is what I explained earlier without using the slides So yeah, they use a tactic to be a cookie or post data and it creates any object. They want in the PHP code This is what I mentioned about the formalities in PHP core It's not even wordpress this fault there to now surface and remote code execution can happen Run the solution as well. I'm sorry. This is the first time I do the slide deck So I'm just telling you what I intended to explain. That's nicer, right? You guys don't like to read slides, correct? I'm sorry. I didn't do pictures of cats should have been pictures of cats That's my other methodology There's a quick note here, too Like I got a nice email From somebody who who was I wrote when I wrote about this on the page to blog and I was explaining the attacks that we're seeing and like How to defend like what we've been doing working with plug-in authors to patch it Somebody wrote me really nice guy and he's like, hey, have you looked at the maybe on serialized function? which is part of wordpress and And I was like, wow, it's so interesting. So I looked into it. I'm like, maybe there is maybe there is a correct Solution here and wordpress already solved it for me So you look into it very deep and I see that all it does is basic validation that it kind of looks like an object But it doesn't do any sort of security and there's many other ways we do objects and objects you nest objects within each other Because an object that can be used in like an array a list of things that array can be object Oh an array of objects so you can nest objects within it. So like it doesn't do the proper validation PHP 7 included a functionality which does the proper validation for objects The problem is you have to be on PHP 7 Otherwise and that ruins your backwards compatibility because you can't call the new version of serialized PHP 5.6 or earlier. You're just gonna be breaking your compatibility problems So maybe I serialized in the end. Unfortunately, I had to write back and I said it doesn't do anything It's not thing and in fact it gives a false hope because it sounds like just based on the words It's maybe on serialized means like there's a safety check in there And there was none an unfortunate the very nice individual who emailed me never emailed me again, and I felt like I thought he was very Maybe my wording was it was too anxious and excited about how you read this and the opportunity and then I knocked it down It's like it does nothing. It's a false hope So I'm gonna show you some code By the way all the coding examples I got from WordPress Voluntary WpVoluntary.com Who here is familiar with this site? Good one person If you want to like continue what you learned in this At home or in your own little more principle and database they list all the current vulnerabilities And you can kind of see exactly what the code is So when you look at the comparison when they do the change the change you look at the diff to the two files They're like, oh, this is how that vulnerability works. And this is how this guy patch that vulnerability That's sort of like extra credit work if you guys really want to do it It's literally what I'm gonna be doing here found the vulnerabilities on WP Voluntary I did the diffs and I'm gonna show you guys code example about what worked what didn't work The so I had a question for everybody here now There's an object injection attack here. Who sees it? Which line for what the others it's there, but Yeah, the backslash It's not worth a promise. I don't know if the slash I don't even know that setting it could be and I don't know that slash is really for in that function But there's an object injection attack there Nobody's got it. I'm gonna be five seconds Yeah, it's a serialized call. That's it. That's the problem more so is that it's using set cookie so it's taking the data from a serialized call so it's serializing that data and Creating an object or taking an object creating to a serialized string Storing it in a cookie which stores in the browser and that's not really what the unserialized attack is But that's the first step the second one is right here on line 4 4 3 to return to data when they try to recreate that same value that same variable Return data that the idea in the program. I understand what they're trying to do here But when they call unserialized against the value of a cookie of inviting one, right? That is where the more ability exists the call for unserialized from data that was sent from a browser Which is a cookie data and that line 4 4 3 is actually where the the whole thing happens The two two lines together this to it's a code or kind of what make this scenario bad You don't have to hash you can just instead of whatever that returned data is it should be a different data structure So in this case, it should be Jason. I think the next one will be the example This is the diff and literally all they did was change it from Unserialized Jason decode what this cookie value is is a great way to store data from the site Let's explain earlier. Let's say it's a list. So it's like an array, right? And they probably had it like what would store in the browser for right now and they'll hold on to that data Then they give it back to me later. The problem is when you get it back later, we run unserialized that function name That's really where the problem is That's where everything they see falls that falls apart and there is an active or abilities for this plug-in Which is called invite anyone is the invite anyone plug-in author here Is that you? I Also should warn I don't I didn't I should apologize now if the plug-in authors for any of the excluded code Or here I apologize. I'm not making fun of the plug-in authors By the way, it's just I'm trying to these are great ways to see the code samples to see what led to a vulnerability existing code so this So it makes sense why this is why this works now It's literally in order to look for this yourself if you're gonna look at vulnerabilities To see if you're doing it right you literally just look for the unserialized function call and you got unserialized function call and On top of that the data that it's being unserialized Ever existed on the browser or is controlled by the user? I mean it could be in the browser you can even be in the database It's a little hard from the database, but it's really from the browser is the problem And then that data that they send back in the any object they want and that's where this vulnerability exists And do another code example Yes, the user controls the cookie I'm sorry yes, the The solution to all of these he's right He said the problem is is that the user can edit and manage the cookie right and that's data from the browser and the big mantra I wanted to say with this talk is never trust user input Is everybody like that's really everybody can leave now just have that one rule when you write code Oh Yeah, don't trust your data is well something The concept of security and that is they want to validate and sanitize So you validate the data when it comes in to be exactly what you expected it to be you could do a very Convoluted fix for these as well where you validate that the object before you unserialize it You validated that is the type of object class you expected. That's actually what PHP 7 introduced You can do an extra argument to the unserialized function call and say Unserialize this only if it's this type of class or if it's only this type of object and it's an extra argument That's why I apologize if I'm going too quick or like missing a core topic I'm doing a more high-level talk again. I haven't done this exact talk, but I'm also Gonna apologize because I didn't dumb down anything. I didn't make anything too basic probably your biggest problem You're doing good marketing product manager, sorry Again another example Who wants to point out the failure you get it? Yes That's it. You just look at this is the same. It's really easy. You just look for unserialized And of course the data the fact the validates on line one six one is that the data value of data is the post post request it's a The post value or is so they sent they decided to look somehow Have people send post data with the unserialized string from the browser, which is a very awkward thing It's also not sense. Yeah. Yeah, anytime you see code that goes directly from Post or cookie or get again all of these things are User inputs the user controls that data you should never trust the data from the user Even if you put the data there most likely this post order this serialized string is probably a hidden form field right because nobody's typing in a PHP serialized object they're very annoying to type in but I write them a lot because I Write exploits for this so I can write in my own my own object But look at it something that was convenient for him to store probably a hidden form field and once it came back to the browser Unfortunately, the browser also controls the post data. I'm old school and the fix. Here's the fix That's the same same vulnerability. That's the same plugin. Here's the fix. Look how easy that is These days on instead. That's so far. Everything is the same damn fix these days on You know, don't use uncrealized don't trust browser data. Oh, I got another vulnerability now somebody else should be able to get this product manager died over years women Yep They've been even better very obviously and the value of the problem there is that it's a get value So that's super easy to just inject they get base 64 decode as well Is that a is base 64? encryption or safe for anything By the way, they didn't do base 64 in this case actually like obfuscate the data They did that because WordPress when you send in a it does strip flashes and they need to be like Sorry back back ticks and stuff like a they they escape all the stuff and serialized strings are full of quotes and backticks and things So the a lot of fucking authors in order to fix what would be data sent over a poster of serialized strings And to work poster a get request they have to be 64 code the stream in order for it to be a Safety pass without WordPress mainly up the screen. So you see this it's not an attempt But I also wanted to make mention that base 64 is never is not security anything And here's again the fix Which is a funny one? remember when I mentioned that php7 has an extra argument to get to the to a Don't serialize This is them attempting to fix and this is sort of a fix But it's a it's not it's not a real fix at all The problem is that they also broke all their backwards compatibility It doesn't work in anything below php7 and because for some reason the The class that they were storing and getting back it is is the false class. It's like this is this is a bad fix unfortunately, I Forgot to actually like this plug-in author because this is still active. This is their last commit So this is a still vulnerable So I'll skip that one So I hope everybody's got some code in front of them I'm going to be open for any questions for like the next five ten minutes The goal of this is and hopefully is your plugins start looking for plugins. Do you guys know how to? I mean you guys need your favorite tools to do it, but I use just grep and Linux or OS 10 any Any a software you have that you can search for strings in your code basis, which I want to pull up right now And from the class, what is the string that you're going to be looking for? Yeah, let's see realize just look for that string see if it's taking data from the browser and then If it is change that to Jason and Jason will work most of the time Any other questions? So this is going to be quiet time to turn the music up and relax. I Like the music. Oh, yes I'm sure This is a bad one This is I wouldn't use stringify, but sure. This is probably the easiest one It's on Vika and Jason income. It's all you need Yes, why is it better to use Jason instead of I mean, I know it's not okay to use serialized But why is it better to use Jason since you can edit anyway, and you can go so yeah, that's a good question Why why does this not why is it not vulnerable now? Yeah, it's because from Jason If you don't it doesn't have to be Jason Jason's is convenient. It needs to be any other data structure You can do it as a darn CSV. I don't care. Yeah It just needs to be a list the difference is that Jason you cannot you only can Decode that to become a Jason string, right? Like it takes a Jason string and like re-creates the object as an array or a list Most of the time there will be exceptions to this Maybe you are sending in a really crazy object to the browser that like it's your custom object class But Jason will never you can never decode. Sorry. You can only take decode Jason to become a list or and When it's a PHP object and you expect it in a way you expected a list But I can from if it's a PHP object and even though your code is expecting a list The browser controls that that code or controls the object It's sending back or the CLI string that it's sending back when it creates the object and that that object can be anything That object can be any class that you have defined in your code base So when you expected just a list you get back, you know, and maybe it's your database object right, maybe you have an object class that you know, like I said creates your database or manages your database and Doesn't special stuff. Well that user creates that object that manages your database and also sets all the values Does that make sense? The problem is is that Jason can only Jason will only over be a list and When it's an object it can be anything in your PHP code base An object yeah, yeah Jason can never decode to become an object it always decodes to be a list a structured list But only one Yeah, you can decode Jason onto a Jason object class, right? We'll keep the question going everybody else who's looking at code I don't really look at the clock to see when and if you guys get bored looking at your code then we can continue on but It's really good to have the questions right now, so really yes. Oh USB stick where are they at? Did they come back? I Don't know I should get those back and like them back. Who has the USB sticks? Needs one right over here Yeah, sorry, it's a lot of data Okay, that's not good I Didn't have I didn't hide any Stuff, but you guys can read that that's my hotel internet request time off request time out Just do a code example if I can Okay So I have this excellent Tool that somebody else wrote called WordPress plug-in slurper and it takes in all the plug-in repo and updates it In fact, there's so many files in this directory. I can't even run an LS right now There it goes I'm gonna look for well, I'm gonna find can you guys read that or should I make it bigger? Good enough. Yep. I guess I don't really old-school. So I'm gonna be using literally like old Linux commands It's good. It doesn't work. You need the other color. So what I'm gonna be looking for is a PHP files, this is gonna be really slow What I need to do I'm gonna grab these files. It's what I'm doing. Does anybody follow me along with this? I'm gonna try to be nice, but yeah, I'm using the find command to look for every page we file in every plug-in So it skips over images and such and then I'm gonna grab for when serialized And I'm gonna say maybe post about it. No, let's let's look for cookies, right? No, I'll find words. Oh, I forgot the path So let's go with plugins that start with the letter R now. Let's see if it finds anything Well, no, that didn't work directories Yeah, I don't want to use I don't want to search all of them because it's a lot of files. Oh Yeah, yeah, that is true. Yeah, I could have put in the dot at least now. I know it's running So anybody have a recommendation on how to do this faster so slow Well, that's true. I could do typef that'll skip the directories, but Gaps gives the directories anyways I'm on the R ease They're gonna keep finding Or if any plug-in authors want me to explicitly search their plug-in, I'll do that as well It's probably not working because I'm looking for cookie that should be There we go, there's more stuff These are pretty safe so far Here's one of the pulling the data as this you realize data is stored in the laser So your life data looks like it's stored in the options table. That's probably safe. Oh, look at there That might be a problem, huh? The second data that's got serialized is basically for encoded. That's a problem That's probably came from over get or post Anybody see one that looks really really fun for me to hunt down the request one. I Don't see it. We're I'll stop now. See how easy it is to find some We're finding bugs here. So where is request? The very Right here request game This is yeah, that's a straight shot right there savvy. Oh, they're very popular I saw their shirts Let me know if I'm going a little over over balance with anything here I don't need to again. I'm not trying to uh to make fun of any specific plugins. I'm just pointing out a vulnerability It's all love for me. It's also really fun Oh Yeah Okay, yeah, yeah, this is definitely I'm gonna do this code and then yeah, you get on that one So here we go. We see array key exists and Unser requests on serial. Yeah, just request key. That's it right there. So let's see if you can get to it in code It's calling this API request. That sounds bad Because that sounds like I can just hit their API and it's it's over. So I'm gonna be nice to them. I'm just gonna search very quick Yep, there it is right there. So I would say I'm not gonna do the full POC You're gonna be nice because then I swear a lot when I write POCs because nothing ever works, right? So it looks like they're adding the action to for this process API request. Do I have that right? right, so if I do this I don't know if I'm gonna get it right there But yeah, they basically have the action created. So I probably get the WP API request API Run that action directly if they have it hooked in somewhere and then it runs that pop function Which has that request data this right here So I would make a note like somebody should make a note to say This won't this plug-in this line not six and there's a lot of it, right? So and you what was there was a 30 what was it all on board or yes? Yeah, which one? Oh Which one feels this one right? Which one which one is it? You don't I don't see early access Maybe I have an old version of it. I don't see any foods folder. Am I in the right plug-in? We can update right now And you go check it out. I want to go. Sorry everybody. I don't have the code example But I want to see what this is and then we'll move on to the next folder ability Yes, yeah, it's re-creating an object right there Yeah Not very good it depends on what that object is and the purpose of the code. Are you the developer for it? No Well, so he said that he hardly understands the code. He said he's not the developer, but I Hardly understand my code half the time so Any questions on un-serialized? Yes product manager, right? I messed it up That's a great question of why is this why is this so prevalent? I can't use that analogy because it won't translate well when it's kind of a talks about bodily fluids, but the What the problem is is that I think people look at code and they learn from reading of a code Right you learn by looking to see what other people are doing and unfortunately I think it became so prevalent because it was prevalent already a few developers wrote their code to use un-serialized in these fancy Ways and somebody just conveniently used it and then they see other people using un-serialized data and post requests and cookies and they Look if you look at the plug-in repo There's so much of it that you think it must be safe because everybody does it and there's not enough people that say They literally what php.net says which is Everybody skips over to this section right here this big red Teal salmon colored box on php.net when you look at how done serialized function works And they don't read that little bit that says don't pass in untrusted data and the problem is in ways It's just it was prevalent already in the plug-in repo and code examples And it just kind of became this thing where everybody does it It's not super good But again, hopefully and then of course I'm trying to fix that by telling everybody here how would be How the exploit vector works? I'm also gonna have to save myself unfortunately. I'm not telling you exactly how to explain it. So So that's your extra credit if you want to do it That's you doing you Question Yeah, sorry, I'm gonna politely I mean later at the bar we can start arguing and I can start writing people concepts but I'm telling you I'll have to fix it That's my goal