Good morning DEF CON. Yeah. Uh how many of you guys went to the demon saw party last night? Anybody? Yeah? One guy? Uh the fact that you're here means that you didn't do it quite right. I was expecting no hands. Um did did you see McAfee last night? Yeah? I'm sorry. Uh alright so uh one quick announcement uh we're gonna get started uh we're gonna get started pretty shortly. Uh about 2 minutes we're gonna get this fine gentleman going. Uh when you leave the room uh please use the back doors. Not either side. They're pretty well marked. Um but back doors. Uh we had we had some issues yesterday. Uh the other announcement uh is uh yesterday uh we were told by hotel staff uh that uh there was some unusual traffic on their point of sale network. Uh so uh we're gonna get this fine gentleman here. Uh they have paid for a very very high class monitoring solution uh just for DEF CON and we have a very very superb I mean I know it's DEF CON but we have a very very good uh standing with all of the hotels and conference centers in the area for not messing with them too hard. Um POS system not cool. Please do not mess with them too hard. Um POS system not mess conference center or hotels network um at all please. Uh if you really feel like uh flexing some particular uh gray or black hat muscles uh DEF CON network is there for a reason. Bring it on. Alright uh so we are right about we are right on time. That is amazing. Uh so without further ado uh Benjamin Holland our first speaker of the day. Let's get a round of applause. Yes. Alright. Thank you everyone for coming today. Uh so my name is Ben and um today we're gonna talk about uh a way to develop managed code root kits for the Java run time environment. Uh so just a little background who I am. Uh I guess I would describe myself as a student. I've been a student for a really long time and probably will be for a little longer. Um so uh I've worked a few places um and I I come from Iowa State University. I see a few other people from Iowa State here. I'm a so yeah, represent, alright. Um, okay, so a little background. Um, first I just kind of want to show you a little, a little taste of what's to come. So here's our, our simple hello world program. Everyone's probably written this program before, right? Um, so let's, let's go ahead and run it on, um, our victim machine and see what happens. So let's go ahead. Okay, so we've got our just, uh, just a Windows 7 latest Java update, um, as of, so Java 8 as of like a week ago. Uh, we go ahead and run hello world, it just prints hello world. Um, but we've got a session on this machine. Um, we've got an interpreter running and we're going to load up this custom post module. Okay, and uh, we're going to go ahead and run this custom post module. I've got a, uh, a dropper here, we'll explain what that is here. We're going to go ahead and manipulate the run time a little bit, uh, and then go back over to the victim machine and see what happens. So now when we run hello world, it prints backwards, right? So we have the ability to manipulate the run time. And what are we going to do with that? Well, we can talk about that today. Okay. Okay, so first of all, um, we should probably understand a little something about what the, you know, the run time looks like, at least from a high level. Um, so we take Java code, um, just plain Java source files, we feed that into the compiler, we spit out class files, we could run those, uh, or if we have a bunch of class files, we just zip them up, and because we're Java, we call it a jar. Um, so that's just a jar, it's just a zip file. Uh, we take that jar file and we run it on our, on our host operating system, so that's Windows, Mac, Linux, and it seems to run the same on each one, right? So it's cross platform, that's really nice, but how, how do we do that, right? If you write a C program, you might have to change things a little bit. But with Java, at least it's, you know, it's standard. So, the way we do this is we create a custom, uh, virtual machine for each, uh, host operating system, and that interprets the, the standard Java bytecode, and then runs it on the host operating system. So, let's take a look inside those. Uh, we have the, the virtual machine, and then we have the standard library, right? We have the definition of what's an object, what's a linked list, all the different, um, primitives, um, in store, inside this, uh, run time jar, and what we're gonna do today is actually just mess with that run time jar, right? And because this run time jar is actually just Java bytecode itself, uh, at least for the most part, um, that also has this nice property of being cross platform, right? So we can write one exploit, and then run it everywhere. Okay. So, there's a few advantages, um, first of all I just want to make it clear that this is a post exploitation activity. So you've already, um, gained, uh, permission on the box, you can write to usually these kind of protected directories, so the program files on Windows is where they store the Java run time. Of course, if you didn't store it in a good place, someone could just manipulate it without having an administrator pro- privileges. Um, but the important part is that we're not manipulating the program itself, we're manipulating the run time. So actually we, uh, can effect every program that's running. So any, that, that hello world program, we didn't touch that program at all. We touched the run time and the hello world program behaved differently because we modified the run time. So, um, in know there's some nice benefits of this, typically we audit the the application code we don't audit the runtime um so you know someone might overlook this uh and we have a lot of contextual information about the application right so if we wanted to do something like grab the password field uh we don't have to write an entire keylogger we could just keylog maybe just password fields of applications. So we have some more contextual information at the application level. Um and of course uh since we're manipulating the runtime and we're doing it you know at an object oriented language these are full featured libraries so we can write object oriented rootkits we can use the standard library um we have lots of access to kind of some low level things that you might not think are in there so we can mess with key events networking all sorts of things. Okay so there's been some pioneering work um I'm not the first to do this and I'm not really expanding on kind of the the main technique I just want to expand on a new way to do this. Um and so Aris Metula um gave me this book um it's called Manage Code Rootkits um and uh he's done a lot a lot of work on this already um so if you're curious about you know kind of all the things you can do you can check out his book uh it's called Manage Code Rootkits um and he also released a tool called Reframe Worker uh it worked on dot net runtimes uh it was able to kind of specify XML uh tasks of how to manipulate the runtime uh and this uses an assembler and disassembler pair to make the modifications and has some deployment scripts so really kind of laid the framework um the groundwork for how how we're going to do these. Um but uh when I started thinking about this um I wanted to do this for for Java um because I'm kind of a Java nut as some of my friends know and um well this uh the the previous tool was for dot net so I thought well I have to extend this but I have an opportunity to to think about um you know how am I going to modify the runtime. Um so there's a couple different um ways you could approach this problem. We have uh bytecode uh we could just try to manipulate the bytecode right away. Um and then we have a couple different ways to manipulate the bytecode right away. Um but this is this is pretty difficult right? Uh it would work but say you change a variable name or a method name well that has lots of references in the code so we have to kind of change all those those little references and the butterfly effect gets kind of a a pain to manipulate. Also we you know most people don't speak raw Java bytecode code so um that's just kind of a pain. Um you know ideally we could just decompile this. Get the source, edit the source, recompile it and we're done. But if anyone's decompiled apps before um if you're lucky it that it even compiles it's probably not even right to start with. Um so decompiling things is definitely a hard problem. Um very hard and we're not going to have perfect decompilers. Um so people come up with things that are kind of in between. So we have these intermediate representations that are used a lot in compiler optimizations. Um for Java you can think about Smalley or um so it's Jimple any of those representations if you played with those. Um but this is nice because we can decompile it to this kind of half way point. So it's not quite source code um but it is text it is like it is a source code but it's not Java source. Um and we can edit that and then we can recompile it and we and we we come to this halfway point because we can guarantee that we can go um back and forth between uh decompiled and compiled output. Um so you know these the editing the bytecode works it's it's a huge pain. Um we can't really rely on decompiled source although we'd really like to work with that. Um and then working with intermediate representations was kind of my first approach um and you know it has been kind of proven people have done this. Um but it's still tricky. Um you know we we learned to write code at the normal source level. We don't write code at an intermediate level. Um it's just kind of a you know it's just something we can we can write tools for. But um yeah but it's still tricky. So I thought I really really want to to just be able to you know lower the bar the barrier to entry so that. Uh if you know how to write basic Java programs then you can write a managed code root kit too. Um so that's kind of the new the new goals of the framework right? I want to support the Java runtime environment and I want this just really low um knowledge prerequisite. So uh just quick show of hands like who has ever written just a basic Java program? Okay yeah so you guys can all write a managed code root kit now. So that's fun and also terrifying. Um alright so the other thing that I wanted to show you is that if you want to write a basic Java program you can write a Java program. So the other thing is we want kind of this natural development environment. If you've written a Java program you've probably used eclipse right? You at least whether or not you like it maybe maybe you like another uh IDE but um it's it's familiar right? You know how to debug your program you know how to um how to easily deploy your program. And again if we can write something from high level and source we don't we can strive towards this portability um and we don't have to worry about kind of low level details in the the runtime. So um I want to want to oh yeah I had this slide. Okay so we want to write root kits in Java source this is the tool itself I called it JRE reframe worker or um and that's kind of a rip off of Erez uh Metula's uh reframe worker um just because kind of a a common pattern is to just to add J in front of a Java project but then I noticed oh J JRE that's nice so I I kept it and I got it kind of attached to the name. Um so uh it's an eclipse plugin so you can work right inside eclipse um we have uh an ability to uh export a way to drop the payload on the on the victim machine um so that's that's all kind of abstracted away from you. Uh it's open source it's free so you can play with it hack on it um and uh have fun with it. So um there's been some early feedback on on twitter um so some guy said just what the internet is dire need of a well engineered malware development tool set. Um I think he was being uh sarcastic but I'm gonna take that as a compliment because I like the idea of a well engineered uh tool um from me. So um I want to revisit that hello world program so this is this is all the code that you have to write uh and the idea is what we'll do is we'll extend since it's object oriented we'll extend the object that we want to manipulate. Um and for now just assume that you can extend any object. Uh so here I'm extending the print stream. Let's see can I run the mouse? Yeah. Okay so I'm extending the the print stream and we have these little annotations that define how we want to manipulate the uh the uh the uh the runtime. Um and these are basically just notes to the tool. They won't end up in the final source. Um so we're gonna say we want to merge these two types. So we're creating a new class called backwards print stream. We're extending the print stream and we're gonna merge this new behavior in. And what we're gonna do is actually uh override the println method to just create a new string, reverse it, and then print that string. Okay um and so we have quite a few uh different annotations. Not not too many I guess actually. Um there's two main types. There's define and merge. Um so a define type basically inserts or replaces the old behavior. Um because sometimes you just want to completely blow it away and replace it with something new. But sometimes you want to preserve that old behavior and then you know maybe just hook into it or um or add a subtle difference to it but then behave like normal in other cases. Uh so that's what the merge type is. And you can put these on each thing. You can put it on a class, you can put it on a method, you can put it on a field. Um and then we'll get to why we need these later but we can also control the qualifiers and things like that. Um and then we'll get to why we need these later things. So if a class is final and you can't extend it well you can basically just say nope no it's not and then extend it. Okay so uh I'm gonna do just a quick demo here of of how to use the tool um so that if you want to play with it um that you can. Okay so let's go over here um so I have a little bit of test code here. Uh it creates a new file called secret file. It writes to that file just writes the word blah to it and then it checks to see if that file exists or not. And then just to clean it up we delete it. So if I go ahead and run this um of course it works. I just ran it with a normal runtime nothing's changed um but what we can do is actually override this. So I'm gonna extend the um file class and um okay so we've extended we can use the clips to kind of help us out here. We need a constructor okay no problem with clips so you can generate that for us. Um, I want to merge this, let's see, merge type, okay, I want to merge this into the file class and what I want to do is override the exist method so that if the file name is secret file, I'll just tell you it doesn't exist. Even though it does, we can still write to it, we can still read from it. Okay, so I'm going to use another annotation, this is just a, a basic Java annotation. It checks to make sure that the, the method we say we're overwriting is actually a method that we're going to override. Um, and this is the exist method, so public boolean exists. And, uh, we have to return something, so I'm just going to return false for now. Okay. And, um, so let's, let's check to see if the file name is a secret file. So, let's see. Uh, let's, let's first say if it's a file, um, and not a directory, for instance, um, and the name is secret, uh, secret, uh, secret file. Um, and then we'll just say, nope, no it doesn't exist, trust me. Um, otherwise, let's just use the default behavior. Right, so the default behavior, um, is the method that we're going to replace. So, I'm just going to return the original method. So, I'm going to use the super call for that. Um, so this will later get rewritten so that, um, all of this works. Okay. Uh, and then we also have to say I want to merge this method into the, uh, into the, uh, uh there we go. Okay um now there's an eclipse builder built into it um so yeah I guess I should first say you'll create a new project so you can do new uh other and then there's a JRE reframe worker project there's some support for other things too um and uh that'll set up the class path everything like that so as you're developing here you're not actually you'll be manipulating your runtime but you're not gonna actually affect it we're just gonna do it locally and then we'll just kinda hot swap it at runtime um so I'm gonna go ahead and build this project here um don't have a uh incremental builder yet so you have to do a build clean but things are coming it's a work in progress. Okay so uh we're building down here the progress um hope it works here uh pray to the demo gods. Okay so we run it uh with the normal runtime it says true but now we're gonna run it with our manipulated runtime and it says false so it worked okay um but we know that that file exists because we wrote to it right? So weird. Okay um now let's take a look at what happened under the hood. So I'm gonna load up uh just a JD GUI just an easy Java decompiler here um and let's decompile the modified runtime just to see what's in there. So I'm gonna go to Java file IO um go down to file and I will search for let's search for the exists method. Exists. Nope. Okay so here's the original method um and all we did was rename it so that we can call it later and then if we can find the other exists. Okay so here's our new one it's the code that we just wrote and the recall to super now just calls our other method which we um made private so that nobody can see it anymore. Okay so I'm gonna quit that we'll go back to the site and we're gonna go back to the slides here. Um so really easy right? We can test this we can run it oh I guess I could say um if we don't want if we want to actually debug this uh in our test code we could go back over here instead of invoking the file we could just try our our normal one so if we wanna set breakpoints stuff like that we can just debug it locally without actually manipulating the runtime uh and then um once we're confident with it we just change the target manipulate the runtime and everything will work fine. Okay so now we're gonna go back to the site and we're gonna have a little bit of fun right? We have a framework we can just start manipulating things. So this is um this is just kind of a fun one um what I'm doing is overriding the print stream object uh yet again um this time we define a new field um it's a integer called Beetlejuice and um every time the println method is called we look at the stack trace so we're looking to see who called us right? Um and if there was a method named Beetlejuice we increment that counter. And if the counter doesn't call us then we're gonna have a new field called Beetlejuice and if the counter is 3 then we call this call and we'll see what that call does in a minute. So we have to now think about what would trigger this code right? So we have um a method named Beetlejuice and we're going to uh invoke it 3 times and uh we're going inside Beetlejuice there's a call to println so we'll trigger that code and uh it'll go Beetlejuice Beetlejuice um if we run this normally it's not very interesting um because let me skip forward a little bit since we already explained all that okay uh if we run this normally uh it's not very interesting it just prints the hashcode of the Tim Burton object um I'm a fan of Beetlejuice anyway um but if we run this with our modified framework yes so someone has ported uh all of the Doom to uh pure Java and uh just as um just as you know a test um of how much complexity we can shove into the run time why not just shove the whole video game in there. Um so it about doubles the size of your run time but that's okay. Um but what's fun is um you know our client can have kind of fun little triggers you know of what of what we want it to um of how we want to trigger it. So here's another one um oh okay I'm gonna reordered my examples here. Okay so um this one is just kind of uh to show off the other things. So normally if you call the string replace method it doesn't modify the variable that it's operating on uh so the receiver variable it doesn't modify that. So in this case demand replace sacrifice with puppy then um you know it wouldn't do anything. So the the the normal behavior was you know it would just say Satan demands a puppy or sorry it demands a puppy. So it would just say Satan demands a sacrifice. But if we make strings mutable and we make this actually modify the behavior then string replace works like how some people think string replace works uh and actually print Satan demands a puppy. So um this one's tricky um because a string is sometimes treated like a primitive object so you shouldn't have to extend the string class. So they make it a final class um and you want to be able to treat it as mutable so you can make those assumptions when you're programming. Um and then you want to be able to treat it as mutable so you can make those assumptions when you're programming. Um and then you want to be able to treat it as mutable so you can mutable so you can make those assumptions when you're programming. Um so they actually make the the value of the string a protected uh sorry a private field and a final field itself ah so that you can't change it. But of course we control the run time so we can easily uh update that. We just say nope string's not final, nope the value field is not final, and hey lets make it protected so that we can actually manipulate it and play with it. Um ok. So uh we can do all sorts of fun things. So I just kind of went crazy. There's a whole bunch of modules that had to cut from this talk. just for time reasons um but I'll release them all on the github repo right after this. Um so this one uh is it takes whenever someone loads an image like a jpeg or something in the in a java gui uh they have to access the raw data of the image. So this just basically adds a hook that says um before you access that image why don't you pixelate it for us. Um and why would we want to do that? Well for the glory of Satan of course. Um and of course we control the pixelation so we can just make this as pixelated as we want. Um here's another fun one I really like um so this was this came from a talk and was partially the inspiration for this talk. Um was I was trying to to say you know what's the difference between you know how do we detect malware if we don't have a definition of malware. Um so in this case I wrote a spell checker. And the spell checker. Was just a normal spell checker. And then I went through and I inverted all the logic. Right? So what do we have now? Something that creates typos right? It just creates kind of realistic typos. Follows the same sort of rules they're just all backwards. Um and then what we can do is we can hook this into a key event. Um so that the faster you type the more typos we create. And then as you slow down we start to behave again. Right? So it's just kind of killing your productivity. Um and it's really annoying. Um in fact the first time I I tested this uh I didn't realize that Windows has two different run times. A 64 bit and a 32 bit. And um I was trying this. I was trying this and I I just couldn't get it to work. Uh and I was running on the command line. Uh and then I went back to Eclipse and I realized um it's working. It's just working on the run wrong wrong run time. Okay so I have a I have a demo of this. Um so you can you can tweak the parameters. This one's actually better to run um in some sort of test harness so you know what typo is mine and which one's not. Because I'm trying to type as fast as I can. So when it turns red it's typing a it's creating typos. And as I slow down it starts to behave again. Um and uh and everything's fine. So um you can kind of play with you know with the sliding average to see how devious you want to be. There's lots of parameters there. Um so that one's kind of fun. Oops. Okay back to slides. Okay um so now um I really liked this idea. Um so people will think about um you know we we have a CVE. And um you know we want to create antivirus to detect the CVE. Or to detect the malware right? But what is malware? Um so I like I like the CVE. I I I've gone through this a few times now. And and I really recommend if if anyone hasn't just pick a CVE and try to just understand as much about that CVE as you can. And you know go through, try to recreate it yourself. Um it's a lot of fun and you'll learn, learned a lot of things. So this one was um really popular. There was an exploit module. It worked on basically every platform. Uh the original bug was in Oracle itself so people like Apple uh copied it into their runtimes uh and uh you know it was exploited in the wild and people are just having all sorts of fun with this. Um and I think that's you know probably one of the reasons Chrome doesn't ever let you run an applet anymore. But um so we have an existing exploit for this. Um and and I wanted you know I did an experiment a little while ago uh about two years ago just to see you know how could I you know just change this a little bit just to get it past AV. So we all know AV is bad right? You know it's it's hard to write good AV I've tried. Um but anyway so let's just see you know what are all the different antiviruses doing. So I created um you know I took the original proof of concept um that was reverse engineered from the from the the malware in the wild. Um uh and I did a little bit of testing. I uploaded so this is 2014. I uploaded it to VirusTotal and um you know 30 out of 55 people detected this and this is two years after you know after the exploit was out. So you know not not great. Um but then let's just start refactoring it a little bit. So start changing the class names, the variable names and we we lose two people right off the bat. Right? We lose two AV right off the bat. Uh we start just obfuscating strings so if you know we have a string we just break it up and concatenate it. So you know now the AV has to kind of reassemble that or do some symbolic execution something like that. We can change the control flow so we can start merging methods, splitting things into multiple methods, add dummy um if branches, stuff like that. Um and that one didn't seem to do too much so nobody was really looking too hard at control flow. Um but then what we can do is start looking at okay well what are the key APIs that people are um you know that people are keying off of and let's just use reflection or another layer of indirection to call those um and then we can um so that um you know so we throw them off. And and we lose a bunch of people right away. But of course we we can do way better. We could just um you know put the whole class into a string, XOR it with just a simple key, just a one byte key. Um and then load it with a class loader at run time and run it. And so nobody gets that. Um okay so not a big deal. Uh if you guys want to play with this yourself the all the source there for for all the different versions is online. Um so I did this two years ago which was two years after the exploit came out. I decided let's just do it again one more time. Um so I run it again and uh well we got a new antivirus in the game. Um and six more people found it but it's there's still you know like 20 people out there that I can't find this. Um changing the class names so we actually got a little bit better right? Um things like changing the class names nobody's keying off of those sort of things anymore. Obfuscating strings still works a little bit. Um the reflective invocation still helps but still nobody can get the XOR or anything. And that's that's a hard problem I don't blame them. Um but it's just that easy right? Anyway um so why don't you know I was kind of bummed out this this this bug doesn't exist anymore. It was used lots in Java one seven. Um they fixed it but hey we control the run time so let's just put it back in. Right? And so I call this the reverse bug patch. Um so yeah so I I I'd love to uh automate this um and so someday I'll do it again. Um and so someday. Anyway um so the the fix was really really easy. Um so uh I started first I started um downloading all the versions of Java um and then uh started doing differencing on them. And you see the fix is um they just add uh two calls in um in the class finder uh object to check package access. And this was because um basically someone was able to use reflection to avoid a security check by um kind tricking um tricking the run time into thinking that the call was coming from a different origin. So we just add this check and we're fixed. Um there's another another check that was added to method finder. This this CVE actually consisted of two different vulnerabilities that were used together. So we had two separate bug patches. Um and then they uh removed a a field uh I think this was just a a case of refactoring later. They removed uh another method that we were using for the exploit. Um so no big deal we'll just put them back in for you. Uh and uh of course you know if you want to upload malware to a target yeah that's fine but why not just upload a vulnerability and then come back and exploit it again later right? Because if if we know we can't detect the vulnerability then we left ourselves kind of a nice back door. Uh and we have lots of examples of great vulnerabilities that nobody's looking for. Um so of course I mean this is expected you upload this to virus total the you know this modified run time and and nobody's gonna detect this. So we're not looking for the vulnerabilities we're looking for the exploits. Um okay so maybe some good uses um for this. So this was a uh um a masters project that um I helped a a student with at Iowa State. Um so he was looking at things like can I take old uh SCADA HMI applications and secure them somehow. Um and so if we have a SCADA HMI application a lot of these happen to be Java applets which would communicate with some backend server. Um so he started creating things like uh uh kind of a smart intelligent firewall, application level firewall um that would wrap the wrap the server, but then we need a way to if you know if we want to do something like support two factor authentication we need a way to um give some sort of feedback to the application so that the application can prompt the user for their their token and then feed that back to the firewall. Um and we can also do some things like add some profiling logics with do something kind of like active defense so um we can we can. Of course those could be disabled but we could also uh it's just nice to be able to add another layer of authentication. So in this case um we have this SCADA application we don't have the source code to it um but that's not too hard because we can just find the object you know maybe that controls this alarms list and say we want to add additional security around this alarms list we can uh we can add you know um the two factor authentication which uh lets you through the firewall uh just to access the alarms list data. Um so in this case um it's just a real simple couple lines of code um with some JSON that passes the the result back and forth um but we can add this prompt and secure this this um this application. So uh I added support to JRE reframe worker to modify applications as well um there's some really early basic support for Android stuff um that one's really early cause you have to go through some additional tool chains. Um but let's talk a little bit about the mitigation side. So how are we gonna you know I'm I'm trying to make this project I'm I'm making things a little bit worse by making it easy for everyone to write these. Um so let's talk about the mitigations. Um okay so does anybody see anything wrong with this picture? This is our file example before. Okay so um if we look at the line numbers these are these are added by the compiler for things like decompilers or debugging um adding to the stack trace you know what line you crashed on. Um but you can see that there's a lot of things that you can do to get rid of these. So you can see in my framework I wasn't too too worried about being super stealthy I just wanted it to work. Um but when I inserted the new the new method you know I didn't go back and recalculate the line numbers. So you can see at the end we're at the the end of the file and it's like line 2000 something and now we go line to 18 19 21 and then we're back to like 2000 something again right? So there's lots of fingerprints that um the run time's gonna get added uh you know if if you're not manipulating byte at the byte level um you can see at the end of the file some tool is gonna add some fingerprints um as a as a result of its manipulations. Um so we can start to look for these things. Um so the easiest way is probably you know have a baseline of all the files on your system and know when they should be changing. Did you run Java update? No? Then why the hash change right? Um but of course we can you know we've rooted the box so it's kind of game over for you anyway um because maybe I'll just backdoor the Java updater and after you update Java I'll remanipulate the box. So we can have a lot of fun with this. Um another kind of fun indicator was um the Java run time is about 50 megabytes but after I manipulate it it's about 25 megabytes which is weird but it's just because I'm using a different compression ratio. So I could try to match the compression ratio of the original library um but it doesn't matter. The jar file is a zip file so it still works um but those these are some of the indicators that you can look for. Um so we can do some code changes with the jref underscore. Um when you rename the the methods uh to to kind of preserve the old behavior by just renaming methods so um you could just look for that easy prefix. Uh I have a preferences menu if you want to change that prefix and not use uh this default jref underscore um that's up to you but you know there's still gonna be kind of a pattern. You could count the number of methods and know the number of methods in each class file and expect you know it's gonna kind of grow at this rate with each update um and if you see a huge spike then you should know why right? Um okay and of course we can use all sorts of code complexity metrics um but yeah we'll have fun with that later. So the biggest thing is being aware of it right? So if you're a forensic investigator um and things are behaving weirdly you might want to look at something like this. Um and this is generally an awareness project um you know Erez talked about this about 6 years ago and I was really surprised that nobody else had really done anything with this since. Um so hopefully by you know lowering the barrier to entry people can play with this more uh and and will be more aware of it as a as a community. Um so my biggest point was you know if I could do this as an evening hobby anybody could be doing this right? And if we're not thinking about it that's a problem. Okay so I have some Q and A um and if I have tons of time left I have more modules I can go through. So I'm gonna go ahead and start um but I'm happy to take questions. Um I just have this this kind of closing poem by Robert Frost which basically is my way of saying um there's a lot of work left to do on this um I'd like to support quite a few more things I'd like to look at other languages um so the Java virtual machine itself I'll come back to this but the Java virtual machine itself um isn't just for Java it supports lots of languages in fact there's you know uh Invoke Dynamic was uh kind of originally added uh to support things like Jython but um I'm happy to take questions. Um I'm happy to take questions um with all of their kind of uh dispatching. But um if we can manipulate the Java runtime itself we can start to kind of branch out and start to consider other things. So things like JRuby will just call into the the Java runtime jars to kind of reuse those languages so you can mix and match things. So if you have um a JRuby website you can start to manipulate it that way. Um and so I just want to say that it's not just about Java um there's lots of managed languages out there and they're all going to have the same sort of issue. Okay um so the source code's out there um if you're interested please play with it make feature requests I'm happy to support it um and I'd like to keep working on this. Um so thank you very very much for coming I'm happy to take any questions you have. Um thank you. Yeah that's fine. Hello. Hi. So if you're modifying skated devices perhaps to improve the security by playing with their Java runtime libraries, then the opposite question comes up. How in the world do you discover whether somebody else did it? Yeah um so you you're asking whether or not um so so if if if you modify the the the application how do we know if it was modified for good reasons or for bad reasons? Well um just arguing that the number one rule of security is that it's easier for the good guy than the bad guy. Yeah um so I think this would be something you would want to do I mean you would do this in house right you would have a specific need for this application that you you don't have the source code to this for whatever reason and you want to you want to add this feature or add this new building this is a way that you could sorry you could um modify that binary and then sign it and you know keep track of that hash in your in your deployment system. So it's I mean it's just it's I'm I'm not necessarily advocating for it but I'm not necessarily advocating for it but I'm not advocating that you should do this it's just that you could use it for this purpose. Okay so I'd have to have like um a a standardized deployment. Yeah I mean if you're deploying this if you're deploying this this already you should have some some system in place for how you're going to deploy it. Um you know of course if if the application is signed you're going to have to re-sign it with your own your own application key and keep track of that because you're not I mean you're not going you're going to violate the the code. Um so you're not going to be able to get the hashes in the the manifest by doing this. Thank you. Hi. Have you tried to circumvent the the requirement that cryptographic providers be signed? So you put in your own like key generator class in the uh JRE. Have you tried to do anything like that? No I haven't played with that too much. I I basically just got it working and then played with a few modules. Um are you talking about like the the class loader stuff or like application loader stuff? I'm not sure. Um I'm talking about like the tablet security. Um where you talking about the key. The key signing? Okay if you're if you're creating a uh security provider that provides like key generator. Yep. And you want to use it that has to be uh signed by son oracle. Right. And so you have that jar in the jre lib exe directory. You have it in java.security. Yeah no I I haven't tried to you know bypass like the key signing on the manifest anything like that. Um what I did was if it was signed basically I just blow away the manifest, re-sign it and then I put together the key. So the key with my own key. Yeah, now you're modifying the JRE and not the application jar. Yeah, the JRE is actually not signed. Right. Yeah. So you could patch that and if key generator, there's key generator and key generator spy, which the security provider provides. Yeah, that would be interesting, I haven't tried that. Yeah, that's a good idea. Hopefully not. Do you provide a way to uh modify the static part of the code? To modify the stack? So underneath it's using ASM. So um if there's things like uh say you add a uh parameter to a method, you've changed the the stack size on the call. So in that case you have, it recomputes the stack when it makes the modifications. So that part is handled by the ASM library. It's a pretty, pretty robust library, it's used in a lot of things. Uh I mean the static uh method. Sorry, can you ask it again? The static method of the class. Not, you cannot extend, right? So, oh, if you can't extend it because it's marked final. Yeah, so in that case there's an annotation, I used to just call it, sorry, I'm losing my voice. Um I used to just call it, I used to just call it static method, and it just called it not final. Um but in this case it's just uh define finality, true or false. So in that case like string was marked final, you can't extend the class, but now you first run, you first mark it as uh not final, and then uh compile it once. Now you can compile it against it again, uh and extend it, add your feature, and then compile it one more time. So there's, you can have multiple passes if you want. It's not final, it's just only static. So you can use the static method. Oh, yeah, you can, you can change the, whether or not something's static. Um, no, actually no you can't. Um, because if it's not static, you've changed quite a few things. You, if you want it to not be static, I would either just declare a member variable, um, that you're gonna use for that. Uh, if you make something not static, you're gonna impact quite a few things. Um, not sure, I'm actually not sure what the use case for that would be. Um, but if you have one, I can, I can look into, to making that. Yeah. Is that certain initialization sometimes in the static? Yeah, so right now I don't handle, um, the static initializers. So, um, you can, it just gets kind of tricky when you start playing with the super calls. Um, it's, it's something, there's, there's actually this white paper right here, um, talks about a one way that you can do that. If you want to merge, say, two constructors or, um, merge the static initializers of two different block, uh, two different classes, um, that's something that has been done before. Um, I just haven't, I didn't need it for any of the, the examples that I did today. Okay, thank you. Yep. Okay, well thank you guys for coming. Um, I'll see you next time. I mean, I appreciate it.