WEBVTT 00:00.000 --> 00:16.000 Good. 00:16.000 --> 00:17.000 Nine o'clock. 00:17.000 --> 00:18.000 First, then people. 00:18.000 --> 00:19.000 Welcome. 00:19.000 --> 00:20.000 Good morning. 00:20.000 --> 00:25.000 And thanks for waking up early to be here with us today. 00:26.000 --> 00:38.000 So, if you read the news lately, these last days, there was some publications about some issues found in open SSL. 00:38.000 --> 00:39.000 Right? 00:39.000 --> 00:48.000 With some security security issues, due to some bugs that opened back door. 00:48.000 --> 00:53.000 In open SSL, some of these were found by artificial intelligence. 00:53.000 --> 00:59.000 And some of these were present for more than 20 years in the systems. 00:59.000 --> 01:05.000 That's a bit what the situation that we have with the PHP engine. 01:05.000 --> 01:12.000 And that's why we have Alexander with us today to lead us through this story. 01:12.000 --> 01:19.000 So, Alexander is the city of 80L.cop. 01:19.000 --> 01:22.000 Let you go, go, go. 01:22.000 --> 01:23.000 Right? 01:23.000 --> 01:30.000 This is also an active contributor of the PHP Franken, and also a contributor to the PHP language. 01:30.000 --> 01:39.000 So, ladies and gentlemen, please welcome Alexander Dubois. 01:40.000 --> 01:41.000 Thank you. 01:41.000 --> 01:48.000 Really glad to be here to present some security talk and talk about PHP. 01:48.000 --> 01:50.000 Really glad to be at first them. 01:50.000 --> 01:53.000 This is actually the first time I'm coming to this event. 01:53.000 --> 01:55.000 So, yeah, pretty excited about it. 01:55.000 --> 02:00.000 It's really impressive the size of the event and the number of tracks that are in parallel. 02:00.000 --> 02:01.000 So, yeah. 02:01.000 --> 02:03.000 Really glad that you choose this one. 02:03.000 --> 02:05.000 And this is a right choice. 02:06.000 --> 02:13.000 So, yeah, let's talk about live exploiting PHP engine security bridges. 02:13.000 --> 02:16.000 So, I'm Alexander Dubois. 02:16.000 --> 02:23.000 I am citywatletiel.cop, French company, based in Lille, near here. 02:23.000 --> 02:28.000 I'm part of the symphony core team, symphony which is PHP framework. 02:28.000 --> 02:32.000 So, how many of you maybe know symphony? 02:33.000 --> 02:35.000 Great, and who use it? 02:35.000 --> 02:37.000 Oh, not great. 02:37.000 --> 02:41.000 Maybe more larvel or things like that, I guess. 02:41.000 --> 02:42.000 Yeah. 02:42.000 --> 02:43.000 Okay. 02:43.000 --> 02:50.000 So, yeah, I'm also part of the Franken PHP and PHP core maintainer team. 02:50.000 --> 02:54.000 And yeah, this is why I'm going to talk about PHP. 02:54.000 --> 03:00.000 Because this is my main expertise domain, let's say. 03:01.000 --> 03:04.000 So, at Lille.cop, we maintain OSS projects. 03:04.000 --> 03:11.000 So, we are French company that creates on-demand websites, applications and so on. 03:11.000 --> 03:15.000 But we also maintain open source projects such as symphony, API platform, 03:15.000 --> 03:19.000 API platform being like an extension of symphony. 03:19.000 --> 03:26.000 Which allows you to create easily API rest API restful APIs and things like this. 03:26.000 --> 03:31.000 We also maintain the PHP interpreter, etc. 03:31.000 --> 03:39.000 We are a few in the company to be a core maintainer of these things. 03:39.000 --> 03:42.000 So, I'm not the only person that maintains these projects. 03:42.000 --> 03:47.000 We are like three, four, five to actively maintain those projects. 03:47.000 --> 03:55.000 And so, yeah, as you can guess, PHP is our expertise because main open source projects are created. 03:55.000 --> 03:59.000 For PHP or in PHP. 03:59.000 --> 04:03.000 And yeah, PHP is very old. 04:03.000 --> 04:07.000 The first time it was released is like in 1994. 04:07.000 --> 04:13.000 And then in 60 years later, in 2000, then giant 1.0 is released. 04:13.000 --> 04:17.000 And this is a huge improvement for the performances of the language. 04:17.000 --> 04:23.000 And then four years after that, then then giant 2.0 is released. 04:23.000 --> 04:29.000 And this is the first time PHP can embed the object oriented programming. 04:29.000 --> 04:33.000 Before that, it was just functional programming and so on. 04:33.000 --> 04:39.000 And then in 2004, then there is object oriented programming. 04:39.000 --> 04:44.000 And in 2020, we have the just in time compiler that is introduced. 04:44.000 --> 04:50.000 So, just in time compiler is like a big optimization for CPU intensive applications. 04:50.000 --> 04:58.000 So, if you have like a lot of calculations and math and things like that, it's a huge per boost for free, literally. 04:58.000 --> 05:00.000 And it works really well. 05:00.000 --> 05:04.000 And then in 2025, we have PHP 8.5 that is released. 05:04.000 --> 05:12.000 And we are currently working on PHP 8.6 that is key to be released in November, 1226. 05:12.000 --> 05:15.000 So, yeah, 30 years and counting. 05:15.000 --> 05:20.000 And I'm showing you this to show you that the language is old. 05:20.000 --> 05:21.000 That's right. 05:21.000 --> 05:25.000 But it's continuing to evolve year after year. 05:25.000 --> 05:29.000 And bugger fixed and new features are introduced. 05:29.000 --> 05:35.000 And it keeps, yeah, catching up with modern languages and modern text and stacks. 05:35.000 --> 05:38.000 So, it's not like PHP 8 is dead and things like that. 05:38.000 --> 05:40.000 It's more alive than ever. 05:40.000 --> 05:49.000 We have the PHP foundation that now sponsors full time and part time code developers to maintain the PHP interpreter. 05:49.000 --> 05:53.000 So, yeah, the future of PHP is assured. 05:53.000 --> 05:59.000 And yeah, we'll see PHP in 10 more years for sure. 05:59.000 --> 06:01.000 So, this is a good look. 06:01.000 --> 06:05.000 The Github page of the PHP interpreter, PHP source. 06:05.000 --> 06:13.000 And we can see that we have more than 100,000 commits in 30 years. 06:13.000 --> 06:14.000 It's huge. 06:14.000 --> 06:20.000 So, yeah, this is a number of commits since the beginning in 30 years. 06:20.000 --> 06:25.000 And if you take it on those entire lifetime of PHP, 06:25.000 --> 06:32.000 it's nearly 5,000 commits per year or 13 commits per day. 06:32.000 --> 06:39.000 And the average time of 2 hours between each commit during the last 30 years on the PHP interpreter. 06:39.000 --> 06:43.000 And this is thanks to more than a thousand unique contributors. 06:43.000 --> 06:46.000 And yeah, my nearly 40 Github stars. 06:46.000 --> 06:53.000 So, again, I'm showing you this to show you that this is really PHP is really a project that is evolving and being maintained. 06:53.000 --> 06:58.000 Actively, like with 2 hours of average time between 2 commits. 06:58.000 --> 07:05.000 And it's not abandoned, I think, and it's still an excellent choice for your application. 07:05.000 --> 07:10.000 If you want to start a new project and things like that, this is definitely a good choice. 07:10.000 --> 07:14.000 And PHP powers 75 to 80% of the web. 07:14.000 --> 07:16.000 So, thanks for a press. 07:16.000 --> 07:21.000 Of course, if anyone wants to create an e-commerce or things like that, 07:21.000 --> 07:24.000 of course, they're going to have a look at a press. 07:24.000 --> 07:29.000 Thanks to all the one-click solutions provided by the cloud providers and things like that. 07:29.000 --> 07:34.000 But here are still PHP powers 75 to 80% of the web. 07:34.000 --> 07:37.000 And this is huge, of course. 07:37.000 --> 07:40.000 And as you can imagine, security is a big challenge. 07:40.000 --> 07:45.000 This is the most important yet complicated topic in tech projects. 07:45.000 --> 07:51.000 And with a project that powers that much websites all over the world, 07:51.000 --> 07:56.000 you can imagine that this is really a big challenge as well. 07:56.000 --> 08:04.000 So, if you have a look at the GitHub page of the projects, again, you have, of course, the security tab, 08:04.000 --> 08:14.000 and all the security advisories that are published for the PHP source code, which is all the security vulnerabilities that were discovered in the source code. 08:14.000 --> 08:21.000 And of course, this is not all the security advisories for the last 30 years. 08:21.000 --> 08:26.000 It is just since PHP is on GitHub, but still. 08:26.000 --> 08:35.000 We have publicly disclosed security advisories that are just available here. 08:35.000 --> 08:44.000 And yeah, so you can see on the right some score on some severity for those bitches. 08:44.000 --> 08:50.000 And this is given thanks to the CVSS, a common vulnerability scoring system. 08:50.000 --> 09:01.000 So, this is a way to give some security escort to Narbitis and to know if this is bad or really bad. 09:01.000 --> 09:07.000 So, you have many factors to determine if this is bad or really bad. 09:07.000 --> 09:09.000 The first one being the attack vector. 09:09.000 --> 09:17.000 So, this is, this is, this vector is how you can exploit this vulnerability. 09:17.000 --> 09:21.000 Is it by plugging a USB stick? Is it by the network? 09:21.000 --> 09:24.000 And things like that. So, attack vector is this. 09:24.000 --> 09:29.000 Second vector is attack complexity. Is it super easy for anyone to use this vulnerability? 09:29.000 --> 09:37.000 Or is it super complicated and you have to to know many prior knowledge to exploit this vulnerability and so on? 09:37.000 --> 09:43.000 Third factor is privilege is required. Is it security vulnerability accessible to anyone? 09:43.000 --> 09:51.000 Unauthenticated user and so on or does it require to be an admin on the website or to be authenticated and things like that? 09:51.000 --> 10:08.000 User interaction. This one is pretty important because this is, you are going to tell if the security vulnerability requires someone to do something on its own to use it. 10:08.000 --> 10:18.000 This is really bad if you have a security vulnerability without any user interaction because this means that you can just use a virality without anyone noticing or doing anything. 10:18.000 --> 10:26.000 And of course, it's order for the security vulnerability to be exploited if user interaction is required. 10:26.000 --> 10:35.000 This factor is a scope. So, does it affect the whole project or just a tiny bit of the project? 10:35.000 --> 10:45.000 Six one is confidentiality. This means that does your security vulnerability is known by everyone. 10:45.000 --> 10:52.000 So, this is really bad or no one knows that it exists. So, this is a better situation, of course. 10:52.000 --> 11:00.000 The seventh is integrity. Those security vulnerability compromised some of your data or not. 11:00.000 --> 11:13.000 So, in the case of the PHP interpreter, it doesn't make that sense but keeping mind that this scale is for all projects and yeah, this is why we have this kind of factors. 11:13.000 --> 11:23.000 And the last factor is availability. So, is it does it touch many versions of your project? 11:23.000 --> 11:42.000 For example, in the PHP source, if the security vulnerability is actually touching like versions since like 10 or 20 years, this is bad, but if it's only on the latest versions, this is less bad. 11:43.000 --> 11:51.000 So, this is how you can know if a security vulnerability is bad or not, thanks to the CVSS V3 here. 11:51.000 --> 12:02.000 And once you have answered all those questions, you have this, which is the string that represents everything that you just answered. 12:02.000 --> 12:16.000 And you can see that it's just actually all the factors that we saw with an answer. So, for the first one, we have AV, so attack vector and N, for example, or network or things like that. 12:16.000 --> 12:23.000 And we have also AC for attack complexity, high, low, non, things like that. 12:24.000 --> 12:38.000 And with this string, you can have the final score that you saw earlier on the GitHub page with the moderate low and so on. This is a thanks to this that you are able to categorize availability. 12:38.000 --> 12:55.000 So, depending on the score you have, the CDRT is different, so zero is none. Of course, zero to 3.9 is low, 4 to 6.9 is moderates 7 to 8.9 is high and then 9 to 10 is exceptional and critical. 12:55.000 --> 13:10.000 As you can imagine, critical and exceptional are not happening that often. Otherwise, we are all knowing that it is happening, like the XZ that we, security vulnerability that we saw, like one or two years ago. 13:10.000 --> 13:23.000 But otherwise, most of the security theories are between zero and seven, let's say. So moderates and low are the most common vulnerabilities of security. 13:23.000 --> 13:35.000 So, know that you know how we can categorize security vulnerability or security weakness. Maybe we want to know how they really look like. 13:35.000 --> 13:54.000 Because we all know about security, we don't exactly know what is it or how to use them actually, like how people that have bad intentions can use them and why they can use them. So this is what we are going to see. 13:54.000 --> 14:02.000 And I would like to present those first. One, I'm going to present is a CVE 2025 11. 14:02.000 --> 14:16.000 So new bad termination in host names. So this is something that happened last July in the PHP interpreter. So this is pretty new and yeah, this is what we are going to see. 14:17.000 --> 14:31.000 So this CVE is about opening a so-cat in PHP with the built-in function fso-copen. So for the people who know also a bit of C language, you also recognize this function, of course. 14:31.000 --> 14:42.000 Because sometimes PHP is just a CVE. A lot of system functions and built-in functions of PHP are actually just wrappers around C functions. 14:42.000 --> 14:49.000 Yeah, a few things of course to make it work with PHP, but it's just a wrapper. 14:50.000 --> 15:04.000 So it looks like this. We have the PHP function. So in this example fso-copen, when you call the fso-copen in your scripts, then we are going to call the wrapper in the PHP interpreter. 15:04.000 --> 15:14.000 Register this function and say, okay, I know this function and I can, yeah, just through and call it in the RIMC function. 15:14.000 --> 15:26.000 And not most, but often in the PHP interpreter, this is how it's done for system functions and low level functions. 15:27.000 --> 15:36.000 And yeah, the problem for the CVE is just here. It's not really the function, the PHP function itself. 15:36.000 --> 15:46.000 No, the wrapper of the PHP interpreter, but actually the underlying C function, but the underlying C function is not the culprit also. 15:46.000 --> 15:50.000 Yeah, we are going to have a look at this. 15:50.000 --> 15:58.000 So to understand how this security bridge works, you have to understand how strings are managed in C. 15:58.000 --> 16:10.000 So storing hello in the C language requires six memory blocks. So five memory blocks for the actual string and then one memory block, when additional memory block with a new byte. 16:10.000 --> 16:24.000 This tells the C language that this is the end of the string and this is a convention that all C programmers knows that the new byte is actually dominating the string. 16:24.000 --> 16:30.000 Because when you are manipulating strings in C, you are not manipulating just a string. 16:30.000 --> 16:45.000 Actually, you are manipulating a pointer to precise memory address. So you are at the first address with the H and then you also have the rest of the memory before that and the rest of the memory after that string. 16:45.000 --> 16:55.000 And if you want to pass the whole string in C, then you are going to just advance the pointer one by one, read the memory block. 16:55.000 --> 17:02.000 And then whenever you are going to encounter the new termination bytes, then it means that this is the end of the string. 17:02.000 --> 17:15.000 And we do this because if we try to read the memory block just after this one, we are not allowed and it's a null defined behavior, but it will likely crash and provoke a cycle. 17:15.000 --> 17:28.000 So this is how you know that a string is stopped in C. And the problem here, this is the whole problem that led to the security advisory. 17:28.000 --> 17:37.000 Because in PHP, you are like, okay, I'm currently manipulating the string, just a string. And in C, you are, I'm currently manipulating a pointer. 17:37.000 --> 17:51.000 So in PHP, because it's a loosely typed language, you have a huge structure to represent all variables, to represent your variables in your PHP scripts, with its typids value and so on. 17:51.000 --> 18:05.000 And many, many other properties like that, but you are manipulating, yeah, just a string. There is no manipulating the pointer, there is no manipulating the null bytes for the end of the string and so on. 18:05.000 --> 18:12.000 So the two representation are pretty different, and of course, C is more low level. 18:12.000 --> 18:29.000 And the problem with the CV is that the PHP interpreter is calling the underlying C function that relies on the null bytes to determine the end of the string, where in PHP, it's not a problem to have a null byte in the string. 18:29.000 --> 18:40.000 So it would look like this. We would like to open the sockets with F sockets, so we have local hosts, and then we put the null bytes. 18:40.000 --> 18:52.000 That's what we are going to see. But then the rest of the URL and the ports, and then we are going to write into the sockets, and then it opens the connection and we write something into it. 18:52.000 --> 19:02.000 But what's really happening here? This is a question. And this is what I want to show you right now. 19:02.000 --> 19:14.000 So let's take PHP storm, yeah, it's big enough, I guess. So we are going to type in with when and so, sorry. 19:15.000 --> 19:21.000 In this one, and we are going to just on the trainer. 19:21.000 --> 19:28.000 In the meantime, so yeah, my container here is just a PHP version, so 8.3.22. 19:28.000 --> 19:36.000 This is the latest version affected by this problem. So this is why I chose this version. 19:36.000 --> 19:48.000 And then we just copy the source into the repository to have our PHP server and we expose port 8080. So yeah nothing fancy here. 19:48.000 --> 20:05.000 One thing that I want to show you is, so okay, we run the container like this, so we expose the port with superb name here, vulnerable PHP, and also we are going to create a secret service. 20:05.000 --> 20:16.000 Into the existing container, okay, so this means that we are going to have a secret service or secret PHP service that is living right into the container. 20:16.000 --> 20:25.000 So it's not accessible from the outside of the container, but only by services that are inside the container because no port is going to be exposed. 20:25.000 --> 20:40.000 So I'm going to, like this, so we have our secret services with some API keys and some environment variables and so on. 20:40.000 --> 20:44.000 Okay, so now we are ready. 20:44.000 --> 20:51.000 Or set up as well here, and I can show you how the security vulnerabilities that I show you can be used. 20:51.000 --> 20:58.000 So let's get here and let's have a look at the first query. 20:58.000 --> 21:04.000 So we are going to call localhosts with a host and a file. 21:05.000 --> 21:08.000 Basically what we are going to do. 21:08.000 --> 21:14.000 Let me show you is we are, okay, so we are getting the request. 21:14.000 --> 21:21.000 We are gathering the hosts and the file parameters that are given in the query parameters, okay. 21:21.000 --> 21:29.000 And we are going to ensure that the host that we are providing is actually ending with secret partners come. 21:29.000 --> 21:40.000 So let's just imagine that this service is like, okay, I want this file on this URL for secret partners, so gather the five for me and then send it back to me. 21:40.000 --> 21:46.000 Because maybe only our PHP server can access the secret partner and so on, okay. 21:46.000 --> 21:50.000 So we are ensuring that it finishes by secret partners come. 21:50.000 --> 21:53.000 We will try to read the file on the server. 21:53.000 --> 21:59.000 And then we are going to open the connection to the hidden service, well, to the service, I mean. 21:59.000 --> 22:05.000 So if so, open with the host that we provided, some error management here. 22:05.000 --> 22:11.000 But if it succeeds and the sockets is open, then we can write an HTTP request. 22:11.000 --> 22:18.000 So we are getting the file and then we are writing into the sockets and we are waiting for response. 22:18.000 --> 22:25.000 And then we are going to wait for the response and then display it to the user. 22:25.000 --> 22:29.000 Okay, so this is what our script is doing. 22:29.000 --> 22:36.000 We check that it finishes by secret partner and then we are opening the sockets and retrieving the file. 22:36.000 --> 22:44.000 So if I'm doing this, we can see that an authority is domain. 22:44.000 --> 22:49.000 Why? Because our host here is not ending with secret partners come. 22:49.000 --> 22:53.000 So of course, it doesn't work. It is expected. 22:53.000 --> 23:00.000 But now, the moment of truth, we have a second query here and we have hosts. 23:00.000 --> 23:09.000 So local host again, then we have a null byte here because it is load in the query parameter. 23:09.000 --> 23:19.000 And then ending with secret partner that come just as we wanted to have in our indexed PHP and then the file. 23:19.000 --> 23:28.000 And if we run this, we can see that we actually gathered something. 23:28.000 --> 23:35.000 And this something is actually a secret service that was inaccessible from the outside of the container. 23:35.000 --> 23:44.000 So what's actually happened here is that, okay, we sent local host null byte secret partner come. 23:44.000 --> 23:48.000 So of course, this one passes because it ends with secret partner come. 23:48.000 --> 23:53.000 And then the host is provided as is to fsocopen. 23:53.000 --> 23:57.000 But fsocopen is just a wrapper to see underline function. 23:57.000 --> 24:02.000 And whenever it finds a null byte, then it will say, okay, this is the end of the string. 24:02.000 --> 24:09.000 So what happens is that it will see this and say, okay, this is my whole string. 24:09.000 --> 24:13.000 So I just cut here and then I will connect to my local host. 24:13.000 --> 24:16.000 And the whole thing here is discarded. 24:16.000 --> 24:22.000 And because I started some secret services on the local host inside the container, 24:22.000 --> 24:29.000 then because PHP is running also inside the container, we are able to access this secret service. 24:29.000 --> 24:35.000 All of this because fsocopen is just a wrapper to the c function. 24:35.000 --> 24:42.000 And whenever it saw the null byte, then it stopped and said, okay, this is the end of the string because everybody does this in c. 24:43.000 --> 24:51.000 And this is how, yeah, this vulnerability could be used in production until, yeah, version. 24:51.000 --> 24:56.000 It's like 8.3.22. So it was discovered last July. 24:56.000 --> 25:05.000 So it's not something that is old and like 10 years ago, I think that's, this is really something that is recent. 25:05.000 --> 25:11.000 So yeah, this is how you can, this is a security vulnerability that was patched. 25:12.000 --> 25:18.000 Lately, right, this is for the demo for this one. 25:18.000 --> 25:22.000 And we just did SSR, so server side request for jury. 25:22.000 --> 25:29.000 We asked another server to create malicious requests on our behalf. 25:29.000 --> 25:40.000 And then the server, the remote server sent this malicious request for us without us to do any request on our side. 25:40.000 --> 25:45.000 And this is a 5.9 on the CVSS score. 25:45.000 --> 25:48.000 So this is a moderate security advisory. 25:48.000 --> 25:52.000 But yeah, as you can see, even if it's moderate, it's impactful. 25:52.000 --> 26:00.000 And pretty easy to use, actually, because you just have to, yeah, put a null byte somewhere and you can put and should use it. 26:00.000 --> 26:04.000 So it's moderate, but impactful. 26:05.000 --> 26:11.000 That's a bit of the problem of this scale, because we could say that's okay, it's low or it's moderate. 26:11.000 --> 26:24.000 So it's not that bad, but actually, even if it's not critical, it could be impactful and should not underestimate what happens with security vulnerabilities like this. 26:24.000 --> 26:27.000 So yeah, language wouldn't raise our attack surfaces. 26:27.000 --> 26:29.000 So PHP is memory safe. She is not. 26:29.000 --> 26:32.000 And the boundary is where bugs are born. 26:33.000 --> 26:51.000 Yeah, it's like, it's not necessarily hold code that was a problem, but yeah, we had interface between two languages that don't have the same represented internal representation of variables and things like that. 26:51.000 --> 27:01.000 PHP strings and C strings are not the same, and because of implicit assumptions, we have vulnerabilities and it's not hard code that was a problem. 27:01.000 --> 27:11.000 It was obvious code, because of course, you are doing this wrapper and you don't necessarily think about, yeah, the null byte is different in C and so on. 27:11.000 --> 27:16.000 So it was obvious code that led to vulnerabilities like this, so pay attention to this. 27:17.000 --> 27:23.000 And yeah, security audits should include the runtime, so just the user name, not just framework. 27:23.000 --> 27:33.000 You should also maybe audit the engine itself, and it's difficult to audit anything, your app or things like that. 27:33.000 --> 27:45.000 But correctly, if you don't have a deep understanding of what happens underneath and how the engine turns on works actually internally. 27:45.000 --> 27:59.000 So yeah, to prevent this, we could just have sanitized a bit more the input and we could have just, yeah, say, okay, we take the host and we are going to sanitize and remove all the forbidden characters. 27:59.000 --> 28:05.000 We don't want to see like null bytes or yeah, whatever forbidden character you want. 28:05.000 --> 28:15.000 But we could have protected ourself easily by always sanitizing their inputs, always, always. 28:15.000 --> 28:28.000 Okay, so that was the first view of the idea I wanted to talk about, and now we are going to talk about the zero-dion bug door and when a full remote control bug door made it to one of the real estate of PHP. 28:28.000 --> 28:35.000 Yeah, this one's bad because bug door is bad, nobody wants a bug door. 28:35.000 --> 28:54.000 Back doors are intentional entry points in malicious entry points in a project in an application where it gives full control to someone just by doing something special. 28:54.000 --> 29:04.000 Like sending a special request and sending a lot and then this server is able to give full access to the people that know the bug door, but it should be invisible. 29:04.000 --> 29:10.000 And this is what we are going to see because this is quite an interesting story. 29:10.000 --> 29:15.000 So all begins with this commit, skip CI, fix typo. 29:15.000 --> 29:20.000 Fix typo, it looks pretty innocent, what could go wrong. 29:20.000 --> 29:29.000 That was on March 28th of 2021, so just four years ago, four or five years ago. 29:29.000 --> 29:33.000 So this commits, here is its contents. 29:34.000 --> 29:39.000 So yeah, what we can see is that it's not typo, definitely. 29:39.000 --> 29:45.000 We don't know exactly what it is yet, but that's not just typo, of course. 29:45.000 --> 29:54.000 This was added in zlib.c, so you can see on the top of the screenshot, the file. 29:55.000 --> 30:06.000 And this is very important because PHP is built with some an extension mechanism, which allows you to enable or disable extensions in your PHP setups. 30:06.000 --> 30:13.000 To have like a minimal PHP installation or have more features if you want to. 30:13.000 --> 30:18.000 But this one's a limit is enabled in every installation of PHP by default. 30:18.000 --> 30:23.000 And it allows to compress responses, sense back to the browser. 30:23.000 --> 30:26.000 So that's why it's enabled by default in PHP. 30:26.000 --> 30:36.000 So this means that the snippet that you saw would be put initially executed on every default installation of PHP. 30:36.000 --> 30:44.000 And this contains all the PHP version distributed by major Linux distribution. 30:44.000 --> 30:55.000 So db on Ubuntu and things like that have this extension enabled by default in their APT repositories. 30:55.000 --> 31:03.000 And then the whole thing is about this HTTP user agent with 2G. 31:03.000 --> 31:06.000 And this is the key. 31:06.000 --> 31:21.000 So what you have to know is that whenever PHP gets an HTTP request, it will automatically parse the HTTP adders and put them in a global variable called HTTP globals. 31:21.000 --> 31:24.000 And then they will be renamed like this. 31:24.000 --> 31:30.000 So this one, this means this is the actually the user agent HTTP adder. 31:30.000 --> 31:34.000 But we still need this type of course. 31:34.000 --> 31:43.000 And we are going to see what it is. So this is the heart of the code that was added in the fixed type of code. 31:43.000 --> 31:52.000 So basically what it happens here is that the first line so right in two lines is okay in the HTTP globals array. 31:52.000 --> 32:03.000 So where are all the HTTP adders find an entry with the HTTP user agent with 2G again. 32:03.000 --> 32:07.000 And if that case have a look at it's value. 32:07.000 --> 32:17.000 And if the value of this header starts with the zero-dium string, then then you are going to call this and ever string. 32:17.000 --> 32:26.000 And this function is basically telling PHP okay this is PHP scripts executed right now. 32:26.000 --> 32:37.000 So you feel it coming okay and this is pretty bad because basically if you have an HTTP adder called user agent with 2G. 32:37.000 --> 32:43.000 And the value starts with the zero-dium and you put anything any PHP scripts just after that. 32:43.000 --> 32:48.000 The server is going to execute it right away. 32:49.000 --> 32:55.000 So we are talking about zero-dium which is a zero-dave in the Arabic marketplace. You saw it in the code. 32:55.000 --> 33:06.000 Actually that was just like a troll or things like that of the person that did it to make it harder for the maintainers to understand where this comes from. 33:06.000 --> 33:13.000 But actually zero-dium which is a known marketplace as never is not related to this. 33:13.000 --> 33:24.000 So the disturbing discovery is that this commit so the skipsi fix type of actually created and pushed by Rasmus Lerdorf. 33:24.000 --> 33:29.000 And Rasmus Lerdorf is the creator of PHP. 33:29.000 --> 33:37.000 Yeah that's strange then this commit was reverted by Nikita Popov which is one of the biggest contributors of PHP. 33:37.000 --> 33:44.000 Okay and then just after that the revert was reverted by Nikita Popov. 33:44.000 --> 33:51.000 Right and then finally the final revert was done by Levi Morison. 33:51.000 --> 34:06.000 So they be your what happened why one of the biggest contributors of PHP would like to revert and then reintroduce it and why the creator himself would like to introduce such backdoor such obvious backdoor in the code. 34:06.000 --> 34:15.000 Well this is something that we are going to see just in a few minutes but all everything that we show you there it was just in a matter of a couple of hours. 34:15.000 --> 34:31.000 So it was pretty quick it was quickly seen that there is a problem in the source code but yeah it was reverted like in a hour or two after the first commit but you have to know that the commit was actually pushed to the 34:31.000 --> 34:46.000 release candidates of PHP and this is the biggest problem. Before going further I would like to show you how you and how this would have work if it was actually in the final release. 34:46.000 --> 35:09.000 So just here I'm going to just stop and it's one and the keynote of course the ways and then to the second one like this. 35:09.000 --> 35:22.000 So in the second directory we have yeah so index.php so just this one whatever way it's every request with response with a little from index.php and that's it. 35:22.000 --> 35:45.000 And here I have compiled a PHP binary with the backdoor so you cannot compile it now because it's too whole version but I took the latest version of PHP and cherry picked the commits just to show you how it would have work if it was in the final release. 35:45.000 --> 35:51.000 So we have the PHP compromised here so don't deploy this one on your service please. 35:51.000 --> 36:10.000 And we are just going to again like this okay so we have an HTTP server like this but it's compromised and I recall that we just have a row in the index from PHP and we are going to send requests like this. 36:10.000 --> 36:18.000 And as I told you we are going to send the get requests or first or anything like that with this. 36:18.000 --> 36:36.000 HTTP editor so user agent with 2G the string 0dm and then any PHP scripts just after that and here I choose to use system and then go to some directory and then print the directory and list everything in it. 36:36.000 --> 36:47.000 So if we ever run this request like this we have a response we have the response from the screens but just above. 36:47.000 --> 37:05.000 We have everything here so it printed the working directory and also it listed everything I have in this directory and I just put here a system but I could have extract any file actually it truly any PHP. 37:05.000 --> 37:26.000 PHP scripts but you can put in there so you can imagine what would be the images if we would have made to the final release but luckily it didn't make it to the final release so let me stop that. 37:26.000 --> 37:44.000 Imagine if this was in PHP right now I would mean that 80% of the web would be vulnerable to this kind of attack which is exceptional in this case because at a vector is super simple you don't have to be authorized. 37:44.000 --> 38:03.000 You can compromise any data super easy to use and you don't have to you don't need any user interaction to have it well this is it would have been a critical or exceptional security vulnerability in this case. 38:03.000 --> 38:13.000 Actually I told you that the creator of PHP committed this it was actually because the VCS server was compromised. 38:13.000 --> 38:41.000 Do you know that gets doesn't check anything in your name or thing that you could put any name you want when you push a commit in the get server until that and at this time the PHP organization was hosting its PHP source code on its own VCS server and this server was compromised and this is what led to it being act. 38:41.000 --> 38:48.000 Actually it was of course not Rasmus Lardorf or Nikita Popov that committed this apart from the reverse of course. 38:48.000 --> 39:04.000 But the actual commit it was some impersonation from someone we don't know who it is but they made it and they nearly made it because I told you it made it to the PHP 8.1 release candidate one. 39:04.000 --> 39:19.000 So it's not like a development version or an alpha or beta it made it to release candidate and if someone didn't code that then it would have maybe it would be still in the source code right now. 39:20.000 --> 39:35.000 So from this they GitHub became the official repository of the PHP organization because they were like okay we are hosting our own GitHub and it just gets on the so do we really want to maintain this and have to. 39:35.000 --> 39:50.000 Yeah, they teach and patch security the Narbitis and so on or self the response is no and at this time GitHub was just a mirror of the PHP source repository. 39:50.000 --> 40:04.000 But yeah, then they decide that GitHub would be the source of truth and they don't want to maintain any VCS server anymore themselves and yeah let that just GitHub do their job and it would be better. 40:04.000 --> 40:08.000 But we can still find the commit on GitHub as I show you. 40:08.000 --> 40:25.000 The screenshot that I show you earlier is still available and we can see some people that commented on the on the comments on the commit sorry saying what's that so it's not a typo and so yeah pretty funny so yeah trust is not a security mechanism. 40:25.000 --> 40:35.000 It was created by a repeatable author's well it seemed to on a repeatable project but it was still compromised and this is because. 40:35.000 --> 40:50.000 Yeah, okay we see Rasmus Lardo of the creator of PHP and so on but it doesn't it doesn't mean that it's this person that created the commit and yeah it's not because you see a famous name or thing like that that this is security mechanism. 40:50.000 --> 40:59.000 Once again because it's VCS and all those tools well doesn't verify the identity. 40:59.000 --> 41:09.000 By default so you can also have then you can have gpg and so on but I mean by default there is no verification whatsoever. 41:09.000 --> 41:16.000 The first structure is part of your tweet model so VCS here if this process everything is. 41:16.000 --> 41:25.000 Yeah part of your tweet model because everything here can be yeah compromised it's not just about your source code or it's not just about. 41:25.000 --> 41:34.000 Yeah reviewing your commits and put requests and so on here it's not the problem the problem here was that the VCS was compromised so. 41:34.000 --> 41:44.000 It's part of the street mode even if we could think that okay just the T the CI and things like that so we don't have to bother but yes you have to bother. 41:44.000 --> 41:47.000 Open source is not even but it is resilience. 41:47.000 --> 41:59.000 Thanks to open source it was detected and publicly documented which wouldn't have been possible if this was not open source if it was proprietary source code then nobody would have noticed maybe. 41:59.000 --> 42:18.000 And maybe we will have this back door in our in our PHP installations but this is only possible because of open source and this is why we always say that open source is more secure than proprietary software because this kind of thing can be audited. 42:18.000 --> 42:36.000 And seen by a hundred and thousands of people that just look at the code by curiosity or want to do some security audit and things like that on those projects and yeah this was detected thanks to this and because the source code was open to everyone. 42:36.000 --> 42:44.000 So yeah these are the few takeaways that I told you so yeah language boundaries are attack surfaces that structure are not the same everywhere. 42:44.000 --> 42:51.000 Security audit should include the runtime and sanitize your inputs please trust in nature security mechanism. 42:51.000 --> 42:58.000 Picture of your in front and open source is not even but it is really resilient and this is why we love open source. 42:59.000 --> 43:08.000 So yeah this was a two bridges that I wanted to show you and yeah I really hope that you liked to. 43:08.000 --> 43:27.000 To yeah understand what are those security but she's how do they look like actually in the code and how they can be exploited by people and to yeah know who to protect yourself again them because we always hear about security which is having their abilities and so but we actually don't really know what it is. 43:27.000 --> 43:35.000 Or what it looks like so I hope that I give you a give you a glimpse of what it is in security and yeah if you want to. 43:35.000 --> 43:42.000 For me for more blog post and things like that I'm being a space engineering goal if you want to have a look next. 43:42.000 --> 43:44.000 Thank you very much. 43:44.000 --> 44:06.000 We have seven minutes for questions so yeah there is one here. 44:06.000 --> 44:16.000 I thank you so for the first one you talked about how was it discovered. 44:16.000 --> 44:24.000 So yeah the the first security bridge was discovered well actually I don't have the name but there are people that are. 44:24.000 --> 44:41.000 sending emails to dedicated address of course if you discover some security vulnerability do not discuss them publicly and do not put them on an issue and GitHub of course there is always dedicated email address. 44:41.000 --> 44:50.000 like security at PHP.net or things like that and yeah someone sent an email saying okay I have this proof of concepts this is how you can. 44:51.000 --> 44:58.000 Yeah compromise something with this function and then we just have to patch it and it's the same for every. 44:58.000 --> 45:06.000 I'm hoping to project I maintain symphony front in PHP and so on everything all these projects always have. 45:06.000 --> 45:19.000 The dedicated email address where you can send some proof of concept and so on and we are going to acknowledge this problem quickly and tell you if it's actually confirmed or not. 45:19.000 --> 45:30.000 And yeah most of the time it's like this that we are aware of this which is. 45:30.000 --> 45:38.000 Yes no. 45:38.000 --> 45:42.000 I know it was super clear so fine. 45:42.000 --> 45:43.000 Okay. 45:43.000 --> 45:49.000 There are still five minutes so if you change your mind if you have a question and don't be shy you can come. 45:49.000 --> 45:51.000 If you have any question and just here so yeah just get me up. 45:51.000 --> 45:52.000 Thank you. 46:00.000 --> 46:06.000 Thank you.